[{"data":1,"prerenderedAt":2139},["ShallowReactive",2],{"docs-nav":3,"docs-article-engineering\u002Fsystem-design\u002Fagentic-platform\u002Fplanes\u002Fidempotency":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":270,"body":799,"customComponent":480,"description":271,"extension":2133,"group":139,"lastUpdated":259,"meta":2134,"navigation":1028,"order":272,"path":269,"related":480,"section":181,"seo":2135,"stem":2136,"tags":2137,"__hash__":2138},"docs\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Fplanes\u002Fidempotency.md",{"type":800,"value":801,"toc":2118},"minimark",[802,805,809,812,820,825,836,842,848,852,855,904,922,929,935,938,951,955,1238,1255,1258,1272,1295,1313,1323,1329,1369,1375,1400,1406,1411,1414,1422,1428,1434,1440,1448,1453,1456,1462,1465,1472,1483,1498,1501,1505,1511,1563,1573,1586,1595,1599,1605,1608,1613,1617,1687,1697,1707,1713,1719,1743,1749,1756,1761,1765,1768,1774,1777,1781,1827,1831,1836,1854,1857,1871,1934,1941,1945,2035,2039,2114],[803,804,270],"h1",{"id":200},[806,807,808],"p",{},"Idempotency is a plane. Every layer that makes an effect passes through it, and it protects the effect, not the orchestration.",[806,810,811],{},"Repeating the same command should have the same effect as making it once.",[806,813,814,815,819],{},"Use ",[816,817,818],"strong",{},"one durable PostgreSQL table and service",". Do not use Redis or distributed locks for the correctness boundary.",[821,822,824],"h2",{"id":823},"record","Record",[826,827,833],"pre",{"className":828,"code":830,"language":831,"meta":832},[829],"language-text","agent.idempotency_keys\n  id\n  organization_id\n  scope\n  key\n  request_hash\n  status: processing | completed\n  lease_token          the fence; a new value on every claim and reclaim\n  resource_type\n  resource_id\n  response\n  claimed_at\n  lease_expires_at     the worker lease; short\n  retain_until         how long the answer is remembered; long\n","text","",[834,835,830],"code",{"__ignoreMap":832},[826,837,840],{"className":838,"code":839,"language":831,"meta":832},[829],"unique(organization_id, scope, key)\n",[834,841,839],{"__ignoreMap":832},[806,843,844,847],{},[834,845,846],{},"request_hash"," prevents the same key from being reused for different content.",[821,849,851],{"id":850},"two-clocks-not-one","Two clocks, not one",[806,853,854],{},"The lease and the retention answer different questions, and one field cannot hold both.",[856,857,858,874],"table",{},[859,860,861],"thead",{},[862,863,864,868,871],"tr",{},[865,866,867],"th",{},"Field",[865,869,870],{},"Question",[865,872,873],{},"Length",[875,876,877,891],"tbody",{},[862,878,879,885,888],{},[880,881,882],"td",{},[834,883,884],{},"lease_expires_at",[880,886,887],{},"Is the worker that owns this claim still alive?",[880,889,890],{},"the operation timeout, plus a margin",[862,892,893,898,901],{},[880,894,895],{},[834,896,897],{},"retain_until",[880,899,900],{},"Do we still remember what this key did?",[880,902,903],{},"the retry window of the caller",[806,905,906,907,910,911,914,915,917,918,921],{},"A tool claim must be remembered for at least the longest ",[834,908,909],{},"max_run_duration"," any definition may set, because an approval can hold a Run for days and the claim is the replay journal. That is a per definition value and retention is a per scope constant, so the constant takes the ceiling: ",[816,912,913],{},"30 days",", which is also the cap validation puts on ",[834,916,909],{},". A tool claim must ",[816,919,920],{},"also"," be reclaimable within seconds, because a worker that died mid call blocks every retry until its lease ends.",[806,923,924,925,928],{},"One ",[834,926,927],{},"expires_at"," cannot be both. Set it long and a segment that restarts five seconds after a crash meets a live lease it cannot take, so the Run stalls until the lease ends. Set it short and the journal forgets an effect the Run already made, so a restarted segment repeats it.",[826,930,933],{"className":931,"code":932,"language":831,"meta":832},[829],"tool.email.send     lease 60 s          retain 30 days\nwebhook.nylas       lease 30 s          retain 24 hours\nsurface.saved_search.start  lease 30 s  retain 24 hours\n",[834,934,932],{"__ignoreMap":832},[806,936,937],{},"The tool retention is 30 days for every tool scope, not a per tool judgement. The paragraph above takes the ceiling on purpose, so a shorter number here would be the same bug it exists to prevent.",[806,939,940,941,943,944,947,948,950],{},"A claim is reclaimable when ",[834,942,884],{}," has passed and the status is still ",[834,945,946],{},"processing",". A claim is readable while ",[834,949,897],{}," holds, whatever the lease says.",[821,952,954],{"id":953},"repository-and-service","Repository and service",[826,956,960],{"className":957,"code":958,"language":959,"meta":832,"style":832},"language-python shiki shiki-themes github-dark","class IdempotencyRepository(Protocol):\n    async def try_claim(\n        self,\n        organization_id: UUID,\n        scope: str,\n        key: str,\n        request_hash: str,\n        *,\n        lease_token: UUID,            # the caller mints it; it must hold it\n        lease_expires_at: datetime,\n        retain_until: datetime,\n    ) -> IdempotencyRecord | None: ...   # None when the key was already claimed\n\n    async def reclaim(\n        self,\n        organization_id: UUID,\n        scope: str,\n        key: str,\n        *,\n        lease_token: UUID,\n        lease_expires_at: datetime,\n        retain_until: datetime,       # the floor; a reclaim never shortens it\n    ) -> IdempotencyRecord | None: ...   # None when another worker took it\n\n    async def get(\n        self, organization_id: UUID, scope: str, key: str\n    ) -> IdempotencyRecord | None: ...   # the service reads after every conflict\n\n    async def complete(\n        self,\n        claim_id: UUID,\n        lease_token: UUID,\n        *,\n        resource_type: str | None,\n        resource_id: str | None,\n        response: dict | None,\n    ) -> IdempotencyRecord | None: ...   # None when the lease moved on\n\n    async def release(self, claim_id: UUID, lease_token: UUID) -> bool:\n        \"\"\"Delete an unfinished claim we still hold. False when the lease moved on.\"\"\"\n\nclass IdempotencyService:\n    async def read(\n        self, organization_id: UUID, scope: str, key: str, request_hash: str\n    ) -> ClaimOutcome: ...       # never writes; answers 'absent' when nothing is stored\n    async def claim(\n        self, organization_id: UUID, scope: str, key: str, request_hash: str,\n        *, lease: timedelta\n    ) -> ClaimOutcome: ...\n    async def complete(self, claim, *, resource_type, resource_id, response): ...\n    async def release(self, claim): ...\n","python",[834,961,962,969,974,979,984,989,994,999,1004,1009,1014,1019,1024,1030,1035,1040,1045,1050,1055,1060,1065,1069,1074,1080,1085,1091,1097,1103,1108,1114,1118,1124,1129,1134,1140,1146,1152,1158,1163,1169,1174,1179,1185,1191,1197,1203,1209,1215,1221,1227,1232],{"__ignoreMap":832},[963,964,966],"span",{"class":965,"line":22},"line",[963,967,968],{},"class IdempotencyRepository(Protocol):\n",[963,970,971],{"class":965,"line":32},[963,972,973],{},"    async def try_claim(\n",[963,975,976],{"class":965,"line":233},[963,977,978],{},"        self,\n",[963,980,981],{"class":965,"line":244},[963,982,983],{},"        organization_id: UUID,\n",[963,985,986],{"class":965,"line":264},[963,987,988],{},"        scope: str,\n",[963,990,991],{"class":965,"line":222},[963,992,993],{},"        key: str,\n",[963,995,996],{"class":965,"line":360},[963,997,998],{},"        request_hash: str,\n",[963,1000,1001],{"class":965,"line":368},[963,1002,1003],{},"        *,\n",[963,1005,1006],{"class":965,"line":375},[963,1007,1008],{},"        lease_token: UUID,            # the caller mints it; it must hold it\n",[963,1010,1011],{"class":965,"line":157},[963,1012,1013],{},"        lease_expires_at: datetime,\n",[963,1015,1016],{"class":965,"line":182},[963,1017,1018],{},"        retain_until: datetime,\n",[963,1020,1021],{"class":965,"line":290},[963,1022,1023],{},"    ) -> IdempotencyRecord | None: ...   # None when the key was already claimed\n",[963,1025,1026],{"class":965,"line":280},[963,1027,1029],{"emptyLinePlaceholder":1028},true,"\n",[963,1031,1032],{"class":965,"line":272},[963,1033,1034],{},"    async def reclaim(\n",[963,1036,1038],{"class":965,"line":1037},15,[963,1039,978],{},[963,1041,1043],{"class":965,"line":1042},16,[963,1044,983],{},[963,1046,1048],{"class":965,"line":1047},17,[963,1049,988],{},[963,1051,1053],{"class":965,"line":1052},18,[963,1054,993],{},[963,1056,1058],{"class":965,"line":1057},19,[963,1059,1003],{},[963,1061,1062],{"class":965,"line":520},[963,1063,1064],{},"        lease_token: UUID,\n",[963,1066,1067],{"class":965,"line":318},[963,1068,1013],{},[963,1070,1071],{"class":965,"line":327},[963,1072,1073],{},"        retain_until: datetime,       # the floor; a reclaim never shortens it\n",[963,1075,1077],{"class":965,"line":1076},23,[963,1078,1079],{},"    ) -> IdempotencyRecord | None: ...   # None when another worker took it\n",[963,1081,1083],{"class":965,"line":1082},24,[963,1084,1029],{"emptyLinePlaceholder":1028},[963,1086,1088],{"class":965,"line":1087},25,[963,1089,1090],{},"    async def get(\n",[963,1092,1094],{"class":965,"line":1093},26,[963,1095,1096],{},"        self, organization_id: UUID, scope: str, key: str\n",[963,1098,1100],{"class":965,"line":1099},27,[963,1101,1102],{},"    ) -> IdempotencyRecord | None: ...   # the service reads after every conflict\n",[963,1104,1106],{"class":965,"line":1105},28,[963,1107,1029],{"emptyLinePlaceholder":1028},[963,1109,1111],{"class":965,"line":1110},29,[963,1112,1113],{},"    async def complete(\n",[963,1115,1116],{"class":965,"line":481},[963,1117,978],{},[963,1119,1121],{"class":965,"line":1120},31,[963,1122,1123],{},"        claim_id: UUID,\n",[963,1125,1127],{"class":965,"line":1126},32,[963,1128,1064],{},[963,1130,1132],{"class":965,"line":1131},33,[963,1133,1003],{},[963,1135,1137],{"class":965,"line":1136},34,[963,1138,1139],{},"        resource_type: str | None,\n",[963,1141,1143],{"class":965,"line":1142},35,[963,1144,1145],{},"        resource_id: str | None,\n",[963,1147,1149],{"class":965,"line":1148},36,[963,1150,1151],{},"        response: dict | None,\n",[963,1153,1155],{"class":965,"line":1154},37,[963,1156,1157],{},"    ) -> IdempotencyRecord | None: ...   # None when the lease moved on\n",[963,1159,1161],{"class":965,"line":1160},38,[963,1162,1029],{"emptyLinePlaceholder":1028},[963,1164,1166],{"class":965,"line":1165},39,[963,1167,1168],{},"    async def release(self, claim_id: UUID, lease_token: UUID) -> bool:\n",[963,1170,1171],{"class":965,"line":503},[963,1172,1173],{},"        \"\"\"Delete an unfinished claim we still hold. False when the lease moved on.\"\"\"\n",[963,1175,1177],{"class":965,"line":1176},41,[963,1178,1029],{"emptyLinePlaceholder":1028},[963,1180,1182],{"class":965,"line":1181},42,[963,1183,1184],{},"class IdempotencyService:\n",[963,1186,1188],{"class":965,"line":1187},43,[963,1189,1190],{},"    async def read(\n",[963,1192,1194],{"class":965,"line":1193},44,[963,1195,1196],{},"        self, organization_id: UUID, scope: str, key: str, request_hash: str\n",[963,1198,1200],{"class":965,"line":1199},45,[963,1201,1202],{},"    ) -> ClaimOutcome: ...       # never writes; answers 'absent' when nothing is stored\n",[963,1204,1206],{"class":965,"line":1205},46,[963,1207,1208],{},"    async def claim(\n",[963,1210,1212],{"class":965,"line":1211},47,[963,1213,1214],{},"        self, organization_id: UUID, scope: str, key: str, request_hash: str,\n",[963,1216,1218],{"class":965,"line":1217},48,[963,1219,1220],{},"        *, lease: timedelta\n",[963,1222,1224],{"class":965,"line":1223},49,[963,1225,1226],{},"    ) -> ClaimOutcome: ...\n",[963,1228,1229],{"class":965,"line":491},[963,1230,1231],{},"    async def complete(self, claim, *, resource_type, resource_id, response): ...\n",[963,1233,1235],{"class":965,"line":1234},51,[963,1236,1237],{},"    async def release(self, claim): ...\n",[806,1239,1240,1246,1247,1249,1250,1254],{},[816,1241,1242,1245],{},[834,1243,1244],{},"read()"," is a separate method, and it takes no claim."," The tool path reads the journal\nbefore the policy checkpoint and claims after it, so a read that claimed would take the key\nfor a call a person has not yet allowed. That claim then sits ",[834,1248,946],{}," for a whole\nlease and blocks the resume. See ",[1251,1252,1253],"a",{"href":190},"tools and integrations",".",[806,1256,1257],{},"The repository owns atomic SQL behavior; the service owns duplicate semantics.",[806,1259,1260,1263,1264,1267,1268,1271],{},[834,1261,1262],{},"complete()"," on the repository and on the service both name the resource. The\nrecord holds ",[834,1265,1266],{},"resource_type"," and ",[834,1269,1270],{},"resource_id",". A method that writes the id alone\nleaves the type null on every row. A reader then cannot tell a CRM company from a\nNylas message.",[806,1273,1274,1284,1285,1267,1287,1290,1291,1294],{},[816,1275,1276,1279,1280,1283],{},[834,1277,1278],{},"claim()"," takes ",[834,1281,1282],{},"organization_id",", because the unique key starts with it.","\nThis platform has no ambient tenant, and every other repository here takes the\ntenant as an argument. ",[834,1286,1262],{},[834,1288,1289],{},"release()"," filter on ",[834,1292,1293],{},"claim_id",". The\nclaim itself answered that id, so neither needs the tenant again.",[806,1296,1297,1300,1301,1304,1305,1308,1309,1312],{},[816,1298,1299],{},"The lease is an argument, and the retention is a constant."," The table above\nreads as though both come from the scope, and only the retention does. The lease\nis the operation timeout plus a margin, which the caller knows and the scope does\nnot: ",[834,1302,1303],{},"ToolSpec.timeout_s"," runs to the 120 second ",[834,1306,1307],{},"STEP_BUDGET_S",", so a fixed 60 second tool lease\nwould let a second worker reclaim a key while the first is still inside its own\ntimeout. The service raises the retention floor to the lease when a caller asks\nfor a longer one, because the row carries a ",[834,1310,1311],{},"retain_until >= lease_expires_at","\ncheck.",[806,1314,1315,1322],{},[816,1316,1317,1318,1321],{},"The caller mints the lease token, and ",[834,1319,1320],{},"try_claim()"," answers None on a\nconflict."," A worker must hold the token it will carry to its ending, and a\nconflict is the ordinary outcome the caller reads the stored row for.",[806,1324,1325,1328],{},[816,1326,1327],{},"The service answers an outcome, never a record."," The four endings of a claim\nare different things to the caller, and a record makes each caller re-derive\nwhich one it holds.",[826,1330,1332],{"className":957,"code":1331,"language":959,"meta":832,"style":832},"@dataclass(frozen=True)\nclass ClaimOutcome:\n    kind: Literal['absent', 'claimed', 'completed', 'processing', 'conflict']\n    claim: IdempotencyRecord | None   # 'claimed' alone; complete()\u002Frelease() take it\n    response: dict | None             # 'completed' alone; the stored answer\n    resource_type: str | None         # 'completed' alone\n    resource_id: str | None           # 'completed' alone\n",[834,1333,1334,1339,1344,1349,1354,1359,1364],{"__ignoreMap":832},[963,1335,1336],{"class":965,"line":22},[963,1337,1338],{},"@dataclass(frozen=True)\n",[963,1340,1341],{"class":965,"line":32},[963,1342,1343],{},"class ClaimOutcome:\n",[963,1345,1346],{"class":965,"line":233},[963,1347,1348],{},"    kind: Literal['absent', 'claimed', 'completed', 'processing', 'conflict']\n",[963,1350,1351],{"class":965,"line":244},[963,1352,1353],{},"    claim: IdempotencyRecord | None   # 'claimed' alone; complete()\u002Frelease() take it\n",[963,1355,1356],{"class":965,"line":264},[963,1357,1358],{},"    response: dict | None             # 'completed' alone; the stored answer\n",[963,1360,1361],{"class":965,"line":222},[963,1362,1363],{},"    resource_type: str | None         # 'completed' alone\n",[963,1365,1366],{"class":965,"line":360},[963,1367,1368],{},"    resource_id: str | None           # 'completed' alone\n",[826,1370,1373],{"className":1371,"code":1372,"language":831,"meta":832},[829],"absent         the journal has no answer; read() alone answers it\nclaimed        we own the key; execute, then complete or release\ncompleted      the stored result; return it, and mark the span replayed\nprocessing     another worker holds a LIVE lease on this key\nconflict       the same key, with a different request hash\n",[834,1374,1372],{"__ignoreMap":832},[806,1376,1377,1378,1384,1385,1387,1388,1390,1391,1393,1394,1396,1397,1399],{},"⚠️ ",[816,1379,1380,1383],{},[834,1381,1382],{},"absent"," is \"no answer\", not \"no row\"."," A ",[834,1386,946],{}," row whose lease has\npassed belongs to a worker that is gone, and the next caller reclaims it. So\n",[834,1389,1244],{}," answers ",[834,1392,1382],{}," for that row. The caller runs its checkpoints, and\n",[834,1395,1278],{}," performs the atomic reclaim. A read that reported ",[834,1398,946],{}," there\nwould raise on every attempt, the reclaim would never run, and the run would fail\non a worker that died seconds earlier.",[806,1401,1402,1403,1254],{},"The request hash is compared first, whatever the lease says. A passed lease on a\nkey claimed for different content is still a ",[834,1404,1405],{},"conflict",[806,1407,1408,1410],{},[834,1409,946],{}," is ordinary concurrency, and a caller must not answer it with a\nvalue. Three cases reach it: two orchestrator attempts, one duplicate delivery,\nand one fan-out that proposes a call twice. In each one the first worker is\nhealthy and still running. A crashed worker is the rarer case, and its lease\nexpires into the reclaim branch below.",[806,1412,1413],{},"Whatever the cause, the effect may be in flight. A result that reported a failure\nwould state something the platform never observed.",[806,1415,1416,1419,1420,1254],{},[816,1417,1418],{},"A caller that a replaying orchestrator drives raises."," A tool call runs inside\nan Inngest step, so the raise ends the step and Inngest runs it again. The lease\nmust expire before that orchestrator makes its last attempt, or every attempt\nmeets the lease and the run fails. The lease is the operation timeout plus a\nmargin, which satisfies that for the retry policies this platform sets. See\n",[1251,1421,1253],{"href":190},[806,1423,1424,1427],{},[816,1425,1426],{},"A caller at an HTTP boundary does not raise."," A webhook handler is the\noutermost frame. A 5xx tells the vendor that a delivery which succeeded failed.\nSlack disables an Event Subscription that answers 5xx often enough. So the\nhandler drops the delivery, records the reason, and answers its ACK.",[826,1429,1432],{"className":1430,"code":1431,"language":831,"meta":832},[829],"completed   ->  drop reason `duplicate`, then ACK\nprocessing  ->  drop reason `duplicate`, then ACK\nconflict    ->  drop reason `hash_mismatch`, then ACK\n",[834,1433,1431],{"__ignoreMap":832},[806,1435,1436,1439],{},[834,1437,1438],{},"completed"," is the common case. The vendor re-sent a delivery this platform\nalready handled.",[806,1441,1442,1444,1445,1254],{},[834,1443,1405],{}," at a webhook means the vendor re-sent one delivery id with different\ncontent. The delivery is not a duplicate, and it is not safe to process either:\nthe key already answers for a different body. Both endings count a drop reason,\nso neither is a silent loss. See ",[1251,1446,1447],{"href":230},"channel gateway",[1449,1450,1452],"h3",{"id":1451},"the-lease-token-is-a-fence-and-a-reclaim-is-unsafe-without-one","The lease token is a fence, and a reclaim is unsafe without one",[806,1454,1455],{},"A worker that stalls past its lease has not stopped. It wakes up later and finishes.",[826,1457,1460],{"className":1458,"code":1459,"language":831,"meta":832},[829],"worker A claims                       lease 60 s\nworker A stalls\n                                      the lease passes\nworker B reclaims, and executes\nworker A wakes, calls release()    ->  it deletes the claim B holds\nworker A wakes, calls complete()   ->  it stores A's stale answer over B's\n",[834,1461,1459],{"__ignoreMap":832},[806,1463,1464],{},"Either line is worse than having no claim at all. The second hands the next caller a result for work that was really done differently.",[806,1466,1467,1468,1471],{},"So every claim and every reclaim mints a new ",[834,1469,1470],{},"lease_token",", and both endings carry the token they were given.",[826,1473,1477],{"className":1474,"code":1475,"language":1476,"meta":832,"style":832},"language-sql shiki shiki-themes github-dark","UPDATE agent.idempotency_keys SET ... WHERE id = :claim_id AND lease_token = :lease_token\n","sql",[834,1478,1479],{"__ignoreMap":832},[963,1480,1481],{"class":965,"line":22},[963,1482,1475],{},[806,1484,1485,1486,1488,1489,1267,1492,1488,1494,1497],{},"Zero rows means the lease moved on. ",[834,1487,1262],{}," returns ",[834,1490,1491],{},"None",[834,1493,1289],{},[834,1495,1496],{},"False",", and the caller does nothing: it must not retry and it must not raise, because another worker owns that key now.",[806,1499,1500],{},"The reclaim rule and this rule are two halves of one guarantee. The first stops two workers reclaiming at once. The second stops the worker they replaced from writing afterwards.",[821,1502,1504],{"id":1503},"complete-or-release","Complete, or release",[806,1506,1507,1508,1510],{},"A claim has exactly two endings. Leaving it in ",[834,1509,946],{}," is a defect, not a third ending.",[856,1512,1513,1526],{},[859,1514,1515],{},[862,1516,1517,1520,1523],{},[865,1518,1519],{},"Outcome",[865,1521,1522],{},"Ending",[865,1524,1525],{},"Why",[875,1527,1528,1540,1552],{},[862,1529,1530,1533,1537],{},[880,1531,1532],{},"The effect happened",[880,1534,1535],{},[834,1536,1262],{},[880,1538,1539],{},"The answer is now the stored result",[862,1541,1542,1545,1549],{},[880,1543,1544],{},"The effect did not happen, and the caller may try again",[880,1546,1547],{},[834,1548,1289],{},[880,1550,1551],{},"A transient upstream failure must not be remembered as an answer",[862,1553,1554,1557,1560],{},[880,1555,1556],{},"The worker died",[880,1558,1559],{},"the lease expires",[880,1561,1562],{},"Nobody is left to call either method",[806,1564,1565,1568,1569,1572],{},[816,1566,1567],{},"A retryable failure releases the claim."," A tool that returns ",[834,1570,1571],{},"ToolResult(ok=False, retryable=True)"," after a vendor 429 made no effect. If that answer were completed, the stored result would be a failure the caller can never get past: the agent proposes the same call, the claim returns the cached 429, and the Run fails on a vendor that recovered minutes ago.",[806,1574,1575,1578,1579,1267,1582,1585],{},[816,1576,1577],{},"A business failure completes the claim."," ",[834,1580,1581],{},"not_found",[834,1583,1584],{},"invalid_input"," are answers. Repeating the call returns the same answer, and caching it is correct.",[806,1587,1588,1589,1592,1593,1254],{},"The distinction is exactly ",[834,1590,1591],{},"ToolError.retryable",". See ",[1251,1594,1253],{"href":190},[821,1596,1598],{"id":1597},"atomic-claim","Atomic claim",[826,1600,1603],{"className":1601,"code":1602,"language":831,"meta":832},[829],"INSERT ... ON CONFLICT DO NOTHING\n          │\n      ┌───┴────┐\n   inserted  conflict\n      │          │\n   new claim   load row\n                 │\n          request_hash same?\n             ┌───┴───┐\n            no      yes\n            │         │\n         conflict  completed -> return saved result\n                   processing + live lease   -> processing\n                   processing + lease passed -> atomic reclaim\n",[834,1604,1602],{"__ignoreMap":832},[806,1606,1607],{},"Stale claim takeover must itself be conditional\u002Fatomic so two workers cannot reclaim the same lease.",[806,1609,1610,1611,1254],{},"A reclaim moves the lease to the new worker. It never shortens ",[834,1612,897],{},[821,1614,1616],{"id":1615},"boundaries","Boundaries",[856,1618,1619,1632],{},[859,1620,1621],{},[862,1622,1623,1626,1629],{},[865,1624,1625],{},"Boundary",[865,1627,1628],{},"Scope",[865,1630,1631],{},"Stable key",[875,1633,1634,1647,1660,1676],{},[862,1635,1636,1639,1644],{},[880,1637,1638],{},"inbound webhook",[880,1640,1641],{},[834,1642,1643],{},"webhook.\u003Cprovider>",[880,1645,1646],{},"provider delivery ID",[862,1648,1649,1652,1657],{},[880,1650,1651],{},"Tool write\u002Fsend",[880,1653,1654],{},[834,1655,1656],{},"tool.\u003Ctool_name>",[880,1658,1659],{},"Run ID + step path + argument hash",[862,1661,1662,1665,1670],{},[880,1663,1664],{},"saved-search input freeze",[880,1666,1667],{},[834,1668,1669],{},"surface.saved_search.start",[880,1671,1672,1675],{},[834,1673,1674],{},"user:"," + user ID + client key",[862,1677,1678,1681,1684],{},[880,1679,1680],{},"downstream vendor",[880,1682,1683],{},"same Tool scope\u002Fkey",[880,1685,1686],{},"pass same key when supported",[806,1688,1377,1689,1692,1693,1696],{},[816,1690,1691],{},"A provider callback resolves its tenant before it claims."," The key is\nscoped to one organization, and a vendor callback names no organization. The\nhandler reads ",[834,1694,1695],{},"agent.provider_jobs"," first, and claims after it.",[806,1698,1699,1700,1267,1703,1706],{},"Two of its endings never reach a claim, so they carry their own drop reasons\nbeside ",[834,1701,1702],{},"duplicate",[834,1704,1705],{},"hash_mismatch",":",[826,1708,1711],{"className":1709,"code":1710,"language":831,"meta":832},[829],"unknown_job    the path names a job this platform does not hold\njob_mismatch   the body names a different job than the path\n",[834,1712,1710],{"__ignoreMap":832},[806,1714,1715,1716,1254],{},"Both answer an ACK, for the reason every drop here does. See ",[1251,1717,1718],{"href":190},"asynchronous provider jobs",[806,1720,1721,1724,1725,1728,1729,1731,1732,1734,1735,1739,1740,1254],{},[816,1722,1723],{},"Run admission does not use this table."," Its effect is a row we own, so\n",[834,1726,1727],{},"agent.runs"," carries the start key and its insert is the Run claim. One narrow\nsurface exception happens before admission. A saved-search start must freeze a\nbrief and baseline from mutable product tables before it can build the Run\nrequest. ",[834,1730,1669],{}," claims that input preparation and stores\nthe immutable input snapshot as its response. It never records admission,\ndispatch or Run status. The completed claim supplies a stable derived key to\nthe normal ",[834,1733,1727],{}," insert. See ",[1251,1736,1738],{"href":1737},"\u002Fengineering\u002Fsystem-design\u002Fagentic-platform\u002Finterfaces\u002Fsurfaces#start-one-saved-search","saved searches","\nand ",[1251,1741,1742],{"href":372},"runtime execution",[806,1744,1745,1746,1254],{},"Inngest checkpoints orchestration. Idempotency protects the ",[816,1747,1748],{},"business effect",[806,1750,1751,1752,1755],{},"A completed Tool claim returns its stored response, so this table is also the ",[816,1753,1754],{},"agent replay journal",". A restarted segment reads back what the earlier attempt did, and the runtime needs no second table for it.",[806,1757,1758,1759,1254],{},"The Tool key never uses the model tool-call ID. A restarted Agent segment makes the model mint a new one, so that key would miss the earlier claim and repeat the effect. See ",[1251,1760,1253],{"href":190},[821,1762,1764],{"id":1763},"external-side-effects","External side effects",[806,1766,1767],{},"Postgres cannot atomically commit with a vendor API.",[826,1769,1772],{"className":1770,"code":1771,"language":831,"meta":832},[829],"Postgres claim       prevents concurrent local execution\nVendor idempotency   protects crash-after-vendor-success retry\n",[834,1773,1771],{"__ignoreMap":832},[806,1775,1776],{},"If a provider has no idempotency support, the handler needs a provider-specific reconciliation strategy before the operation can be considered retry-safe.",[821,1778,1780],{"id":1779},"what-it-does-not-replace","What it does not replace",[856,1782,1783,1793],{},[859,1784,1785],{},[862,1786,1787,1790],{},[865,1788,1789],{},"Mechanism",[865,1791,1792],{},"Job",[875,1794,1795,1803,1811,1819],{},[862,1796,1797,1800],{},[880,1798,1799],{},"Database unique constraint",[880,1801,1802],{},"business data invariants",[862,1804,1805,1808],{},[880,1806,1807],{},"Approval conditional transition",[880,1809,1810],{},"exactly one human resolution",[862,1812,1813,1816],{},[880,1814,1815],{},"Inngest checkpoint",[880,1817,1818],{},"workflow\u002Fretry progress",[862,1820,1821,1824],{},[880,1822,1823],{},"Idempotency Service",[880,1825,1826],{},"duplicate command\u002Feffect guard",[821,1828,1830],{"id":1829},"retention","Retention",[806,1832,1833,1835],{},[834,1834,897],{}," is set per scope, and a scheduled job deletes past it.",[806,1837,1838,1839,1842,1843,1846,1847,1849,1850,1853],{},"That job is ",[834,1840,1841],{},"idempotency.sweeper",", an Inngest cron beside ",[834,1844,1845],{},"run.reaper",". It runs on the hour, which is 24 times finer than the shortest retention it enforces. Nothing else deletes a claim: ",[834,1848,1289],{}," removes an unfinished one, and a completed one ",[816,1851,1852],{},"is"," the journal, so it must outlive every replay that could read it.",[806,1855,1856],{},"A row the sweep deletes is answerable by nobody. The Run that claimed it ended at least a retention ago, so no replay can reach it.",[806,1858,1377,1859,1862,1863,1866,1867,1870],{},[816,1860,1861],{},"The pass is bounded, and the READ count is what says whether it keeps up."," An unbounded delete would hold row locks over every expired claim of every tenant, on the table the tool call path writes. A pass whose read fills its bound leaves rows for the next hour and logs a warning, so a backlog that never drains is visible without reading every quiet pass. The bound stays under ",[834,1864,1865],{},"PGRST_DB_MAX_ROWS",", because PostgREST truncates a read there and reports the truncation in ",[834,1868,1869],{},"Content-Range"," alone, and a larger bound is refused rather than clamped. The delete count answers a different question: a writer that removes a claim between the read and the delete lowers it, and says nothing about the backlog.",[856,1872,1873,1885],{},[859,1874,1875],{},[862,1876,1877,1879,1883],{},[865,1878,1628],{},[865,1880,1881],{},[834,1882,897],{},[865,1884,1525],{},[875,1886,1887,1899,1911,1923],{},[862,1888,1889,1893,1896],{},[880,1890,1891],{},[834,1892,1643],{},[880,1894,1895],{},"24 hours, or the provider window when it is longer",[880,1897,1898],{},"The vendor retry window",[862,1900,1901,1906,1908],{},[880,1902,1903],{},[834,1904,1905],{},"tool.\u003Cname>",[880,1907,913],{},[880,1909,1910],{},"The claim is the replay journal, and an approval holds a Run for days",[862,1912,1913,1917,1920],{},[880,1914,1915],{},[834,1916,1669],{},[880,1918,1919],{},"24 hours",[880,1921,1922],{},"The browser recovery window; an admitted Run replays through its own stable key",[862,1924,1925,1928,1931],{},[880,1926,1927],{},"A send with a vendor key",[880,1929,1930],{},"at least the vendor idempotency window",[880,1932,1933],{},"The two keys must expire together",[806,1935,1936,1937,1940],{},"Do not retain a large saved response indefinitely. A response above the store limit keeps a ",[834,1938,1939],{},"ResourceRef"," in place of the body.",[821,1942,1944],{"id":1943},"rules","Rules",[1946,1947,1948,1952,1955,1960,1967,1970,1976,1986,1989,1999,2002,2005,2014,2017,2020,2023,2026,2029],"ul",{},[1949,1950,1951],"li",{},"PostgreSQL is source of truth.",[1949,1953,1954],{},"Claim and stale reclaim are atomic repository operations.",[1949,1956,1957,1958,1254],{},"Every claim and reclaim mints a new ",[834,1959,1470],{},[1949,1961,1962,1267,1964,1966],{},[834,1963,1262],{},[834,1965,1289],{}," are conditional on the token. A lost fence is a silent no-op.",[1949,1968,1969],{},"Same key + different request hash is a conflict.",[1949,1971,1972,1973,1975],{},"Live ",[834,1974,946],{}," claim is never executed a second time.",[1949,1977,1978,1979,1981,1982,1985],{},"A live ",[834,1980,946],{}," claim is not a value. A caller an orchestrator replays raises ",[834,1983,1984],{},"ClaimInFlight","; an HTTP boundary drops the delivery.",[1949,1987,1988],{},"A lease expires before the orchestrator's last retry attempt, or every attempt meets it.",[1949,1990,1991,1390,1993,1995,1996,1998],{},[834,1992,1244],{},[834,1994,1382],{}," for a claim whose lease passed, so ",[834,1997,1278],{}," reclaims it.",[1949,2000,2001],{},"Completed claim returns saved resource\u002Fresult.",[1949,2003,2004],{},"The lease and the retention are two clocks. Never derive one from the other.",[1949,2006,2007,2008,2010,2011,2013],{},"A claim ends in ",[834,2009,1262],{}," or ",[834,2012,1289],{},", and both endings are terminal.",[1949,2015,2016],{},"A completion carries a response or a resource. One that records neither replays an empty success.",[1949,2018,2019],{},"A retryable failure releases. A business failure completes.",[1949,2021,2022],{},"Pass key to downstream vendor when supported.",[1949,2024,2025],{},"Idempotency logic is shared; Tool\u002FTrigger\u002FRun layers do not reimplement it.",[1949,2027,2028],{},"A Tool claim outlives the Run it belongs to.",[1949,2030,2031,2032,2034],{},"Run admission is guarded by a unique index on ",[834,2033,1727],{},", never by this table. The saved-search surface claim freezes input before admission and does not claim the Run.",[821,2036,2038],{"id":2037},"minimum-contract-tests","Minimum contract tests",[1946,2040,2041,2044,2047,2050,2053,2056,2059,2062,2065,2073,2076,2079,2082,2085,2088,2091,2097,2102,2105,2108,2111],{},[1949,2042,2043],{},"20 concurrent claims for same key produce one owner.",[1949,2045,2046],{},"A direct capability or generic definition start writes no row in this table.",[1949,2048,2049],{},"A saved-search start atomically freezes one input before Run admission; 20 concurrent preparations produce one snapshot.",[1949,2051,2052],{},"A live saved-search preparation returns retryable in-progress. One caller reclaims it after the 30-second lease.",[1949,2054,2055],{},"A saved-search preparation fence lost before completion starts no Run.",[1949,2057,2058],{},"A saved-search snapshot remains for 24 hours. Its stable Run key replays an admitted Run through the 396-day Run retention window.",[1949,2060,2061],{},"Same key\u002Fdifferent hash fails.",[1949,2063,2064],{},"Completed duplicate returns stored resource\u002Fresult.",[1949,2066,2067,2069,2070,2072],{},[834,2068,1244],{}," writes no row, and it answers ",[834,2071,1382],{}," for a claim whose lease passed.",[1949,2074,2075],{},"A crashed worker's claim is reclaimed by the next caller, and the run continues.",[1949,2077,2078],{},"Live lease cannot be stolen.",[1949,2080,2081],{},"A live lease on the caller's own key raises, and no result reports it.",[1949,2083,2084],{},"A passed lease is reclaimed by exactly one worker.",[1949,2086,2087],{},"A worker whose lease passed cannot complete the claim afterwards.",[1949,2089,2090],{},"A worker whose lease passed cannot release the claim another worker holds.",[1949,2092,2093,2094,2096],{},"A claim whose lease passed is still readable while ",[834,2095,897],{}," holds.",[1949,2098,2099,2100,1254],{},"A reclaim moves the lease and never shortens ",[834,2101,897],{},[1949,2103,2104],{},"A retryable tool failure releases the claim, and the next attempt executes.",[1949,2106,2107],{},"A business failure completes the claim, and the next attempt returns the stored answer.",[1949,2109,2110],{},"Vendor idempotency prevents duplicate send after crash\u002Fretry.",[1949,2112,2113],{},"A Tool claim survives a Run that waited on an approval for longer than a day.",[2115,2116,2117],"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":832,"searchDepth":32,"depth":233,"links":2119},[2120,2121,2122,2125,2126,2127,2128,2129,2130,2131,2132],{"id":823,"depth":32,"text":824},{"id":850,"depth":32,"text":851},{"id":953,"depth":32,"text":954,"children":2123},[2124],{"id":1451,"depth":233,"text":1452},{"id":1503,"depth":32,"text":1504},{"id":1597,"depth":32,"text":1598},{"id":1615,"depth":32,"text":1616},{"id":1763,"depth":32,"text":1764},{"id":1779,"depth":32,"text":1780},{"id":1829,"depth":32,"text":1830},{"id":1943,"depth":32,"text":1944},{"id":2037,"depth":32,"text":2038},"md",{},{"title":270,"description":271},"engineering\u002Fsystem-design\u002Fagentic-platform\u002Fplanes\u002Fidempotency",[200,217,194,274,275],"fyu5LOOuApdJ1vhp2ZpPCt5MU22uj6sv0S9qi6i4SBQ",1788650194450]