[{"data":1,"prerenderedAt":3805},["ShallowReactive",2],{"docs-nav":3,"docs-article-engineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Ffront-door":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":242,"body":799,"customComponent":480,"description":243,"extension":3794,"group":139,"lastUpdated":210,"meta":3795,"navigation":1388,"order":244,"path":241,"related":3796,"section":181,"seo":3801,"stem":3802,"tags":3803,"__hash__":3804},"docs\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Ffront-door.md",{"type":800,"value":801,"toc":3762},"minimark",[802,805,809,817,828,831,839,844,847,903,909,973,999,1003,1009,1033,1073,1130,1228,1245,1249,1252,1291,1320,1333,1336,1344,1404,1425,1437,1451,1463,1469,1478,1481,1486,1802,1827,1850,1859,1864,1871,1877,1902,1908,1927,1933,1936,1940,1954,1977,2062,2072,2085,2091,2105,2108,2136,2151,2166,2172,2189,2236,2240,2259,2268,2274,2277,2299,2302,2305,2347,2422,2435,2444,2447,2453,2456,2469,2484,2499,2505,2512,2530,2533,2537,2543,2546,2549,2555,2569,2601,2631,2645,2648,2678,2682,2697,2858,2861,2865,2953,2957,2969,2983,2987,3001,3008,3012,3022,3039,3051,3055,3058,3064,3067,3070,3076,3079,3083,3099,3124,3127,3133,3136,3142,3145,3188,3191,3195,3292,3295,3299,3441,3445,3461,3471,3474,3486,3490,3602,3606,3688,3691,3695,3739,3743,3749,3752,3758],[803,804,242],"h1",{"id":246},[806,807,808],"p",{},"The Front Door is the conversational control layer. It understands what the user wants, selects one product capability or published custom Agent\u002FWorkflow when work is required, and hands a structured command to the runtime.",[806,810,811,812,816],{},"It ",[813,814,815],"strong",{},"does no task execution itself",".",[818,819,825],"pre",{"className":820,"code":822,"language":823,"meta":824},[821],"language-text","Inbound message\n      │\n      ▼\nFrontDoorService\n      ├── ContextBuilder (front_door policy)\n      ├── CapabilityIndex\n      └── Agno front door\n                │\n                ▼\n         FrontDoorOutcome\n                │\n                ▼\n        FrontDoorService\n          \u002F           \\\n     response        RunManager\n","text","",[826,827,822],"code",{"__ignoreMap":824},[806,829,830],{},"The core boundary is:",[832,833,834],"blockquote",{},[806,835,836],{},[813,837,838],{},"One structured model decision in; one deterministic application action out.",[840,841,843],"h2",{"id":842},"one-turn","One turn",[806,845,846],{},"Four inputs, one model decision, and exactly one of four outcomes.",[848,849,850,863],"table",{},[851,852,853],"thead",{},[854,855,856,860],"tr",{},[857,858,859],"th",{},"Step",[857,861,862],{},"Job",[864,865,866,875,883,891],"tbody",{},[854,867,868,872],{},[869,870,871],"td",{},"Context",[869,873,874],{},"Read recent conversation, conversation summary, active Runs, already-scoped entities, definition summaries and platform knowledge. User preferences remain deferred with the memory source.",[854,876,877,880],{},[869,878,879],{},"Capability shortlist",[869,881,882],{},"Read eligible product capabilities and published custom Agents\u002FWorkflows for this actor.",[854,884,885,888],{},[869,886,887],{},"Decision",[869,889,890],{},"One Agno call decides whether to answer, clarify, delegate, or control a live Run.",[854,892,893,896],{},[869,894,895],{},"Handoff",[869,897,898,899,902],{},"Deterministic application code validates the decision and calls ",[826,900,901],{},"RunManager"," when execution is required.",[818,904,907],{"className":905,"code":906,"language":823,"meta":824},[821],"FrontDoorOutcome\n  answer(text)\n  clarify(question)\n  delegate(capability_id, input)\n  control_run(run_id, action)\n",[826,908,906],{"__ignoreMap":824},[848,910,911,921],{},[851,912,913],{},[854,914,915,918],{},[857,916,917],{},"Outcome",[857,919,920],{},"Effect",[864,922,923,933,943,960],{},[854,924,925,930],{},[869,926,927],{},[826,928,929],{},"answer",[869,931,932],{},"Reply using context already supplied to the Front Door.",[854,934,935,940],{},[869,936,937],{},[826,938,939],{},"clarify",[869,941,942],{},"Ask one question because required input or a Run reference is ambiguous.",[854,944,945,950],{},[869,946,947],{},[826,948,949],{},"delegate",[869,951,952,953,956,957,816],{},"Validate the selected capability. A product start calls ",[826,954,955],{},"CapabilityStarter.start_resolved()","; a custom definition start calls ",[826,958,959],{},"RunManager.start()",[854,961,962,967],{},[869,963,964],{},[826,965,966],{},"control_run",[869,968,969,970,816],{},"Validate the target Run and call ",[826,971,972],{},"RunManager.cancel()",[806,974,975,978,979,982,983,986,987,990,991,994,995,998],{},[813,976,977],{},"Approval is not a Front Door model outcome."," Delegation creates\u002Fstarts the normal Run path; admission policy may return ",[826,980,981],{},"allow",", ",[826,984,985],{},"deny",", or ",[826,988,989],{},"require_approval",". The Front Door decides ",[813,992,993],{},"what"," should run. Policy decides ",[813,996,997],{},"whether"," it may run.",[840,1000,1002],{"id":1001},"core-code-components","Core code components",[818,1004,1007],{"className":1005,"code":1006,"language":823,"meta":824},[821],"src\u002Fagentic\u002Fentry_control\u002Ffront_door\u002F\n  service.py        FrontDoorService\n  protocol.py       FrontDoorRuntime, the neutral reasoning port\n  agno.py           AgnoFrontDoorRuntime, build_front_door_agent()\n  policy.py         FRONT_DOOR_CONTEXT_POLICY\n  capabilities.py   CapabilityIndex\n  models.py         FrontDoorOutcome, CapabilitySummary, the decision codec\n",[826,1008,1006],{"__ignoreMap":824},[806,1010,1011,1012,1018,1019,1022,1023,1026,1027,1032],{},"⚠️ ",[813,1013,1014,1015,816],{},"The path is ",[826,1016,1017],{},"src\u002Fagentic\u002F"," The import-linter contract binds ",[826,1020,1021],{},"src.agentic"," as its source module, and a package outside it could import the legacy stack with a green ",[826,1024,1025],{},"lint-imports",". See ",[1028,1029,1031],"a",{"href":1030},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fcontract#coexistence-with-the-live-agent-stack","coexistence",", rule 3.",[806,1034,1011,1035,1042,1043,1046,1047,1050,1051,1054,1055,1057,1058,1061,1062,1065,1066,1050,1069,1072],{},[813,1036,1037,1038,1041],{},"The Agno import is split off into ",[826,1039,1040],{},"agno.py",", and that is not tidiness."," The contract ",[826,1044,1045],{},"agno is imported by src.agentic.runtime.agent.agno and nowhere else"," takes the whole platform as its source, so a ",[826,1048,1049],{},"build_front_door_agent()"," beside ",[826,1052,1053],{},"FrontDoorService"," fails ",[826,1056,1025],{},". The Front Door is a second, deliberate Agno caller, so the fix is one more ignored edge and not a hole: the contract gains ",[826,1059,1060],{},"src.agentic.entry_control.front_door.agno -> agno",", and the rest of the package reads ",[826,1063,1064],{},"FrontDoorRuntime",". This mirrors ",[826,1067,1068],{},"runtime\u002Fagent\u002Fprotocol.py",[826,1070,1071],{},"runtime\u002Fagent\u002Fagno\u002F",", and it is the same reason: Agno stays a reasoning implementation detail.",[806,1074,1075,1078,1079,1082,1083,982,1086,982,1088,982,1090,1093,1094,1096,1097,1100,1101,1104,1105,1108,1109,1112,1113,1116,1117,1120,1121,1123,1124,1126,1127,1129],{},[826,1076,1077],{},"entry_control"," is a new top-level package, so it joins the source list of the ",[826,1080,1081],{},"src.agentic.surfaces is the top layer"," contract, and it takes its own contract: ",[826,1084,1085],{},"services",[826,1087,294],{},[826,1089,149],{},[826,1091,1092],{},"shared"," and ",[826,1095,320],{}," may not import it. ",[826,1098,1099],{},"inngest_functions"," is not in that list and cannot be: the registry imports the module that builds each function, exactly as ",[826,1102,1103],{},"inngest_functions\u002F__init__.py"," imports ",[826,1106,1107],{},"runtime\u002Finngest\u002Fexecute.py"," for ",[826,1110,1111],{},"run.execute",". ",[826,1114,1115],{},"inngest_app"," is not in it either, because the direction is ",[826,1118,1119],{},"entry_control -> inngest_app",". It sits above ",[826,1122,149],{},", because it calls ",[826,1125,901],{},", and below ",[826,1128,253],{},", because the conversation router calls it.",[848,1131,1132,1142],{},[851,1133,1134],{},[854,1135,1136,1139],{},[857,1137,1138],{},"Component",[857,1140,1141],{},"Responsibility",[864,1143,1144,1153,1165,1175,1185,1199,1209,1219],{},[854,1145,1146,1150],{},[869,1147,1148],{},[826,1149,1053],{},[869,1151,1152],{},"Own one conversational turn and apply the structured outcome.",[854,1154,1155,1159],{},[869,1156,1157],{},[826,1158,1064],{},[869,1160,1161,1162,816],{},"The neutral reasoning port. One method, ",[826,1163,1164],{},"decide",[854,1166,1167,1172],{},[869,1168,1169],{},[826,1170,1171],{},"AgnoFrontDoorRuntime",[869,1173,1174],{},"The one implementation. It holds every Agno import.",[854,1176,1177,1182],{},[869,1178,1179],{},[826,1180,1181],{},"FrontDoorOutcome",[869,1183,1184],{},"Closed structured decision contract.",[854,1186,1187,1192],{},[869,1188,1189],{},[826,1190,1191],{},"FRONT_DOOR_CONTEXT_POLICY",[869,1193,1194,1195,1198],{},"The fixed ",[826,1196,1197],{},"ContextPolicy"," that keeps the turn to lightweight control and already-scoped context.",[854,1200,1201,1206],{},[869,1202,1203],{},[826,1204,1205],{},"CapabilityIndex",[869,1207,1208],{},"Find a small shortlist of published Agents\u002FWorkflows.",[854,1210,1211,1216],{},[869,1212,1213],{},[826,1214,1215],{},"CapabilitySummary",[869,1217,1218],{},"Minimal routing DTO exposed to the model.",[854,1220,1221,1225],{},[869,1222,1223],{},[826,1224,901],{},[869,1226,1227],{},"Product-facing Run lifecycle boundary used for start and cancel.",[806,1229,1230,1231,1234,1235,1238,1239,1241,1242,1244],{},"No separate ",[826,1232,1233],{},"DelegateHandler"," or ",[826,1236,1237],{},"CancelHandler"," class is required in V1. ",[826,1240,1053],{}," translates the structured outcome directly into ",[826,1243,901],{}," operations.",[840,1246,1248],{"id":1247},"agno-construction","Agno construction",[806,1250,1251],{},"The Agno agent is deliberately thin.",[818,1253,1257],{"className":1254,"code":1255,"language":1256,"meta":824,"style":824},"language-python shiki shiki-themes github-dark","def build_front_door_agent(model) -> Agent:\n    return Agent(\n        model=model,\n        instructions=FRONT_DOOR_INSTRUCTIONS,\n        output_schema=FrontDoorOutcome,\n    )\n","python",[826,1258,1259,1266,1271,1276,1281,1286],{"__ignoreMap":824},[1260,1261,1263],"span",{"class":1262,"line":22},"line",[1260,1264,1265],{},"def build_front_door_agent(model) -> Agent:\n",[1260,1267,1268],{"class":1262,"line":32},[1260,1269,1270],{},"    return Agent(\n",[1260,1272,1273],{"class":1262,"line":233},[1260,1274,1275],{},"        model=model,\n",[1260,1277,1278],{"class":1262,"line":244},[1260,1279,1280],{},"        instructions=FRONT_DOOR_INSTRUCTIONS,\n",[1260,1282,1283],{"class":1262,"line":264},[1260,1284,1285],{},"        output_schema=FrontDoorOutcome,\n",[1260,1287,1288],{"class":1262,"line":222},[1260,1289,1290],{},"    )\n",[806,1292,1011,1293,1296,1297,1300,1301,1304,1305,1307,1308,1311,1312,1315,1316,1319],{},[813,1294,1295],{},"The model is a constant, and it must be a priced one."," A turn names no definition, so it has no snapshot and no ",[826,1298,1299],{},"ModelConfig"," to read. ",[826,1302,1303],{},"FRONT_DOOR_MODEL"," sits beside ",[826,1306,1049],{}," and names a pair that ",[826,1309,1310],{},"MODEL_REGISTRY"," holds and ",[826,1313,1314],{},"MODEL_PRICING"," prices. An unpriced model bills ",[826,1317,1318],{},"0.00",", the organization day sum never moves, and the ceiling that gates the next turn can never fire.",[806,1321,1322,1323,1326,1327,1093,1329,1332],{},"There are ",[813,1324,1325],{},"no AgencyCore action tools"," attached to this agent. In particular, ",[826,1328,949],{},[826,1330,1331],{},"cancel"," are not model-callable execution tools. They are deterministic application operations performed only after the structured result is validated.",[806,1334,1335],{},"This keeps Agno responsible for reasoning, while AgencyCore remains responsible for authorization, Run state, validation, and execution.",[806,1337,1338,1340,1341,1343],{},[826,1339,1053],{}," never names Agno. It takes a ",[826,1342,1064],{},", which answers one question:",[818,1345,1347],{"className":1254,"code":1346,"language":1256,"meta":824,"style":824},"@dataclass(frozen=True)\nclass FrontDoorTurn:\n    text: str\n    actor: ActorIdentity\n    conversation_id: UUID\n    context: ContextBrief\n    capabilities: Shortlist\n\n\nclass FrontDoorRuntime(Protocol):\n    async def decide(self, turn: FrontDoorTurn) -> FrontDoorOutcome: ...\n",[826,1348,1349,1354,1359,1364,1369,1374,1379,1384,1390,1394,1399],{"__ignoreMap":824},[1260,1350,1351],{"class":1262,"line":22},[1260,1352,1353],{},"@dataclass(frozen=True)\n",[1260,1355,1356],{"class":1262,"line":32},[1260,1357,1358],{},"class FrontDoorTurn:\n",[1260,1360,1361],{"class":1262,"line":233},[1260,1362,1363],{},"    text: str\n",[1260,1365,1366],{"class":1262,"line":244},[1260,1367,1368],{},"    actor: ActorIdentity\n",[1260,1370,1371],{"class":1262,"line":264},[1260,1372,1373],{},"    conversation_id: UUID\n",[1260,1375,1376],{"class":1262,"line":222},[1260,1377,1378],{},"    context: ContextBrief\n",[1260,1380,1381],{"class":1262,"line":360},[1260,1382,1383],{},"    capabilities: Shortlist\n",[1260,1385,1386],{"class":1262,"line":368},[1260,1387,1389],{"emptyLinePlaceholder":1388},true,"\n",[1260,1391,1392],{"class":1262,"line":375},[1260,1393,1389],{"emptyLinePlaceholder":1388},[1260,1395,1396],{"class":1262,"line":157},[1260,1397,1398],{},"class FrontDoorRuntime(Protocol):\n",[1260,1400,1401],{"class":1262,"line":182},[1260,1402,1403],{},"    async def decide(self, turn: FrontDoorTurn) -> FrontDoorOutcome: ...\n",[806,1405,1011,1406,1409,1410,1412,1413,1416,1417,1420,1421,1424],{},[813,1407,1408],{},"The runtime writes the meter row, and the service does not."," The row exists because the vendor charged, the charge happens inside this one method, and the vendor response is the only place the token counts exist. ",[826,1411,1171],{}," therefore takes a ",[826,1414,1415],{},"UsageRecorder",", exactly as the agent loop's ",[826,1418,1419],{},"bridge.py"," builds its own ",[826,1422,1423],{},"UsageRecord"," where the response lands.",[806,1426,1427,1428,1430,1431,1093,1434,816],{},"This is what makes the retry correct. A memoized replay makes no vendor call, so it must write no second row, and one write outside the memoized step would write one on every attempt. Putting the row where the charge is needs no second key and no second guard. It also leaves ",[826,1429,1181],{}," the only thing the step stores, and that is already a pydantic model, so the codec is ",[826,1432,1433],{},"model_dump_json",[826,1435,1436],{},"model_validate_json",[806,1438,1011,1439,1442,1443,1446,1447,1450],{},[813,1440,1441],{},"A lost row never fails the turn."," ",[826,1444,1445],{},"UsageMeter.record"," raises ",[826,1448,1449],{},"MeteringUnavailable",". A run that meets it ends; a turn has no run to end, and the decision is already paid for. The runtime catches it and logs it. A raise here would leave the memoized step failing, and Inngest would retry it into a second vendor call, which is the one outcome worth more than the row.",[806,1452,1011,1453,1458,1459,1462],{},[813,1454,1455,1457],{},[826,1456,1164],{}," raises, and it answers no failure member."," A vendor that returns prose instead of the schema, and a provider that refuses, are both ",[826,1460,1461],{},"FrontDoorUnavailable",". The turn then fails cleanly and creates no run. A tuple with a nullable outcome would make every caller test for a case that has one handler.",[806,1464,1011,1465,1468],{},[813,1466,1467],{},"A failed call is not metered."," The tokens of a refused parse are spent and no row records them. The vendor response that carries the counts is the response that did not arrive, so the alternative is a guess. The day ceiling under-counts by the failures, and the failures are rare.",[806,1470,1011,1471,1474,1475,1477],{},[813,1472,1473],{},"The port is the memoization seam."," The durable turn function wraps this one method in a memoized step keyed on the message id, so a retry replays the decision, makes no vendor call and writes no second meter row. ",[826,1476,1053],{}," is unchanged by it, because a memoizing runtime satisfies the same protocol.",[840,1479,1053],{"id":1480},"frontdoorservice",[806,1482,1483,1485],{},[826,1484,1053],{}," owns the turn.",[818,1487,1489],{"className":1254,"code":1488,"language":1256,"meta":824,"style":824},"class FrontDoorService:\n    async def handle(\n        self,\n        message: NormalizedMessage,\n        actor: ActorIdentity,\n        conversation,\n        on_progress: Callable[[str], None] = lambda _state: None,\n    ):\n        gate = await self.accrual.check(\n            actor.organization_id,\n            root_run_id=None,\n            ceilings=None,\n            scope='day',\n            principal=None,          # no run exists yet, so there is no grant\n        )\n        if gate.outcome == 'deny':\n            return self.day_limit_reached(gate.reason)\n\n        on_progress(\"thinking\")\n        on_progress(\"checking_context\")\n        entity_refs = await self.entity_scope.list_entity_refs(\n            conversation.id,\n            actor.organization_id,\n            limit=20,\n        )\n\n        context = await self.context_builder.build(          # the shared ContextBuilder\n            ContextRequest(\n                subject=ContextSubject.of_actor(actor),\n                query=message.text,\n                entities=entity_refs,\n                conversation_id=conversation.id,\n            ),\n            FRONT_DOOR_CONTEXT_POLICY,\n        )\n\n        on_progress(\"finding_capability\")\n        capabilities = await self.capability_index.search(actor)\n\n        outcome = await self.runtime.decide(          # it writes its own meter row\n            FrontDoorTurn(\n                text=message.text,\n                actor=actor,\n                conversation_id=conversation.id,\n                context=context,\n                capabilities=capabilities,\n            )\n        )\n\n        return await self.apply(\n            outcome=outcome,\n            actor=actor,\n            message=message,\n            conversation=conversation,\n            capabilities=capabilities,\n            on_progress=on_progress,     # apply() emits preparing_task\n        )\n",[826,1490,1491,1496,1501,1506,1511,1516,1521,1526,1531,1536,1541,1546,1551,1556,1561,1567,1573,1579,1584,1590,1595,1600,1605,1610,1616,1621,1626,1632,1638,1644,1649,1655,1661,1667,1673,1678,1683,1689,1695,1700,1705,1711,1717,1723,1728,1734,1740,1746,1751,1756,1761,1767,1773,1779,1785,1791,1797],{"__ignoreMap":824},[1260,1492,1493],{"class":1262,"line":22},[1260,1494,1495],{},"class FrontDoorService:\n",[1260,1497,1498],{"class":1262,"line":32},[1260,1499,1500],{},"    async def handle(\n",[1260,1502,1503],{"class":1262,"line":233},[1260,1504,1505],{},"        self,\n",[1260,1507,1508],{"class":1262,"line":244},[1260,1509,1510],{},"        message: NormalizedMessage,\n",[1260,1512,1513],{"class":1262,"line":264},[1260,1514,1515],{},"        actor: ActorIdentity,\n",[1260,1517,1518],{"class":1262,"line":222},[1260,1519,1520],{},"        conversation,\n",[1260,1522,1523],{"class":1262,"line":360},[1260,1524,1525],{},"        on_progress: Callable[[str], None] = lambda _state: None,\n",[1260,1527,1528],{"class":1262,"line":368},[1260,1529,1530],{},"    ):\n",[1260,1532,1533],{"class":1262,"line":375},[1260,1534,1535],{},"        gate = await self.accrual.check(\n",[1260,1537,1538],{"class":1262,"line":157},[1260,1539,1540],{},"            actor.organization_id,\n",[1260,1542,1543],{"class":1262,"line":182},[1260,1544,1545],{},"            root_run_id=None,\n",[1260,1547,1548],{"class":1262,"line":290},[1260,1549,1550],{},"            ceilings=None,\n",[1260,1552,1553],{"class":1262,"line":280},[1260,1554,1555],{},"            scope='day',\n",[1260,1557,1558],{"class":1262,"line":272},[1260,1559,1560],{},"            principal=None,          # no run exists yet, so there is no grant\n",[1260,1562,1564],{"class":1262,"line":1563},15,[1260,1565,1566],{},"        )\n",[1260,1568,1570],{"class":1262,"line":1569},16,[1260,1571,1572],{},"        if gate.outcome == 'deny':\n",[1260,1574,1576],{"class":1262,"line":1575},17,[1260,1577,1578],{},"            return self.day_limit_reached(gate.reason)\n",[1260,1580,1582],{"class":1262,"line":1581},18,[1260,1583,1389],{"emptyLinePlaceholder":1388},[1260,1585,1587],{"class":1262,"line":1586},19,[1260,1588,1589],{},"        on_progress(\"thinking\")\n",[1260,1591,1592],{"class":1262,"line":520},[1260,1593,1594],{},"        on_progress(\"checking_context\")\n",[1260,1596,1597],{"class":1262,"line":318},[1260,1598,1599],{},"        entity_refs = await self.entity_scope.list_entity_refs(\n",[1260,1601,1602],{"class":1262,"line":327},[1260,1603,1604],{},"            conversation.id,\n",[1260,1606,1608],{"class":1262,"line":1607},23,[1260,1609,1540],{},[1260,1611,1613],{"class":1262,"line":1612},24,[1260,1614,1615],{},"            limit=20,\n",[1260,1617,1619],{"class":1262,"line":1618},25,[1260,1620,1566],{},[1260,1622,1624],{"class":1262,"line":1623},26,[1260,1625,1389],{"emptyLinePlaceholder":1388},[1260,1627,1629],{"class":1262,"line":1628},27,[1260,1630,1631],{},"        context = await self.context_builder.build(          # the shared ContextBuilder\n",[1260,1633,1635],{"class":1262,"line":1634},28,[1260,1636,1637],{},"            ContextRequest(\n",[1260,1639,1641],{"class":1262,"line":1640},29,[1260,1642,1643],{},"                subject=ContextSubject.of_actor(actor),\n",[1260,1645,1646],{"class":1262,"line":481},[1260,1647,1648],{},"                query=message.text,\n",[1260,1650,1652],{"class":1262,"line":1651},31,[1260,1653,1654],{},"                entities=entity_refs,\n",[1260,1656,1658],{"class":1262,"line":1657},32,[1260,1659,1660],{},"                conversation_id=conversation.id,\n",[1260,1662,1664],{"class":1262,"line":1663},33,[1260,1665,1666],{},"            ),\n",[1260,1668,1670],{"class":1262,"line":1669},34,[1260,1671,1672],{},"            FRONT_DOOR_CONTEXT_POLICY,\n",[1260,1674,1676],{"class":1262,"line":1675},35,[1260,1677,1566],{},[1260,1679,1681],{"class":1262,"line":1680},36,[1260,1682,1389],{"emptyLinePlaceholder":1388},[1260,1684,1686],{"class":1262,"line":1685},37,[1260,1687,1688],{},"        on_progress(\"finding_capability\")\n",[1260,1690,1692],{"class":1262,"line":1691},38,[1260,1693,1694],{},"        capabilities = await self.capability_index.search(actor)\n",[1260,1696,1698],{"class":1262,"line":1697},39,[1260,1699,1389],{"emptyLinePlaceholder":1388},[1260,1701,1702],{"class":1262,"line":503},[1260,1703,1704],{},"        outcome = await self.runtime.decide(          # it writes its own meter row\n",[1260,1706,1708],{"class":1262,"line":1707},41,[1260,1709,1710],{},"            FrontDoorTurn(\n",[1260,1712,1714],{"class":1262,"line":1713},42,[1260,1715,1716],{},"                text=message.text,\n",[1260,1718,1720],{"class":1262,"line":1719},43,[1260,1721,1722],{},"                actor=actor,\n",[1260,1724,1726],{"class":1262,"line":1725},44,[1260,1727,1660],{},[1260,1729,1731],{"class":1262,"line":1730},45,[1260,1732,1733],{},"                context=context,\n",[1260,1735,1737],{"class":1262,"line":1736},46,[1260,1738,1739],{},"                capabilities=capabilities,\n",[1260,1741,1743],{"class":1262,"line":1742},47,[1260,1744,1745],{},"            )\n",[1260,1747,1749],{"class":1262,"line":1748},48,[1260,1750,1566],{},[1260,1752,1754],{"class":1262,"line":1753},49,[1260,1755,1389],{"emptyLinePlaceholder":1388},[1260,1757,1758],{"class":1262,"line":491},[1260,1759,1760],{},"        return await self.apply(\n",[1260,1762,1764],{"class":1262,"line":1763},51,[1260,1765,1766],{},"            outcome=outcome,\n",[1260,1768,1770],{"class":1262,"line":1769},52,[1260,1771,1772],{},"            actor=actor,\n",[1260,1774,1776],{"class":1262,"line":1775},53,[1260,1777,1778],{},"            message=message,\n",[1260,1780,1782],{"class":1262,"line":1781},54,[1260,1783,1784],{},"            conversation=conversation,\n",[1260,1786,1788],{"class":1262,"line":1787},55,[1260,1789,1790],{},"            capabilities=capabilities,\n",[1260,1792,1794],{"class":1262,"line":1793},56,[1260,1795,1796],{},"            on_progress=on_progress,     # apply() emits preparing_task\n",[1260,1798,1800],{"class":1262,"line":1799},57,[1260,1801,1566],{},[806,1803,1011,1804,1442,1814,1816,1817,1093,1820,1823,1824,1826],{},[813,1805,1806,1807,1810,1811,816],{},"The turn holds an ",[826,1808,1809],{},"ActorIdentity",", and it never holds a ",[826,1812,1813],{},"Principal",[826,1815,1813],{}," is the frozen authority of one run: it carries ",[826,1818,1819],{},"run_id",[826,1821,1822],{},"definition_id",", and both are required. A Front Door turn has neither, so a principal here could only be a fake one, and a fake authority is the thing the policy plane exists to refuse. ",[826,1825,901],{}," mints the real principal when the delegate outcome starts a run.",[806,1828,1011,1829,1442,1835,1838,1839,1842,1843,1846,1847,1849],{},[813,1830,1831,1834],{},[826,1832,1833],{},"ContextRequest"," therefore takes a subject, not a principal.",[826,1836,1837],{},"ContextSubject"," carries the four fields the sources actually read: organization, user, trigger and definition. ",[826,1840,1841],{},"Principal.subject"," answers one, so the run path is unchanged, and ",[826,1844,1845],{},"ContextSubject.of_actor()"," answers one for a turn with no definition. Without this seam the Front Door cannot call the shared builder at all. ",[1028,1848,179],{"href":178}," owns the shape.",[806,1851,1852,1855,1856,1858],{},[826,1853,1854],{},"apply()"," is deterministic. It validates identifiers and translates the outcome into either a response or one ",[826,1857,901],{}," command.",[1860,1861,1863],"h3",{"id":1862},"the-turn-is-metered-and-it-is-gated","The turn is metered, and it is gated",[806,1865,1866,1867,1870],{},"The Front Door makes one model call per inbound message, and that call happens ",[813,1868,1869],{},"before any Run exists",". Without the two lines above it would write no usage row and pass no checkpoint, so accrual policy would never see it and no ceiling would stop it. A busy shared channel would then spend with no bound but the addressing rule.",[818,1872,1875],{"className":1873,"code":1874,"language":823,"meta":824},[821],"before the model call   AccrualChecker.check(...)  -> PolicyDecision   deny -> answer that the day limit is reached\nafter the model call    one ai_usage_log row, agent_root_run_id null, conversation id in metadata\n",[826,1876,1874],{"__ignoreMap":824},[806,1878,1011,1879,1442,1886,1889,1890,1893,1894,1897,1898,1901],{},[813,1880,1881,1882,1885],{},"The conversation is recorded in ",[826,1883,1884],{},"metadata",", and it takes no column.",[826,1887,1888],{},"public.ai_usage_log"," has no ",[826,1891,1892],{},"conversation_id",", and the day sum reads every row of the organization with no run filter, so the ceiling already covers a turn that names no run. A column would be a migration on the busiest table in the product to hold a value nothing queries. ",[826,1895,1896],{},"UsageRecord.root_run_id"," becomes ",[826,1899,1900],{},"UUID | None"," to match the column, which is already nullable.",[806,1903,1011,1904,1907],{},[813,1905,1906],{},"A denied turn writes no usage row."," The gate runs before the model call, so a refusal spends nothing and records nothing. \"One row per turn\" means one row per turn that reaches the vendor.",[806,1909,1910,1911,1914,1915,1918,1919,1922,1923,1926],{},"Both reuse what already exists. ",[826,1912,1913],{},"AccrualChecker"," is the same component the runtime calls before each segment, it ",[813,1916,1917],{},"returns"," a ",[826,1920,1921],{},"PolicyDecision"," here exactly as it does there, and ",[826,1924,1925],{},"ai_usage_log"," is the same canonical meter. The Front Door adds no counter of its own.",[806,1928,1929,1930,816],{},"A run has no principal yet at this point, so the check reads the organization day ceiling only. There is no run budget to read. See ",[1028,1931,1932],{"href":287},"policy and governance",[806,1934,1935],{},"A null root run id is the honest record: the spend belongs to a conversation, not to a Run. The organization day total sums both, so one ceiling covers routing and execution together.",[840,1937,1939],{"id":1938},"outcome-contract","Outcome contract",[806,1941,1942,1943,1946,1947,1950,1951,816],{},"The model shape. ",[826,1944,1945],{},"CapabilityId"," is the closed set of five IDs in the ",[1028,1948,1949],{"href":315},"capability contract",". It lives in ",[826,1952,1953],{},"src\u002Fagentic\u002Fshared\u002Fcapabilities.py",[806,1955,1956,1959,1960,1963,1964,1112,1967,1969,1970,1093,1973,1976],{},[826,1957,1958],{},"ResourceRef"," is the ",[826,1961,1962],{},"{kind, id, label}"," pointer to one product row, in\n",[826,1965,1966],{},"src\u002Fagentic\u002Fshared\u002Frefs.py",[1028,1968,179],{"href":178},"\nowns it: the same type carries ",[826,1971,1972],{},"ContextRequest.entities",[826,1974,1975],{},"ContextBrief.items",",\nwhich is what makes the citation check below a set membership and not a parse.",[818,1978,1980],{"className":1254,"code":1979,"language":1256,"meta":824,"style":824},"class FrontDoorAnswer(BaseModel):\n    text: str                                 # nonblank\n    citations: list[ResourceRef] = []         # refs of the supplied brief only\n    unresolved: list[str] = []                # the facts the brief did not carry\n\n\nclass FrontDoorOutcome(BaseModel):\n    kind: Literal[\"answer\", \"clarify\", \"delegate\", \"control_run\"]\n\n    answer: FrontDoorAnswer | None = None\n    question: str | None = None\n\n    capability_id: CapabilityId | UUID | None = None\n    input: dict | None = None\n\n    run_id: UUID | None = None\n    action: Literal[\"cancel\"] | None = None\n",[826,1981,1982,1987,1992,1997,2002,2006,2010,2015,2020,2024,2029,2034,2038,2043,2048,2052,2057],{"__ignoreMap":824},[1260,1983,1984],{"class":1262,"line":22},[1260,1985,1986],{},"class FrontDoorAnswer(BaseModel):\n",[1260,1988,1989],{"class":1262,"line":32},[1260,1990,1991],{},"    text: str                                 # nonblank\n",[1260,1993,1994],{"class":1262,"line":233},[1260,1995,1996],{},"    citations: list[ResourceRef] = []         # refs of the supplied brief only\n",[1260,1998,1999],{"class":1262,"line":244},[1260,2000,2001],{},"    unresolved: list[str] = []                # the facts the brief did not carry\n",[1260,2003,2004],{"class":1262,"line":264},[1260,2005,1389],{"emptyLinePlaceholder":1388},[1260,2007,2008],{"class":1262,"line":222},[1260,2009,1389],{"emptyLinePlaceholder":1388},[1260,2011,2012],{"class":1262,"line":360},[1260,2013,2014],{},"class FrontDoorOutcome(BaseModel):\n",[1260,2016,2017],{"class":1262,"line":368},[1260,2018,2019],{},"    kind: Literal[\"answer\", \"clarify\", \"delegate\", \"control_run\"]\n",[1260,2021,2022],{"class":1262,"line":375},[1260,2023,1389],{"emptyLinePlaceholder":1388},[1260,2025,2026],{"class":1262,"line":157},[1260,2027,2028],{},"    answer: FrontDoorAnswer | None = None\n",[1260,2030,2031],{"class":1262,"line":182},[1260,2032,2033],{},"    question: str | None = None\n",[1260,2035,2036],{"class":1262,"line":290},[1260,2037,1389],{"emptyLinePlaceholder":1388},[1260,2039,2040],{"class":1262,"line":280},[1260,2041,2042],{},"    capability_id: CapabilityId | UUID | None = None\n",[1260,2044,2045],{"class":1262,"line":272},[1260,2046,2047],{},"    input: dict | None = None\n",[1260,2049,2050],{"class":1262,"line":1563},[1260,2051,1389],{"emptyLinePlaceholder":1388},[1260,2053,2054],{"class":1262,"line":1569},[1260,2055,2056],{},"    run_id: UUID | None = None\n",[1260,2058,2059],{"class":1262,"line":1575},[1260,2060,2061],{},"    action: Literal[\"cancel\"] | None = None\n",[806,2063,1011,2064,2067,2068,2071],{},[813,2065,2066],{},"An answer carries its evidence, and the service checks it."," A citation\nnaming a ref the context brief did not supply refuses the whole decision, so\nthe model can neither cite the capability shortlist nor invent a row.\n",[826,2069,2070],{},"unresolved"," is where a missing fact goes, rather than a citation that reads as\na source.",[806,2073,1011,2074,2077,2078,2080,2081,2084],{},[813,2075,2076],{},"Every field is optional, so the kind must be made total by a validator.","\nRead as written, an ",[826,2079,929],{}," with a null payload parses, and the turn then has a\ndecision it cannot apply. One ",[826,2082,2083],{},"model_validator"," requires the fields of each\nkind, and refuses the fields of the other three:",[818,2086,2089],{"className":2087,"code":2088,"language":823,"meta":824},[821],"answer       answer                    and nothing else\nclarify      question                  and nothing else\ndelegate     capability_id             input is optional\ncontrol_run  run_id and action         and nothing else\n",[826,2090,2088],{"__ignoreMap":824},[806,2092,1011,2093,2100,2101,2104],{},[813,2094,2095,2096,2099],{},"The union order is ",[826,2097,2098],{},"CapabilityId | UUID",", and it is not free."," The five\nIDs are a ",[826,2102,2103],{},"Literal",", so a UUID string fails that member and parses as the\nsecond. A string that is neither refuses the whole decision, and the turn then\nfails rather than answering. That is the correct trade: the model reads the\nshortlist in the same call, so an ID outside both formats is a broken vendor\nanswer and not a routing miss.",[806,2106,2107],{},"Validation rules:",[2109,2110,2111,2118,2123,2129],"ul",{},[2112,2113,2114,2117],"li",{},[826,2115,2116],{},"delegate.capability_id"," must be one of the candidates supplied to the model.",[2112,2119,2120,2122],{},[826,2121,901],{}," resolves the definition again before execution. The shortlist is routing information, never execution truth.",[2112,2124,2125,2126,2128],{},"A product ID requires an input that passes that capability's published schema. Do not add a ",[826,2127,823],{}," field.",[2112,2130,2131,2132,2135],{},"A custom definition UUID keeps the existing text fallback: ",[826,2133,2134],{},"{'text': message.text} | (outcome.input or {})",".\nThe UUID and product-ID formats are disjoint; no second outcome and no selector tag is needed.",[806,2137,1011,2138,2145,2146,2150],{},[813,2139,2140,2141,2144],{},"The outcome carries no ",[826,2142,2143],{},"contract_version",", and the turn re-resolves no\nbinding."," Both were in an earlier draft of this page, and both are redundant\non this path. The shortlist read, the schema the model reads and the executor\nthe turn starts all come from one registry read of one turn, so there is no\nwindow in which the model could echo a version the turn did not just supply.\nA second resolve would cost two more reads on the hottest path of the product,\nrefuse a start whose input the current schema accepts, and start the ",[2147,2148,2149],"em",{},"new","\nexecutor after a mid-turn upgrade, while the design rule for an admitted Run\nis that it keeps the binding it was admitted against.",[806,2152,1011,2153,2156,2157,2159,2160,2162,2163,816],{},[813,2154,2155],{},"A product start still goes through the shared capability start service.","\nENG-2329. The turn calls ",[826,2158,955],{}," and passes the\ncapability ID, the contract version, the executor and the input schema of its\none registry read. That entry point reads the registry never, so the rule above\nholds. It owns the request digest, the capability-start key namespace and the\nversion pin, so a chat start and an API start of one product request follow one\nreplay rule. Before it, the turn called ",[826,2161,959],{}," directly: a chat\nstart carried no digest and keyed its delivery in the generic definition\nnamespace, so a redelivered message with edited input replayed the earlier Run\ninstead of answering ",[826,2164,2165],{},"idempotency_conflict",[806,2167,2168,2169,2171],{},"The turn pins the version of its own read, so an executor upgraded between the\nshortlist read and the start no longer matches. ",[826,2170,901],{}," refuses that start\nrather than running the new executor on input the model wrote for the old\nschema. The person reads that the capability changed, and asks again.",[806,2173,2174,2175,2178,2179,2181,2182,2184,2185,2188],{},"The direct start API is the opposite case and reads the registry itself. Its\nclient reads a contract out of band, caches it, and builds a body against it\nhours later, so ",[826,2176,2177],{},"CapabilityStarter.start()"," resolves the ID again and compares\nthe requested version.\n",[1028,2180,250],{"href":249}," owns\nthat route, its ",[826,2183,2143],{}," body field and its ",[826,2186,2187],{},"contract_version_conflict","\nanswer.",[2109,2190,2191,2212,2227,2233],{},[2112,2192,2193,2196,2197,2200,2201,2204,2205,2207,2208,2211],{},[826,2194,2195],{},"control_run.run_id"," must resolve to a Run of the actor's organization.\n",[826,2198,2199],{},"RunRepository.get(run_id, organization_id)"," answers it, exactly as\n",[826,2202,2203],{},"_shared\u002Forg_scope.require_run"," does. ",[826,2206,972],{}," filters on the\nactor's organization itself, so this read is the second tenancy gate and not\nthe only one. It is still required: ",[826,2209,2210],{},"cancel()"," returns None for a foreign run\nand for a run that does not exist, so only this read separates \"I stopped it\"\nfrom \"I could not find that job\".",[2112,2213,2214,1442,2217,2219,2220,2222,2223,2226],{},[813,2215,2216],{},"A terminal run is reported as terminal, on both paths.",[826,2218,2210],{}," matches\nzero rows on one, and ",[826,2221,959],{}," answers ",[826,2224,2225],{},"duplicate"," with whatever\nstatus the first delivery's run now holds. Told \"I stopped that\" for a run\nthat succeeded, or \"that is already running\" for one that finished yesterday,\na person waits for an answer they already have.",[2112,2228,2229,2230,2232],{},"If “stop that” or “change it” could refer to more than one active Run, the outcome must be ",[826,2231,939],{},"; never guess.",[2112,2234,2235],{},"Steering is deferred to V2. A person who wants to change a live Run cancels it, then starts it again with new input. That holds for an Agent Run and for a Workflow Run.",[840,2237,2239],{"id":2238},"one-product-delegation-per-turn","One product delegation per turn",[806,2241,2242,2243,982,2246,982,2249,982,2252,1234,2255,2258],{},"The Front Door can select ",[826,2244,2245],{},"company.search",[826,2247,2248],{},"company.enrich",[826,2250,2251],{},"people.search",[826,2253,2254],{},"people.enrich",[826,2256,2257],{},"signals.search",".\nIt receives eligible IDs, product descriptions and a bounded projection of each input schema. It receives no provider tools, no executor configuration and no executor UUID.\nAn unknown, unauthorized or unavailable selection cannot start work.",[806,2260,2261,2262,2264,2265,2267],{},"A missing required field produces one concrete clarification and no Run, and two\nlayers produce it. The prompt asks the model for ",[826,2263,939],{}," when it does not hold\na required field, and that is the normal path. ",[826,2266,1854],{}," then validates the\nwritten input against the same schema, and a failure there becomes one\ndeterministic clarification naming the failing field paths. It starts no Run.",[806,2269,1011,2270,2273],{},[813,2271,2272],{},"The deterministic clarification names field paths, and that is safe."," A\nfield name is the published product contract, which the read API already serves\nto any caller holding the capability's scopes. It is not executor configuration.\nBound the sentence to the first three failing paths, so a wholly wrong input\ncannot render a wall of text.",[806,2275,2276],{},"A request such as \"find companies, enrich them, then find their directors\" is a compound plan.\nAsk which operation to start unless one published capability already covers the whole requested result.\nDo not silently execute the first step and imply that the remaining steps will follow.\nA company brief inside People Search is allowed because the published workflow owns that child composition.",[806,2278,2279,2280,982,2282,982,2284,1093,2286,2288,2289,982,2292,1234,2295,2298],{},"Keep ",[826,2281,929],{},[826,2283,939],{},[826,2285,949],{},[826,2287,966],{}," as the four outcomes.\nCancel remains a deterministic RunManager operation. Live steering and general multi-capability planning remain deferred.\nThe model does not gain callable ",[826,2290,2291],{},"run_capability",[826,2293,2294],{},"steer_run",[826,2296,2297],{},"cancel_run"," tools.",[840,2300,1205],{"id":2301},"capabilityindex",[806,2303,2304],{},"The Front Door discovers product capabilities and custom Agents\u002FWorkflows, never individual tools.",[818,2306,2308],{"className":1254,"code":2307,"language":1256,"meta":824,"style":824},"class CapabilityIndex:\n    async def search(self, actor: ActorIdentity) -> Shortlist: ...\n\n\n@dataclass(frozen=True)\nclass Shortlist:\n    products: list[ProductSummary]      # at most PRODUCT_LIMIT (5)\n    custom: list[CapabilitySummary]     # at most SHORTLIST_LIMIT (10)\n",[826,2309,2310,2315,2320,2324,2328,2332,2337,2342],{"__ignoreMap":824},[1260,2311,2312],{"class":1262,"line":22},[1260,2313,2314],{},"class CapabilityIndex:\n",[1260,2316,2317],{"class":1262,"line":32},[1260,2318,2319],{},"    async def search(self, actor: ActorIdentity) -> Shortlist: ...\n",[1260,2321,2322],{"class":1262,"line":233},[1260,2323,1389],{"emptyLinePlaceholder":1388},[1260,2325,2326],{"class":1262,"line":244},[1260,2327,1389],{"emptyLinePlaceholder":1388},[1260,2329,2330],{"class":1262,"line":264},[1260,2331,1353],{},[1260,2333,2334],{"class":1262,"line":222},[1260,2335,2336],{},"class Shortlist:\n",[1260,2338,2339],{"class":1262,"line":360},[1260,2340,2341],{},"    products: list[ProductSummary]      # at most PRODUCT_LIMIT (5)\n",[1260,2343,2344],{"class":1262,"line":368},[1260,2345,2346],{},"    custom: list[CapabilitySummary]     # at most SHORTLIST_LIMIT (10)\n",[818,2348,2350],{"className":1254,"code":2349,"language":1256,"meta":824,"style":824},"@dataclass(frozen=True)\nclass CapabilitySummary:\n    id: UUID\n    kind: Literal[\"agent\", \"workflow\"]\n    name: str\n    description: str | None\n\n\n@dataclass(frozen=True)\nclass ProductSummary:\n    capability_id: CapabilityId\n    name: str\n    description: str\n    input_schema: dict[str, Any]\n    executor_id: UUID\n",[826,2351,2352,2356,2361,2366,2371,2376,2381,2385,2389,2393,2398,2403,2407,2412,2417],{"__ignoreMap":824},[1260,2353,2354],{"class":1262,"line":22},[1260,2355,1353],{},[1260,2357,2358],{"class":1262,"line":32},[1260,2359,2360],{},"class CapabilitySummary:\n",[1260,2362,2363],{"class":1262,"line":233},[1260,2364,2365],{},"    id: UUID\n",[1260,2367,2368],{"class":1262,"line":244},[1260,2369,2370],{},"    kind: Literal[\"agent\", \"workflow\"]\n",[1260,2372,2373],{"class":1262,"line":264},[1260,2374,2375],{},"    name: str\n",[1260,2377,2378],{"class":1262,"line":222},[1260,2379,2380],{},"    description: str | None\n",[1260,2382,2383],{"class":1262,"line":360},[1260,2384,1389],{"emptyLinePlaceholder":1388},[1260,2386,2387],{"class":1262,"line":368},[1260,2388,1389],{"emptyLinePlaceholder":1388},[1260,2390,2391],{"class":1262,"line":375},[1260,2392,1353],{},[1260,2394,2395],{"class":1262,"line":157},[1260,2396,2397],{},"class ProductSummary:\n",[1260,2399,2400],{"class":1262,"line":182},[1260,2401,2402],{},"    capability_id: CapabilityId\n",[1260,2404,2405],{"class":1262,"line":290},[1260,2406,2375],{},[1260,2408,2409],{"class":1262,"line":280},[1260,2410,2411],{},"    description: str\n",[1260,2413,2414],{"class":1262,"line":272},[1260,2415,2416],{},"    input_schema: dict[str, Any]\n",[1260,2418,2419],{"class":1262,"line":1563},[1260,2420,2421],{},"    executor_id: UUID\n",[806,2423,1011,2424,2430,2431,2434],{},[813,2425,2426,2429],{},[826,2427,2428],{},"executor_id"," is on the summary, and it never reaches the model."," The\nturn resolved the record already, so a second registry read before the start\nwould buy nothing and cost two statements. ",[826,2432,2433],{},"_render()"," prints the stable ID\nalone, and one test asserts that no executor UUID appears in the prompt. It is\nthe same rule the custom half already keeps for prompts and configuration: the\nindex carries what the turn needs, and renders what the model may read.",[806,2436,1011,2437,2440,2441,2443],{},[813,2438,2439],{},"Two lists, and not one tagged union."," The two halves take different\ninput rules, so the model must be able to tell them apart: a product start\ncarries schema-shaped input and no ",[826,2442,823],{},", and a custom start carries the\nmessage text. A discriminator field on one list would make the model read the\ntag before the rule, and a wrong tag would then pick the wrong input rule\nsilently.",[806,2445,2446],{},"The index combines the product registry with the existing definition reads:",[818,2448,2451],{"className":2449,"code":2450,"language":823,"meta":824},[821],"CapabilityIndex\n   ├── CallerRights.held_by(actor): the rights this caller holds now\n   ↓   (no run.start → two empty halves, and the three reads below never run)\n   ├── CapabilityRegistry.list_capabilities(actor): the available records of the five\n   ├── DefinitionRepository.list_page(org, kind='agent',    origin='custom', state='active')\n   └── DefinitionRepository.list_page(org, kind='workflow', origin='custom', state='active')\n",[826,2452,2450],{"__ignoreMap":824},[806,2454,2455],{},"The last three reads run together. The registry read makes two statements of its own,\nso one delegating turn costs four reads and two waves.",[806,2457,1011,2458,2461,2462,2465,2466,2468],{},[813,2459,2460],{},"The rights are read before both halves, and one answer decides them."," ENG-2341.\n",[826,2463,2464],{},"CapabilityRegistry"," applied this rule to the product half alone, so an actor that could\nstart no run still read every custom Agent and Workflow of the tenant, with names and\ndescriptions. That is a disclosure gap and not a privilege escalation: ",[826,2467,901],{}," mints\nthe Principal and applies admission again, so the actor started nothing. A refusal is the\nsame for every capability, so the branch returns before any read and costs nothing.",[806,2470,1011,2471,2476,2479,2480,2483],{},[813,2472,2473,2475],{},[826,2474,2464],{}," keeps its own check, and the pair is not redundant.",[826,2477,2478],{},"resolve()"," is a start path and the read routes of ",[826,2481,2482],{},"surfaces\u002Fcapabilities"," reach it, so\nboth entry points must fail closed on their own.",[806,2485,1011,2486,1442,2492,2495,2496,2498],{},[813,2487,2488,2489,816],{},"Both readers take one ",[826,2490,2491],{},"PrincipalFactory",[826,2493,2494],{},"RoleRights"," holds the 30-second cache,\nso the second read costs nothing and the two answers cannot disagree inside one turn. Two\nfactories over two ",[826,2497,2494],{}," would read the map twice and could split on a role change.",[806,2500,1011,2501,2504],{},[813,2502,2503],{},"A registry fault fails the turn, and it is not swallowed."," An empty\nproduct half reads to the model as a tenant that installed nothing, so the turn\nwould answer that no published capability can do the work and the person would\ngo and build one. The custom half already fails the turn the same way, so the\ntwo halves behave alike.",[806,2506,2507,2508,2511],{},"The custom path makes two definition reads and merges them on ",[826,2509,2510],{},"(created_at, id)"," descending.\nExclude product-bound definitions, including inactive historical executors, from this custom projection.",[806,2513,1011,2514,2517,2518,982,2521,1442,2524,2526,2527,2529],{},[813,2515,2516],{},"The exclusion is a boundary and not tidiness."," A provisioned executor\nis a ",[826,2519,2520],{},"custom",[826,2522,2523],{},"active",[826,2525,34],{}," of the tenant, so the unfiltered custom read\nreturns it beside its own product record. The model could then delegate to it by\nUUID, and the UUID path adds the message text and validates nothing. The tenant\nwould run ",[826,2528,2245],{}," on an input its closed schema refuses. Filter on the\nrow carrying capability metadata, not on the active binding: an inactive\nhistorical executor is the same hole.",[806,2531,2532],{},"Keep the existing ten-custom-definition allowance and reserve up to five additional slots for eligible products.\nThe two budgets are separate counters, so five recent custom definitions cannot displace a product and a full product set cannot narrow custom routing.",[1860,2534,2536],{"id":2535},"rendering-a-schema","Rendering a schema",[806,2538,1011,2539,2542],{},[813,2540,2541],{},"A published input schema may be 32,768 bytes, and the whole Front Door\ncontext budget is 8,500 tokens."," Five raw schemas can exceed the budget of the\nturn that reads them. The prompt therefore renders a compact projection and\nnever the raw JSON Schema: for each root property, the name, whether it is\nrequired, the type, any enum values, and the bounds a person would need to fill\nit in.",[806,2544,2545],{},"One cap covers one capability, not the section. The vocabulary holds five\nstable IDs, so the section is bounded by five times that number, and a\ncapability renders the same whatever else the tenant installed. A cap over the\nsection would let the first capability spend what the fifth needs.",[806,2547,2548],{},"Over the cap, keep every required field, then take the optional fields in\ndeclared order until the next one would not fit. Render the kept fields in\ndeclared order: a reordered list reads to the model as a different contract.",[806,2550,1011,2551,2554],{},[813,2552,2553],{},"A required field is never dropped."," Truncating one leaves the model\nwriting input that fails validation on every attempt, and the person then reads\na clarification for a field the prompt never showed. If the required fields\nalone exceed the cap, drop the whole capability from the shortlist and log it:\na capability that cannot be described cannot be routed to.",[806,2556,1011,2557,2560,2561,2564,2565,2568],{},[813,2558,2559],{},"A reference hop and a branch hop cost no depth, so depth cannot bound the\nwalk."," The V1 shapes publish ",[826,2562,2563],{},"array of $ref -> oneOf -> object",", and a budget\nthat charged for all three renders every tagged union of the contract as an\nunnamed value. A schema is a finite tree, so a cycle can only run through a\nreference: follow each reference at most once on one path. Pydantic emits a\nself-referencing ",[826,2566,2567],{},"$defs"," union for a recursive discriminated union, so it is a\nschema a tenant can publish.",[806,2570,1011,2571,1442,2579,2582,2583,2585,2586,2589,2590,2593,2594,2596,2597,2600],{},[813,2572,2573,2575,2576,2578],{},[826,2574,600],{}," is ",[826,2577,2520],{},", and the default union is wrong here.",[826,2580,2581],{},"list_page","\nwith no origin also returns the platform templates that are ",[826,2584,2523],{},".\n",[826,2587,2588],{},"DefinitionResolver"," filters on ",[826,2591,2592],{},"organization_id"," alone, so a template resolves\nfor no tenant. A shortlisted template is therefore a ",[826,2595,949],{}," that always\nanswers ",[826,2598,2599],{},"definition_not_found",". A template is a fork source, and it is not a\ncapability.",[806,2602,1011,2603,1442,2609,1093,2612,2615,2616,2619,2620,2623,2624,2627,2628,816],{},[813,2604,2605,2608],{},[826,2606,2607],{},"description"," is a new optional key of the agent config and of the workflow\nconfig.",[826,2610,2611],{},"AGENT_FIELDS",[826,2613,2614],{},"WORKFLOW_FIELDS"," are closed sets, and ",[826,2617,2618],{},"read_keys","\nrefuses an unknown key, so the field must be declared before an author can write\none. The ",[826,2621,2622],{},"skill"," validator already carries the same key. ",[826,2625,2626],{},"Definition"," holds the\nname alone, so the index reads the description out of ",[826,2629,2630],{},"published_config",[806,2632,2633,2634,2637,2638,2641,2642,816],{},"There is no ",[826,2635,2636],{},"AgentDefinitionRepository"," and no ",[826,2639,2640],{},"WorkflowDefinitionRepository",". One repository shape serves agents, workflows and skills. See ",[1028,2643,2644],{"href":365},"runtime definitions",[806,2646,2647],{},"Rules:",[2109,2649,2650,2657,2660,2663,2666,2669,2672,2675],{},[2112,2651,2652,2653,2656],{},"Return only ",[813,2654,2655],{},"published and enabled"," capabilities discoverable by the organization\u002Fprincipal.",[2112,2658,2659],{},"Draft Specs never appear in the index.",[2112,2661,2662],{},"Return routing summaries and product input schemas only: no prompts, skills, Tool Registry schemas, or complete executor definitions.",[2112,2664,2665],{},"Policy admission remains authoritative; capability visibility is not authorization.",[2112,2667,2668],{},"Product lookup uses stable IDs. Custom discovery retains its bounded newest-first definition read.",[2112,2670,2671],{},"Add a lexical filter on the day a catalogue outgrows one page, and embeddings\nonly after that.",[2112,2673,2674],{},"Keep at most five product and ten custom candidates, on two separate counters.",[2112,2676,2677],{},"Render a compact schema projection under one byte cap per capability. Never render a raw published schema, and never render an executor UUID.",[840,2679,2681],{"id":2680},"front-door-context","Front Door context",[806,2683,2684,2685,2688,2689,2692,2693,2696],{},"Front Door context is intentionally smaller than execution context. It is ",[813,2686,2687],{},"not a second builder",". The Front Door calls the shared ",[826,2690,2691],{},"ContextBuilder"," from ",[1028,2694,2695],{"href":178},"state and knowledge"," with one fixed platform policy.",[818,2698,2700],{"className":1254,"code":2699,"language":1256,"meta":824,"style":824},"FRONT_DOOR_CONTEXT_POLICY = ContextPolicy(\n    total_token_budget=...,\n    refresh_on_resume=False,\n    sources=[\n        ContextSourceSpec(name='conversation', token_budget=..., limit=20),\n        ContextSourceSpec(name='application', token_budget=..., limit=20),\n        ContextSourceSpec(name='definition_summary', token_budget=..., limit=20),\n        ContextSourceSpec(\n            name='knowledge',\n            token_budget=...,\n            limit=8,\n            options={'include_platform': True},\n        ),\n        ContextSourceSpec(name='run_history', token_budget=..., limit=5),\n    ],\n)\n\nentity_refs = await conversation_scope.list_entity_refs(\n    conversation.id,\n    actor.organization_id,\n    limit=20,\n)\n\ncontext = await context_builder.build(\n    ContextRequest(\n        subject=ContextSubject.of_actor(actor),\n        query=message.text,\n        entities=entity_refs,\n        conversation_id=conversation.id,\n    ),\n    FRONT_DOOR_CONTEXT_POLICY,\n)\n",[826,2701,2702,2707,2712,2717,2722,2727,2732,2737,2742,2747,2752,2757,2762,2767,2772,2777,2782,2786,2791,2796,2801,2806,2810,2814,2819,2824,2829,2834,2839,2844,2849,2854],{"__ignoreMap":824},[1260,2703,2704],{"class":1262,"line":22},[1260,2705,2706],{},"FRONT_DOOR_CONTEXT_POLICY = ContextPolicy(\n",[1260,2708,2709],{"class":1262,"line":32},[1260,2710,2711],{},"    total_token_budget=...,\n",[1260,2713,2714],{"class":1262,"line":233},[1260,2715,2716],{},"    refresh_on_resume=False,\n",[1260,2718,2719],{"class":1262,"line":244},[1260,2720,2721],{},"    sources=[\n",[1260,2723,2724],{"class":1262,"line":264},[1260,2725,2726],{},"        ContextSourceSpec(name='conversation', token_budget=..., limit=20),\n",[1260,2728,2729],{"class":1262,"line":222},[1260,2730,2731],{},"        ContextSourceSpec(name='application', token_budget=..., limit=20),\n",[1260,2733,2734],{"class":1262,"line":360},[1260,2735,2736],{},"        ContextSourceSpec(name='definition_summary', token_budget=..., limit=20),\n",[1260,2738,2739],{"class":1262,"line":368},[1260,2740,2741],{},"        ContextSourceSpec(\n",[1260,2743,2744],{"class":1262,"line":375},[1260,2745,2746],{},"            name='knowledge',\n",[1260,2748,2749],{"class":1262,"line":157},[1260,2750,2751],{},"            token_budget=...,\n",[1260,2753,2754],{"class":1262,"line":182},[1260,2755,2756],{},"            limit=8,\n",[1260,2758,2759],{"class":1262,"line":290},[1260,2760,2761],{},"            options={'include_platform': True},\n",[1260,2763,2764],{"class":1262,"line":280},[1260,2765,2766],{},"        ),\n",[1260,2768,2769],{"class":1262,"line":272},[1260,2770,2771],{},"        ContextSourceSpec(name='run_history', token_budget=..., limit=5),\n",[1260,2773,2774],{"class":1262,"line":1563},[1260,2775,2776],{},"    ],\n",[1260,2778,2779],{"class":1262,"line":1569},[1260,2780,2781],{},")\n",[1260,2783,2784],{"class":1262,"line":1575},[1260,2785,1389],{"emptyLinePlaceholder":1388},[1260,2787,2788],{"class":1262,"line":1581},[1260,2789,2790],{},"entity_refs = await conversation_scope.list_entity_refs(\n",[1260,2792,2793],{"class":1262,"line":1586},[1260,2794,2795],{},"    conversation.id,\n",[1260,2797,2798],{"class":1262,"line":520},[1260,2799,2800],{},"    actor.organization_id,\n",[1260,2802,2803],{"class":1262,"line":318},[1260,2804,2805],{},"    limit=20,\n",[1260,2807,2808],{"class":1262,"line":327},[1260,2809,2781],{},[1260,2811,2812],{"class":1262,"line":1607},[1260,2813,1389],{"emptyLinePlaceholder":1388},[1260,2815,2816],{"class":1262,"line":1612},[1260,2817,2818],{},"context = await context_builder.build(\n",[1260,2820,2821],{"class":1262,"line":1618},[1260,2822,2823],{},"    ContextRequest(\n",[1260,2825,2826],{"class":1262,"line":1623},[1260,2827,2828],{},"        subject=ContextSubject.of_actor(actor),\n",[1260,2830,2831],{"class":1262,"line":1628},[1260,2832,2833],{},"        query=message.text,\n",[1260,2835,2836],{"class":1262,"line":1634},[1260,2837,2838],{},"        entities=entity_refs,\n",[1260,2840,2841],{"class":1262,"line":1640},[1260,2842,2843],{},"        conversation_id=conversation.id,\n",[1260,2845,2846],{"class":1262,"line":481},[1260,2847,2848],{},"    ),\n",[1260,2850,2851],{"class":1262,"line":1651},[1260,2852,2853],{},"    FRONT_DOOR_CONTEXT_POLICY,\n",[1260,2855,2856],{"class":1262,"line":1657},[1260,2857,2781],{},[806,2859,2860],{},"One builder means one budget model, one failure model and one set of tenancy tests. A private Front Door builder would need all three again.",[1860,2862,2864],{"id":2863},"the-sources-the-current-slice-enables","The sources the current slice enables",[848,2866,2867,2880],{},[851,2868,2869],{},[854,2870,2871,2874,2877],{},[857,2872,2873],{},"Source",[857,2875,2876],{},"Answers",[857,2878,2879],{},"State",[864,2881,2882,2899,2915,2928,2940],{},[854,2883,2884,2889,2892],{},[869,2885,2886],{},[826,2887,2888],{},"conversation",[869,2890,2891],{},"“What did we decide earlier?”",[869,2893,2894,2895,2898],{},"New. It reads ",[826,2896,2897],{},"agent.conversation_messages"," and the conversation summary.",[854,2900,2901,2906,2909],{},[869,2902,2903],{},[826,2904,2905],{},"application",[869,2907,2908],{},"“What is true about this scoped company?”",[869,2910,2911,2912,2914],{},"Resolves supplied ",[826,2913,1958],{},"s only.",[854,2916,2917,2922,2925],{},[869,2918,2919],{},[826,2920,2921],{},"definition_summary",[869,2923,2924],{},"“What visible Agents or Workflows can do this?”",[869,2926,2927],{},"Reads safe metadata for visible published definitions.",[854,2929,2930,2934,2937],{},[869,2931,2932],{},[826,2933,186],{},[869,2935,2936],{},"“What do AgencyCore docs say?”",[869,2938,2939],{},"Retrieves bounded ready platform chunks.",[854,2941,2942,2947,2950],{},[869,2943,2944],{},[826,2945,2946],{},"run_history",[869,2948,2949],{},"“Is my company search still running?”",[869,2951,2952],{},"Built in Phase 3.",[1860,2954,2956],{"id":2955},"entity-scope-is-durable-pointer-state","Entity scope is durable pointer state",[806,2958,1011,2959,1442,2962,2965,2966,2968],{},[813,2960,2961],{},"The conversation scope stores refs, not facts.",[826,2963,2964],{},"agent.conversation_entities"," records conversation-scoped ",[826,2967,1958],{}," pointers with a label, the message that introduced them and the last reference time. The row is a convenience index. The current body still comes from the product reader that owns the ref kind.",[806,2970,2971,2974,2975,2978,2979,2982],{},[826,2972,2973],{},"ApplicationContextSource"," resolves ",[826,2976,2977],{},"request.entities"," and never searches ",[826,2980,2981],{},"request.query",". A malformed, unsupported, stale or foreign ref drops before it reaches model context. If exactly one readable company ref fits “this company”, the answer can use it. If more than one fits, the Front Door asks which one instead of guessing.",[1860,2984,2986],{"id":2985},"the-source-that-is-deferred-and-why","The source that is deferred, and why",[806,2988,1011,2989,1442,2994,2589,2997,3000],{},[813,2990,2991,2993],{},[826,2992,185],{}," cannot scope a Front Door turn.",[826,2995,2996],{},"MemoryContextSource",[826,2998,2999],{},"subject.definition_id",", because a memory belongs to the agent that wrote it. A turn names no definition, so the source has nothing to filter by and returns nothing. Widening memory to a definition-less read is a change to a Phase 3 component and its precedence tests, so it is its own ticket.",[806,3002,3003,3004,3007],{},"The policy allows ",[813,3005,3006],{},"control context and already-scoped context",". It enables no exploratory CRM, email, web or research source. Those are task work, and task work is delegated.",[840,3009,3011],{"id":3010},"shared-run-start-contract","Shared Run start contract",[806,3013,3014,3015,3017,3018,3021],{},"Front Door and Triggers use the same runtime boundary. ",[1028,3016,373],{"href":372}," owns the shape of ",[826,3019,3020],{},"StartRunCommand",", and the Front Door must not create a second start contract.",[806,3023,3024,3025,3028,3029,3031,3032,3034,3035,3038],{},"The Front Door passes the ",[813,3026,3027],{},"actor",", not a minted Principal. ",[826,3030,901],{}," mints the ",[826,3033,1813],{},", because the intersection needs the definition and the Run ID. The ",[826,3036,3037],{},"idempotency_key"," the Front Door supplies protects retries or duplicate inbound delivery from creating duplicate Runs.",[806,3040,3041,3042,3044,3045,3047,3048,3050],{},"A product start reaches that boundary through ",[826,3043,955],{},", which is the shared capability start service and not a second start contract. It namespaces the delivery key, builds the request digest and passes one ",[826,3046,3020],{},". A custom definition start calls ",[826,3049,959],{}," directly and keeps the generic delivery key.",[840,3052,3054],{"id":3053},"delegate-and-cancel","Delegate and cancel",[1860,3056,3057],{"id":949},"Delegate",[818,3059,3062],{"className":3060,"code":3061,"language":823,"meta":824},[821],"delegate outcome\n      │\n      ▼\nvalidate capability id\n      │\n      ├── product ──> CapabilityStarter.start_resolved()\n      │                   digest, key namespace, version pin\n      │\n      ▼\nStartRunCommand\n      │\n      ▼\nRunManager.start()\n      │\n      ▼\nPolicy admission\n   ┌─────────┼────────────────┐\n   ▼         ▼                ▼\n allow      deny      require_approval\n   │         │                │\n   ▼         ▼                ▼\ndispatch   reject      approval + wait\n",[826,3063,3061],{"__ignoreMap":824},[806,3065,3066],{},"The Front Door never inserts a Run row directly and never calls Inngest directly.",[1860,3068,3069],{"id":1331},"Cancel",[818,3071,3074],{"className":3072,"code":3073,"language":823,"meta":824},[821],"control_run(cancel)\n      │\n      ▼\nvalidate Run reference\n      │\n      ▼\nRunManager.cancel()\n      │\n      ▼\nproduct state + runtime cancellation\n",[826,3075,3073],{"__ignoreMap":824},[806,3077,3078],{},"Cancellation is idempotent. Cancelling an already-cancelled Run is still success.",[840,3080,3082],{"id":3081},"progress-ownership","Progress ownership",[806,3084,1011,3085,3090,3091,3094,3095,3098],{},[813,3086,2633,3087,816],{},[826,3088,3089],{},"FrontDoorProgressEmitter"," Open decision 4 below is answered: the durable turn function holds the conversation publisher, so it publishes these events, and ",[826,3092,3093],{},"handle()"," takes an ",[826,3096,3097],{},"on_progress"," callback so it can report the two phases that happen inside it. A callback is a parameter with a no-op default. A protocol would be a component, an injected seam and a fake, on the hottest path of the platform, for one call.",[806,3100,1011,3101,1442,3106,3109,3110,3113,3114,3116,3117,1093,3120,3123],{},[813,3102,3103,3104,816],{},"Two of the four states are only visible from inside ",[826,3105,3093],{},[826,3107,3108],{},"checking_context"," fires before the entity-scope and context reads, and ",[826,3111,3112],{},"finding_capability"," fires before the capability index and decision read. A turn function that wrapped ",[826,3115,3093],{}," from outside could publish ",[826,3118,3119],{},"thinking",[826,3121,3122],{},"preparing_task"," and nothing between them, which is the whole span the person is waiting through. That is why the callback exists and the component does not.",[806,3125,3126],{},"The turn publishes a very small semantic vocabulary while the Front Door owns the work:",[818,3128,3131],{"className":3129,"code":3130,"language":823,"meta":824},[821],"thinking\nchecking_context\nfinding_capability\npreparing_task\n",[826,3132,3130],{"__ignoreMap":824},[806,3134,3135],{},"The Gateway decides how to render or drop these events for each channel. They are semantic UI state, not chain-of-thought.",[818,3137,3140],{"className":3138,"code":3139,"language":823,"meta":824},[821],"Front Door progress ---- delegation ----> Run progress\n       owner                                  owner\n    Front Door                            Runtime\u002FRun\n",[826,3141,3139],{"__ignoreMap":824},[806,3143,3144],{},"When delegation begins:",[3146,3147,3148,3172,3182,3185],"ol",{},[2112,3149,3150,2222,3152,982,3155,3157,3158,3164,3165,3167,3168,3171],{},[826,3151,959],{},[826,3153,3154],{},"started",[826,3156,2225],{},", or a refusal.\n",[813,3159,3160,3161,3163],{},"A ",[826,3162,2225],{}," is not a new turn."," The channel gateway seeds the key from the inbound message id, so a redelivered channel message returns the Run the first delivery created. The turn attaches the stream to that Run and publishes no ",[826,3166,3122],{},", because the work is already under way and a second progress line would double-render it. ",[826,3169,3170],{},"StartRunResult.outcome"," is what says which case it was, so the turn reads it and the service returns it.",[2112,3173,3174,3175,2222,3177,3179,3180,816],{},"If ",[826,3176,959],{},[826,3178,3154],{}," with a non-terminal Run, the turn publishes ",[826,3181,3122],{},[2112,3183,3184],{},"Once a Run owns the work, the turn publishes no more task progress.",[2112,3186,3187],{},"Subsequent progress comes from normalized Run events\u002FSSE.",[806,3189,3190],{},"Do not let Front Door and Runtime emit overlapping progress for the same task.",[840,3192,3194],{"id":3193},"what-it-must-never-do","What it must never do",[848,3196,3197,3210],{},[851,3198,3199],{},[854,3200,3201,3204,3207],{},[857,3202,3203],{},"It must not",[857,3205,3206],{},"Because",[857,3208,3209],{},"Owner",[864,3211,3212,3223,3234,3245,3256,3267,3280],{},[854,3213,3214,3217,3220],{},[869,3215,3216],{},"Run long work",[869,3218,3219],{},"Delegated work outlives the conversational turn",[869,3221,3222],{},"Runtime \u002F Run",[854,3224,3225,3228,3231],{},[869,3226,3227],{},"Do deep research or exploratory business reads",[869,3229,3230],{},"That requires task tools and a budget",[869,3232,3233],{},"Agent \u002F Workflow",[854,3235,3236,3239,3242],{},[869,3237,3238],{},"Manage individual tools",[869,3240,3241],{},"Front Door selects capabilities; Agents select tools",[869,3243,3244],{},"Agent definition \u002F tool layer",[854,3246,3247,3250,3253],{},[869,3248,3249],{},"Decide approval conditions",[869,3251,3252],{},"Governance must behave consistently on every path",[869,3254,3255],{},"Policy plane",[854,3257,3258,3261,3264],{},[869,3259,3260],{},"Step through or mutate a Workflow",[869,3262,3263],{},"Workflow coordination is deterministic execution",[869,3265,3266],{},"Workflow executor",[854,3268,3269,3272,3275],{},[869,3270,3271],{},"Trust model-selected IDs blindly",[869,3273,3274],{},"Model output is not authorization",[869,3276,3277,3278],{},"deterministic validation + ",[826,3279,901],{},[854,3281,3282,3285,3288],{},[869,3283,3284],{},"Insert Run rows or call Inngest",[869,3286,3287],{},"That creates a second lifecycle path",[869,3289,3290],{},[826,3291,901],{},[806,3293,3294],{},"Each forbidden responsibility is a path toward turning the Front Door into a second runtime.",[840,3296,3298],{"id":3297},"failure-handling","Failure handling",[848,3300,3301,3311],{},[851,3302,3303],{},[854,3304,3305,3308],{},[857,3306,3307],{},"Failure",[857,3309,3310],{},"Behaviour",[864,3312,3313,3329,3337,3345,3355,3370,3378,3395,3403,3411,3425,3433],{},[854,3314,3315,3318],{},[869,3316,3317],{},"No suitable capability",[869,3319,3320,3321,3324,3325,3328],{},"Clarify if the intent is ambiguous; otherwise explain that no published capability can perform the task. ⚠️ ",[813,3322,3323],{},"Only a catalogue refusal says this."," A spent budget, a snapshot that will not build and a policy outage each get their own sentence, and ",[826,3326,3327],{},"StartRunResult.reason"," is written for an operator, so it is logged and never shown.",[854,3330,3331,3334],{},[869,3332,3333],{},"Hallucinated capability id",[869,3335,3336],{},"Reject deterministically; never start a Run. An ID in neither format refuses the decision itself, and the turn fails.",[854,3338,3339,3342],{},[869,3340,3341],{},"Product input fails its schema",[869,3343,3344],{},"One deterministic clarification naming the first three failing paths. No Run.",[854,3346,3347,3350],{},[869,3348,3349],{},"Capability disabled after shortlist",[869,3351,3352,3354],{},[826,3353,959],{}," resolves again and fails closed.",[854,3356,3357,3360],{},[869,3358,3359],{},"Capability upgraded after shortlist",[869,3361,3362,3363,3365,3366,3369],{},"No Run starts. The turn pins the contract version of its own registry read, so ",[826,3364,901],{}," finds a binding that no longer matches and answers ",[826,3367,3368],{},"capability_unavailable",". The person reads that the capability changed, and the next turn reads the new contract.",[854,3371,3372,3375],{},[869,3373,3374],{},"Ambiguous Run reference",[869,3376,3377],{},"Ask one clarification question.",[854,3379,3380,3383],{},[869,3381,3382],{},"Admission denied",[869,3384,3385,3386,3388,3389,1050,3391,3394],{},"Return the policy denial reason; do not retry through another path. ",[826,3387,901],{}," carries it on ",[826,3390,3327],{},[826,3392,3393],{},"error_code",", and a refusal with a null reason still names a rule rather than the catalogue.",[854,3396,3397,3400],{},[869,3398,3399],{},"Admission requires approval",[869,3401,3402],{},"Return\u002Fstream the waiting state owned by the Run; approval machinery owns resolution.",[854,3404,3405,3408],{},[869,3406,3407],{},"Front Door model failure",[869,3409,3410],{},"Fail the turn cleanly; do not create a Run from partial output.",[854,3412,3413,3416],{},[869,3414,3415],{},"Duplicate inbound request",[869,3417,3418,3419,3421,3422,3424],{},"Reuse the shared idempotency key so ",[826,3420,959],{}," does not create duplicate work. A product start also compares the request digest, so a redelivery carrying edited input answers ",[826,3423,2165],{}," and starts nothing.",[854,3426,3427,3430],{},[869,3428,3429],{},"The worker retries the turn",[869,3431,3432],{},"The model call is memoized on the message id, so the retry re-reads the decision and does not re-charge.",[854,3434,3435,3438],{},[869,3436,3437],{},"The worker retries after the answer was written",[869,3439,3440],{},"The assistant message is keyed by the message it answers, so the second write updates one row.",[1860,3442,3444],{"id":3443},"the-whole-turn-is-idempotent-and-not-only-the-delegate-half","The whole turn is idempotent, and not only the delegate half",[806,3446,3447,3449,3450,3453,3454,3457,3458,3460],{},[826,3448,959],{}," already protects delegation: the idempotency key derives from ",[826,3451,3452],{},"NormalizedMessage.message_id",", so a redelivered message returns the Run the first delivery created. A product start namespaces that key under ",[826,3455,3456],{},"capability:"," and compares the request digest too, so a redelivery whose input the turn wrote differently answers ",[826,3459,2165],{}," rather than replaying the earlier Run.",[806,3462,1011,3463,3470],{},[813,3464,3465,1093,3467,3469],{},[826,3466,929],{},[826,3468,939],{}," have no such guard, and they need one."," A turn runs on the durable worker, so any retry re-runs the whole body. Without a key, one retry after a successful model call charges the model twice and appends a second assistant bubble to the conversation.",[806,3472,3473],{},"Two rules close it.",[2109,3475,3476,3479],{},[2112,3477,3478],{},"The model call runs inside one memoized durable step, keyed by the message id. A retry replays the stored decision and makes no vendor call.",[2112,3480,3481,3482,3485],{},"The assistant message carries ",[826,3483,3484],{},"in_reply_to"," = the inbound message id, under a unique index. A retry that reaches the write updates the row it already wrote.",[840,3487,3489],{"id":3488},"v1-decisions","V1 decisions",[848,3491,3492,3501],{},[851,3493,3494],{},[854,3495,3496,3498],{},[857,3497,887],{},[857,3499,3500],{},"V1 choice",[864,3502,3503,3513,3521,3529,3537,3545,3554,3562,3570,3578,3586,3594],{},[854,3504,3505,3508],{},[869,3506,3507],{},"Front Door framework",[869,3509,3510,3511],{},"Agno, in-process, behind ",[826,3512,1064],{},[854,3514,3515,3518],{},[869,3516,3517],{},"Model hops",[869,3519,3520],{},"One",[854,3522,3523,3526],{},[869,3524,3525],{},"Routing",[869,3527,3528],{},"Deterministic capability shortlist + one structured model decision",[854,3530,3531,3534],{},[869,3532,3533],{},"Executable targets",[869,3535,3536],{},"One of five product capabilities by stable ID, or a published custom Agent\u002FWorkflow by UUID",[854,3538,3539,3542],{},[869,3540,3541],{},"Product input",[869,3543,3544],{},"Validated against the published schema of the same turn's registry read. No version echo, no second resolve",[854,3546,3547,3550],{},[869,3548,3549],{},"Execution boundary",[869,3551,3552],{},[826,3553,901],{},[854,3555,3556,3559],{},[869,3557,3558],{},"Approval owner",[869,3560,3561],{},"Policy + approval service; Runtime owns wait\u002Fresume",[854,3563,3564,3567],{},[869,3565,3566],{},"Run control",[869,3568,3569],{},"Idempotent cancel only. Steering is V2",[854,3571,3572,3575],{},[869,3573,3574],{},"Capability search",[869,3576,3577],{},"The newest active capabilities of the organization, capped. No query in V1",[854,3579,3580,3583],{},[869,3581,3582],{},"Action tools on Front Door",[869,3584,3585],{},"None",[854,3587,3588,3591],{},[869,3589,3590],{},"Platform documentation",[869,3592,3593],{},"Bounded ready platform chunks from the knowledge source",[854,3595,3596,3599],{},[869,3597,3598],{},"Progress",[869,3600,3601],{},"Four semantic events, then hand off to Run progress",[840,3603,3605],{"id":3604},"rules","Rules",[2109,3607,3608,3614,3620,3626,3632,3638,3646,3652,3658,3664,3670,3676,3682],{},[2112,3609,3610,3613],{},[813,3611,3612],{},"It plans dispatch, not execution."," It chooses one Agent or Workflow and supplies the input.",[2112,3615,3616,3619],{},[813,3617,3618],{},"One model call; no routing model before it."," Capability search is deterministic retrieval, not another agentic hop.",[2112,3621,3622,3625],{},[813,3623,3624],{},"It selects a capability, never a tool."," The selected Agent owns tool selection through its definition.",[2112,3627,3628,3631],{},[813,3629,3630],{},"It selects a product by its stable ID, never by its executor UUID."," The executor UUID is turn state; the stable ID is the product contract.",[2112,3633,3634,3637],{},[813,3635,3636],{},"One agentic hop."," A delegated Agent may create child Runs through the runtime, but it never calls another Front Door.",[2112,3639,3640,3645],{},[813,3641,3642,3643,816],{},"Every delegation goes through ",[826,3644,901],{}," There is no private synchronous execution path.",[2112,3647,3648,3651],{},[813,3649,3650],{},"Ask before dispatch when required input is missing."," One clarification is cheaper than a failed Run.",[2112,3653,3654,3657],{},[813,3655,3656],{},"Policy owns approval."," The Front Door contains no rules such as “500 emails requires approval”.",[2112,3659,3660,3663],{},[813,3661,3662],{},"Platform questions are knowledge questions."," Relevant AgencyCore documentation may be answered directly from retrieved platform context. When retrieval returns no relevant chunk, the Front Door says the available docs do not contain enough information.",[2112,3665,3666,3669],{},[813,3667,3668],{},"Fresh business exploration is delegated."," CRM searches, email searches, web research, and external-system work belong to runtime Agents\u002FWorkflows.",[2112,3671,3672,3675],{},[813,3673,3674],{},"The model never writes Run state."," Structured output is validated before application code acts.",[2112,3677,3678,3681],{},[813,3679,3680],{},"Every turn is metered and gated."," One usage row per turn, and one accrual check before the model call.",[2112,3683,3684,3687],{},[813,3685,3686],{},"Agno remains a reasoning implementation detail."," Product Run state, policy, context ownership, and execution boundaries belong to AgencyCore.",[806,3689,3690],{},"It runs on Agno in-process and must remain fast. It needs no sandbox, MCP server, skill execution, workflow engine, durable agent session, or tool catalogue of its own.",[840,3692,3694],{"id":3693},"open-decisions","Open decisions",[3146,3696,3697,3700,3703,3713,3725],{},[2112,3698,3699],{},"Should the Front Door use an Agno session, or remain stateless over AgencyCore-owned conversation state? Decide with a latency benchmark.",[2112,3701,3702],{},"At what catalogue size does lexical capability search stop being good enough?",[2112,3704,3705,1442,3709,3712],{},[3706,3707,3708],"del",{},"How much platform documentation may consume the Front Door context budget per turn?",[813,3710,3711],{},"Decided: 1,500 tokens across up to eight chunks."," This keeps the whole Front Door context budget at 8,500 tokens.",[2112,3714,3715,1442,3721,3724],{},[3706,3716,3717,3718,3720],{},"Can ",[826,3719,3089],{}," be deleted?",[813,3722,3723],{},"Decided: yes."," The durable turn function publishes the four events. See Progress ownership.",[2112,3726,3727,1442,3730,3735,3736,3738],{},[3706,3728,3729],{},"Where does a conversation store its entity scope?",[813,3731,3732,3733,816],{},"Decided: ",[826,3734,2964],{}," The turn passes the current scoped refs to ",[826,3737,1972],{},". See Entity scope is durable pointer state.",[840,3740,3742],{"id":3741},"minimum-contract-tests","Minimum contract tests",[818,3744,3747],{"className":3745,"code":3746,"language":823,"meta":824},[821],"answer outcome never creates a Run\nclarify outcome never creates a Run\nan outcome missing the field of its own kind is refused\ndelegate accepts only a supplied capability id\ndelegate calls RunManager.start exactly once\ncustom delegate input carries the message-text fallback\nproduct delegate input carries no text key\nproduct delegate input that fails its schema returns clarify and creates no Run\na product start passes the executor uuid the shortlist resolved\ncompound requests never create an implicit multi-start plan\nproduct shortlist entries cannot be displaced by recent custom definitions\na product-bound definition never appears in the custom shortlist\nthe prompt holds no executor uuid and no raw published schema\na required schema field is never dropped by the byte cap\nStartRunCommand carries source + conversation + idempotency key\nthe index returns no skill, no draft, and no platform template\npolicy denial cannot be bypassed by Front Door\na require_approval admission becomes waiting Run state\na disabled capability answers definition_not_published, and the turn reports it\ncontrol_run refuses a Run of another organization\nambiguous Run control returns clarify\ncancel is idempotent\nFront Door never receives the tool registry\na turn that reaches the vendor writes one usage row, with a null root run id\nthe usage row carries the conversation id in metadata\na turn over the organization day ceiling makes no model call, and writes no row\na memoized replay makes no vendor call and writes no second usage row\nthe turn holds an actor, and mints no Principal\n",[826,3748,3746],{"__ignoreMap":824},[806,3750,3751],{},"The turn function owns three more, because it owns the durable step and the\nconversation write:",[818,3753,3756],{"className":3754,"code":3755,"language":823,"meta":824},[821],"progress stops after Run ownership begins\na retried turn makes one model call\na retried turn writes one assistant message, not two\n",[826,3757,3755],{"__ignoreMap":824},[3759,3760,3761],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":824,"searchDepth":32,"depth":233,"links":3763},[3764,3765,3766,3767,3770,3771,3772,3775,3780,3781,3785,3786,3787,3790,3791,3792,3793],{"id":842,"depth":32,"text":843},{"id":1001,"depth":32,"text":1002},{"id":1247,"depth":32,"text":1248},{"id":1480,"depth":32,"text":1053,"children":3768},[3769],{"id":1862,"depth":233,"text":1863},{"id":1938,"depth":32,"text":1939},{"id":2238,"depth":32,"text":2239},{"id":2301,"depth":32,"text":1205,"children":3773},[3774],{"id":2535,"depth":233,"text":2536},{"id":2680,"depth":32,"text":2681,"children":3776},[3777,3778,3779],{"id":2863,"depth":233,"text":2864},{"id":2955,"depth":233,"text":2956},{"id":2985,"depth":233,"text":2986},{"id":3010,"depth":32,"text":3011},{"id":3053,"depth":32,"text":3054,"children":3782},[3783,3784],{"id":949,"depth":233,"text":3057},{"id":1331,"depth":233,"text":3069},{"id":3081,"depth":32,"text":3082},{"id":3193,"depth":32,"text":3194},{"id":3297,"depth":32,"text":3298,"children":3788},[3789],{"id":3443,"depth":233,"text":3444},{"id":3488,"depth":32,"text":3489},{"id":3604,"depth":32,"text":3605},{"id":3693,"depth":32,"text":3694},{"id":3741,"depth":32,"text":3742},"md",{},[3797,3798,3799,3800],"engineering\u002Fsystem-design\u002Fagentic-platform\u002Fcontract","engineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Fchannel-gateway","engineering\u002Fsystem-design\u002Fagentic-platform\u002Fcapabilities\u002Fstate-and-knowledge","engineering\u002Fsystem-design\u002Fagentic-platform\u002Fruntime\u002Fexecution",{"title":242,"description":243},"engineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Ffront-door",[246,247,197,184,198,217],"tr1BV_qNb7MCP3GToqjkjS3ht00xx7-_XoyGEtRrTtw",1788650190860]