[{"data":1,"prerenderedAt":3892},["ShallowReactive",2],{"docs-nav":3,"docs-article-engineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fcapability-contracts":797},[4,17,27,44,55,67,75,82,94,106,114,122,129,135,144,153,161,169,177,189,202,211,218,229,240,248,260,268,276,286,296,305,314,323,331,337,343,350,356,364,371,378,383,393,401,410,415,422,432,439,444,451,458,462,467,475,487,499,509,516,525,533,539,545,551,557,563,567,579,593,603,614,621,626,633,640,646,653,658,665,673,678,686,692,699,704,710,721,730,740,747,753,761,767,776,782,791],{"path":5,"title":6,"description":7,"group":8,"section":6,"order":9,"tags":10,"lastUpdated":16},"\u002Fagents\u002Fagentic-crm","Agentic CRM","Research brief and build plan for an AgencyCore agentic CRM layer, rendered as an interactive page — the core operating loop, the target architecture, the typed-tool risk gateway, the proposed-actions review queue, and the four-slice MVP.","Agents",0,[11,12,13,14,15],"crm","agents","ai","architecture","research","2026-06-12",{"path":18,"title":19,"description":20,"group":8,"section":21,"order":22,"tags":23,"lastUpdated":26},"\u002Fagents\u002Fchat","Chat agent","High-level system design of the AgencyCore chat agent — core components, data flow, and the two abstractions that hold it together.","Reference",1,[12,14,24,25],"chat","system-design","2026-05-13",{"path":28,"title":29,"description":30,"group":8,"section":31,"order":32,"tags":33,"lastUpdated":43},"\u002Fagents\u002Fcompany-enrichment","Company Enrichment","The company enrichment workflow - a cache-first read in front of the company intelligence database that fills firmographic, contact and technographic facts via a fixed-order provider waterfall, and writes every resolved fact back with provenance so the first org pays once and every later search rides free.","Enrichment",2,[12,34,35,36,37,38,39,40,41,42],"workflow","enrichment","companies","waterfall","cache","intelligence-database","firmographics","provenance","sonar","2026-06-10",{"path":45,"title":46,"description":47,"group":8,"section":48,"order":9,"tags":49,"lastUpdated":54},"\u002Fagents\u002Fcompany-sonar","Company Signals","Signal-first company discovery for marketing agencies, on the Claude Agent SDK, with a global intelligence cache and deterministic composite scoring.","Company Sonar",[12,34,42,50,51,52,35,53,14],"company-search","signals","agent-sdk","scoring","2026-06-08",{"path":56,"title":57,"description":58,"group":8,"section":48,"order":22,"tags":59,"lastUpdated":66},"\u002Fagents\u002Fcompany-sonar\u002Fsignal-monitoring","Company Signals Monitoring","Realtime signal capture layer on top of the data graph. Detects hot events, scores them with a Claude managed agent against each agency's ICP, fans out alerts.",[14,51,60,61,62,63,64,65],"intel","icp","alerts","monitoring","sse","managed-agents","2026-06-09",{"path":68,"title":69,"description":70,"group":8,"section":71,"order":22,"tags":72,"lastUpdated":74},"\u002Fagents\u002Fconcepts\u002Fchat-agent-design-principles","Designing chat agents","The 2026 playbook for production chat agents that reach into internal systems via tools — context engineering, memory, tool design, when to add complexity.","Concepts",[12,14,24,73],"context-engineering","2026-05-14",{"path":76,"title":77,"description":78,"group":8,"section":71,"order":32,"tags":79,"lastUpdated":74},"\u002Fagents\u002Fconcepts\u002Fsystem-prompt-architecture","System prompt architecture","How to structure a production chat agent system prompt — eight sections, what each one does, and the rules vendors converge on.",[12,80,81],"prompt-engineering","system-prompt",{"path":83,"title":84,"description":85,"group":8,"section":84,"order":9,"tags":86,"lastUpdated":54},"\u002Fagents\u002Fenvoy","Envoy","High-level system design for the AI outreach engine — the sequence step state machine, the human-in-the-loop draft approval gate, multi-source context enrichment, and the inbox sentiment flow, rendered as an interactive page.",[12,87,88,89,90,91,92,93,14],"envoy","outreach","sales-engagement","sequences","state-machine","human-in-the-loop","nylas",{"path":95,"title":96,"description":97,"group":8,"section":98,"order":9,"tags":99,"lastUpdated":16},"\u002Fagents\u002Fheadhunter","Headhunter","The AI talent-search pipeline on one page - the production six-step design with its current-title relevance gate, and the 2.0 system design with internal-first waterfall sourcing, a pluggable source registry, automatic entity resolution, and a people intelligence graph that compounds every run.","General Search",[12,34,100,101,14,25,102,37,103,104,105],"headhunter","recruiting","multi-source","entity-resolution","people-intelligence","flywheel",{"path":107,"title":108,"description":109,"group":8,"section":21,"order":32,"tags":110,"lastUpdated":113},"\u002Fagents\u002Fpaperclip","Paperclip","Architecture deep dive into the Paperclip orchestration system.",[12,14,111,112],"orchestration","paperclip","2026-04-20",{"path":115,"title":116,"description":117,"group":8,"section":31,"order":22,"tags":118,"lastUpdated":16},"\u002Fagents\u002Fpeople-enrichment","People Enrichment","The people enrichment workflow - a cache-first read in front of the people intelligence database that fills profile, contact and employment facts via a fixed-order provider waterfall, keyed on the LinkedIn URL, and writes every resolved fact back with provenance so the first org pays once and every later search rides free. The fill step Headhunter and People Signals both call.",[12,34,35,119,37,38,39,120,41,100,121],"people","linkedin","people-sonar",{"path":123,"title":124,"description":125,"group":8,"section":126,"order":9,"tags":127,"lastUpdated":54},"\u002Fagents\u002Fpeople-sonar","People Signals","Signal-first people discovery for marketing agencies, built on the headhunter pipeline, with a composite score weighted by signal strength, source reputation, recency, and ICP fit.","People Sonar",[12,34,121,128,51,100,35,53,14],"people-search",{"path":130,"title":131,"description":132,"group":8,"section":126,"order":22,"tags":133,"lastUpdated":54},"\u002Fagents\u002Fpeople-sonar\u002Fpeople-signal-monitoring","People Signals Monitoring","Forward-looking design for the push layer that tracks known people - champions, past contacts, target-company decision-makers - and fires a warm lead the moment they change jobs, get promoted, or their company has an event.",[14,51,60,119,63,134],"warm-leads",{"path":136,"title":137,"description":138,"group":139,"section":140,"order":22,"tags":141,"lastUpdated":143},"\u002Fengineering\u002Fguides\u002Fagent-execution-stack","The Agent Execution Stack","Durable workflows over pluggable agent backends — how AgencyCore runs AI agents on Inngest over a webhook-driven Claude Managed Agents backend.","Engineering","Guides",[12,142,14,25],"inngest","2026-06-25",{"path":145,"title":146,"description":147,"group":139,"section":140,"order":9,"tags":148,"lastUpdated":143},"\u002Fengineering\u002Fguides\u002Fagent-runtime","Agent runtime","How AgencyCore runs AI agents on a provider-neutral runtime — the abstraction layer that lets us swap the agent backend, with Claude managed agents as the current provider.",[12,149,14,150,151,152,25],"runtime","anthropic","claude","providers",{"path":154,"title":155,"description":156,"group":139,"section":21,"order":157,"tags":158,"lastUpdated":160},"\u002Fengineering\u002Freference\u002Fagno-to-agent-sdk-migration","Agno → Claude Agent SDK migration","System-design spec for moving the ac-python-api workflow engine off Agno onto Anthropic's Claude Agent SDK \u002F Managed Agents, tiered by control-flow shape.",10,[12,14,159,52,65],"migration","2026-06-06",{"path":162,"title":163,"description":164,"group":139,"section":21,"order":22,"tags":165,"lastUpdated":54},"\u002Fengineering\u002Freference\u002Fcloudflare-agent-sandbox","Cloudflare agent sandbox","Cloudflare's Workers-based agent platform, evaluated as an alternative sandbox for our Agno workflows.",[12,166,167,168,159],"sandbox","cloudflare","workers",{"path":170,"title":171,"description":172,"group":139,"section":21,"order":32,"tags":173,"lastUpdated":176},"\u002Fengineering\u002Freference\u002Fvirtual-filesystem-rag","Virtual filesystem for AI assistants","How ChromaFs provides AI agents with structured file access.",[12,174,14,175],"rag","chromafs","2026-04-18",{"path":178,"title":179,"description":180,"group":139,"section":181,"order":182,"tags":183,"lastUpdated":188},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fcapabilities\u002Fstate-and-knowledge","State and knowledge","What a run may know. One deterministic context builder over application state, knowledge and memory, one owner for every fact, and memory that is written through a tool.","Agentic platform",11,[184,185,186,11,187],"context","memory","knowledge","pgvector","2026-08-31",{"path":190,"title":191,"description":192,"group":139,"section":181,"order":157,"tags":193,"lastUpdated":201},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fcapabilities\u002Ftools-and-integrations","Tools and integrations","A tool is the one way an agent reaches the world. AgencyCore owns the model facing contract, the invoke path, the credentials and the result boundary.",[194,195,196,197,198,199,200],"tools","integrations","mcp","agno","policy","security","idempotency","2026-09-04",{"path":203,"title":204,"description":205,"group":139,"section":181,"order":22,"tags":206,"lastUpdated":210},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fcontract","Platform contract","One platform behind chat, interactive channels, triggers, approvals and background runs, with one Agno runtime, one tool layer, one state layer, and three cross-cutting planes.",[12,14,197,142,194,207,149,208,198,209],"skills","channels","observability","2026-09-02",{"path":212,"title":181,"description":213,"group":139,"section":214,"order":22,"tags":215,"lastUpdated":201},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform","The whole agentic platform on one page - who starts a run, the one boundary every run passes, how the work executes, and what comes back.","System design",[12,14,216,197,142,217,198],"overview","runs",{"path":219,"title":220,"description":221,"group":139,"section":181,"order":222,"tags":223,"lastUpdated":228},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Fagent-access","Agent access (CLI and MCP)","How an outside AI agent reaches AgencyCore. The ac CLI works today as a user seat. An MCP server is planned and not designed.",6,[224,196,12,151,225,226,227],"cli","access","auth","todo","2026-08-18",{"path":230,"title":231,"description":232,"group":139,"section":181,"order":233,"tags":234,"lastUpdated":239},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Fchannel-gateway","Channel gateway","The only layer that knows both an interactive channel and the platform. One message shape converges inbound, one intent shape diverges outbound, and no model call happens here.",3,[208,235,236,237,238,199],"slack","web","identity","sessions","2026-08-30",{"path":241,"title":242,"description":243,"group":139,"section":181,"order":244,"tags":245,"lastUpdated":210},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Ffront-door","Front door","The conversational control layer. It turns a request into one structured decision, then deterministic application code answers or hands work to RunManager.",4,[246,247,197,184,198,217],"front-door","routing",{"path":249,"title":250,"description":251,"group":139,"section":181,"order":32,"tags":252,"lastUpdated":259},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Fsurfaces","Surfaces","Every product surface and its API contract. Web chat goes through the gateway; every schema-native surface calls the domain API.",[253,254,24,255,256,257,258,217,64],"surfaces","api","approvals","prospects","saved-searches","builder","2026-09-03",{"path":261,"title":262,"description":263,"group":139,"section":181,"order":264,"tags":265,"lastUpdated":188},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Ftriggers","Triggers","A Run with no person. Every producer emits one Event, matching is deterministic, and dispatch reuses RunManager, Policy and Inngest.",5,[266,267,142,200],"triggers","events",{"path":269,"title":270,"description":271,"group":139,"section":181,"order":272,"tags":273,"lastUpdated":259},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fplanes\u002Fidempotency","Idempotency","One durable PostgreSQL key service prevents duplicate effects and freezes mutable input before selected Run starts. A Run start is guarded by a unique index on the Run row.",14,[200,217,194,274,275],"webhooks","reliability",{"path":277,"title":278,"description":279,"group":139,"section":181,"order":280,"tags":281,"lastUpdated":285},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fplanes\u002Fobservability-and-operations","Observability and operations","One run row, one span tree and one usage meter. Sentry reports system failure; AgencyCore spans explain what the agent did.",13,[209,217,282,283,64,284],"spans","usage","sentry","2026-08-26",{"path":287,"title":288,"description":289,"group":139,"section":181,"order":290,"tags":291,"lastUpdated":295},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fplanes\u002Fpolicy-and-governance","Policy and governance","One deterministic plane answers may this happen, at three checkpoints, with one grant model, one approval model and one decision log.",12,[198,292,255,293,294],"permissions","limits","governance","2026-08-25",{"path":297,"title":6,"description":298,"group":139,"section":299,"order":22,"tags":300,"lastUpdated":210},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fagentic-crm","The AgencyCore CRM loop for turning signals and discovery into qualified organization prospects, CRM relationships and outreach.","Agentic products",[11,301,51,302,256,35,303,304,87],"lead-generation","intelligence","signals-search","email-sequence",{"path":306,"title":307,"description":308,"group":139,"section":299,"order":264,"tags":309,"lastUpdated":188},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fbuilder-chat","Front door builder chat","Conversational authoring for organization-specific Agent and Workflow definitions, entered through the normal Front Door and backed by the existing DefinitionService.",[310,311,246,12,312,313,198],"authoring","definitions","workflows","templates",{"path":315,"title":316,"description":317,"group":139,"section":181,"order":318,"tags":319,"lastUpdated":201},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fcapability-contracts","Company, People and Signals contracts","The five Phase 7 product capabilities, their bounded inputs, stable references, permissions and results.",21,[320,321,119,51,322],"capabilities","company","contracts",{"path":324,"title":325,"description":326,"group":139,"section":181,"order":327,"tags":328,"lastUpdated":330},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fcapability-scenarios","Capability design scenarios","Normal, failure and recovery cases for the Phase 7 capability contracts, with implementation owners.",22,[320,329,321,119,51],"validation","2026-09-05",{"path":332,"title":333,"description":334,"group":139,"section":299,"order":233,"tags":335,"lastUpdated":210},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Femail-sequence","Email sequence workflow","Envoy durable outreach for one or many people, with fresh context, approvals, reply waits, follow-ups and Nylas transport.",[336,87,34,142,93,255],"email",{"path":338,"title":339,"description":340,"group":139,"section":299,"order":244,"tags":341,"lastUpdated":188},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fgeneral-chat","Front door general chat","The default conversational answer path for AgencyCore. It answers from supplied context, cites what it used, asks when context is insufficient, and delegates real work through the normal Front Door.",[24,246,186,184,247,342],"citations",{"path":344,"title":345,"description":346,"group":139,"section":299,"order":222,"tags":347,"lastUpdated":188},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fhuman-review","Human review inbox","One product page for every agentic action that is paused because a person must authorize an exact proposal. It is a view over the shared approval primitive, not a second review system.",[348,255,349,198,12],"human-review","inbox",{"path":351,"title":352,"description":353,"group":139,"section":299,"order":32,"tags":354,"lastUpdated":259},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fsignals-search","Signals Search","One bounded discovery workflow that finds companies, verifies signals, finds relevant people, and produces evidence-backed organization prospects without prematurely creating CRM records.",[303,355,36,119,51,302,256,11,35],"discovery",{"path":357,"title":358,"description":359,"group":139,"section":299,"order":360,"tags":361,"lastUpdated":188},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fworkflow-visualizer","Workflow visualizer","One constrained workflow graph, reused to author a draft, read a published definition, and watch a Run. Build mode edits the draft; run mode overlays Run and span state on the frozen snapshot.",7,[312,362,258,311,217,282,363,255],"visualizer","graph",{"path":365,"title":366,"description":367,"group":139,"section":181,"order":368,"tags":369,"lastUpdated":201},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fruntime\u002Fdefinitions","Runtime definitions","Editable drafts, one published configuration per definition, template forks, deterministic validation, and the Run snapshot that keeps in flight work stable.",8,[149,311,329,370],"publishing",{"path":372,"title":373,"description":374,"group":139,"section":181,"order":375,"tags":376,"lastUpdated":259},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fruntime\u002Fexecution","Runtime execution","The Run record, the Inngest step boundaries, agent segments, workflow nodes, approvals, cancellation, failure handling and live events.",9,[149,217,197,142,255,377,64],"cancellation",{"path":379,"title":380,"description":381,"group":139,"section":181,"order":360,"tags":382,"lastUpdated":285},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fruntime","Agentic runtime","One Run contract, one Agno agent runtime, one deterministic workflow model, and the component boundaries that keep the framework replaceable.",[149,217,197,312,207,142],{"path":384,"title":385,"description":386,"group":139,"section":387,"order":244,"tags":388,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Fcompany-context","Company context","L3. Company state, knowledge and memory are three different things. One deterministic builder turns them into one brief.","Mission Control",[389,390,186,185,184,391,11],"mission-control","company-state","retrieval","2026-08-12",{"path":394,"title":395,"description":396,"group":139,"section":387,"order":22,"tags":397,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Fexperience","Experience","L6. Where a person observes and controls the company, and the one rule that keeps the UI out of the business.",[389,398,399,255,400],"ui","control-plane","activity",{"path":402,"title":403,"description":404,"group":139,"section":387,"order":222,"tags":405,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Ffoundation","Foundation","L1. Generic infrastructure with no business logic in it. The test is that another product could run on it unchanged.",[389,406,407,408,267,409,226,209],"infrastructure","database","queue","storage",{"path":411,"title":387,"description":412,"group":139,"section":214,"order":233,"tags":413,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control","The internal Company OS. Six layers and one policy plane put a person in control of company state and of autonomous execution.",[389,414,14,12,312,198,399],"company-os",{"path":416,"title":417,"description":418,"group":139,"section":387,"order":32,"tags":419,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Fintelligence","Intelligence","L5. The agent is the primitive. A skill is how it works, a tool is how it reaches the world, and the two are never the same thing.",[389,12,207,420,421],"planning","reasoning",{"path":423,"title":424,"description":425,"group":139,"section":387,"order":368,"tags":426,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Fmetrics-and-connectors","Metrics and connectors","A worked example across every layer. Three vendors, one metric pipeline, three views, and the rule that decides what we store.",[389,427,195,428,429,284,430,431],"metrics","stripe","posthog","ingest","dashboards",{"path":433,"title":434,"description":435,"group":139,"section":387,"order":233,"tags":436,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Forchestration","Orchestration","L4. Workflow, run, step, trigger and event. Five nouns that turn a decision into durable execution.",[389,312,217,266,267,437,438],"durability","retry",{"path":440,"title":288,"description":441,"group":139,"section":387,"order":360,"tags":442,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Fpolicy-and-governance","A plane, not a layer. One place decides what an agent may do, under what conditions, and how much. Human approval is one of its three answers.",[389,198,294,255,292,293,443],"audit",{"path":445,"title":191,"description":446,"group":139,"section":387,"order":264,"tags":447,"lastUpdated":392},"\u002Fengineering\u002Fsystem-design\u002Fmission-control\u002Ftools-and-integrations","L2. One contract for every capability. The tool is the only route to the world, and it is where policy, audit and tenancy meet.",[389,194,195,448,449,450],"adapters","registry","credentials",{"path":452,"title":453,"description":454,"group":139,"section":455,"order":22,"tags":456,"lastUpdated":210},"\u002Fengineering\u002Fsystem-design\u002Fworkflows\u002Fcompany-search","Company search","Implementation notes for company.search. Search resolves and gates company identities; enrichment is a separate capability.","Workflows",[321,457,142,42],"search",{"path":459,"title":31,"description":460,"group":139,"section":455,"order":233,"tags":461,"lastUpdated":210},"\u002Fengineering\u002Fsystem-design\u002Fworkflows\u002Fenrichment","Reusable company and people enrichment workflows with canonical Intelligence write-back, existing tier freshness and bounded asynchronous email.",[35,321,119,142],{"path":463,"title":464,"description":465,"group":139,"section":455,"order":32,"tags":466,"lastUpdated":259},"\u002Fengineering\u002Fsystem-design\u002Fworkflows\u002Fpeople-search","People search","Implementation notes for people.search. Bounded company scope and persona gates return selectable person identities without enrichment.",[119,457,142,100],{"path":468,"title":469,"description":470,"group":139,"section":455,"order":244,"tags":471,"lastUpdated":474},"\u002Fengineering\u002Fsystem-design\u002Fworkflows\u002Fsignals-search","Signals search","Superseded. The earlier on-demand buying-signal search component, kept as a record of the design that the agentic platform Signals Search workflow replaces.",[51,12,142,472,473],"intelligence-databases","superseded","2026-08-28",{"path":476,"title":477,"description":478,"group":479,"section":480,"order":481,"tags":482,"lastUpdated":66},"\u002Flearnings\u002Fagentic-sdlc","The agentic SDLC","How AI agents move from autocomplete to owning the loop across the software lifecycle, and why that shifts the bottleneck from coding to verification.","Learnings",null,30,[12,483,484,485,486],"sdlc","engineering","verification","review",{"path":488,"title":489,"description":490,"group":479,"section":480,"order":491,"tags":492,"lastUpdated":498},"\u002Flearnings\u002Fagi-to-asi","From AGI to ASI","What lies beyond human-level AI. The four technological pathways from AGI to artificial superintelligence, the formal ceiling that bounds them, and the six bottlenecks that could stall the climb - distilled from the DeepMind report.",50,[493,494,495,496,497],"ai-futures","asi","agi","scaling","recursive-self-improvement","2026-06-19",{"path":500,"title":501,"description":502,"group":479,"section":480,"order":503,"tags":504,"lastUpdated":66},"\u002Flearnings\u002Fai-native-company-playbook","AI native company playbook","Why AI should be the operating system your company runs on, not a tool it uses, and the concrete practices that follow - closed loops, a queryable org, software factories, and token maxing.",40,[505,506,12,507,508],"ai-native","company-building","gtm","founders",{"path":510,"title":511,"description":512,"group":479,"section":480,"order":157,"tags":513,"lastUpdated":54},"\u002Flearnings\u002Fbuying-intent-signals","Buying intent signals","How buyers leak their intent before they ever fill in a form, and how to read those signals before the window closes.",[514,51,507,515],"intent","sales",{"path":517,"title":518,"description":519,"group":479,"section":480,"order":520,"tags":521,"lastUpdated":54},"\u002Flearnings\u002Fcold-outbound-system","Cold outbound system","A high-level study of an open-source 29-skill cold email system, organized into five sequential tracks from ICP to iteration.",20,[522,523,507,524],"outbound","cold-email","systems",{"path":526,"title":527,"description":528,"group":479,"section":480,"order":529,"tags":530,"lastUpdated":532},"\u002Flearnings\u002Fswan-gtm-skills-architecture","Swan GTM skills architecture","A research note on Swan AI's foundations and maps model for GTM agents, with ASCII diagrams and ideas AgencyCore can borrow.",60,[507,12,73,531,14],"swan","2026-07-01",{"path":534,"title":535,"description":536,"group":387,"section":480,"order":272,"tags":537,"lastUpdated":43},"\u002Fmission-control\u002Fciops-agent","CIOps agent","High-level system architecture and design notes for the Mission Control CIOps agent.",[389,12,538,14],"ciops",{"path":540,"title":541,"description":542,"group":387,"section":480,"order":182,"tags":543,"lastUpdated":43},"\u002Fmission-control\u002Fcostops-agent","CostOps agent","High-level system architecture and design notes for the Mission Control CostOps agent.",[389,12,544,14],"finops",{"path":546,"title":547,"description":548,"group":387,"section":480,"order":520,"tags":549,"lastUpdated":54},"\u002Fmission-control\u002Fdashboard","Dashboard","The Mission Control product UI - a dark cockpit with a fleet-nav rail, company-state grid, a working escalation queue, live ledger and a global kill switch.",[389,12,550,398],"dashboard",{"path":552,"title":553,"description":554,"group":387,"section":480,"order":280,"tags":555,"lastUpdated":43},"\u002Fmission-control\u002Fproduct-analytics-agent","ProductAnalytics agent","High-level system architecture and design notes for the Mission Control ProductAnalytics agent.",[389,12,556,14],"product-analytics",{"path":558,"title":559,"description":560,"group":387,"section":480,"order":290,"tags":561,"lastUpdated":43},"\u002Fmission-control\u002Frevenueops-agent","RevenueOps agent","High-level system architecture and design notes for the Mission Control RevenueOps agent.",[389,12,562,14],"revops",{"path":564,"title":214,"description":565,"group":387,"section":480,"order":157,"tags":566,"lastUpdated":54},"\u002Fmission-control\u002Fsystem-design","One screen for the whole company, watched by a guardrailed fleet of ops agents that explain, propose, act and learn overnight.",[389,12,544,14],{"path":568,"title":569,"description":570,"group":571,"section":480,"order":32,"tags":572,"lastUpdated":578},"\u002Fproduct-design\u002Fonboarding-flow","Onboarding flow","Product design for the signup wizard and how TAM building folds into it. Analyzes the flow today (account, profile, company), the gap (no ICP, empty dashboard), and the integration of a new \"who you sell to\" ICP step plus a build-and-reveal screen that lands the user on a populated, ranked list.","Product Design",[573,61,574,575,576,577],"onboarding","tam","activation","ux","user-journey","2026-06-11",{"path":580,"title":581,"description":582,"group":571,"section":480,"order":233,"tags":583,"lastUpdated":592},"\u002Fproduct-design\u002Fpricing-entitlements","Pricing tiers, entitlements and usage credits","Specification for subscription tiers with gated platform access: composable plan entitlements, a unified usage-credit currency, plan-sourced limits, per-module trials and a two-ticket delivery plan built on the Stripe billing foundation. Written for discussion; the Linear document is the canonical copy with ticket links.",[584,585,586,587,588,589,590,591],"pricing","entitlements","billing","credits","subscriptions","plans","seats","trials","2026-07-06",{"path":594,"title":595,"description":596,"group":571,"section":480,"order":233,"tags":597,"lastUpdated":578},"\u002Fproduct-design\u002Fsales-signals-ux","Designing Signals","Product design for the sales-signals experience in ac-frontend: the 14-type taxonomy and its color system, the anatomy of a signal card across four densities, the 0-10 lead score scale, the origin tag (sonar pull vs proactive push), the seven surfaces where signals render (launchpad, sonar app, company detail, timeline, activities, data layer, Envoy), and the interaction rules that keep them consistent.",[51,576,598,11,42,599,600,601,602],"design-system","lead-score","origin","pull","push",{"path":604,"title":605,"description":606,"group":607,"section":608,"order":244,"tags":609,"lastUpdated":43},"\u002Fproprietary-data\u002Fcrm\u002Factivities","Activities","Deep dive on crm_activities, the interaction + task log of the CRM — where it is served from, how a row is born and read, and its full schema, relationships and rules.","Proprietary data","CRM",[11,610,611,612,613],"activities","tasks","data-model","schema",{"path":615,"title":616,"description":617,"group":607,"section":608,"order":264,"tags":618,"lastUpdated":43},"\u002Fproprietary-data\u002Fcrm\u002Fcommunications","Communications","Deep dive on crm_communications and crm_communication_events, the unified email\u002Fcall\u002Fmessage log and its per-message engagement tracking — where it is served from, the outbound message lifecycle, and the full schema, relationships and rules.",[11,619,336,620,612],"communications","engagement",{"path":622,"title":623,"description":624,"group":607,"section":608,"order":22,"tags":625,"lastUpdated":43},"\u002Fproprietary-data\u002Fcrm\u002Fcompanies","Companies","Deep dive on crm_companies, the account record at the centre of the CRM — where it is served from, how a row is born and read, and its full schema, relationships and rules.",[11,36,612,613,14],{"path":627,"title":628,"description":629,"group":607,"section":608,"order":233,"tags":630,"lastUpdated":43},"\u002Fproprietary-data\u002Fcrm\u002Fdeals","Deals","Deep dive on the deal pipeline — crm_deals, crm_pipeline_stages and crm_pipeline_config. Where it is served from, the life of a deal, and its full schema, relationships and rules.",[11,631,632,612,613],"deals","pipeline",{"path":634,"title":635,"description":636,"group":607,"section":608,"order":222,"tags":637,"lastUpdated":43},"\u002Fproprietary-data\u002Fcrm\u002Flists","Lists","Deep dive on crm_lists and crm_list_members, the static or dynamic member collections of the CRM — where they are served from, how a list and its members come to be and are read, and their schema, relationships and rules.",[11,638,639,612,613],"lists","segments",{"path":641,"title":642,"description":643,"group":607,"section":608,"order":32,"tags":644,"lastUpdated":43},"\u002Fproprietary-data\u002Fcrm\u002Fpeople","People","Deep dive on crm_people, the contact record of the CRM — where it is served from, how a row is born and read, and its full schema, relationships and rules.",[11,119,645,612,613],"contacts",{"path":647,"title":648,"description":649,"group":607,"section":608,"order":368,"tags":650,"lastUpdated":43},"\u002Fproprietary-data\u002Fcrm\u002Fsaved-filters","Saved filters","Deep dive on crm_saved_filters, the named reusable filter snapshots over the company, person and signal list views — where it is served from, how a saved view is born and applied, and its full schema, relationships and rules.",[11,651,652,612,613],"saved-filters","views",{"path":654,"title":655,"description":656,"group":607,"section":608,"order":360,"tags":657,"lastUpdated":578},"\u002Fproprietary-data\u002Fcrm\u002Fsignals","Signals","Deep dive on the signals tables - signals, company_signals and person_signals, the CRM's sales-intelligence layer. Where signals are served from, how one is born and attached, and the full schema, relationships and rules.",[11,51,302,612,613],{"path":659,"title":660,"description":661,"group":607,"section":662,"order":22,"tags":663,"lastUpdated":43},"\u002Fproprietary-data\u002Fintelligence-databases\u002Fcompany-intelligence-database","Company Intelligence Database","Decided architecture for ENG-669, the cross-org company intelligence layer that acts as a read-through cache in front of enrichment providers, with public-facts-only privacy and provenance-tracked write-back.","Intelligence databases",[14,60,36,51,38,664],"eng-669",{"path":666,"title":667,"description":668,"group":607,"section":662,"order":244,"tags":669,"lastUpdated":578},"\u002Fproprietary-data\u002Fintelligence-databases\u002Forg-signal-feed","Org Signal Feed","The per-org activation layer on top of the shared signals store. One immutable intel_signals row fans out to many orgs through scoring (signal-type weight times ICP fit times recency decay) and materializes as ranked, tiered rows in intel_org_signal_feed - the only org-scoped, RLS-per-org table of the signal stack, the door the launchpad, inbox and digest all read through. Signals enter by two ingest classes - a user's sonar pull (ungated) or an automated push (gated by threshold plus an optional competitor-ICP check) - logged in intel_signal_ingests, and each feed row records its origin.",[14,60,51,670,53,671,672,575,430,601,602,600],"feed","decay","rls",{"path":674,"title":675,"description":676,"group":607,"section":662,"order":32,"tags":677,"lastUpdated":578},"\u002Fproprietary-data\u002Fintelligence-databases\u002Fpeople-intelligence-database","People Intelligence Database","Decided architecture for the cross-org people intelligence layer - a read-through cache in front of headhunter research and Hunter email lookups, with LinkedIn-URL identity, append-only employment edges, per-tier freshness stamps on the flat profile, shared intel_sources provenance, unified intel_signals, and a GDPR erasure path.",[14,60,119,51,38,100],{"path":679,"title":680,"description":681,"group":607,"section":662,"order":233,"tags":682,"lastUpdated":578},"\u002Fproprietary-data\u002Fintelligence-databases\u002Fsignals-intelligence-database","Signals Intelligence Database","Decided v1 architecture for the unified signal store - one polymorphic append-only intel_signals table that holds both company and person signals, with a shared taxonomy, source-ranked provenance, an intel_signal_ingests log that records which pipeline found each signal, decay at read time, and a person-to-company rollup so a champion job change surfaces on the company feed.",[14,60,51,683,671,684,670,685,41,601,602],"polymorphic","taxonomy","ingests",{"path":687,"title":688,"description":689,"group":607,"section":480,"order":9,"tags":690,"lastUpdated":16},"\u002Fproprietary-data\u002Foverview","Data Layer Overview","The AgencyCore data layer in one map - the org-scoped CRM plane in production today and the global intelligence plane designed to sit in front of it, with interactive diagrams of both, the end-to-end data flow, freshness and precedence rules, the privacy seam, and the rollout path.",[691,14,60,11,51,38,25,216],"data-layer",{"path":693,"title":694,"description":695,"group":696,"section":480,"order":9,"tags":697,"lastUpdated":54},"\u002Froadmap","Roadmap - June 2026","June 2026 product plan across four themes. The spine is moving our agents onto an isolated sandbox runtime and rebuilding the core agents and workflows on it, then standing up a read-through intelligence data store and shipping the Stripe billing system. Knowledge base, assistant, and credit tracking carry into the July roadmap.","Roadmap",[698,420],"roadmap",{"path":700,"title":701,"description":702,"group":696,"section":480,"order":22,"tags":703,"lastUpdated":54},"\u002Froadmap\u002Fjuly-2026","Roadmap - July 2026","July 2026 product plan across three themes, all carried over from June. Building on June's sandbox runtime, July grounds the agents in a knowledge base, launches the AI chat assistant, and meters every action with per-action credit tracking that reconciles into the Stripe billing system shipped in June.",[698,420],{"path":705,"title":706,"description":707,"group":696,"section":480,"order":32,"tags":708,"lastUpdated":532},"\u002Froadmap\u002Fjune-2026-slides","Roadmap slides - June 2026","Board-review slide deck for the June 2026 product roadmap, rendered directly from the original PPTX in the docs site.",[698,420,709],"slides",{"path":711,"title":712,"description":713,"group":714,"section":8,"order":520,"tags":715,"lastUpdated":16},"\u002Fsymphony\u002Fagents\u002Fdevops-agent","DevOps agent","Interactive design for a Slack-first Symphony DevOps agent that wraps production promotion, rollback, audit, and operational jobs behind policy gates, typed runbooks, and an auditable ledger.","Symphony",[716,235,717,718,719,720],"symphony","devops","production","runbooks","operations",{"path":722,"title":723,"description":724,"group":714,"section":8,"order":157,"tags":725,"lastUpdated":16},"\u002Fsymphony\u002Fagents\u002Foncall-agent","Oncall agent","Interactive design for a Symphony oncall agent that turns Sentry incidents into rich Linear tickets, investigates with Codex, opens fix PRs, and resolves Sentry after merge.",[716,284,726,727,728,729],"linear","oncall","incident-response","codex",{"path":731,"title":732,"description":733,"group":714,"section":734,"order":157,"tags":735,"lastUpdated":16},"\u002Fsymphony\u002Fhousekeeping\u002Fcodex-vacuum","Codex vacuum","Interactive design for the Symphony housekeeping timer that checkpoints and vacuums Codex sqlite stores on the VPS.","Housekeeping",[716,736,737,729,738,739],"timed-jobs","housekeeping","sqlite","vps",{"path":741,"title":742,"description":743,"group":714,"section":734,"order":481,"tags":744,"lastUpdated":16},"\u002Fsymphony\u002Fhousekeeping\u002Fhost-cleanup","Host cleanup","Interactive design for the Symphony housekeeping timer that removes stale \u002Ftmp debris, vacuums the journal, and optionally cleans the apt package cache.",[716,736,737,739,745,746],"disk","cleanup",{"path":748,"title":749,"description":750,"group":714,"section":734,"order":520,"tags":751,"lastUpdated":16},"\u002Fsymphony\u002Fhousekeeping\u002Fworkspace-cleanup","Workspace cleanup","Interactive design for the Symphony housekeeping timer that prunes idle per-issue workspaces after their TTL.",[716,736,737,752,746,739],"workspaces",{"path":754,"title":755,"description":756,"group":714,"section":480,"order":9,"tags":757,"lastUpdated":66},"\u002Fsymphony","Symphony orchestration","How AgencyCore runs OpenAI Symphony as a long-running daemon that turns Linear tickets into isolated, autonomous Codex runs, reviewed by Claude and merged by humans. High-level workflow, system architecture, and the engineer playbook.",[716,729,726,758,111,739,759,760],"claude-review","qa","automation",{"path":762,"title":763,"description":764,"group":714,"section":214,"order":22,"tags":765,"lastUpdated":392},"\u002Fsymphony\u002Fsystem-design\u002Fhigh-level-design","High-level design","The Symphony daemon end to end — the standing agent workforce and its label-routed workflows, then the runtime that polls, dispatches, runs and writes back.",[716,14,111,12,729,726,766],"systemd",{"path":768,"title":769,"description":770,"group":714,"section":771,"order":503,"tags":772,"lastUpdated":16},"\u002Fsymphony\u002Ftimed-jobs\u002Fdaily-security-agent","Daily security agent","Interactive design for a report-only Symphony timed job that reviews the last 24h of commits, scans the system for vulnerabilities, and opens focused follow-up tickets.","Timed jobs",[716,199,736,729,773,774,775],"semgrep","threat-model","ownership",{"path":777,"title":778,"description":779,"group":714,"section":771,"order":481,"tags":780,"lastUpdated":16},"\u002Fsymphony\u002Ftimed-jobs\u002Fdaily-sentry-triage","Daily Sentry triage","Interactive design for the Symphony timed job that performs read-only Sentry triage, deduplicates existing tracked clusters, and creates focused ENG bugs for new actionable errors.",[716,736,284,209,781,726],"triage",{"path":783,"title":784,"description":785,"group":714,"section":771,"order":157,"tags":786,"lastUpdated":16},"\u002Fsymphony\u002Ftimed-jobs\u002Fnightly-local-staging-e2e","Nightly local staging E2E","Interactive design for the Symphony timed job that seeds local Supabase, runs ac-frontend Playwright E2E against the local staging stack, uploads evidence, and cleans artifacts.",[716,736,787,788,789,790],"e2e","playwright","staging","frontend",{"path":792,"title":793,"description":794,"group":714,"section":771,"order":520,"tags":795,"lastUpdated":16},"\u002Fsymphony\u002Ftimed-jobs\u002Fnightly-staging-qa","Nightly staging QA","Interactive design for the Symphony timed job that seeds a staging QA Linear issue, runs an agent-browser crawl, validates feature-map coverage, and files focused follow-up work.",[716,736,789,759,796,726],"agent-browser",{"id":798,"title":316,"body":799,"customComponent":480,"description":317,"extension":3879,"group":139,"lastUpdated":201,"meta":3880,"navigation":3881,"order":318,"path":315,"related":3882,"section":181,"seo":3888,"stem":3889,"tags":3890,"__hash__":3891},"docs\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fcapability-contracts.md",{"type":800,"value":801,"toc":3846},"minimark",[802,806,828,833,888,891,894,898,906,1025,1047,1054,1065,1121,1128,1132,1139,1150,1210,1217,1221,1231,1246,1251,1254,1260,1368,1394,1400,1456,1459,1472,1475,1511,1525,1535,1539,1542,1545,1563,1572,1575,1593,1596,1599,1602,1606,1615,1699,1710,1717,1720,1724,1753,1760,1763,1767,1783,1807,1810,1817,1824,1828,1835,1913,1958,2013,2044,2059,2062,2122,2162,2168,2171,2175,2189,2198,2217,2225,2238,2245,2257,2261,2289,2306,2309,2316,2346,2370,2373,2450,2468,2501,2504,2508,2522,2551,2563,2583,2586,2605,2621,2678,2694,2697,2712,2729,2751,2757,2774,2778,2790,2796,2813,2842,2850,2856,2876,2880,2883,2887,2952,2982,2986,3000,3012,3044,3053,3059,3066,3180,3208,3212,3230,3245,3284,3317,3363,3366,3370,3499,3503,3516,3586,3607,3617,3621,3624,3643,3654,3660,3688,3695,3701,3704,3708,3739,3749,3756,3760],[803,804,316],"h1",{"id":805},"company-people-and-signals-contracts",[807,808,809,810,814,815,818,819,822,823,827],"p",{},"This page defines the Phase 7 contract. All five capabilities install and reconcile on the runtime baseline.\nThe runtime baseline is ",[811,812,813],"code",{},"agentic-platform",". The documentation repository uses ",[811,816,817],{},"main",".\nENG-2285 proves this contract through the API and the CLI, with ",[811,820,821],{},"ac-python-api scripts\u002Fagentic_phase7_exit_test\u002Frun.sh",".\nThe ",[824,825,826],"a",{"href":324},"design scenarios"," list the cases those tests cover.",[829,830,832],"h2",{"id":831},"product-boundary","Product boundary",[834,835,836,849],"table",{},[837,838,839],"thead",{},[840,841,842,846],"tr",{},[843,844,845],"th",{},"Concept",[843,847,848],{},"Meaning",[850,851,852,864,872,880],"tbody",{},[840,853,854,858],{},[855,856,857],"td",{},"Capability",[855,859,860,861],{},"A stable business action, such as ",[811,862,863],{},"company.search",[840,865,866,869],{},[855,867,868],{},"Workflow",[855,870,871],{},"The published steps that execute the action",[840,873,874,877],{},[855,875,876],{},"Agent",[855,878,879],{},"Reasoning inside a bounded task",[840,881,882,885],{},[855,883,884],{},"Tool",[855,886,887],{},"One technical operation with a schema, grant and policy check",[807,889,890],{},"Companies and People each have Search and Enrich segments. Signals finds opportunities and explains their timing.\nSearch returns selectable references. Enrich completes known identities and writes canonical Intelligence.\nSearch never starts enrichment or email lookup. CRM and list writes require a separate explicit action.",[807,892,893],{},"All five V1 executors are workflows. They may contain bounded Agent steps where reasoning is necessary.\nThe Front Door starts at most one capability per turn. A published workflow may compose child workflows.\nCompound chat plans, live steering, CSV parsing and Deep enrichment remain outside Phase 7.",[829,895,897],{"id":896},"registry-record","Registry record",[807,899,900,901,905],{},"The tenant registry projects published ",[824,902,904],{"href":903},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fruntime\u002Fdefinitions#product-capability-bindings","definition bindings",".\nIt does not maintain a second copy of executable configuration.",[834,907,908,918],{},[837,909,910],{},[840,911,912,915],{},[843,913,914],{},"Field",[843,916,917],{},"Contract",[850,919,920,930,944,957,970,983,995,1005],{},[840,921,922,927],{},[855,923,924],{},[811,925,926],{},"id",[855,928,929],{},"One of the five IDs below; case-sensitive",[840,931,932,941],{},[855,933,934,937,938],{},[811,935,936],{},"name",", ",[811,939,940],{},"description",[855,942,943],{},"Product text from the published binding",[840,945,946,951],{},[855,947,948],{},[811,949,950],{},"contract_version",[855,952,953,954],{},"Positive integer; V1 is ",[811,955,956],{},"1",[840,958,959,967],{},[855,960,961,937,964],{},[811,962,963],{},"input_schema",[811,965,966],{},"output_schema",[855,968,969],{},"Closed JSON Schema contracts for that version",[840,971,972,977],{},[855,973,974],{},[811,975,976],{},"required_scopes",[855,978,979,982],{},[811,980,981],{},"run.start"," plus the published workflow's derived required tool scopes",[840,984,985,990],{},[855,986,987],{},[811,988,989],{},"executor_type",[855,991,992,994],{},[811,993,34],{}," in V1",[840,996,997,1002],{},[855,998,999],{},[811,1000,1001],{},"executor_id",[855,1003,1004],{},"The active definition UUID in the caller's organization",[840,1006,1007,1012],{},[855,1008,1009],{},[811,1010,1011],{},"availability",[855,1013,1014,1017,1018,1021,1022],{},[811,1015,1016],{},"available"," or ",[811,1019,1020],{},"unavailable",", with a bounded ",[811,1023,1024],{},"reason",[807,1026,1027,1028,937,1030,937,1033,937,1036,1039,1040,1043,1044,1046],{},"The five stable IDs are ",[811,1029,863],{},[811,1031,1032],{},"company.enrich",[811,1034,1035],{},"people.search",[811,1037,1038],{},"people.enrich"," and ",[811,1041,1042],{},"signals.search",".\nThe vocabulary is code and the bindings are data, so an organization that installed nothing still reads five records.\nDisplay names, provider names and definition UUIDs never replace these IDs.\nPublic reads expose schemas and availability. They omit executor configuration, Tool Registry details and foreign bindings.\nThe executor UUID is internal registry data; clients start by product ID.\nA public read exposes ",[811,1045,976],{}," on an available record, and it omits the field on an unavailable one.\nThe registry answers a contract only to a caller that holds every scope in that set, so the field discloses nothing new. It says what a start consumes.",[807,1048,1049,1053],{},[1050,1051,1052],"strong",{},"An unavailable record carries the ID, the availability and the reason alone.","\nThe registry cannot check the caller's rights against a capability it cannot resolve, because the required scopes live in the binding.\nProduct text and schemas there would be a contract nobody authorized, so those fields are absent rather than null.",[807,1055,1056,1057,1060,1061,1064],{},"Missing installation, disabled executor and invalid binding make an authorized capability unavailable in the registry.\nAn incompatible contract version and a missing provider connection are not registry reasons.\nA start answers a stale version with ",[811,1058,1059],{},"contract_version_conflict",", and a request-level check answers a missing connection. Both read data the registry does not.\nDuplicate active bindings fail closed as ",[811,1062,1063],{},"invalid_binding",". The registry never selects the newest duplicate.\nUnsupported optional fields have request-level availability checks. Missing email support does not disable profile enrichment.",[834,1066,1067,1077],{},[837,1068,1069],{},[840,1070,1071,1075],{},[843,1072,1073],{},[811,1074,1024],{},[843,1076,848],{},[850,1078,1079,1089,1099,1108],{},[840,1080,1081,1086],{},[855,1082,1083],{},[811,1084,1085],{},"not_installed",[855,1087,1088],{},"No bound row of this organization names the ID",[840,1090,1091,1096],{},[855,1092,1093],{},[811,1094,1095],{},"inactive_executor",[855,1097,1098],{},"A bound row names it, and none is active",[840,1100,1101,1105],{},[855,1102,1103],{},[811,1104,1063],{},[855,1106,1107],{},"Metadata, scope contract or executor row does not validate; also two active bindings",[840,1109,1110,1115],{},[855,1111,1112],{},[811,1113,1114],{},"unauthorized",[855,1116,1117,1118,1120],{},"The caller does not hold ",[811,1119,981],{},", or does not hold every required scope",[807,1122,1123,1039,1125,1127],{},[811,1124,1085],{},[811,1126,1095],{}," are two answers on purpose.\nDisabling a definition clears its activation in the same database write, so a disabled executor leaves a bound inactive row.\nOne answer for both would send an operator to look for an installer fault that is not there.",[829,1129,1131],{"id":1130},"authorization-and-effects","Authorization and effects",[807,1133,1134,1135,1138],{},"Registry visibility is not a grant. Start rechecks tenant ownership, current rights, binding health, schema and policy.\n",[811,1136,1137],{},"RunManager"," mints the Principal and applies its existing admission, approval and budget rules.\nRequired tool scopes come from the published graph. Clients cannot submit or widen them.",[807,1140,1141,1144,1146,1147,1149],{},[1050,1142,1143],{},"The registry checks rights in two stages, because the required scopes live in the binding.",[811,1145,981],{}," is checked first, before any binding lookup. An actor that may start no run reads five ",[811,1148,1114],{}," records and learns nothing about what this tenant installed.\nThe published required scopes are checked second, for each capability whose binding resolved.\nBoth stages read the live role rights, so one role change reaches the registry and the admission checkpoint together.",[834,1151,1152,1161],{},[837,1153,1154],{},[840,1155,1156,1158],{},[843,1157,857],{},[843,1159,1160],{},"Required effect boundary",[850,1162,1163,1172,1181,1192,1201],{},[840,1164,1165,1169],{},[855,1166,1167],{},[811,1168,863],{},[855,1170,1171],{},"Granted discovery and identity reads; tenant-owned Run output only",[840,1173,1174,1178],{},[855,1175,1176],{},[811,1177,1035],{},[855,1179,1180],{},"Granted discovery and identity reads; company child scopes when used",[840,1182,1183,1187],{},[855,1184,1185],{},[811,1186,1032],{},[855,1188,1189,1191],{},[811,1190,1032],{}," write permission covers the shared provider workflow and its canonical Intelligence write",[840,1193,1194,1198],{},[855,1195,1196],{},[811,1197,1038],{},[855,1199,1200],{},"Published profile, write and email-child scopes; the whole graph is checked at admission",[840,1202,1203,1207],{},[855,1204,1205],{},[811,1206,1042],{},[855,1208,1209],{},"Published research, Intelligence and prospect scopes; no CRM or send scopes",[807,1211,1212,1213,1216],{},"Implementations register new tool names in ",[811,1214,1215],{},"ROLE_RIGHTS"," before publishing their executors.\nA capability ID is not a tool scope. A provider connection never grants a tool by itself.\nAn unavailable optional lane must fail before a paid call; it must not silently return a narrower result.\nRequired scopes are static for a published workflow, including both sides of a branch. Request fields never narrow that set.\nA profile request also needs the email tool scopes when its bound executor contains the email child.\nA profile-only executor can serve the initial installation; its email field requests are unavailable until the email executor is installed.\nAdding required scopes requires an explicit managed upgrade, not a silent binding refresh. Provider connection checks can remain field-dependent.",[829,1218,1220],{"id":1219},"shared-schema-rules","Shared schema rules",[807,1222,1223,1224,1226,1227,1230],{},"The tables below are normative schema definitions for version ",[811,1225,956],{},". Implementation tickets encode them as JSON Schema and typed models.\nAll objects reject unknown fields. Optional fields are omitted, unless a row explicitly permits ",[811,1228,1229],{},"null",".\nStrings are nonempty and at most 1,000 characters. URLs are at most 2,048 characters; domains are at most 253.\nIDs use UUID format where specified. Counts are integers. Booleans do not count as integers.\nFilter lists contain 1 to 20 unique values. Unsupported filters or enum values fail validation before provider work.",[807,1232,1233,1234,1237,1238,1241,1242,1245],{},"Every start uses ",[811,1235,1236],{},"{contract_version: 1, input: \u003Ccapability input>}"," and an ",[811,1239,1240],{},"Idempotency-Key"," header.\nThe header contains 1 to 255 characters. The CLI requires the same key.\nThe server records a digest of the normalized capability ID, version and input with the admitted Run.\nThe same tenant, caller, source and key return the same Run. A changed request under that key returns ",[811,1243,1244],{},"idempotency_conflict",".\nThe selected binding and contract stay fixed for that admitted Run, even if an upgrade occurs before a retry.\nRead authorization still applies to a replay. Retry does not start or charge for a second Run.",[1247,1248,1250],"h3",{"id":1249},"cross-field-rule-projection","Cross-field rule projection",[807,1252,1253],{},"ENG-2328 owns this rule. The start endpoint validates a body against the published JSON Schema and nothing else.\nA rule that lives only in a typed model therefore admits input the Run then fails on, after it spent an admission and a Run row.\nEvery rule a schema can express must be published. A rule a schema cannot express stays at execution time.",[807,1255,1256,1259],{},[1050,1257,1258],{},"The published schema owns these."," Each one is structural, so JSON Schema states it exactly.",[834,1261,1262,1271],{},[837,1263,1264],{},[840,1265,1266,1268],{},[843,1267,857],{},[843,1269,1270],{},"Rule",[850,1272,1273,1295,1307,1323,1337,1355],{},[840,1274,1275,1279],{},[855,1276,1277],{},[811,1278,863],{},[855,1280,1281,1282,1285,1286,1288,1289,1291,1292,1294],{},"The ",[811,1283,1284],{},"supplied"," source requires ",[811,1287,36],{},". ",[811,1290,36],{}," requires the ",[811,1293,1284],{}," source.",[840,1296,1297,1301],{},[855,1298,1299],{},[811,1300,863],{},[855,1302,1281,1303,1306],{},[811,1304,1305],{},"explorium"," source requires one filter at least.",[840,1308,1309,1313],{},[855,1310,1311],{},[811,1312,1035],{},[855,1314,1281,1315,1285,1317,1288,1319,1291,1321,1294],{},[811,1316,1284],{},[811,1318,119],{},[811,1320,119],{},[811,1322,1284],{},[840,1324,1325,1329],{},[855,1326,1327],{},[811,1328,1035],{},[855,1330,1281,1331,1285,1333,1336],{},[811,1332,1305],{},[811,1334,1335],{},"company_scope",".",[840,1338,1339,1345],{},[855,1340,1341,937,1343],{},[811,1342,1032],{},[811,1344,1038],{},[855,1346,1281,1347,1350,1351,1354],{},[811,1348,1349],{},"basic"," preset limits ",[811,1352,1353],{},"fields"," to the basic set.",[840,1356,1357,1361],{},[855,1358,1359],{},[811,1360,1042],{},[855,1362,1363,1364,1367],{},"Each ",[811,1365,1366],{},"source"," value carries its own fields, and no other. A company reference names exactly one identity.",[807,1369,1370,1371,1374,1375,937,1378,1381,1382,1385,1386,1389,1390,1393],{},"A projection is one ",[811,1372,1373],{},"allOf"," entry with ",[811,1376,1377],{},"if",[811,1379,1380],{},"then"," and an optional ",[811,1383,1384],{},"else",".\nThe negative direction writes ",[811,1387,1388],{},"{\"\u003Cfield>\": {\"not\": {}}}"," and never a root ",[811,1391,1392],{},"not",".\nBoth refuse the same input. Only the first reports the field path design case ST08 asks for.",[807,1395,1396,1399],{},[1050,1397,1398],{},"Execution time owns these."," JSON Schema cannot state them, and a projection would refuse legal input.",[834,1401,1402,1411],{},[837,1403,1404],{},[840,1405,1406,1408],{},[843,1407,1270],{},[843,1409,1410],{},"Why a schema cannot hold it",[850,1412,1413,1427,1437],{},[840,1414,1415,1420],{},[855,1416,1281,1417,1419],{},[811,1418,1305],{}," industry belongs to the provider vocabulary",[855,1421,1422,1423,1426],{},"523 values, and the check casefolds. An ",[811,1424,1425],{},"enum"," compares exact case, so it would refuse a legal spelling.",[840,1428,1429,1434],{},[855,1430,1281,1431,1433],{},[811,1432,1305],{}," department and seniority belong to their vocabularies",[855,1435,1436],{},"The same casefold rule, over 29 and 17 values.",[840,1438,1439,1442],{},[855,1440,1441],{},"A persona or filter list holds no case-duplicate value",[855,1443,1444,1447,1448,1451,1452,1455],{},[811,1445,1446],{},"uniqueItems"," compares exact case. It accepts ",[811,1449,1450],{},"CEO"," beside ",[811,1453,1454],{},"ceo",", and the model does not.",[807,1457,1458],{},"Do not project a rule from the second table. A start that carries one of those values is admitted, and the Run reports the refusal.\nRead the second table before you file a schema gap. The gap may be deliberate.",[807,1460,1461,1464,1465,1467,1468,1471],{},[1050,1462,1463],{},"A published schema change always raises the contract version."," The installer compares the whole binding.\nA schema edit under an unchanged ",[811,1466,950],{}," makes a provisioned tenant report ",[811,1469,1470],{},"invalid",", and that tenant cannot recover.\nThe upgrade refuses for the same reason, a rollback to the only released revision writes nothing, and a database trigger refuses both a delete and a binding update on a bound row.\nThe tenant then serves the old schema for as long as it exists.",[807,1473,1474],{},"So a schema edit takes three steps together:",[1476,1477,1478,1490,1497],"ol",{},[1479,1480,1481,1482,1485,1486,1489],"li",{},"Raise the capability's number in ",[811,1483,1484],{},"CONTRACT_VERSIONS"," (",[811,1487,1488],{},"ac-python-api src\u002Fagentic\u002Fshared\u002Fcapabilities.py","). It is the one place any reader compares against.",[1479,1491,1492,1493,1496],{},"Add a node revision in ",[811,1494,1495],{},"capabilities\u002Fprovisioning.py"," to carry the new binding, and bump every node that references it.",[1479,1498,1499,1500,1039,1503,1506,1507,1510],{},"Re-record ",[811,1501,1502],{},"RELEASED_NODE_DIGESTS",[811,1504,1505],{},"RELEASED_BINDING_DIGESTS"," in ",[811,1508,1509],{},"tests\u002Fagentic\u002Fcapabilities\u002Ftest_provisioning.py",". The binding table names the capability whose contract moved.",[807,1512,1513,1514,1517,1518,1521,1522,1524],{},"An operator then runs ",[811,1515,1516],{},"scripts\u002Freconcile_capabilities.py --upgrade \u003Ccapability> --apply",", and the tenant reports ",[811,1519,1520],{},"upgraded",".\nA client that still names the old version reads ",[811,1523,1059],{},", which is design case ST27.",[807,1526,1527,1528,937,1530,1039,1532,1534],{},"ENG-2328 raised ",[811,1529,863],{},[811,1531,1035],{},[811,1533,1042],{}," to version 2.",[1247,1536,1538],{"id":1537},"capability-start-identity","Capability start identity",[807,1540,1541],{},"ENG-2276 owns this rule for the shared start service and RunManager.\nThe registry and Run capability fields already exist on runtime trunk. Reuse both.",[807,1543,1544],{},"The key namespace includes the actor kind, actor ID, source and a capability-start prefix.\nThe tenant remains the database uniqueness scope. Do not include the capability ID or request digest in the key.\nThus, the same key with a different capability conflicts. Generic definition starts use a separate namespace.",[807,1546,1547,1548,1039,1550,1553,1554,1557,1558,1560,1561,1336],{},"Normalize the request as parsed JSON with sorted object keys, compact separators and UTF-8 text.\nPreserve arrays, strings, parsed numeric types and omitted fields. Reject non-finite numbers and invalid Unicode.\nParsed ",[811,1549,956],{},[811,1551,1552],{},"1.0"," differ. JSON parsing already equates ",[811,1555,1556],{},"1e0"," with ",[811,1559,1552],{},"; source text spelling is not part of the digest.\nDo not insert schema defaults, trim identities or apply product transformations at this boundary.\nAn omitted default and an explicit value are different requests. Capability executors own their semantic normalization.\nThe digest includes the capability ID, contract version and input. Record digest format version ",[811,1562,956],{},[807,1564,1565,1566,1017,1569,1571],{},"Store the digest metadata in the frozen Run snapshot in the same insert as the Run and its start key.\nDo not add a claim table, separate digest write, lease or process-local lock.\nOnly RunManager inserts the Run. The unique tenant\u002Fkey constraint selects the concurrent winner.\nThe losing request compares its digest with the stored digest before it returns ",[811,1567,1568],{},"duplicate",[811,1570,1244],{},".\nA missing or malformed stored digest fails closed; it never starts replacement work.",[807,1573,1574],{},"Read an existing key before resolving the current binding or checking current admission.\nAn authenticated caller can replay its own tenant-visible Run after an upgrade, disable, budget change or scope removal.\nThis is a read of the stored Run. It does not prove that admission completed.\nA fresh key requires scopes, schema, binding and policy checks.\nThe replay does not repeat admission or dispatch. The existing reaper repairs a lost dispatch after admission completes.",[807,1576,1577,1578,937,1581,1584,1585,1588,1589,1592],{},"Insert a capability start in the existing temporary approval hold: ",[811,1579,1580],{},"waiting",[811,1582,1583],{},"waiting_on: approval",", and a null approval reference.\nSet the hold expiry to insertion time. No human approval exists until policy requests one and its row is written.\nOn allow, RunManager conditionally releases this hold to ",[811,1586,1587],{},"queued",", clears the wait fields, and dispatches.\nThe release requires the same null-reference admission hold. It cannot release a human approval or a terminal Run.\nOn deny, RunManager fails the held Run. On require-approval, it uses the existing approval creation and dispatch path.\nA crash before the decision or release leaves an undispatched hold. The existing wait recovery ends it with ",[811,1590,1591],{},"wait_abandoned",".\nThis hold prevents the queued-run recovery path from executing work whose admission never completed.\nA crash before insertion claims nothing. A crash after insertion leaves the key and digest together.",[807,1594,1595],{},"A fresh start checks the selected executor again in RunManager before insertion.\nIts active state, capability ID, version and required scopes must still match.\nRights use the existing shared RoleRights cache, with a maximum age of 30 seconds.\nA repeated check does not promise immediate revocation. A scope absent from the observed rights refuses before insertion.\nA binding change before that check refuses the start. A later change does not rewrite the selected immutable executor.\nThe start and a concurrent upgrade can overlap; this endpoint does not add a transaction across definition reads and Run insertion.",[807,1597,1598],{},"Validate input against the selected published Draft 2020-12 schema, including local references and declared formats.\nDo not fetch remote schema references. Return a bounded list of field paths without echoing the input.\nThe envelope rejects extra fields and requires a positive integer version and an input object.\nMeasure the input with the existing 32 KiB boundary before schema work. Oversized input returns 413.",[807,1600,1601],{},"Reference ownership and provider availability remain with each capability's input resolver and executor.\nThis shared endpoint validates the published schema; it does not add five product-specific database lookup paths.\nThose resolvers must refuse foreign references before provider work, as specified in their own tickets.",[1247,1603,1605],{"id":1604},"stable-references","Stable references",[807,1607,1608,1039,1611,1614],{},[811,1609,1610],{},"CompanyRef",[811,1612,1613],{},"PersonRef"," are tagged unions. Each value has exactly the fields for its tag.",[834,1616,1617,1626],{},[837,1618,1619],{},[840,1620,1621,1623],{},[843,1622,21],{},[843,1624,1625],{},"Shape",[850,1627,1628,1638,1648,1658,1668,1678,1688],{},[840,1629,1630,1633],{},[855,1631,1632],{},"Canonical company",[855,1634,1635],{},[811,1636,1637],{},"{kind: \"intel_company\", id: UUID}",[840,1639,1640,1643],{},[855,1641,1642],{},"Company domain",[855,1644,1645],{},[811,1646,1647],{},"{kind: \"domain\", value: string}",[840,1649,1650,1653],{},[855,1651,1652],{},"Domainless company",[855,1654,1655],{},[811,1656,1657],{},"{kind: \"company_linkedin\", value: URL}",[840,1659,1660,1663],{},[855,1661,1662],{},"Canonical person",[855,1664,1665],{},[811,1666,1667],{},"{kind: \"intel_person\", id: UUID}",[840,1669,1670,1673],{},[855,1671,1672],{},"Person profile",[855,1674,1675],{},[811,1676,1677],{},"{kind: \"person_linkedin\", value: URL}",[840,1679,1680,1683],{},[855,1681,1682],{},"Search row",[855,1684,1685],{},[811,1686,1687],{},"{kind: \"search_result\", run_id: UUID, result_id: UUID}",[840,1689,1690,1693],{},[855,1691,1692],{},"CRM person input",[855,1694,1695,1698],{},[811,1696,1697],{},"{kind: \"crm_person\", id: UUID}","; People Enrich adapter only",[807,1700,1701,1702,1705,1706,1709],{},"The search-row tag resolves only within the caller's organization and to the expected entity type.\nThe stored row owns ",[811,1703,1704],{},"result_id","; retries and pagination reuse it. A new search has new result IDs.\nThe row retains a normalized domain or LinkedIn identity and an optional canonical Intelligence UUID.\nSearch need not create a canonical record to return a stable identity.\nIf the source Run or row is unavailable, return ",[811,1707,1708],{},"stale_reference",". Never reconstruct it from client display text.",[807,1711,1712,1713,1716],{},"Normalize identities through shared identity functions. Do not strip meaningful LinkedIn path segments or merge companies by display name.\nCompany domain is primary; company LinkedIn is the fallback when no domain is known.\nA person requires a normalized individual LinkedIn URL in V1. Name plus company is unresolved, not a guessed identity.\nIf supplied keys resolve to different canonical records, return ",[811,1714,1715],{},"identity_conflict",". Do not merge the records.",[807,1718,1719],{},"CRM, prospect, list, saved-search and Run references are tenant-owned. Resolve their ownership before reading their contents.\nThe canonical Intelligence cache is global. Only allowed public facts enter that cache.\nCRM notes, private list membership, scores, prompts and tenant selections never enter global Intelligence.",[1247,1721,1723],{"id":1722},"superadmin-company-identity-writes","Superadmin company identity writes",[807,1725,1726,1727,1730,1731,1734,1735,1738,1739,1742,1743,937,1746,1039,1749,1752],{},"The superadmin company service stores ",[811,1728,1729],{},"intel_companies.linkedin_url"," as ",[811,1732,1733],{},"linkedin.com\u002F\u003Ckind>\u002F\u003Cslug>",".\nOn create and update, apply ",[811,1736,1737],{},"linkedin_organization_key"," after ",[811,1740,1741],{},"clean_writes"," and before any database call.\nPreserve ",[811,1744,1745],{},"\u002Fcompany\u002F",[811,1747,1748],{},"\u002Fschool\u002F",[811,1750,1751],{},"\u002Fshowcase\u002F"," as distinct identities.\nUse the shared parser's case, locale, query, fragment and page-subpath normalization.\nA value already in match-key form stays unchanged.",[807,1754,1755,1756,1759],{},"Omitted, null and blank values stay absent after cleaning. They never clear an existing LinkedIn key.\nA create still requires a name, domain or valid LinkedIn key. An empty update keeps its existing validation error.\nRefuse a nonblank value when the parser returns no organization key or raises ",[811,1757,1758],{},"ValueError",".\nReturn the existing HTTP 400 validation error before any database write or cache invalidation.\nKeep successful-write cache invalidation and the existing HTTP 409 mapping for unique-key conflicts.\nThe unique index resolves concurrent collisions on stored match keys; do not add a lookup before the write.",[807,1761,1762],{},"ENG-2311 owns this write contract and scenarios IW01 to IW14.\nENG-2310 owns legacy-row repair, including collisions with values still stored in display form.\nThis write contract changes no CRM display form, shared parser, endpoint schema or database schema.",[1247,1764,1766],{"id":1765},"intelligence-identity-repair","Intelligence identity repair",[807,1768,1769,1770,1039,1773,1775,1776,1778,1779,1782],{},"ENG-2310 repairs ",[811,1771,1772],{},"intel_people.linkedin_url",[811,1774,1729],{},".\nThe stored match key is ",[811,1777,1733],{},". CRM fields keep their display URLs.\n",[811,1780,1781],{},"canonicalize_identity"," keeps its CRM display contract. Intelligence writers use the existing key helpers.\nReads by LinkedIn require the match key. Reads by UUID and company domain remain available.",[807,1784,1785,1786,1789,1790,1793,1794,937,1796,1017,1799,1802,1803,1806],{},"This migration converts stored identity forms. It does not add a URL parser to the database.\nAccept an exact match key or the exact display prefix ",[811,1787,1788],{},"https:\u002F\u002Fwww.linkedin.com\u002F",".\nPeople use ",[811,1791,1792],{},"in",". Companies use ",[811,1795,321],{},[811,1797,1798],{},"school",[811,1800,1801],{},"showcase","; each kind remains distinct.\nThe slug uses lowercase ASCII URI path characters: ",[811,1804,1805],{},"[a-z0-9_%.'~!$&()*+,=:@-]+",".\nKeep percent escapes as stored. Do not decode them or resolve aliases.\nPreserve null company URLs. Stop the transaction for any other value, including blank text or a wrong kind.\nThe operator must inspect unexpected values before another attempt. Do not clear or guess their identities.",[807,1808,1809],{},"Before a write, count both tables in local, staging and production.\nRecord totals, display forms, match keys, nulls, unsupported values and collision groups.\nRefresh the target counts under a write lock when the migration runs.\nUse one transaction and lock both intelligence tables in the same order.\nUse a short lock timeout and a bounded statement timeout. A timeout rolls back the complete repair.\nOrdinary reads can continue. Concurrent writes wait until the transaction ends.\nDeploy the person and company writer fixes to the target before applying the repair there.",[807,1811,1812,1813,1816],{},"Build one set that includes every supported row, including rows already stored as match keys.\nGroup by table and match key. Company groups include rows with and without domains.\nA group with one row can change its display URL to the match key.\nA group with two or more rows keeps every row unchanged. Do not choose a winner or merge facts.\nRecord all member UUIDs, in sorted order, in ",[811,1814,1815],{},"firmographics_linkedin_collisions"," with a null organization.\nUse the match key as the report's canonical value. This separates the report from earlier display-form reports.\nRetain the report with service-role access only. Revoke all table grants from PUBLIC, anon and authenticated roles. Do not insert the same group snapshot twice on a repeat run.",[807,1818,1819,1820,1823],{},"Preserve row UUIDs, facts, provenance and freshness dates. The existing update trigger can advance ",[811,1821,1822],{},"updated_at"," on changed rows.\nDo not update a row that already holds the key. Do not change CRM rows, indexes, API contracts or cached Run results.\nCollision rows can remain unavailable through LinkedIn reads; the retained report makes that limitation explicit.\nA failed transaction needs no reverse migration. After commit, use the normal recovery process; do not reverse newer writes.\nProve the repair with rollback-based database tests and a PeopleIntelStore write followed by a people.search read.",[1247,1825,1827],{"id":1826},"shared-results","Shared results",[807,1829,1830,1831,1336],{},"Company and People capabilities return the following closed envelope.\nSignals keeps its ",[824,1832,1834],{"href":1833},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fsignals-search#result-shape","existing product output",[834,1836,1837,1845],{},[837,1838,1839],{},[840,1840,1841,1843],{},[843,1842,914],{},[843,1844,1625],{},[850,1846,1847,1859,1869,1888,1902],{},[840,1848,1849,1856],{},[855,1850,1851,937,1854],{},[811,1852,1853],{},"capability_id",[811,1855,950],{},[855,1857,1858],{},"The admitted stable ID and version",[840,1860,1861,1866],{},[855,1862,1863],{},[811,1864,1865],{},"items",[855,1867,1868],{},"Up to 100 typed search or enrichment rows",[840,1870,1871,1876],{},[855,1872,1873],{},[811,1874,1875],{},"outcome",[855,1877,1878,937,1881,1017,1884,1887],{},[811,1879,1880],{},"complete",[811,1882,1883],{},"partial",[811,1885,1886],{},"empty","; this is not a Run status",[840,1889,1890,1895],{},[855,1891,1892],{},[811,1893,1894],{},"diagnostics",[855,1896,1897,1898,1901],{},"Up to 100 ",[811,1899,1900],{},"{item_index: integer or null, reason: string}"," records",[840,1903,1904,1908],{},[855,1905,1906],{},[811,1907,283],{},[855,1909,1910],{},[811,1911,1912],{},"{cost_cents: nonnegative number, cost_kind: \"estimated\" or \"settled\", provider_calls: nonnegative integer}",[807,1914,1915,1918,1919,937,1922,937,1924,937,1926,937,1929,937,1932,937,1935,937,1938,937,1941,937,1944,937,1947,1017,1950,1953,1954,1957],{},[811,1916,1917],{},"diagnostics.reason"," is one of ",[811,1920,1921],{},"unresolved",[811,1923,1715],{},[811,1925,1708],{},[811,1927,1928],{},"filter_mismatch",[811,1930,1931],{},"provider_failed",[811,1933,1934],{},"deadline_reached",[811,1936,1937],{},"budget_reached",[811,1939,1940],{},"scope_truncated",[811,1942,1943],{},"output_truncated",[811,1945,1946],{},"not_found",[811,1948,1949],{},"no_matches",[811,1951,1952],{},"unknown_filter_value",".\nThe response reports omitted diagnostic counts separately as ",[811,1955,1956],{},"diagnostics_omitted",", a required nonnegative integer.\nForeign tenant references fail the whole request with a non-disclosing error, before any work starts.\nOther item failures preserve valid items and caller order. Duplicate inputs share one work item and retain their input indexes.\nUsage reads the canonical Run meter. Parent summaries include child usage once and never create a second charge.",[807,1959,1960,1961,937,1963,1966,1967,937,1970,937,1973,1039,1976,1979,1980,1982,1983,1985,1986,1988,1989,1991,1992,1995,1996,1039,1999,2002,2003,2005,2006,937,2008,1017,2010,2012],{},"Search rows contain ",[811,1962,1704],{},[811,1964,1965],{},"ref",", nullable ",[811,1968,1969],{},"canonical_id",[811,1971,1972],{},"display",[811,1974,1975],{},"evidence",[811,1977,1978],{},"input_indexes",".\n",[811,1981,1965],{}," is a normalized identity tag. ",[811,1984,1978],{}," is an integer array, empty for discovered rows.\n",[811,1987,1972],{}," permits only the fields in the relevant enrichment field table, excluding email and verification data.\nPeople Search adds the discovery-only person fields, which no enrichment preset can supply. Its own section lists them.\nSearch displays only values already returned by discovery or an allowed cache read. It makes no extra enrichment calls.\n",[811,1990,1975],{}," holds at most three ",[811,1993,1994],{},"{source, provider_ref, url}"," records; ",[811,1997,1998],{},"provider_ref",[811,2000,2001],{},"url"," can be null.\n",[811,2004,1366],{}," is ",[811,2007,1284],{},[811,2009,1305],{},[811,2011,38],{},". Provider refs are observations, not entity keys.",[807,2014,2015,2016,2019,2020,2023,2024,2027,2028,2031,2032,2035,2036,2038,2039,1017,2041,2043],{},"Search also returns ",[811,2017,2018],{},"funnel: {candidates, duplicates, unresolved, excluded, returned}"," with nonnegative integer counts.\n",[811,2021,2022],{},"per_source"," maps each requested source to ",[811,2025,2026],{},"{status: \"complete\" or \"partial\" or \"failed\", candidates: integer}",".\nPeople Search also returns ",[811,2029,2030],{},"per_company",", with one ",[811,2033,2034],{},"{ref, candidates, returned, reason}"," row for each attempted company.\nIts nullable ",[811,2037,1024],{}," uses the diagnostic enum. An unattempted company has an explicit ",[811,2040,1934],{},[811,2042,1937],{}," row.",[807,2045,2046,2047,2049,2050,1039,2053,2055,2056,2058],{},"All outputs obey the runtime payload limit. Reduce optional evidence first and report ",[811,2048,1943],{},".\nNever cut an identity, JSON value or field-state record. If the required result cannot fit, fail with the existing payload error.\nA valid empty search succeeds with ",[811,2051,2052],{},"outcome: empty",[811,2054,1949],{},". Total provider failure fails the Run; it is not an empty success.\nUsable results with an item or source failure return ",[811,2057,1883],{},". Invalid input creates no Run.",[829,2060,2061],{"id":50},"Company Search",[834,2063,2064,2073],{},[837,2065,2066],{},[840,2067,2068,2071],{},[843,2069,2070],{},"Input",[843,2072,917],{},[850,2074,2075,2090,2102,2112],{},[840,2076,2077,2082],{},[855,2078,2079],{},[811,2080,2081],{},"sources",[855,2083,2084,2085,937,2087,2089],{},"Required unique list from ",[811,2086,1284],{},[811,2088,1305],{},"; no automatic source expansion",[840,2091,2092,2096],{},[855,2093,2094],{},[811,2095,36],{},[855,2097,2098,2099,2101],{},"1 to 100 CompanyRefs when ",[811,2100,1284],{}," is selected; absent otherwise",[840,2103,2104,2109],{},[855,2105,2106],{},[811,2107,2108],{},"filters",[855,2110,2111],{},"Optional closed object defined below; at least one filter for provider discovery",[840,2113,2114,2119],{},[855,2115,2116],{},[811,2117,2118],{},"target_count",[855,2120,2121],{},"Default 50; range 1 to 100",[807,2123,2124,2125,937,2128,937,2131,1039,2134,1979,2137,2139,2140,2142,2143,937,2146,937,2149,1039,2152,2155,2156,1336],{},"V1 filters are ",[811,2126,2127],{},"country_codes",[811,2129,2130],{},"industries",[811,2132,2133],{},"employee_bands",[811,2135,2136],{},"revenue_bands",[811,2138,2127],{}," uses ISO alpha-2. ",[811,2141,2130],{}," uses LinkedIn industry names from the adapter's versioned vocabulary.\nEmployee and revenue bands use published adapter enums, never guessed numeric conversions.\nThe adapter maps these fields to Explorium ",[811,2144,2145],{},"country_code",[811,2147,2148],{},"linkedin_category",[811,2150,2151],{},"company_size",[811,2153,2154],{},"company_revenue",".\nSee ",[824,2157,2161],{"href":2158,"rel":2159},"https:\u002F\u002Fdevelopers.explorium.ai\u002Freference\u002Fbusinesses\u002Ffetch_businesses",[2160],"nofollow","Explorium business filters",[807,2163,2164,2165,2167],{},"Both sources feed the same identity resolution, deduplication and gates.\nMerge duplicate observations before gating. Retain bounded evidence from both sources.\nKeep an unknown field and mark it unknown. Drop an explicit contradiction with ",[811,2166,1928],{},".\nNo score, enrichment, CRM write or list write occurs.",[807,2169,2170],{},"Technology, free-text thesis, funding-event, city and signals-store filters are deferred for direct Company Search.\nDo not silently map these requests to a different query. Signals research retains its own broader brief contract.\nExplorium access is a deployment prerequisite; public API documentation does not prove an account's entitlement.",[1247,2172,2174],{"id":2173},"supplied-list-core","Supplied-list core",[807,2176,2177,2178,2181,2182,2185,2186,2188],{},"The retained ",[811,2179,2180],{},"company.search_supplied"," tool accepts exactly ",[811,2183,2184],{},"sources: [\"supplied\"]"," and remains unmetered.\nThe provider-capable workflow uses a separate ",[811,2187,863],{}," tool and grant. Republish through the definition lifecycle.\nA published supplied-only grant must never authorize provider spend.\nThe product registry and start routes remain with ENG-2275 and ENG-2276.\nThe bundle uses the existing definition lifecycle. It does not install itself into a tenant.",[807,2190,2191,2192,2194,2195,2197],{},"The core accepts canonical company, domain, company LinkedIn and company search-row references.\nA missing or inaccessible source Run fails the request with the same non-disclosing ",[811,2193,1708],{}," error.\nCheck every source Run before any company cache read. A missing row in an accessible Run produces an item diagnostic.\nRead only frozen ",[811,2196,863],{}," output. Do not accept person rows or client display fields.",[807,2199,2200,2201,2203,2204,2206,2207,937,2209,1039,2211,2213,2214,2216],{},"A valid domain or organization LinkedIn URL remains selectable when Intelligence has no match.\nA canonical UUID with no record produces ",[811,2202,1946],{},". A record with no usable domain or LinkedIn URL produces ",[811,2205,1921],{},".\nUse shared normalization. Preserve ",[811,2208,1745],{},[811,2210,1748],{},[811,2212,1751],{}," as distinct organization identities.\nIf a cache observation has keys that identify different canonical records, exclude it with ",[811,2215,1715],{},".\nNever merge two canonical UUIDs through a shared domain or LinkedIn key.",[807,2218,2219,2220,1017,2222,2224],{},"Merge observations before filters. Domain is primary; LinkedIn connects a domainless observation only when the identity is unambiguous.\nRetain first-input order and all duplicate input indexes. Use the first nonempty display value in that order.\nEvaluate all observed filter values: any explicit contradiction excludes the group. Missing values alone do not exclude it.\nUse OR within each filter list and AND between filter fields. Compare industry names without case differences.\nThe supplied-only path accepts bounded industry names. Provider requests validate names against the versioned Explorium vocabulary.\nCompare names without case differences. Do not guess aliases or request live autocomplete during validation.\nUse ISO alpha-2 country codes and the published Explorium employee and revenue band tokens.\nNever infer a band from an exact count, revenue amount or currency. An absent or unrecognized observed band is unknown.\nEmit one ",[811,2221,1928],{},[811,2223,1952],{}," diagnostic per group, using its first input index.",[807,2226,2227,2228,2230,2231,2233,2234,1039,2236,1336],{},"Return the first ",[811,2229,2118],{}," retained groups. Do not refill, score or enrich them.\nThe funnel counts input observations, merged duplicates, unresolved observations, excluded groups and returned groups.\nThe target can omit valid groups, so the funnel fields are not a partition of the input count.\nAn unknown filter value does not make a result partial. Item identity failures do.\nAny item identity failure makes the outcome ",[811,2232,1883],{},", even when no item remains after filters.\nOtherwise, if no group survives the filters, return ",[811,2235,1886],{},[811,2237,1949],{},[807,2239,2240,2241,2244],{},"Derive each result UUID from the current Run UUID and normalized identity. Replay preserves it; a new Run changes it.\nThe workflow stores its capability envelope under ",[811,2242,2243],{},"RunResult.output.company_search",".\nThe supplied-only lane has zero provider calls and zero settled cost. It creates no usage charge.\nKeep at most 100 diagnostics and report the exact omitted count.",[807,2246,2247,2248,1039,2250,2252,2253,2256],{},"Reserve space for the Run result envelope below the existing 32,768-byte limit.\nRemove optional evidence from the last row first, then optional display fields in stable order.\nReport ",[811,2249,1943],{},[811,2251,1883],{}," when this removes data. Keep every selected identity and input index intact.\nIf the required fields still exceed the limit, fail with ",[811,2254,2255],{},"payload_too_large",". Never return a malformed or silently cut result.",[1247,2258,2260],{"id":2259},"explorium-execution","Explorium execution",[807,2262,2263,2264,1506,2267,2270,2271,2274,2275,2278,2279,2281,2282,2284,2285,2288],{},"The adapter calls ",[811,2265,2266],{},"POST \u002Fv1\u002Fbusinesses",[811,2268,2269],{},"full"," mode. It makes no match or enrichment call.\nUse numbered pages with ",[811,2272,2273],{},"size = target_count"," and fixed ",[811,2276,2277],{},"page_size = min(20, target_count)",".\nStart at page one. Do not mix page and cursor pagination or change the page size during collection.\nCollect at most ",[811,2280,2118],{}," raw provider rows before merging and gates. This makes the cost predictable.\nThis collection can return fewer companies after duplicates or contradictions. Do not fetch replacement rows.\nSupplied observations come first in input order. Provider observations follow in page and row order, regardless of source selection order.\nProvider-only rows have empty ",[811,2283,1978],{},"; provider diagnostics use a null ",[811,2286,2287],{},"item_index",".\nValidate all saved Run references before the first provider request. Read only exact public company identities from the cache.",[807,2290,2291,2292,1039,2295,2298,2299,1039,2302,2305],{},"Map ",[811,2293,2294],{},"domain",[811,2296,2297],{},"linkedin_profile"," to shared identities. A provider ID is evidence, never a canonical ID.\nMap ",[811,2300,2301],{},"number_of_employees_range",[811,2303,2304],{},"yearly_revenue_range"," directly to band tokens.\nMap an exact ISO country name to its alpha-2 code. Unrecognized country names remain unknown.\nRead industry only when the response supplies a LinkedIn industry field. Never copy the requested industry into observed facts.\nA name-only row is unresolved. Invalid optional facts remain absent. Valid rows survive malformed sibling rows.",[807,2307,2308],{},"Use one request at a time. The lane permits five pages and ten attempts, with at most 100 rows per page and 500 candidates.\nThe smaller raw collection limit above applies first. Each attempt has a ten-second deadline.\nThe lane has a 60-second deadline, reduced by the root deadline. Stop provider calls 20 seconds before that deadline.\nReserve five seconds each for the last meter write, final meter read, cache reads and output.\nEach provider attempt has an absolute ten-second deadline. Do not start another attempt after the provider deadline.\nCheck the canonical root meter before each attempt. Require enough remaining budget for the maximum page charge.\nThe Company Search runtime uses four US cents per credit and one credit per fetched business.\nThis estimate is below the current public Lite price. Verify account pricing before enabling this executor.\nThe workflow default is 400 cents. A smaller root budget can stop collection before the first page.\nAccount-specific pricing and licensed access remain deployment prerequisites.",[807,2310,2311,2312,2315],{},"Request ",[811,2313,2314],{},"credit-usage: true",". Record one canonical usage row for each attempt that returns control, including uncertain timeout charges.\nUse reported nonnegative credit usage when valid. Otherwise record the maximum page estimate; do not report zero for an uncertain call.\nThe output reports estimated cents from the canonical root meter. It does not create another usage charge.\nA meter read or write failure fails the Run. Do not continue provider work when spend cannot be counted.\nDo not retry provider requests in V1. This avoids duplicate spend after a lost response and stays within the retry ceilings.\nMeter persistence retries remain owned by the canonical meter. A cancellation still propagates to the runtime.\nThe no-retry rule applies within one tool execution. Completed durable steps replay their stored result.\nAn interrupted step can repeat a paid call. A process stop before meter persistence can leave an unrecorded charge.\nThis adapter has no provider idempotency key or durable attempt recovery. It does not promise exactly-once provider spend.\nThe runtime bounds interrupted step retries. Operators reconcile uncertain charges through the provider account records.",[807,2317,2318,2319,2321,2322,2324,2325,1557,2327,937,2329,1017,2331,2333,2334,1979,2336,2338,2339,2342,2343,2345],{},"An empty successful page stops collection and retains observations from earlier pages.\nReturn ",[811,2320,1886],{}," only when no merged group survives and no identity failure, source failure or bound occurred.\nA failed provider request with no usable identity fails the Run, even if the supplied source was requested.\nA failed request with usable supplied or provider identities returns ",[811,2323,1883],{},"; gates can reduce those identities to zero output rows.\nA page, deadline or budget stop returns ",[811,2326,1883],{},[811,2328,1940],{},[811,2330,1934],{},[811,2332,1937],{},".\nThose stops can return zero rows and must not claim ",[811,2335,1949],{},[811,2337,2022],{}," contains only requested sources. Identity failures make the affected source partial.\nA provider transport or malformed-page failure is ",[811,2340,2341],{},"failed"," before any good page, and ",[811,2344,1883],{}," after a good page.\nPreserve the shared diagnostic and byte limits. A provider error never exposes a response body, API key or cursor.",[807,2347,2348,2349,2353,2354,2353,2359,2364,2365,1336],{},"Provider details: ",[824,2350,2352],{"href":2158,"rel":2351},[2160],"fetch schema",",\n",[824,2355,2358],{"href":2356,"rel":2357},"https:\u002F\u002Fdevelopers.explorium.ai\u002Freference\u002Fbusinesses\u002Fautocomplete\u002Flinkedin_categories",[2160],"industry vocabulary",[824,2360,2363],{"href":2361,"rel":2362},"https:\u002F\u002Fdevelopers.explorium.ai\u002Freference\u002Fcredits\u002Fper-call-credit-usage",[2160],"credit reporting",",\nand ",[824,2366,2369],{"href":2367,"rel":2368},"https:\u002F\u002Fwww.explorium.ai\u002Fpricing\u002F",[2160],"credit prices",[829,2371,2372],{"id":128},"People Search",[834,2374,2375,2383],{},[837,2376,2377],{},[840,2378,2379,2381],{},[843,2380,2070],{},[843,2382,917],{},[850,2384,2385,2397,2419,2430,2440],{},[840,2386,2387,2391],{},[855,2388,2389],{},[811,2390,2081],{},[855,2392,2084,2393,937,2395],{},[811,2394,1284],{},[811,2396,1305],{},[840,2398,2399,2403],{},[855,2400,2401],{},[811,2402,1335],{},[855,2404,2405,2406,1017,2409,2412,2413,2415,2416],{},"Exactly ",[811,2407,2408],{},"{companies: [CompanyRef]}",[811,2410,2411],{},"{company_search: \u003CCompany Search input>}","; optional when ",[811,2414,2081],{}," is exactly ",[811,2417,2418],{},"[\"supplied\"]",[840,2420,2421,2425],{},[855,2422,2423],{},[811,2424,119],{},[855,2426,2427,2428,2101],{},"1 to 100 PersonRefs when ",[811,2429,1284],{},[840,2431,2432,2437],{},[855,2433,2434],{},[811,2435,2436],{},"persona",[855,2438,2439],{},"Required object with at least one supported criterion",[840,2441,2442,2447],{},[855,2443,2444],{},[811,2445,2446],{},"target_per_company",[855,2448,2449],{},"Default 5; range 1 to 10; total output at most 100; the supplied-only lane ignores it",[807,2451,2452,2453,2455,2456,2458,2459,2461,2462,2464,2465,2467],{},"Known scope contains 1 to 20 companies. More than 20 explicit companies fails validation.\nA company-search brief can return more. Keep its first 20 deduplicated refs in result order and report ",[811,2454,1940],{},".\nThe scope child uses ",[811,2457,863],{}," without enrichment. Zero resolved companies starts no people source.\nA complete zero scope returns ",[811,2460,1886],{},". A partial zero scope returns ",[811,2463,1883],{},", without a ",[811,2466,1949],{}," claim.\nThe child mapping is published with the parent definition. The Front Door still makes one delegation.",[807,2469,2470,2471,937,2474,937,2477,1039,2480,2482,2483,937,2486,937,2489,2492,2493,2495,2496,1336],{},"Persona fields are ",[811,2472,2473],{},"titles",[811,2475,2476],{},"departments",[811,2478,2479],{},"seniority",[811,2481,2127],{},", each a bounded list.\nExplorium maps these to ",[811,2484,2485],{},"job_title",[811,2487,2488],{},"job_department",[811,2490,2491],{},"job_level"," and the person's ",[811,2494,2145],{},".\nResolve provider company IDs before querying people; ambiguous company matches remain unresolved.\nEmployer country does not substitute for person country. Related-title expansion is off in V1.\nSee ",[824,2497,2500],{"href":2498,"rel":2499},"https:\u002F\u002Fdevelopers.explorium.ai\u002Freference\u002Fprospects\u002Ffetch_prospects",[2160],"Explorium prospect filters",[807,2502,2503],{},"People need a LinkedIn identity even when a provider supplies its own ID.\nApply company and persona gates to observed fields. Keep unknown values with explicit diagnostics; never claim verified fit.\nReport companies that return no people. Do not let the first company consume the total result allowance.\nFill the output in company-scope order, one person for each company in each pass, and stop at 100 rows.\nWeb sources, signals-store sources, email lookup and profile enrichment are outside direct People Search V1.\nNo unofficial LinkedIn scraping adapter is part of this design.",[1247,2505,2507],{"id":2506},"company-brief-resolution","Company-brief resolution",[807,2509,2510,2511,2514,2515,2518,2519,2521],{},"ENG-2293 owns this composition. The request uses the full ",[811,2512,2513],{},"CompanyDiscoveryInput"," contract for ",[811,2516,2517],{},"company_search",".\nIt accepts supplied companies, Explorium filters, or both. A free-text string is not a company-search input.\nReject both scope forms, an empty scope object, explicit null, and unknown fields before child work.\nCheck supplied person source-Run access before company work, including requests whose company scope later resolves to zero.\nUse the existing non-disclosing ",[811,2520,1708],{}," refusal. This check reads no person cache facts.\nKeep the supplied-only tool and its grant unchanged. A composed definition requires all tools in its published graph, including company discovery.\nKnown refs and an omitted supplied-only scope skip the company child, but do not reduce that definition's required grants.",[807,2523,2524,2525,2527,2528,2531,2532,2535,2536,2539,2540,2542,2543,2546,2547,2550],{},"Resolve one active tenant ",[811,2526,863],{}," V1 binding when publishing the composition.\nReject missing, disabled, foreign, ambiguous or incompatible bindings before creating a draft.\nPublish the child definition ID in native ",[811,2529,2530],{},"subworkflow"," nodes directly under the People Search workflow.\nThe input DSL maps named fields and cannot forward a whole object or omit a missing reference.\nUse ",[811,2533,2534],{},"resolve-company-brief"," for supplied or mixed company sources, and ",[811,2537,2538],{},"discover-company-brief"," for Explorium only.\nThe source branch selects exactly one node. The Explorium-only node omits ",[811,2541,36],{},"; both forward normalized filters and target count.\nDo not add a wrapper workflow, custom child dispatcher or new retry loop.\nBranch nodes produce no shared output, and references cannot select an absent branch output.\nEach branch therefore validates the request and checks person source-Run access.\nThe brief branch then runs the company child. The known branch starts no child.\nA common ",[811,2544,2545],{},"people.search_scoped"," tool reads that completed child from durable storage only for a brief.\nMatch the trusted tenant, parent Run, source-selected fixed child node and frozen company capability attribution.\nUse the runtime's hashed workflow-step delivery key. A missing or incomplete child fails closed; the reader never starts work.\nThis explicit metered tool shares the people provider implementation. Its grant does not widen either existing search grant.\nIt skips discovery for zero scope and emits the common People Search envelope for every branch.\nThe Run snapshot freezes the child tree. An upgrade changes only new Runs.\nThe runtime owns child admission, parent\u002Froot lineage, cancellation, shared budget and the stable parent-Run\u002Fnode idempotency key.\nA failed or cancelled child stops the parent. A waiting child must finish before any people source starts.\nA succeeded child with ",[811,2548,2549],{},"outcome: partial"," supplies its usable scope; it is not a failed Run.",[807,2552,2553,2554,2556,2557,2559,2560,2562],{},"Validate the complete ",[811,2555,2517],{}," envelope before mapping refs. Missing, malformed or oversized output fails closed.\nKeep canonical company refs when ",[811,2558,1969],{}," exists; otherwise keep the normalized identity ref from the child row.\nDeduplicate canonical IDs and normalized identities in child result order before applying the 20-company ceiling.\nReject duplicate result IDs and conflicting canonical IDs for one normalized identity. Do not guess an identity from display fields.\nKeep the first 20 distinct refs. Add one scope-level ",[811,2561,1940],{}," diagnostic when more refs exist.\nDo not refill the scope, repeat the company search or enrich companies.\nEvery selected people source receives the same bounded refs.\nThe supplied lane still reports unknown employer identity when only the cached employer name exists.",[807,2564,2565,2566,1039,2568,2570,2571,2574,2575,2578,2579,2582],{},"A resolved empty scope skips supplied reads and provider discovery. This differs from an omitted supplied-only scope.\nPreserve a partial child outcome, including when it has no rows. A complete zero scope yields an empty people envelope.\nKeep people funnel, ",[811,2567,2022],{},[811,2569,2030],{}," counts about people only. Skipped sources have zero candidates.\nCopy child diagnostic reasons with ",[811,2572,2573],{},"item_index: null","; a company index must never identify a person.\nPreserve omitted diagnostic counts and reserve space for the scope truncation reason within the 100-diagnostic limit.\nRead cumulative cost once from the canonical root meter after composition, including empty and supplied-only branches.\nCompany and provider people outputs already report root cost; never add their cost totals.\nThe root total includes earlier parent or sibling work. A nonzero total is conservatively ",[811,2576,2577],{},"estimated",".\nAdd the child and people local ",[811,2580,2581],{},"provider_calls"," once. This output calculation never writes the meter again.\nA failed final meter read fails the result. The normal root meter remains the budget authority.\nApply the existing 31 KiB result bound after combining scope diagnostics and people output.\nTrim optional evidence and display fields only. If required fields do not fit, fail without dropping identities.",[1247,2584,2174],{"id":2585},"supplied-list-core-1",[807,2587,1281,2588,2181,2591,2185,2593,2595,2596,2598,2599,2601,2602,2604],{},[811,2589,2590],{},"people.search_supplied",[811,2592,2184],{},[811,2594,1035],{}," tool and grant. Republish through the definition lifecycle.\nENG-2291 adds ",[811,2597,1035],{},". ENG-2293 adds ",[811,2600,2545],{},", which reuses its source execution after company-scope resolution. Contract version ",[811,2603,956],{}," does not change, and no client migrates.\nA published supplied-only grant must never authorize provider spend.\nThe product registry and start routes remain with ENG-2275 and ENG-2276.\nThe bundle uses the existing definition lifecycle. It does not install itself into a tenant.",[807,2606,2607,2608,2611,2612,2614,2615,2617,2618,2620],{},"The core accepts canonical person, person LinkedIn and people search-row references.\nIt refuses the ",[811,2609,2610],{},"crm_person"," tag, because that tag belongs to the People Enrich adapter.\nThe supplied-only tool always refuses the ",[811,2613,2517],{}," form. The composed workflow resolves that form before source execution.\nA missing or inaccessible source Run fails the request with the same non-disclosing ",[811,2616,1708],{}," error.\nCheck every source Run before any person cache read. A missing row in an accessible Run produces an item diagnostic.\nRead only frozen ",[811,2619,1035],{}," output. Do not accept company rows or client display fields.",[807,2622,2623,2624,2626,2627,937,2630,937,2633,937,2636,937,2639,937,2641,2353,2644,937,2647,1039,2650,2653,2654,937,2657,1039,2659,2662,2663,1039,2665,2667,2668,937,2671,1039,2674,2677],{},"People Search ",[811,2625,1972],{}," holds the People Enrich profile fields without the email family.\nIt holds ",[811,2628,2629],{},"full_name",[811,2631,2632],{},"current_title",[811,2634,2635],{},"current_company_text",[811,2637,2638],{},"location",[811,2640,2145],{},[811,2642,2643],{},"avatar_url",[811,2645,2646],{},"summary",[811,2648,2649],{},"twitter_url",[811,2651,2652],{},"personal_website",".\nIt also holds three discovery-only fields: ",[811,2655,2656],{},"industry",[811,2658,207],{},[811,2660,2661],{},"languages",".\nPeople Enrich accepts identities, not queries, so only search supplies them.\n",[811,2664,207],{},[811,2666,2661],{}," hold at most 20 strings each.\n",[811,2669,2670],{},"experience_history",[811,2672,2673],{},"education_history",[811,2675,2676],{},"certifications"," stay outside the V1 display.\nThe contract closes every object, and those records have no canonical closed schema.\nThe cache keeps them, and the existing person reads still return them.",[807,2679,2680,2681,2683,2684,2686,2687,2690,2691,2693],{},"A valid individual LinkedIn profile URL remains selectable when Intelligence has no match.\nA canonical UUID with no record produces ",[811,2682,1946],{},". A record with no usable LinkedIn URL produces ",[811,2685,1921],{},".\nUse shared normalization. The ",[811,2688,2689],{},"\u002Fin\u002F"," profile path is the only V1 person identity.\nAn organization LinkedIn URL and a name with an employer are unresolved, not a person identity.\nIf a cache observation has keys that identify different canonical records, exclude it with ",[811,2692,1715],{},".\nNever merge two canonical UUIDs through a shared LinkedIn key.",[807,2695,2696],{},"Merge observations before gates. Retain first-input order and all duplicate input indexes.\nUse the first nonempty display value in that order. Keep at most three evidence records for each group.\nEvaluate all observed company and persona values: any explicit contradiction excludes the group.\nMissing values alone do not exclude it.",[807,2698,2699,2700,2702,2703,2705,2706,2708,2709,2711],{},"The company gate compares the observed employer identity with the refs in ",[811,2701,1335],{},".\nA resolved employer outside that scope excludes the group with ",[811,2704,1928],{},".\nAn absent or unresolved employer stays unknown and does not exclude the group.\n",[811,2707,1335],{}," holds references, not an enum vocabulary, so ",[811,2710,1952],{}," never applies to it.\nThe people cache stores an employer display name, not an employer identity, and a name is never an identity.\nThe supplied lane therefore keeps every employer unknown. ENG-2291 adds the provider company ID this gate resolves.",[807,2713,2714,2715,2717,2718,2720,2721,2723,2724,1017,2726,2728],{},"The persona gate uses OR within each persona list and AND between persona fields.\nCompare titles, departments and seniority without case differences. Use ISO alpha-2 codes for ",[811,2716,2127],{},".\nThe person's own country decides ",[811,2719,2127],{},". An employer country is never a substitute.\nAn observed persona value outside the supported vocabulary is ",[811,2722,1952],{},". It stays unknown.\nThe people cache stores a title and a country code. It stores no department and no seniority.\nThe supplied lane therefore keeps those two persona fields unknown. ENG-2291 supplies both from the provider.\nEmit one ",[811,2725,1928],{},[811,2727,1952],{}," diagnostic for each group, using its first input index.",[807,2730,2731,2732,2734,2735,2737,2738,2740,2741,2743,2744,2746,2747,1039,2749,1336],{},"The supplied-only lane attempts no company. It returns an empty ",[811,2733,2030],{}," list and ignores ",[811,2736,2446],{},".\nReturn the first 100 retained groups. Do not refill, score or enrich them.\nThe funnel counts input observations, merged duplicates, unresolved observations, excluded groups and returned groups.\n",[811,2739,2022],{}," reports the ",[811,2742,1284],{}," source alone.\nAn unknown persona value does not make a result partial. Item identity failures do.\nAny item identity failure makes the outcome ",[811,2745,1883],{},", even when no item remains after gates.\nOtherwise, if no group survives the gates, return ",[811,2748,1886],{},[811,2750,1949],{},[807,2752,2240,2753,2756],{},[811,2754,2755],{},"RunResult.output.people_search",".\nThe supplied-only lane has zero provider calls and zero settled cost. It creates no usage charge.\nA failed or timed-out cache read fails the tool. It never reports an empty successful search.\nKeep at most 100 diagnostics and report the exact omitted count.",[807,2758,2759,2760,937,2763,1039,2765,2767,2768,1039,2770,2252,2772,2256],{},"Reserve space for the Run result envelope below the existing 32,768-byte limit.\nRemove optional evidence from the last row first, then optional display fields in stable order.\nKeep ",[811,2761,2762],{},"funnel",[811,2764,2022],{},[811,2766,2030],{}," complete; they are required result fields.\nReport ",[811,2769,1943],{},[811,2771,1883],{},[811,2773,2255],{},[1247,2775,2777],{"id":2776},"licensed-provider-execution","Licensed provider execution",[807,2779,2780,2781,2783,2784,2786,2787,2789],{},"ENG-2291 adds ",[811,2782,1035],{}," for known company refs. ENG-2293 owns the company-brief child step.\nKeep ",[811,2785,2590],{}," and its input unchanged. Publish new workflows with the metered ",[811,2788,1035],{}," grant.\nThe new tool accepts supplied identities, Explorium, or both. Require known scope only when Explorium is selected.\nWhen Explorium is selected, validate department and seniority filters against its published vocabulary before reads or calls.\nSupplied-only requests keep the existing free-text persona contract.\nTitles remain exact strings. Disable related-title expansion. Do not add implicit contact-data filters.",[807,2791,2792,2793,2795],{},"Resolve known company refs with the Company Search identity core and its tenant checks.\nKeep the first ref for each resolved identity. Keep unresolved refs as separate company diagnostics.\nCheck all selected company and person Runs before provider work. Never use a company name as a match key.\nSend one bounded match batch with at most 20 domain or company LinkedIn identities.\nValidate each echoed match input. Missing, ambiguous or conflicting matches remain unresolved.\nIf distinct company identities receive one provider business ID, reject those matches with ",[811,2794,1715],{},".\nA provider business ID is only a query key. It never replaces a canonical company or person identity.",[807,2797,2798,2799,2802,2803,1039,2806,2809,2810,2812],{},"Fetch one prospect page per matched company, in scope order. Set ",[811,2800,2801],{},"page=1"," and both ",[811,2804,2805],{},"size",[811,2807,2808],{},"page_size"," to ",[811,2811,2446],{},".\nThis limits V1 to 21 HTTP requests and 200 raw candidates, below the shared Search ceilings.\nDo not refill after identity checks or gates remove candidates. A requested raw target is a normal stop.\nUse sequential requests and no automatic retries. This keeps spend and response order predictable.\nA transport failure affects its company; continue with later companies while time and budget remain.\nStop all provider work on an authentication failure or a meter failure.",[807,2814,2815,2816,2818,2819,2822,2823,2826,2827,2829,2830,2833,2834,2837,2838,2841],{},"Use the primary ",[811,2817,120],{}," field for person identity. Do not merge distinct profile URLs through ",[811,2820,2821],{},"prospect_id"," or alias arrays.\nMap only observed public profile fields. Never return email hashes, phone data or raw provider payloads.\nUse ",[811,2824,2825],{},"job_department_main",", then ",[811,2828,2488],{},"; use ",[811,2831,2832],{},"job_level_main",", then a singleton ",[811,2835,2836],{},"job_seniority_level",".\nA multi-value fallback or unsupported token remains unknown. Person ",[811,2839,2840],{},"country_name"," can map to an exact ISO country name.\nAn observed employer ID that differs from the queried company excludes that observation's merged group.\nA missing employer ID remains unknown. Query membership alone does not prove employment.",[807,2843,2844,2845,2847,2848,1336],{},"Merge supplied observations first, then provider observations in company order. Apply all gates after merging.\nProvider-only rows have no supplied input index. Preserve every supplied index when observations merge.\nKeep at most three evidence records, with one record for each contributing source before extra cache evidence.\nUse first-observed display facts. Explicit contradictory facts exclude the merged group.\nAssign a merged provider group to its first company. Return one row per company per pass, up to its target and 100 total.\nAppend supplied-only groups in input order when room remains. They do not claim a verified company.\nReport ",[811,2846,1940],{}," if the total output cap omits retained groups.\nEach deduplicated company reports raw candidates, returned groups and one reason, including no matches or an unattempted bound.\nAn unresolved company makes the output partial. A successful empty scope starts no prospect fetch.\nA failed provider call fails the tool only when no usable supplied or provider identity exists.\nOtherwise return partial data, even if gates exclude every usable identity. Never turn provider failure into ",[811,2849,1949],{},[807,2851,2852,2853,2855],{},"Use the canonical root meter before each request and after collection. Record every attempted match and fetch request.\nEstimate one credit per submitted company match and one credit per requested prospect.\nUse six US cents per credit. These are admission estimates, not verified account tariffs.\nVerify match pricing and licensed access before deployment; request ",[811,2854,2314],{}," for both endpoints.\nUse valid reported credits; otherwise record the requested-row estimate. Mark all dollar costs estimated.\nA charge above the admitted estimate stops provider work. A failed request retains a conservative uncertain charge.\nA missing key or license returns an explicit provider failure. Account access and pricing require deployment verification.\nCompleted workflow steps replay their stored results. Cancellation propagates after the attempt's usage write.\nAn interrupted step can repeat a paid call or leave an uncertain charge. This adapter does not promise exactly-once spend.\nThe root meter checks accrued cost; it does not reserve funds across concurrent lanes.\nKeep a 60-second lane deadline, ten-second request timeouts and time for metering, cache reads and the result envelope.\nKeep the existing 31 KiB product output bound and exact diagnostic omission count.",[807,2857,2858,2859,2353,2863,2353,2868,1039,2873,1336],{},"Provider references: ",[824,2860,2862],{"href":2498,"rel":2861},[2160],"prospect fields and filters",[824,2864,2867],{"href":2865,"rel":2866},"https:\u002F\u002Fdevelopers.explorium.ai\u002Freference\u002Fbusinesses\u002Fmatch_businesses",[2160],"business matching",[824,2869,2872],{"href":2870,"rel":2871},"https:\u002F\u002Fwww.explorium.ai\u002Fcredit-details\u002F",[2160],"credit units",[824,2874,2369],{"href":2367,"rel":2875},[2160],[1247,2877,2879],{"id":2878},"search-bounds","Search bounds",[807,2881,2882],{},"Company Search scans at most 500 candidates over five provider pages.\nPeople Search scans at most 500 candidates over 20 provider pages and 20 companies.\nEach provider page holds at most 100 rows. Stop at the first candidate, page, deadline or budget bound.\nCompany Search allows at most ten provider requests; People Search allows at most 40, including matching and retries.\nUse at most four concurrent provider requests. Each request times out after ten seconds; each search lane has a 60-second deadline.\nRetries consume the same request, time and cost budgets. A root deadline or cost ceiling can reduce these limits.\nReturn explicit partial diagnostics at a bound. Do not refill after deterministic gates drop rows.",[829,2884,2886],{"id":2885},"company-enrich-and-people-enrich","Company Enrich and People Enrich",[834,2888,2889,2897],{},[837,2890,2891],{},[840,2892,2893,2895],{},[843,2894,2070],{},[843,2896,917],{},[850,2898,2899,2909,2926,2935],{},[840,2900,2901,2906],{},[855,2902,2903],{},[811,2904,2905],{},"subjects",[855,2907,2908],{},"Required list of 1 to 100 CompanyRefs or PersonRefs, matching the capability",[840,2910,2911,2916],{},[855,2912,2913],{},[811,2914,2915],{},"preset",[855,2917,2918,1017,2920,2923,2924],{},[811,2919,1349],{},[811,2921,2922],{},"standard","; default ",[811,2925,1349],{},[840,2927,2928,2932],{},[855,2929,2930],{},[811,2931,1353],{},[855,2933,2934],{},"Optional nonempty unique subset of the chosen preset; omitted means the whole preset",[840,2936,2937,2942],{},[855,2938,2939],{},[811,2940,2941],{},"refresh",[855,2943,2944,1017,2947,2923,2950],{},[811,2945,2946],{},"missing",[811,2948,2949],{},"stale",[811,2951,2949],{},[807,2953,2954,2955,2957,2958,2960,2961,2963,2964,1039,2966,2969,2970,1039,2973,2976,2977,1039,2979,2981],{},"People Enrich also accepts ",[811,2956,2610],{}," refs through its tenant input adapter.\nContract version ",[811,2959,956],{}," declares the whole ",[811,2962,1613],{}," union, including ",[811,2965,2610],{},[811,2967,2968],{},"search_result",".\nThe profile core resolves ",[811,2971,2972],{},"intel_person",[811,2974,2975],{},"person_linkedin",".\nThe tenant adapter resolves ",[811,2978,2610],{},[811,2980,2968],{}," under the same version and public schema.\nRaw CSV, arbitrary CRM\u002Flist objects and unresolved name-plus-company inputs are not accepted.\nAn input adapter preserves selection order, verifies ownership and emits only canonical identity inputs.\nProvider payloads and unverified client display fields cannot overwrite the canonical cache.",[1247,2983,2985],{"id":2984},"people-enrich-input-adapter","People Enrich input adapter",[807,2987,2988,2989,2992,2993,2996,2997,2999],{},"ENG-2301 owns this adapter. It uses the existing durable preparation step and profile component.\nThe request accepts 1 to 100 subjects across all four PersonRef tags. It accepts no list or prospect reference.\nRead CRM people through ",[811,2990,2991],{},"scoped_db(organization_id)",". Read source Runs through ",[811,2994,2995],{},"agent_db()"," with an explicit organization filter.\nA missing or foreign CRM person or source Run refuses the whole request with ",[811,2998,1708],{},".\nThese cases use the same error text. Never query outside the caller's organization to distinguish them.\nComplete tenant checks before canonical cache reads and person child dispatch.",[807,3001,3002,3003,1039,3005,3008,3009,3011],{},"Read only ",[811,3004,926],{},[811,3006,3007],{},"linkedin_url"," from CRM people. A CRM person has no canonical Intelligence ID column.\nNormalize its LinkedIn value with the existing person contract. An absent or invalid identity returns ",[811,3010,1921],{}," for that item.\nDo not use CRM names, email, employment, notes or manual edits as enrichment facts or fallback identities.",[807,3013,3014,3015,3018,3019,3022,3023,3026,3027,3029,3030,3032,3033,3035,3036,3038,3039,1017,3041,3043],{},"A selected row must occur exactly once in a succeeded Run's ",[811,3016,3017],{},"result.output.people_search.items",".\nThe envelope must declare ",[811,3020,3021],{},"capability_id: people.search",", integer ",[811,3024,3025],{},"contract_version: 1",", and at most 100 items.\nA partial product outcome is valid when the Run succeeded. An unfinished or failed Run supplies no selected identity.\nRead only the selected row's ",[811,3028,1704],{},", identity ",[811,3031,1965],{},", and nullable ",[811,3034,1969],{},".\nIgnore its display, evidence, old input indexes and unrelated rows' display validation.\nDo not reconstruct an identity from display fields, provider IDs or another capability's output.\nA missing, duplicate, malformed or wrong-kind selected row returns an item ",[811,3037,1708],{}," diagnostic.\nA selected row cannot contain another ",[811,3040,2968],{},[811,3042,2610],{}," reference. Do not follow reference chains.",[807,3045,3046,3047,3049,3050,3052],{},"Resolve canonical UUIDs with bounded cache reads. A missing canonical record or unusable stored profile returns ",[811,3048,1708],{},".\nIf a selected identity and its canonical UUID disagree, return ",[811,3051,1715],{}," for the item.\nDo not fall back to its frozen profile when the canonical record is missing.\nCarry the canonical UUID as the existing component's expected-row guard. The component rechecks identity before provider work and persistence.",[807,3054,3055,3056,3058],{},"Group resolved subjects by normalized LinkedIn identity. Preserve the first selection position and all input indexes.\nA group that claims two canonical UUIDs returns ",[811,3057,1715],{}," for every input in that group. Do not select one UUID.\nUnresolved inputs keep separate rows and their original positions. They start no provider work.\nPass only normalized person identity and the expected canonical UUID to profile execution.\nThe original request contains reference values only and remains available for result index checks.",[807,3060,3061,3062,3065],{},"Deduplicate lookup IDs and query at most 50 UUIDs per request. The whole preparation has a ten-second timeout.\nThere are at most 100 CRM IDs, 100 source Run IDs, and 200 canonical ID claims before conflict checks.\nThese are ceilings, not separate subject allowances. The total subject count remains at most 100.\nA read failure or timeout refuses the batch with ",[811,3063,3064],{},"cache_unavailable",". Cancellation propagates.\nUse the existing result byte preflight after grouping. No new endpoint, provider call, CRM write or schema is required.\nA completed preparation replay reuses the stored identity snapshot. A fresh Run resolves the current tenant rows.\nA process stop before the preparation checkpoint can repeat reads and observe a later identity.\nA CRM edit after preparation does not redirect the prepared work. Tenant rows are not read again during a completed-step replay.",[834,3067,3068,3080],{},[837,3069,3070],{},[840,3071,3072,3074,3077],{},[843,3073,857],{},[843,3075,3076],{},"Basic field set",[843,3078,3079],{},"Standard additions",[850,3081,3082,3145],{},[840,3083,3084,3087,3109],{},[855,3085,3086],{},"Company Enrich",[855,3088,3089,937,3091,937,3094,937,3096,937,3098,937,3100,937,3103,937,3106],{},[811,3090,936],{},[811,3092,3093],{},"website",[811,3095,3007],{},[811,3097,2656],{},[811,3099,2145],{},[811,3101,3102],{},"employee_count_exact",[811,3104,3105],{},"employee_count_band",[811,3107,3108],{},"logo_url",[855,3110,3111,937,3113,937,3116,937,3119,937,3121,937,3124,937,3127,937,3130,937,3133,937,3136,937,3139,937,3142],{},[811,3112,940],{},[811,3114,3115],{},"sub_industry",[811,3117,3118],{},"business_model",[811,3120,2638],{},[811,3122,3123],{},"founding_year",[811,3125,3126],{},"annual_revenue",[811,3128,3129],{},"revenue_band",[811,3131,3132],{},"revenue_currency",[811,3134,3135],{},"revenue_year",[811,3137,3138],{},"funding_round",[811,3140,3141],{},"funding_amount",[811,3143,3144],{},"funding_currency",[840,3146,3147,3150,3164],{},[855,3148,3149],{},"People Enrich",[855,3151,3152,937,3154,937,3156,937,3158,937,3160,937,3162],{},[811,3153,2629],{},[811,3155,2632],{},[811,3157,2635],{},[811,3159,2638],{},[811,3161,2145],{},[811,3163,2643],{},[855,3165,3166,937,3168,937,3170,937,3172,937,3174,937,3177],{},[811,3167,2646],{},[811,3169,2649],{},[811,3171,2652],{},[811,3173,336],{},[811,3175,3176],{},"email_source",[811,3178,3179],{},"email_score",[807,3181,3182,3183,3185,3186,1506,3188,3190,3191,937,3193,937,3195,937,3197,937,3199,1039,3201,3203,3204,3207],{},"These are bounded target sets, not promises of provider coverage. Missing fields remain missing.\nCompany scalar fields are strings, except nonnegative numeric counts, years and monetary amounts.\n",[811,3184,3179],{}," uses the current Intelligence numeric representation.\nEmail source or score requests also require ",[811,3187,336],{},[811,3189,1353],{},".\nEvery field in a preset must have a V1 enrichment source. A field only discovery can supply does not belong in a preset.\n",[811,3192,2656],{},[811,3194,207],{},[811,3196,2661],{},[811,3198,2670],{},[811,3200,2673],{},[811,3202,2676],{}," reach a person through People Search.\nPeople Enrich accepts identities, not queries, so it cannot fill them. They stay stored, readable and outside both presets.\nPhone, new technology schemas, arbitrary keywords, custom research questions and a ",[811,3205,3206],{},"deep"," preset are deferred.",[1247,3209,3211],{"id":3210},"cache-freshness-and-merge","Cache, freshness and merge",[807,3213,3214,3215,3217,3218,3221,3222,3225,3226,3229],{},"Reuse the current company and people enrichment components. There is one waterfall per subject, shared by all callers.\nThe platform wrapper invokes the existing component by its registered durable function boundary, with typed input and root usage attribution.\nThe ",[811,3216,1032],{}," write permission authorizes the complete operation, including canonical Intelligence persistence.\nIts policy, approval and journal checks run before dispatch. It does not call a second ",[811,3219,3220],{},"intelligence.upsert_company"," tool.\nCRM changes still require a separate explicit CRM action.\nThe current component imports legacy helpers. Do not import that module into ",[811,3223,3224],{},"src.agentic"," or copy its waterfall.\nENG-2279 must preserve the import-linter boundary and prove that retries keep one root cost record.\nSelected company batches invoke one existing company child at a time. Settle its saved usage before starting the next child.\nAn ordinary item failure keeps valid siblings. A meter fault stops further paid children and fails the Run.\nCheckpoint source eligibility before its first call, so a settings change cannot skip saved provider usage on replay.\nIt does not wrap only the narrow ",[811,3227,3228],{},"research.enrich_company"," exact-domain tool.",[807,3231,3232,3233,3236,3237,3240,3241,3244],{},"Current Intelligence stores carry ",[811,3234,3235],{},"source_ids"," linked to provider-fetch records and ",[811,3238,3239],{},"fetched_\u003Ctier>_at"," timestamps.\nThey do not provide a reliable source and ",[811,3242,3243],{},"filled_at"," timestamp for every field.\nDo not invent per-field provenance, freshness or billing data from a row timestamp.",[834,3246,3247,3260],{},[837,3248,3249],{},[840,3250,3251,3254,3257],{},[843,3252,3253],{},"Subject",[843,3255,3256],{},"Current tier windows",[843,3258,3259],{},"Operational check",[850,3261,3262,3273],{},[840,3263,3264,3267,3270],{},[855,3265,3266],{},"Company",[855,3268,3269],{},"Cold 180 days; warm 30 days; hot 7 days reserved",[855,3271,3272],{},"The company component uses warm currentness",[840,3274,3275,3278,3281],{},[855,3276,3277],{},"Person",[855,3279,3280],{},"Hot 30 days; warm 90 days; cold 365 days reserved",[855,3282,3283],{},"Profile uses warm; email uses hot",[807,3285,3286,3287,3290,3291,3293,3294,3296,3297,1557,3299,1039,3302,3304,3305,1557,3307,1039,3309,3311,3312,1451,3314,3316],{},"A missing or future timestamp is stale. Capture ",[811,3288,3289],{},"evaluated_at"," once inside a durable read step and reuse it on replay.\nAn exact TTL boundary is stale. Cache freshness does not prove that a missing requested field exists.\n",[811,3292,2946],{}," keeps existing values and fills gaps. ",[811,3295,2949],{}," also bypasses stale cache values for the requested target fields.\nThe ordered source waterfall fills remaining gaps. A later source cannot overwrite a value from an earlier accepted source.\nEach selected field needs its own usable value. A count band does not satisfy an explicitly selected exact count.\nA selected field can enable a capable source even when the legacy full-profile preset does not target that field.\nExisting current fields outside the refresh target remain unchanged. No null or failed lookup erases an existing fact.\nKeep related facts together: count and band; revenue amount, currency, year and band; funding amount, currency and round; address fields; industry and sub-industry.\nThe people groups are ",[811,3298,2638],{},[811,3300,3301],{},"country",[811,3303,2145],{},", and ",[811,3306,336],{},[811,3308,3176],{},[811,3310,3179],{},".\nThe shared location normalizer always writes ",[811,3313,3301],{},[811,3315,2145],{},", so one observation must supply the whole place.\nA changed group must come from one compatible observation. Do not attach an old currency or year to a new amount.\nIf the source cannot verify the retained parts, keep the stored group and leave the selected field unavailable.\nA later source cannot change a group already verified in this attempt. A concurrent group change cannot count as this attempt's refresh.",[807,3318,3319,3320,937,3322,937,3324,937,3326,937,3328,937,3330,937,3332,937,3334,1039,3336,3338,3339,937,3341,1039,3343,1979,3345,937,3348,937,3351,3353,3354,3356,3357,3359,3360,3362],{},"The wrapper must pass the selected target set to the existing component. It must not fetch unrelated fields just to satisfy a legacy full-profile gate.\nA source gates on the pending selected fields it can supply. It must not gate on one stored value that a different caller wanted.\nThe people Hunter source currently returns nothing when the person already has an avatar. That guard belongs to the discovery caller.\nUnder a selected request it must run whenever a pending selected field is in its output set, and stay unchanged for the legacy caller.\nStale refresh does not guarantee a changed value. Report a field as unavailable when no source provides it.\nThe cache retains old facts when refresh fails, with their original freshness. A failed attempt never makes them current.\nA partial or selected-field refresh preserves its old tier timestamp when any retained stale field in that tier remains unverified.\nAdvance a tier only when every retained field in that tier is current or successfully refreshed in this attempt.\nOnly a sourced field can hold a stamp back. A sourced field is a stored profile field that a V1 enrichment source can supply.\nA stored field with no V1 source can never be verified. It must not pin a tier stamp for the life of the record.\nThe company profile uses its existing mergeable profile field set. Email and its metadata use the hot tier.\nThe people warm set is the profile fields of both presets, without the email family.\nIt holds ",[811,3321,2629],{},[811,3323,2632],{},[811,3325,2635],{},[811,3327,2638],{},[811,3329,2145],{},[811,3331,2643],{},[811,3333,2646],{},[811,3335,2649],{},[811,3337,2652],{},".\nThe people hot set holds ",[811,3340,336],{},[811,3342,3176],{},[811,3344,3179],{},[811,3346,3347],{},"work_phone",[811,3349,3350],{},"mobile_phone",[811,3352,3301],{}," and the six discovery-only fields are in neither set, so they never hold a stamp back.\nA sourced field must also be verifiable. ",[811,3355,3301],{}," is stored and a source supplies it, but the contract exposes ",[811,3358,2145],{}," alone, so no result can verify ",[811,3361,3301],{}," by itself.\nIn the warm set it could never be verified, and the stamp could never advance again. The shared location normalizer re-derives it on every write instead.\nThe two tiers are decided on their own windows. A record is often warm current and hot stale, so a warm hit never reports a stale email as current.\nA successful lookup that returns no replacement cannot validate a retained stale value.\nA profile-only write never refreshes the email hot stamp. A failed email refresh preserves that stamp too.\nThe shared company and people write boundaries accept a preserve-stamp decision.\nThe wrapper must pass this decision through the component before it writes; a later compensating timestamp write is unsafe.\nNo new per-field provenance table is required. Conservative tier stamps can repeat some reads, but cannot hide a failed refresh.\nTier freshness remains coarse; the response states this limit rather than claiming field-level verification.",[807,3364,3365],{},"Serialize updates for the same canonical identity, or use the shared store's conflict check and retry with a fresh read.\nUnion provider lineage without losing concurrent source IDs. Recheck identity before each canonical write.\nA conflict retry rereads identity keys, profile values and timestamps, then rebuilds the selected-field merge.\nDo not replay a stale full-row payload after only refreshing the source IDs.\nPersist only normalized, allowed provider facts. Read tenant CRM data for identity resolution, not as global enrichment facts.\nCRM data changes only through a later explicit CRM action.",[1247,3367,3369],{"id":3368},"enrichment-result-rows","Enrichment result rows",[807,3371,3372,3373,1966,3375,937,3377,937,3379,937,3382,937,3385,1039,3387,1979,3389,3391,3392,3394,3395,937,3398,937,3401,937,3404,937,3406,937,3409,1017,3411,1979,3414,3416,3417,3419,3420,3423,3424,1017,3426,3428,3429,1017,3431,1979,3433,3435,3436,3439,3440,2002,3443,2005,3446,937,3449,937,3452,1017,3454,3457,3458,2005,3461,3464,3465,3467,3468,1039,3470,3472,3473,3476,3477,3480,3481,3483,3484,3487,3488,3490,3491,3493,3494,3496,3497,1336],{},"Each row contains ",[811,3374,1965],{},[811,3376,1969],{},[811,3378,1978],{},[811,3380,3381],{},"values",[811,3383,3384],{},"field_states",[811,3386,38],{},[811,3388,3235],{},[811,3390,3381],{}," uses the closed field table above. It contains only requested fields that have usable values.\n",[811,3393,3384],{}," maps every requested field to ",[811,3396,3397],{},"current",[811,3399,3400],{},"retained",[811,3402,3403],{},"refreshed",[811,3405,1946],{},[811,3407,3408],{},"pending",[811,3410,2341],{},[811,3412,3413],{},"cancelled",[811,3415,3397],{}," means the cache value is within its tier window.\n",[811,3418,3400],{}," means ",[811,3421,3422],{},"refresh: missing"," keeps an existing stale value without provider verification.\nA failed stale refresh can return the old value with ",[811,3425,2341],{},[811,3427,1946],{},"; it never reports ",[811,3430,3397],{},[811,3432,3403],{},[811,3434,38],{}," contains ",[811,3437,3438],{},"{tier, evaluated_at, fetched_at, decision}",". Times are UTC timestamps; ",[811,3441,3442],{},"fetched_at",[811,3444,3445],{},"decision",[811,3447,3448],{},"hit",[811,3450,3451],{},"miss",[811,3453,2949],{},[811,3455,3456],{},"not_read","; ",[811,3459,3460],{},"tier",[811,3462,3463],{},"warm"," for profile results.\nAn unresolved or unstarted row uses ",[811,3466,3456],{},", the durable preparation time, and null ",[811,3469,3442],{},[811,3471,1969],{},".\nEmail has its own ",[811,3474,3475],{},"email_cache"," with tier ",[811,3478,3479],{},"hot"," when email is requested.\n",[811,3482,3235],{}," is the canonical provider-lineage UUID list, bounded by the runtime output limit.\nIf lineage exceeds that limit, return a bounded list and a required ",[811,3485,3486],{},"source_ids_omitted"," count. Keep full lineage in Intelligence.\nKeep selected values and field states intact. Trim only lineage and diagnostics, with exact omitted counts.\nDeduplicate identities, then check the minimum result size before paid work and between company children.\nIf completed values and required row data cannot fit, stop further children and return ",[811,3489,2255],{},".\nFacts and usage already persisted remain available. Do not truncate identity keys or change a value to fit.\nThe 100-subject limit is also subject to the 31 KiB output limit; a full Basic or Standard batch can exceed it before providers run.\nAn unresolved subject has no canonical UUID and a diagnostic. A failed write must never report ",[811,3492,3403],{},".\nRehost selected cached LinkedIn logos when necessary, without a provider charge or newer tier timestamp.\nIf rehosting fails, keep the stored fact. Omit an unusable LinkedIn URL from output and mark the selected logo ",[811,3495,2341],{},".\nKeep an older usable logo when a new replacement fails.\nThe people avatar uses the same rules on the same shared rehost path. A failed rehost keeps the stored avatar and marks the selected field ",[811,3498,2341],{},[1247,3500,3502],{"id":3501},"email-verification-metadata","Email verification metadata",[807,3504,3505,3506,3508,3509,3512,3513,3515],{},"When ",[811,3507,336],{}," is requested, each enrichment row also returns ",[811,3510,3511],{},"email_verification",", independently of the selected ",[811,3514,3381],{}," fields.\nIt is null while no lookup or cached email result exists. Otherwise it is a closed object:",[834,3517,3518,3526],{},[837,3519,3520],{},[840,3521,3522,3524],{},[843,3523,914],{},[843,3525,1625],{},[850,3527,3528,3548,3557,3566,3576],{},[840,3529,3530,3535],{},[855,3531,3532],{},[811,3533,3534],{},"status",[855,3536,3537,937,3540,937,3543,1017,3546],{},[811,3538,3539],{},"verified",[811,3541,3542],{},"unverified",[811,3544,3545],{},"unknown",[811,3547,1946],{},[840,3549,3550,3554],{},[855,3551,3552],{},[811,3553,336],{},[855,3555,3556],{},"The exact email value this status describes, or null for no email",[840,3558,3559,3563],{},[855,3560,3561],{},[811,3562,1366],{},[855,3564,3565],{},"Bounded provider name, or null when unknown",[840,3567,3568,3573],{},[855,3569,3570],{},[811,3571,3572],{},"provider_status",[855,3574,3575],{},"Bounded normalized provider status, or null",[840,3577,3578,3583],{},[855,3579,3580],{},[811,3581,3582],{},"checked_at",[855,3584,3585],{},"Provider verification timestamp in UTC, or null when not supplied",[807,3587,3588,3589,3591,3592,3594,3595,3597,3598,3600,3601,3603,3604,3606],{},"An ",[811,3590,3179],{}," alone never proves verification. An old cache row without verification evidence returns ",[811,3593,3545],{},".\nOnly an explicitly verified provider result with matching identity and no role mailbox can return ",[811,3596,3539],{},".\nMap catch-all, unverifiable and unverified results to ",[811,3599,3542],{},". A completed lookup with no email returns ",[811,3602,1946],{},".\nPending, failed and cancelled work still use ",[811,3605,3384],{},"; retained cached metadata does not hide that operation state.",[807,3608,3609,3610,3613,3614,3616],{},"ENG-2299 stores the metadata under existing canonical ",[811,3611,3612],{},"extra.email_verification"," and writes it atomically with the matching email value.\nAn email replacement invalidates metadata for the previous value. Readers return ",[811,3615,3545],{}," if the metadata does not match the current email.\nThis is provider verification evidence, not a new per-field freshness model or a guessed verification date.\nThe final Run freezes this metadata with its email value. Reconnect renders that pair without reading raw provider jobs.\nCurrent canonical reads use their own matching pair and remain separate from the frozen result.",[1247,3618,3620],{"id":3619},"asynchronous-email","Asynchronous email",[807,3622,3623],{},"People Enrich requests FullEnrich only for requested email fields that are missing or stale.\nThe profile step writes canonical results first. Clients can read those results while the email child waits.\nThe root remains live until that child reaches a terminal state. Profile readiness is not root completion.\nThe final result is immutable; later UI reads of canonical Intelligence do not rewrite it.",[807,3625,3626,3627,3630,3631,3634,3635,3638,3639,3642],{},"The native email child stores the complete profile output in its immutable ",[811,3628,3629],{},"input.profile",".\nA product client reads that child through the Run list and detail routes while the root is live.\nThe client accepts the preview only when the root has exactly one direct workflow child.\nThe child must name the same root and parent, use ",[811,3632,3633],{},"workflow_step"," as its source and carry only ",[811,3636,3637],{},"profile"," in its input.\nThe client validates that profile against the root's frozen request before display.\nIt does not read span payloads, poll provider jobs or call the superadmin Intelligence API.\nThe root's valid final ",[811,3640,3641],{},"people_enrich"," output replaces the preview.",[807,3644,3645,3646,3649,3650,3653],{},"The root invokes one email child after the profile tool completes. Signals Search can therefore use the three-level workflow limit.\nThe child processes up to four sequential batches of at most 25 deduplicated subjects. Empty batches make no provider call.\nEach batch submits through ",[811,3647,3648],{},"fullenrich.submit",", waits on the platform event, and reads through ",[811,3651,3652],{},"fullenrich.collect",".\nDo not add another workflow level, concurrent provider waits, vendor polling, or a second provider-job store.\nA job wait lasts at most 600 seconds. The root budget must cover profile work, four waits, and persistence overhead.",[807,3655,3656,3657,3659],{},"Use canonical person facts to build the provider identity. Require a canonical ID, matching LinkedIn URL, and a usable first and last name.\nSplit the canonical full name at its first space. Do not guess a missing name or copy tenant CRM facts into the global store.\nAn unsupported identity fails only that subject with ",[811,3658,1921],{},". Email-only requests do not start an unrelated profile lookup.\nEach contact ref is the canonical person UUID. Match only that exact echoed ref, never array order, name, or a vendor ID.\nThe job must belong to the current organization, email child, root Run and submitted contact set before a canonical write.\nDuplicate, missing, unknown and malformed refs produce bounded diagnostics. Valid sibling contacts remain usable.",[807,3661,3662,3665,3666,937,3669,1039,3672,3675,3676,3678,3679,3681,3682,3684,3685,3687],{},[811,3663,3664],{},"email_job"," is null when no job exists. Otherwise it contains ",[811,3667,3668],{},"job_id",[811,3670,3671],{},"child_run_id",[811,3673,3674],{},"root_run_id",".\nThe profile result marks selected email targets ",[811,3677,3408],{},". The child's submit output and Run lineage identify the job while it waits.\nThe final row includes that lineage and a terminal field state. ",[811,3680,3403],{}," means a found email was persisted.\nA completed lookup with no email uses ",[811,3683,1946],{},". Invalid or missing contact results use ",[811,3686,2341],{},".\nFound results from a failed or cancelled provider batch can survive; contacts without usable results use that batch's terminal state.\nA missing provider score stays missing. It cannot inherit the score of a replaced email.",[807,3689,3690,3691,3694],{},"The durable provider-job row is the completion truth. The runtime reads it before waiting and again on timeout.\nAn event in the registration gap can delay completion until the second read. The wait never becomes unbounded.\nENG-2300 establishes the signed callback contract. ENG-2210 reserves the job before submission and bounds stored results.\nThose dependencies are complete. ENG-2299 uses their behavior and does not repeat their infrastructure work.\nFreeze the first durable collect result after the wait. A ",[811,3692,3693],{},"running"," result records timeout and stays unchanged on write retries.\nA later callback can settle cost but cannot reopen that batch for canonical writes.",[807,3696,3697,3698,3700],{},"Persist the email family and matching verification metadata in one conflict-checked write. Preserve unrelated profile facts and the warm stamp.\nRecheck canonical identity and live Run authority before each write attempt. Preserve a concurrent email-group change and report ",[811,3699,1715],{},".\nUse one stable source ID per job and contact. Replay preserves source lineage, facts and freshness without a second provider submission.\nA storage fault retries the canonical write from stored provider evidence. It never restarts the profile workflow or resubmits a batch.\nA failed lookup retains the old email, matching metadata and hot stamp. Its operation state still reports the failure or absence.\nNo-email evidence describes null only when no cached email remains. A score alone does not establish verification.",[807,3702,3703],{},"Cancellation stops further calls and canonical writes. The runtime can terminate before a final result exists.\nWhen the email child exists, its immutable input keeps the profile output readable.\nCancellation before child creation exposes no profile snapshot, so clients do not guess one from canonical data.\nConsumers derive cancelled email state from the terminal root Run, as ENG-2289 specifies.\nA late callback cannot resume a cancelled Run. Provider settlement can still record a real charge once.\nRead the root usage meter for the final result. Provider accounting remains owned by the existing settlement function.\nCheck byte bounds before paid work where overflow is certain. Never trim selected facts, verification data or job lineage to fit a result.",[829,3705,3707],{"id":3706},"signals-search-composition","Signals Search composition",[807,3709,3710,3712,3713,937,3715,1039,3718,3721,3722,3725,3726,3729,3730,822,3734,3738],{},[811,3711,1042],{}," keeps the three root sources: ",[811,3714,355],{},[811,3716,3717],{},"company_set",[811,3719,3720],{},"saved_search",".\nIts schema uses ",[811,3723,3724],{},"SearchSourceInput",", the scoring brief, shared ",[811,3727,3728],{},"PersonaCriteria"," and bounded company reference definitions.\nENG-2324 owns the ",[824,3731,3733],{"href":3732},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fsignals-search#shared-persona-contract","shared persona and legacy correction contract",[824,3735,3737],{"href":3736},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fsignals-search#one-run-input-three-shapes","Signals Search page"," owns those fields and its existing output projection.\nDo not apply the Company\u002FPeople result envelope to existing Signals clients.\nCapability identity and version still appear on the Run and telemetry.",[807,3740,3741,3742,3745,3746,3748],{},"Published child nodes store resolved executor UUIDs. No ",[811,3743,3744],{},"capability"," DSL node or live registry lookup is added to workflow execution.\nThe company and people lanes compose the four capabilities with parent\u002Fchild lineage and shared root budgets.\nSignals web research can discover candidates, then pass them to the ",[811,3747,1284],{}," search source for normalization and gates.\nThis preserves thesis and signal discovery without adding web sources to direct Company or People Search.\nCompany\u002Fperson enrichment is explicit in the published Signals graph and requests only its needed fields.\nSignals scoring, persona fit, saved-search diffs, smart-feed publication, prospect promotion and stream semantics remain in place.\nSignals does not start CRM promotion or outreach without the existing explicit product action.",[807,3750,1281,3751,3755],{},[824,3752,3754],{"href":3753},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fsignals-search#company-lane-contract","company lane contract"," defines the exact ENG-2282 handoff.\nResearch keeps canonical identity and signal writes. Company Enrich replaces its private profile provider calls.\nEmpty-input wrappers skip capability starts without weakening direct Search or Enrich input validation.",[829,3757,3759],{"id":3758},"implementation-owners","Implementation owners",[834,3761,3762,3772],{},[837,3763,3764],{},[840,3765,3766,3769],{},[843,3767,3768],{},"Contract area",[843,3770,3771],{},"Tickets",[850,3773,3774,3782,3790,3798,3806,3814,3822,3830,3838],{},[840,3775,3776,3779],{},[855,3777,3778],{},"Binding, registry, initial install, upgrades",[855,3780,3781],{},"ENG-2287, ENG-2275, ENG-2277, ENG-2303",[840,3783,3784,3787],{},[855,3785,3786],{},"Start\u002Fread API and CLI, telemetry",[855,3788,3789],{},"ENG-2276, ENG-2286, ENG-2298",[840,3791,3792,3795],{},[855,3793,3794],{},"Company core, provider, enrichment",[855,3796,3797],{},"ENG-2278, ENG-2295, ENG-2279",[840,3799,3800,3803],{},[855,3801,3802],{},"People core, provider, scope, enrichment adapters",[855,3804,3805],{},"ENG-2280, ENG-2291, ENG-2293, ENG-2281, ENG-2301",[840,3807,3808,3811],{},[855,3809,3810],{},"Email live gate, tools, child workflow",[855,3812,3813],{},"ENG-2300, ENG-2210, ENG-2299",[840,3815,3816,3819],{},[855,3817,3818],{},"Signals persona alignment",[855,3820,3821],{},"ENG-2324",[840,3823,3824,3827],{},[855,3825,3826],{},"Signals company and people composition",[855,3828,3829],{},"ENG-2282, ENG-2302",[840,3831,3832,3835],{},[855,3833,3834],{},"Front Door and direct surfaces",[855,3836,3837],{},"ENG-2283, ENG-2284, ENG-2288, ENG-2289, ENG-2290, ENG-2292, ENG-2294",[840,3839,3840,3843],{},[855,3841,3842],{},"API\u002FCLI, Front Door and browser exits",[855,3844,3845],{},"ENG-2285, ENG-2297, ENG-2296",{"title":3847,"searchDepth":32,"depth":233,"links":3848},"",[3849,3850,3851,3852,3860,3864,3870,3877,3878],{"id":831,"depth":32,"text":832},{"id":896,"depth":32,"text":897},{"id":1130,"depth":32,"text":1131},{"id":1219,"depth":32,"text":1220,"children":3853},[3854,3855,3856,3857,3858,3859],{"id":1249,"depth":233,"text":1250},{"id":1537,"depth":233,"text":1538},{"id":1604,"depth":233,"text":1605},{"id":1722,"depth":233,"text":1723},{"id":1765,"depth":233,"text":1766},{"id":1826,"depth":233,"text":1827},{"id":50,"depth":32,"text":2061,"children":3861},[3862,3863],{"id":2173,"depth":233,"text":2174},{"id":2259,"depth":233,"text":2260},{"id":128,"depth":32,"text":2372,"children":3865},[3866,3867,3868,3869],{"id":2506,"depth":233,"text":2507},{"id":2585,"depth":233,"text":2174},{"id":2776,"depth":233,"text":2777},{"id":2878,"depth":233,"text":2879},{"id":2885,"depth":32,"text":2886,"children":3871},[3872,3873,3874,3875,3876],{"id":2984,"depth":233,"text":2985},{"id":3210,"depth":233,"text":3211},{"id":3368,"depth":233,"text":3369},{"id":3501,"depth":233,"text":3502},{"id":3619,"depth":233,"text":3620},{"id":3706,"depth":32,"text":3707},{"id":3758,"depth":32,"text":3759},"md",{},true,[3883,3884,3885,3886,3887],"engineering\u002Fsystem-design\u002Fagentic-platform\u002Fcontract","engineering\u002Fsystem-design\u002Fagentic-platform\u002Fruntime\u002Fdefinitions","engineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Ffront-door","engineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Fsurfaces","engineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fcapability-scenarios",{"title":316,"description":317},"engineering\u002Fsystem-design\u002Fagentic-platform\u002Fproducts\u002Fcapability-contracts",[320,321,119,51,322],"6f1ADktJr-vjgCKt6g341AgCrJT8WyBAwrlGBrpVyag",1788650194709]