Skip to content

Main agent starts private work ​

Opted-in coding runs also obey the first coding baseline admission and durable receipt contract. A plain-language fix request in a proved private requester conversation starts one existing Ship coordinator unit with the question and sourced findings in a durable brief. The dispatcher supplies the requester, conversation, message ID, permissions, and private worker availability. The unit keeps person review and merge gates.

  • Code: src/core/coordinator/contract.ts, src/core/coordinator/mainStart.ts, src/core/coordinator/handOff.ts, src/core/coordinator/instanceStore.ts, src/core/coordinator/requesterAuthority.ts, src/core/coordinator/briefs.ts, src/tools/mainStart.ts, src/tools/toolsets.ts, src/tools/runnableTool.ts, src/core/dispatch/run.ts, src/core/dispatch/provision.ts, src/core/dispatch/runLoop.ts, src/core/dispatch/mainContextCapture.ts, src/core/mainContextRefusal.ts, src/core/dispatch/mainSource.ts, src/core/dispatch/privateConversation.ts, src/core/dispatch/privateDestination.ts, src/core/dispatch/originalOrganizationInput.ts, src/core/dispatch/settle.ts, src/core/dispatcher.ts, src/core/runEvents.ts, src/core/privateMainEvent.ts, src/core/harness/contract.ts, src/core/harness/pi/harness.ts, src/core/harness/opencode/harness.ts, src/core/threadAdmission.ts, src/core/types.ts, src/index.ts, src/agents/registry.ts, deploy/cloudflare-memory/worker.ts
  • Tests: src/core/coordinator/contract.test.ts, src/core/coordinator/mainStart.test.ts, src/core/coordinator/handOff.test.ts, src/core/coordinator/instanceStore.test.ts, src/core/coordinator/briefs.test.ts, src/channels/adminCoordinator.test.ts, src/tools/mainStart.test.ts, src/tools/toolsets.test.ts, src/core/dispatch/run.test.ts, src/core/dispatch/provision.test.ts, src/core/dispatch/mainContextCapture.test.ts, src/core/dispatch/runLoop.test.ts, src/core/dispatch/mainSource.test.ts, src/core/dispatch/settle.test.ts, src/core/harness/pi/harness.test.ts, src/core/harness/opencode/harness.test.ts, src/core/dispatcher.test.ts, deploy/cloudflare-memory/runLedger.test.ts, src/agents/registry.test.ts
CriterionProof
Dispatch freezes structured conversation evidence in a bounded immutable unit capsule before starting a worker. The model cannot supply the capsule; capture failure, a stop, or audience loss during capture starts nothing. Saved unit retries keep the original capsule.[unit] src/tools/mainStart.test.ts::work_start — plain-language private worker handoff::captures trusted context separately from tool arguments and refuses capture failures or changed authority; src/core/coordinator/mainStart.test.ts::main-agent private worker start::persists the original context capsule before worker creation and preserves it on replay
A private work context refusal records each distinct bounded category for an untracked run, absent capture route, each typed checkpoint failure, mismatched checkpoint, snapshot or dependency failure, validation failure, invalid capsule, or unknown exception. The finished run retains these sanitized categories independently of live backlog eviction, middle-event record truncation, and a run restart. No category or private run receipt contains requester text, source names or raw storage errors; the requester sees only a generic private refusal and no child starts. A typed transient checkpoint state-unavailable retries once on the same owned run; permanent, fenced, missing-route, unknown and validation failures never retry.[unit] src/core/dispatch/mainContextCapture.test.ts::private work context capture — durable refusal categories::classifies every capture branch without copying a private source or store error; ::retries only typed transient checkpoint unavailability once on the same owned run; src/tools/mainStart.test.ts::work_start — plain-language private worker handoff::keeps capture refusal private and emits a bounded category without starting a worker; ::waits for the durable refusal receipt before returning the private refusal; src/core/dispatch/runLoop.test.ts::runLoop — the model turn and everything that rides on it::records a sanitized durable work context refusal without a child or private reply leak; ::keeps every private context refusal category after the live backlog evicts its notes; src/core/dispatch/runLoop.test.ts::a resume with the answer in hand…::keeps a prior private capture refusal when a resumed run finishes after its note was lost; src/core/dispatch/record.test.ts::private context refusal receipt on the finished run::retains the bounded category even when the record budget drops its middle note; ::retains the bounded refusal when a reclaimed run has no surviving note
New private work requires a versioned typed brief with explicit hypothesis and uncertainty or unknown cause, nonempty acceptance, declared analysis/evidence requirements and provided evidence or an unavailable reason. Observation labels cannot satisfy required analysis. Invalid input returns typed field issues before the atomic claim; legacy stored briefs remain readable but cannot admit new work.[unit] src/core/coordinator/mainStart.test.ts::main-agent private worker start::returns typed brief issues before claiming incomplete or mislabeled evidence; ::admits explicit unknown cause and unavailable evidence only under the declared policy; src/core/coordinator/handOff.test.ts::main-agent work hand-off::retries a legacy checkpoint under its original act without upgrading or regenerating its brief
A main-agent start binds a bounded question, findings, requested change and acceptance to one fresh person-merged unit. The source message ID gives the act a stable identity; retries preserve the original unit and evidence. A denied repository, foreign origin, missing message ID, unavailable private worker, stopped main run or lost private audience starts nothing. A trusted main-run liveness fence is required and must return true before preflight, after async preflight, before the durable claim and before Workflow creation; missing, unknown, throwing and false fences fail closed, including direct coordinator hand-off.[unit] src/core/coordinator/mainStart.test.ts::main-agent private worker start::binds a plain-language fix and sourced findings to one fresh person-merged unit; ::repeats one user message without starting a second worker or replacing evidence; ::refuses foreign origins, unbound messages, denied repositories, and absent private IO before claiming; ::refuses a stopped main run or lost private audience before claiming; ::refuses a missing or indeterminate main-run fence before claiming; ::rechecks the main-run fence after async preflight before claiming; src/core/coordinator/handOff.test.ts::main-agent work hand-off::requires a live main-run fence even when private worker routing exists
A main-agent task remains a generated, person-merged unit even when its ordinary prose resembles a seeded plan request. A direct hand-off cannot select the unit's branch.[unit] src/core/coordinator/mainStart.test.ts::main-agent private worker start::treats task prose that resembles a plan command as a person-merged fix; src/core/coordinator/handOff.test.ts::main-agent work hand-off::refuses a caller-selected branch for a fresh main task
The main run answers while the worker continues, so it is not reused as the worker host record. The child's task comes from the durable brief. Task prose cannot override coordinator-selected child model, effort or budget.[unit] src/core/coordinator/mainStart.test.ts::main-agent private worker start::repeats one user message without starting a second worker or replacing evidence; src/core/coordinator/briefs.test.ts::composeChild — the child a brief names::a generated unit carries its attributed query result and time window as data into round zero
A started main task's generated unit moves to private IO before coding spawn, with no Slack child thread opened.[unit] src/channels/adminCoordinator.test.ts::the plan runner's steps — plan, unit-start, branch, round, unit-end, finish (item 9)::a plain fix hand-off binds its generated child to private IO before any spawn
The accepted hand-off describes the private work log and does not promise a requester-thread worker or plan card.[unit] src/core/coordinator/handOff.test.ts::main-agent work hand-off::describes a private worker without promising a requester-thread unit or card
The orchestrator exposes work_start only in an attested, unshared requester Slack DM, a verified organization-private browser conversation, or an exact server-attested personal MCP delegation and rechecks the audience before preflight, claim and Workflow creation. A model proposal names a quote from the latest delivered requester turn; the code binds that proposal to the verified source message and the one trusted configured or source-bound repository. Only the latest durable requester revision can authorize a new claim. Mixed senders, unverified follow-ups, absent message IDs and a repo outside pilot configuration refuse. Plane control rows do not change the requester. A stopped main run starts no worker; a durable claim can retry its original unit only while the same requester revision remains current.[unit] src/tools/mainStart.test.ts::work_start — plain-language private worker handoff::*; src/core/dispatch/mainSource.test.ts::main action source::*; src/core/dispatch/admission.test.ts::admit — the thread admission claim::a requester DM question followed by fix it keeps one live run and its private address through durable delivery; src/core/coordinator/mainStart.test.ts::main-agent private worker start::refuses work if a direct conversation becomes shared during repository preflight; src/core/coordinator/mainStart.test.ts::main-agent private worker start::rechecks privacy after a durable claim and before Workflow creation; src/core/coordinator/handOff.test.ts::main-agent work hand-off::stops before a claim and before Workflow create, preserving a safe same-act retry; src/core/dispatch/run.test.ts::claimRun — the ledger claim once the prompt exists::only a direct requester Slack DM main run advertises private work start to the model; src/core/dispatch/runLoop.test.ts::runLoop — the model turn and everything that rides on it::withdraws private work start before a relayed follow-up reaches the model; src/tools/toolsets.test.ts::the toolset table::a shared conversation's model tool list omits linked-work calls while a private one retains them
A refused private work source names the producer's bounded typed cause: compromised or unavailable delivered source, missing or mismatched quote, unavailable authority store, failed or absent durable turn read, superseded turn, or missing or mismatched configured repository. The private run receipt retains only that code, never the message, actor, repository or store error. A quote mismatch returns a bounded literal from the latest delivered turn only after a fresh private-audience check, so the private model can retry in the same conversation; no cause can bypass the original requester, current durable revision, private audience or canonical repository binding.[unit] src/core/dispatch/mainSource.test.ts::main action source::reports a compromised source separately from a quote that is not in the latest turn; ::keeps missing pilot configuration distinct from a mismatched target; src/core/dispatch/runLoop.test.ts::runLoop — the model turn and everything that rides on it::records the private start source predicate without exposing its message or target; src/tools/mainStart.test.ts::work_start — plain-language private worker handoff::binds a quote only to the latest delivered follow-up; ::returns a bounded latest-turn quote for a private same-turn retry
A verified direct requester turn advances a private durable revision before routing or live model delivery. The session log and model quote are context, not authority. For the first pilot, the target repository comes from channel configuration; a question or contextual citation cannot create another target. The main model interprets the whole latest turn and chooses whether to call work_start, answer, or ask once; code does not classify natural-language intent with keyword rules. A later requester turn invalidates an older unclaimed act regardless of its wording. The state Worker compares expected message ID and revision inside the atomic task claim, stores that authority with the link, and refuses old or legacy links. A claimed or new task rechecks the requester revision after final async privacy checks and immediately before Workflow creation.[unit] src/core/dispatch/mainSource.test.ts::main action source::binds only the latest delivered person turn to the configured pilot repository; ::lets a later delivered correction supersede an unstarted earlier act; src/core/dispatcher.test.ts::dispatch::does not infer a work target from question wording; ::records a live DM fix or cancellation before delivering it to the running main agent; ::uses the configured pilot repository for a later main-run fix…; ::does not promote raw Slack history into a cross-run work target; src/core/dispatch/runLoop.test.ts::runLoop — the model turn and everything that rides on it::persists a verified live follow-up before it can start work or revoke an older request; ::keeps the latest work request valid when an earlier follow-up is already superseded; src/core/coordinator/instanceStore.test.ts::private requester revision before a main task claim::records each Slack turn once and makes a later turn revoke an unclaimed act; deploy/cloudflare-memory/runLedger.test.ts::run ledger — main-agent task claims::commits a main task only at the latest private requester revision; src/core/coordinator/handOff.test.ts::main-agent work hand-off::does not create a claimed but absent Workflow after a newer requester turn; ::does not create a newly claimed Workflow when the requester changes during final privacy checks; ::does not retry a saved Workflow when the requester changes during final privacy checks
A staged follow-up becomes a work source only when Pi echoes it or OpenCode confirms the server delivered it. A lost steer cannot start work.[unit] src/core/harness/pi/harness.test.ts::runPiHarness — a run on pi from the first file to the answer::a thread follow-up is steered into pi with the loop's follow-up prompt…; src/core/harness/opencode/harness.test.ts::OpenCodeHarness — the resident's control plane resets under a write::a follow-up's steer whose answer the reset cut after the row landed…
A model tool call may refer only to the latest delivered requester message. An operator-combined or rewritten prompt cannot supply the source quote or a repository outside the pilot binding.[unit] src/core/dispatch/runLoop.test.ts::runLoop — the model turn and everything that rides on it::does not authorize work from an operator-joined prompt when the delivered reply says no; src/core/dispatch/mainSource.test.ts::main action source::binds only the latest delivered person turn to the configured pilot repository
Several unconsumed follow-ups may be merged for an ordinary answer, but the merged turn cannot start private work under the first sender's message ID.[unit] src/core/dispatch/settle.test.ts::prepareFreshTurn — the one request the unconsumed follow-ups run as::does not attest a merged fresh turn as one direct request
The model treats a question alone, quoted instructions and same-turn withdrawal as conversation, not a coding request; it asks once when intent is unclear.[gap] Measure the configured pilot model against question, correction, quoted-evidence and fix-it turns before broadening the pilot.
A deployed main agent starts the child through private IO and reports its reviewed PR in the main thread.[gap] Routing, release and real question-to-PR receipt follow.
Typed tool evidence survives resolved admission, the atomic unit checkpoint and child rendering with directive-looking data escaped. Legacy decoding never satisfies new admission; a hypothesis requires explicit uncertainty.[unit] src/core/coordinator/mainStart.test.ts::main-agent private worker start::preserves typed tool evidence through resolved admission storage and child rendering; src/core/coordinator/contract.test.ts::main-agent work brief::decodes legacy rows without promoting them to new admission; ::requires explicit hypothesis uncertainty and projects only known proposal fields
A canonical worker commits its coordinator identity before attachment and admission notification. Restart retains the original identity without appending another tag. The earlier claim-stage tag proof is replaced by the registration-stage proof.[unit] src/core/dispatch/provision.test.ts::registerRun — the run's row on every surface before the attach::publishes the coordinator admission tag before attachment and never duplicates it on restart
CriterionProof
A new private work capsule identifies its original orchestrator run, requester, channel and thread. Child admission saves that link before the first provider call; the finished child record retains it. The link supplies context only and does not change requester grants or worker permissions.[unit] src/core/dispatcher.test.ts::dispatch::uses the configured pilot repository…; src/core/dispatcher.test.ts::durable structured child context::requires the applicable coding seed acknowledgment…
A proved browser destination starts one original unit; lost proof and JSON guesses start none[unit] src/tools/mainStart.test.ts::work_start — plain-language private worker handoff::starts from a proved browser destination and refuses lost proof or forged JSON audience; src/core/coordinator/mainStart.test.ts::main-agent private worker start::keeps a proved browser request on one original private unit across retry
Browser dispatch binds the original actor, message, admission ordinal and current context; a host repository overrides no body authority[unit] src/core/dispatcher.test.ts::dispatch::starts browser private work through the original owner with captured current context
Browser followups preserve the current actor and source ordinal; JSON cannot restore the private stamp[unit] src/core/dispatch/mainSource.test.ts::main action source::keeps a browser followup's fresh actor and source ordinal and rejects a JSON source guess
An unread private input continues under its consumed original identity with fresh history, without a rival run or cached deleted seed[unit] src/core/dispatcher.test.ts::dispatch::continues an unread private input under its consumed original ledger identity with fresh history
Merged fresh inputs cannot inherit one sender's private proof or original owner[unit] src/core/dispatch/settle.test.ts::prepareFreshTurn — the one request the unconsumed follow-ups run as::keeps a single browser input's original owner and removes private proof from merged inputs

| A protected personal MCP delegation keeps the actual service actor and its own self set while starting one unit credited to the proved human. Only an exact server private-destination capability admits that sender; lost current private proof, forged JSON, mismatched sender/requester and generic services cannot start private work. Current credential and human repository permissions remain conjunctive | [unit] src/tools/mainStart.test.ts::work_start — plain-language private worker handoff::offers a delegated device only through its exact sealed private source and current verifier; src/core/coordinator/mainStart.test.ts::main-agent private worker start::keeps the personal device and human permission ceilings while creating one credited unit |