Root trusts service-writable hostguard and health records under /data (claim root paths) open
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 6387394d · claude-code/2.1.284 · DOCS-T1
Found by Opus in the authority review of moves Task 7b, the root held release under the claim. The problem predates Task 7b and covers claim Plan 11's root launch too. It is the same class as #267.
What root trusts:
Hostguard records. hostbox.WorkSource.Select captures from /data/hostguard/<host>.json. hostguard.Guard.With reads ActiveFence and FenceJournal from that same file (hostguard/guard.go:116-160). The directory is 2770 service:service (bootstrap.go:68). - A compromised agent can strip a completed fence for its own session. Root then acts (publishes or launches) inside a window where the claim still reads landing/configured, after root has already fenced that session. - Claim Plan 11's root launch trusts the same records.
D3 health history. The proof gate reads /data/healthy/<acct>/<app>.json through safefile, so symlinks are stopped, but the owner isn't checked. - /data belongs to the service user, so the agent can rename /data/healthy within its parent and plant a "healthy" sha. That bypasses the D3 proof for the pinned release. - Signed authorization still applies, so this is limited to the pin. Root's adoption pass has the same exposure (agent.go:4294).
Fix direction: root-trusted state lives in a root-owned directory (as Task 7b's receipt already does). Otherwise root requires uid 0 on the file and on every directory it walks. That means moving hostguard's root-consumed records and the health records root reads to root-owned paths, with a migration.
Status: open. Claim-side to fix (platform-1e). Not an activation blocker for inert code, but it must land before CARLOSHOSTCLAIM is switched on anywhere.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 6387394d · claude-code/2.1.284 · DOCS-T1
Paul's ruling, 2026-10-12: targeted scope. Plan 14 rev 3's root-read census (ad75a26c on design-replica-ownership) flags about 2,243 root-path functions that read the service-writable registry or /data. That's a conservative upper bound: the scan doesn't prove root reaches each one. Fixing them read by read isn't feasible, so the ruling is:
Plan 14 fixes the high-impact families now, each with tests: - fence and claim installation authority (root-owned records, root lease broker, migration); - capability grants; - D3 health history; - release denials and swap failures; - moves floors; - readiness, settings and good-version.
The census becomes a freeze. Every other existing read is classified as accepted-legacy, and any new or changed root read of the registry or /data fails until it's classified.
A root-owned registry is its own design item. In that design, the edge and the service user write through a root API, and a compromised carlos can no longer steer root. It's tracked separately.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 6387394d · claude-code/2.1.284 · DOCS-T1
Plan 14 track E: Paul's rulings, 2026-10-13 (after the Opus scope review, opus-trackE-scope-review.md)
Keep what's built. The independent named-unit recovery path, the signed reconstruction, replacement, status and readback stay. Finish E1 to E4 on top of them. Nothing is cut.
Unknown or corrupt history on a census box: root allows any signed target that has no known refusal. Recovery to an authorized build is never blocked, including builds from before the roll that have no root health history.
Minting on boxes without a census pauses until Part 3. No proofs are minted there, and the roll notes say so. No code is needed beyond making the pause explicit and logged once per pass.
E4 grants: the existing box-local carlos route --grant, run as root, writes consent directly. No signed envelope and no receipt protocol.
Controller ruling: E3 gating is census-only, with no claims-off records. Merge ruling 6 applies.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession c4a04fdc · claude-code/2.1.292 · DOCS-T1
Census ruling requested: census-ruling-ls284 (branch litestream-oom-284, commit 7cbde945, amadan #284 slice A). From session platform-6e [2bd169]; I do not own the census, so this asks the owner to confirm or correct the classification before the branch merges.
The branch adds overlay plan14-root-reads-ls284.tsv, loaded after hotfix281, earlier overlays untouched. Five rows, all legacy / accepted-legacy, seal e22293f6…:
| Unit | Sites | Basis claimed | |---|---|---| | internal/ops/ops.go:runLitestream (changed) | data-literal, file:Open, file:ReadFile, same three as before at new offsets | Same registry open and prior-config read. Adds one root-owned write (a systemd drop-in stating the replicator's memory cap, sized from the database count this run computed) and a daemon-reload. No new input is trusted. | | internal/ops/ops.go:systemdDaemonReload (new) | file:Command | Root runs a fixed systemctl daemon-reload with no caller input. Same class as internal/host/bootstrap.go:systemctl under J4 root-input. | | internal/host/restartwatch.go:platformUnitRestarts (new) | file:Command | The agent, as carlos, runs systemctl show --property=Id --property=NRestarts 'carlos-*.service'. Fixed command, no registry or tenant input. Same class as probes.go:adoptTimerActive under J4 root-input. Feeds an alert only; no root decision. | | internal/host/units/carlos-litestream.service:external (changed) | file:external | Default MemoryMax 512M with GOMEMLIMIT, restart backoff. User, paths, command and sandboxing unchanged. | | internal/console/templates/metrics.html:external (changed) | file:external | The alerts table shows a rule's detail beside its name. Same alert state objects. |
runLitestream gains a root write under /etc/systemd/system/ and a daemon-reload. The census counts reads, so the row looks unchanged; the write is the new thing. The path is fixed (or an operator-supplied flag), the content is two generated lines, and nothing service-writable is read to produce it beyond what the verb already reads.
The overlay will be regenerated once more before merge if Paul's copy review changes a string inside runLitestream (the digest covers it). The rows and bases stay the same; only digests and the seal move.
If the answer is that any of these is not accepted-legacy, say which class and task and I will rewrite the row.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession c4a04fdc · claude-code/2.1.292 · DOCS-T1
Update to the census-ruling-ls284 request above: review fixes added two rows. The overlay on litestream-oom-284 is now at db57e5ca with seven rows, seal 4501bab2….
| Unit | Sites | Basis claimed | |---|---|---| | internal/ops/litestream_memory.go:writeMemoryDropIn (new) | file:ReadFile, file:Lstat | Root reads the root-owned drop-in this verb itself wrote, and lstats its own reload-pending marker beside it, to decide whether to rewrite and reload. The same compare-before-write as writeIfChanged under J4 root-input. The path is fixed or an operator-supplied flag. | | internal/host/restartwatch.go:loadRestartWatch (new) | file:ReadFile | The agent, as carlos, reads back its own restart-watch state from <data>/monitor/restarts.json, beside the alert state it already keeps there. The file is validated as input (version, times, counter ranges) and anything else is discarded. Feeds an alert only; never read by root; no root decision. |
The other five rows are as described above; their digests moved with the code. The seal will move once more if copy review changes a string in runLitestream.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 6387394d · claude-code/2.1.284 · DOCS-T1
Part 3 obligations from feature-branch census rulings (2026-10-14):
F2-F4 (root-owned floors) must cover the seeds floor (/data/.moves/seeds-floor.json: readLocalSeedsFloor, judgeSeedsPrev, rootJudgeSeedsPrev, authority F,J4 under census-ruling-seeded-instances) alongside the moves floor.
G (census bootstrap and collector) must set CensusReport.Seeds through hostops.CollectCensusSeeds, or every activation through Backfill.Publish refuses. CollectCensusSeeds and Registry.ImportJournalHosts are authority G and must stay deny-only.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 6387394d · claude-code/2.1.284 · DOCS-T1
Plan 14 track E: controller rulings on E2 (2026-10-14, after checkpoint 41)
Binding. These answer the two items the checkpoint-41 report left as proposals.
R-E2a. Positive root-relayed relocation is deferred to Part 3
Part 2 ships the claim-mode relocation refusal already built at checkpoint 41 (relocationinstall.go, plus its unit and root tests). Claims-off relocation stays byte-for-byte main's.
Do not build the root-relayed relocation the checkpoint-41 report proposed (continuation item 2). Record it in the report as "deferred to Part 3 by R-E2a" and drop it from E2's open list and from the audit's open rows. Mark the row "deferred (R-E2a)", not "done".
Why: - moves are switched off on every box (CARLOSMOVESPHASE1 unset); - activating moves already needs the claim and Part 3; - the proposal is far past the scope guard of about 200 lines for a derived ruling.
Cost if wrong: claim-mode relocation is unavailable until Part 3. No box runs in claim mode before then.
R-E2b. D3 launch verifier: the caller holds release exclusion, and the verifier never takes it
Lock order is fixed: release exclusion first (outer), then participation exclusion (transaction.lock, inner). Nothing may take release exclusion while holding participation exclusion.
The registered launch verifier must never acquire release exclusion. Every path that reaches VerifyLaunches takes release exclusion before participation exclusion: - Ledger.Idle via hostfloorControllersIdle/CheckControllersIdle (guardtransaction.go); - rootparticipation.ActivationReady (claimstop_run.go).
Proof travels with the call. Release exclusion's holder puts an unexported held-token in the context, and only the release package can mint it. The verifier checks the token, and a missing or foreign token returns ErrUnavailable. Fail closed: never fall back to taking the lock.
Production registration: register the verifier once, at root startup, from the code that owns the census and reservations. That code must hold the reservation reader and the kernel census reader that E2 built. - With no census (ruling 6), nothing changes on the box: the verifier is either not consulted or, where it is, the existing claims-off path is main's.
D-family edits are allowed only for this hoist and the context token, at the call sites named above. Change nothing else in D.
Tests: - verifier refuses without the token; passes with it; - a concurrent holder of release exclusion plus an Idle caller completes without deadlock, under -race locally for this package only; - a test that the verifier refuses a token minted for a different lock instance. - If installed claim-launch acceptance needs real root, write it to the runner contract and list it as pending.
Remaining E2 after these rulings
Positive root-reserved workers: boot and fallback, replacement and recycling, generation support.
Running-tenant containment.
Protected timer registration and removal.
D3 connection per R-E2b.
Then E3 (census-only), then E4 (box-local carlos route --grant).
Close whole items per run.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 6387394d · claude-code/2.1.284 · DOCS-T1
Claim activation scope, NARROWED (Paul's decision, 2026-10-16). BINDING on every builder.
Source: minimal-boundary-result.md (Astra). Paul chose to narrow the activation gate, and to activate in cohorts: dev and boxes without named units first, the flagship eu-west-1 console box last. This supersedes the parts of the spec rev 6.34 / Plan 14 activation gate listed below as FREEZE or DROP. Those items are finished AFTER activation, not before it.
The boundary that must hold before activation (KEEP)
Root independently authorizes every enabled claim effect (launch, stop completion, cold handover, retirement, publication and replay): the host, installation, session, operation and authenticated controller are bound. Fences, retirement decisions and lease uncertainty are held outside agent control and rechecked at execution and receipt replay.
The whole execution configuration is authorized: executable bytes, the effective unit plus its drop-ins, privileged arguments and environment, identity, mounts, capabilities and containment. Every restart route uses the same reservation boundary.
Root derives and revalidates destructive targets. It stops the recorded containment, retires the recorded installation, and removes only exact root-recorded artifacts. Pending and running generation pins stay independent of registry deletion. (Destructive covers deletion, wrong-target stop, overwrite, rename, chown, mounts and publication.)
A verified, recoverable migration: admission exclusion; drain and stop existing work; old-session denies retained; a real installation census; no imported legacy "allow".
Boxes survive ordinary lifecycle events: seed, cold wake, stop, second wake, reboot, and signed repair or update. Device numbers are boot-local. Floors keep a usable repair executor. Nothing turns routine operation into a permanent, box-wide trap.
Proven at the real boundaries, with hostile service-UID inputs, substitution, durability failures at AUTHORITY TRANSITIONS (fence before effect, reservation before launch, retirement intent before mutation, permission and receipt before success), and permitted positive cases through production constructors. No-census boxes keep exactly main's behaviour.
Per-track decisions
| Work | Decision | |---|---| | 4a named units plus console always-running (boot, adoption, restart, recover) | KEEP, but it gates only the eu-west-1 cohort, not the first activation | | Unit containment compatibility with the REAL console and woodstar services | KEEP (for eu-west-1) | | Containment population on the selected boxes | KEEP | | Device audit of active launch, inventory, retirement and unit bindings | KEEP. Other families: FREEZE | | E3: canonical attribution and the inputs that authorize claim effects; retry and recovery for root denials already shipped | KEEP | | E3: remaining failure/intent producers; exhaustive served/build/completion history | FREEZE. But sticky root state must never block legitimate operation: either complete its delivery and settlement, or gate the sticky state off | | E4: protection of claim-bound units on BOTH convergence paths (fixed root configuration, or refusal) | KEEP | | E4: the full dynamic route --grant workflow | FREEZE | | J4: the five E4 slots as mandatory metadata | DROP | | J4: exhaustive mapping of about 1,100 authority rows | FREEZE | | H2: production boundary witnesses for enabled effects and their shared recovery | KEEP | | H2: the whole matrix as one indivisible gate | FREEZE | | Floors: enforcement plus a usable boot, update and recovery path | KEEP. Further moves and seeds floor machinery: FREEZE | | Historical-record conversion for records that cannot exist at first activation | FREEZE (explicit refusal is enough) | | Files seed: the reboot race (fixed in run 31), FS-R11 (done in run 31), and unverifiable retained parks blocking later retirement | KEEP (the last one is an availability trap) | | Files seed: full readback, repair, sizing and automatic rehabilitation | FREEZE | | #250: C8 provider, admitted provenance, Plan 15 writer, scoped root guard, claim-on launch/isolation/two cold wakes, reader→home→enable order, release key, IAM, scoped rollout | KEEP | | #250: cmd role, workers, sidecars, seeded cold install; moves Plans 4/5; moves secrets; #272 | FREEZE | | Whole-registry conversion; fixtures for unchanged legacy families | DROP |
Census and J4 under the narrowed gate
The runtime installation census stays.
The source-read census test (TestPlan14RootReadCensus) stays as it is: it freezes changes.
J4 (TestPlan14RootInputInventoryCoverage) must check ONLY the families of the ENABLED effects listed in KEEP, plus the exemption list. Every other authority row is reported (t.Log, plus a generated report file), not failed. Do not weaken the check for the enabled families.
Risks to resolve before shipping
No named-unit replacement before always-running startup works on the target box.
The unit sandbox must be proven against the real console and woodstar services before eu-west-1.
No sticky E3 state without delivery and settlement.
Retained parks must not block retirement.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession efaa3a81 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-155 (branch instance-bound-tokens-155, #155 half 1, instance-bound tokens). Tip 8f8867d7.
The root-read census flagged 11 changed units and 2 new ones, all in the console's own SQLite and templates.
Re-frozen at main's dispositions, read sets unchanged in kind:Store.CLIPrincipal, Store.CLITokens, Store.ServicePrincipals, Store.migrateCLIAuth, Store.PurgeAppRow, Store.PurgeClaimAppRow, Store.MoveApp, Store.renameAppIn, the two credential templates, and cli.go runInstances. clitokens gains host and `hostborn and a kind instance`. The listings leave out an instance row whose app row is gone. Purge deletes instance rows, rename and move carry them, and the stale-credential counts don't count them.
New, proposed as PROPOSED-155 at their siblings' disposition (accepted-legacy;rev3=J4;basis=root-input, like claimRawNewAppToken and claimRawRevokeCLIToken):Store.claimRawNewInstanceToken (INSERT) and Store.claimRawRevokeInstanceTokens (UPDATE revokedat, scoped to hostborn). Both run behind withAutoAppSQL.
Envelopes:., internal/console, internal/console/templates, internal/instanceupdates (a comment only) and internal/svcrole.
No bucket, file, process or registry read is added or changed. The seal moves to 78159fba…. The record-write census (Plan 9 B8) is re-pinned in the same commit: six units gained a role or binding check before an unchanged write, and the CLI's token client is a new key-site.
Asking for: rule the two PROPOSED rows (I'll swap in census-ruling-155), or tell me what to change.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession efaa3a81 · claude-code/2.1.292 · DOCS-T1
Update to the plan14-root-reads-155 ask: the tip is now 3e90e650, and there are three new units, not two.
The delete door's token revoke now snapshots token ids before it retires the record, rather than reading the record from the bucket. The units:
Store.LiveInstanceTokenIDs: a SELECT of a host's live instance token ids from cli_tokens.
Store.claimRawRevokeInstanceTokenIDs: an UPDATE of revoked_at for exactly those ids, kind, account and app. It replaces claimRawRevokeInstanceTokens.
Store.claimRawNewInstanceToken: unchanged.
All three are proposed as accepted-legacy;rev3=PROPOSED-155;basis=root-input, the same disposition as their cli_tokens siblings. The re-frozen set is unchanged. The seal is now dd8f3289….
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession ccaf58bf · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-adopt-unit-root-pass-315 (branch adopt-unit-root-pass-315, #315). Tip 8fa64a0a.
#315: the agent (User=carlos) adopted a console release in-process, failed systemd's permission check restarting console.service, and rolled back a good build as a failed one. The fix: release.RootRestartsUnits(), set only on the agent's in-process loops when euid != 0, hands any route a named unit serves to root's pass through the stage relay before staging or repointing. carlos adopt (root) never sets it.
Re-pinned at main's class and task:adoptHost (authority B3,E1,E2,E3,E4,J1; the new hand-off precedes staging and only returns) and type passConfig (authority E2,E3; gains the unitsToRoot bool).
New, proposed as PROPOSED-315:rollback.go unitServed, authority B3,E1,E3,J1 with processGroup's basis (root-route;kept=B3,E1,E3;scope=protected-decision-only). It reads the registry routes exactly as processGroup does, inverted (is this route served by a route that names a unit?). It only narrows the agent pass to a hand-off, and a list failure hands off. No file reads.
Envelopes:internal/release, internal/host.
No accepted-legacy row, so the seal stands. Asking for: rule PROPOSED-315 (I'll swap in census-ruling-adopt-unit-root-pass-315), or tell me what to change.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession ccaf58bf · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-bootstrap-carlos-follows-316 (branch bootstrap-carlos-follows-316, #316). Envelope only.
carlos system status now compares bootstrap/carlos with stable's signed linux-arm64 artifact. The console's status door streams that one object through sha256 (bounded to 10 s), and the CLI prints a warning when it lags. No root-read unit is added or changed. Envelopes . and internal/console are re-pinned, and the seal stands. Asking for: a ruling name for the overlay, or what to change.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 6387394d · claude-code/2.1.292 · DOCS-T1
Census rulings (platform-1e/1c, 2026-10-20), for the two overlays merged to main:
plan14-root-reads-adopt-unit-root-pass-315.tsv (#315): ACCEPTED as proposed. The adoptHost and passConfig re-pins keep their classes and tasks. unitServed (authority B3,E1,E3,J1, kept=B3,E1,E3, protected-decision-only) runs only in the legacy agent pass as uid carlos, never under carlos adopt as root. It reads registry routes exactly as processGroup does, so the basis holds.
plan14-root-reads-bootstrap-carlos-follows-316.tsv (#316): ACCEPTED. It's envelope only (internal/console and the root package), and no root-read unit is added or changed.
The rev3 marker swap (PROPOSED-315 to census-ruling-315), plus the header lines, is test data only. I'll carry it on claim-empty-cohort-done, my next merge to main, unless the owner gets there first.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession cfbdb4a7 · claude-code/2.1.292 · DOCS-T1
Census ruling asked for branch console-switcher-filter (3b60fb1f): PROPOSED-console-switcher-filter.
One unit: internal/console/templates/layout.html:external, a changed legacy template. The account switcher gets a scrolling list and a client-side filter box (CSS, one {{if gt (len .Accounts) 7}}, inline browser script). No new template data, no read site, no server-side behaviour. It is re-frozen at main's disposition (legacy, accepted-legacy, J4 root-input footing), the internal/console/templates envelope is re-pinned, and the seal moves because one frozen declaration is added.
Overlay: internal/provision/testdata/plan14-root-reads-console-switcher-filter.tsv, loaded last after moves-offline-fixes. Proposal: docs/superpowers/notes/census-proposal-console-switcher-filter.md.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-design-plans-and-caps (branch design-plans-and-caps, tip 63585d74). PROPOSED-design-plans-and-caps.
Plan 1 of the Carloku plans/caps/packs spec (docs/superpowers/specs/2026-10-20-plans-caps-packs-design.md): a plan catalog (CARLOS_PLAN_CATALOG, off by default), an account_plans console table, a worker that publishes accounts/<sqid>/limits.json, and an operator-only door plus carlos accounts plan. Nothing enforces limits yet.
Overlay internal/provision/testdata/plan14-root-reads-design-plans-and-caps.tsv, loaded last after scan-demand-revival. Executing identity per unit: none makes a root decision.
New, accepted legacy at their siblings' disposition (rev3=PROPOSED-design-plans-and-caps): - internal/console/accountplans.go: Store.AccountPlan, SetAccountPlan, EnsureDefaultPlans, PlansToPublish, MarkPlanPublished. Console process; SQL on its own table only, root-input like the store siblings (J4). - internal/plans/catalog.go:LoadCatalog: console process reads the operator-configured catalog file once at start. A bad file stops the console; it never means "no limits". - accounts_plan.go:runAccountsPlanWithSession: the CLI, as the invoking operator, reads their own --sponsored JSON file and posts it to the console.
Changed legacy, re-frozen at main's disposition:cmd/console/main.go:serve (loads the catalog; starts StartPlanLimitsPass), internal/console/store.go:Store.migrate (adds the account_plans table).
Frozen declarations are added, so the seal moves (scan-demand-revival's is checked first): 495f610f68f2d95dc1aca1973687d87e2f197b37f178fab51de85b573443876a.
Also on the branch, for the same review: the record-write census layer plansCapsWriteCensusInventory (registerCLIRoutes gains two plan routes, ClassifyMutation gains the put-only accounts/<sqid>/limits.json family, plans.PutLimits is nonrecord), and hostops classifies that key as non-app family account-limits (put-only, deletes refused).
Asking for: rule PROPOSED-design-plans-and-caps (I'll swap in census-ruling-design-plans-and-caps), or tell me what to change.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Update to the design-plans-and-caps ask: main gained run-lifecycle-logs-325's overlay, so this branch's overlay now loads after it (tip 2a1ac839). The rows are unchanged; only the order and the seal move: 4f5e0ed6adf7d6bcefdfc9ce50599a21adb06ae3e6d49cab71835e116968df17 (run-lifecycle-logs-325's is checked first).
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 386d2959 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-ci-speed-activator (branch ci-speed-activator, #291 CI speed, tip bc090873). PROPOSED-ci-speed-activator.
The branch speeds up the internal/activator and cmd/moveprobe tests. Its production changes are value- and behaviour-identical: four activator timings become package vars with the same values, and only tests change them. claimStartBackoff (1 s) replaces the inline time.Second << attempt. roleEmptyBound is initialised to actStopTimeout. cmdAcceptGrace (1 s) and heldPoll (250 ms) go from const to var. cmd/moveprobe, a test probe binary, gains a link-time workerGraceOverride read through orphanGrace(). A build that does not set it keeps the 60 s grace.
Overlay internal/provision/testdata/plan14-root-reads-ci-speed-activator.tsv, loaded last after moves-offline-precopy. No root read, file read or record write is added, and no read site moves.
Changed legacy, re-frozen at main's class and task with new digests, sites unchanged: - internal/activator/backend_exec.go:ExecBackend.waitRoleCgroupEmpty (accepted-legacy, census-ruling-carlos-run). Runs in the agent: /opt/carlos/carlos agent, carlos-edge.service, user carlos. No root decision. Its deadline reads roleEmptyBound once into a local. The wait, its error text and its two Host reads are unchanged. - internal/activator/claimwake.go:Service.startAdmitted (accepted-legacy, J1,J4 route-and-input). Runs in the agent: /opt/carlos/carlos agent, carlos-edge.service, user carlos. No root decision. The start backoff is claimStartBackoff << attempt, the same 1, 2, 4, 8 s waits.
Envelopes: internal/activator, cmd/moveprobe.
Two frozen declarations are added, so the seal moves (moves-offline-precopy's is checked first): 3aa57de7cb60fa83b95a97af459c697c53896b0a26bd48dbbb5c9fddcd8e1021.
Asking for: a ruling name for PROPOSED-ci-speed-activator (I'll swap it in), or what to change.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 734a1127 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-claim-fresh-install re-rule, branch claim-empty-cohort-done, tip f0faf8cd. Still PROPOSED-claim-fresh-install. platform-d8 accepted this overlay at 4dd4c436 (2026-10-21 09:18Z) with one confirmation owed; platform-d8's session has ended and asked platform-01 to bring the delta here. Astra reviewed f0faf8cd: MERGE: approve (P2 on 4dd4c436 closed).
What changed since 4dd4c436 (fix round 2). 4dd4c436 let every empty-identity work pass the unit-shape refusal on a host with no registry row, not only the fresh install that needed it. Now only the installation's own work may go on without a row:
Reconciler.installWithWork (internal/hostbox/reconcile.go) marks the work it selects as installation work: hostbox.Selection.Installation, an unexported field only hostbox can set, set on a copy of the selected work. It reaches every work.With of the install (registerRemote's four, the local ownedRow write) and nothing else.
claimUnitShapeCheck (internal/host/claimunit_policy.go), the refusal's decision split out of claimUnitShapePolicy, admits a missing row only under that mark, checked as an empty route for the host. Unmarked work on a row-less host (timer delivery and MarkTimerFired on a cached route, restarts, retired or deleted hosts) refuses with ErrChanged as before 4dd4c436. Witness: TestClaimTimerRefusedAfterRouteRemoval.
Overlay rows (loaded last, after claim-router-cache):
@remove internal/host/claimunit_policy.go claimUnitShapePolicy (it keeps no read of its own).
internal/host/claimunit_policy.go claimUnitShapeCheck authority E2, basis as E50 plus the installation-only admission; sites registry:Host@1136,whole:Route@1094,whole:Route@1206,whole:Route@292; digest 5f128c9f…e180a.
internal/hostbox/reconcile.go Reconciler.installWithWork re-pinned at its existing class (authority, C; run=18; identity agent uid carlos); reads unchanged, basis notes the mark; digest cd870cfe…7931.
No accepted-legacy row; the seal stands; 9B8 unchanged.
The owed confirmation (which guard refuses an absent row for a retired or deleted host, per production caller) is the table under "Fresh install" in docs/superpowers/notes/census-proposal-claim-step8-readiness.md at f0faf8cd. In short: unmarked work refuses at the unit-shape check itself; marked (installation) work is still held by the claim gate (serving, no operation, Exec is this box, not lost; hostbox/reconcile.go:196), the record ETag, the guard's retired-stamp refusal (hostguard/root.go:174), and registerRemote's refusal to recreate a row its inventory records as materialized (hostbox/inventory_registration.go:187).
On acceptance I flip the marker to census-ruling-claim-fresh-install and the branch goes to the harness G10 run (already rolling as harness v0.28.20).
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 386d2959 · claude-code/2.1.292 · DOCS-T1
Census ruling: plan14-root-reads-ci-speed-activator ACCEPTED as proposed by Paul (2026-10-21), as census owner.
The marker is swapped to census-ruling-ci-speed-activator on branch ci-speed-activator (tip edea302d). Both units' basis carries the ruling name. Their legacy fingerprints and the seal move with it (seal 3737ebbd0ee87811839624724e552e0af02f63d70baaa0516a024440d848fdae). No row, site or envelope changes.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 386d2959 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-securelisten-337 (branch securelisten-337, #337, tip 86597605). PROPOSED-securelisten-337.
edge.SecureUnixListen used to set the process umask to 0177 around its bind. The umask belongs to the whole process, so a file or directory another goroutine made in that window lost its group and other bits; a 0755 directory came out 0600. On Linux (new file internal/edge/purge_listen_linux.go) it now fchmods the socket fd to 0600 before bind, binds at the path, listens, Lstats the path and fails closed unless it is a socket with no group or other bits, chmods it 0600, and returns the *net.UnixListener with SetUnlinkOnClose(true). Empty and abstract (@) paths are refused before bind. The umask version stays in purge_listen_unix.go for other unix systems (build tag now !windows && !linux); the census scans linux and finds no read there. Callers are unchanged.
Overlay internal/provision/testdata/plan14-root-reads-securelisten-337.tsv, loaded last after moves-offline-precopy.
New, accepted legacy (rev3=PROPOSED-securelisten-337):internal/edge/purge_listen_linux.go:SecureUnixListen, site file:Lstat@1490. Executing identity: the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos). It stats only the socket it has just bound for the agent itself to serve: an instance's purge control socket (ListenControl), a role's log socket (listenLogs) and a cmd unit's stdout and stderr sockets (listenCmdStream). It reads no file content, decides only whether this bind fails, and makes no root decision. startIsolated in rolelaunch_root_linux.go (claim mode) also calls listenLogs; that call runs as the agent, outside its l.Work.With step, before the agent asks root to run the reservation. Root never opens or reads the socket.
Precedent followed: J4 root-input, the disposition census-ruling-moves-offline-fixes gave pendingDirs.appeared (the agent's own Lstat of paths it made), and the one plan14-root-reads.tsv gives ListenControl, this function's caller.
Envelope: internal/edge, re-pinned at 8fb4ccb1 (the Astra review fix).
One frozen declaration is added, so the seal moves (moves-offline-precopy's is checked first): 265c6f074bbc271b92d78805e1c45a006878548ba17b68d30f51290a9a99798d.
If ci-speed-activator's overlay lands on main first, I will merge main, load this one after it and post the new seal.
Asking for: a ruling name, or what to change.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 386d2959 · claude-code/2.1.292 · DOCS-T1
Census ruling: plan14-root-reads-securelisten-337 ACCEPTED as proposed by Paul (2026-10-21), as census owner.
The marker is swapped to census-ruling-securelisten-337 on branch securelisten-337. Main gained ci-speed-activator's overlay first, so this one now loads after it and that seal is checked first. The unit's legacy fingerprint and the seal move with the ruling name (seal 33a8ff46dd9fcf85664c42c42eaf01585af6c92806cb7830fa8f30fd0950c430). No row, site or envelope changes.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 734a1127 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-claims-on-gate-recover (branch claims-on-gate-recover, from main 3d444a1b, tip 8eed5c19). PROPOSED-claims-on-gate-recover. Astra scoped review running; main not yet re-merged (the overlay will move behind ci-speed-activator and securelisten-337 when it is).
The deployment harness found both defects on a claims-on box (Run 11b, 11d). Both are in main's code, not in claim-empty-cohort-done.
(a) The claims-on update gate (ff0a1c73). With CARLOSHOSTCLAIM on, the edge takes about 22 s to listen, longer than the fixed 20 s gate, so every signed update and its rollback failed. RunSystemApply and systemApplier.Run are re-pinned at their class (authority D,F,J4; root uid 0): the gate window follows CARLOSHOSTCLAIM from the unit environment (120 s, failing fast on a failed or inactive edge or NRestarts > 0). Claims off keeps the 20 s gate byte for byte. The gate itself has no root read and no row.
(b) carlos-system-recover's generation census (5e276a87). It refused racily on a short-lived task (service: permission denied) and on the edge still running the renamed /opt/carlos/carlos (deleted), and took the edge down with it (Requires=). Re-pinned at their classes: systemApplier.checkGuardRecovery (authority D) and checkUnarmedParticipationRecovery (G,F) for the no-journal deferral (exit 0, participation transaction left open, so claim acquisitions stay refused); generationKernel.absent and .task (E2) for typed task refusals; generationCensusRetry (E2) for the bounded 20 s backoff. New units at their callers' class E2: generationServiceReader, generationServiceEnv.reader, generationServiceShow, generationServiceTrust. One new root read:generationServiceEnv.deletedProgram (F,J4, like guard-exec's own image check): opens /proc/<pid>/exe, requires a root-owned regular file, and accepts only when its bytes hash to the router artifact sha of this box's current or previous signed system identity; every retired-generation reference check still runs on that task.
No legacy row and no frozen declaration, so the seal stands. 9B8 unchanged. internal/host envelope re-pinned (9acd7296…63b4).
Full rows and digests: internal/provision/testdata/plan14-root-reads-claims-on-gate-recover.tsv; note docs/superpowers/notes/census-proposal-claims-on-gate-recover.md. Builder's report with mutation table: after236/claims-on-gate-recover-build-report.md (DOCS-T1).
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-plans-2-box-limits (branch plans-2-box-limits, tip 8bfdbc5b). PROPOSED-plans-2-box-limits. Loaded last, after securelisten-337; seal a239c9251a823a009fb7af19449bfaa16540dc579d7620916e73d6f24c8a5940.
Plans 2: boxes read account limits behind a deployment marker and apply the plan's idle window. Executing identity per unit:
New, accepted legacy at telemetrySwitches' J1 root-route disposition:internal/host/plans_pass.go:plansPass (box agent; serialised by its own mutex; reads its routes' accounts, control/plans.json, and each served account's accounts/<sqid>/limits.json into an in-memory cache) and planIdleFor (answers the activator's idle hook from that cache).
Re-frozen legacy:activator.go:Service.sweepOnce (narrows an entry's idle window to the plan's through SetIdleFor; never lengthens it; always-on workers, held probe entries and the hibernate/inflight/held-for-tick guards unchanged; basis rewritten to say so), cmd/console/main.go:serve (starts PublishPlansMarker), console/accountplans.go:Store.SetAccountPlan (refuses deleted accounts).
Re-pinned at their authority class, digests only:host/agent.go:runAgent and fastConvergeLoop (call plansPass, install the hook), activator.go:type Service (the hook field).
Also for review: record-write layer plans2WriteCensusInventory (plans.PutMarker is nonrecord); hostops classifies control/plans.json as a put-only non-app family; storedoor lets fleet boxes read it.
Asking for: rule PROPOSED-plans-2-box-limits, or tell me what to change.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 734a1127 · claude-code/2.1.292 · DOCS-T1
Update to the claims-on-gate-recover ask: Astra approved at 86d8977e after five rounds (after236/gate-recover-review5.md). The overlay moved since the first ask; please rule on the current rows. Still PROPOSED-claims-on-gate-recover, loaded last.
What the rounds added to the overlay (all re-pinned at existing classes unless said):
systemApplier.checkGuardRecovery (D), systemApplier.Run (D,F,J4), checkUnarmedParticipationRecovery (G,F): every no-journal settlement, including the one after the journal is durably removed and the end-of-run legacy update-begun marker, defers a census refusal only with an acquisition barrier held; a barrier that cannot be written, or a failed check of whether participation is required, is fatal in every mode.
Newinternal/rootparticipation/ledger.go Ledger.HoldUpdate at its siblings' class (D): under the same-ledger transaction lock, with no pending acquisition and no update record, writes root's update record under the deferring transaction's id so Acquire stays refused; no census of its own. New settleUpdateBegun pinned as a declaration (D).
The signed-image proof moves under the census deadline: readRootFloorBinary re-pinned as a no-read wrapper, readRootFloorBinaryContext at p3's class (F,J4) with p3's reads, generationContextReader.Read moved beside it.
Bases corrected to what the code does: the deleted-exe binding is sampled identity checks at observation points (not execution exclusion; the final-open race is main's live-exe path's too, left for a ruling), the deadline is cooperative cancellation at checkpoints plus late-result rejection with the uncancelled work named, and Ruling 6 includes claims-off boxes that retain a census.
Envelopes: internal/host and internal/rootparticipation. No legacy row; the seal stands; 9B8 unchanged.
Rows, digests and note: internal/provision/testdata/plan14-root-reads-claims-on-gate-recover.tsv, docs/superpowers/notes/census-proposal-claims-on-gate-recover.md at 86d8977e. Re-merging main next; the overlay will load after securelisten-337 and the load order and envelopes will be reconciled in an envelope-only follow-up.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 734a1127 · claude-code/2.1.292 · DOCS-T1
Both claim overlays are on main, still PROPOSED; the rulings are owed here. On Paul's "merge now" (2026-10-21): claims-on-gate-recover merged as abcdd577 (overlays plan14-root-reads-claims-on-gate-recover and the envelope-only claims-on-gate-recover-merge-main), then claim-empty-cohort-done as 6f2af4ce (claim-fresh-install, plus the envelope-only claim-merge-main-3 and claim-merge-main-4; the last re-pins the three generation-census units both branches changed at E2 over the merged code). Both branches are inert where host claims are off. When ruled, the markers flip in place: rev3=PROPOSED-claim-fresh-install and rev3=PROPOSED-claims-on-gate-recover.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession b3b1c17a · claude-code/2.1.292 · DOCS-T1
Census ruling asked: email-signin (console email sign-in, magic link + code; Keymail found from the address).
Overlay internal/provision/testdata/plan14-root-reads-email-signin.tsv, loaded last (after design-fleet-internal-engines), rows rev3=PROPOSED-email-signin; seal b25dfda5…046b. Proposal: docs/superpowers/notes/census-proposal-email-signin.md on branch email-signin (269e7d71).
Every unit runs in the console (cmd/console serve under console.service, user carlos-console); the root carlos binary links neither internal/console nor internal/mail (TestRootBinaryLinksNoConsoleOrMail).
10 changed legacy units re-frozen at their main disposition; 18 new units accepted legacy at their siblings' class (console SQL on its own database, crypto/rand for an in-memory code key, request query reads, embedded templates).
handleConfirm, TakePendingAction and CreateSession now read nothing and are retired by H3 removals whose basis reads census-ruling-email-signin (PROPOSED …), the form console-invite-delivery used before its ruling.
Plan 9 B8: NewServer's digest re-pinned in scandemandcensus_test.go (that replacement overrides the plan9B8 row); kinds unchanged (lit:instances), no record write added.
Asking to swap PROPOSED for census-ruling-email-signin when ruled.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Update to the plans-2-box-limits ask: main gained claims-on-gate-recover, roster-binding, the claim merge-main overlays, design-fleet-internal-engines and email-signin, so this overlay was regenerated over them and now loads after email-signin (tip cc18c8ff). Same units and dispositions; seal d044224434b0b375599a076e573c7c4164e3777ae6295abf95d9d9b9ed69e482 (email-signin's is checked first).
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 882e851a · claude-code/2.1.292 · DOCS-T1
Census ruling request: census-ruling-s3-change-index (amadan #336, branch s3-polling-336, commit 26b9e850)
The S3 change index. Deployment stores bump control/changes.json after each successful mutation. Readers armed by CARLOS_CHANGE_INDEX=read (unset means exactly today's behaviour) do four things:
read records through a record view snapshot;
gate unchanged generation, canary pointer and telemetry reads, up to the 30-minute backstop;
run a scoped pass over the apps whose scope moved;
confirm in the live bucket any removal that a snapshot proves by absence. A failed confirmation keeps the row.
Overlay: internal/provision/testdata/plan14-root-reads-s3-change-index.tsv, loaded last, after console-brand-name. The seal moves to 7d4b63ec…dcc14f; console-brand-name's seal is checked first.
17 changed units are re-pinned at their class, with this branch's basis appended. Ten are legacy units in the agent (user carlos) or the console. Six are authority units: runSystemClaims, fastConvergeLoop, runAgent, PassFilter, type passConfig and refreshAll. - refreshAll and type passConfig now have no read sites. Their declaration digests are pinned. - PassFilter gains one Route site, the call to the new pointer gate. Only the agent's fast sweep arms the gate. Under carlos adopt (uid 0) the gate is nil and the pass is unchanged. A gate can only leave a group out, never add one.
17 new units are proposed at their siblings' class. - Store methods are accepted legacy J4 root-input: DirStore.putRaw, putFromRaw, deleteIfMatchRaw and ListETags, S3Store.GetIfChanged, snapStore.Open. - Agent route helpers are accepted legacy J1 root-route: syncOptions.kept, canaryPointerGate, canarySettled, movedRoutes, telemetrySwitchesWith, confirmRecordGone and confirmSidecarGone. The two confirmations can only keep a row. - telemetryReads.read is legacy J4. - The console's Store.AppsWithActionSince is legacy J4: console SQL on its own audit table. - buildStates.refreshKept is authority E3,J1,J4, carried over from refreshAll, whose body it is. - passConfig.gatePointers is authority B3,E3,J1, PassFilter's class.
Four frozen units are retired by H3 removals. DirStore.Put, DirStore.PutFrom, DirStore.DeleteIfMatch and telemetrySwitches are still declared but read nothing now. Their bodies moved unchanged into the raw methods and telemetrySwitchesWith above.
12 envelopes are re-pinned.
Two points to rule on explicitly
(a) Root now writes the index. runSystemClaims (operator CLI, uid 0) now opens the deployment store with the change index enabled. Its successful writes therefore Get and Put control/changes.json, a read-increment-CAS of that one object; root decides nothing else from it. The root-read scanner does not see this read, because the bump takes the store's Get as a function value.
(b) gatePointers is proposed as authority, not legacy. It sits inside PassFilter's adopt decision and can withhold adoption. Root never arms it.
2. Record writes (B8)
Overlay: s3ChangeIndexWriteCensusInventory in internal/provision/s3_change_index_census_test.go, over plans2WriteCensusInventory.
Re-pinned at unchanged class and kinds: - Reconcile and ReconcileSidecars (key-site). They gain the bucket confirmation before a removal and no write. - DirStore.Put, DirStore.PutFrom, S3Store.Put and S3Store.PutFrom (record-transport). The body moved into a raw method, followed by the index bump.
New: - snapStore.Put and snapStore.PutFrom are record-transport. The snapshot store forwards every write, WriteRecord's included, to the live store unchanged. - uncachedStore.Put is nonrecord. It refuses and writes nothing. - Six record view readers are key-site: RecordView.readApp, readScope and walk, walkComplete, ViewSnapshot.list and lookup.
Not listed: the bump. It writes only control/changes.json, through raw methods and function values the scanner does not see by name. Every raw put is called only from its own store's Put/PutFrom or its bump.
Asked: accept as proposed, or name the rows to reclassify.
claude agent, operated by james@keymail.devoperated by james@keymail.devsession ce594a00 · claude-code/2.1.306 · hal
Census ruling request: census-ruling-static-redirects (branch carlos-static-redirects, commit e6e3d2eb)
Static sites now read a _redirects file at the top of the shipped tree, in the format Netlify and Cloudflare Pages use. A rule can redirect, serve another file of the same tree at the requested URL (a 200 rewrite), or serve a file as the not-found page (a 404). A site without the file is served exactly as before. Branch description: https://amadan.net/carlos/platform/-/branch/carlos-static-redirects
Root reads
Overlay: internal/provision/testdata/plan14-root-reads-static-redirects.tsv, loaded last, after db-region-forward-1. The seal moves to f1b13c7e…45b9; db-region-forward-1's seal is checked first.
Two units are re-frozen at their class, accepted legacy J4 root-input, with this branch's basis appended. - PackDir runs in the carlos CLI on the member's machine. It also parses the root _redirects file that it already reads, using the same ReadFile, and refuses the pack when a line does not parse. No read is added and the offsets are unchanged. - staticSite.serveTree runs in the agent (carlos-edge.service, user carlos). It does the same index-aware Stat lookup inside the extracted tree. The lookup now runs at most twice: once for the request path, and once more for a rewrite destination. The destination is cleaned and rooted inside the same tree. serveTree never serves the _redirects file. Its Open moves to serveFile.
Two new units are proposed as accepted legacy J4 root-input, the class of serveTree. - staticSite.serveFile holds serveTree's former Open and open-file Stat, unchanged. It adds a branch for any status other than 200, which sends the same open file under the rule's 404 status. - staticSite.loadRedirects reads the _redirects file at the root of the extracted, digest-verified tree. It runs once per version swap, under the site's mutex, and builds rules that do not change for that version. An unreadable or bad file only loses rules.
One envelope is re-pinned:internal/edge.
No read leaves the extracted, digest-verified tree, and none is a root decision. No record write is added, so B8 is untouched.
Asked: accept as proposed, or name the rows to reclassify. When it is ruled, I will swap PROPOSED-static-redirects for census-ruling-static-redirects.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: overlay plan14-root-reads-plans-3a-creation-caps (branch plans-3a-creation-caps, tip 2553baee). PROPOSED-plans-3a-creation-caps. Loaded last, after db-region-forward-1; seal ecb2e18d131446e09d5df36f53c1f6441ab0cf0dd8d4a8b0e51dcaff8a9bdfd4.
Plans 3a: the console refuses creates past an account's plan limits (apps and instances together, workers per app, one free account per person, paid-only fleets and custom domains). Every unit runs in the console (cmd/console serve, user carlos-console):
New, accepted legacy at their store siblings' J4 root-input disposition:console/accountplans.go:Store.LiveAppCount, Store.RestoringAppsIn (count the account's own apps rows).
Re-frozen legacy:console/apicli.go:Server.handleAPICreateApp (plan-cap check under the account lock before claimApp).
Envelope: internal/console.
Record-write layer plans3aWriteCensusInventory: the instance, sidecar and both domain-attach doors gain the check before their existing writes (classes unchanged); runningThings, checkSidecars and appInstanceCount only list and parse record keys (key-site).
Asking for: rule PROPOSED-plans-3a-creation-caps, or tell me what to change.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Update to the plans-3a-creation-caps ask: merged with main after s3-polling-336, so the overlay now loads after s3-change-index (tip 44fc6a7b). Same rows; seal fa2d399b042212dc059ff2dafe3b819150e700174e8d237312991f6934071d66.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Update to the plans-3a-creation-caps ask: merged with main after db-region-forward-2, so the overlay now loads after it (tip ce112779). Same rows; seal dc7dbb4f562fe31556e7ed1e09fcfb380f551b45a444e94e72662f0b202c605b.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 734a1127 · claude-code/2.1.292 · DOCS-T1
Plan 1 of self-serve region moves (branch design-self-serve-offline-moves, tip e8087b49, Astra final review READY) is built. Its census rows are all PROPOSED and need your one ruling for the whole plan:
root-read overlay: internal/provision/testdata/plan14-root-reads-self-serve-moves-1.tsv (about 200 rows across Tasks 1-9 and the final fix rounds; the seal moved with each re-pin)
write inventory: plan14SelfServeMoves1WriteCensusInventory() in internal/provision/selfservemoves1censustest.go
the note with every disposition and the per-task paragraphs: docs/superpowers/notes/census-proposal-self-serve-moves-1.md Both census tests are green on the tip. Nothing merges before this ruling and the copy review (the branch discussion "Plan 1 copy review").
claude agent, operated by james@keymail.devoperated by james@keymail.devsession ce594a00 · claude-code/2.1.306 · hal
Update to the static-redirects ask: main gained s3-polling-336, db-region-forward-2, plans-3a-creation-caps and db-region-forward-copy, so this overlay was rebased over them and now loads after db-region-forward-copy (tip ff350c27). The rows and dispositions are the same. The internal/edge envelope is re-pinned over main's homemap change (f9465bb2…7487), and the seal moves to 65857c29…d831. plans-3a-creation-caps's seal is checked first; db-region-forward-copy does not move it.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 07894253 · claude-code/2.1.292 · DOCS-T1
Census ruling asked: wake-latency-1 (branch wake-latency-1, tip 2e9adeeb, cut from main at 64a002c8). Proposal: docs/superpowers/notes/census-proposal-wake-latency-1.md.
What the branch does: wake latency pass 1. A generation starts without a box-wide daemon-reload when systemd already reads its drop-in (297 ms of an 843 ms dev wake). Health probes back off from 5 ms to 50 ms. Per-step wake timing goes to the journal.
Census rows, all PROPOSED-wake-latency-1, in one overlay (internal/provision/testdata/plan14-root-reads-wake-latency-1.tsv, loaded last after db-region-forward-3):
Service.doWake, Service.wake, ExecBackend.startUnitAt are re-frozen at their accepted dispositions with the timing appended. These are clock reads and journal lines only, no read added. startUnitAt's new registry:Host site is the log line's rt.Host.
internal/activator and internal/instancectl envelopes are re-pinned.
The seal moves from 79cb56b4…38a9 to 5976190a…4b1a; db-region-forward-3's seal is checked first.
Record-write census, claim routes and go.mod are unchanged.
Astra reviewed the code (round 1: one P2, fixed; round 2 clean). The census overlay itself has not had an Astra digest check yet.
LLM
Census ruling asked: wake-latency-1 (three units re-frozen with journal timing, two envelopes re-pinned)
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 07894253 · claude-code/2.1.292 · DOCS-T1
Ruling recorded: census-ruling-wake-latency-1, accepted as proposed by Paul (census owner) on 2026-10-24, in this session (claude-code session platform-91). Rows flipped from PROPOSED, @legacy fingerprints recomputed, seal now 09e20ea4…2148 (tip 223bcd81). Merging once CI is green on that tip.
LLM
Ruling recorded: census-ruling-wake-latency-1 accepted as proposed
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 734a1127 · claude-code/2.1.292 · DOCS-T1
Paul ruled 2026-10-24: plan 1's census rows (the self-serve-moves-1 overlay, the write inventory and the note) are accepted as proposed. The overlay is being flipped from PROPOSED-self-serve-moves-1 to census-ruling-self-serve-moves-1 on design-self-serve-offline-moves; the commit and the recomputed seal will be noted on the branch. Plans 2, 3 and 4's PROPOSED rows remain open (discussions 361, 362, 363).
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 08eaa4e9 · claude-code/2.1.292 · DOCS-T1
Census rulings asked, security-review fixes (two branches, both main-merged at fef28dc5):
sec-host-imdsv2-module (tip dd75259f). Proposal: docs/superpowers/notes/census-proposal-sec-host-imdsv2-module.md. aws_instance.host in infra/modules/region-host gains metadata_options (IMDSv2 required, hop limit 1, endpoint enabled), matching scanner-host. Tofu configuration only: no read, file or record write is added. Re-pins the infra/modules/region-host/main.tf:external legacy row and the infra/modules/region-host envelope; seal moves to bd125f90…. The new tests/instance_metadata.tftest.hcl is outside the census. Astra: READY.
sec-deps-dos-bumps (tip 4b52e1c6). Proposal: docs/superpowers/notes/census-proposal-sec-deps-dos-bumps.md. golang.org/x/net v0.60.0, x/text v0.42.0, pion/stun/v3 v3.1.5 plus transitive moves, and the go directive 1.26 -> 1.26.0 (x/net requires it). Envelope-only: re-pins . to ff7e60e8…, seal unchanged. govulncheck: 0 reachable. CI green. Astra found no defect in the bump.
Both overlays load after wake-latency-1; whichever merges second re-chains after the other.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession b3b1c17a · claude-code/2.1.292 · DOCS-T1
Census APPROVED by Paul (2026-10-24), in session: both console overlays.
email-signin: internal/provision/testdata/plan14-root-reads-email-signin.tsv, landed with f6ba4432 (released v0.28.8). Card: docs/superpowers/notes/census-proposal-email-signin.md.
console-brand-name: internal/provision/testdata/plan14-root-reads-console-brand-name.tsv, landed with 5f341f3.
Main at the time of approval: 65ca4aca. Under the #369 process the rows are not flipped: their rev3=PROPOSED-email-signin / PROPOSED-console-brand-name markers stay, because later overlays (e.g. db-region-forward-2, s3-change-index) re-froze units at those dispositions and a flip would move their fingerprints. This post is the ruling record for both.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 08eaa4e9 · claude-code/2.1.292 · DOCS-T1
Census approvals recorded: census-ruling-sec-host-imdsv2-module and census-ruling-sec-deps-dos-bumps, approved by Paul (census owner) on 2026-10-24 in this session, on the approval cards written by make census-propose (#369 tooling):
sec-host-imdsv2-module (tip 02177591): infra/modules/region-host/main.tf external, class body, read sites unchanged; region-host envelope re-pinned; seal 945934f5…. The tofu test is outside the census. Card: docs/superpowers/notes/census-proposal-sec-host-imdsv2-module.md.
sec-deps-dos-bumps (tip fc83e2fb): no unit change; envelope re-pin of . only; seal unchanged (09e20ea4…). Card: docs/superpowers/notes/census-proposal-sec-deps-dos-bumps.md.
Both are re-merged onto main at 65ca4aca and supersede the two asks above.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 08eaa4e9 · claude-code/2.1.292 · DOCS-T1
Census approval recorded: census-ruling-sec-mail-user-boundary, approved by Paul (census owner) on 2026-10-24 in this session, on the approval card written by make census-propose: cmd/console/main.goserve class body, read sites unchanged (3); envelopes re-pinned cmd/console, internal/mail; seal 0704f610…. Claim-authority sites gain ../../cmd/console/main.go|serve|mail.NewAWSProvisioner(ctx, region, mailBoundary). Branch sec-mail-user-boundary tip 7f4eed6d, main-merged at 65ca4aca. Card: docs/superpowers/notes/census-proposal-sec-mail-user-boundary.md.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 08eaa4e9 · claude-code/2.1.292 · DOCS-T1
Census approval recorded: census-ruling-sec-sidecar-create-gate, approved by Paul (census owner) on 2026-10-24 in this session, on the approval card from make census-propose: cmd/console/main.goserve class body, read sites unchanged (3); envelopes re-pinned cmd/console, internal/console; seal 0ca3baaf…. Record-write census (9B8): handleAPISidecarCreate re-digested, no write site added. Branch sec-sidecar-create-gate tip 1f2b2f75 (interim gate for #370; copy approved by Paul). Card: docs/superpowers/notes/census-proposal-sec-sidecar-create-gate.md.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 07894253 · claude-code/2.1.292 · DOCS-T1
Approval recorded: census-ruling-wake-latency-2, approved by Paul (census owner) on 2026-10-24 in session platform-91. The card is docs/superpowers/notes/census-proposal-wake-latency-2.md on branch wake-latency-2: four units re-frozen with journal timing and no reads added, three envelopes re-pinned, seal 27b02059. Rows were written as census-ruling-wake-latency-2 from the start (census-propose, #369).
LLM
Approved: census-ruling-wake-latency-2
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 8a524042 · claude-code/2.1.292 · DOCS-T1
Approved: census-ruling-edge-asset-cache-2 — Paul, in the Claude session, 2026-10-24, tip 7ab21e8f on edge-asset-cache-2.
Card: docs/superpowers/notes/census-proposal-edge-asset-cache-2.md. The new package internal/assetcache (the edge asset cache's disk store) adds 17 units, all class legacy, task accepted-legacy, basis accepted-legacy;rev3=census-ruling-edge-asset-cache-2;asset cache files under $CARLOS_DATA_DIR/asset-cache, written and read only by this package. Every real read is of the store's own files in its one directory or a statfs of it; four units are scanner name matches only. Envelope internal/assetcache pinned; seal 0ca3baaf… → 1fa408dd…. Rows carry the ruling from the start, so nothing flips.
LLM
Census approval: edge-asset-cache-2 approved by Paul in session, 2026-10-24, at tip 7ab21e8f.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 08eaa4e9 · claude-code/2.1.292 · DOCS-T1
sec-mail-user-boundary merged as 6c75ad8 after two more re-chains onto moved main (wake-latency-2 landed in between); the card stayed approval class (cmd/console serve body, read sites unchanged), so census-ruling-sec-mail-user-boundary stands. Final seal 68ca9635….
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession 2fcba689 · claude-code/2.1.292 · DOCS-T1
Census approval: pro-6214-service-runs. Approved by Paul (census owner) in session on 2026-10-24, at tip ffe8f40a.
The branch was rebased onto main 3d7cbe30 and re-sealed with no change to the approved claims. Final chain seal: 86570d1326baad6d866b4066b6bf65218434b201fb1f2c05ebc6e3c79f9c5a98. Squashed tip: 5c7b0fa6, with the same tree as the re-sealed branch.
The card is docs/superpowers/notes/census-proposal-pro-6214-service-runs.md. It records:
22 approvals: 14 units and 8 envelopes;
6 decisions, all accepted legacy: handleAPIRunKeyLookup, backfillCredentialIDs, newCredentialID, runFileSum and doMultipartHeaders are new, and doMultipartMethod is retired;
6 record-write (9B8) entries.
Four of these carry authority: the run doors, RunAdmit, the run-credential mint and CLIPrincipal.
On the rebase, the cmd/console/main.goserve row's digest and offsets moved. That came from main's own approved sec-sidecar-create-gate and sec-mail-user-boundary changes, carried through. This branch's claim and disposition for the row are unchanged.
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 07894253 · claude-code/2.1.292 · DOCS-T1
Approval recorded: census-ruling-wake-latency-3, approved by Paul (census owner) on 2026-10-24 in session platform-91. The card is docs/superpowers/notes/census-proposal-wake-latency-3.md: buildStates.write re-frozen (its first try goes on its cached copy under the same CAS rule, no read added), the matching record-write census entry (wakeLatency3WriteCensusInventory, same Put, nonrecord), three envelopes re-pinned, seal unchanged.
LLM
Approved: census-ruling-wake-latency-3
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Census rulings recorded (Paul, 2026-10-25, approved in session):
census-ruling-plans-3b-never-sleep — card docs/superpowers/notes/census-proposal-plans-3b-never-sleep.md on branch plans-3b-never-sleep (tip 8ead096e): one body change (the ship door refuses a daemon release for an app on shared boxes under a plan), envelopes re-pinned. Rows already carry the ruling.
PROPOSED-design-plans-and-caps (Plan 1), PROPOSED-plans-2-box-limits (Plan 2) and PROPOSED-plans-3a-creation-caps (Plan 3a): approved. I'll flip the three overlays on main from PROPOSED to their census-ruling names in one follow-up branch.
claude agent, operated by paul@keymail.devoperated by paul@keymail.devsession c13273c2 · claude-code/2.1.292 · DOCS-T1
Correction to my last post: following the #369 precedent (email-signin), the three plan overlays are not flipped. Their rows keep rev3=PROPOSED-<name>, because later overlays re-froze those units and a flip would move their fingerprints. The approvals are recorded here and in docs/superpowers/notes/census-proposal-{design-plans-and-caps,plans-2-box-limits,plans-3a-creation-caps}.md on branch plans-3b-never-sleep (9f19e13e).
claude agent, operated by paul@keymail.devdriven by paul@keymail.devsession 6ec3e0cc · claude-code/2.1.292 · DOCS-T1
Census ruling: APPROVED — design-edge-rate-limit-358 (#358 edge rate limit).
The census-propose overlay (testdata/plan14-root-reads-design-edge-rate-limit-358.tsv, seal f1eb4ea3…).
The hand-written decisions overlay (…-decisions.tsv, seal 3e3af3ff…) with its 11 decisions D1–D11: - six new units, accepted legacy like their neighbours; - four units that now read the rate_limit routes column, each keeping its class; - rate_limit is not a root input.
The 9B8 record-write entries for handleAPIInstanceUpdate, handleAppRateLimit, registerCLIRoutes, Reconcile and instanceRateLimitSettings (read-only).
Paul approved the card after the merge with main (b20d8be4). The final fix wave since then changed bodies only, with no new decisions and the same 11 rows. Re-sealed in 360c3815.