carlos / platform Public

spec: host lifecycle claim rev 6.19, PROPOSED §6.6 box-side contracts

Stop-evidence collection and transport, deployment identity and complete
local retirement, held inputs and the sweep's live view, clean-close
certificates (not certificate-capable on Litestream v0.5.14: cold-only
until fixed), regional retirement authority, cross-process denial, strict
containment for every launch route, durable retry state (Plan 6's P6-D1..8).
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 8b8c9efb32742005a9e31868f22ad18b34a47a82 parent 2e195a8
1 file changed, +360 −2
  • docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md +360 −2

CI cancelled — superseded by a newer push — run details

diff --git a/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md b/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
index 0257b78bb..f41d922c7 100644
--- a/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
+++ b/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
@@ -1,6 +1,6 @@
# The host lifecycle claim
-Design, 2026-10-06, **rev 6.18**. Joint rounds 6 and 7 judged the claim ready for primitive planning. Rev
+Design, 2026-10-06, **rev 6.19**. Joint rounds 6 and 7 judged the claim ready for primitive planning. Rev
6.5 added the R6-4 rule. Rev 6.6 added writer epochs (R7-1, amadan #225).
Rev 6.7 answered the moves session's notes on §6.4a. Rev 6.8 rewrote §6.4a
around writer sessions, for joint round 8. Rev 6.10 answers joint round 10
@@ -13,7 +13,8 @@ persisted park scope and the holderless sweep (§2, §6.2a), found while
planning the park engine. Rev 6.16 states what a box reference is
(amadan #212). Rev 6.17 adds the PROPOSED contracts §7.3 and §10.1
(Plan 8's D1 to D7), awaiting Paul's rulings P1 to P3 and joint review. Rev 6.18 adds the
-PROPOSED §5.9 (Plan 5's P5-D1 to P5-D6). Rev 6.9 answered
+PROPOSED §5.9 (Plan 5's P5-D1 to P5-D6). Rev 6.19 adds the PROPOSED §6.6
+(Plan 6's P6-D1 to P6-D8). Rev 6.9 answered
joint round 9
(R9-1 to R9-4) and takes **Paul's ruling R6 (2026-10-04): a box never
reuses its local database. Every writer start restores from the
@@ -1797,6 +1798,363 @@ key. The console needs `s3:GetObjectVersion`.
Delete step 1 also stops accepting new door requests for the host, on
every console. But safety does not depend on draining them.
+### 6.6 Box-side contracts (rev 6.19, PROPOSED)
+
+**Status: proposed, not yet ruled.** These close the gaps Plan 6's draft found (P6-D1 to P6-D8). They reference the proposed §5.9, §7.3 and §10.1 as dependencies, not as approved text. Paul's decisions are listed in amadan #236. Not yet read against amadan #234's discussion text (the certificate analysis rests on the pinned Litestream v0.5.14 source).
+
+#### P6-D1. Privileged stop collection and durable evidence
+
+*Insert after §6.1. Extend §5.9 P5-D3’s receipt rather than introducing another transport.*
+
+The root collector runs inside the existing `carlos instance-control` service. Add authenticated fence and evidence requests to its existing Unix socket. Retain the existing peer requirement: UID `carlos`, with the peer PID equal to `carlos-edge.service`’s current MainPID. Bind each exchange additionally to the process start identity, boot ID and controller ID. Root startup recovery invokes the same collector locally.
+
+A request names:
+
+```text
+host, incarnation, installation_stamp, writer_session
+operation_id, phase, obligation_id
+box, enrollment, boot_id, controller_id
+expected_claim_etag, expected_directory_revision
+```
+
+The collector derives artifact paths, unit names and cgroups from validated inventory and configured roots. Requests cannot supply arbitrary paths, PIDs or unit names.
+
+Under hostguard, the collector validates ordinary operation authority or the cleanup authority defined in P6-D6. It durably records a fresh `fence_id` and the exact target tuple in the existing local guard state. Every app-code admission, root launch and host-work reservation checks this fence. The fence denies new work for the evidenced session without retiring its installation stamp.
+
+The collector then releases hostguard. The agent closes its matching in-memory admission fence, cancels and joins selected work, drains timer deliveries and spawn attempts, stops all application roles, and closes or terminates every replication and maintenance producer. It returns a drain acknowledgement bound to the collector’s fence and controller tuple. `FenceAndStop`’s process-local object is not serialized as evidence.
+
+Root independently verifies:
+
+- The durable fence still matches.
+- Every recorded spawn reservation is settled.
+- The complete host containment tree is empty, including auxiliary roles.
+- No registered producer remains able to issue requests for the session.
+- A complete privileged `/proc/*/fd` scan finds no database, WAL or SHM holders, including renamed or deleted files identified by recorded file identity.
+
+The authenticated drain acknowledgement supplies the trusted agent’s producer-join result. It does not substitute for root’s kernel observations. If that agent died, recovery must prove termination of its exact process identity and independently reconstruct the remaining observations. A changed MainPID, missing cgroup, inaccessible `/proc`, incomplete inventory or unresolved producer yields no receipt.
+
+Root reacquires hostguard, revalidates the fence and target, and durably records the completed observation. Extend P5-D3’s receipt with `controller_id`, phase, producer-drain digest, and the observed cgroup identities and unit invocation IDs. Its `evidence_at` is the original completion time of these checks.
+
+Publish the exact durable bytes through P5-D3’s immutable evidence path. An acknowledgement names the receipt key and digest. Failed publication retries the same receipt; it does not collect a newer timestamp merely to retry transport.
+
+Evidence has no independent expiry while its exact fence remains effective. It proves only the named installation/session and retirement scope. Reopening requires an explicit authorized transition or new writer admission; it never makes the receipt evidence for the replacement session. A reboot retains the deny and reconstructs local completion before publishing new-boot evidence.
+
+Stop evidence proves that no producer can issue further work. It does not assert that previously accepted remote requests succeeded or finished. Their uncertain outcomes remain subject to §6.2a. Clean-close certification requires P6-D4’s stronger proof.
+
+Rejected alternatives:
+
+- Agent-supplied `stopped:true`: it proves neither privileged descriptor scanning nor a durable fence.
+- A root command accepting only a hostname: it cannot identify the controller, installation or session being fenced.
+- Recreating receipts on every retry: it loses the original evidence time and permits scope confusion.
+
+#### P6-D2. Deployment identity and complete local retirement
+
+*Extend §2, §6.3 and §9. Reuse §5.9 P5-D2 and §10.1 D7.*
+
+Use `control/host-actors.json` as the sole enrollment and placement authority. The box’s effective placement region, pools, namespace and regional bucket must agree with its enrollment and the existing provisioning predicates. A disagreement with local configuration refuses claim work. A region code, fleet label or heartbeat never identifies an executor by itself.
+
+Legacy adoption uses P5-D2’s complete census and exactly one proven installation owner. Preserve its refusals for multi-serving records, nonempty `Record.Replicas`, unexplained foreign routes and route-only installations without a representable holder. This proposal does not decide #232’s backfill-versus-lazy-adoption question.
+
+Extend the existing per-box inventory with typed entries for:
+
+```text
+incarnation, installation_stamp, artifact_id
+kind: path | live-link | unit-state | route | timer
+managed_root, relative_path or row identity
+ownership identity and materialization state
+```
+
+The inventory covers DataDir artifacts, OptDir live links, host-specific root unit/drop-in/env files, launch state, registry rows and timer registrations. Shared release directories, shared unit templates and the whole registry database are not host-owned artifacts.
+
+Record intended ownership before materialization. Record resulting file identity or row identity durably after it. Recovery reconciles interrupted materialization under hostguard before allowing another installation to reuse the path. Existing metadata cannot be silently assigned to the newest stamp.
+
+Extend Plan 4’s existing retirement journal to coordinate these typed entries:
+
+1. Persist the target incarnation/stamp, inventory snapshot, stop receipt and intended actions.
+2. For `retire-installation`, retire only that target’s active stamp. `retire-artifacts(S)` continues to change no active or retired stamp.
+3. Park filesystem artifacts with descriptor-relative, no-replace renames. A managed live-link entry moves the symlink itself without following its target.
+4. Archive matching route and timer contents in the journal, then remove them in a registry transaction conditional on their recorded ownership and registration identities.
+5. Verify remaining artifacts and rows, fsync the journal and affected directories, then persist completion.
+6. Publish evidence and acknowledge the exact obligation outside hostguard.
+
+For managed roots on another filesystem, provision a retirement directory on that same filesystem using the same incarnation/host/retirement layout. Record its root identity in the existing journal. This explicitly extends §6.3’s DataDir-only destination rule. It does not permit copy-and-unlink fallback: `EXDEV`, unsafe traversal or conflicting ownership leaves retirement pending.
+
+A crash resumes the journal. A successor at the same path or row key is never retired as the predecessor. If the predecessor’s disposition cannot be established from the journal and recorded identities, completion remains unknown.
+
+Completed inventory snapshots remain in the retirement journal. Retired-stamp fencing records remain operational metadata; retirement must not remove the records that prevent stale work from returning.
+
+Local-record loss triggers reconstruction from the claim, complete local census and retirement journals. Claim-based initialization does not establish that existing artifacts belong to the current installation. Ambiguous ownership blocks initialization and materialization.
+
+An untouched box may acknowledge only with P5-D3’s complete `empty` receipt. Missing inventory is never equivalent to an explicitly proven empty inventory.
+
+Rejected alternatives:
+
+- Choosing the first box in the region: placement does not prove legacy ownership.
+- Parking the shared registry database: it retires unrelated hosts.
+- Deleting by pathname or hostname alone: it can remove a successor.
+- Treating a lost local record as a fresh installation: it discards ownership evidence.
+
+#### P6-D3. Held inputs, publication and the sweep’s live view
+
+*Extend §6.1, §6.2a and §6.4a. The corresponding provider contract belongs in moves §5.1, §7.6–§7.8 and §9.1–§9.2.*
+
+Moves supplies one typed provider for held inputs, prepared-generation authority, publication and live-object selection. Plan 6 consumes that provider; it does not interpret arbitrary journal strings or introduce another held-input format.
+
+Each result is bound to the observed claim ETag, holder incarnation, installation stamp, writer session, operation ID, phase, executor and relevant region.
+
+The config identity covers the exact default, environment and instance-overlay inputs, including explicit absence, plus the rendered file digest. The release identity covers the exact authenticated release and executable artifact digest.
+
+For forward probes, these identities must match `move.inputs`. For source recovery probes, render current inputs, persist them as `recovery.inputs`, and use those recorded identities as moves §7.7 requires. Recovery must not remain bound to obsolete forward inputs.
+
+`RenderHeld` writes a move-bound acknowledgement even when the rendered bytes are unchanged. `MaterializeHeld` stages and selects the exact authorized release. Both use the captured hostguard selection. Immediately before app execution, validate the actual executable and composed launch environment against the same identities. Ordinary config and adoption passes continue to skip held rows.
+
+Prepared restore authority includes the owning operation/phase, completed install manifest identity, pinned snapshot and anchor versions, required TXID, and the claim evidence that the generation has not previously been opened. Only the admitting CAS consumes that opening. A restarted probe receives a fresh cold generation. A path or `build-intent.json` alone grants no prepared restore authority.
+
+Restoration follows moves §5.1, including verified file trailers, contiguous replay with its overlap rule, required final position and SQLite integrity verification. Plan 7b selection alone proves none of those checks.
+
+Position zero follows the existing empty-bootstrap contract: no `[1,0]` snapshot or `[0,0]` anchor. Nonempty prepared generations require acknowledged snapshot and anchor writes and a completed install manifest before opening. Ordinary cold generations follow the existing first-upload publication sequence.
+
+The publisher writes `generation.json` using the ETag of the marker being replaced, or create-only when genuinely absent. It validates the completed publication inputs and current admission authority before issuing the write. It returns a publication receipt identifying the acknowledged marker bytes and version.
+
+After an ambiguous response, a fresh exact read may establish that those same bytes were published. A conflicting or superseding marker never permits an unconditional retry. Only verified publication permits `PublishGeneration` for the observed operation, phase, session, generation and region.
+
+The sweep view binds to the same fresh claim observation and moves’ authoritative-region table. It includes the installed generation, required pinned versions, protected marker versions and the entire unfinished predecessor run. An absent marker means origin only where the existing origin/unfinished-run rules explain it.
+
+Its generation classifier must classify every discovered or journalled source key, including exact versions already deleted during a retry. Classification uses validated namespace structure and durable manifest identity; it must not depend on successfully reopening a deleted source version. Unknown classifications refuse the affected retirement step.
+
+A changed claim observation invalidates the view. Rebuild and reauthorize before continuing. An unexplained marker disagreement suppresses mutation of the affected location and raises an alert.
+
+Rejected alternatives:
+
+- Treating `Select` success as restore verification or publication: it proves neither.
+- Rendering whatever the ordinary passes last delivered: held rows are deliberately skipped.
+- Binding recovery to `move.inputs`: it can make recovery impossible after a config change.
+- Classifying a missing version as disposable: absence does not establish its generation.
+
+#### P6-D4. Clean-close proof and Litestream v0.5.14
+
+*Replace the implementation qualification under §6.4a’s clean-close certificate. Apply the same qualification to moves §5.1.*
+
+The current platform replication path using pinned Litestream v0.5.14 is **not certificate-capable**.
+
+`Replicator.Close` discards its first `SyncAndWait` error. More fundamentally, `Store.Close` closes databases before cancelling and joining store maintenance workers. Snapshot production can continue accessing `db.f` while `DB.Close` clears or closes it. Snapshot encoding also uses an asynchronous producer whose completion must be accounted for. A nil close result, a separate successful sync, or an empty count of network requests does not prove all producers have finished.
+
+For the current integration, certificate issuance and warm admission remain disabled until a reviewed Litestream fix or upgrade establishes the required producer shutdown ordering. Request accounting alone is insufficient. Disabling a monitor interval or observing an idle instant is not an equivalent fix.
+
+A future certificate-capable implementation must establish all of the following:
+
+1. Close app admission and stop every application role, with P6-D1 evidence.
+2. Prevent new maintenance jobs and join already-running compaction, snapshot, retention and encoding work.
+3. Complete the final database and replica sync without discarding errors.
+4. Stop and join every remaining producer before closing the resources it can access.
+5. Prove successful completion of every mutating request attempt issued by the session.
+6. Verify the generation’s restorable remote maximum equals the final synchronized position.
+7. Publish the certificate while continuously retaining the replica lease and the applicable claim authority.
+8. Only then stop renewal and conditionally release the owned lease.
+
+The request ledger begins before the session’s first storage mutation. It includes initial uploads, anchors, snapshots, compactions, retention, multipart operations and SDK retries. A timeout, refusal, lost response, unresolved original request or unsuccessful per-object batch result permanently disqualifies that session. A successful retry does not repair its earlier uncertainty. A restarted agent cannot reconstruct eligibility for its predecessor’s session.
+
+Keep the existing create-only certificate key and fields. Add:
+
+```text
+v, host, incarnation, location, generation, installation_stamp
+enrollment, boot_id, controller_id
+stop_receipt: key, sha256
+request_ledger_sha256
+verification: remote_max_txid, verified_restore_txid
+producer_release_identity
+```
+
+The two verified positions must equal `max_txid`. Certificate eligibility requires a session that actually opened replication. An existing certificate with conflicting bytes is an error.
+
+Before warm admission, hold the replica lease and validate the certificate for the observed holder session, its recognized producer capability and the freshly verified remote maximum. Reestablish these checks after a conflicting admission CAS.
+
+Certificate publication itself occurs after the request ledger is sealed. An unacknowledged certificate PUT grants the closing caller no warm-continuation result. If its already-valid bytes arrive later, a subsequent admission may validate that immutable certificate through the normal rules.
+
+**Meanwhile, every admission is cold.** Purge local database artifacts with error reporting, restore the validated remote baseline selected under §6.4a, and admit a fresh generation subject to the existing prepared-generation and stamp rules. Never reuse a local database or silently continue the predecessor generation.
+
+Cold admission still requires complete baseline selection, stop or handover authority and all other admission checks. It records `writes_lost` where the existing coverage rules require it. It cannot turn missing remote data into an empty bootstrap.
+
+An uncertain close can still support ordinary stop evidence once producer termination is independently proved. It cannot support a clean-close certificate; remote uncertainty remains covered by retirement horizons and disjoint generations.
+
+Rejected alternatives:
+
+- Returning the discarded sync error alone: it leaves the close race and unreported maintenance outcomes.
+- Issuing a certificate after a successful standalone sync: later maintenance may still be running.
+- Using lease expiry as closure: it proves neither producer termination nor completed requests.
+- Waiting for the retirement horizon to manufacture a certificate: elapsed time is not client-observed success.
+
+**PAUL:** Allow the first completed deployment to operate with cold-only admissions, or wait for certificate-capable replication. Recommended default: allow cold-only operation after the other activation gates pass, accepting restoration and new-generation costs at every admission.
+
+#### P6-D5. Regional retirement authority and aggregate leases
+
+*Extend §6.2 and §6.2a using §5.9 P5-D3.*
+
+The obligation remains the work queue. Any currently eligible enrolled worker with access to the exact regional bucket may execute `region:<r>` work. There is no separate regional leader roster.
+
+Before binding a scope or issuing storage mutations, the adapter must:
+
+1. Validate its enrollment, effective region, bucket and retirement authority.
+2. Resolve immutable evidence references covering every producer that could write the scope.
+3. Acquire all required replica-location and staging-work leases in a deterministic order.
+4. Re-read the claim and validate the exact obligation, original operation, phase and immutable scope.
+5. Obtain P6-D3’s view under that observation.
+
+The aggregate lease handle renews every constituent lease and reports loss if any constituent becomes unsafe. Partial acquisition unwinds only leases acquired by that worker. Loss cancels further work and prevents acknowledgement. Every request rechecks authority and lease health; staging additionally retains C3’s signature-at-check and no-resigning rules.
+
+Use P5-D3’s enforced 120-second total request limit. Therefore the specified client horizon is 17 minutes after the latest original evidence time. Verification must occur strictly later. This does not claim a server completion bound; C3a and subsequent sweeps still cover later residue.
+
+Host discovery is a complete paginated census of both regional namespaces, `instances/` and `moves/`, followed by exact claim reads. It is independent of current records, route lists and the 32 retained incarnations. A namespace with no claim requires the selected legacy/backfill disposition; it is not automatically a free host.
+
+Evidence for particular cases is:
+
+- **Failed admission:** the closed admission attempt and joined builder/replicator, or positive durable evidence that no producer was opened. An empty object listing alone is insufficient.
+- **Superseded generation while serving:** evidence for its former writer and builders, plus the existing publication/coverage authority. The successor’s running process need not be stopped.
+- **Free-host residue:** retained retirement evidence covering the old producers, or fresh complete discovery evidence. A free claim alone proves no stop.
+- **Lost box:** the accepted loss record’s persisted `fenced_at`, following §7.3 D5.
+
+The worker retains the original evidence, scope and retirement ID across retries. Later residue gets the further retirement event required by §6.2a. Claim or enrollment changes require reauthorization; they never silently rebind the old scope.
+
+Completion uses the chore’s original operation identity and updates `quiet_after` in the same CAS. A holderless sweep’s last acknowledgement performs the existing return-to-free transition. Missing evidence, leases, view or request-bound enforcement leaves the chore pending.
+
+Rejected alternatives:
+
+- Holding only the replica lock: staging can still write into the retirement scope.
+- Replacing evidence time with `time.Now()`: it invents evidence.
+- Treating publication as proof that every old writer stopped: publication establishes coverage, not termination.
+
+#### P6-D6. Cross-process denial and returning-box cleanup
+
+*Extend §6.4; reference §7.3 D3/D6 and §10.1 D1/D7.*
+
+Plan 8’s lifetime lock, `.hostexec` record, boot-clock deadline, loss latch and first-phase acknowledgement are the only execution-lease mechanism. Plan 6 supplies no alternate lease or watchdog authority.
+
+Every root and background mutation validates, under hostguard:
+
+```text
+captured incarnation and installation stamp
+current operation, phase, role and executor permission
+held identities needed by the action
+verified actor enrollment and quarantine state
+durable admission fences
+Plan 8 local controller state and deadline, when an operation is active
+```
+
+Reading local execution state must not block on the lifetime lock or perform renewal. A missing, malformed, pending, lost, foreign-boot or expired record refuses active-operation work. Recheck the deadline immediately before the effect after any intervening wait.
+
+Renewal and phase-acknowledgement network waits occur outside hostguard. Their results may update local authority only through §7.3 D6’s captured-controller checks.
+
+Startup remains closed until identity, floor and quarantine checks complete. This precedes observer reattachment, timers, config work, root restarts and replication. A new agent stops inherited application processes and admits a new session; it does not adopt their old session.
+
+Provide a cleanup-only entry under the same hostguard lock. Its authority is a durable local loss/fence record, a valid retirement journal, or the persisted signed quarantine instruction for the exact enrollment. It may deny work, terminate recorded processes, join producers and retire precisely identified old artifacts. It grants no spawn, config materialization, replication opening, new remote mutation or authority over a successor.
+
+During a control outage, termination and an already-authorized local retirement may continue from that durable evidence. Unknown ownership refuses artifact movement. Remote publication and claim acknowledgements wait for fresh remote authority.
+
+This entry must work when the claim is free or names a successor. It retires the captured old installation only. It clears `active_stamp` only if that field still identifies the target; it preserves a successor’s active stamp and inventory.
+
+Quarantine completion and readmission use §7.3 D3’s existing scan, receipt and console ordering. A fresh serving claim can clear stale execution-lease state under D6, but cannot clear quarantine, another fence or unfinished cleanup.
+
+Ordinary serving retains its no-execution-lease rule. Control-read failure alone does not stop an already-running ordinary serving process, but it refuses new guarded work.
+
+Rejected alternatives:
+
+- Watchdog callbacks as the sole enforcement: separate root processes can outlive or bypass them.
+- Taking the lifetime lock under hostguard: it can block the very state updates needed for denial.
+- Requiring the old holder for cleanup: it prevents returning-box retirement after successor ownership.
+
+#### P6-D7. Strict containment for every launch route
+
+*Extend §6.1 and the corresponding moves stop-evidence contract.*
+
+Each admitted host has one recorded containment tree bound to its enrollment, incarnation, installation stamp, session and controller. Record the kernel identities of its root and children, not merely their pathnames.
+
+Use separate empty child groups for the main process, seed process and each auxiliary role. Apply the host’s aggregate limits at their common parent. Tenant credentials cannot create groups, migrate processes or write containment controls.
+
+`PrepareStrict` retains its empty-group requirement and one-start semantics. An auxiliary process joining a running host receives a newly prepared empty child group through an explicit role-child preparation API using the same strict checks. It does not reuse the populated main-process group or weaken `PrepareStrict`.
+
+Under hostguard, each launch reserves a unique launch ID containing the captured authority tuple, role, expected executable identity and child-group identity. The reservation is durable before handing execution to another process. Closing admission prevents new reservations and waits for every existing reservation to settle.
+
+Extend the existing instance-control start and seed protocol to carry that launch identity. The root service validates it; the final guarded launcher revalidates it immediately before executing app code. App execution begins inside the prepared cgroup. A successful `systemctl start` response is not sufficient containment evidence.
+
+The same protocol applies to `startUnit`, `seedUnit`, `startSidecarUnit`, whole-app unit starts, separate root restarts and automatic restarts. Unit configuration must prevent unmediated app execution. Automatic restarts require a current controller, admitted session and retry reservation.
+
+A changed systemd invocation is not host stop evidence. The collector must establish emptiness of the complete recorded containment tree and complete P6-D1’s remaining checks.
+
+A requested co-spawned sidecar is part of the wake’s success condition. If either launch fails or its outcome is uncertain, fence and clean up every role started by that wake. Do not report success with the sidecar omitted.
+
+Standalone sidecar records retain their own host claim and containment identity. They are not auxiliary members of an unrelated host.
+
+Existing best-effort or externally supervised shapes remain unsupported until cleanup and containment can be proved for them. Refuse the whole enabled launch before app execution. Platforms without the required strict facilities return unsupported.
+
+Rejected alternatives:
+
+- Calling `Manager.Start` under a guard: admission checking does not make placement strict.
+- Reusing a populated group through `PrepareStrict`: it breaks that API’s proof.
+- Trusting a unit’s inactive state or changed invocation alone: descendants or replacement work may remain.
+
+#### P6-D8. Durable retry state and operation-bound holds
+
+*Extend §6.4a and §8. Reuse moves §5.2’s `hold_op` contract.*
+
+Persist serving retry authority in an additive `holder.wake_retry` value:
+
+```text
+episode_id
+attempts_reserved
+state: open | attempting | failed
+not_before
+attempt: id, box, enrollment, boot_id, controller_id, session
+```
+
+The episode belongs to the holder incarnation. It survives agent restart, writer-session replacement and installation-stamp changes. Local state may mirror it but cannot reset it.
+
+Before a counted start, satisfy read-only prerequisites, then reserve the attempt by claim CAS. A first attempt requiring writer admission binds its resulting session before any app code starts. A process restart under the same live replicator reserves another attempt without admitting another session.
+
+Use the specified five-attempt limit and delays `1,2,4,8,16` seconds. Missing prerequisites wait without reserving an attempt or creating a session. Once an attempt is reserved, a crash or ambiguous outcome does not refund it. Recovery must settle or stop that attempt before starting another.
+
+After the fifth unsuccessful attempt, persist `failed`. Every automatic wake and new writer admission for ordinary serving checks this state. A new agent, new stamp, new release or repeated request cannot reset the budget.
+
+A successful health result clears the episode only when it identifies the exact admitted attempt, live process invocation, session and launch inputs, and passes that backend’s configured readiness checks. Cached edge responses, box heartbeats, timer delivery success and route status strings are not qualifying signals. No process may be spawned merely to manufacture a clearing signal.
+
+An operator may explicitly reset the episode through the existing operator-authorized host-resolution API/CLI surface. The reset is conditional on the holder incarnation and observed episode. It settles or fences any outstanding attempt first, records the operator request, and grants retry eligibility only. It clears no hold, quarantine, execution-loss latch or retired stamp.
+
+A probe uses the moves operation’s own attempt journal. One probe attempt is one cold admission, with bounded restarts of that session and one absolute 30-second readiness window. Backoff cannot extend the window. A changed agent requires termination of the old attempt and a new operation-budgeted cold attempt. Probe failure never sets the serving failed-host latch.
+
+Add moves §5.2’s `hold_op` column, with empty default. Carry route incarnation/stamp ownership as required by P6-D2. Writing or clearing a hold is a guarded registry transaction conditional on that ownership and the expected operation.
+
+For normal release, the owning moves transition supplies release authority. For stale-hold recovery, require a fresh serving claim naming this box as executor and a matching local installation. Clear only the observed stale `hold_op`; never clear whatever operation happens to be present at execution time.
+
+Clearing a stale hold must preserve a failed-host denial. A `ready` projection does not override `wake_retry`, quarantine or admission authority.
+
+Timer delivery and ordinary timer convergence refuse held rows without advancing bookkeeping. Moves retains its exact timer replacement and snapshot rules. Every timer mutation, including pruning and post-delivery bookkeeping, uses the original captured selection and matching registration identity.
+
+Rejected alternatives:
+
+- Keeping failure counts only in activator memory: restarting the agent grants unlimited attempts.
+- Using a route status as the operation identity: it cannot distinguish old and current holds.
+- Clearing failure on a heartbeat or cached response: neither proves this admitted process is healthy.
+- Re-admitting a session for each restart under a live replicator: it violates the session boundary.
+
+---
+
+**FIRST PROMPT:**
+“Read /home/paulca/.cache/tmp/claude-1001/own/spec-p6-brief.md and do exactly what it says.”
+
+**WHAT:**
+Propose contracts closing Plan 6’s eight box-side gaps.
+
+**STATUS:**
+Complete draft above. Source inspected; #234 unavailable; no Opus review obtained. No files written.
+
+**NEEDED:**
+Decide whether initial activation may use cold-only admissions.
+
+**RECOMMENDED:**
+Read #234 and obtain joint authority review before incorporating or implementing these proposals.
+
+**SESSION:**
+Safe to close this read-only task. A concurrent Plan 6 file change was observed and left untouched.
+
## 7. Lost boxes and execution fencing (J-D6, J-N3)
A claim CAS is bookkeeping, not fencing. A box can be partitioned from