Skip to content

feat(placement): v13 PLACECLI placement process boundary and lifecycle - #1971

Draft
ViperJuice wants to merge 17 commits into
mainfrom
t3/v13-placecli
Draft

ViperJuice wants to merge 17 commits into
mainfrom
t3/v13-placecli

Conversation

@ViperJuice

@ViperJuice ViperJuice commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

v13 PLACECLI: placement process boundary and lifecycle

This implements plans/phase-plan-v13-PLACECLI.md, the re-plan merged in agent-harness#1965. It is built against the landed binding plans/artifacts/v13-PLACECLI-landed-binding.md, and it produces IF-0-PLACECLI-1 and IF-0-PLACECLI-2.

It stays in draft pending independent review, hosted CI, and integration after v12 CLOSEOUT.

What it adds

  • agent-harness-placement --client agent-harness|agent-toolkit reserve|release|reap|version (placement_cli.py; console script in pyproject.toml, with uv.lock unchanged). It reads one JSON request on stdin and writes one response line on stdout, with exit classes 0, 10, 20 and 70. Schema-invalid input exits 70 with stdout absent. --client alone selects the configuration, OU and inventory. No environment variable is read for selection.
  • placement_process_contract.py. It ships the frozen protocol v1 byte for byte as contracts/placement/process-v1.schema.json (SHA-256 130a894d…). The strict codec covers duplicate keys, trailing data, UTF-8, non-finite and unsafe numbers, and the 64 KiB bound, then validates against the schema and builds immutable records.
  • sandbox_placement.PlacementLifecycle. place(..., reserve_only=True) adds a reservation-only exit that stops after admission, before commit, seal or execute. The lifecycle:
    • journals reservations per client;
    • replays erratum-1 R1–R3 (indeterminate, settling and settle-bound cases);
    • arms barriers per (client, reservation) only;
    • runs caller-scoped release and reap;
    • enforces provider allowlists, the generic probe receipt and OD-7;
    • records the effective-egress digest;
    • applies per-host headroom thresholds and caps readiness at reservation time (P-S1). An unreadable caps record refuses reserve, while release, reap, version and --help keep working.
  • config_sha256 covers the whole per-client configuration (binding §4.1), including the launch member, the policy digests and seat_caps_sha256.
  • placement_bridge.ForwardTcpUnixBridge. One 0700 directory and one 0600 socket per remote Pi or leg reservation. A reservation-lifetime helper serves it, launched through seat_uid.trusted_module_argv. It opens no TCP listener and is torn down on release.
  • Smaller extensions:
    • placement_lease: per-client inventories and owner ids;
    • MTLSConfig.client_ou: the certificate OU per client;
    • phase-loop placement reap --client: delegates to the same service;
    • the packaged [placement.local_headroom] defaults equal x-local-headroom-defaults.
  • Docs and records: docs/placement-process-cli.md (including the v2 bare-hex egress spelling, P-S2), a README section, one changelog entry, a .doc-decisions.json entry, and manifest executing and completed events.
  • Inventories: one launch decision for the bridge helper plus 19 classified host-I/O and helper reference rows.

Live routes stay disabled: no production OpenShell backend is registered, _NONLOCAL_EXECUTION_DRIVER stays false, policies.json stays pending_qualification, and E2B is off.

Verification

All runs were on ai: a private scratch worktree, uv sync --locked, an -I pre-check, the project admission lock, PSI gates, serial runs and timeout 900. Results at 1e54b95 (receipt validator at 58b5d5f):

Group Result
V0 124 passed
V1 807 passed, 14 skipped (pre-existing optional grpc)
V2 114 passed, 6 skipped (pre-existing opt-in)
V3 93 passed
V4 (installed wheel, standalone tests) 213 passed, 17 skipped (repo-only tests, by design)
Manifest and console-script tests 75 passed, 1 skipped
Receipt validator 13 passed

The mutation controls pair an intact witness with a killed run for every named guard. The receipt plans/evidence/placement/PLACECLI.md pins only phase-exclusive files (agent-harness#1955).

Hosted CI remains unverified. Recent runs show workflow startup failures and failed aggregate jobs; the cause has not been established. Earlier executed checks found an entry-doc path issue and an unused test import; both are fixed and passed their local checks.

The release wheel console metadata now includes agent-harness-placement, with matching wheel fixtures. The focused release-console regression passed, as did four source-only parser controls (declared set accepted; missing, altered and extra entries refused), lint and diff checks. Three wheel-binding tests could not reach assertions because their local fixture setup failed with a permission error. These controls are not installed-wheel or attended-canary qualification.

Consumers and rollback

LANEEXEC consumes PlacementLifecycle, ForwardTcpUnixBridge.open/close and config_sha256 (binding §4). Existing place() callers are unchanged, because the new keywords default to the old behaviour. To roll back, revert this PR; no state outside the new per-client inventories is written.

Implementation update: durable admission, operation deadlines and the bridge relay (head 46ca5f1)

This update leaves the frozen signatures, schema, plan and scope unchanged, and keeps the console-metadata commit d83f9c7.

  • Durable admission.
    • Each admission is committed in steps, each durable in the attempt journal before the next: the exact reservation with expiry fixed at admission, plus its complete cleanup effect; then the bridge handle; then publication of the active record; then settlement.
    • After an interruption, a replay settles admitted only from a complete commit, returning the original reservation, expiry and bridge. It makes no target, exposure or bridge call and never recomputes expiry.
    • At the settle bound, the complete effect passes to a single cleanup entry, and any published record of the same reservation is retired.
    • A bridge whose handle was never journaled is reclaimed through the reservation's directory.
  • Start-up. Each unsettled attempt is read again under its lock, so a record that another process settled is never overwritten.
  • Deadlines. reserve, release and reap each run under one deadline taken from deadline_ms. It bounds the walk, the exposure lookup, bridge readiness and teardown, the reservation lock, and the kill and owner listing.
    • When time runs out, or the caller cancels, after admission, no admission is reported; the effects stay journaled and the response is timeout.
    • A release that outlasts its deadline answers cleanup_pending.
  • Bridge relay. The relay is non-blocking, with bounded per-direction buffers, so a peer that stops reading stalls only its own direction. The helper stops promptly on request and at expiry.
  • Configuration. A present launch member must be an object; "launch": null refuses at load.
  • Docs. docs/placement-process-cli.md describes the recovery, deadline and relay behaviour.

Validation at the repaired head. All runs were on ai: a private scratch worktree, uv sync --locked with uv.lock unchanged, an -I pre-check, the project lock held for the run, PSI gates, serial runs and timeout 900.

Group Result
V0 124 passed
V1 823 passed, 14 skipped (pre-existing optional)
V2 119 passed, 6 skipped (pre-existing opt-in)
V3 93 passed
V4 (installed wheel) 213 passed, 17 skipped (repo-only, by design)
Manifest and console-script tests 75 passed, 1 skipped
Receipt validator (restamped receipt) 13 passed

New regression cases cover:

  • admission interrupted at each journal step, restarted before and at the bound;
  • start-up racing a concurrent settlement;
  • slow exposure, slow readiness and teardown, a contended release lock, and cancellation after admission;
  • a stalled relay peer, its expiry and a graceful stop.

Not verified here.

  • Hosted CI for this head.
  • Three test_agy_canary_evidence.py installed-wheel fixture tests fail on this branch with "installed RECORD is missing governed files". They pass before d83f9c7, because the installed-wheel fixture writes launchers for the previous five console scripts only. That fixture is outside this phase's files.
  • Two tree-snapshot boundary tests in the same file fail on ai at main as well. They depend on the host.

Implementation update: cleanup hand-over and operation deadlines (head 4877182)

Frozen signatures, schema, policy and scope are unchanged, and the installed-launcher fixture commit 19451e5 is kept.

  • Cleanup hand-over. It is durable and restartable:
    • The hand-over is journaled in the attempt, under stable keys, before any cleanup entry is written.
    • Any later start-up resumes it, including after the terminal response has been journaled.
    • Every consumer of a reservation's effect holds that reservation's lock: the active record, the cleanup entry, replay and the hand-over itself.
    • A consumed cleanup entry is kept as a completion record until the attempt journals the completion.
    • Replay re-checks for tombstones and hand-overs inside the lock before it publishes.
  • Deadlines and cancellation. These now also cover start-up, the hand-over, committed recovery and local-slot locking.
    • A lock is never waited on in the kernel when a deadline applies.
    • Start-up only tries other attempts' locks, so it never blocks an unrelated operation.
    • Replay re-checks the remaining time, cancellation and the settle bound before it publishes.
    • Every helper stop wait is capped by the remaining time, and a helper that is not confirmed stopped stays owned for a later collection.
  • Docs. docs/placement-process-cli.md now says that replay may perform one bounded read-only reconciliation and never creates a target, lease or bridge or recomputes an expiry. It also describes the hand-over.

Validation at 4877182. Producers ran at ec0e05f, where the code is final; only the receipt changed after it. All runs were on ai: a private scratch worktree, uv sync --locked, the -I pre-check, the project lock, PSI gates, serial runs and timeout 900.

Group Result
V0 124 passed
V1 838 passed, 14 skipped (pre-existing optional)
V2 120 passed, 6 skipped (pre-existing opt-in)
V3 93 passed
V4 (installed wheel) 213 passed, 17 skipped (repo-only, by design)
Manifest and console-script tests 75 passed, 1 skipped
The three installed-wheel canary tests 3 passed
Receipt validator (restamped receipt, at 4877182) 13 passed

New regression cases cover:

  • interruption after each hand-over step, with an interleaved reap and two restarts;
  • a reap racing a replay for the reservation's lock;
  • held locks during each public operation;
  • replay running out of time, being cancelled or reaching its settle bound;
  • capped helper stop waits;
  • a contended local-slot lock.

Not verified here. Hosted CI for this head.

🤖 Generated with Claude Code

ViperJuice and others added 17 commits November 9, 2026 12:40
…v13 PLACECLI)

Package the frozen placement process protocol v1 schema and add its strict
codec, the per-client PlacementLifecycle with a reservation-only walk exit,
the reservation-scoped ForwardTcp-to-Unix bridge and the
agent-harness-placement console entry. Tests, inventories and docs follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts (v13 PLACECLI)

Add the SL-0..SL-3 lane tests, the language-neutral placement-cli
black-box corpus with its fake coordinator, and the inventory decisions
for the new bridge helper launch and file reads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd refusal codes (v13 PLACECLI)

Pass the protocol's own placement codes through the reservation walk's
pre-probe refusals, document agent-harness-placement, add the receipt
validator and record the phase's executing lifecycle event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ut touching the inventory

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… ai run (v13 PLACECLI)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h (v13 PLACECLI)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s and a non-blocking bridge relay (v13 PLACECLI)

Commit each admission recoverably in the attempt journal before publishing
it, recover only from a complete commit without allocating anything or
recomputing expiry, and hand an interrupted admission's complete effect to a
single cleanup owner at the settle bound. Re-read attempts under their lock at
start-up. Bound every blocking step of reserve, release and reap by one
operation deadline. Relay bridge bytes without blocking, with bounded
per-direction buffers, and reclaim a helper by its directory. Refuse an
explicit null launch member.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ead ai run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…operation deadlines (v13 PLACECLI)

Journal each cleanup hand-over under stable keys before materializing it,
serialize every consumer of a reservation's effect on that reservation's
lock, keep consumed cleanup owners as completion records until the attempt
journals completion, and recheck tombstones and transfers inside the lock
before replay publishes. Carry the operation deadline and cancellation through
start-up, hand-over, recovery and slot locking, never wait on a kernel lock
when a deadline applies, and cap every helper stop wait by the remaining time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ections ai run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y budget check

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

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant