Skip to content

WP-10: flows run / flows resume — the authored ladder runs on the live kernel - #9

Closed
khaliqgant wants to merge 4 commits into
mainfrom
flow/drive-77b2457-08280058
Closed

WP-10: flows run / flows resume — the authored ladder runs on the live kernel#9
khaliqgant wants to merge 4 commits into
mainfrom
flow/drive-77b2457-08280058

Conversation

@khaliqgant

Copy link
Copy Markdown
Member

Implements WP-10 exactly as selected in ops/NEXT.md. The full literal verification transcript follows and is also committed in ops/DRIVE-LOG.md.

WP-10 — flows run / flows resume cross the live authored-surface seam

This 2026-08-28 tick finished the six unfinished paths named by
ops/NEXT.md. Commit 5b1226e makes the shipped CLI dispatch check, run,
and resume; declares the run-surface outcome taxonomy; pins the standalone
deterministic fixture on the SDK and kernel sides; and exercises the built CLI
against a live relayflowd. The live cases prove deterministic success,
typed parking for both llm and agent, a failed journal terminal carrying
completionReason: step_failed, preflight before journaling, an unreachable
daemon creating no run artifact, and one successful completion per step after
kill-and-resume.

Veto MCP was not exposed in this non-interactive subprocess, so no Veto
review or scan is claimed. Local diff checks and every package DoD command ran
instead. The exact DoD below ran from clean implementation commit 5b1226e.
The initial and post-verification status command produced zero bytes:

$ git status --porcelain

The kernel workspace passed 73 tests (18 + 19 + 26 + 4 + 6), including the
new deterministic parity case. Literal output:

$ (cd kernel && ../ops/cargo.sh test --workspace)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.22s
     Running unittests src/lib.rs (target/debug/deps/relayflowd-399037c915557fdb)

running 18 tests
test server::client::tests::resume_waits_while_the_heartbeat_renewed_lease_is_live ... ok
test server::tests::agent::contract::an_agent_worker_attaching_without_pins_is_refused_at_attach ... ok
test exec_det::tests::captures_deterministic_output ... ok
test exec_det::tests::timeout_has_an_explicit_completion_reason ... ok
test server::tests::agent::contract::an_oversized_trajectory_tail_is_refused_at_step_complete ... ok
test server::tests::agent::contract::agent_without_a_compatible_worker_parks_without_starting ... ok
test server::tests::agent::contract::an_agent_worker_missing_a_declared_surface_parks_the_run_instead_of_erroring ... ok
test server::tests::agent::contract::an_llm_completion_claiming_an_effect_fails_closed_with_the_reason_journaled ... ok
test server::tests::hello_enforces_protocol_version ... ok
test server::tests::run_start_fails_closed_on_an_unknown_verification_key ... ok
test server::tests::agent::contract::a_replacement_worker_that_never_reported_the_pinned_surface_is_not_dispatched_to ... ok
test server::tests::a_failed_disconnect_journal_append_is_retained_and_retried_not_dropped ... ok
test server::tests::agent::pins::consecutive_agent_steps_on_different_surfaces_each_start_from_their_own_pins ... ok
test server::tests::agent::pins::reset_worker_reporting_a_revision_other_than_its_pin_fails_closed_as_worker_error ... ok
test server::tests::stopped_heartbeats_past_the_deadline_journal_lease_expired_and_release_the_step ... ok
test exec_det::tests::timeout_kills_the_whole_process_group ... ok
test server::tests::agent::pins::a_replacement_worker_at_a_different_revision_is_not_dispatched_the_stale_pins ... ok
test server::tests::an_entry_appended_during_watch_registration_is_delivered_exactly_once ... ok

test result: ok. 18 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.56s

     Running unittests src/main.rs (target/debug/deps/relayflowd-9e21fa47745f4fb0)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running tests/crash_resume.rs (target/debug/deps/crash_resume-e6635a3f0d48512c)

running 19 tests
test agent::resume_without_a_worker_parks_immediately_instead_of_timing_out ... ok
test agent::rung_c_sigkill_after_final_effect_replays_results_without_redispatch ... ok
test concurrency::live_resume_leaves_an_active_lease_running ... ok
test concurrency::concurrent_resumes_lease_exactly_one_attempt ... ok
test agent::rung_c_reset_sigkill_mid_edit_restores_pins_dedupes_effect_and_explains_attempts ... ok
test agent::rung_c_crash_between_effect_election_and_the_provider_call_performs_it_exactly_once ... ok
test llm::serve_plumbs_watch_events_and_replayable_stream_verbs ... ok
test llm::failing_llm_verification_schedules_a_durable_retry_and_succeeds ... ok
test llm::llm_verification_exhaustion_is_a_declared_failure_kind ... ok
test agent::rung_c_sigkill_between_agent_completion_and_final_effect_memoizes_the_agent ... ok
test agent::rung_c_sigkill_boundaries_resume_only_unfinished_steps_via_real_cli ... ok
test llm::sigkill_after_the_final_rung_b_effect_resumes_without_redispatching_llm ... ok
test llm::completed_llm_output_is_memoized_when_serve_dies_during_the_next_step ... ok
test llm::worker_killed_while_holding_a_lease_is_explained_and_released_on_cli_resume ... ok
test sigkill_mid_step_replaces_and_explains_the_dead_attempt ... ok
test llm::sigkill_under_serve_mid_llm_releases_the_lease_and_finishes_via_cli_resume ... ok
test sigkill_sweep_covers_every_hello_step_boundary ... ok
test sigkill_under_serve_resumes_the_socket_started_run ... ok
test llm::sigkill_sweep_covers_before_and_between_the_rung_b_steps ... ok

test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.83s

     Running unittests src/lib.rs (target/debug/deps/relayflowd_core-b1fe3b3250e9e7a2)

running 26 tests
test clock::tests::simulated_clock_is_explicitly_advanced ... ok
test journal::tests::memory_journal_assigns_sequences_and_rolls_epochs ... ok
test machine::tests::machine_starts_runnable_step_with_stable_effect_key ... ok
test machine::tests::all_backing_off_steps_return_timers ... ok
test machine::tests::successful_memo_is_never_scheduled_again ... ok
test machine::tests::crashed_attempt_does_not_consume_an_iteration ... ok
test machine::tests::manual_recovery_parks_needs_human_and_never_redispatches ... ok
test retry::tests::jitter_is_repeatable_and_bounded ... ok
test machine::tests::verification_failure_schedules_a_durable_retry ... ok
test spec::tests::a_misspelled_step_level_key_is_a_parse_error ... ok
test machine::tests::reset_recovery_dispatches_the_original_pinned_revision ... ok
test spec::tests::a_misspelled_verification_gate_key_is_a_parse_error_not_a_dropped_gate ... ok
test machine::tests::inspect_recovery_injects_the_dirty_pin_completion_reason_and_tail ... ok
test spec::tests::cycles_are_rejected ... ok
test spec::tests::zero_agent_flow_is_valid ... ok
test spec::tests::unknown_root_and_nested_fields_are_rejected ... ok
test machine::tests::every_failed_run_terminates_with_declared_completion_reasons ... ok
test state::tests::budget_decimal_strings_add_without_floats ... ok
test spec::tests::the_full_ladder_parses_in_the_one_dialect ... ok
test state::tests::completed_output_is_memoized_and_unlocks_dependents ... ok
test verify::tests::deterministic_output_requires_successful_exit_and_content ... ok
test spec::tests::spec_version_is_semver_and_gated ... ok
test spec::tests::preflight_data_is_fail_closed ... ok
test state::tests::end_pin_chain_is_enforced_and_a_broken_chain_is_a_hard_error ... ok
test state::tests::a_completion_that_omits_a_surface_does_not_drop_it_from_the_pin_chain ... ok
test verify::tests::json_schema_is_a_control_gate ... ok

test result: ok. 26 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s

     Running tests/spec_parity.rs (target/debug/deps/spec_parity-bbda6cf1e1cf1c19)

running 4 tests
test the_kernel_parses_the_deterministic_rung_and_stamps_the_same_hash ... ok
test the_kernel_parses_the_rung_b_spec_and_stamps_the_same_hash ... ok
test the_kernel_parses_the_rung_c_agent_spec_and_stamps_the_same_hash ... ok
test the_kernel_parses_the_sdk_compiled_spec_and_stamps_the_same_hash ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running unittests src/lib.rs (target/debug/deps/relayflowd_journal-d13cb7954335385c)

running 6 tests
test registry::tests::registry_is_a_rebuildable_run_locator ... ok
test tests::failed_commit_is_returned_not_swallowed ... ok
test tests::rollover_is_atomic_scaffolding_for_epoch_resume ... ok
test tests::append_is_durable_and_monotonic_after_reopen ... ok
test tests::effects_are_deduplicated_at_the_journal_boundary ... ok
test tests::an_unconfirmed_election_is_reclaimed_by_the_next_attempt_not_treated_as_done ... ok

test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

   Doc-tests relayflowd

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests relayflowd_core

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests relayflowd_journal

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Clippy passed with warnings denied:

$ (cd kernel && ../ops/cargo.sh clippy --workspace -- -D warnings)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.20s

Rust formatting exited 0 with zero output bytes:

$ (cd kernel && ../ops/cargo.sh fmt --check)

The kernel build produced an executable daemon:

$ (cd kernel && ../ops/cargo.sh build && test -x target/debug/relayflowd && ls -l target/debug/relayflowd)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
-rwxr-xr-x  1 khaliqgant  staff  22712808 Aug 28 00:32 target/debug/relayflowd

The clean install, build, and full SDK suite passed 143 tests with no skipped
tests. bin.test.ts ran all seven cases and live-kernel.test.ts ran all four:

$ (cd sdk && npm ci && npm run build && npm test)

added 48 packages, and audited 49 packages in 653ms

13 packages are looking for funding
  run `npm fund` for details

5 vulnerabilities (3 moderate, 1 high, 1 critical)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

> @relayflows/sdk@0.1.0 build
> tsc && node scripts/make-cli-executable.mjs


> @relayflows/sdk@0.1.0 test
> tsc --noEmit && vitest run


 RUN  v2.1.9 /Users/khaliqgant/Projects/AgentWorkforce/flows/sdk

 ✓ tests/preflight.test.ts (12 tests) 11ms
stdout | tests/live-kernel.test.ts
LIVE_KERNEL relayflowd=/Users/khaliqgant/Projects/AgentWorkforce/flows/kernel/target/debug/relayflowd
LIVE_KERNEL flows=/Users/khaliqgant/Projects/AgentWorkforce/flows/sdk/dist/cli.js

 ✓ tests/validate.test.ts (36 tests) 14ms
 ✓ tests/deterministic-llm.test.ts (5 tests) 17ms
 ✓ tests/journal-client.test.ts (12 tests) 85ms
 ✓ tests/hello-deterministic.test.ts (5 tests) 21ms
 ✓ tests/spec-parity.test.ts (15 tests) 58ms
 ✓ tests/cli.test.ts (47 tests) 979ms
stdout | tests/live-kernel.test.ts > surface resume after a real daemon kill > resumes a three-step run with each successful completion exactly once
LIVE_KERNEL kill -9 pid=6381 run=01M13CPZ4HEJA91X7MGFPCB3QA

 ✓ tests/live-kernel.test.ts (4 tests) 1518ms
   ✓ built flows CLI against live relayflowd > runs rung (a), parks rung (b), and keeps JSON report-shaped 1199ms
 ✓ tests/bin.test.ts (7 tests) 1599ms

 Test Files  9 passed (9)
      Tests  143 passed (143)
   Start at  01:15:34
   Duration  1.94s (transform 384ms, setup 0ms, collect 1.06s, tests 4.30s, environment 1ms, prepare 670ms)

The behavioral proof used only the built CLI and live daemon. The failing
flow was supplied through /dev/stdin; no fixture outside the package was
added. The journal reads used the shipped SDK client against the same live
daemon:

BEHAVIOR_TMP=/tmp/wp10-clean-behavior.yBCapH
$ node sdk/dist/cli.js run --data-dir /tmp/wp10-clean-behavior.yBCapH/main-data testdata/hello-deterministic.flow.yaml
WARNING [unprovable_effects] Step "greet" command "echo" resolves, but its effects cannot be proven before execution.
WARNING [unprovable_effects] Step "shout" command "echo" resolves, but its effects cannot be proven before execution.
RUN 01M13CQY51MEG1ZBY0YRN3PG5T completed (2 steps) completionReason: success
exit=0
$ node sdk/dist/cli.js run --data-dir /tmp/wp10-clean-behavior.yBCapH/main-data testdata/hello-llm.flow.yaml
WARNING [unprovable_effects] Step "greet" command "printf" resolves, but its effects cannot be proven before execution.
WARNING [unprovable_effects] Step "finish" command "printf" resolves, but its effects cannot be proven before execution.
PARKED [run_parked] Run "01M13CQY7C506T64WDQJ2YSEGM" parked at step "answer" (llm): no worker is attached for step type "llm".
RUN 01M13CQY7C506T64WDQJ2YSEGM parked (1 steps)
exit=3
$ node sdk/dist/cli.js run --data-dir /tmp/wp10-clean-behavior.yBCapH/main-data testdata/hello-agent.flow.yaml
WARNING [unprovable_effects] Step "greet" command "printf" resolves, but its effects cannot be proven before execution.
WARNING [unprovable_effects] Step "finish" command "printf" resolves, but its effects cannot be proven before execution.
PARKED [run_parked] Run "01M13CQY9RMSX0X5C5QYB9CKPT" parked at step "edit" (agent): no worker is attached for step type "agent".
RUN 01M13CQY9RMSX0X5C5QYB9CKPT parked (1 steps)
exit=3
$ node sdk/dist/cli.js run --data-dir /tmp/wp10-clean-behavior.yBCapH/main-data /dev/stdin <<< <non-zero flow>
WARNING [command_unresolved] Step "fail" command "exit" does not resolve as an executable; it runs only if the shell supplies it.
FAILED [step_failed] Run "01M13CQYBT7Z2K97RA5DQ9A1QQ" failed with completionReason: step_failed.
RUN 01M13CQYBT7Z2K97RA5DQ9A1QQ failed (1 steps) completionReason: step_failed
exit=1
$ JournalClient.journalRead(01M13CQYBT7Z2K97RA5DQ9A1QQ) terminal completionReason
{"entry_type":"run.completed","completionReason":"step_failed","failed_step_id":"fail"}
$ node sdk/dist/cli.js run --data-dir /tmp/wp10-clean-behavior.yBCapH/absent-data testdata/hello-deterministic.flow.yaml
WARNING [unprovable_effects] Step "greet" command "echo" resolves, but its effects cannot be proven before execution.
WARNING [unprovable_effects] Step "shout" command "echo" resolves, but its effects cannot be proven before execution.
REFUSED [daemon_unreachable] No compatible relayflowd is listening at "/tmp/wp10-clean-behavior.yBCapH/absent-data/relayflowd.sock". Start it with: relayflowd --data-dir "/tmp/wp10-clean-behavior.yBCapH/absent-data" serve
exit=2
journal_files=0
$ kernel/target/debug/relayflowd --data-dir /tmp/wp10-clean-behavior.yBCapH/resume-data run testdata/hello-deterministic.spec.canonical.json --stop-after 1
{"run_id":"01M13CQYFDD2SX79JH85178HVX","status":"interrupted","completion_reason":null,"completed_steps":1}
$ kill -9 7076 # relayflowd, run 01M13CQYFDD2SX79JH85178HVX interrupted after one step
$ node sdk/dist/cli.js resume --data-dir /tmp/wp10-clean-behavior.yBCapH/resume-data 01M13CQYFDD2SX79JH85178HVX
RUN 01M13CQYFDD2SX79JH85178HVX completed (2 steps) completionReason: success
exit=0
$ JournalClient.journalRead(01M13CQYFDD2SX79JH85178HVX) successful step.completed counts
{"greet":1,"shout":1}

The exact package command confirms that no source under kernel or sdk/src
crosses 500 lines:

$ find kernel sdk/src -name '*.rs' -o -name '*.ts' | grep -v target | xargs wc -l | sort -nr | head -5
   13024 total
     468 kernel/relayflowd/src/server.rs
     465 kernel/relayflowd/src/server/session.rs
     454 sdk/src/validate.ts
     452 kernel/relayflowd-core/src/spec.rs

Gate 1 remains GREEN with the live authored-surface seam now cited in
ops/SCOREBOARD.md. The PR remains for human review and merge; this tick does
not merge it.

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 54 minutes.

View limit details

Limit details: You’ve used the included review currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: bc5e901e-afcf-43da-b07c-1b6e4a62d65e

📥 Commits

Reviewing files that changed from the base of the PR and between c83a367 and 3616c0a.

📒 Files selected for processing (2)
  • ops/DRIVE-LOG.md
  • ops/reviews/20260828-0244-pr9-adversarial.md
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: f4cddf45-ca3d-4348-8349-b4d0ba3c3a96

📥 Commits

Reviewing files that changed from the base of the PR and between f435545 and c83a367.

📒 Files selected for processing (7)
  • docs/SURFACE.md
  • kernel/relayflowd/src/server.rs
  • sdk/src/cli/run.ts
  • sdk/src/journal-client.ts
  • sdk/tests/cli.test.ts
  • sdk/tests/journal-client.test.ts
  • sdk/tests/live-kernel.test.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The SDK now provides asynchronous check, run, and resume commands. Runs use relayflowd and journal protocol operations. Reports include typed outcomes and exit codes. Tests cover deterministic parity, parked steps, failures, daemon refusal, protocol behavior, and crash recovery.

Changes

Gate 1 CLI execution

Layer / File(s) Summary
Deterministic flow parity
testdata/hello-deterministic.*, sdk/tests/spec-parity.test.ts, kernel/relayflowd-core/tests/spec_parity.rs
Adds a deterministic two-step flow with canonical JSON and SHA-256 parity fixtures. SDK and kernel tests validate the same representation.
Check flow and CLI dispatch
sdk/src/cli.ts, sdk/src/cli/check.ts
Moves checking into a dedicated flow. The CLI validates commands and options, supports JSON output, and performs configuration, dialect, compilation, and executable checks.
Run and resume orchestration
sdk/src/cli/run.ts, sdk/src/failure-kinds.ts, sdk/src/journal-client.ts, kernel/relayflowd/src/server.rs
Adds daemon connection, run submission, resume handling, outcome classification, parked-step discovery, protocol diagnostics, timeout handling, and typed exit codes.
Protocol and CLI validation
sdk/tests/cli.test.ts, sdk/tests/journal-client-loopback.ts, sdk/tests/journal-client.test.ts
Adds loopback journal protocol utilities and coverage for completed, failed, parked, resumed, invalid, and kernel-dialect runs.
Live verification and Gate 1 records
sdk/tests/live-kernel.test.ts, ops/*, docs/SURFACE.md
Adds live daemon tests for protocol operations and crash resume. Updates Gate 1 evidence, execution plans, and shipped CLI documentation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to c83a3

The PR adds the authored flows run and flows resume paths against the live kernel, with successful validation and integration checks; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant flowsCLI
  participant relayflowd
  participant journal
  flowsCLI->>relayflowd: Connect and handshake
  flowsCLI->>relayflowd: Submit or resume run
  relayflowd->>journal: Persist run and step records
  journal-->>flowsCLI: Return completion or parked outcome
Loading

Poem

A rabbit checks the flow at dawn
Then sends two steps along
The journal keeps each hop in place
Resume returns with steady pace
Parked dreams wait for workers to sing


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/settings/billing.

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f435545f3e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sdk/src/cli/run.ts

try {
const spec = toKernelSpec(checked.flow);
const outcome = await client.runStart(spec);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep long run requests alive through completion

When the combined duration of deterministic steps, retries, or durable timers exceeds JournalClient's 30-second request timeout, this await rejects and the CLI reports protocol_error and closes the socket even though relayflowd continues driving the journaled run. For example, two sequential 20-second deterministic steps are individually valid but make flows run fail after 30 seconds without reporting the run's eventual declared completion; use a lifecycle-appropriate timeout or watch/poll the submitted run instead.

AGENTS.md reference: AGENTS.md:L16-L18

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c83a367. Audit: run.start and run.resume now opt out of the bounded per-request timer; the 32-second live deterministic regression completed successfully, and reverting the lifecycle opt-out made the focused test fail with run.start timed out after 10ms.

Comment thread sdk/src/cli/run.ts Outdated
Comment on lines +166 to +168
if (outcome.status === 'parked') {
const parkedStep = await findParkedStep(client, outcome.run_id, knownSpec);
if (parkedStep !== undefined) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle dispatched parked outcomes without calling them protocol errors

When an llm or agent worker is already attached to the daemon, run.start returns the protocol's parked outcome after dispatch while run.get reports that step as Running, not Runnable. This lookup therefore finds no parkedStep and falls through to protocolFailure, so every CLI-started flow that successfully dispatches to a live worker is reported as a protocol error; distinguish waiting-on-worker state from the no-worker parked case rather than requiring a runnable step.

AGENTS.md reference: AGENTS.md:L14-L15

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c83a367. Audit: flows run now distinguishes a Runnable out-of-band step (no worker, exit 3) from a Running dispatched step, follows the latter over run.get, and resumes classification after it settles. The live attached-worker regression failed with protocol_error when Running recognition was removed and passed after restoration.

const beforeClient = await connectClient(dataDir);
const before = (await beforeClient.journalRead(initial.run_id, 1)).entries;
expect(successfulCompletions(before)).toEqual({ one: 1 });
beforeClient.close();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Kill the daemon that is actually driving the test run

This test does not exercise crash recovery: the run is first created by a separate relayflowd run --stop-after 1 process that exits normally, and only afterward is firstDaemon started to read the already-interrupted journal. Killing that idle daemon cannot interrupt a step or a boundary, so the test would still pass if socket-started crash recovery were broken; start the run through the daemon being killed and inject SIGKILL while that run is active.

AGENTS.md reference: AGENTS.md:L19-L21

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c83a367. Audit: the CLI now starts the flow through the daemon that is SIGKILLed, records step two as Running before the kill, observes the first CLI fail closed, then resumes to exactly one successful completion per step with step two reasons [crashed, success]. Moving the kill after the active run completed made the regression fail.

Comment thread sdk/src/cli/run.ts
Comment on lines +84 to +86
} catch (error) {
return {
exitCode: 2,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reserve run_unavailable for missing resume targets

Any run.resume rejection is mapped here to exit 2 and run_unavailable, including request timeouts, connection loss, malformed responses, and daemon internal_error or journal_write_failed errors after resume processing began. That contradicts the documented exit-2 meaning of refusal before a journal write and can tell automation that nothing ran when the journal may already have changed; inspect the protocol error code and classify only run_not_found as unavailable, routing transport and runtime errors through protocolFailure.

AGENTS.md reference: AGENTS.md:L16-L18

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c83a367. Audit: JournalClient now rejects daemon errors as JournalProtocolError with code; relayflowd returns run_not_found for a missing resume journal; resumeFlow maps only that code to run_unavailable/exit 2 and sends journal_write_failed, transport, and runtime failures to protocol_error/exit 1. Focused mutations of each layer failed their regressions and passed after restoration.

@khaliqgant
khaliqgant force-pushed the flow/drive-77b2457-08280058 branch from f435545 to c83a367 Compare August 28, 2026 06:43
khaliqgant pushed a commit that referenced this pull request Aug 28, 2026
The tick's own product was the WP-11 assessment and its adversarial
gate, not the repair; the repair ran on PR #9's branch and its evidence
stays there. Verify re-executed on this head (72 kernel / 131 SDK, all
nine test-result lines unfiltered) proves this head clean and nothing
about PR #9's 73/147 claim.

Recorded against this tick: the review landed 15 minutes after the
implementation it was meant to steer. Recorded against PR #9: its
transcript names c83a367, not head 3616c0a; the branch is one commit
behind main; and the live suite has not run on a merge candidate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@khaliqgant

Copy link
Copy Markdown
Member Author

Review swarm: SWARM_FAILED (2 of 3 lenses reject)

Lens Model Verdict
structure opencode PASSEDcli.ts split 311→170 into three single-purpose modules (dispatch / check 229 / run 288, all under the smell threshold); the kernel change is a 16-line fail-closed run_not_found guard in the I/O shell (server.rs 484), not the pure core; no product logic in the kernel, no new primitive; RUN_FAILURE_KINDS correctly surface taxonomy
maintainability claude FAILED — 8 findings
history codex FAILED — 2 findings

maintainability (ops/reviews/20260828-0307-pr9-maintainability.md)

  • F1 — a needs_human park is reported to the author as FAILED [protocol_error]. The flow is waiting for a person and the CLI says it crashed. This is the covenant-2 anti-behavior in the command a user actually types.
  • F2flows run's control flow parses a Rust Debug string as if it were a wire contract.
  • F3readRunSpec assumes journal sequence 1 is run.spawned, which settled decision WP-4 — flows check preflight (covenant 2) #8 (segment-per-epoch) already retires.
  • F4connect() discards the kernel's typed refusal and reports every failure as "start the daemon".
  • F5waitForRunningStep has no deadline, no cancellation, no output.
  • F6 — two divergent notions of "the ladder"; LADDER no longer means the ladder.
  • F7run.resume's existence check duplicates run-file layout and bypasses the registry.
  • F8npm test now requires prebuilt artifacts and races the suite that builds them.

history (ops/reviews/20260828-0309-pr9-history.md)

  • H1ops/SCOREBOARD.md repeats the stale-measurement failure.
  • H2 — final-head ops/NEXT.md still queues the already-completed WP-10 state.

Note on prior signal

Both vendor checks are green and the tick's own reviewer passed this diff. Neither caught F1. That is the second consecutive PR where the swarm found blocking defects after a single-reviewer pass — the reason the merge bar no longer counts a green bot as review signal.

PR stays blocked. F1 and F3 are the priority: one misreports a human-wait as a crash, the other contradicts a settled decision.

@khaliqgant

Copy link
Copy Markdown
Member Author

Superseded by #12. PR #12 contains this branch history and restates the disposition of all ten review-swarm findings; continue review there.

@khaliqgant khaliqgant closed this Aug 28, 2026
khaliqgant added a commit that referenced this pull request Aug 28, 2026
* Add flows run and resume live-kernel surface

* Record WP-10 verification evidence

* Repair flows run and resume lifecycle reporting

* Record WP-11 repair evidence and adversarial review

* drive: WP-11: repair PR #9 under review before anything else

* drive: WP-11 tick log — assessment gated, PR #9 short of the bar

The tick's own product was the WP-11 assessment and its adversarial
gate, not the repair; the repair ran on PR #9's branch and its evidence
stays there. Verify re-executed on this head (72 kernel / 131 SDK, all
nine test-result lines unfiltered) proves this head clean and nothing
about PR #9's 73/147 claim.

Recorded against this tick: the review landed 15 minutes after the
implementation it was meant to steer. Recorded against PR #9: its
transcript names c83a367, not head 3616c0a; the branch is one commit
behind main; and the live suite has not run on a merge candidate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* ops: WP-12 assessment

* fix(cli): make parked lifecycle reporting protocol-safe

* test(cli): avoid racing the human-park snapshot

* test(cli): make lease mutation terminate deterministically

* ops: record WP-12 verification evidence

* fix(kernel): expose heartbeat-renewed lease deadlines

* ops: record final-head WP-12 revalidation

* ops(review): record WP-12 adversarial verdict

* ops: record WP-12 PR supersession

---------

Co-authored-by: Relayflow Lead <lead@relayflows.local>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
khaliqgant pushed a commit that referenced this pull request Aug 28, 2026
… ground truth

Run 54ebd998 failed at assess-1 after three retries. The Lead had done the
right thing all three times: it hit a genuine contradiction, wrote a precise
ops/NEEDS_HUMAN.md, and ended with BLOCKED_NEEDS_HUMAN exactly as its task
instructed. But the gate is output_contains: ASSESS_DONE, so the designed
escape hatch was unreachable and correct behavior scored as a crash. Same
class as the review gate that once scored an honest rejection as a crash.

Fixed by separating the report from the verdict, the way review/verdict
already are: assess ALWAYS ends ASSESS_DONE, and a new deterministic
assess-gate step reads ops/NEEDS_HUMAN.md and parks with a typed exit 75.

ops/STATE.md is new: a cloud sandbox has no .git and no gh, so an assessor
there cannot reconstruct state from history. It now reads gate and open-PR
truth from the repo instead, plus the known sandbox faults that are not
reasons to block. It must be kept current — a stale STATE.md misleads a
reader that cannot check it.

ops/NEXT.md described WP-12 (repair PR #9) long after PR #12 merged. That
stale package is what the assessor tripped over. Replaced, with the answer to
its question: gate 1 closed, gate 6 next.

Third independent sighting of the exec-bit fault, this one from inside the
sandbox: the Lead reported ops/cargo.sh as Permission denied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kjgbot kjgbot mentioned this pull request Sep 7, 2026
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