carlos / platform Public

Bind resident resume contracts and refuse granted socket ports

Paul Campbell pushed by paul@keymail.dev c6281d5f802db409befa7376dcff2d35bcfb9efc parent 09b92e8
1 file changed, +9 −8
  • implementation/always-awake-exec.md +9 −8

CI passed — run details

diff --git a/implementation/always-awake-exec.md b/implementation/always-awake-exec.md
index 44155daa5..140339482 100644
--- a/implementation/always-awake-exec.md
+++ b/implementation/always-awake-exec.md
@@ -1,6 +1,6 @@
# Always-awake exec lifecycle for Home
-Status: design proposal for LLM implementation and independent review. No code or new authority is approved by this document. Revision 2 addresses Fable’s seven requested changes to 80f6169. Independent rereview remains required before implementation; deployment additionally requires the explicit gates below. User copy review is waived. Platform task 32/discussion 117 and Home discussion 44 track this amendment.
+Status: design proposal for LLM implementation and independent review. No code or new authority is approved by this document. Revision 3 addresses Fable’s seven original requested changes and the two integration findings on 09b92e8. Independent rereview remains required before implementation; deployment additionally requires the explicit gates below. User copy review is waived. Platform task 32/discussion 117 and Home discussion 44 track this amendment.
Base: platform `11a303996d5503d29ede77598243ddc66f735279`, which merges the Fable-approved inert maintenance components e87b410. Home requirement: `7e282e2a363b9cc90cd74dd97809e6613a699af8`, `docs/superpowers/specs/2026-08-30-home-design.md` §2.1 and AGENTS.md; both are supplied with the review bundle. Maintenance design `6a81dac`, `implementation/maintenance-exec.md`, is approved. Guard/claim/RecoverClaim, Held lease, strict containment, local fence and scheduled-token primitives now exist in this base. They are unmounted components: the maintenance worker, browser approval workflow, preflight, end-to-end resume (including proposed ResumeFenced), checker launch adapter and enforced platform floor are NOT implemented. References below to the maintenance workflow mean that approved/proposed integration contract, not an existing executable service. No component approval proves deployment capabilities.
@@ -30,7 +30,7 @@ A record carrying this value must also carry explicit `hibernate:false`. The two
Required eligibility: an existing provisioned `instance`; derived canonical local Unix socket and nonempty canonical primary database path; ordinary exec backing; exactly one verified residence; ready status.
-Refused shapes: any unit, TCP upstream, static/service kind, backing override, tunnel, fleet, pool, in-flight move, or capability requiring unit execution. The serving box must be the currently verified owner. Preserve existing account/app/host/creation identity and replication class. Unknown placement or owner refuses. Do not infer single residence from an empty region string without authoritative placement resolution.
+Refused shapes: any unit, TCP upstream, static/service kind, backing override, tunnel, fleet, pool, in-flight move, any capability requiring unit execution, or any granted port (`grantedPortTokens` nonempty). Resolve the actual capability set and grants in preflight; an unknown grant state refuses. Granted ports can start a socket-activated unit beside the exec child even without Daemon. The serving box must be the currently verified owner. Preserve existing account/app/host/creation identity and replication class. Unknown placement or owner refuses. Do not infer single residence from an empty region string without authoritative placement resolution.
This first slice is an opt-in for existing initialized instances, implemented through the fixed platform maintenance action below. Clean installation and new Home credential/directory roles need a separate supported always-awake provisioning path; that remains an outstanding suite requirement. Existing-only migration is not full Home readiness. It does not add a create-time always-awake option, an opt-out, a unit conversion, or a generic command runner. Once activated, clearing or changing `lifecycle`, flipping hibernate, changing its execution class, or starting a move is refused by ordinary writers. Retirement/trash/purge still use their reviewed lifecycle protocols. A later policy downgrade or relocation needs its own reviewed transition; “legacy” is not an escape hatch.
@@ -64,7 +64,7 @@ Concrete Go names may follow local conventions, but no consumer may reconstruct
The registry update must preserve the replication rung. Existing `Registry.SetHibernate(false)` executes `hibernate=0, replication=''`; calling it during this transition is wrong. Add a dedicated checked transactional projection of lifecycle+hibernate with the existing replication value preserved, or extend the canonical projection transaction to do exactly that. Do not alter legacy SetHibernate behavior for unrelated routes. The invariant is `Replication != ""` implies `OwnsExecReplication`, rather than implies Hibernate. Apply this invariant to BOTH Registry.Upsert INSERT normalization and its ON CONFLICT replication expression, as well as the dedicated projection transaction. Update `replicationRail` and `carlos add` validation/defaulting to the same predicate; neither may accept a rung for an empty DBPath or externally managed route. Preserve the existing rung when an eligible resident route is re-upserted with no new rung. Reconcile’s existing-owned branch must use the dedicated projection instead of SetHibernate(false), including after record CAS succeeded but projection failed.
-Before `convergeOwned` or ANY owned-row field update in Reconcile, compare the authoritative record lifecycle with the existing row. A row already carrying v1 paired with an absent, unknown or conflicting record lifecycle is an invalid regression, including a stripped legacy record. Quarantine it: preserve the entire v1 row and replication ownership, install local admission/start denial and cancel pending starts. Keep that primary in the activator-owned retention set so Edge.Reload/RetireExcept cannot reinterpret it as external ownership. Stop any running main/sidecar and replica through the checked stop path; retain uncertain resources and deny replacement on failure, with no premature lease release. Even after a proven stop, retain the row so root replication continues to exclude its DB. Record/row disagreement supplies neither ordinary startup nor a policy repair permission; repair requires the exact approved maintenance operation. This rule differs from temporary nonauthoritative discovery failure, which does not fabricate a regression or retirement.
+Before `convergeOwned` or ANY owned-row field update in Reconcile, compare the authoritative record lifecycle with the existing row. A row already carrying v1 paired with an absent, unknown or conflicting record lifecycle is an invalid regression, including a stripped legacy record. Quarantine it: preserve the entire v1 row and replication ownership, install a distinct local `policy-regression` admission/start denial keyed to the exact primary identity and observed record/row revisions, and cancel pending starts. This is a new denial reason, not a fabricated maintenance generation. Reconstruct it from the persisted row plus authoritative mismatch before admission after restart; normal maintenance resume cannot clear it without resolving the exact mismatch through its approved projection. Keep that primary in the activator-owned retention set so Edge.Reload/RetireExcept cannot reinterpret it as external ownership. Stop any running main/sidecar and replica through the checked stop path; retain uncertain resources and deny replacement on failure, with no premature lease release. Even after a proven stop, retain the row so root replication continues to exclude its DB. Record/row disagreement supplies neither ordinary startup nor a policy repair permission; repair requires the exact approved maintenance operation. This rule differs from temporary nonauthoritative discovery failure, which does not fabricate a regression or retirement.
`ops.FleetDBsWithSkipped` currently excludes exec DBs only when `Hibernate` is true. Replace that exclusion with `OwnsExecReplication`; otherwise the root replicator may pick up a database already streamed under the activator lease. The generated fleet replication config must be checked before activation, and missing/unreadable ownership must refuse a potentially duplicate replication change. This mode does not rename `HibernatePrefix` or move existing objects.
@@ -119,7 +119,7 @@ The worker performs the following ordered protocol:
5. Read back the actual resulting record revision and compare all protected fields to the approved snapshot. Publish an immutable action receipt naming original identity, approved request/delta, pre/post record revisions, target policy, current claim/guard generation and the checked stop/lease evidence references. Sensitive snapshot material remains in the existing private envelope; public status contains no environment or DB contents. Receipt publication failure is ambiguous and leaves the fence held.
6. Materialize the target lifecycle and false Hibernate in one checked registry transaction while still fenced, preserving DB/socket/owner/replication columns. It must be the projection of the exact target record revision, not a freestanding local edit. Read back and verify it. No ordinary manager adoption can open admission. A stale projection is a repairable incomplete action only under the exact operation recovery below.
7. After matching target record/registry state and the normal final checkpoint/receipt requirements, publish succeeded with immutable action evidence. Successful policy installation remains fenced. Report that state; do not release the app claim or automatically start Home.
-8. Explicit fresh owner-approved resume validates the target policy under the amended eligible class and the exact target record, selected serving release/config, capability floors and action receipt. Before serving, run the fresh app-specific non-serving compatibility checker from that selected release under the fence and exclusive lease, exactly as maintenance6a requires. Bind its successful receipt to this resume attempt, selected artifact/config and current database/record identity; complete its normal Wait and checked process-tree cleanup. The policy action itself still invokes no app subprocess, but resume retains this separate mandatory checker. Only then start the approved serving app under the retained exclusive lease and checked resume protocol with admission closed. Verify health/version, publish the matching resumed guard and record projection, verify both, then open local admission and release the matching app claim only after serving health agrees. Install resident desired state as part of that handoff; it cannot precede or replace it.
+8. Explicit fresh owner-approved resume validates the target policy under the amended eligible class and the exact target record, selected serving release/config, capability floors and action receipt. Before serving, run the fresh app-specific non-serving compatibility checker from that selected release under the fence and exclusive lease, exactly as maintenance6a requires. Bind its successful receipt to this resume attempt, selected artifact/config and current database/record identity; complete its normal Wait and checked process-tree cleanup. The policy action itself still invokes no app subprocess, but resume retains this separate mandatory checker. Only then start the approved serving app under the retained exclusive lease and checked resume protocol with admission closed. The accepted ResumeRequested guard MUST carry a nonempty sorted unique lowercase RequiredContracts set, derived from the exact selected Home release’s verified signed manifest and preserving all already-required contracts. The same set is bound to fresh owner approval and remains pinned through Resumed. At least one selected-release contract is mandatory; no available verified contract means resume refuses before any start. This action invents no unsigned contract or capability name. Verify health/version, publish the matching resumed guard and record projection, verify both, then open local admission and release the matching app claim only after serving health agrees. Install resident desired state as part of that handoff; it cannot precede or replace it.
No generic lifecycle claim enum is needed. The original maintenance claim stays held across requested, policy execution and explicit resume. This serializes trash/restore/purge and other maintenance for the app. Ordinary conflicting record/config/adoption writers still need the existing guard/record-CAS protections; the app claim does not magically serialize those writers. Platform transition code is a narrow additional authorized writer of the two fields, recognized only by this typed accepted operation.
@@ -127,7 +127,7 @@ The live registry transition now happens only with the old process stopped and a
### Recovery of the exact transition
-The table below applies only while the SAME live executor retains its valid exclusive maintenance lease and execution reservation. Rows involving policy CAS, receipt publication, registry repair or resume are unreachable without those retained resources. It does not authorize post-crash recovery. If the executor dies or loses either resource, the first implementation has no supported recovery: the operation stays fenced and service remains unavailable. This is an explicit first-slice availability limitation, not an implied fresh-lease path. A separately reviewed executor handoff is required to remove it.
+The table below applies only while the SAME live executor retains its valid exclusive maintenance lease and execution reservation. Rows involving policy CAS, receipt publication, registry repair or resume are unreachable without those retained resources. The same-executor owner-approval wait consumes the existing five-to-ten-minute bounded maintenance execution deadline; retries do not reset it. On expiry, those rows become unavailable, cleanup/uncertainty follows the parent protocol, and the host stays fenced. The renewer’s ability to renew indefinitely does not extend this operation deadline. It does not authorize post-crash recovery. If the executor dies or loses either resource, the first implementation has no supported recovery: the operation stays fenced and service remains unavailable. This is an explicit first-slice availability limitation, not an implied fresh-lease path. A separately reviewed executor handoff is required to remove it.
Claims never expire. `RecoverClaim` observes only the exact operation ID; status/GET is read-only. A new random request cannot take over an interrupted operation. Stopping/checkpointing cleanup under an accepted guard follows maintenance6a's existing limited recovery rule; it does not automatically apply the policy CAS or start an app.
@@ -161,7 +161,7 @@ The remaining recovery implementation is bounded by existing maintenance lease d
Activation is blocked until every record writer, serving box, edge, agent, root replicator/adopter and relevant recovery binary understands this policy and enforces its supported rollback floor. Additive JSON alone is not safe: an old writer strips lifecycle, an old edge treats false-hibernate as external ownership, and an old replication scanner can add a second replicator. An old route reader may also preserve stale hibernation state during partial conversion.
-The signed app runtime-contract design is a separate pending dependency and does not itself define a platform binary floor. A distinct authenticated platform-floor design is still required. This design requires a distinct platform capability identifier for always-awake exec support in that reviewed mechanism; do not repurpose an app's maintenance semantic contract as a platform binary capability or trust a self-reported unsigned capability. Floors must precede both policy-writing activation and host/replication activation, even if no maintenance operation is enabled. Until a reviewed authenticated floor and its deployment proof exist, this mode remains disabled. This proposal does not define a new signing format or mark that dependency approved.
+The signed app runtime-contract design is a separate pending dependency and does not itself define a platform binary floor. A distinct authenticated platform-floor design is still required. Independently, the reviewed signed app runtime-contract mechanism gates step 8 and EVERY subsequent wake: CheckServing must receive the exact verified manifest contracts and find the pinned RequiredContracts set. An unsigned self-report, only a platform floor, or an empty set cannot satisfy the Resumed guard. This design requires a distinct platform capability identifier for always-awake exec support in that reviewed mechanism; do not repurpose an app's maintenance semantic contract as a platform binary capability or trust a self-reported unsigned capability. Floors must precede both policy-writing activation and host/replication activation, even if no maintenance operation is enabled. Until a reviewed authenticated floor and its deployment proof exist, this mode remains disabled. This proposal does not define a new signing format or mark that dependency approved.
Deploy readers and deny/replication protections before exposing the policy operation. Activate a synthetic existing canary only after a wrong-version/writer negative control proves refusal. The fixed platform transition above requires checked downtime. Policy CAS and registry projection remain separate objects: during disagreement, serving and proactive startup deny. Repair only under the exact held operation, never by clearing lifecycle or starting another child. This is a reviewed-action proposal with a concrete ordering; it is not approved until the fixed-action discriminator, recovered-target receipt and fresh recovery lease rule have been independently reviewed.
@@ -169,7 +169,7 @@ After activation, old binaries cannot be an availability rollback. Roll back onl
## Capability dispatch and checker launch
-Carry `ManagedByActivator` as an explicit validated field in `caps.Plan` from capabilityPlan and every other plan constructor. Before filesystem or unit mutations, refuse `Set.Daemon && ManagedByActivator`; checking only Hibernate would permit the false-hibernate resident to install a second service. Preserve the existing unit/socket bypass for every activator-managed route in Converge, rollback snapshots and adoption dispatch. Unsupported combinations refuse before capability writes. A signed manifest cannot override this execution-class restriction.
+Carry `ManagedByActivator` and `RequiresResidentProcess` as explicit validated fields in `caps.Plan` from capabilityPlan and every other plan constructor. Before filesystem or unit mutations, refuse `Set.Daemon && ManagedByActivator`; checking only Hibernate would permit the false-hibernate resident to install a second service. For `ManagedByActivator && RequiresResidentProcess`, also refuse any nonempty grantedPortTokens before any write or unit action. Converge currently has NO Hibernate-keyed bypass for granted sockets; this refusal is new. Preserve the existing exec dispatch bypasses at adopt.go:772, adopt.go:1207 and agent.go:2640 for all activator-managed routes, and carry the new refusals through rollback snapshots and all plan constructors. Unsupported combinations refuse before capability writes. A signed manifest cannot override this execution-class restriction.
The selected-release compatibility checker uses the proposed checked maintenance launch adapter, with command/context and executable verification, not the ordinary serving path. Child fd4 must be explicitly closed and checked before Home’s database descriptor baseline; worker-held executable proof remains retained. The adapter and corresponding Home open-contract amendment remain unimplemented review dependencies. This proposal adds neither a path-based fallback nor approval for an absent checker.
@@ -212,12 +212,13 @@ The choice of an explicit always-awake exec lifecycle and preservation requireme
- Accept or reject the first-slice outage consequence: an executor crash at any fixed-action boundary leaves Home fenced with no supported recovery until a separately reviewed exclusive-executor handoff exists. No fresh approval, elapsed time or new DB lease overrides this limitation.
- Approve or reject the fixed platform action, inert policy preparation, recovered-target receipt and pinned-owner fresh recovery lease rule above. They specify activation and retained-executor recovery without a generic claim enum, but are NEW authority proposals, distinct from app-exec. Fresh-lease takeover remains unavailable until the explicit exclusive-executor/death proof is implemented and reviewed; it is not implied by this design. Rejection leaves this branch not implementation-ready until revised.
+- The selected Home release must carry at least one verified signed app runtime contract for ResumeRequested/Resumed and every later wake. Its reviewed signing/verification mechanism is a separate implementation gate from the authenticated platform binary floor.
- The authenticated platform capability/floor identifier and evidence needed for all old writers and the root replication generator. Its signed-floor foundation is still pending independent review.
- The human-owner policy endpoint and CLI spelling, including current-owner checks for a long-running convergence wait. This document proposes them; no existing API is claimed to authorize this field already.
- The four-start ceiling, retry timings and effective startup readiness deadline on the actual supported box. Preserve the stated bounds unless review changes them; measure an RTO rather than infer it from timers.
- A supported app-specific non-serving compatibility checker in each selected Home serving release. If none exists, implementing and reviewing it is a consumer dependency; current Home operator preparation, fixed-action success, recovered-target evidence and HTTP health are not substitutes.
- Exact Home primary/alias/role/config/DB ownership inventory from supported preflight. Supplied effective route receipts do not establish those facts.
-Implementation must also test Daemon with Hibernate=false and ManagedByActivator=true: refuse before unit/file writes, including rollback/adoption paths.
+Implementation must also test Daemon with Hibernate=false and ManagedByActivator=true: refuse before unit/file writes, including rollback/adoption paths. Repeat with Daemon=false but a granted port and assert no socket/service write or start; preflight must also refuse unknown grants.
No Home policy change, unit migration, maintenance operation, signing contract or runtime-floor declaration is approved by committing this design.