Skip to content

Issue #29: targeted task reconciliation - #50

Merged
myobie merged 39 commits into
mainfrom
agent/issue-29-targeted-reconcile
Jul 30, 2026
Merged

Issue #29: targeted task reconciliation#50
myobie merged 39 commits into
mainfrom
agent/issue-29-targeted-reconcile

Conversation

@myobie

@myobie myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Problem

Task-scoped reconciliation must avoid whole-catalog mutation and preserve sibling isolation. The motivating failure in #29 was a targeted agent/task change blocked by an unrelated slow workspace because materialization walked the entire host catalog.

What changed

  • Added exact local task resolution for runtime ids and qualified <host>.<agent>.<task> selectors.
  • Added selected reconcile planning for missing, live, dead, kept, retired, and unrunnable tasks.
  • Added st2 up --materialize-only --task <selector> for owner-only rendering.
  • Added st2 up --once --task <selector> for bounded owner-only materialization plus selected task reconciliation.
  • Kept single-file specs and unbounded targeted supervision fail-closed.
  • Preserved selected Codex lifecycle-hook gates, including direct-argv Codex launches, and made targeted CLI report errors nonzero.
  • Documented the R19 targeted reconciliation contract and operator command.

Safety contract

Unknown, ambiguous, and wrong-host selectors refuse before workspace writes or runner inspection. Materialization, hook gates, planning, and actions are restricted to the selected owner/task. Unrelated diagnostics remain visible, while sibling workspace content and live PTY PID/creation generation remain unchanged.

Proof

  • Pure selector and reconcile refusal/action matrices.
  • Two-agent KDL + recording-runner missing/live/dead matrix.
  • Owner render-failure and unrelated malformed-sibling diagnostic proofs.
  • CLI proof that refusal/render failure precedes pty list and that only the selected exec is started.
  • Hermetic real-PTY lifecycle proof preserving the sibling PID and createdAt generation across selected launch, adoption, and replacement.
  • Bounded ETXTBSY handling in the nomad replacement fixture so parallel binary-replacement gates are reliable.
  • Refreshed head 138acbc6e93cf91e5d0f320ab639eee5df041399 is a normal two-parent merge of accepted PR head 348f81546ea989c31a2f5ce396add82d53187bc9 and live main 6cec77485213a47893d7c1804d1942a42d4df4bf. The only manual conflict resolution preserves main's macOS-gated std::process::Command import.

Validation on refreshed head

  • Focused: cargo test --test targeted_reconcile --test reconcile --test run --test materialize --test nomad_survival --test exec_backend -- --test-threads=1
  • Full: cargo test --workspace --all-targets -- --test-threads=1
  • Focused and full Clippy with -D warnings
  • cargo doc --workspace --no-deps and cargo test --doc --workspace
  • PR-local rustfmt --edition 2024 --check
  • git diff --check
  • Hosted nix flake check --print-build-logs: run 30541681147 / job 90867702311

No live rollout.

Closes #29

myobie added 30 commits July 29, 2026 09:56
@myobie

myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Live acceptance — R4 dual-final GREEN

Accepted exact head: 348f81546ea989c31a2f5ce396add82d53187bc9.

Fresh isolated release binary:

  • version: st2 0.1.0 — running from local source (348f815, 2 hours ago)
  • SHA-256: 29d1311e8feb821da3c5b98901bdb5ace6157a2f4ba4141f4c4f5f32e027281f

Exact commands, where $R4_ROOT is the fresh evidence directory:

"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/active/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/active/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/retired/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/retired/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
st2 doctor --catalog "$CATALOG" --host hetz --require-supervisor

Exact action receipts:

reconcile pass on host 'hetz':
  launched (1): hetz.st2-pr50-acceptance-r4.selected

reconcile pass on host 'hetz':
  adopted (1): st2-pr50-acceptance-r4

reconcile pass on host 'hetz':
  torn down (1): hetz.st2-pr50-acceptance-r4.selected

reconcile pass on host 'hetz':
  gc (1): hetz.st2-pr50-acceptance-r4.selected

All action commands exited 0 with empty stderr.

Process identity:

  • PID 115615
  • createdAt 2026-07-29T13:37:15.851Z
  • wrapper sh -c exec /usr/bin/sleep 3600
  • kernel start ticks 181454103, CLK_TCK=100
  • direct-floor remaining lifetime: AT1 3583; AT2 pre/post 3459
  • AT3 exited tuple preserved the generation and wrapper with exitCode=129

Isolation and final-state proof:

  • ACTIVE and RETIRED shadow catalogs strict-validated with 2 agents, 0 warnings, 0 errors.
  • AT1 rendered only the selected owner marker; same-owner sibling and unrelated owner/task remained absent.
  • AT2 retained the exact PID, creation generation, wrapper, start ticks, and HZ.
  • AT3 tore down only the selected task.
  • AT4 GC removed only the selected record.
  • AT5 production doctor passed with exit 0 and empty stderr.
  • Final R4 IDs were absent across PTY JSON/files, Hetz exec state, systemd, process command lines, and production catalog paths.
  • Final terminal set was empty.
  • Final PTY/process/exec/scope/catalog/render/lock/service/unit/installed-binary/freeze state was exact T0.
  • Production service remained MainPID=4149392, InvocationID=057336e2e1ec4e84aa903153bb17ef24.
  • Silber.root health-wake remained absent and the frozen declaration/template/render inputs remained unchanged.

Evidence receipts:

  • owner T0 aggregate: 8484e355b58196eadfdcff7dbaa8051eb0f8b66e0e8e1996bb47d3a802cb516f
  • owner 274-file final evidence-manifest SHA-256: b81df194d33c06f2d48c55b83e1ca9bc10fbeb6a92752492e5b082be85980281
  • owner sha256sum -c verification: pass
  • independent root verification: the same 274-file manifest verified; doctor stdout SHA-256 d284028415d747b92fd25c8f11255152217f1ae81bbeff1660260300436377de
  • independent final PTY SHA-256: 8f962cd8fc5d356230b3d5ed37bec7a66059cdcc295090967b8113318b9c7aad
  • independent final service SHA-256: 0ee76c541a1af0b64bdf153ecf230111922d224de040babf6ab4978452dee196
  • independent final freeze SHA-256: 5c8fc463b92d2f3cf8dd8a4fe5261e331157da3b09f79d8a883345d069120240

Owner and independent root dual-final receipts are GREEN. The worktree is clean and GitHub still reports this exact head mergeable/clean with Nix successful.

Nathan delegated final merge authority to the requested reviewer, schickling-codex, if approval, checks, and head remain green. The PR owner will not self-merge.

@myobie
myobie marked this pull request as ready for review July 29, 2026 13:49
@myobie

myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Post-acceptance reviewer request blocker: GitHub returned Could not resolve user with login 'schickling-codex' for the exact delegated reviewer. The PR is ready and the R4 evidence receipt is published. No substitute reviewer was requested, and the owner will not self-merge.

@myobie

myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the reviewer blocker above: the intended reviewer login is schickling-assistant; schickling-codex was a CoS transcription error. GitHub exposes schickling-assistant with write permission on this repository. Nathan delegates final merge authority to that reviewer if approval, checks, and the accepted head remain green. The PR owner will not self-merge.

@myobie
myobie merged commit 58c4851 into main Jul 30, 2026
1 check passed
@schickling schickling added area:catalog Catalog structure, declarations, transactions, and admission · Set: manual area:reconcile Supervisor run loop, lifecycle, restart, park, and teardown · Set: manual type:feature New user-visible or system capability · Set: manual labels Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:catalog Catalog structure, declarations, transactions, and admission · Set: manual area:reconcile Supervisor run loop, lifecycle, restart, park, and teardown · Set: manual type:feature New user-visible or system capability · Set: manual

Projects

None yet

Development

Successfully merging this pull request may close these issues.

targeted materialize/reconcile selector needed for shortest-path agent changes

2 participants