carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1# Census: db region forward, plan 1 (the box side and the wire, dark)
2
3Status: ACCEPTED in full by the census owner on #280, 2026-10-22, as
4`census-ruling-db-region-forward-1`. Every row now carries
5`rev3=census-ruling-db-region-forward-1`, and the H3 removal names
6`census-ruling-db-region-forward-1 (accepted by the census owner on #280,
72026-10-22)`. The ruling covers every row below: the H3 retirement of
8`runQueryContext`, the J1/J4 legacy rows, the diagnostic probe row, the two
9external unit rows, the re-frozen and re-pinned changed units (including the
10shared `ensureSystemArmed`), the 9B8 nonrecord puts and the re-pinned
11envelopes.
12
13The census owner's rationale: every new read runs as the agent (carlos) or
14the sandboxed DynamicUser worker, not root. The only root change is
15`ensureSystemUnits` installing two fixed embedded units. The worker reads
16only the files the agent sent and its private scratch. `SelfView`'s open of
17host.env only confirms that the sandbox hides it.
18
19The branch is `db-region-forward-1`, cut from `design-db-region-forward`
20(e765d57d, which already holds main at 5f341f33). It builds plan 1 of
21`docs/superpowers/specs/2026-10-22-db-region-forward-design.md` (rev 6):
22`internal/dbquery` (the query runner moved out of `db.go`),
23`internal/dbreads` (the wire, the box's db-reads agent and the db-read
24worker), `dbdoor` planning over any replica reader, the two
25`carlos-dbread` units installed and armed by `ensureSystemUnits`, and the
26`db-read-1` capability. Nothing runs unless a console asks, and no console
27asks until plan 2.
28
29It adds one root-read overlay,
30`internal/provision/testdata/plan14-root-reads-db-region-forward-1.tsv`,
31loaded last in `TestPlan14RootReadCensus`, after `console-brand-name` (the
32overlay main loads last at 5f341f33). Its record-write entries are layered
33on `plans2WriteCensusInventory` in
34`internal/provision/db_region_forward_census_test.go`.
35
36## Root reads
37
38Executing identities, named once:
39
40- **the agent**: `/opt/carlos/carlos agent`, `carlos-edge.service`, user `carlos`.
41- **the worker**: `carlos system db-worker`, `carlos-dbread@.service`, a
42 `DynamicUser` with `PrivateNetwork=yes`, `RestrictAddressFamilies=AF_UNIX`,
43 its own `PrivateTmp`, `/data`, `/var/lib`, `/opt/carlos` and `/run/carlos`
44 empty, `/etc/carlos` inaccessible. It reads only the files the agent sent
45 and its own scratch.
46- **the CLI**: `carlos db query` on a person's machine, as the person.
47
48| unit | change | executing identity | proposed disposition |
49|---|---|---|---|
50| `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 |
51| `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 |
52| `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 |
53| `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 |
54| `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 |
55| `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 |
56| `internal/dbreads/worker.go` `ServeWorker` | new: stats the restored copy in its private `/var/tmp` for the size cap | the worker | legacy, J4 |
57| `internal/dbreads/worker.go` `receiveFile` | new: creates each planned file, exclusively, under its private `/var/tmp` | the worker | legacy, J4 |
58| `internal/host/dbreads_linux.go` `dbReadUnits` | new: `systemctl list-units 'carlos-dbread@*.service'`, readable without privilege, for the orphan rule | the agent | legacy, J4 |
59| `internal/host/dbreads_linux.go` `varTmpFree` | new: one `Statfs` of `/var/tmp` for the disk reservation | the agent | legacy, J4 |
60| `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 |
61| `internal/host/units/carlos-dbread@.service` `external` | new unit file | the worker's unit | legacy external unit |
62| `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` |
63| `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 |
64| `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 |
65| `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 |
66| `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 |
67| `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 |
68
69Scanner notes for the ruling:
70
71- `internal/dbdoor` `ListLevel`, `PlanFrom`, `finishPlan`, `listing.*` and
72 `RestoreLocal`, which the plan expected to need rows, are not named by the
73 scanner (their I/O goes through replica-client methods it does not
74 match), so they have none. Their package envelope is re-pinned.
75- `internal/console/apidb.go` `listReplicaLevel` and `dbClassRefusal` now
76 delegate to `dbdoor.ListLevel` and `dbreads.ClassRefusal`; the scanner
77 names neither, and the `internal/console` envelope is re-pinned.
78
79Envelopes re-pinned: `.`, `internal/console`, `internal/dbdoor`,
80`internal/dbquery` (new), `internal/dbreads` (new),
81`internal/dbreads/dbreadstest` (new), `internal/host`, `internal/host/units`.
82
83Seal: console-brand-name's `78e18e222a8178bbe16b638c5e3811b8f64c4c2664ffd6649eb4273e72fae24e`
84is checked first; with this overlay's 12 frozen declarations it becomes
85`fc73854854f9e75d122ebd0eacf330d126201aa9d5c4295c634cc1c204a9168d` with the
86accepted ruling's markers (it was `20d70361...` while proposed, and
87`d57f153e...` before the round 1 fixes below).
88
89## Record writes (9B8)
90
91| site | class | why |
92|---|---|---|
93| `internal/dbreads/agent.go` `Agent.elect` | nonrecord | the create-only `db-reads/<id>/picked` in the deployment bucket |
94| `internal/dbreads/chunks.go` `putCreateOnly` | nonrecord | create-only sealed chunks and `result.json` under `db-reads/<id>/` |
95| `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 |
96
97No record writer and no `Delete` site is added.
98
99## Not in this plan
100
101The console route (`registerCLIRoutes` key-site, `claim-routes.txt`) and its
102creates (`request.json`, the queue entry, `cancel`) are plan 2's.
103
104## Round 1 fixes (Astra, 1760ea5f)
105
106Three rows changed with the fixes; each keeps its disposition and appends a
107`round 1` clause:
108
109| unit | change | disposition |
110|---|---|---|
111| `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 |
112| `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 |
113| `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 |
114
115One read the census does not see, named for the ruling:
116`internal/host/dbreads.go` `dbReadsSocketWanted` reads `/etc/carlos/host.env`
117as root (from `ensureSystemUnits`, the adopt pass) through the
118`readClaimUnitFile` variable, which the scanner does not match, so it has no
119row. It reads six db-reads keys and decides only whether the db-read socket
120is armed; it refuses (keeps the socket dark) on anything it cannot read or
121parse. The claim unit settings already read the same file the same way.
122
123The check-B fix (`afterCheckB`) and the deadline fix (`serve`) add no read
124the scanner names; the `internal/dbreads` and `internal/host` envelopes are
125re-pinned.
126