diff --git a/ops/RUNTIME-STATUS.md b/ops/RUNTIME-STATUS.md new file mode 100644 index 000000000..f78af0474 --- /dev/null +++ b/ops/RUNTIME-STATUS.md @@ -0,0 +1,385 @@ +# Runtime status — 2026-09-07 + +## Result + +A relayflow runs locally on this checkout. No Cloud admission, Daytona, +Relaycast workspace, or model provider is needed for deterministic execution. +The local tick executed the real **F8b** item from `ops/BACKLOG.md`: it renamed +`validateKernelRetry` to `validateAuthoringRetryDefaults` at its declaration +and call, without changing the rule. Selection, mutation, existing tests, +and the resulting diff were executed as four journaled deterministic steps. +This is the smallest local equivalent of drive, not a migration of the full +legacy assess/build/review/PR loop. The tick itself does not commit or open a +PR; the operator delivers its recorded diff on this branch. No merge is authorized. + +The kernel was already capable of local execution. The immediate setup gap was +no built SDK or local daemon. The legacy drive YAML has a separate format gap: +this SDK refuses its old `swarm`/`workflows` schema before execution. + +## Environment and first local failure + +The supplied sf-mini binary path was not present in the actual cwd environment. +This work ran on Darwin arm64, with all build/cache locations selected inside +the worktree. The initial disk check before installing/building showed 22 GiB +available; the later captured inventory is [environment.txt](runtime-evidence/environment.txt): + +```text +$ pwd +/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt +exit=0 +$ uname -sm +Darwin arm64 +exit=0 +$ df -h . +Filesystem Size Used Avail Capacity iused ifree %iused Mounted on +/dev/disk3s5 228Gi 174Gi 21Gi 90% 4.2M 221M 2% /System/Volumes/Data +exit=0 +$ git branch --show-current +runtime/flows-restore-0907 +exit=0 +$ git rev-parse HEAD +460c0f7723da0c0fe8d5fffb87f60c058996ca3e +exit=0 +$ node --version +v26.7.0 +exit=0 +$ sh -c 'command -v flows; command -v relayflows' +exit=1 +$ sh -c 'ls "$HOME"/.relayflows-toolchain/target/*/debug/relayflowd' +ls: /Users/khaliqgant/.relayflows-toolchain/target/*/debug/relayflowd: No such file or directory +exit=1 + +``` + +Built the existing SDK, then attempted: + +```sh +node packages/sdk/dist/cli.js run --json testdata/hello-deterministic.flow.yaml +``` + +Exit 2. First refusal (literal; full stdout/stderr in +[hello-before.txt](runtime-evidence/hello-before.txt)): + +```text +REFUSED [daemon_unreachable] No compatible relayflowd is listening at "/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflowd/relayflowd.sock". Start it with: relayflowd --data-dir ".relayflowd" serve +``` + +Starting the locally built daemon resolved that refusal. No kernel source was +changed. The standalone kernel command also completed: + +```sh +kernel/target/debug/relayflowd --data-dir .relayflowd run testdata/hello-deterministic.spec.canonical.json +``` + +```text +{"run_id":"01M1YSGGNGHFF10DYQB4WESTG4","status":"completed","completion_reason":"success","completed_steps":2} + +``` + +## Reproduce local hello + +Setup commands used on this machine (npm always has the explicit userconfig; +the config path need not exist and was not created outside the worktree): + +```sh +mkdir -p .relayflow/tmp +export TMPDIR="$PWD/.relayflow/tmp" +npm_config_cache="$PWD/.relayflow/npm-cache" npm --userconfig /tmp/empty-npmrc ci --ignore-scripts --no-audit --no-fund --prefix packages/sdk +npm_config_cache="$PWD/.relayflow/npm-cache" npm --userconfig /tmp/empty-npmrc run build --prefix packages/sdk +CARGO_HOME="$PWD/.cargo-home" CARGO_TARGET_DIR="$PWD/kernel/target" RUSTC="$HOME/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rustc" "$HOME/.rustup/toolchains/stable-aarch64-apple-darwin/bin/cargo" build --manifest-path kernel/Cargo.toml --locked +``` + +The Rust command reads the installed compiler and writes build/cache files here. +On another host use its installed cargo/rustc or set `RELAYFLOWD_BIN` to an +existing binary; the launcher defaults to `kernel/target/debug/relayflowd`. +Captured build output: [SDK](runtime-evidence/build-sdk.txt), +[kernel](runtime-evidence/build-kernel.txt). + +Run with a clean environment containing only PATH, HOME and a local TMPDIR: + +```sh +env -i PATH="$PATH" HOME="$HOME" TMPDIR="$PWD/.relayflow/tmp" node scripts/run-local-workflow.mjs testdata/hello-deterministic.flow.yaml +``` + +Exit 0. Terminal report (literal full report; the preceding journal records +include `stdout_tail: "hello\n"` and `stdout_tail: "HELLO\n"`): + +```json +{"ok":true,"command":"run","path":"testdata/hello-deterministic.flow.yaml","projectConfigPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/testdata/flows.json","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"greet","message":"Step \"greet\" command \"echo\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"shout","message":"Step \"shout\" command \"echo\" resolves, but its effects cannot be proven before execution."}],"runId":"01M1YT6CC37S7MVDXXTNEZRT8Z","socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-ydugI4/relayflowd.sock","status":"completed","completionReason":"success","completedSteps":2} +``` + +Full command output: [hello-clean-env.txt](runtime-evidence/hello-clean-env.txt). +This clears ambient Cloud/Relaycast credentials; it is not a network packet +capture. The executed commands are the checked-in `echo` steps. + +## Which workflows need Cloud? + +[workflows/README.md](../workflows/README.md) records the per-file dependency +matrix. The distinction is engine dialect versus deployment location: + +- `drive-local.yaml`: local deterministic work; no service call at runtime. +- `preswarm-check.yaml`: local kernel, but nested Claude/Codex/OpenCode reviewers + require their provider authentication. No Cloud admission or Daytona. +- `drive.yaml`: legacy engine; authored for local checkout or cloud snapshot. + PR delivery needs GitHub or the cloud proxy. Its sync step changes branches, + so it was not executed over this active worktree. +- `drive-cloud.yaml`: legacy, generated Cloud/artifact-delivery variant. +- `bootstrap-gate1.yaml`: legacy bootstrap; could be locally placed with its + toolchains and authenticated model CLIs. It mutates the engine source. +- `review-swarm.yaml`: legacy; CI currently places it in Cloud. A local legacy + execution would also need staged review inputs and three authenticated CLIs. +- `watchdog.yaml`: explicitly reads Cloud schedules, plus GitHub/model/Relaycast. + +For every existing top-level YAML the literal `flows check` command, exit code, +and full stdout/stderr are in [workflow-checks.txt](runtime-evidence/workflow-checks.txt). +The five legacy YAMLs all returned exit 2, first diagnostic: + +```text +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array +``` + +`preswarm-check.yaml` returned exit 0 with warnings. This is compilation and +preflight evidence, not a completed review. The later +[workflow-summary.txt](runtime-evidence/workflow-summary.txt) also includes the +new local drive spec. No legacy `relayflows` executable was installed here. +Its runtime behavior was not tested or inferred from a successful v2 check. + +## Work package execution and delivery + +Scaffold commit: `89f2f1d31f262420c2c5f613efa3f50c70153bfa`. +From a clean work branch at that commit, after the setup above: + +```sh +node scripts/run-local-workflow.mjs workflows/drive-local.yaml +``` + +Exit 0. Full report: + +```json +{"ok":true,"command":"run","path":"workflows/drive-local.yaml","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"select-package","message":"Step \"select-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"implement-package","message":"Step \"implement-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"command_unresolved","stepId":"verify-package","message":"Step \"verify-package\" command \"set\" does not resolve as an executable; it runs only if the shell supplies it."},{"severity":"warning","kind":"unprovable_effects","stepId":"report-package","message":"Step \"report-package\" command \"node\" resolves, but its effects cannot be proven before execution."}],"runId":"01M1YT3XA5QB7GYRGY2MH2HG7T","socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-J50W0n/relayflowd.sock","status":"completed","completionReason":"success","completedSteps":4} +``` + +The `implement-package` step captured this mutation receipt: + +```text +PACKAGE_APPLIED: F8b 5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d -> 92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93 +``` + +It asserted the file changed and re-read its SHA-256 before returning success. +The actual two-line rename is [f8b.diff](runtime-evidence/f8b.diff). +The new name describes the SDK's authoring-default restriction; the existing +error text and kernel retry behavior are unchanged. + +The next step ran these existing commands, without editing their tests: + +```sh +set -eu +npm_config_cache="$PWD/.relayflow/npm-cache" npm --userconfig /tmp/empty-npmrc run build --prefix packages/sdk +cd packages/sdk +node node_modules/vitest/vitest.mjs run tests/spec-parity.test.ts tests/cli.test.ts +``` + +Literal stdout/stderr: + +```text + +> @relayflows/sdk@2.0.1 build +> tsc && node scripts/make-cli-executable.mjs + + + RUN v2.1.9 /Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/packages/sdk + + ✓ tests/spec-parity.test.ts (28 tests) 160ms + ✓ tests/cli.test.ts (63 tests) 2386ms + ✓ flows check CLI > binds a checked relative wrapper to the flow directory for worker execution 380ms + ✓ flows check CLI > resolves a project CLI path relative to the flows.json that declares it 310ms + + Test Files 2 passed (2) + Tests 91 passed (91) + Start at 22:49:22 + Duration 2.79s (transform 168ms, setup 0ms, collect 402ms, tests 2.55s, environment 0ms, prepare 75ms) + + +``` + +The full run is [drive-local.txt](runtime-evidence/drive-local.txt); the ten raw +journal entries are also exported in +[drive-local.journal.jsonl](runtime-evidence/drive-local.journal.jsonl). +The SQLite record remains in the printed `LOCAL_DATA_DIR` in this worktree. +The package file, source hashes and diff appear in the journal itself. + +There were two successful F8b ticks. The first output is retained in +[drive-local-first.txt](runtime-evidence/drive-local-first.txt). Before the final +run, only its known two-line source change was restored byte-for-byte to the +scaffold commit, asserting both hashes; the reset receipt is +[reset-package-for-final-run.txt](runtime-evidence/reset-package-for-final-run.txt). +This is **not** a mutation-verification claim. On the final delivered head a +new F8b tick intentionally refuses because the package is already applied; +use the scaffold commit for reproduction, or hello for a repeatable smoke run. + +## Launcher checks and failures found while implementing it + +```sh +node --test scripts/run-local-workflow.test.mjs +``` + +Final literal output: + +```text +✔ local launcher journals deterministic effects and reads more than one journal page (537.042792ms) +✔ a failed command fails the run and prevents dependent effects (127.248833ms) +✔ the SDK worker completes an agent step through the local journal protocol (541.697084ms) +✔ missing daemon is refused before a data directory or run is created (59.212417ms) +ℹ tests 4 +ℹ suites 0 +ℹ pass 4 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 1305.905833 + +``` + +These checks exercise a 51-step run (journal pagination), a command exiting 7 +whose dependent file write must not happen, SDK `AgentWorker` dispatch through +a deterministic wrapper, and refusal before submission when the binary is absent. +They do not call a model provider. + +The first implementation left a stale socket after daemon exit. Its first +four-test run failed three socket-cleanup assertions; captured in +[launcher-tests-first.txt](runtime-evidence/launcher-tests-first.txt). +Cleanup now waits for the owned daemon to exit before unlinking its socket. +The next run exposed two separate facts: + +```text +TypeError: Cannot read properties of null (reading 'exit_code') +bad_request: an agent worker must attach with the pins of the surfaces it holds +``` + +Full output: [launcher-tests-second.txt](runtime-evidence/launcher-tests-second.txt). +The failure assertion was corrected to check the kernel's recorded verification +verdict/detail (`exit code was 7`); failed outputs are null. The launcher now +pins declared streams at offset 0 in its fresh cell. It refuses workspace or +external surfaces instead of manufacturing revisions; an agent flow with no +stream pins is refused before creating a run. No kernel admission rule changed. + +## Existing crash/resume gate + +```sh +CARGO_HOME="$PWD/.cargo-home" CARGO_TARGET_DIR="$PWD/kernel/target" RUSTC="$HOME/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rustc" "$HOME/.rustup/toolchains/stable-aarch64-apple-darwin/bin/cargo" test --manifest-path kernel/Cargo.toml --locked -p relayflowd --test crash_resume +``` + +Captured output (full build/test output in +[crash-resume.txt](runtime-evidence/crash-resume.txt)): + +```text +running 37 tests +test agent::resume_without_a_worker_parks_immediately_instead_of_timing_out ... ok +test channels::channels_reject_foreign_workers_stale_attempts_and_invalid_acknowledgements ... ok +test concurrency::cancel_closes_the_lease_and_rejects_a_late_completion ... ok +test agent::rung_c_sigkill_after_final_effect_replays_results_without_redispatch ... ok +test concurrency::cancel_and_completion_race_has_one_terminal_fact ... ok +test agent::rung_c_sigkill_between_agent_completion_and_final_effect_memoizes_the_agent ... ok +test concurrency::run_start_dispatches_every_independent_lane_before_any_completion ... ok +test concurrency::concurrent_resumes_lease_exactly_one_attempt ... ok +test concurrency::live_resume_leaves_an_active_lease_running ... ok +test agent::rung_c_crash_between_effect_election_and_the_provider_call_performs_it_exactly_once ... ok +test agent::rung_c_reset_sigkill_mid_edit_restores_pins_dedupes_effect_and_explains_attempts ... 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::completed_llm_output_is_memoized_when_serve_dies_during_the_next_step ... ok +test llm::llm_verification_exhaustion_is_a_declared_failure_kind ... ok +test llm::sigkill_after_the_final_rung_b_effect_resumes_without_redispatching_llm ... ok +test concurrency::server_restart_recovers_every_parallel_lease_without_duplicate_success ... ok +test agent::rung_c_sigkill_boundaries_resume_only_unfinished_steps_via_real_cli ... ok +test llm::sigkill_under_serve_mid_llm_releases_the_lease_and_finishes_via_cli_resume ... ok +test pin_projection::rejected_completion_cannot_forge_inspect_retry_pins_over_the_real_socket ... ok +test llm::sigkill_sweep_covers_before_and_between_the_rung_b_steps ... ok +test protocol_admission::every_mutating_run_verb_refuses_terminal_before_changing_state ... ok +test sigkill_after_cancel_request_resumes_to_one_canceled_fact ... ok +test llm::worker_killed_while_holding_a_lease_is_explained_and_released_on_cli_resume ... ok +test memory::memory_sigkill_after_injection_replays_pack_and_charges_it_once ... ok +test sigkill_mid_step_replaces_and_explains_the_dead_attempt ... ok +test parallel_lifecycle::overlapping_agent_lanes_serialize_while_disjoint_lanes_merge_in_either_order ... ok +test parallel_lifecycle::overlapping_agent_conflict_survives_server_crash_and_resume ... ok +test parallel_lifecycle::terminal_failure_drains_or_explains_every_live_sibling ... ok +test surface_identity::aliases_are_rejected_and_external_ancestors_serialize_over_real_sockets ... ok +test workspace_identity::workspace_aliases_are_refused_and_canonical_subtrees_serialize_over_real_sockets ... ok +test worker_capacity::two_workers_receive_a_deterministic_fair_capacity_bounded_batch ... ok +test sigkill_under_serve_resumes_the_socket_started_run ... ok +test worker_capacity::default_capacity_one_reopens_only_after_durable_completion_or_crash ... ok +test sigkill_sweep_covers_every_hello_step_boundary ... ok +test channels::channels_sigkill_resume_redelivers_unacked_messages_with_exactly_once_effects ... ok +test parallel_lifecycle::renewed_parallel_leases_survive_the_original_grant_and_remain_distinct ... ok + +test result: ok. 37 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 37.91s + + +``` + +## Limits and remaining work + +- The delivered work package is deterministic and bounded. Autonomous agent + implementation/review/PR delivery from the old `drive.yaml` is not restored. +- The launcher serves stream-only agent work with the existing SDK worker. It + does not implement workspace revision/reset, mount effects, worker heartbeats, + filesystem isolation, or a bare-LLM worker. Model-backed execution was not + attempted. These limits are named rather than hidden behind successful hello. +- Local CLI auth and the previous runner are separate from local kernel health. + Nested deterministic shell commands still have unprovable effects; preflight + warns about them. No claim of complete offline preflight or provider readiness. +- Broker-supplied Cloud facts were accepted, not re-probed: production v2 + admission disabled; preview v1 bootstrap/Relaycast-repair transient failures; + wrong-database CI API key returning 401, with cloud#3430 owning the fix. + No Cloud credentials, Cloud source, admission settings, CI gates, legacy + workflows, backlog ledger, or merge authority were changed here. + +## Source whitespace check + +`git diff --cached --check` returned exit 2 for whitespace already present in +literal captured stdout and in the captured unified diff; it is preserved as +raw evidence. The complete output is +[raw-evidence-whitespace.txt](runtime-evidence/raw-evidence-whitespace.txt). +Literal diagnostic lines (the raw file also contains the whitespace itself): + +```text +ops/runtime-evidence/build-sdk.txt:4: new blank line at EOF. +ops/runtime-evidence/crash-resume.txt:59: new blank line at EOF. +ops/runtime-evidence/drive-verify.txt:17: new blank line at EOF. +ops/runtime-evidence/f8b.diff:17: trailing whitespace. +ops/runtime-evidence/launcher-tests-second.txt:30: trailing whitespace. +ops/runtime-evidence/launcher-tests-second.txt:31: trailing whitespace. +ops/runtime-evidence/launcher-tests-second.txt:33: trailing whitespace. +ops/runtime-evidence/workflow-checks.txt:32: new blank line at EOF. +``` + +The source/documentation-only check excludes those literal transcripts: +`git diff --cached --check -- . ':!ops/runtime-evidence/**'` (exit 0, no output). + +## Delivery + +PR: https://github.com/AgentWorkforce/flows/pull/231 (human review/merge). +Branch: `runtime/flows-restore-0907`. + +- `89f2f1d31f262420c2c5f613efa3f50c70153bfa`: local runner and package scaffold. +- `77a60be`: flow-produced F8b source change and captured runtime evidence. + +The PR is open; no merge, CI-green claim, or independent signoff is recorded. + +## Spec review follow-up (2026-09-07) + +The package now writes and flushes a same-directory temporary file, renames it +atomically, and flushes its directory. A SIGKILL injected during the temporary +write leaves the target intact; retry applies the package and a second retry +observes the intended final bytes. Local test fixtures are removed after the +suite. Captured command/output: [five local checks](runtime-evidence/spec-review-local-tests.txt). + +The existing test-count finding was not reproduced: the fresh run produced 63 +CLI tests plus 28 parity tests (91 total). See the literal +[rerun](runtime-evidence/spec-review-existing-tests.txt); the earlier journal +transcripts are preserved. [SDK build](runtime-evidence/spec-review-build.txt) +is also captured. `workflow-summary.txt` now contains freshly captured full CLI +output and exit codes, replacing its previously transformed summary JSON. + +These local checks do not supply independent merge signoff or green CI. diff --git a/ops/local-work-package.mjs b/ops/local-work-package.mjs new file mode 100644 index 000000000..00affa790 --- /dev/null +++ b/ops/local-work-package.mjs @@ -0,0 +1,71 @@ +// The smallest useful local drive package: a mechanical change from BACKLOG. +import assert from 'node:assert/strict'; +import { execFileSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { closeSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs'; +import { dirname } from 'node:path'; +import { randomUUID } from 'node:crypto'; + +const target = 'packages/sdk/src/compile.ts'; +const packagePath = '.relayflow/drive-local/package.json'; +const oldName = 'validateKernelRetry'; +const newName = 'validateAuthoringRetryDefaults'; +const hash = text => createHash('sha256').update(text).digest('hex'); +const read = path => readFileSync(path, 'utf8'); +const git = (...args) => execFileSync('git', args, { encoding: 'utf8' }).trim(); + +// A killed writer leaves the destination wholly old or wholly new. Flush the +// replacement before rename and the containing directory before reporting it. +function writeAtomically(path, contents) { + const temporary = `${path}.${randomUUID()}.tmp`; + try { + const mode = path === target ? statSync(path).mode & 0o777 : 0o600; + writeFileSync(temporary, contents, { flag: 'wx', mode, flush: true }); + renameSync(temporary, path); + const directory = openSync(dirname(path), 'r'); + try { fsyncSync(directory); } finally { closeSync(directory); } + } finally { rmSync(temporary, { force: true }); } +} + +switch (process.argv[2]) { + case 'select': { + const branch = git('branch', '--show-current'); + assert(branch && branch !== 'main', 'LOCAL_DRIVE_REFUSED: use a work branch'); + assert.equal(git('status', '--porcelain', '--', target), '', 'LOCAL_DRIVE_REFUSED: target has uncommitted edits'); + const entry = read('ops/BACKLOG.md').match(/^- \*\*F8b\*\*[^\n]*(?:\n [^\n]*)*/m)?.[0]; + assert(entry?.includes(oldName), 'BACKLOG_F8B_MISSING: expected the recorded work item'); + const source = read(target); + assert.equal(source.split(oldName).length - 1, 2, 'PACKAGE_ALREADY_APPLIED_OR_CHANGED: expected declaration and call'); + const work = { id: 'F8b', entry, branch, target, before: hash(source), after: hash(source.replaceAll(oldName, newName)) }; + mkdirSync('.relayflow/drive-local', { recursive: true }); + writeAtomically(packagePath, JSON.stringify(work, null, 2) + '\n'); + assert.equal(JSON.parse(read(packagePath)).before, work.before); + console.log(JSON.stringify(work)); + break; + } + case 'apply': { + const work = JSON.parse(read(packagePath)); + assert.equal(git('branch', '--show-current'), work.branch, 'work branch changed'); + const before = read(target); + // A retry after an interrupted write can observe the exact intended end state. + if (hash(before) === work.after) { console.log('PACKAGE_ALREADY_APPLIED: F8b'); break; } + assert.equal(hash(before), work.before, 'TARGET_CHANGED: refusing to overwrite intervening work'); + const after = before.replaceAll(oldName, newName); + assert.notEqual(after, before); + writeAtomically(target, after); + assert.equal(hash(read(target)), work.after, 'MUTATION_NOT_PERSISTED'); + console.log(`PACKAGE_APPLIED: F8b ${work.before} -> ${work.after}`); + console.log(git('diff', '--', target)); + break; + } + case 'report': { + const work = JSON.parse(read(packagePath)); + assert.equal(hash(read(target)), work.after, 'TARGET_CHANGED: expected the applied package'); + const diff = git('diff', '--', target); + assert(diff.includes(`+function ${newName}(`), 'PACKAGE_DIFF_MISSING'); + console.log('PACKAGE_EXECUTED: F8b; delivery requires a branch commit and human-reviewed PR.'); + console.log(diff); + break; + } + default: throw new Error('Usage: node ops/local-work-package.mjs '); +} diff --git a/ops/local-work-package.test.mjs b/ops/local-work-package.test.mjs new file mode 100644 index 000000000..3aa83f6d2 --- /dev/null +++ b/ops/local-work-package.test.mjs @@ -0,0 +1,53 @@ +import assert from 'node:assert/strict'; +import { spawnSync, execFileSync } from 'node:child_process'; +import { mkdtempSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join, resolve } from 'node:path'; +import test from 'node:test'; + +const script = resolve('ops/local-work-package.mjs'); + +test('interrupted package write preserves the original and retry applies once', t => { + const root = mkdtempSync(join(tmpdir(), 'local-package-')); + t.after(() => rmSync(root, { recursive: true, force: true })); + const git = (...args) => execFileSync('git', args, { cwd: root, stdio: 'pipe' }); + git('init', '-q', '-b', 'work'); + mkdirSync(join(root, 'packages/sdk/src'), { recursive: true }); + mkdirSync(join(root, 'ops')); + const target = join(root, 'packages/sdk/src/compile.ts'); + const original = 'function validateKernelRetry() {}\nvalidateKernelRetry();\n'; + writeFileSync(target, original); + writeFileSync(join(root, 'ops/BACKLOG.md'), '- **F8b** — rename `validateKernelRetry`\n'); + git('add', '.'); + git('-c', 'user.name=Fixture', '-c', 'user.email=fixture@example.test', + '-c', 'commit.gpgsign=false', 'commit', '-qm', 'fixture'); + const run = (operation, extra = []) => spawnSync(process.execPath, [...extra, script, operation], + { cwd: root, encoding: 'utf8', timeout: 5000 }); + const selected = run('select'); + assert.equal(selected.status, 0, selected.stderr); + // Intercept the real fs write in a separate process, write a partial prefix, + // then SIGKILL before rename. Never change the package implementation. + const hook = join(root, 'interrupt.cjs'); + writeFileSync(hook, `const fs = require('node:fs'); +const write = fs.writeFileSync; +fs.writeFileSync = (path, data, options) => { + if (String(path).includes('compile.ts') && String(path).endsWith('.tmp')) { + write(path, data.slice(0, 9), options); + process.kill(process.pid, 'SIGKILL'); + } + return write(path, data, options); +}; +require('node:module').syncBuiltinESMExports(); +`); + const interrupted = run('apply', ['--require', hook]); + assert.equal(interrupted.signal, 'SIGKILL', interrupted.stderr); + assert.equal(readFileSync(target, 'utf8'), original); + const applied = run('apply'); + assert.equal(applied.status, 0, applied.stderr); + const expected = original.replaceAll('validateKernelRetry', 'validateAuthoringRetryDefaults'); + assert.equal(readFileSync(target, 'utf8'), expected); + const retry = run('apply'); + assert.equal(retry.status, 0, retry.stderr); + assert.match(retry.stdout, /PACKAGE_ALREADY_APPLIED/); + assert.equal(readFileSync(target, 'utf8'), expected); +}); diff --git a/ops/runtime-evidence/build-kernel.txt b/ops/runtime-evidence/build-kernel.txt new file mode 100644 index 000000000..d1aa4c3de --- /dev/null +++ b/ops/runtime-evidence/build-kernel.txt @@ -0,0 +1,250 @@ + Updating crates.io index + Downloading crates ... + Downloaded heck v0.5.0 + Downloaded idna_adapter v1.2.2 + Downloaded itoa v1.0.18 + Downloaded outref v0.5.2 + Downloaded percent-encoding v2.3.2 + Downloaded tinystr v0.8.4 + Downloaded num v0.4.3 + Downloaded ulid v1.2.1 + Downloaded zerofrom v0.1.8 + Downloaded crypto-common v0.1.7 + Downloaded bit-set v0.8.0 + Downloaded block-buffer v0.10.4 + Downloaded colorchoice v1.0.5 + Downloaded potential_utf v0.1.6 + Downloaded strsim v0.11.1 + Downloaded autocfg v1.5.1 + Downloaded bit-vec v0.8.0 + Downloaded cpufeatures v0.2.17 + Downloaded find-msvc-tools v0.1.11 + Downloaded utf8_iter v1.0.4 + Downloaded yoke-derive v0.8.2 + Downloaded uuid-simd v0.8.0 + Downloaded zerofrom-derive v0.1.7 + Downloaded yoke v0.8.3 + Downloaded fallible-streaming-iterator v0.1.9 + Downloaded generic-array v0.14.7 + Downloaded utf8parse v0.2.2 + Downloaded borrow-or-share v0.2.4 + Downloaded clap_lex v1.1.0 + Downloaded wait-timeout v0.2.1 + Downloaded writeable v0.6.4 + Downloaded fallible-iterator v0.3.0 + Downloaded zmij v1.0.23 + Downloaded ref-cast v1.0.27 + Downloaded stable_deref_trait v1.2.1 + Downloaded is_terminal_polyfill v1.70.2 + Downloaded num-cmp v0.1.0 + Downloaded num-iter v0.1.46 + Downloaded version_check v0.9.5 + Downloaded vsimd v0.8.0 + Downloaded zerovec-derive v0.11.6 + Downloaded unicode-ident v1.0.24 + Downloaded uuid v1.26.0 + Downloaded zerotrie v0.2.5 + Downloaded typenum v1.20.1 + Downloaded zerovec v0.11.8 + Downloaded anstyle-query v1.1.5 + Downloaded bytecount v0.6.9 + Downloaded cfg-if v1.0.4 + Downloaded displaydoc v0.2.7 + Downloaded foldhash v0.1.5 + Downloaded hashlink v0.10.0 + Downloaded pkg-config v0.3.34 + Downloaded ppv-lite86 v0.2.21 + Downloaded quote v1.0.47 + Downloaded rand_chacha v0.9.0 + Downloaded rand_core v0.9.5 + Downloaded ref-cast-impl v1.0.27 + Downloaded referencing v0.33.0 + Downloaded scopeguard v1.2.0 + Downloaded sha2 v0.10.9 + Downloaded shlex v2.0.1 + Downloaded synstructure v0.13.2 + Downloaded thiserror-impl v2.0.20 + Downloaded anstream v1.0.0 + Downloaded anstyle v1.0.14 + Downloaded anstyle-parse v1.0.0 + Downloaded anyhow v1.0.104 + Downloaded bitflags v2.13.1 + Downloaded clap_derive v4.6.4 + Downloaded digest v0.10.7 + Downloaded email_address v0.2.9 + Downloaded fluent-uri v0.3.2 + Downloaded lock_api v0.4.14 + Downloaded num-complex v0.4.6 + Downloaded num-integer v0.1.47 + Downloaded num-rational v0.4.2 + Downloaded lazy_static v1.5.0 + Downloaded ahash v0.8.12 + Downloaded icu_provider v2.3.1 + Downloaded vcpkg v0.2.15 + Downloaded zerocopy v0.8.56 + Downloaded litemap v0.8.3 + Downloaded thiserror v2.0.20 + Downloaded clap v4.6.6 + Downloaded getrandom v0.3.4 + Downloaded smallvec v1.15.2 + Downloaded icu_locale_core v2.3.0 + Downloaded parking_lot_core v0.9.12 + Downloaded num-traits v0.2.19 + Downloaded proc-macro2 v1.0.107 + Downloaded parking_lot v0.12.5 + Downloaded icu_normalizer_data v2.3.0 + Downloaded cc v1.4.4 + Downloaded serde v1.0.229 + Downloaded serde_core v1.0.229 + Downloaded once_cell v1.21.4 + Downloaded serde_derive v1.0.229 + Downloaded icu_collections v2.3.0 + Downloaded base64 v0.22.1 + Downloaded icu_properties v2.3.0 + Downloaded fraction v0.15.4 + Downloaded memchr v2.8.3 + Downloaded rand v0.9.5 + Downloaded aho-corasick v1.1.5 + Downloaded fancy-regex v0.16.2 + Downloaded num-bigint v0.4.8 + Downloaded jsonschema v0.33.0 + Downloaded hashbrown v0.15.5 + Downloaded serde_json v1.0.151 + Downloaded idna v1.1.0 + Downloaded icu_properties_data v2.3.0 + Downloaded regex v1.13.1 + Downloaded rusqlite v0.37.0 + Downloaded clap_builder v4.6.6 + Downloaded syn v3.0.4 + Downloaded syn v2.0.119 + Downloaded regex-syntax v0.8.11 + Downloaded icu_normalizer v2.3.0 + Downloaded regex-automata v0.4.18 + Downloaded libc v0.2.189 + Downloaded libsqlite3-sys v0.35.0 + Compiling proc-macro2 v1.0.107 + Compiling unicode-ident v1.0.24 + Compiling quote v1.0.47 + Compiling libc v0.2.189 + Compiling stable_deref_trait v1.2.1 + Compiling version_check v0.9.5 + Compiling cfg-if v1.0.4 + Compiling autocfg v1.5.1 + Compiling serde_core v1.0.229 + Compiling zerocopy v0.8.56 + Compiling getrandom v0.3.4 + Compiling serde v1.0.229 + Compiling smallvec v1.15.2 + Compiling memchr v2.8.3 + Compiling litemap v0.8.3 + Compiling num-traits v0.2.19 + Compiling writeable v0.6.4 + Compiling generic-array v0.14.7 + Compiling icu_normalizer_data v2.3.0 + Compiling utf8_iter v1.0.4 + Compiling icu_properties_data v2.3.0 + Compiling syn v3.0.4 + Compiling syn v2.0.119 + Compiling num-integer v0.1.47 + Compiling typenum v1.20.1 + Compiling ref-cast v1.0.27 + Compiling zmij v1.0.23 + Compiling parking_lot_core v0.9.12 + Compiling synstructure v0.13.2 + Compiling num-bigint v0.4.8 + Compiling zerofrom-derive v0.1.7 + Compiling yoke-derive v0.8.2 + Compiling zerofrom v0.1.8 + Compiling zerovec-derive v0.11.6 + Compiling displaydoc v0.2.7 + Compiling serde_derive v1.0.229 + Compiling ref-cast-impl v1.0.27 + Compiling aho-corasick v1.1.5 + Compiling ahash v0.8.12 + Compiling shlex v2.0.1 + Compiling regex-syntax v0.8.11 + Compiling find-msvc-tools v0.1.11 + Compiling scopeguard v1.2.0 + Compiling serde_json v1.0.151 + Compiling cc v1.4.4 + Compiling lock_api v0.4.14 + Compiling num-rational v0.4.2 + Compiling yoke v0.8.3 + Compiling rand_core v0.9.5 + Compiling ppv-lite86 v0.2.21 + Compiling num-iter v0.1.46 + Compiling num-complex v0.4.6 + Compiling pkg-config v0.3.34 + Compiling vcpkg v0.2.15 + Compiling borrow-or-share v0.2.4 + Compiling itoa v1.0.18 + Compiling regex-automata v0.4.18 + Compiling bit-vec v0.8.0 + Compiling once_cell v1.21.4 + Compiling num v0.4.3 + Compiling bit-set v0.8.0 + Compiling rand_chacha v0.9.0 + Compiling parking_lot v0.12.5 + Compiling block-buffer v0.10.4 + Compiling crypto-common v0.1.7 + Compiling foldhash v0.1.5 + Compiling outref v0.5.2 + Compiling libsqlite3-sys v0.35.0 + Compiling lazy_static v1.5.0 + Compiling uuid v1.26.0 + Compiling percent-encoding v2.3.2 + Compiling thiserror v2.0.20 + Compiling vsimd v0.8.0 + Compiling utf8parse v0.2.2 + Compiling zerovec v0.11.8 + Compiling zerotrie v0.2.5 + Compiling anstyle-parse v1.0.0 + Compiling uuid-simd v0.8.0 + Compiling fraction v0.15.4 + Compiling hashbrown v0.15.5 + Compiling fluent-uri v0.3.2 + Compiling email_address v0.2.9 + Compiling digest v0.10.7 + Compiling rand v0.9.5 + Compiling thiserror-impl v2.0.20 + Compiling cpufeatures v0.2.17 + Compiling is_terminal_polyfill v1.70.2 + Compiling num-cmp v0.1.0 + Compiling referencing v0.33.0 + Compiling anstyle v1.0.14 + Compiling base64 v0.22.1 + Compiling colorchoice v1.0.5 + Compiling tinystr v0.8.4 + Compiling potential_utf v0.1.6 + Compiling anstyle-query v1.1.5 + Compiling bytecount v0.6.9 + Compiling anstream v1.0.0 + Compiling ulid v1.2.1 + Compiling icu_collections v2.3.0 + Compiling icu_locale_core v2.3.0 + Compiling regex v1.13.1 + Compiling fancy-regex v0.16.2 + Compiling sha2 v0.10.9 + Compiling hashlink v0.10.0 + Compiling heck v0.5.0 + Compiling anyhow v1.0.104 + Compiling clap_lex v1.1.0 + Compiling bitflags v2.13.1 + Compiling strsim v0.11.1 + Compiling fallible-streaming-iterator v0.1.9 + Compiling fallible-iterator v0.3.0 + Compiling clap_derive v4.6.4 + Compiling clap_builder v4.6.6 + Compiling wait-timeout v0.2.1 + Compiling icu_provider v2.3.1 + Compiling icu_properties v2.3.0 + Compiling icu_normalizer v2.3.0 + Compiling idna_adapter v1.2.2 + Compiling idna v1.1.0 + Compiling jsonschema v0.33.0 + Compiling clap v4.6.6 + Compiling rusqlite v0.37.0 + Compiling relayflowd-core v0.1.0 (/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/kernel/relayflowd-core) + Compiling relayflowd-journal v0.1.0 (/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/kernel/relayflowd-journal) + Compiling relayflowd v0.1.0 (/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/kernel/relayflowd) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 16.52s diff --git a/ops/runtime-evidence/build-sdk.txt b/ops/runtime-evidence/build-sdk.txt new file mode 100644 index 000000000..fd43e8b6e --- /dev/null +++ b/ops/runtime-evidence/build-sdk.txt @@ -0,0 +1,4 @@ + +> @relayflows/sdk@2.0.1 build +> tsc && node scripts/make-cli-executable.mjs + diff --git a/ops/runtime-evidence/crash-resume.txt b/ops/runtime-evidence/crash-resume.txt new file mode 100644 index 000000000..6c51f85c5 --- /dev/null +++ b/ops/runtime-evidence/crash-resume.txt @@ -0,0 +1,59 @@ + Downloading crates ... + Downloaded errno v0.3.14 + Downloaded fastrand v2.5.0 + Downloaded getrandom v0.4.3 + Downloaded tempfile v3.27.0 + Downloaded rustix v1.1.4 + Compiling bitflags v2.13.1 + Compiling rustix v1.1.4 + Compiling getrandom v0.4.3 + Compiling errno v0.3.14 + Compiling fastrand v2.5.0 + Compiling rusqlite v0.37.0 + Compiling relayflowd-journal v0.1.0 (/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/kernel/relayflowd-journal) + Compiling relayflowd v0.1.0 (/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/kernel/relayflowd) + Compiling tempfile v3.27.0 + Finished `test` profile [unoptimized + debuginfo] target(s) in 4.06s + Running tests/crash_resume.rs (kernel/target/debug/deps/crash_resume-2875ce6010be4631) + +running 37 tests +test agent::resume_without_a_worker_parks_immediately_instead_of_timing_out ... ok +test channels::channels_reject_foreign_workers_stale_attempts_and_invalid_acknowledgements ... ok +test concurrency::cancel_closes_the_lease_and_rejects_a_late_completion ... ok +test agent::rung_c_sigkill_after_final_effect_replays_results_without_redispatch ... ok +test concurrency::cancel_and_completion_race_has_one_terminal_fact ... ok +test agent::rung_c_sigkill_between_agent_completion_and_final_effect_memoizes_the_agent ... ok +test concurrency::run_start_dispatches_every_independent_lane_before_any_completion ... ok +test concurrency::concurrent_resumes_lease_exactly_one_attempt ... ok +test concurrency::live_resume_leaves_an_active_lease_running ... ok +test agent::rung_c_crash_between_effect_election_and_the_provider_call_performs_it_exactly_once ... ok +test agent::rung_c_reset_sigkill_mid_edit_restores_pins_dedupes_effect_and_explains_attempts ... 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::completed_llm_output_is_memoized_when_serve_dies_during_the_next_step ... ok +test llm::llm_verification_exhaustion_is_a_declared_failure_kind ... ok +test llm::sigkill_after_the_final_rung_b_effect_resumes_without_redispatching_llm ... ok +test concurrency::server_restart_recovers_every_parallel_lease_without_duplicate_success ... ok +test agent::rung_c_sigkill_boundaries_resume_only_unfinished_steps_via_real_cli ... ok +test llm::sigkill_under_serve_mid_llm_releases_the_lease_and_finishes_via_cli_resume ... ok +test pin_projection::rejected_completion_cannot_forge_inspect_retry_pins_over_the_real_socket ... ok +test llm::sigkill_sweep_covers_before_and_between_the_rung_b_steps ... ok +test protocol_admission::every_mutating_run_verb_refuses_terminal_before_changing_state ... ok +test sigkill_after_cancel_request_resumes_to_one_canceled_fact ... ok +test llm::worker_killed_while_holding_a_lease_is_explained_and_released_on_cli_resume ... ok +test memory::memory_sigkill_after_injection_replays_pack_and_charges_it_once ... ok +test sigkill_mid_step_replaces_and_explains_the_dead_attempt ... ok +test parallel_lifecycle::overlapping_agent_lanes_serialize_while_disjoint_lanes_merge_in_either_order ... ok +test parallel_lifecycle::overlapping_agent_conflict_survives_server_crash_and_resume ... ok +test parallel_lifecycle::terminal_failure_drains_or_explains_every_live_sibling ... ok +test surface_identity::aliases_are_rejected_and_external_ancestors_serialize_over_real_sockets ... ok +test workspace_identity::workspace_aliases_are_refused_and_canonical_subtrees_serialize_over_real_sockets ... ok +test worker_capacity::two_workers_receive_a_deterministic_fair_capacity_bounded_batch ... ok +test sigkill_under_serve_resumes_the_socket_started_run ... ok +test worker_capacity::default_capacity_one_reopens_only_after_durable_completion_or_crash ... ok +test sigkill_sweep_covers_every_hello_step_boundary ... ok +test channels::channels_sigkill_resume_redelivers_unacked_messages_with_exactly_once_effects ... ok +test parallel_lifecycle::renewed_parallel_leases_survive_the_original_grant_and_remain_distinct ... ok + +test result: ok. 37 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 37.91s + diff --git a/ops/runtime-evidence/drive-local-first.txt b/ops/runtime-evidence/drive-local-first.txt new file mode 100644 index 000000000..d91d8d3ab --- /dev/null +++ b/ops/runtime-evidence/drive-local-first.txt @@ -0,0 +1,17 @@ +{"severity":"warning","kind":"unprovable_effects","stepId":"select-package","message":"Step \"select-package\" command \"node\" resolves, but its effects cannot be proven before execution."} +{"severity":"warning","kind":"unprovable_effects","stepId":"implement-package","message":"Step \"implement-package\" command \"node\" resolves, but its effects cannot be proven before execution."} +{"severity":"warning","kind":"command_unresolved","stepId":"verify-package","message":"Step \"verify-package\" command \"set\" does not resolve as an executable; it runs only if the shell supplies it."} +{"severity":"warning","kind":"unprovable_effects","stepId":"report-package","message":"Step \"report-package\" command \"node\" resolves, but its effects cannot be proven before execution."} +LOCAL_DATA_DIR=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-jqsEXC +{"at_ms":1788813768357,"attempt":null,"entry_type":"run.spawned","payload":{"created_by":"protocol-v0","journal_version":1,"parent_run_id":null,"spec":{"description":"Correct the retry validator name to describe the authoring restriction (BACKLOG F8b).","name":"drive-local-f8b","steps":[{"command":"node ops/local-work-package.mjs select","depends_on":[],"id":"select-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}},{"command":"node ops/local-work-package.mjs apply","depends_on":["select-package"],"id":"implement-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}},{"command":"set -eu\nnpm_config_cache=\"$PWD/.relayflow/npm-cache\" npm --userconfig /tmp/empty-npmrc run build --prefix packages/sdk\ncd packages/sdk\nnode node_modules/vitest/vitest.mjs run tests/spec-parity.test.ts tests/cli.test.ts\n","depends_on":["implement-package"],"id":"verify-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"timeout_ms":120000,"type":"deterministic","verification":{}},{"command":"node ops/local-work-package.mjs report","depends_on":["verify-package"],"id":"report-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}}],"version":"0.1.0"},"spec_hash":"4a4823a6ce6db186a64ebed705c4f44e29425a5c892d76dc80dbd59b7fe982a6"},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":1,"step_id":null} +{"at_ms":1788813768362,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"64cffbf2f5f37af61c97e73f35d8228f5b802f52ee5dc4add9d958906fbc71b9","lease_deadline_ms":1788813798362,"lease_id":"01M1YSQXNA16PT98KT4JC0APJP","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":2,"step_id":"select-package"} +{"at_ms":1788813768418,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"{\"id\":\"F8b\",\"entry\":\"- **F8b** — `validateKernelRetry` names an authoring rule as if the kernel\\n imposed it — a doc claim the kernel does not make.\",\"branch\":\"runtime/flows-restore-0907\",\"target\":\"packages/sdk/src/compile.ts\",\"before\":\"5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d\",\"after\":\"92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93\"}\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":3,"step_id":"select-package"} +{"at_ms":1788813768419,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"6a85828eb5faab9716a8c2675437d3d9ffc38bda73c1ec58d49de2f365785432","lease_deadline_ms":1788813798419,"lease_id":"01M1YSQXQ37SMCEFKF3ETJA02K","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":4,"step_id":"implement-package"} +{"at_ms":1788813768477,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"PACKAGE_APPLIED: F8b 5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d -> 92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93\ndiff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts\nindex 87f1f24..8cd088d 100644\n--- a/packages/sdk/src/compile.ts\n+++ b/packages/sdk/src/compile.ts\n@@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const\n : [];\n assertKernelKeys(step, [...commonKeys, ...typeKeys], at);\n- if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`);\n+ if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`);\n const dependsOn = step['depends_on'];\n const common = {\n id: step['id'],\n@@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n return common;\n }\n \n-function validateKernelRetry(value: unknown, at: string): void {\n+function validateAuthoringRetryDefaults(value: unknown, at: string): void {\n const retry = requireKernelObject(value, [\n 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent',\n ], at);\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":5,"step_id":"implement-package"} +{"at_ms":1788813768478,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"52c245888715ba16265d6534f4d9ea2b2e1e4ed26232659d04b14d242c81b377","lease_deadline_ms":1788813798478,"lease_id":"01M1YSQXRY980ZXXG8SYXJ2RG8","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":6,"step_id":"verify-package"} +{"at_ms":1788813773324,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"\n> @relayflows/sdk@2.0.1 build\n> tsc && node scripts/make-cli-executable.mjs\n\n\n RUN v2.1.9 /Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/packages/sdk\n\n ✓ tests/spec-parity.test.ts (28 tests) 153ms\n ✓ tests/cli.test.ts (63 tests) 2966ms\n ✓ flows check CLI > binds a checked relative wrapper to the flow directory for worker execution 413ms\n ✓ flows check CLI > uses the raw Claude adapter model flag instead of accepting auth status as model proof 316ms\n ✓ flows check CLI > accepts an exact allowlisted named-agent model and probes that model 303ms\n\n Test Files 2 passed (2)\n Tests 91 passed (91)\n Start at 22:42:49\n Duration 3.33s (transform 144ms, setup 0ms, collect 344ms, tests 3.12s, environment 0ms, prepare 82ms)\n\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":7,"step_id":"verify-package"} +{"at_ms":1788813773325,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"5d6f37cf7b91ce4087668b3499bfe5c65195b18cf25ac3e0a3636cfde20989e0","lease_deadline_ms":1788813803325,"lease_id":"01M1YSR2GD2QHJW7XFTTPBHS3B","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":8,"step_id":"report-package"} +{"at_ms":1788813773370,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"PACKAGE_EXECUTED: F8b; delivery requires a branch commit and human-reviewed PR.\ndiff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts\nindex 87f1f24..8cd088d 100644\n--- a/packages/sdk/src/compile.ts\n+++ b/packages/sdk/src/compile.ts\n@@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const\n : [];\n assertKernelKeys(step, [...commonKeys, ...typeKeys], at);\n- if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`);\n+ if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`);\n const dependsOn = step['depends_on'];\n const common = {\n id: step['id'],\n@@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n return common;\n }\n \n-function validateKernelRetry(value: unknown, at: string): void {\n+function validateAuthoringRetryDefaults(value: unknown, at: string): void {\n const retry = requireKernelObject(value, [\n 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent',\n ], at);\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":9,"step_id":"report-package"} +{"at_ms":1788813773371,"attempt":null,"entry_type":"run.completed","payload":{"budget_total":{"dollars":"0","tokens_in":0,"tokens_out":0},"completionReason":"success","failed_step_id":null},"run_id":"01M1YSQXN51VB1VJ5E9X0EP9KT","segment_id":1,"seq":10,"step_id":null} +LOCAL_JOURNAL=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-jqsEXC/journal.jsonl +{"ok":true,"command":"run","path":"workflows/drive-local.yaml","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"select-package","message":"Step \"select-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"implement-package","message":"Step \"implement-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"command_unresolved","stepId":"verify-package","message":"Step \"verify-package\" command \"set\" does not resolve as an executable; it runs only if the shell supplies it."},{"severity":"warning","kind":"unprovable_effects","stepId":"report-package","message":"Step \"report-package\" command \"node\" resolves, but its effects cannot be proven before execution."}],"runId":"01M1YSQXN51VB1VJ5E9X0EP9KT","socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-jqsEXC/relayflowd.sock","status":"completed","completionReason":"success","completedSteps":4} diff --git a/ops/runtime-evidence/drive-local.journal.jsonl b/ops/runtime-evidence/drive-local.journal.jsonl new file mode 100644 index 000000000..93a61a13e --- /dev/null +++ b/ops/runtime-evidence/drive-local.journal.jsonl @@ -0,0 +1,10 @@ +{"at_ms":1788814161221,"attempt":null,"entry_type":"run.spawned","payload":{"created_by":"protocol-v0","journal_version":1,"parent_run_id":null,"spec":{"description":"Correct the retry validator name to describe the authoring restriction (BACKLOG F8b).","name":"drive-local-f8b","steps":[{"command":"node ops/local-work-package.mjs select","depends_on":[],"id":"select-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}},{"command":"node ops/local-work-package.mjs apply","depends_on":["select-package"],"id":"implement-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}},{"command":"set -eu\nnpm_config_cache=\"$PWD/.relayflow/npm-cache\" npm --userconfig /tmp/empty-npmrc run build --prefix packages/sdk\ncd packages/sdk\nnode node_modules/vitest/vitest.mjs run tests/spec-parity.test.ts tests/cli.test.ts\n","depends_on":["implement-package"],"id":"verify-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"timeout_ms":120000,"type":"deterministic","verification":{}},{"command":"node ops/local-work-package.mjs report","depends_on":["verify-package"],"id":"report-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}}],"version":"0.1.0"},"spec_hash":"4a4823a6ce6db186a64ebed705c4f44e29425a5c892d76dc80dbd59b7fe982a6"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":1,"step_id":null} +{"at_ms":1788814161226,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"177b1ec55bc3a10008383cf5ddb88b3711458cae829cf08fcc79aea9bee74cf2","lease_deadline_ms":1788814191226,"lease_id":"01M1YT3XAAN5XP6S2JCY7PN0MK","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":2,"step_id":"select-package"} +{"at_ms":1788814161282,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"{\"id\":\"F8b\",\"entry\":\"- **F8b** \u2014 `validateKernelRetry` names an authoring rule as if the kernel\\n imposed it \u2014 a doc claim the kernel does not make.\",\"branch\":\"runtime/flows-restore-0907\",\"target\":\"packages/sdk/src/compile.ts\",\"before\":\"5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d\",\"after\":\"92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93\"}\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":3,"step_id":"select-package"} +{"at_ms":1788814161282,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"1826c0e0c2ab403f4298a4efc0a0202f06d60a0ed3c5e2750fa458caea2e38e6","lease_deadline_ms":1788814191282,"lease_id":"01M1YT3XC2BPFJWJQEKK63W6T9","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":4,"step_id":"implement-package"} +{"at_ms":1788814161335,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"PACKAGE_APPLIED: F8b 5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d -> 92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93\ndiff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts\nindex 87f1f24..8cd088d 100644\n--- a/packages/sdk/src/compile.ts\n+++ b/packages/sdk/src/compile.ts\n@@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const\n : [];\n assertKernelKeys(step, [...commonKeys, ...typeKeys], at);\n- if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`);\n+ if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`);\n const dependsOn = step['depends_on'];\n const common = {\n id: step['id'],\n@@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n return common;\n }\n \n-function validateKernelRetry(value: unknown, at: string): void {\n+function validateAuthoringRetryDefaults(value: unknown, at: string): void {\n const retry = requireKernelObject(value, [\n 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent',\n ], at);\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":5,"step_id":"implement-package"} +{"at_ms":1788814161336,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"5a2fb3e41a4d1b3ea01df7b2e23f6e290e50803b420f40892b840cb3b7057563","lease_deadline_ms":1788814191336,"lease_id":"01M1YT3XDRFYEKYZQWPYGE0CPT","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":6,"step_id":"verify-package"} +{"at_ms":1788814165156,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"\n> @relayflows/sdk@2.0.1 build\n> tsc && node scripts/make-cli-executable.mjs\n\n\n RUN v2.1.9 /Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/packages/sdk\n\n \u2713 tests/spec-parity.test.ts (28 tests) 160ms\n \u2713 tests/cli.test.ts (63 tests) 2386ms\n \u2713 flows check CLI > binds a checked relative wrapper to the flow directory for worker execution 380ms\n \u2713 flows check CLI > resolves a project CLI path relative to the flows.json that declares it 310ms\n\n Test Files 2 passed (2)\n Tests 91 passed (91)\n Start at 22:49:22\n Duration 2.79s (transform 168ms, setup 0ms, collect 402ms, tests 2.55s, environment 0ms, prepare 75ms)\n\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":7,"step_id":"verify-package"} +{"at_ms":1788814165157,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"33e0b96063948a73bbe37ca86eb33d94cb7e6a1a0f4f9568b9ddfadacdb1e749","lease_deadline_ms":1788814195157,"lease_id":"01M1YT4155CBTGVGT35CXTQPWK","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":8,"step_id":"report-package"} +{"at_ms":1788814165205,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"PACKAGE_EXECUTED: F8b; delivery requires a branch commit and human-reviewed PR.\ndiff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts\nindex 87f1f24..8cd088d 100644\n--- a/packages/sdk/src/compile.ts\n+++ b/packages/sdk/src/compile.ts\n@@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const\n : [];\n assertKernelKeys(step, [...commonKeys, ...typeKeys], at);\n- if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`);\n+ if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`);\n const dependsOn = step['depends_on'];\n const common = {\n id: step['id'],\n@@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n return common;\n }\n \n-function validateKernelRetry(value: unknown, at: string): void {\n+function validateAuthoringRetryDefaults(value: unknown, at: string): void {\n const retry = requireKernelObject(value, [\n 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent',\n ], at);\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":9,"step_id":"report-package"} +{"at_ms":1788814165205,"attempt":null,"entry_type":"run.completed","payload":{"budget_total":{"dollars":"0","tokens_in":0,"tokens_out":0},"completionReason":"success","failed_step_id":null},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":10,"step_id":null} diff --git a/ops/runtime-evidence/drive-local.txt b/ops/runtime-evidence/drive-local.txt new file mode 100644 index 000000000..1b719de20 --- /dev/null +++ b/ops/runtime-evidence/drive-local.txt @@ -0,0 +1,17 @@ +{"severity":"warning","kind":"unprovable_effects","stepId":"select-package","message":"Step \"select-package\" command \"node\" resolves, but its effects cannot be proven before execution."} +{"severity":"warning","kind":"unprovable_effects","stepId":"implement-package","message":"Step \"implement-package\" command \"node\" resolves, but its effects cannot be proven before execution."} +{"severity":"warning","kind":"command_unresolved","stepId":"verify-package","message":"Step \"verify-package\" command \"set\" does not resolve as an executable; it runs only if the shell supplies it."} +{"severity":"warning","kind":"unprovable_effects","stepId":"report-package","message":"Step \"report-package\" command \"node\" resolves, but its effects cannot be proven before execution."} +LOCAL_DATA_DIR=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-J50W0n +{"at_ms":1788814161221,"attempt":null,"entry_type":"run.spawned","payload":{"created_by":"protocol-v0","journal_version":1,"parent_run_id":null,"spec":{"description":"Correct the retry validator name to describe the authoring restriction (BACKLOG F8b).","name":"drive-local-f8b","steps":[{"command":"node ops/local-work-package.mjs select","depends_on":[],"id":"select-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}},{"command":"node ops/local-work-package.mjs apply","depends_on":["select-package"],"id":"implement-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}},{"command":"set -eu\nnpm_config_cache=\"$PWD/.relayflow/npm-cache\" npm --userconfig /tmp/empty-npmrc run build --prefix packages/sdk\ncd packages/sdk\nnode node_modules/vitest/vitest.mjs run tests/spec-parity.test.ts tests/cli.test.ts\n","depends_on":["implement-package"],"id":"verify-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"timeout_ms":120000,"type":"deterministic","verification":{}},{"command":"node ops/local-work-package.mjs report","depends_on":["verify-package"],"id":"report-package","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{}}],"version":"0.1.0"},"spec_hash":"4a4823a6ce6db186a64ebed705c4f44e29425a5c892d76dc80dbd59b7fe982a6"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":1,"step_id":null} +{"at_ms":1788814161226,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"177b1ec55bc3a10008383cf5ddb88b3711458cae829cf08fcc79aea9bee74cf2","lease_deadline_ms":1788814191226,"lease_id":"01M1YT3XAAN5XP6S2JCY7PN0MK","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":2,"step_id":"select-package"} +{"at_ms":1788814161282,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"{\"id\":\"F8b\",\"entry\":\"- **F8b** — `validateKernelRetry` names an authoring rule as if the kernel\\n imposed it — a doc claim the kernel does not make.\",\"branch\":\"runtime/flows-restore-0907\",\"target\":\"packages/sdk/src/compile.ts\",\"before\":\"5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d\",\"after\":\"92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93\"}\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":3,"step_id":"select-package"} +{"at_ms":1788814161282,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"1826c0e0c2ab403f4298a4efc0a0202f06d60a0ed3c5e2750fa458caea2e38e6","lease_deadline_ms":1788814191282,"lease_id":"01M1YT3XC2BPFJWJQEKK63W6T9","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":4,"step_id":"implement-package"} +{"at_ms":1788814161335,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"PACKAGE_APPLIED: F8b 5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d -> 92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93\ndiff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts\nindex 87f1f24..8cd088d 100644\n--- a/packages/sdk/src/compile.ts\n+++ b/packages/sdk/src/compile.ts\n@@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const\n : [];\n assertKernelKeys(step, [...commonKeys, ...typeKeys], at);\n- if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`);\n+ if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`);\n const dependsOn = step['depends_on'];\n const common = {\n id: step['id'],\n@@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n return common;\n }\n \n-function validateKernelRetry(value: unknown, at: string): void {\n+function validateAuthoringRetryDefaults(value: unknown, at: string): void {\n const retry = requireKernelObject(value, [\n 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent',\n ], at);\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":5,"step_id":"implement-package"} +{"at_ms":1788814161336,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"5a2fb3e41a4d1b3ea01df7b2e23f6e290e50803b420f40892b840cb3b7057563","lease_deadline_ms":1788814191336,"lease_id":"01M1YT3XDRFYEKYZQWPYGE0CPT","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":6,"step_id":"verify-package"} +{"at_ms":1788814165156,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"\n> @relayflows/sdk@2.0.1 build\n> tsc && node scripts/make-cli-executable.mjs\n\n\n RUN v2.1.9 /Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/packages/sdk\n\n ✓ tests/spec-parity.test.ts (28 tests) 160ms\n ✓ tests/cli.test.ts (63 tests) 2386ms\n ✓ flows check CLI > binds a checked relative wrapper to the flow directory for worker execution 380ms\n ✓ flows check CLI > resolves a project CLI path relative to the flows.json that declares it 310ms\n\n Test Files 2 passed (2)\n Tests 91 passed (91)\n Start at 22:49:22\n Duration 2.79s (transform 168ms, setup 0ms, collect 402ms, tests 2.55s, environment 0ms, prepare 75ms)\n\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":7,"step_id":"verify-package"} +{"at_ms":1788814165157,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"33e0b96063948a73bbe37ca86eb33d94cb7e6a1a0f4f9568b9ddfadacdb1e749","lease_deadline_ms":1788814195157,"lease_id":"01M1YT4155CBTGVGT35CXTQPWK","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":8,"step_id":"report-package"} +{"at_ms":1788814165205,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"PACKAGE_EXECUTED: F8b; delivery requires a branch commit and human-reviewed PR.\ndiff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts\nindex 87f1f24..8cd088d 100644\n--- a/packages/sdk/src/compile.ts\n+++ b/packages/sdk/src/compile.ts\n@@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const\n : [];\n assertKernelKeys(step, [...commonKeys, ...typeKeys], at);\n- if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`);\n+ if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`);\n const dependsOn = step['depends_on'];\n const common = {\n id: step['id'],\n@@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown {\n return common;\n }\n \n-function validateKernelRetry(value: unknown, at: string): void {\n+function validateAuthoringRetryDefaults(value: unknown, at: string): void {\n const retry = requireKernelObject(value, [\n 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent',\n ], at);\n"},"verification":{"detail":"all gates passed","gate":"exit_code","verdict":"pass"}},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":9,"step_id":"report-package"} +{"at_ms":1788814165205,"attempt":null,"entry_type":"run.completed","payload":{"budget_total":{"dollars":"0","tokens_in":0,"tokens_out":0},"completionReason":"success","failed_step_id":null},"run_id":"01M1YT3XA5QB7GYRGY2MH2HG7T","segment_id":1,"seq":10,"step_id":null} +LOCAL_JOURNAL=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-J50W0n/journal.jsonl +{"ok":true,"command":"run","path":"workflows/drive-local.yaml","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"select-package","message":"Step \"select-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"implement-package","message":"Step \"implement-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"command_unresolved","stepId":"verify-package","message":"Step \"verify-package\" command \"set\" does not resolve as an executable; it runs only if the shell supplies it."},{"severity":"warning","kind":"unprovable_effects","stepId":"report-package","message":"Step \"report-package\" command \"node\" resolves, but its effects cannot be proven before execution."}],"runId":"01M1YT3XA5QB7GYRGY2MH2HG7T","socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-J50W0n/relayflowd.sock","status":"completed","completionReason":"success","completedSteps":4} diff --git a/ops/runtime-evidence/drive-verify.txt b/ops/runtime-evidence/drive-verify.txt new file mode 100644 index 000000000..ec45e84e8 --- /dev/null +++ b/ops/runtime-evidence/drive-verify.txt @@ -0,0 +1,17 @@ + +> @relayflows/sdk@2.0.1 build +> tsc && node scripts/make-cli-executable.mjs + + + RUN v2.1.9 /Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/packages/sdk + + ✓ tests/spec-parity.test.ts (28 tests) 160ms + ✓ tests/cli.test.ts (63 tests) 2386ms + ✓ flows check CLI > binds a checked relative wrapper to the flow directory for worker execution 380ms + ✓ flows check CLI > resolves a project CLI path relative to the flows.json that declares it 310ms + + Test Files 2 passed (2) + Tests 91 passed (91) + Start at 22:49:22 + Duration 2.79s (transform 168ms, setup 0ms, collect 402ms, tests 2.55s, environment 0ms, prepare 75ms) + diff --git a/ops/runtime-evidence/environment.txt b/ops/runtime-evidence/environment.txt new file mode 100644 index 000000000..a10c43934 --- /dev/null +++ b/ops/runtime-evidence/environment.txt @@ -0,0 +1,24 @@ +$ pwd +/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt +exit=0 +$ uname -sm +Darwin arm64 +exit=0 +$ df -h . +Filesystem Size Used Avail Capacity iused ifree %iused Mounted on +/dev/disk3s5 228Gi 174Gi 21Gi 90% 4.2M 221M 2% /System/Volumes/Data +exit=0 +$ git branch --show-current +runtime/flows-restore-0907 +exit=0 +$ git rev-parse HEAD +460c0f7723da0c0fe8d5fffb87f60c058996ca3e +exit=0 +$ node --version +v26.7.0 +exit=0 +$ sh -c 'command -v flows; command -v relayflows' +exit=1 +$ sh -c 'ls "$HOME"/.relayflows-toolchain/target/*/debug/relayflowd' +ls: /Users/khaliqgant/.relayflows-toolchain/target/*/debug/relayflowd: No such file or directory +exit=1 diff --git a/ops/runtime-evidence/f8b.diff b/ops/runtime-evidence/f8b.diff new file mode 100644 index 000000000..33bab453e --- /dev/null +++ b/ops/runtime-evidence/f8b.diff @@ -0,0 +1,22 @@ +diff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts +index 87f1f24..8cd088d 100644 +--- a/packages/sdk/src/compile.ts ++++ b/packages/sdk/src/compile.ts +@@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown { + ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const + : []; + assertKernelKeys(step, [...commonKeys, ...typeKeys], at); +- if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`); ++ if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`); + const dependsOn = step['depends_on']; + const common = { + id: step['id'], +@@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown { + return common; + } + +-function validateKernelRetry(value: unknown, at: string): void { ++function validateAuthoringRetryDefaults(value: unknown, at: string): void { + const retry = requireKernelObject(value, [ + 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent', + ], at); diff --git a/ops/runtime-evidence/hello-before.txt b/ops/runtime-evidence/hello-before.txt new file mode 100644 index 000000000..6165f0c74 --- /dev/null +++ b/ops/runtime-evidence/hello-before.txt @@ -0,0 +1,4 @@ +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 "/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflowd/relayflowd.sock". Start it with: relayflowd --data-dir ".relayflowd" serve +{"ok":false,"command":"run","path":"testdata/hello-deterministic.flow.yaml","projectConfigPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/testdata/flows.json","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"greet","message":"Step \"greet\" command \"echo\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"shout","message":"Step \"shout\" command \"echo\" resolves, but its effects cannot be proven before execution."},{"severity":"refusal","kind":"daemon_unreachable","message":"No compatible relayflowd is listening at \"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflowd/relayflowd.sock\". Start it with: relayflowd --data-dir \".relayflowd\" serve"}],"socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflowd/relayflowd.sock"} diff --git a/ops/runtime-evidence/hello-clean-env.txt b/ops/runtime-evidence/hello-clean-env.txt new file mode 100644 index 000000000..c98eb231b --- /dev/null +++ b/ops/runtime-evidence/hello-clean-env.txt @@ -0,0 +1,11 @@ +{"severity":"warning","kind":"unprovable_effects","stepId":"greet","message":"Step \"greet\" command \"echo\" resolves, but its effects cannot be proven before execution."} +{"severity":"warning","kind":"unprovable_effects","stepId":"shout","message":"Step \"shout\" command \"echo\" resolves, but its effects cannot be proven before execution."} +LOCAL_DATA_DIR=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-ydugI4 +{"at_ms":1788814242180,"attempt":null,"entry_type":"run.spawned","payload":{"created_by":"protocol-v0","journal_version":1,"parent_run_id":null,"spec":{"description":"The canonical hello ladder rung (a) — zero agents, legal.","name":"hello-deterministic","steps":[{"command":"echo hello","depends_on":[],"id":"greet","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{"output_contains":"hello"}},{"command":"echo HELLO","depends_on":["greet"],"id":"shout","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{"output_contains":"HELLO"}}],"version":"0.1.0"},"spec_hash":"e77b0920a08ee65ea632f54f3f477f14698781d2670634c89bb408f8cd727117"},"run_id":"01M1YT6CC37S7MVDXXTNEZRT8Z","segment_id":1,"seq":1,"step_id":null} +{"at_ms":1788814242189,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"a0c9f603ea949a86c55d0731e8fea78086b43c2358876c7c8dbe1469e1cb70c4","lease_deadline_ms":1788814272189,"lease_id":"01M1YT6CCDQADAQ8Y1E49339KE","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT6CC37S7MVDXXTNEZRT8Z","segment_id":1,"seq":2,"step_id":"greet"} +{"at_ms":1788814242193,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"hello\n"},"verification":{"detail":"all gates passed","gate":"exit_code+output_contains","verdict":"pass"}},"run_id":"01M1YT6CC37S7MVDXXTNEZRT8Z","segment_id":1,"seq":3,"step_id":"greet"} +{"at_ms":1788814242194,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"ac87a2fc8cc92bd0e9e3752f4a2859f214e3b834a3eb314c5028f2c1f505c557","lease_deadline_ms":1788814272194,"lease_id":"01M1YT6CCJ7HHPYV3RGRZ7Y9B0","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YT6CC37S7MVDXXTNEZRT8Z","segment_id":1,"seq":4,"step_id":"shout"} +{"at_ms":1788814242197,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"HELLO\n"},"verification":{"detail":"all gates passed","gate":"exit_code+output_contains","verdict":"pass"}},"run_id":"01M1YT6CC37S7MVDXXTNEZRT8Z","segment_id":1,"seq":5,"step_id":"shout"} +{"at_ms":1788814242198,"attempt":null,"entry_type":"run.completed","payload":{"budget_total":{"dollars":"0","tokens_in":0,"tokens_out":0},"completionReason":"success","failed_step_id":null},"run_id":"01M1YT6CC37S7MVDXXTNEZRT8Z","segment_id":1,"seq":6,"step_id":null} +LOCAL_JOURNAL=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-ydugI4/journal.jsonl +{"ok":true,"command":"run","path":"testdata/hello-deterministic.flow.yaml","projectConfigPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/testdata/flows.json","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"greet","message":"Step \"greet\" command \"echo\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"shout","message":"Step \"shout\" command \"echo\" resolves, but its effects cannot be proven before execution."}],"runId":"01M1YT6CC37S7MVDXXTNEZRT8Z","socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-ydugI4/relayflowd.sock","status":"completed","completionReason":"success","completedSteps":2} diff --git a/ops/runtime-evidence/hello-kernel.txt b/ops/runtime-evidence/hello-kernel.txt new file mode 100644 index 000000000..3ba4c3589 --- /dev/null +++ b/ops/runtime-evidence/hello-kernel.txt @@ -0,0 +1 @@ +{"run_id":"01M1YSGGNGHFF10DYQB4WESTG4","status":"completed","completion_reason":"success","completed_steps":2} diff --git a/ops/runtime-evidence/hello-launcher.txt b/ops/runtime-evidence/hello-launcher.txt new file mode 100644 index 000000000..6f0f7f0a7 --- /dev/null +++ b/ops/runtime-evidence/hello-launcher.txt @@ -0,0 +1,11 @@ +{"severity":"warning","kind":"unprovable_effects","stepId":"greet","message":"Step \"greet\" command \"echo\" resolves, but its effects cannot be proven before execution."} +{"severity":"warning","kind":"unprovable_effects","stepId":"shout","message":"Step \"shout\" command \"echo\" resolves, but its effects cannot be proven before execution."} +LOCAL_DATA_DIR=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-S0NmcN +{"at_ms":1788813760358,"attempt":null,"entry_type":"run.spawned","payload":{"created_by":"protocol-v0","journal_version":1,"parent_run_id":null,"spec":{"description":"The canonical hello ladder rung (a) — zero agents, legal.","name":"hello-deterministic","steps":[{"command":"echo hello","depends_on":[],"id":"greet","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{"output_contains":"hello"}},{"command":"echo HELLO","depends_on":["greet"],"id":"shout","max_iterations":1,"retry":{"initial_backoff_ms":100,"jitter_percent":20,"max_backoff_ms":60000,"multiplier":2},"type":"deterministic","verification":{"output_contains":"HELLO"}}],"version":"0.1.0"},"spec_hash":"e77b0920a08ee65ea632f54f3f477f14698781d2670634c89bb408f8cd727117"},"run_id":"01M1YSQNV679TF3H9VVWSFVTC4","segment_id":1,"seq":1,"step_id":null} +{"at_ms":1788813760362,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"9e7da1769c3278cd571772fb351f1348ae6b9aa301ec326dfc7485252ea6d52b","lease_deadline_ms":1788813790362,"lease_id":"01M1YSQNVANYM1CQ8CZ3F2C0EA","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YSQNV679TF3H9VVWSFVTC4","segment_id":1,"seq":2,"step_id":"greet"} +{"at_ms":1788813760366,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"hello\n"},"verification":{"detail":"all gates passed","gate":"exit_code+output_contains","verdict":"pass"}},"run_id":"01M1YSQNV679TF3H9VVWSFVTC4","segment_id":1,"seq":3,"step_id":"greet"} +{"at_ms":1788813760366,"attempt":1,"entry_type":"step.attempt.started","payload":{"executor":"kernel","idempotency_key":"4dae5eb080e491e3c8e051630f2befadfce0b4d603ca58b73ee95003468b7505","lease_deadline_ms":1788813790366,"lease_id":"01M1YSQNVE905JAKYTAAMPX7NP","max_iterations":1,"pins":{"streams":[],"workspace":[]},"recovery_mode":null,"step_type":"deterministic"},"run_id":"01M1YSQNV679TF3H9VVWSFVTC4","segment_id":1,"seq":4,"step_id":"shout"} +{"at_ms":1788813760369,"attempt":1,"entry_type":"step.completed","payload":{"budget":{"dollars":"0","tokens_in":0,"tokens_out":0},"completed_by":"kernel","completionReason":"success","disposition":"step_done","effects":[],"end_pins":null,"next_attempt_at_ms":null,"output":{"exit_code":0,"stderr_tail":"","stdout_tail":"HELLO\n"},"verification":{"detail":"all gates passed","gate":"exit_code+output_contains","verdict":"pass"}},"run_id":"01M1YSQNV679TF3H9VVWSFVTC4","segment_id":1,"seq":5,"step_id":"shout"} +{"at_ms":1788813760370,"attempt":null,"entry_type":"run.completed","payload":{"budget_total":{"dollars":"0","tokens_in":0,"tokens_out":0},"completionReason":"success","failed_step_id":null},"run_id":"01M1YSQNV679TF3H9VVWSFVTC4","segment_id":1,"seq":6,"step_id":null} +LOCAL_JOURNAL=/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-S0NmcN/journal.jsonl +{"ok":true,"command":"run","path":"testdata/hello-deterministic.flow.yaml","projectConfigPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/testdata/flows.json","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"greet","message":"Step \"greet\" command \"echo\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"shout","message":"Step \"shout\" command \"echo\" resolves, but its effects cannot be proven before execution."}],"runId":"01M1YSQNV679TF3H9VVWSFVTC4","socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflow/local-S0NmcN/relayflowd.sock","status":"completed","completionReason":"success","completedSteps":2} diff --git a/ops/runtime-evidence/hello-sdk.txt b/ops/runtime-evidence/hello-sdk.txt new file mode 100644 index 000000000..2d3ec1f75 --- /dev/null +++ b/ops/runtime-evidence/hello-sdk.txt @@ -0,0 +1,3 @@ +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. +{"ok":true,"command":"run","path":"testdata/hello-deterministic.flow.yaml","projectConfigPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/testdata/flows.json","resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"greet","message":"Step \"greet\" command \"echo\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"shout","message":"Step \"shout\" command \"echo\" resolves, but its effects cannot be proven before execution."}],"runId":"01M1YSGZZJ3Z0SD3RCM53EF8G5","socketPath":"/Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/.relayflowd/relayflowd.sock","status":"completed","completionReason":"success","completedSteps":2} diff --git a/ops/runtime-evidence/launcher-tests-first.txt b/ops/runtime-evidence/launcher-tests-first.txt new file mode 100644 index 000000000..808cb2a09 --- /dev/null +++ b/ops/runtime-evidence/launcher-tests-first.txt @@ -0,0 +1,69 @@ +✖ local launcher journals deterministic effects and reads more than one journal page (556.277042ms) +✖ a failed command fails the run and prevents dependent effects (128.573917ms) +✖ the SDK worker completes an agent step through the local journal protocol (508.455542ms) +✔ missing daemon is refused before a data directory or run is created (61.799041ms) +ℹ tests 4 +ℹ suites 0 +ℹ pass 1 +ℹ fail 3 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 1293.743333 + +✖ failing tests: + +test at scripts/run-local-workflow.test.mjs:25:1 +✖ local launcher journals deterministic effects and reads more than one journal page (556.277042ms) + AssertionError [ERR_ASSERTION]: owned daemon socket must be removed on exit + at run (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:21:16) + at TestContext. (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:26:18) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1397:25) + at Test.start (node:internal/test_runner/test:1257:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: '==', + diff: 'simple' + } + +test at scripts/run-local-workflow.test.mjs:37:1 +✖ a failed command fails the run and prevents dependent effects (128.573917ms) + AssertionError [ERR_ASSERTION]: owned daemon socket must be removed on exit + at run (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:21:16) + at TestContext. (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:39:18) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1397:25) + at Test.processPendingSubtests (node:internal/test_runner/test:969:18) + at Test.postRun (node:internal/test_runner/test:1537:19) + at Test.run (node:internal/test_runner/test:1462:12) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: '==', + diff: 'simple' + } + +test at scripts/run-local-workflow.test.mjs:50:1 +✖ the SDK worker completes an agent step through the local journal protocol (508.455542ms) + AssertionError [ERR_ASSERTION]: owned daemon socket must be removed on exit + at run (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:21:16) + at TestContext. (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:55:18) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1397:25) + at Test.processPendingSubtests (node:internal/test_runner/test:969:18) + at Test.postRun (node:internal/test_runner/test:1537:19) + at Test.run (node:internal/test_runner/test:1462:12) + at async Test.processPendingSubtests (node:internal/test_runner/test:969:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: '==', + diff: 'simple' + } diff --git a/ops/runtime-evidence/launcher-tests-second.txt b/ops/runtime-evidence/launcher-tests-second.txt new file mode 100644 index 000000000..f98e20e09 --- /dev/null +++ b/ops/runtime-evidence/launcher-tests-second.txt @@ -0,0 +1,47 @@ +✔ local launcher journals deterministic effects and reads more than one journal page (540.837792ms) +✖ a failed command fails the run and prevents dependent effects (127.706375ms) +✖ the SDK worker completes an agent step through the local journal protocol (509.003125ms) +✔ missing daemon is refused before a data directory or run is created (60.591541ms) +ℹ tests 4 +ℹ suites 0 +ℹ pass 2 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 1277.121583 + +✖ failing tests: + +test at scripts/run-local-workflow.test.mjs:37:1 +✖ a failed command fails the run and prevents dependent effects (127.706375ms) + TypeError: Cannot read properties of null (reading 'exit_code') + at TestContext. (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:47:98) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1397:25) + at Test.processPendingSubtests (node:internal/test_runner/test:969:18) + at Test.postRun (node:internal/test_runner/test:1537:19) + at Test.run (node:internal/test_runner/test:1462:12) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) + +test at scripts/run-local-workflow.test.mjs:50:1 +✖ the SDK worker completes an agent step through the local journal protocol (509.003125ms) + AssertionError [ERR_ASSERTION]: bad_request: an agent worker must attach with the pins of the surfaces it holds + + + 1 !== 0 + + at TestContext. (file:///Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/scripts/run-local-workflow.test.mjs:61:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1397:25) + at Test.processPendingSubtests (node:internal/test_runner/test:969:18) + at Test.postRun (node:internal/test_runner/test:1537:19) + at Test.run (node:internal/test_runner/test:1462:12) + at async Test.processPendingSubtests (node:internal/test_runner/test:969:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 1, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/ops/runtime-evidence/launcher-tests.txt b/ops/runtime-evidence/launcher-tests.txt new file mode 100644 index 000000000..ac79de202 --- /dev/null +++ b/ops/runtime-evidence/launcher-tests.txt @@ -0,0 +1,12 @@ +✔ local launcher journals deterministic effects and reads more than one journal page (537.042792ms) +✔ a failed command fails the run and prevents dependent effects (127.248833ms) +✔ the SDK worker completes an agent step through the local journal protocol (541.697084ms) +✔ missing daemon is refused before a data directory or run is created (59.212417ms) +ℹ tests 4 +ℹ suites 0 +ℹ pass 4 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 1305.905833 diff --git a/ops/runtime-evidence/raw-evidence-whitespace.txt b/ops/runtime-evidence/raw-evidence-whitespace.txt new file mode 100644 index 000000000..96ff28004 --- /dev/null +++ b/ops/runtime-evidence/raw-evidence-whitespace.txt @@ -0,0 +1,12 @@ +ops/runtime-evidence/build-sdk.txt:4: new blank line at EOF. +ops/runtime-evidence/crash-resume.txt:59: new blank line at EOF. +ops/runtime-evidence/drive-verify.txt:17: new blank line at EOF. +ops/runtime-evidence/f8b.diff:17: trailing whitespace. ++ +ops/runtime-evidence/launcher-tests-second.txt:30: trailing whitespace. ++ +ops/runtime-evidence/launcher-tests-second.txt:31: trailing whitespace. ++ +ops/runtime-evidence/launcher-tests-second.txt:33: trailing whitespace. ++ +ops/runtime-evidence/workflow-checks.txt:32: new blank line at EOF. diff --git a/ops/runtime-evidence/reset-package-for-final-run.txt b/ops/runtime-evidence/reset-package-for-final-run.txt new file mode 100644 index 000000000..c05ab7e15 --- /dev/null +++ b/ops/runtime-evidence/reset-package-for-final-run.txt @@ -0,0 +1,3 @@ +Restored only the first local tick's two-line rename to scaffold HEAD for the final run. +before=92d08a43a14c1406b2238259513fda0906da276470b24f76270b0f5ed863aa93 +after=5840c31f95d1446cbbd8e523073176abb3c2fffd684864cb4fdeb2932709865d diff --git a/ops/runtime-evidence/scaffold-head.txt b/ops/runtime-evidence/scaffold-head.txt new file mode 100644 index 000000000..72f1816c1 --- /dev/null +++ b/ops/runtime-evidence/scaffold-head.txt @@ -0,0 +1 @@ +89f2f1d31f262420c2c5f613efa3f50c70153bfa diff --git a/ops/runtime-evidence/spec-review-build.txt b/ops/runtime-evidence/spec-review-build.txt new file mode 100644 index 000000000..b0cfad0df --- /dev/null +++ b/ops/runtime-evidence/spec-review-build.txt @@ -0,0 +1,7 @@ +$ npm --userconfig /tmp/empty-npmrc run build --prefix packages/sdk + +> @relayflows/sdk@2.0.1 build +> tsc && node scripts/make-cli-executable.mjs + + +exit_code=0 diff --git a/ops/runtime-evidence/spec-review-existing-tests.txt b/ops/runtime-evidence/spec-review-existing-tests.txt new file mode 100644 index 000000000..b17bb8a9c --- /dev/null +++ b/ops/runtime-evidence/spec-review-existing-tests.txt @@ -0,0 +1,16 @@ +$ node node_modules/vitest/vitest.mjs run tests/spec-parity.test.ts tests/cli.test.ts + + RUN v2.1.9 /Users/khaliqgant/AgentWorkforce/flows-runtime-0907-wt/packages/sdk + + ✓ tests/spec-parity.test.ts (28 tests) 153ms + ✓ tests/cli.test.ts (63 tests) 2492ms + ✓ flows check CLI > binds a checked relative wrapper to the flow directory for worker execution 474ms + ✓ flows check CLI > uses the raw Claude adapter model flag instead of accepting auth status as model proof 306ms + + Test Files 2 passed (2) + Tests 91 passed (91) + Start at 23:44:42 + Duration 2.86s (transform 166ms, setup 0ms, collect 408ms, tests 2.64s, environment 0ms, prepare 76ms) + + +exit_code=0 diff --git a/ops/runtime-evidence/spec-review-local-tests.txt b/ops/runtime-evidence/spec-review-local-tests.txt new file mode 100644 index 000000000..d0b9f2b79 --- /dev/null +++ b/ops/runtime-evidence/spec-review-local-tests.txt @@ -0,0 +1,16 @@ +$ node --test scripts/run-local-workflow.test.mjs ops/local-work-package.test.mjs +✔ interrupted package write preserves the original and retry applies once (243.952833ms) +✔ local launcher journals deterministic effects and reads more than one journal page (601.889709ms) +✔ a failed command fails the run and prevents dependent effects (130.195167ms) +✔ the SDK worker completes an agent step through the local journal protocol (595.823584ms) +✔ missing daemon is refused before a data directory or run is created (62.254666ms) +ℹ tests 5 +ℹ suites 0 +ℹ pass 5 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 1429.743458 + +exit_code=0 diff --git a/ops/runtime-evidence/workflow-checks.txt b/ops/runtime-evidence/workflow-checks.txt new file mode 100644 index 000000000..19a671632 --- /dev/null +++ b/ops/runtime-evidence/workflow-checks.txt @@ -0,0 +1,32 @@ +$ node packages/sdk/dist/cli.js check --json workflows/bootstrap-gate1.yaml +exit=2 +{"ok":false,"path":"workflows/bootstrap-gate1.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array + +$ node packages/sdk/dist/cli.js check --json workflows/drive-cloud.yaml +exit=2 +{"ok":false,"path":"workflows/drive-cloud.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array + +$ node packages/sdk/dist/cli.js check --json workflows/drive.yaml +exit=2 +{"ok":false,"path":"workflows/drive.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array + +$ node packages/sdk/dist/cli.js check --json workflows/preswarm-check.yaml +exit=0 +{"ok":true,"path":"workflows/preswarm-check.yaml","gates":[{"stepId":"lens-maintainability","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true},{"stepId":"lens-history","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true},{"stepId":"lens-structure","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true}],"resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"lens-maintainability","message":"Step \"lens-maintainability\" command \"sh\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"lens-history","message":"Step \"lens-history\" command \"sh\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"lens-structure","message":"Step \"lens-structure\" command \"sh\" resolves, but its effects cannot be proven before execution."}]} +WARNING [unprovable_effects] Step "lens-maintainability" command "sh" resolves, but its effects cannot be proven before execution. +WARNING [unprovable_effects] Step "lens-history" command "sh" resolves, but its effects cannot be proven before execution. +WARNING [unprovable_effects] Step "lens-structure" command "sh" resolves, but its effects cannot be proven before execution. + +$ node packages/sdk/dist/cli.js check --json workflows/review-swarm.yaml +exit=2 +{"ok":false,"path":"workflows/review-swarm.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array + +$ node packages/sdk/dist/cli.js check --json workflows/watchdog.yaml +exit=2 +{"ok":false,"path":"workflows/watchdog.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array + diff --git a/ops/runtime-evidence/workflow-summary.txt b/ops/runtime-evidence/workflow-summary.txt new file mode 100644 index 000000000..768fa4889 --- /dev/null +++ b/ops/runtime-evidence/workflow-summary.txt @@ -0,0 +1,39 @@ +$ node packages/sdk/dist/cli.js check --json workflows/bootstrap-gate1.yaml +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array +{"ok":false,"path":"workflows/bootstrap-gate1.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +exit=2 + +$ node packages/sdk/dist/cli.js check --json workflows/drive-cloud.yaml +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array +{"ok":false,"path":"workflows/drive-cloud.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +exit=2 + +$ node packages/sdk/dist/cli.js check --json workflows/drive-local.yaml +WARNING [unprovable_effects] Step "select-package" command "node" resolves, but its effects cannot be proven before execution. +WARNING [unprovable_effects] Step "implement-package" command "node" resolves, but its effects cannot be proven before execution. +WARNING [command_unresolved] Step "verify-package" command "set" does not resolve as an executable; it runs only if the shell supplies it. +WARNING [unprovable_effects] Step "report-package" command "node" resolves, but its effects cannot be proven before execution. +{"ok":true,"path":"workflows/drive-local.yaml","gates":[{"stepId":"select-package","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true},{"stepId":"implement-package","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true},{"stepId":"verify-package","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true},{"stepId":"report-package","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true}],"resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"select-package","message":"Step \"select-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"implement-package","message":"Step \"implement-package\" command \"node\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"command_unresolved","stepId":"verify-package","message":"Step \"verify-package\" command \"set\" does not resolve as an executable; it runs only if the shell supplies it."},{"severity":"warning","kind":"unprovable_effects","stepId":"report-package","message":"Step \"report-package\" command \"node\" resolves, but its effects cannot be proven before execution."}]} +exit=0 + +$ node packages/sdk/dist/cli.js check --json workflows/drive.yaml +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array +{"ok":false,"path":"workflows/drive.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +exit=2 + +$ node packages/sdk/dist/cli.js check --json workflows/preswarm-check.yaml +WARNING [unprovable_effects] Step "lens-maintainability" command "sh" resolves, but its effects cannot be proven before execution. +WARNING [unprovable_effects] Step "lens-history" command "sh" resolves, but its effects cannot be proven before execution. +WARNING [unprovable_effects] Step "lens-structure" command "sh" resolves, but its effects cannot be proven before execution. +{"ok":true,"path":"workflows/preswarm-check.yaml","gates":[{"stepId":"lens-maintainability","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true},{"stepId":"lens-history","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true},{"stepId":"lens-structure","kind":"data","checks":["exit_code"],"evaluator":"kernel","preflightable":true,"replayable":true}],"resolutions":[],"diagnostics":[{"severity":"warning","kind":"unprovable_effects","stepId":"lens-maintainability","message":"Step \"lens-maintainability\" command \"sh\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"lens-history","message":"Step \"lens-history\" command \"sh\" resolves, but its effects cannot be proven before execution."},{"severity":"warning","kind":"unprovable_effects","stepId":"lens-structure","message":"Step \"lens-structure\" command \"sh\" resolves, but its effects cannot be proven before execution."}]} +exit=0 + +$ node packages/sdk/dist/cli.js check --json workflows/review-swarm.yaml +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array +{"ok":false,"path":"workflows/review-swarm.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +exit=2 + +$ node packages/sdk/dist/cli.js check --json workflows/watchdog.yaml +REFUSED [invalid_spec] Relayflow spec is invalid: spec: unknown key "swarm" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key "workflows" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version "1.0" (expected "0.1.0"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array +{"ok":false,"path":"workflows/watchdog.yaml","gates":[],"resolutions":[],"diagnostics":[{"severity":"refusal","kind":"invalid_spec","message":"Relayflow spec is invalid: spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget); spec.version: unsupported version \"1.0\" (expected \"0.1.0\"); spec.agents: expected a map of named { cli, model } declarations; spec.steps: expected a non-empty array","errors":["spec: unknown key \"swarm\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec: unknown key \"workflows\" (expected one of version | name | description | cli | agents | triggers | steps | budget)","spec.version: unsupported version \"1.0\" (expected \"0.1.0\")","spec.agents: expected a map of named { cli, model } declarations","spec.steps: expected a non-empty array"]}]} +exit=2 diff --git a/packages/sdk/src/compile.ts b/packages/sdk/src/compile.ts index 87f1f2489..8cd088d52 100644 --- a/packages/sdk/src/compile.ts +++ b/packages/sdk/src/compile.ts @@ -368,7 +368,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown { ? ['instruction', 'cli', 'model', 'recovery_mode', 'surfaces', 'permissions'] as const : []; assertKernelKeys(step, [...commonKeys, ...typeKeys], at); - if (step['retry'] !== undefined) validateKernelRetry(step['retry'], `${at}.retry`); + if (step['retry'] !== undefined) validateAuthoringRetryDefaults(step['retry'], `${at}.retry`); const dependsOn = step['depends_on']; const common = { id: step['id'], @@ -404,7 +404,7 @@ function kernelStepToAuthoring(value: unknown, at: string): unknown { return common; } -function validateKernelRetry(value: unknown, at: string): void { +function validateAuthoringRetryDefaults(value: unknown, at: string): void { const retry = requireKernelObject(value, [ 'initial_backoff_ms', 'max_backoff_ms', 'multiplier', 'jitter_percent', ], at); diff --git a/scripts/run-local-workflow.mjs b/scripts/run-local-workflow.mjs new file mode 100644 index 000000000..8822a6e77 --- /dev/null +++ b/scripts/run-local-workflow.mjs @@ -0,0 +1,114 @@ +#!/usr/bin/env node +// A local cell for one YAML/JSON run. No cloud admission or sandbox provider. +import { spawn } from 'node:child_process'; +import { once } from 'node:events'; +import { access, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { constants } from 'node:fs'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { setTimeout as delay } from 'node:timers/promises'; + +const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +process.chdir(root); + +async function main() { + const [path, ...extra] = process.argv.slice(2); + if (!path || extra.length) throw new Error('Usage: node scripts/run-local-workflow.mjs '); + await access('packages/sdk/dist/cli.js').catch(() => { + throw new Error('LOCAL_SDK_MISSING: build packages/sdk first (see ops/RUNTIME-STATUS.md).'); + }); + const { checkFlow } = await import('../packages/sdk/dist/cli/check.js'); + const { classifyOutcome } = await import('../packages/sdk/dist/cli/run.js'); + const { toKernelSpec } = await import('../packages/sdk/dist/compile.js'); + const { JournalClient } = await import('../packages/sdk/dist/journal-client.js'); + const { AgentWorker } = await import('../packages/sdk/dist/worker.js'); + const checked = checkFlow(path); + for (const diagnostic of checked.report.diagnostics) console.error(JSON.stringify(diagnostic)); + if (!checked.report.ok) return 2; + const spec = toKernelSpec(checked.flow); + const streams = new Set(); + // This launcher has no mount revision manager or LLM worker. Refuse before + // creating a run rather than inventing pins or leaving an unserviceable step. + for (const step of spec.steps) { + if (step.type === 'llm') throw new Error(`LOCAL_LLM_WORKER_UNAVAILABLE: ${step.id}`); + if (step.type === 'agent') { + if (step.surfaces?.workspace?.length || step.surfaces?.external?.length) { + throw new Error(`LOCAL_SURFACE_PINS_UNAVAILABLE: ${step.id}`); + } + for (const { stream } of step.surfaces?.streams ?? []) streams.add(stream); + } + } + if (spec.steps.some(step => step.type === 'agent') && streams.size === 0) { + throw new Error('LOCAL_AGENT_PINS_REQUIRED: declare a stream; the kernel refuses workers with no pins.'); + } + const binary = resolve(process.env.RELAYFLOWD_BIN ?? 'kernel/target/debug/relayflowd'); + await access(binary, constants.X_OK).catch(() => { + throw new Error(`LOCAL_DAEMON_MISSING: ${binary}; build kernel or set RELAYFLOWD_BIN.`); + }); + await mkdir('.relayflow', { recursive: true }); + const dataDir = await mkdtemp(join(root, '.relayflow', 'local-')); + const socket = join(dataDir, 'relayflowd.sock'); + if (Buffer.byteLength(socket) >= 104) throw new Error(`LOCAL_SOCKET_PATH_TOO_LONG: ${socket}`); + console.log(`LOCAL_DATA_DIR=${dataDir}`); + const daemon = spawn(binary, ['--data-dir', dataDir, 'serve'], { stdio: ['ignore', 'ignore', 'inherit'] }); + let daemonError; + daemon.on('error', error => { daemonError = error; }); + const exited = once(daemon, 'close'); + // Keep rejections observed even if startup fails before shutdown awaits it. + exited.catch(() => {}); + const client = new JournalClient(socket); + let worker; + let workerError; + try { + let connected = false; + for (let attempt = 0; attempt < 100; attempt++) { + if (daemonError) throw daemonError; + if (daemon.exitCode !== null) throw new Error(`LOCAL_DAEMON_EXITED: ${daemon.exitCode}`); + try { await client.connect(); connected = true; break; } + catch { client.close(); await delay(50); } + } + if (!connected) throw new Error('LOCAL_DAEMON_START_TIMEOUT: no socket after 5 seconds'); + await client.hello('local-workflow'); + if (spec.steps.some(step => step.type === 'agent')) { + worker = new AgentWorker(client, { + workerId: 'local-agent', capacity: 1, + // Every run uses a fresh cell: its declared streams start at offset 0. + // No worktree revision or recovery ability is claimed by these pins. + pins: { workspace: [], streams: [...streams].map(stream => ({ stream, read_offset: 0 })) }, + }); + worker.on('error', error => { workerError = error; client.close(); }); + await worker.attach(); + } + const outcome = await client.runStart(spec); + const execution = await classifyOutcome(client, 'run', outcome, checked.report, socket, {}); + if (workerError) throw workerError; + const entries = []; + let from = 0; + for (;;) { + const page = await client.journalRead(outcome.run_id, from, 100); + if (page.entries.length === 0) break; + entries.push(...page.entries); + from = page.entries.at(-1).seq + 1; + } + const journalPath = join(dataDir, 'journal.jsonl'); + await writeFile(journalPath, entries.map(entry => JSON.stringify(entry)).join('\n') + '\n'); + for (const entry of entries) console.log(JSON.stringify(entry)); + console.log(`LOCAL_JOURNAL=${journalPath}`); + console.log(JSON.stringify(execution.report)); + return execution.exitCode; + } finally { + await worker?.close(); + client.close(); + daemon.kill('SIGTERM'); + const forced = setTimeout(() => daemon.kill('SIGKILL'), 1000); + try { + await exited; + await rm(socket, { force: true }); + } finally { clearTimeout(forced); } + } +} + +main().then(code => { process.exitCode = code; }).catch(error => { + console.error(error.message); + process.exitCode = 1; +}); diff --git a/scripts/run-local-workflow.test.mjs b/scripts/run-local-workflow.test.mjs new file mode 100644 index 000000000..8243b7a9c --- /dev/null +++ b/scripts/run-local-workflow.test.mjs @@ -0,0 +1,84 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import test, { after } from 'node:test'; + +const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +mkdirSync(join(root, '.relayflow'), { recursive: true }); +const fixtures = mkdtempSync(join(root, '.relayflow', 'launcher-tests-')); +const dataDirectories = new Set(); +after(() => { + for (const path of dataDirectories) rmSync(path, { recursive: true, force: true }); + rmSync(fixtures, { recursive: true, force: true }); +}); + +function run(name, steps, env = {}) { + const path = join(fixtures, `${name}.json`); + writeFileSync(path, JSON.stringify({ version: '0.1.0', name, steps })); + const result = spawnSync(process.execPath, ['scripts/run-local-workflow.mjs', path], { + cwd: root, encoding: 'utf8', timeout: 15000, env: { ...process.env, ...env }, + }); + const dataDir = result.stdout.match(/^LOCAL_DATA_DIR=(.+)$/m)?.[1]; + if (dataDir) dataDirectories.add(dataDir); + assert.equal(result.error, undefined, result.stderr); + const records = result.stdout.split('\n').filter(line => line.startsWith('{')).map(line => JSON.parse(line)); + if (dataDir) assert(!existsSync(join(dataDir, 'relayflowd.sock')), 'owned daemon socket must be removed on exit'); + return { ...result, records, dataDir }; +} + +test('local launcher journals deterministic effects and reads more than one journal page', () => { + const result = run('pagination', Array.from({ length: 51 }, (_, i) => ({ + id: `step-${i}`, type: 'deterministic', command: `printf step-${i}`, + ...(i ? { dependsOn: [`step-${i - 1}`] } : {}), + }))); + assert.equal(result.status, 0, result.stderr); + assert.equal(result.records.at(-1).completedSteps, 51); + const journal = readFileSync(join(result.dataDir, 'journal.jsonl'), 'utf8').trim().split('\n').map(JSON.parse); + assert.equal(journal.filter(entry => entry.entry_type === 'step.completed').length, 51); + assert.equal(journal.at(-1).entry_type, 'run.completed'); +}); + +test('a failed command fails the run and prevents dependent effects', () => { + const marker = join(fixtures, 'must-not-exist'); + const result = run('failure', [ + { id: 'fail', type: 'deterministic', command: 'exit 7' }, + { id: 'blocked', type: 'deterministic', command: `touch '${marker}'`, dependsOn: ['fail'] }, + ]); + assert.equal(result.status, 1, result.stderr); + assert.equal(result.records.at(-1).ok, false); + assert.equal(result.records.at(-1).status, 'failed'); + assert(!existsSync(marker)); + const completion = result.records.find(entry => entry.entry_type === 'step.completed'); + assert.equal(completion.payload.verification.detail, 'exit code was 7'); + assert.equal(completion.payload.verification.verdict, 'fail'); +}); + +test('the SDK worker completes an agent step through the local journal protocol', () => { + // A deterministic wrapper proves worker wiring, not model quality or auth. + const cli = join(fixtures, 'local-agent'); + const wrapper = join(root, 'testdata/preflight/wrapper-session.mjs'); + writeFileSync(cli, `#!/usr/bin/env node\nimport { receiveWrapperRequest } from ${JSON.stringify(wrapper)};\nconst request = await receiveWrapperRequest();\nif (request) console.log(JSON.stringify({ answer: request.instruction }));\n`, { mode: 0o755 }); + const result = run('worker', [{ + id: 'agent', type: 'agent', cli, instruction: 'local-worker-proof', + surfaces: { streams: [{ stream: 'local-proof' }] }, + verification: { type: 'json_schema', schema: { + type: 'object', required: ['answer'], properties: { answer: { const: 'local-worker-proof' } }, + } }, + }]); + assert.equal(result.status, 0, result.stderr); + const completion = result.records.find(entry => entry.entry_type === 'step.completed'); + assert.equal(completion.payload.completionReason, 'success'); + assert.deepEqual(completion.payload.output, { answer: 'local-worker-proof' }); + assert.equal(result.records.at(-1).completedSteps, 1); +}); + +test('missing daemon is refused before a data directory or run is created', () => { + const result = run('missing-daemon', [{ id: 'hello', type: 'deterministic', command: 'echo hello' }], { + RELAYFLOWD_BIN: join(fixtures, 'absent-relayflowd'), + }); + assert.equal(result.status, 1); + assert.match(result.stderr, /LOCAL_DAEMON_MISSING/); + assert.equal(result.dataDir, undefined); +}); diff --git a/workflows/README.md b/workflows/README.md new file mode 100644 index 000000000..7a2758a2a --- /dev/null +++ b/workflows/README.md @@ -0,0 +1,54 @@ +# Running the workflows + +There are two engines here. `flows` (this repository's SDK + `relayflowd`) +accepts the `version: '0.1.0'`, top-level `steps:` dialect. `relayflows` is +the previous engine: its `version: '1.0'`, `swarm:` / `workflows:` dialect is +not accepted by `flows`. Changing the launch location does not translate it. + +| Workflow | Engine | Placement and external dependencies | +| --- | --- | --- | +| `drive-local.yaml` | `flows` / local kernel | Local, deterministic F8b work package from `ops/BACKLOG.md`. Requires built SDK, local kernel, Node/npm and a work branch. Runtime has no Cloud, Daytona, Relaycast, GitHub or model call. Installation needs package registries. | +| `preswarm-check.yaml` | `flows` / local kernel | Local review of a committed diff against `main` (or `BASE_REF`). Invokes installed/authenticated Claude, Codex and OpenCode CLIs; those use their model services. No Cloud admission or Daytona. Passing `flows check` proves only that `sh` resolves, not the nested reviewers' auth. | +| `drive.yaml` | Previous `relayflows` engine | Written for either an existing checkout or a cloud snapshot. Local operation requires that engine plus Claude/Codex and toolchains; PR delivery needs GitHub access. Cloud snapshot delivery uses the Cloud proxy or external recovery. Its sync step resets/checks out branches: do not run it over an active worktree. | +| `drive-cloud.yaml` | Previous `relayflows` engine | Generated cloud-oriented drive loop. Its documented delivery path relies on Cloud run artifacts and `agent-relay cloud sync`. Local execution would not reproduce that delivery contract. Do not hand-edit the generated file. | +| `bootstrap-gate1.yaml` | Previous `relayflows` engine | Bootstrap using the previous generation, per RFC §2.1. No intrinsic Cloud/Daytona command; needs Claude, Codex, OpenCode, Rust/npm and writable source. Historical bootstrap, not a harmless smoke test. | +| `review-swarm.yaml` | Previous `relayflows` engine | Repository CI launches this in Cloud with staged `.review-target` artifacts. The steps could run under a local legacy engine with those artifacts and all three authenticated reviewers; Cloud is the CI placement, not a kernel requirement. It writes `/tmp` review inputs and commits transcripts. | +| `watchdog.yaml` | Previous `relayflows` engine | Requires Cloud API access even with a local executor: it inspects `agent-relay cloud schedules`. Also needs GitHub, Claude and Relaycast channel delivery. | + +These are dependency classifications from the checked-in workflows and +launchers, not claims that the legacy flows completed on this machine. Their +first observed failure with the current SDK is `invalid_spec`. Literal +checks and current execution evidence are in [RUNTIME-STATUS](../ops/RUNTIME-STATUS.md). + +## Start a local run + +After building the SDK and kernel (commands in RUNTIME-STATUS): + +```sh +node scripts/run-local-workflow.mjs testdata/hello-deterministic.flow.yaml +node scripts/run-local-workflow.mjs workflows/drive-local.yaml +``` + +The launcher starts a fresh local daemon, submits through the journal +protocol, prints journal entries and the terminal report, then stops its +daemon. `LOCAL_DATA_DIR` contains the SQLite journal and a `journal.jsonl` +export. It can also attach the SDK worker for stream-only agent steps; +bare LLM steps and agent workspace/external surfaces are refused before +submission. This is a bounded local runner, not a cloud scheduler or sandbox. +Agent CLIs use the host's existing execution/auth configuration; it supplies +no filesystem isolation, workspace reset, or lease heartbeat loop. The agent +wiring test uses a deterministic wrapper, not a model service. + +`drive-local.yaml` executes one explicitly selected package (F8b), rather than +autonomously choosing arbitrary engineering work. It refuses a dirty target, +changed source, or an already-applied package. Its implementation step checks +the before/after bytes. Existing SDK tests run as a dependent deterministic +step, with their stdout in the journal. Commit and PR delivery remain an +operator action; a human owns merge. After F8b is delivered, use the hello +flow for a repeatable smoke run. The scaffold commit recorded in +RUNTIME-STATUS is the reproducible starting point for the F8b tick. + +`scripts/run-workflow.sh` is still the legacy launcher: it requires a +stored Relaycast workspace key and mints an observer link before invoking +`relayflows run`. Use the local launcher above when proving independence +from Cloud and Relaycast; local journals remain the source of truth. diff --git a/workflows/drive-local.yaml b/workflows/drive-local.yaml new file mode 100644 index 000000000..9760c43c2 --- /dev/null +++ b/workflows/drive-local.yaml @@ -0,0 +1,28 @@ +# A bounded, deterministic drive tick: execute backlog F8b on this checkout. +# Run: node scripts/run-local-workflow.mjs workflows/drive-local.yaml +# Selection, mutation, existing tests, and the resulting diff are journaled. +# Delivery is a branch/PR by the operator; this flow never merges or switches branches. +version: '0.1.0' +name: drive-local-f8b +description: Correct the retry validator name to describe the authoring restriction (BACKLOG F8b). +steps: + - id: select-package + type: deterministic + command: node ops/local-work-package.mjs select + - id: implement-package + type: deterministic + dependsOn: [select-package] + command: node ops/local-work-package.mjs apply + - id: verify-package + type: deterministic + dependsOn: [implement-package] + timeoutMs: 120000 + command: | + set -eu + npm_config_cache="$PWD/.relayflow/npm-cache" npm --userconfig /tmp/empty-npmrc run build --prefix packages/sdk + cd packages/sdk + node node_modules/vitest/vitest.mjs run tests/spec-parity.test.ts tests/cli.test.ts + - id: report-package + type: deterministic + dependsOn: [verify-package] + command: node ops/local-work-package.mjs report