carlos / platform Public

census: approval card for pro-6214-service-runs (run-role service credentials, keyed run create)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by claude agent, operated by paul@keymail.dev ffe8f40a4956dcfa2f04b457d3c7d0eb6ca232e2 parent f9a52e3
6 files changed, +243 −1
  • docs/superpowers/notes/census-proposal-pro-6214-service-runs.md +126 −0
  • internal/provision/plan9_b8_census_test.go +1 −1
  • internal/provision/service_runs_census_test.go +56 −0
  • internal/provision/testdata/plan14-root-reads-chain.tsv +2 −0
  • internal/provision/testdata/plan14-root-reads-pro-6214-service-runs-decisions.tsv +20 −0
  • internal/provision/testdata/plan14-root-reads-pro-6214-service-runs.tsv +38 −0

CI passed — run details

CI log
=== gate ===
.amadan/test-gate.sh
=== launchctx (1 s)
ok  	amadan.net/carlos/platform.git/launchctx	0.012s
?   	amadan.net/carlos/platform.git/launchctx/controlname	[no test files]
?   	amadan.net/carlos/platform.git/launchctx/wireid	[no test files]
=== vet (18 s)
=== gofmt (1 s)
gofmt -l .: clean
=== rest (169 s)
?   	github.com/carlosframework/platform/cmd/changelog	[no test files]
ok  	github.com/carlosframework/platform/cmd/console	3.746s
ok  	github.com/carlosframework/platform/cmd/moveprobe	11.750s
ok  	github.com/carlosframework/platform/cmd/zddprobe	0.759s
ok  	github.com/carlosframework/platform/internal/activator	58.528s
ok  	github.com/carlosframework/platform/internal/agentsock	0.029s
ok  	github.com/carlosframework/platform/internal/alerting	0.004s
ok  	github.com/carlosframework/platform/internal/analytics	0.026s
ok  	github.com/carlosframework/platform/internal/appconfig	2.798s
ok  	github.com/carlosframework/platform/internal/apperr	0.105s
ok  	github.com/carlosframework/platform/internal/applog	0.201s
ok  	github.com/carlosframework/platform/internal/awsinv	0.005s
ok  	github.com/carlosframework/platform/internal/boxchoice	0.006s
ok  	github.com/carlosframework/platform/internal/boxid	0.934s
?   	github.com/carlosframework/platform/internal/boxid/boxidtest	[no test files]
?   	github.com/carlosframework/platform/internal/boxid/internal/signtest	[no test files]
ok  	github.com/carlosframework/platform/internal/boxvolumes	0.011s
ok  	github.com/carlosframework/platform/internal/caps	0.025s
ok  	github.com/carlosframework/platform/internal/certwarm	0.004s
ok  	github.com/carlosframework/platform/internal/cgroup	0.764s
ok  	github.com/carlosframework/platform/internal/changelog	0.498s
ok  	github.com/carlosframework/platform/internal/claimactivation	1.150s
ok  	github.com/carlosframework/platform/internal/clamd	0.065s
?   	github.com/carlosframework/platform/internal/cliflag	[no test files]
?   	github.com/carlosframework/platform/internal/controlname	[no test files]
?   	github.com/carlosframework/platform/internal/controlsock	[no test files]
ok  	github.com/carlosframework/platform/internal/dbdoor	8.370s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.009s
ok  	github.com/carlosframework/platform/internal/dbquery	0.006s
ok  	github.com/carlosframework/platform/internal/dbreads	2.101s
?   	github.com/carlosframework/platform/internal/dbreads/dbreadstest	[no test files]
ok  	github.com/carlosframework/platform/internal/dbverify	0.008s
ok  	github.com/carlosframework/platform/internal/dnsrec	0.004s
ok  	github.com/carlosframework/platform/internal/docsite	0.013s
ok  	github.com/carlosframework/platform/internal/domains	2.765s
ok  	github.com/carlosframework/platform/internal/doorkey	0.013s
ok  	github.com/carlosframework/platform/internal/economics	0.003s
ok  	github.com/carlosframework/platform/internal/edge	45.433s
?   	github.com/carlosframework/platform/internal/edgeproof	[no test files]
ok  	github.com/carlosframework/platform/internal/edgesfile	0.013s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.173s
ok  	github.com/carlosframework/platform/internal/gate	1.679s
ok  	github.com/carlosframework/platform/internal/genselect	0.026s
ok  	github.com/carlosframework/platform/internal/geo	0.023s
ok  	github.com/carlosframework/platform/internal/geoip	0.062s
ok  	github.com/carlosframework/platform/internal/historyreadback	0.201s
ok  	github.com/carlosframework/platform/internal/host	140.607s
ok  	github.com/carlosframework/platform/internal/hostactors	6.061s
ok  	github.com/carlosframework/platform/internal/hostactors/awsmembership	0.005s
ok  	github.com/carlosframework/platform/internal/hostbox	3.111s
ok  	github.com/carlosframework/platform/internal/hostclaim	0.795s
ok  	github.com/carlosframework/platform/internal/hostenv	0.009s
ok  	github.com/carlosframework/platform/internal/hostevidence	0.010s
ok  	github.com/carlosframework/platform/internal/hostexec	5.283s
ok  	github.com/carlosframework/platform/internal/hostfence	0.058s
ok  	github.com/carlosframework/platform/internal/hostfiles	10.320s
ok  	github.com/carlosframework/platform/internal/hostfloor	0.022s
ok  	github.com/carlosframework/platform/internal/hostguard	1.014s
ok  	github.com/carlosframework/platform/internal/hostops	1.924s
?   	github.com/carlosframework/platform/internal/hostops/fencerelease	[no test files]
ok  	github.com/carlosframework/platform/internal/hostops/internal/fencerelease	0.004s
ok  	github.com/carlosframework/platform/internal/hostquarantine	0.003s
ok  	github.com/carlosframework/platform/internal/hostrelocate	0.596s
ok  	github.com/carlosframework/platform/internal/hostresolve	0.212s
ok  	github.com/carlosframework/platform/internal/hostwrite	0.004s
ok  	github.com/carlosframework/platform/internal/infraview	0.004s
ok  	github.com/carlosframework/platform/internal/instancectl	5.224s
ok  	github.com/carlosframework/platform/internal/instanceexec	2.771s
ok  	github.com/carlosframework/platform/internal/instancefs	0.007s
ok  	github.com/carlosframework/platform/internal/instancekey	0.006s
ok  	github.com/carlosframework/platform/internal/instanceupdates	0.015s
ok  	github.com/carlosframework/platform/internal/layout	1.778s
ok  	github.com/carlosframework/platform/internal/lbhealth	0.005s
ok  	github.com/carlosframework/platform/internal/lease	10.276s
ok  	github.com/carlosframework/platform/internal/lease/leasetest	0.511s
ok  	github.com/carlosframework/platform/internal/ledger	0.039s
ok  	github.com/carlosframework/platform/internal/mail	0.216s
ok  	github.com/carlosframework/platform/internal/maintenance	0.094s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	5.558s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.106s
ok  	github.com/carlosframework/platform/internal/metrics	0.006s
ok  	github.com/carlosframework/platform/internal/moves	22.327s
ok  	github.com/carlosframework/platform/internal/moves/archive	0.949s
ok  	github.com/carlosframework/platform/internal/objstore	0.241s
ok  	github.com/carlosframework/platform/internal/ops	0.236s
ok  	github.com/carlosframework/platform/internal/park	0.308s
ok  	github.com/carlosframework/platform/internal/plans	0.007s
ok  	github.com/carlosframework/platform/internal/privatefile	0.006s
ok  	github.com/carlosframework/platform/internal/provision	23.572s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.008s
?   	github.com/carlosframework/platform/internal/regionname	[no test files]
ok  	github.com/carlosframework/platform/internal/registry	5.504s
ok  	github.com/carlosframework/platform/internal/relay	7.231s
ok  	github.com/carlosframework/platform/internal/release	26.302s
ok  	github.com/carlosframework/platform/internal/rollout	3.848s
ok  	github.com/carlosframework/platform/internal/rolloutwords	0.003s
ok  	github.com/carlosframework/platform/internal/rootaws	0.008s
ok  	github.com/carlosframework/platform/internal/rootparticipation	0.063s
ok  	github.com/carlosframework/platform/internal/rootstate	0.027s
ok  	github.com/carlosframework/platform/internal/runs	0.567s
ok  	github.com/carlosframework/platform/internal/s3compat	0.007s
ok  	github.com/carlosframework/platform/internal/safefile	0.006s
ok  	github.com/carlosframework/platform/internal/schedule	2.617s
ok  	github.com/carlosframework/platform/internal/seeds	0.013s
ok  	github.com/carlosframework/platform/internal/sim/engines	2.626s
ok  	github.com/carlosframework/platform/internal/sim/hostlife	10.505s
ok  	github.com/carlosframework/platform/internal/sim/litestreamfacts	3.588s
ok  	github.com/carlosframework/platform/internal/status	0.068s
ok  	github.com/carlosframework/platform/internal/steering	0.006s
ok  	github.com/carlosframework/platform/internal/stopevidence	0.285s
ok  	github.com/carlosframework/platform/internal/svcrole	0.002s
ok  	github.com/carlosframework/platform/internal/telemetry	0.004s
ok  	github.com/carlosframework/platform/internal/termfence	0.004s
ok  	github.com/carlosframework/platform/internal/tunnelclient	0.006s
ok  	github.com/carlosframework/platform/internal/unixdial	0.004s
ok  	github.com/carlosframework/platform/internal/updatewords	0.005s
ok  	github.com/carlosframework/platform/internal/usage	0.008s
ok  	github.com/carlosframework/platform/internal/version	0.002s
ok  	github.com/carlosframework/platform/internal/vet	1.715s
=== internal_console@0 (83 s)
ok  	github.com/carlosframework/platform/internal/console	81.387s
=== internal_console@1 (40 s)
ok  	github.com/carlosframework/platform/internal/console	39.255s
=== internal_console@2 (44 s)
ok  	github.com/carlosframework/platform/internal/console	42.424s
=== internal_console@3 (44 s)
ok  	github.com/carlosframework/platform/internal/console	42.946s
=== internal_console@4 (42 s)
ok  	github.com/carlosframework/platform/internal/console	40.876s
=== internal_console@5 (38 s)
ok  	github.com/carlosframework/platform/internal/console	36.972s
=== internal_console@6 (44 s)
ok  	github.com/carlosframework/platform/internal/console	42.404s
=== internal_console@7 (47 s)
ok  	github.com/carlosframework/platform/internal/console	45.421s
=== root@0 (109 s)
ok  	github.com/carlosframework/platform	108.261s
=== root@1 (97 s)
ok  	github.com/carlosframework/platform	95.552s
=== root@2 (77 s)
ok  	github.com/carlosframework/platform	76.198s
=== cross ===
--- shard 0 of 5 ---
cross-compiling darwin/arm64
--- shard 1 of 5 ---
cross-compiling darwin/amd64
--- shard 2 of 5 ---
cross-compiling linux/arm64
linux/arm64 carlos binary: 50528418 bytes (ceiling 52000000)
--- shard 3 of 5 ---
cross-compiling windows/amd64
--- shard 4 of 5 ---
cross-compiling windows/arm64
=== minio-contract ===
minio contract: arm64, minio RELEASE.2025-09-07T16-13-09Z, mc RELEASE.2025-08-13T08-35-41Z
  minio: downloading https://github.com/minio/minio/releases/download/RELEASE.2025-09-07T16-13-09Z/minio.linux-arm64.RELEASE.2025-09-07T16-13-09Z
  minio: downloaded, digest verified
  mc: downloading https://github.com/minio/mc/releases/download/RELEASE.2025-08-13T08-35-41Z/mc.linux-arm64.RELEASE.2025-08-13T08-35-41Z
  mc: downloaded, digest verified
  minio healthy on 127.0.0.1:20999
Added `local` successfully.
Bucket created successfully `local/contract-bucket`.
Bucket created successfully `local/denied-bucket`.
Created policy `contract-only` successfully.
Added user `scopeduser` successfully.
Attached Policies: [contract-only]
To User: scopeduser
  buckets and scoped user ready
=== RUN   TestDeliveredContractMinio
=== RUN   TestDeliveredContractMinio/put
=== RUN   TestDeliveredContractMinio/get_round-trips_the_body
=== RUN   TestDeliveredContractMinio/list_shows_the_key
=== RUN   TestDeliveredContractMinio/head_and_list_agree_on_the_version
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed
=== RUN   TestDeliveredContractMinio/delete_removes_it
=== RUN   TestDeliveredContractMinio/cross-bucket_denial
--- PASS: TestDeliveredContractMinio (0.02s)
    --- PASS: TestDeliveredContractMinio/put (0.00s)
    --- PASS: TestDeliveredContractMinio/get_round-trips_the_body (0.00s)
    --- PASS: TestDeliveredContractMinio/list_shows_the_key (0.00s)
    --- PASS: TestDeliveredContractMinio/head_and_list_agree_on_the_version (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route (0.01s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed (0.00s)
    --- PASS: TestDeliveredContractMinio/delete_removes_it (0.00s)
    --- PASS: TestDeliveredContractMinio/cross-bucket_denial (0.00s)
PASS
ok  	github.com/carlosframework/platform/internal/objstore	0.022s
=== RUN   TestT4StorageProbeMinio
2026/10/24 19:30:47 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18E18DFDD020DAD9, HostID: 7c420053e0fbcd7f41653fdd92ffa2802c903d05303b1aa15adc2e8bb65d183f, api error SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
--- PASS: TestT4StorageProbeMinio (0.00s)
PASS
ok  	github.com/carlosframework/platform/internal/host	0.023s
=== RUN   TestS3StoreMinioContract
=== RUN   TestS3StoreMinioContract/conditional_get_and_etag_listing
=== RUN   TestS3StoreMinioContract/bump_through_every_mutation_path
--- PASS: TestS3StoreMinioContract (0.02s)
    --- PASS: TestS3StoreMinioContract/conditional_get_and_etag_listing (0.01s)
    --- PASS: TestS3StoreMinioContract/bump_through_every_mutation_path (0.01s)
PASS
ok  	github.com/carlosframework/platform/internal/release	0.028s
Bucket created successfully `local/dbf-deploy`.
Bucket created successfully `local/dbf-data-ie`.
Bucket created successfully `local/dbf-data-uk`.
local/dbf-deploy versioning is enabled
Created policy `dbf-console` successfully.
Created policy `dbf-ukbox` successfully.
Added user `dbfconsole` successfully.
Added user `dbfukbox` successfully.
Attached Policies: [dbf-console]
To User: dbfconsole
Attached Policies: [dbf-ukbox]
To User: dbfukbox
=== RUN   TestDBForwardMinio
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000000 txid.db=0000000000000001
2026/10/24 19:30:50 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000001 maxTXID=0000000000000001 size=720
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000001 txid.db=0000000000000001
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000001 txid.db=0000000000000002
2026/10/24 19:30:50 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000002 maxTXID=0000000000000002 size=370
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000002 txid.db=0000000000000002
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000002 txid.db=0000000000000003
2026/10/24 19:30:50 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000003 maxTXID=0000000000000003 size=454
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000003 txid.db=0000000000000003
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000000 txid.db=0000000000000001
2026/10/24 19:30:50 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000001 maxTXID=0000000000000001 size=720
2026/10/24 19:30:50 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000001 txid.db=0000000000000001
2026/10/24 19:30:50 console: CARLOS_SECRETS_PUBKEY is unset, so no region outside the home can be chosen automatically
2026/10/24 19:30:50 console: could not notify member@example.com of a CLI token issue: keymail: lookup member@example.com: keymail: GET /api/federation/lookup?addr=member%40example.com&from=console%40127.0.0.1%3A40041: could not determine target mailbox
    agent.go:135: dbreads: dbr_566x3kuj4tjmbne63ztnazuaz4: planned 3 files (1544 bytes) and restored to 3 in 9ms
    agent.go:135: dbreads: dbr_566x3kuj4tjmbne63ztnazuaz4: output 5 bytes in 1 confirmed chunks in 1ms
2026/10/24 19:30:51 console: db read dbr_566x3kuj4tjmbne63ztnazuaz4: relayed 1 chunks (102 bytes) in 1.004s, ended done
    agent.go:135: dbreads: dbr_z2atg6k22cgpqrw77yligv4xwa: planned 1 files (720 bytes) and restored to 1 in 7ms
    agent.go:135: dbreads: dbr_z2atg6k22cgpqrw77yligv4xwa: output 5 bytes in 1 confirmed chunks in 1ms
2026/10/24 19:30:52 console: db read dbr_z2atg6k22cgpqrw77yligv4xwa: relayed 1 chunks (102 bytes) in 1.003s, ended done
    agent.go:135: dbreads: dbr_yhxwid6n7vknnyaohnn37nsvm4: planned 3 files (1544 bytes) and held through 3 in 8ms
    agent.go:135: dbreads: dbr_yhxwid6n7vknnyaohnn37nsvm4: output 1544 bytes in 1 confirmed chunks in 1ms
2026/10/24 19:30:53 console: db read dbr_yhxwid6n7vknnyaohnn37nsvm4: relayed 1 chunks (1641 bytes) in 1.003s, ended done
=== RUN   TestDBForwardMinio/by_disconnect
=== NAME  TestDBForwardMinio
    agent.go:135: dbreads: dbr_bp6cchb5xwxdithmtoe3ycknva: planned 3 files (1544 bytes) and restored to 3 in 9ms
2026/10/24 19:30:53 console: db read dbr_bp6cchb5xwxdithmtoe3ycknva: relayed 0 chunks (0 bytes) in 15ms, ended client gone
    agent.go:135: dbreads: dbr_bp6cchb5xwxdithmtoe3ycknva: output 5 bytes in 1 confirmed chunks in 11ms
=== RUN   TestDBForwardMinio/by_timeout
=== NAME  TestDBForwardMinio
    agent.go:135: dbreads: dbr_xp7zfjujgk2mpgc4awgr3leppa: planned 3 files (1544 bytes) and restored to 3 in 9ms
2026/10/24 19:31:13 console: db read dbr_xp7zfjujgk2mpgc4awgr3leppa: relayed 0 chunks (0 bytes) in 19.638s, ended no-result
    agent.go:135: dbreads: dbr_xp7zfjujgk2mpgc4awgr3leppa: output 5 bytes in 1 confirmed chunks in 19.629s
--- PASS: TestDBForwardMinio (22.98s)
    --- PASS: TestDBForwardMinio/by_disconnect (0.13s)
    --- PASS: TestDBForwardMinio/by_timeout (19.75s)
PASS
ok  	github.com/carlosframework/platform/internal/console	23.001s
minio contract: PASS
diff --git a/docs/superpowers/notes/census-proposal-pro-6214-service-runs.md b/docs/superpowers/notes/census-proposal-pro-6214-service-runs.md
new file mode 100644
index 000000000..199b2bb6e
--- /dev/null
+++ b/docs/superpowers/notes/census-proposal-pro-6214-service-runs.md
@@ -0,0 +1,126 @@
+# Census approval: pro-6214-service-runs
+
+Ruling `census-ruling-pro-6214-service-runs`, asked of the census owner on
+#280 before the merge. Every row already carries it (#369). Branch
+`pro-6214-service-runs`. Spec:
+`docs/superpowers/specs/2026-10-24-service-runs-design.md` (Linear PRO-6214).
+
+The branch adds a service role, `run`, so that a server (Tito's Fleet) can
+start and follow `carlos run` runs without a person's token. It also adds
+idempotent run create (`Idempotency-Key`, recorded in the instance record's
+`run_keys`). No root read is added. The console units run in the console
+(`cmd/console serve`, user `carlos-console`), and the root `carlos` binary
+does not link `internal/console` (`TestRootBinaryLinksNoConsoleOrMail`). The
+CLI units run in `carlos run` as its caller.
+
+## What you are asked
+
+- **Approvals (22): 14 changed units and 8 envelopes.** Each changed unit
+ keeps its class and task and reads only the kinds it already read. 13 are
+ `body` changes. 1 is `sites`: `migrateCLIAuth` has one more SQLite `Exec`,
+ the new index. census-propose wrote these rows into
+ `plan14-root-reads-pro-6214-service-runs.tsv`, and their table is under
+ "Approvals" below.
+- **Decisions (6): 5 new units and 1 removed unit.** census-propose cannot
+ write these. They are hand-written in
+ `plan14-root-reads-pro-6214-service-runs-decisions.tsv`, which loads
+ before the approvals overlay. Each new unit is proposed as accepted legacy
+ at the class of the row it mirrors:
+
+ | decision | unit | proposed disposition | mirrors | reads | digest |
+ |---|---|---|---|---|---|
+ | new | `internal/console/apiruns.go` `Server.handleAPIRunKeyLookup` | legacy, accepted-legacy. **Authority: a run door** | `handleAPIRunGet` (census-ruling-carlos-run) | `file:Query@528`, which is `r.URL.Query()` (the key), not a file; then the instance record from the deployment bucket. Writes nothing | `635e57ad…076e` |
+ | new | `internal/console/authstore.go` `Store.backfillCredentialIDs` | legacy, accepted-legacy (J4) | `migrateCLIAuth` (J4 root-input) | `file:Query@62`, `file:Exec@554` on the console's own `cli_tokens`; it sets an id only where none is set | `3fbb21ec…48b5` |
+ | new | `internal/console/authstore.go` `newCredentialID` | legacy, accepted-legacy (J4) | `newStore` (email-signin), `Keymail.sealEnvelope` (console-invite-delivery) | `file:Read@78`, a 16-byte `crypto/rand.Read`: an identity, not a secret | `57049041…0cb5` |
+ | new | `run.go` `runFileSum` | legacy, accepted-legacy | `runMetaFor` (census-ruling-carlos-run) | `file:Open@58` of a `--file` path the caller named, hashed to EOF; only with `--idempotency-key` | `745fa0d0…6991` |
+ | new | `auth.go` `consoleClient.doMultipartHeaders` | legacy, accepted-legacy (J4) | `consoleClient.doMultipartMethod` (J4 root-input) | `file:ReadAll@1418` of the console's response body: `doMultipartMethod`'s body, moved, plus extra request headers that cannot override the content type or the bearer | `4682be87…c17b` |
+ | removed | `auth.go` `consoleClient.doMultipartMethod` | H3 census-ruling removal | zddr3's and email-signin's form | still declared and reads nothing: it calls `doMultipartHeaders` with no headers | |
+
+- **Record-write census (9B8): 6 entries re-digested, classes and kinds
+ unchanged** (`internal/provision/service_runs_census_test.go`, hand-written
+ as 9B8 still requires). They are `admitRun` (record-writer,
+ `key:SetRecordRun`: it passes the key, digest and caller to `RunAdmit`,
+ and the key is written by the same CAS), `handleAPIRunAck`, `Cancel` and
+ `Expire` (refusal codes only), `auditRunEnd` (nonrecord, the requester
+ line), and `registerCLIRoutes` (key-site: the run doors move to
+ `svcrole.Exactly(svcrole.Run)`, plus one route for the key lookup).
+ `RunAdmit` names no census identifier, so it is not a 9B8 site.
+
+## The four units that carry authority
+
+The census classes are all accepted legacy, because nothing here is root
+authority. The branch does grant authority, though, and these four are where
+it lives:
+
+1. **The run doors.**
+ - `Server.handleAPIRunCreate` (approval) and the new
+ `Server.handleAPIRunKeyLookup` (decision). The follow doors
+ `handleAPIRunGet`, cancel, expire and `handleAPIRunAck` reach a service
+ only through `runGate`, which has no scanned site and is pinned by the
+ `internal/console` envelope.
+ - They admit a service principal only with role `run` and a credential
+ id. The route sets are `svcrole.Exactly(Run)`, so Admin does not reach
+ them.
+ - A service runs only an argv that starts, word for word, with a prefix
+ its credential was minted with. It sees and acts on only the runs its
+ credential id started; any other answers 404.
+ - `on_behalf_of` is recorded on the service's word, shape-checked as an
+ email, and grants nothing.
+2. **`provision.RunAdmit`** (approval).
+ - Admission and the idempotency dedupe are one compare-and-swap.
+ - Keys are pruned at 24 hours, each caller keeps its newest 32, and a
+ key is stored hashed with its caller.
+ - Only `RunAdmit` assigns `RunKeys` (`TestOnlyRunAdmitWritesRunKeys`).
+3. **The mint, `Store.claimRawNewServicePrincipalScoped`** (approval).
+ - It is the only writer of a run credential, and is reached from the two
+ owner-gated mint doors. The API door is registered `svcrole.Set{}`, so
+ no service credential can mint one.
+ - A run credential needs an app and 1 to 32 valid command prefixes.
+ - Every mint draws a fresh `credential_id`, so a revoked name minted
+ again owns none of the old runs.
+4. **The read, `Store.CLIPrincipal`** (approval).
+ - A run row resolves only with an app, a `credential_id`, and a command
+ list in the exact canonical form this console writes. Anything else
+ does not resolve: it fails closed.
+
+## Seal
+
+The chain ends at `sec-host-imdsv2-module`: `945934f5…6c6a`.
+
+- The decisions overlay adds five frozen declarations:
+ `bcad5454f7ad3a575d43f02dc598b20409e4637fc222fad06b501259fd3389a2`.
+- The approvals overlay re-freezes fourteen:
+ `b9f9c8c785afb6c1092b88dd0e359ba199a982bece21e672f45c4dbb6ffc975c`.
+
+Both lines are in `plan14-root-reads-chain.tsv`.
+
+Re-running `make census-propose NAME=pro-6214-service-runs` rewrites the
+section below and replaces this whole file. Restore the sections above
+after a re-run.
+
+## Approvals (written by census-propose)
+
+Ruling `census-ruling-pro-6214-service-runs`. Every change below keeps the disposition it already has, so it needs an approval, not a decision.
+
+| unit | change | read sites | what changed |
+|---|---|---|---|
+| `cmd/console/main.go` `serve` | body | unchanged (3) | the console (cmd/console serve, user carlos-console): reads CARLOS_RUN_KEYS, an environment variable, into Config.RunKeysEnabled; keyed run creates are refused 503 keys_not_ready unless it is on; the same three /data literals; no read added |
+| `internal/console/apiruns.go` `Server.handleAPIRunCreate` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors): also admits a run service (runCaller: role run with a credential id, after the unchanged shared gate and the route's svcrole.Exactly(Run), which Admin does not join); a service's argv must start word for word with one of its granted prefixes (runs.CommandGranted), else 403 command_not_granted before any object is written; on_behalf_of only from a service, one bare email of at most 254 bytes, never checked against membership, granting nothing; a keyed create (Idempotency-Key, only with CARLOS_RUN_KEYS=on) answers a key the record's run_keys holds for this caller before the record refusals and without reading a file (same digest: 202 replayed; another: 409); keyed files must declare and match their sha256; records by_service, by_credential, on_behalf_of and the scoped key hash; an open-run refusal is redacted for another caller's run; refusal codes; its one site is still rec.ActiveRun.Open(), a method, not a file; no read added (the record and request.json from the deployment bucket, as before) |
+| `internal/console/apirunsfollow.go` `Server.handleAPIRunAck` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors, via runGate): a run service acks only its own runs; refusal codes; RunClear unchanged and leaves run_keys as they are; its one site, run.Open(), a method, moves; no read added |
+| `internal/console/apirunsfollow.go` `Server.handleAPIRunGet` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors, via runGate): a run service reaches it only for a run whose request.json records its credential id, any other answering 404 as an unknown id; refusal codes; the same r.URL.Query() site; no read added |
+| `internal/console/apirunsfollow.go` `Server.runTransitionRefused` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): refusal codes only (run_started, run_ended and the shared codes); its one site, run.Open() on the record's run state, a method, moves; no read added |
+| `internal/console/authstore.go` `Store.CLITokens` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): its Query also selects cli_tokens.commands; the same Query site; no read added |
+| `internal/console/authstore.go` `Store.claimRawNewAppToken` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): the legacy app token's INSERT also writes a fresh credential_id (newCredentialID); the same Exec site; no read added |
+| `internal/console/svcprincipal.go` `Store.CLIPrincipal` | body | unchanged (2) | the console (cmd/console serve, user carlos-console): AUTHORITY (the credential read): its cli_tokens QueryRow also selects credential_id and commands; a run row resolves only with an app, a credential_id and a command list that parses, passes runs.CheckCommandPrefixes and is byte-identical to the canonical JSON this console writes, else it does not resolve (fail closed, the deploy rungs rule's twin); any other role carrying commands does not resolve; the same QueryRow and last_used Exec sites; no read added |
+| `internal/console/svcprincipal.go` `Store.ServicePrincipals` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): its Query also selects cli_tokens.commands for the account's service listing; the same Query site; no read added |
+| `internal/console/svcprincipal.go` `Store.claimRawNewServicePrincipalScoped` | body | unchanged (2) | the console (cmd/console serve, user carlos-console): AUTHORITY (the mint): the only writer of a run credential, from the two owner-gated mint doors (POST /api/cli/services/{account}, registered svcrole.Set{} so no service credential reaches it, and the settings page behind serviceOwner); a run credential must name an app and 1 to 32 valid command prefixes, takes no rungs, and other roles may not name commands; stores the list as canonical JSON in cli_tokens.commands and a fresh credential_id on every mint, including a reused revoked name; the same QueryRow and INSERT Exec sites; no read added |
+| `internal/console/templates/account_settings.html` `external` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): embedded UI: a Commands column, the minted line names a run credential's commands, and a commands input on the mint form; markup only; no read added |
+| `internal/provision/run.go` `RunAdmit` | body | unchanged (1) | the console (cmd/console serve, user carlos-console): AUTHORITY (RunAdmit): still applied only by the create door's admitRun through SetRecordRun's unchanged read-CAS-write; prunes run_keys older than 24h on every admission; a keyed admission checks its key before every refusal (same digest: *RunKeyReplay; another: ErrRunKeyReused; neither changes the record); a keyed admission that succeeds appends {key, run_id, digest, caller, at} and keeps each caller's newest 32, in the same write that queues the run; refusals and the queued RunState unchanged; within internal/provision only RunAdmit assigns RunKeys (TestOnlyRunAdmitWritesRunKeys); its one site is still rec.ActiveRun.Open(), a method; no read added |
+| `run.go` `runMetaFor` | body | unchanged (1) | the carlos CLI on the caller's own machine, as that caller: with --idempotency-key it also declares each --file's sha256 (runFileSum, a new unit); the same Stat of the path the caller named; no read added here |
+| `internal/console/authstore.go` `Store.migrateCLIAuth` | sites | +file:Exec | the console (cmd/console serve, user carlos-console): one more Exec of the kind it already makes: SQLite DDL on its own database, the partial unique index cli_tokens_credential_id; the ALTER loop adds credential_id and commands (TEXT NOT NULL DEFAULT ''); then calls backfillCredentialIDs; additive; no new kind of read |
+
+Envelopes re-pinned: `.`, `cmd/console`, `internal/console`, `internal/console/templates`, `internal/host`, `internal/provision`, `internal/runs`, `internal/svcrole`.
+
+Seal: `bcad5454f7ad3a575d43f02dc598b20409e4637fc222fad06b501259fd3389a2` → `b9f9c8c785afb6c1092b88dd0e359ba199a982bece21e672f45c4dbb6ffc975c`.
+
+Overlay: `internal/provision/testdata/plan14-root-reads-pro-6214-service-runs.tsv`, appended to `internal/provision/testdata/plan14-root-reads-chain.tsv`.
diff --git a/internal/provision/plan9_b8_census_test.go b/internal/provision/plan9_b8_census_test.go
index 525edfb2c..a16efb787 100644
--- a/internal/provision/plan9_b8_census_test.go
+++ b/internal/provision/plan9_b8_census_test.go
@@ -366,7 +366,7 @@ func TestPlan9B8RecordWriteCensus(t *testing.T) {
if len(got) < 100 {
t.Fatalf("census found only %d units under %s; the walk is broken", len(got), root)
}
- inventory := dbRegionForward3WriteCensusInventory()
+ inventory := serviceRunsWriteCensusInventory()
problems := append(censusDiff(inventory, got), censusPolicy(inventory)...)
if len(problems) > 0 {
t.Fatalf("record-write census rejected %d site(s); update the explicit inventory only after reviewing the source:\n %s", len(problems), strings.Join(problems, "\n "))
diff --git a/internal/provision/service_runs_census_test.go b/internal/provision/service_runs_census_test.go
new file mode 100644
index 000000000..e7fee162a
--- /dev/null
+++ b/internal/provision/service_runs_census_test.go
@@ -0,0 +1,56 @@
+package provision
+
+// Record-write census entries for pro-6214-service-runs (Linear PRO-6214:
+// run-role service credentials, keyed run create; spec
+// docs/superpowers/specs/2026-10-24-service-runs-design.md), layered on
+// dbRegionForward3WriteCensusInventory (still main's last at 65ca4aca).
+// Reviewed by the branch author; census-ruling-pro-6214-service-runs, asked
+// of the census owner on #280 before the merge with the approval card
+// (docs/superpowers/notes/census-proposal-pro-6214-service-runs.md).
+// Every unit keeps its class and its site kinds; only digests move, and no
+// write site is added, moved to another class or removed.
+// - Server.admitRun passes the keyed create's scoped key, request digest
+// and caller into RunAdmit, and answers a *RunKeyReplay naming its own
+// id as its admission. Still one SetRecordRun (RunAdmit): the key is
+// recorded in run_keys by that same compare-and-swap, never by a write
+// of its own. record-writer.
+// - Server.handleAPIRunAck, Server.handleAPIRunCancel and
+// Server.handleAPIRunExpire: refusal codes only (jsonErrorCode); their
+// RunClear, RunCancelTransition and RunExpire writes are unchanged, and
+// none of them touches run_keys. A run service reaches them only for a
+// run its own credential started (runGate, no census site).
+// record-writer.
+// - Server.auditRunEnd adds a service's run's requester line to the
+// run-end activity detail; its one Put, the audited marker under
+// runs/<id>/, is unchanged. nonrecord.
+// - Server.registerCLIRoutes registers the five run doors with
+// svcrole.Exactly(svcrole.Run) instead of svcrole.Set{}, and adds GET
+// .../instances/{host}/runs (handleAPIRunKeyLookup, which writes
+// nothing). Route lines only. key-site.
+//
+// provision.RunAdmit, the transition admitRun applies, names no census
+// identifier, so it is not a site here; its run_keys change is in the
+// root-read overlay plan14-root-reads-pro-6214-service-runs.tsv.
+func serviceRunsWriteCensusInventory() []censusEntry {
+ entries := append([]censusEntry(nil), dbRegionForward3WriteCensusInventory()...)
+ replacements := []censusEntry{
+ {"internal/console/apiruns.go", "Server.admitRun", "record-writer", "key:SetRecordRun", "b2d56d70b24aeecbe191fc868a8afb8c2ee4c9eb73371edad17210441e0bd8ce"},
+ {"internal/console/apirunsfollow.go", "Server.auditRunEnd", "nonrecord", "sel:Put", "e112ac93c83aebf1325fca43f4d94a257783f5d2f3983b462d8f7c84459297f6"},
+ {"internal/console/apirunsfollow.go", "Server.handleAPIRunAck", "record-writer", "key:SetRecordRun", "2680a0bb0550b3c4811487dfffb8ec56ec9c381085d67ef4b6af0e3b17035587"},
+ {"internal/console/apirunsfollow.go", "Server.handleAPIRunCancel", "record-writer", "key:SetRecordRun", "4a7f3b95ccdffb9c868d92a368036fb7af8115972ea060c0949f065c27f93581"},
+ {"internal/console/apirunsfollow.go", "Server.handleAPIRunExpire", "record-writer", "key:SetRecordRun", "fd67215764cf8c0ae94a240f2637fd126e79675bd17ab72603cb43e7b7ba7277"},
+ {"internal/console/authcli.go", "Server.registerCLIRoutes", "key-site", "lit:instances,lit:sidecars", "12e06989835b4de0d1fc2e8082cb2f62d1e961b689a61c886d6e201ac350285f"},
+ }
+ for _, r := range replacements {
+ found := false
+ for i, e := range entries {
+ if e.File == r.File && e.Unit == r.Unit {
+ entries[i], found = r, true
+ }
+ }
+ if !found {
+ entries = append(entries, r)
+ }
+ }
+ return entries
+}
diff --git a/internal/provision/testdata/plan14-root-reads-chain.tsv b/internal/provision/testdata/plan14-root-reads-chain.tsv
index 6e21d1925..bc2c60f8f 100644
--- a/internal/provision/testdata/plan14-root-reads-chain.tsv
+++ b/internal/provision/testdata/plan14-root-reads-chain.tsv
@@ -2,3 +2,5 @@
# One per line: <overlay file name under testdata>\t<the seal it leaves>.
# make census-propose appends here; nothing else edits this file.
plan14-root-reads-sec-host-imdsv2-module.tsv 945934f5978ace14dc5a9bae0ed69dfabf29b994504fc843c03d4a633ecd6c6a
+plan14-root-reads-pro-6214-service-runs-decisions.tsv bcad5454f7ad3a575d43f02dc598b20409e4637fc222fad06b501259fd3389a2
+plan14-root-reads-pro-6214-service-runs.tsv b9f9c8c785afb6c1092b88dd0e359ba199a982bece21e672f45c4dbb6ffc975c
diff --git a/internal/provision/testdata/plan14-root-reads-pro-6214-service-runs-decisions.tsv b/internal/provision/testdata/plan14-root-reads-pro-6214-service-runs-decisions.tsv
new file mode 100644
index 000000000..d2f42008d
--- /dev/null
+++ b/internal/provision/testdata/plan14-root-reads-pro-6214-service-runs-decisions.tsv
@@ -0,0 +1,20 @@
+# Census overlay pro-6214-service-runs-decisions, written BY HAND (AGENTS.md, The census: census-propose refuses decisions). The decisions of census-ruling-pro-6214-service-runs (Linear PRO-6214: run-role service credentials, keyed run create; docs/superpowers/specs/2026-10-24-service-runs-design.md): five new units and one removed. Loaded from the chain manifest before plan14-root-reads-pro-6214-service-runs.tsv, which census-propose wrote for the approvals. Asked of the census owner on #280 with the card docs/superpowers/notes/census-proposal-pro-6214-service-runs.md; rows carry the ruling from the start (#369).
+# No root read is added. The console units run as carlos-console, and the root carlos binary links neither internal/console nor internal/mail (TestRootBinaryLinksNoConsoleOrMail); the CLI units run in carlos run as its caller. Each new unit is accepted legacy at the class of the row it mirrors, named in its basis. Five frozen declarations are added, so the seal moves.
+# NEW, authority (the run doors): the keyed-create lookup door, GET .../instances/{host}/runs?key=<key>. Mirrors handleAPIRunGet (census-ruling-carlos-run): the run doors' gate, then a read.
+@legacy b8dd3663d5257adc761ba2ae1812580d54515444f35e854c3e687e7c48e7b03b internal/console/apiruns.go Server.handleAPIRunKeyLookup legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the console (cmd/console serve under console.service, user carlos-console);basis=new: GET .../instances/{host}/runs?key=<key>, registered with svcrole.Exactly(Run) (a person on the member rule, or a run service; Admin does not join): runCaller, the shared gate, the host-claim refusal and the runs budget, then the instance record from the deployment bucket and the run id its run_keys holds for runs.ScopedKey(caller scope, key), or 404; a key is stored scoped to its caller and hashed, so another caller's key is never found; its one scanned site is r.URL.Query() of the request URL (the key), not a file, as handleAPIRunGet's after; it writes nothing; the class of handleAPIRunGet (census-ruling-carlos-run) file:Query@528 635e57ad13d3468fdacc021543d52c36d1c1867a46f828665e2e0f657271076e
+internal/console/apiruns.go Server.handleAPIRunKeyLookup legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the console (cmd/console serve under console.service, user carlos-console);basis=new: GET .../instances/{host}/runs?key=<key>, registered with svcrole.Exactly(Run) (a person on the member rule, or a run service; Admin does not join): runCaller, the shared gate, the host-claim refusal and the runs budget, then the instance record from the deployment bucket and the run id its run_keys holds for runs.ScopedKey(caller scope, key), or 404; a key is stored scoped to its caller and hashed, so another caller's key is never found; its one scanned site is r.URL.Query() of the request URL (the key), not a file, as handleAPIRunGet's after; it writes nothing; the class of handleAPIRunGet (census-ruling-carlos-run) file:Query@528 635e57ad13d3468fdacc021543d52c36d1c1867a46f828665e2e0f657271076e
+# NEW at J4: console SQL on its own database, as migrateCLIAuth.
+@legacy f28f3445ca3a2b61534ec796b72df7b2647e072ee300eefe57cc68ca27745436 internal/console/authstore.go Store.backfillCredentialIDs legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the console (cmd/console serve under console.service, user carlos-console);basis=new: runs at every console Open, from migrateCLIAuth: one Query of the console's own cli_tokens (CONSOLE_DB, SQLite) for service and legacy app rows whose credential_id is empty, then one Exec per row setting a fresh newCredentialID only WHERE credential_id is still empty, so an id once given is never replaced and a second run changes nothing; a person's row keeps ''; the class of migrateCLIAuth (J4 root-input) file:Exec@554,file:Query@62 3fbb21eca5b07c5278e86ee25d70dcd570cced18514f3d7af6666dc2d85748b5
+internal/console/authstore.go Store.backfillCredentialIDs legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the console (cmd/console serve under console.service, user carlos-console);basis=new: runs at every console Open, from migrateCLIAuth: one Query of the console's own cli_tokens (CONSOLE_DB, SQLite) for service and legacy app rows whose credential_id is empty, then one Exec per row setting a fresh newCredentialID only WHERE credential_id is still empty, so an id once given is never replaced and a second run changes nothing; a person's row keeps ''; the class of migrateCLIAuth (J4 root-input) file:Exec@554,file:Query@62 3fbb21eca5b07c5278e86ee25d70dcd570cced18514f3d7af6666dc2d85748b5
+# NEW at J4: crypto/rand, as newStore (email-signin) and Keymail.sealEnvelope (console-invite-delivery).
+@legacy c899e2382f8efc86faa20bd8e3bb80939cb79a3ef5ef4901698aa4990c792588 internal/console/authstore.go newCredentialID legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the console (cmd/console serve under console.service, user carlos-console);basis=new: one crypto/rand.Read of 16 bytes from the kernel's random source, hex-encoded: a service credential's stable identity, not a secret, never derived from its name; no file, no store, no box state; the class of newStore's crypto/rand reads (email-signin) and Keymail.sealEnvelope's (census-ruling-console-invite-delivery) file:Read@78 570490418b8acb1cf1ff543f9db2a226bb42e8d1ba458456b0a3fd7ba3780cb5
+internal/console/authstore.go newCredentialID legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the console (cmd/console serve under console.service, user carlos-console);basis=new: one crypto/rand.Read of 16 bytes from the kernel's random source, hex-encoded: a service credential's stable identity, not a secret, never derived from its name; no file, no store, no box state; the class of newStore's crypto/rand reads (email-signin) and Keymail.sealEnvelope's (census-ruling-console-invite-delivery) file:Read@78 570490418b8acb1cf1ff543f9db2a226bb42e8d1ba458456b0a3fd7ba3780cb5
+# NEW: hashes a --file the caller named, as runMetaFor stats it.
+@legacy 728ed7b2a43ca78f5235e4e2f47d056b93313d949b171b8f44926c485ed7e9b9 run.go runFileSum legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the carlos CLI on the caller's own machine, as that caller: a person, or a server holding a run credential as CARLOS_SERVICE_TOKEN; no box unit runs carlos run;basis=new: opens a --file path the caller named on their own command line, which runMetaFor has just stat'ed as a regular file, and hashes it to EOF; nothing else is opened; reached only with --idempotency-key; the class of runMetaFor (census-ruling-carlos-run) file:Open@58 745fa0d005c295604b2ebc35f6293e41f761e9add6092f5341be051cd7fa6991
+run.go runFileSum legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the carlos CLI on the caller's own machine, as that caller: a person, or a server holding a run credential as CARLOS_SERVICE_TOKEN; no box unit runs carlos run;basis=new: opens a --file path the caller named on their own command line, which runMetaFor has just stat'ed as a regular file, and hashes it to EOF; nothing else is opened; reached only with --idempotency-key; the class of runMetaFor (census-ruling-carlos-run) file:Open@58 745fa0d005c295604b2ebc35f6293e41f761e9add6092f5341be051cd7fa6991
+# NEW at J4: doMultipartMethod's body moved here with extra request headers.
+@legacy 59a2b392040051489bdc0975160d4e53435d47e35da02710a1ccd2cf558759d6 auth.go consoleClient.doMultipartHeaders legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the carlos CLI on the caller's own machine, as that caller: a person, or a server holding a run credential as CARLOS_SERVICE_TOKEN; no box unit runs carlos run;basis=new: consoleClient.doMultipartMethod's body moved here unchanged, plus caller-supplied request headers (a run's Idempotency-Key), set before the content type and the bearer, which they cannot override; its one site, io.ReadAll of the console's response body, is doMultipartMethod's, J4 root-input as that row was file:ReadAll@1418 4682be879f99a1ede5b839198dd1568973b06cdbd0d911b0a95f821e1437c17b
+auth.go consoleClient.doMultipartHeaders legacy accepted-legacy accepted-legacy;rev3=census-ruling-pro-6214-service-runs;identity=the carlos CLI on the caller's own machine, as that caller: a person, or a server holding a run credential as CARLOS_SERVICE_TOKEN; no box unit runs carlos run;basis=new: consoleClient.doMultipartMethod's body moved here unchanged, plus caller-supplied request headers (a run's Idempotency-Key), set before the content type and the bearer, which they cannot override; its one site, io.ReadAll of the console's response body, is doMultipartMethod's, J4 root-input as that row was file:ReadAll@1418 4682be879f99a1ede5b839198dd1568973b06cdbd0d911b0a95f821e1437c17b
+# Removed: still declared, and reads nothing now. Retired by an H3 census-ruling removal (zddr3's form; the loader takes H3 only with a census-ruling- basis). A removal is not in the seal.
+@remove auth.go consoleClient.doMultipartMethod
+@removed auth.go consoleClient.doMultipartMethod H3 census-ruling-pro-6214-service-runs: still declared, and reads nothing now: its body and its one site, io.ReadAll of the console's response body, moved unchanged into consoleClient.doMultipartHeaders, an accepted-legacy row in this overlay, which it calls with no extra headers. It runs in the carlos CLI as its caller.
diff --git a/internal/provision/testdata/plan14-root-reads-pro-6214-service-runs.tsv b/internal/provision/testdata/plan14-root-reads-pro-6214-service-runs.tsv
new file mode 100644
index 000000000..60dfd8a4a
--- /dev/null
+++ b/internal/provision/testdata/plan14-root-reads-pro-6214-service-runs.tsv
@@ -0,0 +1,38 @@
+# Census overlay pro-6214-service-runs, written by census-propose (#369). census-ruling-pro-6214-service-runs, approved by the census owner before the merge; the approval card is docs/superpowers/notes/census-proposal-pro-6214-service-runs.md.
+# 13 body, 1 sites, 8 envelope: each changed unit re-frozen at its existing disposition with its claim appended.
+@legacy dfbe85f4f2de47ca2f89f00de8014bce9dbbbc40eabaff5b727464396080a0c4 cmd/console/main.go serve legacy accepted-legacy accepted-legacy;rev3=PROPOSED-scan-demand-revival;basis=Console service wires the optional callback signer and starts the claim-guarded queue worker. The same three data path literals move; it does not add a privileged reader.;rev3=PROPOSED-email-signin;identity=the console (cmd/console serve under console.service, user carlos-console);basis=passes CARLOS_CONSOLE_NAME to NewServer as Config.ConsoleName, the name the console's emails use; the same three /data literals at the same offsets; no read added;rev3=PROPOSED-s3-change-index;identity=the console (cmd/console serve under console.service, user carlos-console);basis=arms the record view when CARLOS_CHANGE_INDEX=read (armChangeIndex) for the run and seed sweeps and starts its backstop loop; the same three /data literals at the same offsets; no read added;rev3=census-ruling-db-region-forward-2;identity=the console (cmd/console serve under console.service, user carlos-console);basis=parses CARLOS_DB_FORWARD (dbForward) into Config.DBForward and builds its http.Server with console.NewHTTPServer, the same two timeouts; the same three /data literals at the same offsets; no read added;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): reads CARLOS_RUN_KEYS, an environment variable, into Config.RunKeysEnabled; keyed run creates are refused 503 keys_not_ready unless it is on; the same three /data literals; no read added data-literal@4077,data-literal@5178,data-literal@5415 20d2603867d98a491d9f084a69d55190ebfa76ef2b961cc7da0e00e445495ea6
+@legacy ce411ba77d0198cddfe75a1c29be5218251d90232e0d268f74b7dfdfb2897412 internal/console/apiruns.go Server.handleAPIRunCreate legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the run create door; it reads the record from the bucket and refuses an open run; no root decision;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors): also admits a run service (runCaller: role run with a credential id, after the unchanged shared gate and the route's svcrole.Exactly(Run), which Admin does not join); a service's argv must start word for word with one of its granted prefixes (runs.CommandGranted), else 403 command_not_granted before any object is written; on_behalf_of only from a service, one bare email of at most 254 bytes, never checked against membership, granting nothing; a keyed create (Idempotency-Key, only with CARLOS_RUN_KEYS=on) answers a key the record's run_keys holds for this caller before the record refusals and without reading a file (same digest: 202 replayed; another: 409); keyed files must declare and match their sha256; records by_service, by_credential, on_behalf_of and the scoped key hash; an open-run refusal is redacted for another caller's run; refusal codes; its one site is still rec.ActiveRun.Open(), a method, not a file; no read added (the record and request.json from the deployment bucket, as before) file:Open@2106 1b6af835b3b709a20c046837c0415d60b6c15f7d7dcc50c12bdcd0d25a0c68a6
+@legacy 14d651ad63a4077c3bd0b53890295672478dbcb96efc1678a257d922e5f4b694 internal/console/apirunsfollow.go Server.handleAPIRunAck legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the ack door; clears a finished run from the record by CAS;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors, via runGate): a run service acks only its own runs; refusal codes; RunClear unchanged and leaves run_keys as they are; its one site, run.Open(), a method, moves; no read added file:Open@1316 2680a0bb0550b3c4811487dfffb8ec56ec9c381085d67ef4b6af0e3b17035587
+@legacy fe5c95db4a613a52b32fcf1aed1b2f50b9974fe9d38e32fc0c1dd281e4b789a9 internal/console/apirunsfollow.go Server.handleAPIRunGet legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the follow door; pages a run's chunks and result from the bucket;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors, via runGate): a run service reaches it only for a run whose request.json records its credential id, any other answering 404 as an unknown id; refusal codes; the same r.URL.Query() site; no read added file:Query@169 e426b56dc75dca7ea970785df9ad6de0fcea95bdb49dd034b511aa9c75a03384
+@legacy 1def3790bd1cb1eca81b161aaf4fe2c3b56cf559ea3c32a5084ff8fac96b4af4 internal/console/apirunsfollow.go Server.runTransitionRefused legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): words a refused cancel, expire or ack from the record's run state;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): refusal codes only (run_started, run_ended and the shared codes); its one site, run.Open() on the record's run state, a method, moves; no read added file:Open@615 63e0baeadb156f6d99a674592c2e7a180f294ad71c2578e5f26383af3e1921a5
+@legacy 0b758ac7c67e2a7b5999f8cf4f6847b30bb2d9fc84f083e3d75f69e691b963a2 internal/console/authstore.go Store.CLITokens legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): its Query also selects cli_tokens.commands; the same Query site; no read added file:Query@78 30216364db3a080dc80c83d5dd1fd5f34923b8da9358497e06779fa737fe23db
+@legacy e9ab4c437fe58eb580e9134d0e37b7e2f1bc0d98df237b3321bec468c5f04993 internal/console/authstore.go Store.claimRawNewAppToken legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): the legacy app token's INSERT also writes a fresh credential_id (newCredentialID); the same Exec site; no read added file:Exec@264 15c4236fbbe2724dd114e67f029ee7b2c7666e348b63e68a0fa3845d4b6d17d9
+@legacy 89f3fd21d90025cb16b2f05e0d55ff3131b808cdde7b2d885878d3f9d333e41e internal/console/svcprincipal.go Store.CLIPrincipal legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the credential read): its cli_tokens QueryRow also selects credential_id and commands; a run row resolves only with an app, a credential_id and a command list that parses, passes runs.CheckCommandPrefixes and is byte-identical to the canonical JSON this console writes, else it does not resolve (fail closed, the deploy rungs rule's twin); any other role carrying commands does not resolve; the same QueryRow and last_used Exec sites; no read added file:Exec@3861,file:QueryRow@286 c3244624910adb4b6b4416719957527d383aea4a48348cef3b7fdb17cc11bea7
+@legacy ef2a99bd7255f7f1554623df55ef8b11a84654f373fa405d7389766bc2e7448c internal/console/svcprincipal.go Store.ServicePrincipals legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): its Query also selects cli_tokens.commands for the account's service listing; the same Query site; no read added file:Query@87 29b33d2785551e03b51b1d21bd04a48eced9ef0e3b6793e440a64bd7976ff4eb
+@legacy 0031cc73ee797c398d150c567afab280db9eca7baadc559ce58fad144906d12e internal/console/svcprincipal.go Store.claimRawNewServicePrincipalScoped legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the mint): the only writer of a run credential, from the two owner-gated mint doors (POST /api/cli/services/{account}, registered svcrole.Set{} so no service credential reaches it, and the settings page behind serviceOwner); a run credential must name an app and 1 to 32 valid command prefixes, takes no rungs, and other roles may not name commands; stores the list as canonical JSON in cli_tokens.commands and a fresh credential_id on every mint, including a reused revoked name; the same QueryRow and INSERT Exec sites; no read added file:Exec@2371,file:QueryRow@2046 78b86668f2baf879be5705310942e346966a722834734a670b780b89590ed5df
+@legacy 85c97ae24776b41fc10ea021be014cc015abf9e7769f0f5b2b04ad1d0f09bd43 internal/console/templates/account_settings.html external legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): embedded UI: a Commands column, the minted line names a run credential's commands, and a commands input on the mint form; markup only; no read added file:external@0 d8b4c78309e718c4094bcf3cfbd75ab420e46fd1b1cb79a55cf454c41a1a78ad
+@legacy 028271fef8a422cfaff3179ca658e7da948ce7cface1fec720e0636d21e4cd61 internal/provision/run.go RunAdmit legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the record transition the console's run create door runs;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (RunAdmit): still applied only by the create door's admitRun through SetRecordRun's unchanged read-CAS-write; prunes run_keys older than 24h on every admission; a keyed admission checks its key before every refusal (same digest: *RunKeyReplay; another: ErrRunKeyReused; neither changes the record); a keyed admission that succeeds appends {key, run_id, digest, caller, at} and keeps each caller's newest 32, in the same write that queues the run; refusals and the queued RunState unchanged; within internal/provision only RunAdmit assigns RunKeys (TestOnlyRunAdmitWritesRunKeys); its one site is still rec.ActiveRun.Open(), a method; no read added file:Open@636 aa473b2f605cac7841bc91ce5b52594af5fc0da9e281dca411c5ea3aa9de2b12
+@legacy 3d700d09f5a46c375d4ef551edc5ecd65abeaa604814a517ff631050f076234d run.go runMetaFor legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the carlos CLI on a person's machine, as that person (no box unit): builds the run request's file list;rev3=census-ruling-pro-6214-service-runs;basis=the carlos CLI on the caller's own machine, as that caller: with --idempotency-key it also declares each --file's sha256 (runFileSum, a new unit); the same Stat of the path the caller named; no read added here file:Stat@162 4bd18823c8af404a7ddc33b69834e6617a7494bce7c44d1d600d522a3d1b9e96
+@legacy 5d1a143aac277712ed0ed9afd403ffefbe557d66251e5bc667c4471eb6a9692c internal/console/authstore.go Store.migrateCLIAuth legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): one more Exec of the kind it already makes: SQLite DDL on its own database, the partial unique index cli_tokens_credential_id; the ALTER loop adds credential_id and commands (TEXT NOT NULL DEFAULT ''); then calls backfillCredentialIDs; additive; no new kind of read file:Exec@1447,file:Exec@3087,file:Exec@3565,file:Exec@4057,file:Exec@4899 8b0dd2d959642a38990fda9645308b7182b70e0d6b7af05084b55167ecadebca
+cmd/console/main.go serve legacy accepted-legacy accepted-legacy;rev3=PROPOSED-scan-demand-revival;basis=Console service wires the optional callback signer and starts the claim-guarded queue worker. The same three data path literals move; it does not add a privileged reader.;rev3=PROPOSED-email-signin;identity=the console (cmd/console serve under console.service, user carlos-console);basis=passes CARLOS_CONSOLE_NAME to NewServer as Config.ConsoleName, the name the console's emails use; the same three /data literals at the same offsets; no read added;rev3=PROPOSED-s3-change-index;identity=the console (cmd/console serve under console.service, user carlos-console);basis=arms the record view when CARLOS_CHANGE_INDEX=read (armChangeIndex) for the run and seed sweeps and starts its backstop loop; the same three /data literals at the same offsets; no read added;rev3=census-ruling-db-region-forward-2;identity=the console (cmd/console serve under console.service, user carlos-console);basis=parses CARLOS_DB_FORWARD (dbForward) into Config.DBForward and builds its http.Server with console.NewHTTPServer, the same two timeouts; the same three /data literals at the same offsets; no read added;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): reads CARLOS_RUN_KEYS, an environment variable, into Config.RunKeysEnabled; keyed run creates are refused 503 keys_not_ready unless it is on; the same three /data literals; no read added data-literal@4077,data-literal@5178,data-literal@5415 20d2603867d98a491d9f084a69d55190ebfa76ef2b961cc7da0e00e445495ea6
+internal/console/apiruns.go Server.handleAPIRunCreate legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the run create door; it reads the record from the bucket and refuses an open run; no root decision;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors): also admits a run service (runCaller: role run with a credential id, after the unchanged shared gate and the route's svcrole.Exactly(Run), which Admin does not join); a service's argv must start word for word with one of its granted prefixes (runs.CommandGranted), else 403 command_not_granted before any object is written; on_behalf_of only from a service, one bare email of at most 254 bytes, never checked against membership, granting nothing; a keyed create (Idempotency-Key, only with CARLOS_RUN_KEYS=on) answers a key the record's run_keys holds for this caller before the record refusals and without reading a file (same digest: 202 replayed; another: 409); keyed files must declare and match their sha256; records by_service, by_credential, on_behalf_of and the scoped key hash; an open-run refusal is redacted for another caller's run; refusal codes; its one site is still rec.ActiveRun.Open(), a method, not a file; no read added (the record and request.json from the deployment bucket, as before) file:Open@2106 1b6af835b3b709a20c046837c0415d60b6c15f7d7dcc50c12bdcd0d25a0c68a6
+internal/console/apirunsfollow.go Server.handleAPIRunAck legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the ack door; clears a finished run from the record by CAS;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors, via runGate): a run service acks only its own runs; refusal codes; RunClear unchanged and leaves run_keys as they are; its one site, run.Open(), a method, moves; no read added file:Open@1316 2680a0bb0550b3c4811487dfffb8ec56ec9c381085d67ef4b6af0e3b17035587
+internal/console/apirunsfollow.go Server.handleAPIRunGet legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the follow door; pages a run's chunks and result from the bucket;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the run doors, via runGate): a run service reaches it only for a run whose request.json records its credential id, any other answering 404 as an unknown id; refusal codes; the same r.URL.Query() site; no read added file:Query@169 e426b56dc75dca7ea970785df9ad6de0fcea95bdb49dd034b511aa9c75a03384
+internal/console/apirunsfollow.go Server.runTransitionRefused legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): words a refused cancel, expire or ack from the record's run state;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): refusal codes only (run_started, run_ended and the shared codes); its one site, run.Open() on the record's run state, a method, moves; no read added file:Open@615 63e0baeadb156f6d99a674592c2e7a180f294ad71c2578e5f26383af3e1921a5
+internal/console/authstore.go Store.CLITokens legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): its Query also selects cli_tokens.commands; the same Query site; no read added file:Query@78 30216364db3a080dc80c83d5dd1fd5f34923b8da9358497e06779fa737fe23db
+internal/console/authstore.go Store.claimRawNewAppToken legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): the legacy app token's INSERT also writes a fresh credential_id (newCredentialID); the same Exec site; no read added file:Exec@264 15c4236fbbe2724dd114e67f029ee7b2c7666e348b63e68a0fa3845d4b6d17d9
+internal/console/svcprincipal.go Store.CLIPrincipal legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the credential read): its cli_tokens QueryRow also selects credential_id and commands; a run row resolves only with an app, a credential_id and a command list that parses, passes runs.CheckCommandPrefixes and is byte-identical to the canonical JSON this console writes, else it does not resolve (fail closed, the deploy rungs rule's twin); any other role carrying commands does not resolve; the same QueryRow and last_used Exec sites; no read added file:Exec@3861,file:QueryRow@286 c3244624910adb4b6b4416719957527d383aea4a48348cef3b7fdb17cc11bea7
+internal/console/svcprincipal.go Store.ServicePrincipals legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): its Query also selects cli_tokens.commands for the account's service listing; the same Query site; no read added file:Query@87 29b33d2785551e03b51b1d21bd04a48eced9ef0e3b6793e440a64bd7976ff4eb
+internal/console/svcprincipal.go Store.claimRawNewServicePrincipalScoped legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (the mint): the only writer of a run credential, from the two owner-gated mint doors (POST /api/cli/services/{account}, registered svcrole.Set{} so no service credential reaches it, and the settings page behind serviceOwner); a run credential must name an app and 1 to 32 valid command prefixes, takes no rungs, and other roles may not name commands; stores the list as canonical JSON in cli_tokens.commands and a fresh credential_id on every mint, including a reused revoked name; the same QueryRow and INSERT Exec sites; no read added file:Exec@2371,file:QueryRow@2046 78b86668f2baf879be5705310942e346966a722834734a670b780b89590ed5df
+internal/console/templates/account_settings.html external legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): embedded UI: a Commands column, the minted line names a run credential's commands, and a commands input on the mint form; markup only; no read added file:external@0 d8b4c78309e718c4094bcf3cfbd75ab420e46fd1b1cb79a55cf454c41a1a78ad
+internal/provision/run.go RunAdmit legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the console (cmd/console serve under console.service, user carlos-console): the record transition the console's run create door runs;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): AUTHORITY (RunAdmit): still applied only by the create door's admitRun through SetRecordRun's unchanged read-CAS-write; prunes run_keys older than 24h on every admission; a keyed admission checks its key before every refusal (same digest: *RunKeyReplay; another: ErrRunKeyReused; neither changes the record); a keyed admission that succeeds appends {key, run_id, digest, caller, at} and keeps each caller's newest 32, in the same write that queues the run; refusals and the queued RunState unchanged; within internal/provision only RunAdmit assigns RunKeys (TestOnlyRunAdmitWritesRunKeys); its one site is still rec.ActiveRun.Open(), a method; no read added file:Open@636 aa473b2f605cac7841bc91ce5b52594af5fc0da9e281dca411c5ea3aa9de2b12
+run.go runMetaFor legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the carlos CLI on a person's machine, as that person (no box unit): builds the run request's file list;rev3=census-ruling-pro-6214-service-runs;basis=the carlos CLI on the caller's own machine, as that caller: with --idempotency-key it also declares each --file's sha256 (runFileSum, a new unit); the same Stat of the path the caller named; no read added here file:Stat@162 4bd18823c8af404a7ddc33b69834e6617a7494bce7c44d1d600d522a3d1b9e96
+internal/console/authstore.go Store.migrateCLIAuth legacy accepted-legacy accepted-legacy;rev3=J4;basis=root-input;rev3=census-ruling-pro-6214-service-runs;basis=the console (cmd/console serve, user carlos-console): one more Exec of the kind it already makes: SQLite DDL on its own database, the partial unique index cli_tokens_credential_id; the ALTER loop adds credential_id and commands (TEXT NOT NULL DEFAULT ''); then calls backfillCredentialIDs; additive; no new kind of read file:Exec@1447,file:Exec@3087,file:Exec@3565,file:Exec@4057,file:Exec@4899 8b0dd2d959642a38990fda9645308b7182b70e0d6b7af05084b55167ecadebca
+@coverage . 238bbe91dfcc717c898df9ff417516ec72a4f6ce56fc96b2be38931a10db1d0c
+@coverage cmd/console 1a957205e84b1ef983e369a21c56b24f1f8b16b98b80c47b1851fb8a2226e20d
+@coverage internal/console 99809ec11b363ae535e588d6b4466aab9e3df1447a031474254d881eae523ea2
+@coverage internal/console/templates ae956ec35057e84094421e66ff216aeec7571bb8ab1ff6a4c499953d3754d88e
+@coverage internal/host b1ce9e67f06d3fe4ebe5a6c506387746c56026331f9d614af370b343093417dd
+@coverage internal/provision af98e837618adfad3574d90202590b944575f2ab7d53eb97c0113a2185d41ab1
+@coverage internal/runs 941ec9583b85e0d68cd483df9c447abe7f9d5bdb6577f0c15c8cf3676e23dc72
+@coverage internal/svcrole 53527cfffc108ef6e017874c15a0bb42e99a1984d97947301055890670e19f32