Skip to content

kernel+spec: gate 7 slice 1 — declare placement requirements and journal the routing decision #225

Description

@kjgbot

Gate 1 is met and gate 5's substrate landed, so RFC-0001's horizontals are open. This is gate 7's first slice, and it is much smaller than the gate reads, because the hard part already exists elsewhere.

What already exists — do not rebuild it

AgentWorkforce/cloud solves placement and source continuity today:

capability where
run source uploaded and extracted into the sandbox packages/core/src/code-sync/, storage/code-transfer
per-root leases, one-shot sync vs continuous daemon, acquire/release packages/core/src/executor/sandbox-orchestrator.ts
one sandbox for a whole run, steps sharing a tree by default bootstrap (SandboxedStepExecutor, writeRunManifest)
provider runtimes packages/core/src/runtime/{daytona,local-http}.ts

This issue is not about reimplementing any of that. It is about the flows-side contract that lets a step ask for placement and lets the journal record what was chosen.

Verified absent on the flows side

  • requirements, sandbox, placement: 0 occurrences in packages/sdk/src/spec.ts. A step cannot state what it needs.
  • The routing decision is not a journal entry. Gate 7 requires "the routing decision (profile matched, provider chosen, fallbacks attempted) is a journal entry".
  • Pins — the type that would bind a step to a workspace revision — is returned empty: worker.rs:70, Ok(Pins::default()). The contract is declared in entry.rs:185 (WorkspacePin { surface, revision_id }, documented as journal facts, never spec fields) and nothing populates it.

Acceptance, taken from a live failure

AgentWorkforce/relayflows#52 is effectively this gate's acceptance test, already written up with a reproduction. Its Daytona backend:

  1. provisions a separate sandbox per deterministic step, so two steps cannot see one tree;
  2. never syncs source, and passes the runner's local cwd to a remote machine — surfacing as fork/exec /usr/bin/bash: no such file or directory, which blames the shell for a missing directory;
  3. exposes no sandbox id, so no sandbox is identifiable from the run.

Those are gate 7's three requirements stated as failures. Proposed acceptance here, pinning the property rather than an API:

  • A flow whose steps declare requirements runs unchanged locally and against a remote provider, with no placement config in the flow — gate 7's own wording.
  • Two deterministic steps in one run observe one tree: step 1 writes a file, step 2 reads it back. That single test kills symptom 1 and 2 together.
  • The journal carries the routing decision — profile matched, provider chosen, fallbacks attempted — and replay reproduces it without re-deciding.
  • Pins is populated with the workspace revision each step started from, so the run is bound to a source revision rather than to whatever the machine happened to hold.
  • Killing the sandbox mid-step resumes per gate 1's contract.

Scope discipline

Slice 1 is the declaration and the journal record. Provider selection can be a fixed choice; the point is that the choice is declared by the step, made by the engine, and written to the journal — not that the ranking is clever yet. Cost/latency/reliability ranking is a later slice.

Do not add a second sandbox implementation. If the engine needs to place work remotely, it should reach cloud's existing orchestration; relayflows#52 exists precisely because a third, thinner implementation was written instead of using the path that already worked.

Ledger: https://claude.ai/code/artifact/1edcf8ae-af0c-4115-b953-df5bd8cdd0c9

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions