carlos / platform Public

Readiness, handoff and outstanding at 06:22: the launch tip 8777d28e passed its gate and CI; the replicator's next design scoped

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev b71e6dd51a909fb17c694e3c3eb1a9f53757577b parent 8777d28
3 files changed, +4 −4
  • .claude/HANDOFF.md +2 −2
  • implementation/carloku-paid-launch/OUTSTANDING.md +1 −1
  • implementation/carloku-paid-launch/READINESS.md +1 −1

CI cancelled — superseded by a newer push — run details

diff --git a/.claude/HANDOFF.md b/.claude/HANDOFF.md
index 3461259b2..92d25644e 100644
--- a/.claude/HANDOFF.md
+++ b/.claude/HANDOFF.md
@@ -7,7 +7,7 @@
Get Carloku's paid plans live with Stripe Tax and the complete metered model; have the pricing page and signup flow reviewable in the morning.
**STATUS:**
-Written 06:10 Dublin on 2026-10-03 (resumed 21:40 on 2026-10-02 after a provider limit; nothing was lost), during the second overnight run (brief: "continue overnight until we're ready to enable payments"; ready means reviewed, tested, integrated code and a scoped enablement plan, not payments switched on). Billing is OFF everywhere. No live Stripe write, no AWS change, no charge, no merge to main. **At 01:55 the currency branch (the price book and the retirement protocol) merged into this branch at `d64180a7`, after its twenty-sixth and twenty-seventh reviews ended with both reviewers accepting; the AWS principal report merged at `c4ee8807` after its seventh; the operator CLI at `1cd5a0d8`; per-line tax codes (OUTSTANDING item 17, built behind its hold, decision 16 untouched) at `e2adf26f` after three code reviews.** The merged tip `7399d9fe` passed its gate (exit 0, three cross builds) and CI. Every payment anyone can see is a labelled simulation.
+Written 06:22 Dublin on 2026-10-03 (resumed 21:40 on 2026-10-02 after a provider limit; nothing was lost), during the second overnight run (brief: "continue overnight until we're ready to enable payments"; ready means reviewed, tested, integrated code and a scoped enablement plan, not payments switched on). Billing is OFF everywhere. No live Stripe write, no AWS change, no charge, no merge to main. **At 01:55 the currency branch (the price book and the retirement protocol) merged into this branch at `d64180a7`, after its twenty-sixth and twenty-seventh reviews ended with both reviewers accepting; the AWS principal report merged at `c4ee8807` after its seventh; the operator CLI at `1cd5a0d8`; per-line tax codes (OUTSTANDING item 17, built behind its hold, decision 16 untouched) at `e2adf26f` after three code reviews.** The merged tip `7399d9fe` passed its gate (exit 0, three cross builds) and CI. Every payment anyone can see is a labelled simulation.
Review servers, all answering 200: pricing page `http://100.119.180.57:38009` (static, rebuilt from site `2fc6388`), signup and billing demo `http://100.119.180.57:41881` (**rebuilt at 02:10 from the integrated launch branch, `404e699f`, whose code is `7399d9fe`: the currency branch and the AWS principal report merged, gate and CI passed**; it runs until about 17:10 Dublin, restart recipe in `layout-review/STATE-demo.txt`; a labelled simulation, not Stripe proof: Keymail and Stripe simulated on the same listener; the `68f6ee23` build served until 02:06), console billing copy `http://100.119.180.57:45033` if still up.
@@ -45,6 +45,6 @@ Branches (all on the forge, none merged; the local gate is not CI):
- Then, each on its own branch: quantity reduction at renewal, the evidence door for a box's first minutes, the AWS principal inventory and the bucket ownership attestation door, Free-tier enforcement, dormancy and pool accounting.
**SESSION:**
-Running at 06:10: the gate on this branch's tip (the per-line tax codes merge `e2adf26f` plus this records commit), alone. Done tonight: the currency branch (`d64180a7`), the AWS principal report (`c4ee8807`), the operator CLI (`1cd5a0d8`) and per-line tax codes (`e2adf26f`) merged, each after its reviews, its gate alone and CI; `29ea6676` gate and CI passed. Next: the build list below; the approvals and decisions 1 to 16 are Paul's. Next: item 17's design (per-line tax codes; the mechanics that need no decision) on its own branch with an Astra design review; the rest of the build list. Done: the gates on `2b0abef1` (00:51Z), `0491ff76` (00:46Z), `9b872e38` (00:42Z), `4a1a92d9` (00:36Z). Then: the build list below, each on its own branch. Full package runs need `GOFLAGS=-buildvcs=false`, as the gate sets it. Detached `setsid` processes. A gate must be started with `logs/run-gate.sh`, which uses the default build cache; full runs take the gate's `-timeout 30m`.
+Nothing running at 06:22. The gate and CI passed on this branch's tip `8777d28e` (the per-line tax codes merge plus Task 5's records). Done tonight: the currency branch (`d64180a7`), the AWS principal report (`c4ee8807`), the operator CLI (`1cd5a0d8`) and per-line tax codes (`e2adf26f`) merged, each after its reviews, its gate alone and CI; `29ea6676` gate and CI passed. Next: the build list below; the approvals and decisions 1 to 16 are Paul's. Next: item 17's design (per-line tax codes; the mechanics that need no decision) on its own branch with an Astra design review; the rest of the build list. Done: the gates on `2b0abef1` (00:51Z), `0491ff76` (00:46Z), `9b872e38` (00:42Z), `4a1a92d9` (00:36Z). Then: the build list below, each on its own branch. Full package runs need `GOFLAGS=-buildvcs=false`, as the gate sets it. Detached `setsid` processes. A gate must be started with `logs/run-gate.sh`, which uses the default build cache; full runs take the gate's `-timeout 30m`.
Scratch on the box: `~/.cache/tmp/claude-1001/{currency-wt,replicator-wt,fencing-wt,evidence-wt,opcli-wt,inventory-wt,flush-wt,reduction-wt}` (git worktrees), the demo binaries, `/var/tmp/ck`, `~/.cache/carloku-gate`. The void gate logs are named `*VOID*`.
diff --git a/implementation/carloku-paid-launch/OUTSTANDING.md b/implementation/carloku-paid-launch/OUTSTANDING.md
index 2c912ba1f..47129c781 100644
--- a/implementation/carloku-paid-launch/OUTSTANDING.md
+++ b/implementation/carloku-paid-launch/OUTSTANDING.md
@@ -32,7 +32,7 @@ Each is concrete. None is waived.
### Meters (the complete metered model cannot invoice until both are proven)
-1. **Replication writes (`durability_writes_1k`) cannot be proven on any box.** The external replicator writes outside the ledger. Path A (scoped attestation) was built, reviewed in round six, and cannot prove an exclusive writer; it is off this branch and parked on `feat/carloku-scoped-attestation-20261001`. Path B (the platform's own replicator as the only writer) is **partial, unwired, and has not had a whole-branch pass from both reviewers** (nineteen builds; Opus rejected the first, second and eighth and accepts the rest with fixes, Astra rejects each on the deep items), on `feat/carloku-metered-replicator-20261001` (the forge has the tip; `READINESS.md` names it with its gate and CI state). What is built there: a request gate in `internal/lease` that stops an attempt before it is sent; an ownership generation in the registry moved by the six route columns the replicator reads (not by its own bookkeeping writes); a fleet that holds every recorder's days in doubt and watches without a request; one strict inventory with file checks (one name, ordinary siblings, a link named with its target as written and classified by that spelling through a directory-only descriptor, no crossing onto another filesystem (a same-filesystem bind alias is not detected), the chain root's owner, under a platform directory) and a second look on a timer; and shadow state made private before litestream can make it. Still open there, each named in its dispositions as blocking wiring: litestream's own opens by path after a look (needs litestream to open beneath a pinned root), replaceable ancestry above a protected directory, an admitted request delayed past the margin, a process dying between a change and the rebuild (the doubt is in memory only), device effects through an ancestor swap, hibernating aliases and claims on skipped files, required coverage that disappears without an entry, that any tenant can stop a rebuild for the box, route identity unbound to filesystem authority, and the uid binding under approval H. `DISPOSITIONS-metered-replicator.md` on that branch has every finding and what each build did about it. What is there: a litestream store whose every replica client is metered with no unmetered fallback, an owner for each database the box replicates, and a fleet store that refuses anything it cannot meter, each with tests. **Absent**: the agent wiring that binds those meters to the box's ledger, a restore path that does not shell out to the external binary, the unit change, moving the replica credentials so nothing else on the box holds them (the unit runs as the same user as the agent today), and any attestation. Until all of that exists and is approved for a box, this meter is incomplete every month and nothing is invoiced.
+1. **Replication writes (`durability_writes_1k`) cannot be proven on any box.** The external replicator writes outside the ledger. Path A (scoped attestation) was built, reviewed in round six, and cannot prove an exclusive writer; it is off this branch and parked on `feat/carloku-scoped-attestation-20261001`. Path B (the platform's own replicator as the only writer) is **partial, unwired, and has not had a whole-branch pass from both reviewers** (nineteen builds; Opus rejected the first, second and eighth and accepts the rest with fixes, Astra rejects each on the deep items), on `feat/carloku-metered-replicator-20261001` (the forge has the tip; `READINESS.md` names it with its gate and CI state). What is built there: a request gate in `internal/lease` that stops an attempt before it is sent; an ownership generation in the registry moved by the six route columns the replicator reads (not by its own bookkeeping writes); a fleet that holds every recorder's days in doubt and watches without a request; one strict inventory with file checks (one name, ordinary siblings, a link named with its target as written and classified by that spelling through a directory-only descriptor, no crossing onto another filesystem (a same-filesystem bind alias is not detected), the chain root's owner, under a platform directory) and a second look on a timer; and shadow state made private before litestream can make it. Still open there, each named in its dispositions as blocking wiring: litestream's own opens by path after a look (needs litestream to open beneath a pinned root), replaceable ancestry above a protected directory, an admitted request delayed past the margin, a process dying between a change and the rebuild (the doubt is in memory only), device effects through an ancestor swap, hibernating aliases and claims on skipped files, required coverage that disappears without an entry, that any tenant can stop a rebuild for the box, route identity unbound to filesystem authority, and the uid binding under approval H. `DISPOSITIONS-metered-replicator.md` on that branch has every finding and what each build did about it. What is there: a litestream store whose every replica client is metered with no unmetered fallback, an owner for each database the box replicates, and a fleet store that refuses anything it cannot meter, each with tests. **Absent**: the agent wiring that binds those meters to the box's ledger, a restore path that does not shell out to the external binary, the unit change, moving the replica credentials so nothing else on the box holds them (the unit runs as the same user as the agent today), and any attestation. Until all of that exists and is approved for a box, this meter is incomplete every month and nothing is invoiced. Scoped 2026-10-03 06:20 for the next design, not built: the replicator's eleven deferred items (dispositions of review twenty) need one design before any wiring, in three parts: the replicator's own opens beneath a root pinned at admission (`os.Root` on Go 1.26 resolves beneath a directory descriptor and refuses a link out; the header read, the listing and the link reads go through it, with the manual `openat` walk in `internal/privatefile` as the shape on a kernel where `openat2` is blocked); the vendored litestream's opens beneath the same root (its database and WAL opens are by path through the sqlite driver, which takes no descriptor; the candidates are a fork taking an `*os.Root` for its own files and a descriptor-derived path for the connection, each with a stated cost); and durable transition state across a crash or restart (an admitted request's deadline and the uncertainty after exit, journaled). The box-wide refusal (decision) and approval H stay separate.
2. **Store transfer (`store_egress_gb`) has no source.** No Cost and Usage Report export exists on the account. It needs the scoped infrastructure approval, a first real delivery, a basis for the ledger's completeness claim on AWS that no listing can give (decision 14 and proposals A and B in `docs/superpowers/plans/2026-10-02-aws-principal-inventory.md`: a rule the account enforces and a bucket whose creation is provably the grant's own, neither designed; the attestation plan's IAM-read proof is superseded), and the resource side of stores that already exist (bucket policy, ACL, access points; not built). The principal report on `feat/carloku-principal-inventory-20261002` is **a report for a person, not the proof**, in its fifth review; never run against AWS.
3. **A store's partial first hour** with a charged line holds the month, and nothing releases it. It holds by default and nobody is asked to waive it. What can release it is evidence: an operator door that records, for one bucket-hour, who is shown to have owned it and on what evidence, which the fold then honours. **Partial, unwired into this branch**, on `feat/carloku-bucket-hour-evidence-20261001` (`0aa1fbec`, rebased onto this branch): the record, the fold change and three operator API doors, with tests and mutation checks. It accepts only the hour a complete ledger began vouching in and only the owner that ledger names. The full local gate passes on it. First review: Astra rejected it, Opus accepted with fixes. Both confirmed that through the fold it releases nothing but that hour for that owner. Both also found that the evidence is free text that the same operator records and that stands at once, which in practice is a waiver: what counts as evidence, and whether a second person must approve it, needs Paul's ruling (approval J) before more is built. Nothing fixed yet (`DISPOSITIONS-bucket-hour-evidence.md` on that branch). No CI run, no CLI verb, and its operator-facing sentences are unreviewed.
4. **A box's first minutes** before its ledger opened hold that day for everyone. Same as item 3: it holds by default, and the release is an operator evidence door, not a waiver. **Absent**.
diff --git a/implementation/carloku-paid-launch/READINESS.md b/implementation/carloku-paid-launch/READINESS.md
index dc8f92f2d..6ed6a63c5 100644
--- a/implementation/carloku-paid-launch/READINESS.md
+++ b/implementation/carloku-paid-launch/READINESS.md
@@ -19,7 +19,7 @@ Log files are under `/home/paulca/.local/share/carloku-paid-launch-20260930/logs
| `feat/carloku-storage-sole-holder-20261001` | `eaf6e63e` | passed on `3af02a65`; `eaf6e63e` is wording and reports | passed | 9 rounds; round 9 both accept (omitted-holder class closed) | needs approval K and a recorded cutover date; not merged |
| `feat/carloku-metered-replicator-20261001` | `e1280811` (review twenty answered with comments, a fixture and dispositions only; the code is the twentieth build `c9ec11eb`: a tree claim refuses a tenant's file in a platform directory too, the fixture's guard reachable, the no-recorder refusal quoted; after `53e3dcd8`, the nineteenth build: a tenant's file in a platform directory refused in both layouts, the long-target fixture within the pathname budget and under XFS's link limit, refusal messages quoted; after `6249af63`, the eighteenth; reviews eight to eighteen's reports in the tree) | passed on every code tip through `f306222c`, then **failed on `bffc76b5`** (`gate-replicator-bffc76b5.txt`, exit 2: the seventeenth build's long-target fixture held only under a temp root of about 34 bytes or more; the gate's `/var/tmp/ck` is shorter), passed on `6249af63` (09:04Z, `gate-replicator-6249af63.txt`, exit 0, three cross builds, clean tree); `53e3dcd8`: passed (09:38Z, `gate-replicator-53e3dcd8.txt`, exit 0, three cross builds); `c9ec11eb`: passed (09:52Z, `gate-replicator-c9ec11eb.txt`, exit 0, three cross builds); `e1280811`: passed (10:10Z, `gate-replicator-e1280811.txt`, exit 0, three cross builds). Void: `gate-replicator-e8211fc6-VOID-stopped-for-astra17-followup.txt` (stopped so Astra's report could be answered in the same build) | passed through `f306222c`; **failed on `bffc76b5`** (the same fixture); passed on `6249af63`, `53e3dcd8`, `c9ec11eb` and `e1280811` | 4 to 7: each Opus accept with fixes, Astra reject; 8: both reject on one P1 the eighth build made (fixed in the ninth); 9 to 15: Opus accept with fixes, Astra reject, each round finding the previous build's own addition wanting (15 at `03b19014`: the fifteenth build joined a relative link target and so cleaned a `..` the kernel resolves physically, a regression that let a link to a directory outside the tree pass in silence; fixed in the sixteenth build by concatenating uncleaned, with the fixture both asked for); 16 at `f306222c`: Opus accept with fixes, Astra reject; both found the fifteenth's regression closed and one bound Astra named (the concatenated spelling could outgrow PATH_MAX), fixed in the seventeenth build `bffc76b5` with `fstatat` against the link's directory. 17 at `bffc76b5`: Opus accept with fixes, Astra reject; both named the same two new defects in that fix: the directory was opened by path with Go's default flags (a FIFO a tenant swaps in blocks the watch and Close; a device would have its driver's open run) and the long-target fixture failed under any short temp root (which is what failed the gate and CI). The eighteenth build opens the directory with `O_DIRECTORY|O_NONBLOCK|O_NOCTTY|O_CLOEXEC` (anything but a directory refused by the open itself; three mutants killed: default flags, `O_DIRECTORY` alone dropped, the fixed fixture size under `/var/tmp/ck`), sizes the fixture from the temp root, compares `render` across sections, and corrects the comments and names Astra listed; the false "package tests pass under /tmp" claim of the seventeenth build is marked false in its dispositions. 18 at `6249af63`: Opus accept (three P3s: the fixture's 3 KB link target, which XFS refuses; a tenant's file in a platform directory accepted under the tenant's tree and refused under the platform's; wording), Astra reject on the deep items (and the fixture's fixed depth). The nineteenth build `53e3dcd8` answers them (two mutants killed). 19 at `53e3dcd8`: Opus accept (two P3s), Astra reject on the deep items; the twentieth build `c9ec11eb` makes the bounded changes (one mutant killed) and its dispositions list the deferred items separately, each as blocking wiring and needing a design or a decision. 20 at `c9ec11eb`: Opus accept with fixes, Astra reject on the deep items; `e1280811` changes no behaviour and is not sent for another round; the two refusals Opus named as decisions are in `DECISIONS-FOR-PAUL.md` (11, 12). Each build's dispositions section lists its killed mutants. The deep items stay open and are listed there: litestream's own opens by path (every reopen), protected endpoints under tenant-replaceable ancestry, a delayed admitted request past the margin, requests across a crash or restart, the header open through a swapped ancestor (a walk by directory descriptor, required before wiring), a tenant sharing the platform's uid, root-run units and a route naming another user's coherent tree (approval H), hibernating aliases and claims on skipped files, required coverage that can vanish without an entry, whether one tenant's unaccepted links refuse the whole box (a decision before wiring), one tenant's deletion holding every account's days once (a stated cost). None of these is minor: the branch cannot be wired until they are closed or decided | not merged; unwired side work gated on approval H |
| `fix/carloku-observe-routes-cleanup-20261001` | `023e106c` | passed on `51587e00`; `023e106c` changes a test and two docs | passed | both accept at `51587e00` | merged into the launch branch at `47c97fa6` |
-| `feat/carloku-paid-launch-20260916` (launch) | this commit: documents only on top of `e2adf26f`, the merge of per-line tax codes (06:10); before it `1cd5a0d8` (the operator CLI), `d64180a7` (the currency branch) and `c4ee8807` (the AWS principal report) | the gate on this commit runs next, alone; `29ea6676`: **passed** (01:15Z, `gate-launch-29ea6676.txt`, exit 0, three cross builds); CI passed on `29ea6676`. `7399d9fe` (the currency merge `d64180a7` plus records): **passed** (`gate-launch-7399d9fe.txt`, exit 0, three cross builds, alone); CI passed on `7399d9fe`. `0491ff76` (the inventory merge plus records): **passed** (00:46Z, `gate-launch-0491ff76.txt`, exit 0, three cross builds). passed 03:06Z on `b953fae4` (`gate-launch-b953fae4.txt`, exit 0, three cross builds); every commit since is documents | passed on `3d47602b` | 17 rounds, no whole-branch pass | **the currency branch and the AWS principal report are merged in; the operator CLI is merged in (its public section waits on Paul's reading before any publish); everything else is as listed below.** the integration target; first accepted side branch merged |
+| `feat/carloku-paid-launch-20260916` (launch) | this commit: documents only on top of `e2adf26f`, the merge of per-line tax codes (06:10); before it `1cd5a0d8` (the operator CLI), `d64180a7` (the currency branch) and `c4ee8807` (the AWS principal report) | `8777d28e` (the per-line tax codes merge `e2adf26f` plus Task 5's records): **passed** (05:13Z, `gate-launch-8777d28e.txt`, exit 0, three cross builds, alone); CI passed on `8777d28e`. `29ea6676`: **passed** (01:15Z, `gate-launch-29ea6676.txt`, exit 0, three cross builds); CI passed on `29ea6676`. `7399d9fe` (the currency merge `d64180a7` plus records): **passed** (`gate-launch-7399d9fe.txt`, exit 0, three cross builds, alone); CI passed on `7399d9fe`. `0491ff76` (the inventory merge plus records): **passed** (00:46Z, `gate-launch-0491ff76.txt`, exit 0, three cross builds). passed 03:06Z on `b953fae4` (`gate-launch-b953fae4.txt`, exit 0, three cross builds); every commit since is documents | passed on `3d47602b` | 17 rounds, no whole-branch pass | **the currency branch and the AWS principal report are merged in; the operator CLI is merged in (its public section waits on Paul's reading before any publish); everything else is as listed below.** the integration target; first accepted side branch merged |
| `feat/carloku-quantity-reduction-20261002` | `978ddc8a` (design only, off `68f6ee23`) | n/a (no code) | n/a | Astra's design review rejected revision 1 on four P1s (a request can cross the renewal and its confirmation proves nothing about the invoiced quantity; a future-dated assignment blocks every change before the renewal; a missed window postpones the reduction a year in silence; fence-only enablement leaves no path to restore returning seats). Revision 2 waits on three decisions that are Paul's (`2026-10-02-quantity-reduction-at-renewal-design.md`, last section) | OUTSTANDING 14 stays absent in code |
| `feat/carloku-flush-only-class-20261002` | `5f43a0e4` (off the launch branch at `65363554`; a unit-backed route's rung can be cleared; the test waits for the start-up snapshot; after `5c327226`): the `hibernate-flush` word in the registry's vocabulary and the activator's interval map, **withdrawn from the rungs on offer and set by nothing**; the CLI rail refuses any rung on a unit-backed route | `0e8ea227` **failed** (the CLI's word test; `gate-flush-0e8ea227-FAILED-cli-word-test-stopped.txt`); `5c327226` passed (12:54Z); `5f43a0e4` passed (13:35Z, `gate-flush-5f43a0e4.txt`, exit 0, three cross builds) | `0e8ea227` failed; `5c327226` and `5f43a0e4` passed | 1 at `0e8ea227`: Opus accept with fixes, Astra reject: the ten-year interval does not give "wake and sleep only" against the vendored litestream (daily snapshot while awake; the awake backlog waits for a 30-second flush at sleep; the local log untrimmed), so the class's contract is decision 10a and nothing of its options is built; the inherited defect Astra found (`Replicator.Close` can return nil having flushed nothing) is forge discussion 200. 2 at `5c327226`: both accept with fixes (the unit-backed refusal blocked clearing an existing rung; the test raced the start-up snapshot; listings print the raw word; three inaccurate statements), fixed in `5f43a0e4`, which has not been read by a reviewer. Stated open and unchanged: `Replicator.Close` can return nil having flushed nothing and a failed flush still ends in hibernation (inherited, every class, forge discussion 200); the unbounded awake backlog; no verified wake boundary; class-blind restore drill and lag thresholds | **does not implement the Free plan's durability**; not mergeable as a feature until 10a; the rest of OUTSTANDING 15 waits on who is Free |
| `feat/carloku-billing-operator-cli-20261002` | `fc7daebd` (a merge of the currency tip `2b0abef1`); before it `6d4c2912` (the fourth review's P3s answered: `account_deleted` always on the wire and printed; the console's own 5xx on a write; the moved console after the offer; the help's two facts); before it `4e9cac43` (`f9683fbe`: the third review's twelve P3s answered: a write names its console or is refused; refusals from in front of the console; the moved console through the interactive offer; the whole command tested through `runBillingWith`; then the currency tip `e152df30` merged in); before it `31731fdd` (Astra's second review answered in `f155e543`: ambiguous flag values refused, the keep wording, strict listing envelopes, write advice that fits the write, the console's note predicate, `billingRun` tested; then the currency tip `05ccec07` merged in); before it `51ef27ac` (the first review answered in `57f70c16`, then the currency tip `b260ac8e` merged in): `carlos billing reviews\|resolve\|rejected\|house`, a client for the four operator doors | `fc7daebd`: **passed** (01:04Z, `gate-opcli-fc7daebd.txt`, exit 0, three cross builds, alone). `40ea61b1`: **passed** (00:08Z, `gate-opcli-40ea61b1.txt`, exit 0, three cross builds, alone). `6d4c2912` was not gated on its own (superseded by the merge). `4e9cac43`: **passed** (23:09Z, `gate-opcli-4e9cac43.txt`, exit 0, three cross builds, alone). `51ef27ac`: **passed** (21:29Z, exit 0, three cross builds); `31731fdd`: **passed** (22:16Z, `gate-opcli-31731fdd.txt`, exit 0, three cross builds). `0f507bff` **failed** (exit 2, `gate-opcli-0f507bff.txt`): one test, the docs gate, which requires a `carlos billing` heading in the public CLI reference. `51ef27ac`: started 21:18Z, run alone (`gate-opcli-51ef27ac.txt`) | passed on `6d4c2912`, `40ea61b1` and `fc7daebd`; `0f507bff` failed (the docs gate) | 4 at `4e9cac43`: **both accept with fixes, all P3**, answered in `6d4c2912` (CI passed); no fifth review unless the client changes. 3 at `31731fdd`: **both accept with fixes** (six P3 each), answered in `f9683fbe`; a fourth reading not started. 2 at `51ef27ac`: Astra accept with fixes (three P2, six P3), answered in `f155e543`; Opus's second reading and Astra's third running on `31731fdd`. 1 at `0f507bff`: Opus accept with fixes (P1 the docs gate, four P2), Astra reject (five P2). Answered in `57f70c16`: arguments are one unambiguous request or refused before anything is sent; writes are reported only on the door's acknowledgement and name the console; one wire-contract file both sides' tests read. Second review not started | **merged into this branch at `1cd5a0d8` (02:12, a merge commit) after the gate and CI on `fc7daebd`; its `docs/site/cli.md` section is unreviewed public copy and must be read before anything publishes the site's CLI page (merging publishes nothing)**; before: not merged (it is built on the currency branch, which merges first). **Its `docs/site/cli.md` section is new public copy and is unreviewed**: it does not merge before Paul reads it