carlos / platform Public
Census: db region forward, plan 1 (the box side and the wire, dark)
Status: ACCEPTED in full by the census owner on #280, 2026-10-22, as census-ruling-db-region-forward-1. Every row now carries rev3=census-ruling-db-region-forward-1, and the H3 removal names census-ruling-db-region-forward-1 (accepted by the census owner on #280, 2026-10-22). The ruling covers every row below: the H3 retirement of runQueryContext, the J1/J4 legacy rows, the diagnostic probe row, the two external unit rows, the re-frozen and re-pinned changed units (including the shared ensureSystemArmed), the 9B8 nonrecord puts and the re-pinned envelopes.
The census owner's rationale: every new read runs as the agent (carlos) or the sandboxed DynamicUser worker, not root. The only root change is ensureSystemUnits installing two fixed embedded units. The worker reads only the files the agent sent and its private scratch. SelfView's open of host.env only confirms that the sandbox hides it.
The branch is db-region-forward-1, cut from design-db-region-forward (e765d57d, which already holds main at 5f341f33). It builds plan 1 of docs/superpowers/specs/2026-10-22-db-region-forward-design.md (rev 6): internal/dbquery (the query runner moved out of db.go), internal/dbreads (the wire, the box's db-reads agent and the db-read worker), dbdoor planning over any replica reader, the two carlos-dbread units installed and armed by ensureSystemUnits, and the db-read-1 capability. Nothing runs unless a console asks, and no console asks until plan 2.
It adds one root-read overlay, internal/provision/testdata/plan14-root-reads-db-region-forward-1.tsv, loaded last in TestPlan14RootReadCensus, after console-brand-name (the overlay main loads last at 5f341f33). Its record-write entries are layered on plans2WriteCensusInventory in internal/provision/db_region_forward_census_test.go.
Root reads
Executing identities, named once:
- the agent:
/opt/carlos/carlos agent,carlos-edge.service, usercarlos. - the worker:
carlos system db-worker,carlos-dbread@.service, aDynamicUserwithPrivateNetwork=yes,RestrictAddressFamilies=AF_UNIX, its ownPrivateTmp,/data,/var/lib,/opt/carlosand/run/carlosempty,/etc/carlosinaccessible. It reads only the files the agent sent and its own scratch. - the CLI:
carlos db queryon a person's machine, as the person.
| unit | change | executing identity | proposed disposition | |---|---|---|---| | db.go runQueryContext | still declared; reads nothing now: a one-line call to dbquery.RunContext | the CLI | retired: @remove plus @removed ... H3 census-ruling-db-region-forward-1, the form the carlos-run H3 removal used | | internal/dbquery/dbquery.go RunContext | new: runQueryContext's body moved unchanged but for the immutable=1 open option the worker passes | the CLI and the worker; neither is root | legacy, accepted-legacy, J4 (basis=root-input, main's footing for the same body), both callers named | | internal/dbreads/agent.go nonce | new: 16 bytes from crypto/rand for picked's attempt nonce (the scanner reads rand.Read as a read) | the agent | legacy, J1/J4 route-and-input, as the offline move's agent units | | internal/dbreads/read.go sendFile | new: reads one planned LTX file whole from the box's own region replica (read-only reader), between identity checks A and B, and frames it to the worker undecoded | the agent | legacy, J1/J4 route-and-input | | internal/dbreads/seal.go open | new: AES-GCM open of a sealed chunk or summary (cipher.AEAD.Open, read by the scanner as Open) | the CLI (plan 2); no production caller in plan 1 | legacy, J4 | | internal/dbreads/worker.go SelfView | new: /proc/self/net/dev, a listing of /data, an open of /etc/carlos/host.env, only to report what the sandbox hides | the worker | legacy, J4 | | internal/dbreads/worker.go ServeWorker | new: stats the restored copy in its private /var/tmp for the size cap | the worker | legacy, J4 | | internal/dbreads/worker.go receiveFile | new: creates each planned file, exclusively, under its private /var/tmp | the worker | legacy, J4 | | internal/host/dbreads_linux.go dbReadUnits | new: systemctl list-units 'carlos-dbread@*.service', readable without privilege, for the orphan rule | the agent | legacy, J4 | | internal/host/dbreads_linux.go varTmpFree | new: one Statfs of /var/tmp for the disk reservation | the agent | legacy, J4 | | internal/host/units/carlos-dbread.socket external | new unit file | written by root's ensureSystemUnits; bound by PID 1, owned by carlos | legacy external unit, as carlos-instance-cmd@.service took | | internal/host/units/carlos-dbread@.service external | new unit file | the worker's unit | legacy external unit | | internal/dbreads/agent.go Agent.probe | new: the readiness probe, a hello on its own worker connection; the scanner names no read in it, so this is a declaration row | the agent | diagnostic, J4: decides only whether the box publishes db-read-1 | | internal/host/edgesfile.go edgesFileLoop | changed legacy: db-read-1 joins the capabilities while the armed loop's probe passes; the published draining flag is stored for the loop; read site unchanged, offset moved | the agent | re-frozen at main's disposition (census-ruling-moves-offline) with the change appended | | internal/host/agent.go fastConvergeLoop | changed authority: the serial pass nudges the db-reads loop after the runs pass (a channel send) | the agent | re-pinned at main's B3 | | internal/host/agent.go runAgent | changed authority: armDBReads beside armRunsPass in the activator's Configure step | the agent | re-pinned at main's B,C,D,F | | internal/host/systemunits.go ensureSystemUnits | changed authority: installs the two units, asks one more is-active, arms the socket (never the template); the armed list is now ensureSystemArmed, which the claim census reads too | root (the adopt pass) | re-pinned at main's F,J4 | | system.go runSystem, systemVerb | changed declarations (no reads): dispatch carlos system db-worker | the operator CLI and the worker unit | re-pinned at main's authority rows |
Scanner notes for the ruling:
internal/dbdoorListLevel,PlanFrom,finishPlan,listing.*andRestoreLocal, which the plan expected to need rows, are not named by the scanner (their I/O goes through replica-client methods it does not match), so they have none. Their package envelope is re-pinned.internal/console/apidb.golistReplicaLevelanddbClassRefusalnow delegate todbdoor.ListLevelanddbreads.ClassRefusal; the scanner names neither, and theinternal/consoleenvelope is re-pinned.
Envelopes re-pinned: ., internal/console, internal/dbdoor, internal/dbquery (new), internal/dbreads (new), internal/dbreads/dbreadstest (new), internal/host, internal/host/units.
Seal: console-brand-name's 78e18e222a8178bbe16b638c5e3811b8f64c4c2664ffd6649eb4273e72fae24e is checked first; with this overlay's 12 frozen declarations it becomes fc73854854f9e75d122ebd0eacf330d126201aa9d5c4295c634cc1c204a9168d with the accepted ruling's markers (it was 20d70361... while proposed, and d57f153e... before the round 1 fixes below).
Record writes (9B8)
| site | class | why | |---|---|---| | internal/dbreads/agent.go Agent.elect | nonrecord | the create-only db-reads/<id>/picked in the deployment bucket | | internal/dbreads/chunks.go putCreateOnly | nonrecord | create-only sealed chunks and result.json under db-reads/<id>/ | | internal/dbreads/dbreadstest/dbreadstest.go Submit | testsupport | test support imported only by _test.go files: the console's two creates for a test with no console, as leasetest's sites are |
No record writer and no Delete site is added.
Not in this plan
The console route (registerCLIRoutes key-site, claim-routes.txt) and its creates (request.json, the queue entry, cancel) are plan 2's.
Round 1 fixes (Astra, 1760ea5f)
Three rows changed with the fixes; each keeps its disposition and appends a round 1 clause:
| unit | change | disposition | |---|---|---| | internal/host/units/carlos-dbread.socket external | listens at /run/carlos/dbread/worker.sock, under the /run/carlos tree every tenant unit hides (tenants run as carlos, the uid the worker serves), and is armed only where host.env arms db reads | re-frozen, legacy external unit | | internal/dbreads/worker.go ServeWorker | refuses, before writing anything, a plan whose restored-size cap is above its own LimitFSIZE or whose files total more than twice that cap | re-frozen, legacy J4 | | internal/host/systemunits.go ensureSystemUnits | arms the socket only when the installed host.env arms db reads (same rule as the capability) and stops and disables it elsewhere | re-pinned at main's F,J4 |
One read the census does not see, named for the ruling: internal/host/dbreads.go dbReadsSocketWanted reads /etc/carlos/host.env as root (from ensureSystemUnits, the adopt pass) through the readClaimUnitFile variable, which the scanner does not match, so it has no row. It reads six db-reads keys and decides only whether the db-read socket is armed; it refuses (keeps the socket dark) on anything it cannot read or parse. The claim unit settings already read the same file the same way.
The check-B fix (afterCheckB) and the deadline fix (serve) add no read the scanner names; the internal/dbreads and internal/host envelopes are re-pinned.