CL-6324 step 1: the agent-runtime source package - #90
Closed
TheGreatAxios wants to merge 4 commits into
Closed
Conversation
Covers the deploy-time config contract (arktype-parsed, env-delivered) and the two definition shapes its mode selects: the folded unbounded step and the per-turn onTrigger section.
…deploy The workflow.json retirement makes source-ref the only deploy lineage: a deployment's definition is evaluated from its own pinned code closure and re-verified against the hub-approved wire hash. Workbench had no code-sourced package to deploy, so this adds the one every agent run will share. The bytes are static and versioned; everything per-run — mailbox, system prompt, inference chain, tool package pins, credential bindings — arrives as deploy-time config in the child's environment and is parsed at the entry module's boundary. The config's mode selects the shape, so the deploy front keeps one parameter set and never branches on step-vs-section.
The first shape here read the config from the child's environment. That cannot work: the approval probe and the run child each evaluate the entry module independently, and the hashed projection covers the trigger address, the system prompt, the (provider, model) pairs, the tool package pins, and the credential bindings — every field of the config. A config read from outside the closure diverges between the two evaluations and fails the re-verify barrier closed. There is also nowhere to read one from: no source variant carries an overlay, the deploy frame carries no config bag, and the probe frame carries no environment at all. So the config becomes the bytes. renderAgentRuntimeSourceTree emits a thin per-run package that pins this versioned one and calls the builder with the run's config as a literal, ready to commit into a workflow-kind asset and deploy as source at a commitSha — the only source variant cheap enough to mint per run.
This was referenced Aug 20, 2026
Contributor
Author
|
Superseded — |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #87 (
cl-6324-repin-interchange). Step 1 of the deploy-front conversion: give workbench a code-sourced workflow to deploy. Step 2 (the sidecar swap) is not here.What landed
packages/agent-runtime— the versioned definition builder every workbench agent run will deploy, plus the renderer that pins it into a per-run code-sourced package.AgentRuntimeConfig(arktype) is the contract for everything that differs per run: trigger address, system prompt, resolved inference chain, tool-package pins, credential bindings, and themode.buildAgentRuntimeWorkflowreturns either shape from that one config: the folded unbounded single step, or the per-turnonTriggersection. The mode lives in the config, so the deploy front keeps one parameter set and no call site branches on shape —deployCodeSourcedWorkflowalready enumerates inertonTriggerbodies on every deploy.renderAgentRuntimeSourceTreeemits the per-run tree: apackage.jsonwithinterchange.workflowand a four-line entry that imports the builder and calls it with the config as a literal.27 tests, green; package typechecks and lints clean.
The design changed mid-flight, and it matters
The brief called for a static published package whose entry reads deploy-time config. That cannot work at this pin. The approval probe and the run child each evaluate the entry module independently, and the child refuses any definition whose recomputed wire hash differs from the approved one. The hashed projection (
live-inert-projector.ts) covers the trigger address, the agent's system prompt, its(provider, model)pairs, its tool-package pins, and the definition's credential bindings — every field of the config. A config read from outside the closure diverges between the two evaluations and fails closed.There is also nowhere to read one from: no
WorkflowDefinitionSourcevariant carries an overlay or params;AgentDeployWorkflowcarries no config bag (the code-sourced route buildsHarnessConfigwith emptysystemPrompt/tools/grants);SpawnTimeEnvhas no config field; andWorkflowProbeRequestFramecarries no environment at all, so even a sidecar willing to inject one could not make the probe agree.Hence the renderer: the config is the bytes. Behaviour stays in the one versioned package; what varies per run is a JSON literal, committed into a
workflow-kind asset and deployed aspackage.format: "source"at acommitSha— the only source variant whose pin is cheap enough to mint per run.What did not land, and why
deployAtHeadis not converted. Neither code-sourced deploy front accepts a folded run:deployWorkflowFromSourcedeployPreparedCodeSourcedWorkflowA folded run pre-mints its own anchor
workflow_runrow (carrying theprincipalIditsagent_sessionjoin needs), sodeployWorkflowFromSourcecollides on that primary key; and itscommonDeploypasses nocredentialCipher, so every@corbits/mcp-toolslaunch throws insidedeployCodeSourcedWorkflow. The prepared front does both correctly but hard-requires anallocationTarget, and exclusive placement is dormant in-tree. Composing the halves is not open:emitSourceRefDeployFrameandbuildInertProjectionStepSourcesare module-private inhub-sessions.[Intx gap] The missing capability is a shared-capacity code-sourced deploy that adopts a pre-existing anchor run and threads a
credentialCipher—deployPreparedCodeSourcedWorkflowminus the allocation lock. Until it exists,deployAtHeadcannot cut over without forking the front or dismantling the folded run's anchor-row ownership. Rather than ship a half-wired deploy or a shim recreating the deleted front, this PR stops at the contract and documents the blocker.Two further step-2 prerequisites confirmed unimplemented in-tree: nothing produces
CLOSURE_PACKAGE_DIR, and noWorkflowProbeExecutoris wired on the sidecar (every probe answersworkflow.probe.error).[Intx gap]
onBodyFailuredoes not exist at4ed8baf4—OnTriggerOptshas no such field and the projector's onTrigger whitelist has no slot for it. Section mode is authored without it rather than with a workbench-local reimplementation of the primitive. When upstream lands it, it is authored indefinition.ts.Follow-ups
CLOSURE_PACKAGE_DIR, the probe executor, closure staging.deployAtHead+wake.tsonto the renderer.