Pin team ID codec and clarify pending operator authority adapters
1 file changed,
+41
−21
implementation/home-operator-seed.md+41 −21
CI passed — run details
diff --git a/implementation/home-operator-seed.md b/implementation/home-operator-seed.md| index 2e71e85..4e42141 100644 |
| --- a/implementation/home-operator-seed.md |
| +++ b/implementation/home-operator-seed.md |
| @@ -1,6 +1,7 @@ |
| # Local Home operator seed and provisioning |
| -Status: proposed internal design, 2026-09-08. Fable approval is required before |
| +Status: revised internal design, 2026-09-08. Fable R1 ended at a provider quota |
| +refusal without a verdict; Home discussion 37 records it. Approval is required before |
| implementation. This branch starts at directory runtime 171f49a. It defines an |
| application package and a local command protocol; it neither mounts a public |
| operator endpoint nor authorizes live provisioning. |
| @@ -41,16 +42,16 @@ missing generation alongside existing consumers is a refusal, never a repair. |
| Platform discussion 117 owns stopping traffic and all background work, holding |
| the database lease, selecting the immutable executable and exact database, and |
| resuming safely. Its private-input/result protocol is generic. The proposed |
| -entry point is `home operator-v1 --db <platform-selected-existing-db>` with a |
| -private result file descriptor supplied by the transport. The fixed command and |
| +entry point is `home operator-v1 --db <platform-selected-existing-db>`, with |
| +standard output captured as the private result by the transport. The fixed command and |
| role permissions belong to reviewed deployment configuration. No request chooses |
| a binary, path, SQL, environment variable, shell fragment or network destination. |
| The command never starts an HTTP server, sends mail or makes network calls. |
| Read one UTF-8 JSON object from private stdin with a 64 KiB hard limit including |
| whitespace, then require EOF. Write one JSON result of at most 64 KiB to the |
| -private result descriptor only, after transaction commit. Standard output and |
| -standard error carry no data and the transport discards them. Input and result |
| +private standard-output channel only, after transaction commit. The transport |
| +never tees or logs stdout and discards stderr. Input and result |
| are encrypted at rest by the transport, available only through its authenticated |
| private result channel, and never included in public status, receipts or logs. |
| The application does not implement its own remote encryption protocol. |
| @@ -71,8 +72,9 @@ an immutable operation allowlist and expected role/origin/database identity from |
| reviewed launch configuration. A request's `operation` only selects within that |
| allowlist. Package constructors are private to the command adapter or receive an |
| opaque validated operator context; exported structs cannot fabricate that context. |
| -The transport's signed operation ID is distinct from Home operation_id. Both are |
| -bound by the adapter's verified invocation context. No body field can claim an |
| +The transport's operation ID is distinct from Home operation_id. Both must be |
| +bound by the adapter's verified invocation context. Current platform source has |
| +no signed Home invocation receipt, and this design does not assert otherwise. No body field can claim an |
| operator identity or maintenance state. The platform must provide an authenticated |
| invocation context or equivalent private launch configuration before command |
| wiring is approved; an environment boolean supplied by the caller is insufficient. |
| @@ -98,11 +100,9 @@ Add role-specific operator result tables through additive migrations. Credential |
| and directory databases never receive each other's tables. Each result row has |
| operation_id primary key, fixed action, opaque operator reference from verified |
| invocation context, creation time, a keyed request digest, and a sealed result. |
| -The request digest is HMAC-SHA256 using a dedicated key derived through the shared |
| -sealer's supported key separation or, if no derivation API exists, an independently |
| -provisioned 32-byte idempotency key. No custom KDF is introduced. The chosen |
| -implementation must use the independent key when the shared API offers only |
| -Seal/Open. Digest canonical typed operation input, not raw JSON whitespace. |
| +The request digest is HMAC-SHA256 using an independently provisioned 32-byte |
| +idempotency key. The actual shared sealer exposes Seal/Open, not a key derivation |
| +API. No custom KDF is introduced. Digest canonical typed operation input, not raw JSON whitespace. |
| This prevents a stored bare address/name digest becoming an offline dictionary. |
| Seal result bytes with the existing role sealer and purpose |
| @@ -134,9 +134,19 @@ manifest or per-team config exception. |
| `directory.inspect` accepts no payload and returns only current generation (or |
| explicit absent), the next proposed team integer, and derived team sqid. It writes |
| no authority and is not a reservation. Derive next ID from the maximum existing |
| -team ID and sqlite_sequence, reject overflow, and encode with the suite's pinned |
| -sqid codec. Before implementation select and cite that actual shared codec; |
| -there is no random substitute for the integer-encoding sqid required by §10. |
| +team ID and sqlite_sequence, then add one, refusing signed-64-bit overflow. No |
| +shared Home/suite codec exists today. Pin official github.com/sqids/sqids-go |
| +v0.4.1 (upstream commit 2ba95c7920dcf08340e099c7b22beb1178da6106), using |
| +sqids.New() and that version's fixed default alphabet, blocklist and zero minimum |
| +length. Encode exactly one positive integer. Require Decode to return exactly |
| +one integer in 1..MaxInt64 and Encode(decoded) to equal the original string. |
| +This preserves the integer-encoding sqid required by §10; Docs' random document |
| +IDs are unrelated. Golden vectors are 1=Uk, 2=gb, 3=Ef, 1000=pnd and |
| +MaxInt64=AqkYhRmbHpEX. Refuse zero, negative/multiple numbers, alternate encodings |
| +and reserved DNS labels independently. Dependency/options changes require explicit |
| +compatibility review and must preserve existing team sqids. The upstream |
| +[canonical encoding guidance](https://github.com/sqids/sqids-go/tree/v0.4.1) |
| +requires re-encoding; a disposable local pinned-library probe verified these vectors. |
| The seed checks this proposal again under the write lock. A concurrent seed makes |
| the old proposal fail; the operator obtains a new proposal and new owner receipt. |
| @@ -148,7 +158,10 @@ normalizes and blind-indexes with the same credential helper as sign-in, resolve |
| or creates the normal opaque person stub, and never mints a session. Synthetic |
| live previews require already authenticated synthetic identities and an |
| `existing_only:true` mode; that mode refuses a missing person and sends no mail. |
| -The directory cannot request address resolution over HTTP. |
| +The directory cannot request address resolution over HTTP. Refactor the existing |
| +findOrMintPerson SQL into a transaction-capable internal helper: its current |
| +a.db.Writer() call cannot participate in the required operator transaction. |
| +Keep sign-in semantics, blindIndex and day-coarsened created_at unchanged. |
| The result is `{version:1, operation_id, outcome:"committed", receipt}`. receipt |
| uses the shared closed `{v,kid,payload,signature}` envelope pattern with canonical |
| @@ -166,8 +179,13 @@ bootstrap receipt; existing teams/memberships may be retained. Generate a random |
| 32-byte canonical base64url generation once, persist it and a bootstrap receipt |
| plus sealed result atomically. Require explicit deployment precondition that no |
| consumer has ever been provisioned; a database which has lost generation/receipt |
| -history cannot satisfy this precondition based on its own empty tables. Supported |
| -transport must bind the independently verified initial-install attestation. If |
| +history cannot satisfy this precondition based on its own empty tables. An independently |
| +signed external installation record and its monotonic registry floor must attest |
| +that this exact directory database has never had a roster generation provisioned. |
| +The record issuer, signature verification and durable external registry are not |
| +implemented by current Home or platform. They require a separate concrete design |
| +and approval before the adapter can construct initial-install authority. Platform |
| +maintenance provides exclusion, not this Home-specific historical evidence. If |
| that evidence is unavailable, initialization is unavailable. Restore cannot use |
| this verb. Ordinary boot only applies empty schema and never invokes it. |
| @@ -215,8 +233,10 @@ attestation. Requery pending binding, consumer enabled state, token, generation |
| record metadata, then switch only that existing pending binding to live and commit |
| its audit/result atomically. This package verifies an opaque approved activation |
| context; it does not fetch a URL or trust arbitrary deployment evidence JSON. |
| -Until the transport/operator adapter can construct that context, activation remains |
| -unwired. A compatibility account-link preview is not sufficient for activation. |
| +Current platform receipts do not attest all these Home-specific facts. The |
| +external provisioner/verification adapter and its pinned evidence verifier require |
| +a separate concrete authority design; no constructor may accept caller-controlled |
| +booleans as a substitute. Until that adapter exists, activation remains unwired. A compatibility account-link preview is not sufficient for activation. |
| ## Transaction and existing-database checks |
| @@ -258,7 +278,7 @@ synthetic addresses, names, bearer strings, receipt payloads and private results |
| Prove current Home session acceptance/signout and all existing team ciphertexts |
| survive applying the additive tables. Mutation tests must fail when signature, |
| consumed-receipt uniqueness, FK verification or idempotency checks are removed. |
| -Demonstrate the private-FD command with a disposable local fence fixture only; that |
| +Demonstrate the private-stdout command with a disposable local fence fixture only; that |
| fixture is not evidence of platform maintenance correctness. Full repo gates, exact |
| CI and Fable whole-code review precede integration. Live use additionally requires |
| approved/shipped platform 117, operator authority and invocation/activation context |