Skip to content

CL-6324 step 1: the agent-runtime source package - #90

Closed
TheGreatAxios wants to merge 4 commits into
cl-6324-repin-interchangefrom
cl-6324-conversion-step1
Closed

CL-6324 step 1: the agent-runtime source package#90
TheGreatAxios wants to merge 4 commits into
cl-6324-repin-interchangefrom
cl-6324-conversion-step1

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

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 the mode.
  • buildAgentRuntimeWorkflow returns either shape from that one config: the folded unbounded single step, or the per-turn onTrigger section. The mode lives in the config, so the deploy front keeps one parameter set and no call site branches on shape — deployCodeSourcedWorkflow already enumerates inert onTrigger bodies on every deploy.
  • renderAgentRuntimeSourceTree emits the per-run tree: a package.json with interchange.workflow and 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 WorkflowDefinitionSource variant carries an overlay or params; AgentDeployWorkflow carries no config bag (the code-sourced route builds HarnessConfig with empty systemPrompt/tools/grants); SpawnTimeEnv has no config field; and WorkflowProbeRequestFrame carries 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 as package.format: "source" at a commitSha — the only source variant whose pin is cheap enough to mint per run.

What did not land, and why

deployAtHead is not converted. Neither code-sourced deploy front accepts a folded run:

Front Anchor row Credential cipher Capacity
deployWorkflowFromSource INSERTs not threaded shared
deployPreparedCodeSourcedWorkflow UPDATEs threaded exclusive allocation only

A folded run pre-mints its own anchor workflow_run row (carrying the principalId its agent_session join needs), so deployWorkflowFromSource collides on that primary key; and its commonDeploy passes no credentialCipher, so every @corbits/mcp-tools launch throws inside deployCodeSourcedWorkflow. The prepared front does both correctly but hard-requires an allocationTarget, and exclusive placement is dormant in-tree. Composing the halves is not open: emitSourceRefDeployFrame and buildInertProjectionStepSources are module-private in hub-sessions.

[Intx gap] The missing capability is a shared-capacity code-sourced deploy that adopts a pre-existing anchor run and threads a credentialCipherdeployPreparedCodeSourcedWorkflow minus the allocation lock. Until it exists, deployAtHead cannot 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 no WorkflowProbeExecutor is wired on the sidecar (every probe answers workflow.probe.error).

[Intx gap] onBodyFailure does not exist at 4ed8baf4OnTriggerOpts has 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 in definition.ts.

Follow-ups

  1. Upstream: the anchor-adopting shared code-sourced deploy.
  2. Step 2: CLOSURE_PACKAGE_DIR, the probe executor, closure staging.
  3. Then deployAtHead + wake.ts onto the renderer.

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.
@TheGreatAxios

Copy link
Copy Markdown
Contributor Author

Superseded — packages/agent-runtime is on main already.

@TheGreatAxios
TheGreatAxios deleted the cl-6324-conversion-step1 branch August 25, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant