diff --git a/ops/NEXT.md b/ops/NEXT.md index 649c80cc6..86ababf65 100644 --- a/ops/NEXT.md +++ b/ops/NEXT.md @@ -1,87 +1,82 @@ # NEXT — work package for this tick -**Scope:** Build a minimal agent worker in the SDK. CODE task, SDK-side. +**Scope:** Make CI run the suites it already has. CI task, `.github/` only. -This run is pinned to **gate 3** and must not work on any other gate. +This run is pinned to **the CI coverage gap** and must not work on any other +gate. It is a small change with an outsized effect, and it is the reason six of +eight independent signoffs on 2026-09-03 found P0s in PRs that were green. ## Objective -Promote the throwaway worker the tests already build into a real SDK component -that can execute agent steps by running their declared CLI as a subprocess. - -## Context - -Nothing in this repo can execute an agent step. Searching for `workerAttach` / -`step.complete` finds only TESTS (`sdk/tests/live-kernel.test.ts`, -`journal-client.test.ts`, `journal-client-loopback.ts`) and the protocol -definitions. `sdk/src/cli/run.ts` only OBSERVES worker leases and waits for one -that never arrives. - -The kernel's dispatch, lease and claim machinery is real and tested. The worker -side of the protocol is simply unimplemented, and that is what blocks gate 2 -("a workload RUNS as a relayflow" — today a run can only be shown CREATED) and -gate 3 ("every claim/lease/retry served by the kernel"). - -`sdk/tests/live-kernel.test.ts` around the `live-manual-agent` case (line 288) -shows the whole shape: connect, `hello`, `workerAttach` with pins, receive -`step.dispatch`, act, complete. The protocol is already proven there. - -## Files in scope - -- `sdk/src/worker.ts` — new file, the worker implementation -- `sdk/src/index.ts` — export the worker -- `sdk/tests/live-kernel.test.ts` OR a new test file — add a test that runs a - real flow with an agent step end to end against a live `relayflowd`, with - this worker attached, and asserts the step reaches `done`. +`.github/workflows/cloud-runtime-artifact.yml` is the repository's ONLY +workflow. Verified on 2026-09-03: + +- The only cargo invocation is `cargo build --locked --release -p relayflowd`. + **`cargo test` appears nowhere.** The entire kernel suite — 130 tests — never + runs in CI. +- Vitest runs exactly **four** files: + `typed-output`, `validate`, `spec-parity`, `deterministic-llm`. The other ~22 + SDK test files never run. + +Every kernel-side defect found on 2026-09-03 was invisible to CI by +construction: an exactly-once double-fire where one effect fired twice; a +`$ref` cycle that aborted the daemon and re-ran the effect on every resume +(4 executions of one logical step); and two tests in the tree that encoded +**opposite** contracts and both passed, because neither ran. + +## What to do + +Add the missing coverage to `.github/workflows/cloud-runtime-artifact.yml`. +The job already installs a Rust toolchain and builds the kernel, so the +marginal cost of testing it is the test run itself. + +1. Run the kernel suite: `cargo test --workspace` from `kernel/`, using + `ops/cargo.sh` the way the repo does elsewhere. +2. Run the whole SDK suite rather than four named files. Note `npm test` does + `test:prep && typecheck && build` first — a bare `vitest run` fails ~6 files + because `sdk/dist` does not exist. Use the repo's own script rather than + inventing an invocation. +3. Keep the existing artifact build, verify and smoke steps working. Do not + restructure the workflow; add coverage. + +## Constraints + +- **`.github/` only.** Do not fix any test this newly exposes. If enabling the + suites turns CI red, that is the correct and expected outcome — report + exactly which tests fail and stop. A red CI that tells the truth is the + deliverable; a green CI that runs nothing is what we have. +- Do not touch `kernel/`, `sdk/`, or `testdata/`. +- Do not add a second workflow file. ## Definition of done ALL of the following must hold: -1. The worker in `sdk/src/worker.ts`, exported from `sdk/src/index.ts` - -2. A test that runs a real flow with an agent step end to end against a live - `relayflowd`, with this worker attached, and asserts the step reaches - `done`. `sdk/tests/live-kernel.test.ts` already starts a daemon — follow - that pattern. - -3. **The worker must attach BEFORE the run starts.** A run that finds no worker - parks, and attaching afterwards does not re-drive it — `run.resume` is what - picks a parked run back up. That contract is pinned in the live-kernel - suite; do not fight it. - -4. The worker must: - - attach for `agent` steps with the pins it holds - - on `step.dispatch`, run the step's declared `cli` as a subprocess - - report the result back through the existing protocol (`step.complete`, and - the failure path when the CLI exits nonzero) - - nothing speculative: no retries of its own, no scheduling, no LLM calls. - The kernel owns retry and lease policy — do not reimplement it. - -5. `cd sdk && npm test` must be green. Run it and paste the literal command and - output tail showing test counts. - -6. `cd kernel && sh ../ops/cargo.sh test` must be green. Run it and paste the - literal command and output tail showing test counts. - -7. EVERY new test confirmed to FAIL against current code, with the literal - failing output quoted in the summary. - -8. As your LAST action, run `git status --porcelain` and paste it. - -## Explicitly OUT of scope - -- LLM steps — not in the gate 3 scope -- Retry logic in the worker — the kernel owns retry policy -- Scheduling or lease management — the kernel owns lease policy -- Optimizations, abstractions, or speculative features -- Changes to the kernel -- Changes to existing tests (except adding new test cases) -- Work on any gate other than gate 3 - -## If blocked - -If gate 3 is genuinely unreachable from the current state, write -ops/NEEDS_HUMAN.md saying exactly why and still end with ASSESS_DONE. Do not -silently substitute different work: a run that reports progress on the wrong -gate is worse than one that reports it is blocked. +1. `.github/workflows/cloud-runtime-artifact.yml` runs `cargo test --workspace` + and the full SDK suite. +2. You have run both suites LOCALLY and pasted the literal commands and their + output tails with test counts, so the change is grounded in what actually + passes rather than in what you expect CI to do. + - `cd kernel && PATH="$HOME/.cargo/bin:$PATH" RUSTUP_TOOLCHAIN=stable sh ../ops/cargo.sh test --workspace` + - `cd sdk && ./node_modules/.bin/vitest run` (after a build; `npx` hangs on + some hosts, use `./node_modules/.bin/`) +3. If either suite is red locally, you STOP and report which tests fail with + their literal output. Do not fix them. Do not weaken the workflow to go + green. +4. `sdk/tests/live-kernel.test.ts` needs a built `relayflowd`; if it cannot + collect in your sandbox, say so explicitly rather than reporting a pass that + excluded it. +5. As your LAST action, run `git status --porcelain` and paste it. + +## Why this and not a product change + +A sandbox cannot deliver — no git remote, no GitHub token — so its output is a +patch a human applies. That makes a small, self-contained, high-leverage +change the right shape for a tick. This one is three lines of intent, needs no +product knowledge to review, and every future tick benefits from it. + +The previous contents of this file described building `sdk/src/worker.ts`. That +file exists and gate-2 workloads run against it; the package was complete and +the file had not been updated. A tick that assesses against a finished work +package burns a whole cycle, so treat a stale NEXT.md as a defect in its own +right and say so in your assess step if you find one.