carlos / platform Public

Readiness, decisions, enablement and handoff at 23:22: round twenty-two not accepted and answered in 2618403f; the operator CLI's gate passed on 31731fdd; the principal inventory is a report, not the proof (decision 14 reworded); decision 15 and the test-mode gate on a dead subscription

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 582c663b2f7b4ef820f6300d3b176a2e5403040c parent 33bae77
5 files changed, +29 −19
  • .claude/HANDOFF.md +7 −7
  • implementation/carloku-paid-launch/DECISIONS-FOR-PAUL.md +7 −6
  • implementation/carloku-paid-launch/ENABLEMENT.md +10 −1
  • implementation/carloku-paid-launch/OUTSTANDING.md +2 −2
  • implementation/carloku-paid-launch/READINESS.md +3 −3

CI passed — run details

diff --git a/.claude/HANDOFF.md b/.claude/HANDOFF.md
index 0f876a975..9de01669d 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 22:21 Dublin on 2026-10-02 (resumed at 21:40 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. Every payment anyone can see is a labelled simulation.
+Written 23:22 Dublin on 2026-10-02 (resumed at 21:40 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. 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` (**still the build from `68f6ee23`**, before the retirement protocol; not the code under review, and not Stripe proof; price book configured, USD/EUR/GBP end to end; Keymail and Stripe simulated), console billing copy `http://100.119.180.57:45033` if still up.
@@ -16,23 +16,23 @@ The durable records are on this branch under `implementation/carloku-paid-launch
Decisions received 2026-10-01 evening, applied: the annual bases (28/24/22, 6/5/4.50, 60/50/45 USD/EUR/GBP, team minimum ten) confirmed for implementation only; the currency rulings (USD default, EUR for EU member states, GBP for the UK, visible override, one stored currency for subscription and overages, bands by billing country only); the five currency strings and the regrouped pricing page copy, approved verbatim and applied. Still a draft: the book `2026-10-01-draft1` and the USD/GBP overage rates and floors.
Branches (all on the forge, none merged; the local gate is not CI):
-- `feat/carloku-multi-currency-20261001` `b260ac8e`: the price book and one stored currency per purchase end to end, one form with a server-signed quote, ownership on every path, the retirement protocol's stage one, and the evidence invariant made structural (every provider read of a session or subscription goes through three recording methods; a parser test forbids any other). Gate passed on `b260ac8e` (21:13Z, run alone) and CI passed. **Not accepted: round twenty-one is Opus accept with fixes, Astra reject.** Both found one new P2 that round twenty's own fix opened (an intent that never had a session is cleaned up under its review, and `retire` then passes with a subscription attached); Astra found two more P2s (a subscription seen before any refusal vanishes when an ordinary purchase consumes the intent; held currency and customer not rechecked in the transaction that creates an intent). **Review eighteen's P2 stays open.** The gate failure on `43d326b5` was the gate's scratch build cache being deleted under it, not the tree; the gate script now uses the default cache.
+- `feat/carloku-multi-currency-20261001` `2618403f`: the price book and one stored currency per purchase end to end, one form with a server-signed quote, ownership on every path, the retirement protocol's stage one, the evidence invariant made structural, and the named-subscription rule (a subscription that names an intent is recorded from the first read, and nothing deletes an intent past one). Gates passed on `b260ac8e` and `05ccec07` (alone, default cache); CI passed on both; the gate on `2618403f` is running. **Not accepted: round twenty-two (on `05ccec07`) is Opus accept with fixes, Astra reject**, each round closing the last one's findings. Opus says review eighteen's P2 is closed for deletion and consumption; the branch keeps it recorded open until a round accepts. Round twenty-three is running on `2618403f`. What the rule costs an honest buyer if the provider ever makes a subscription before its checkout completes is a test-mode gate (`ENABLEMENT.md` section 6 step 2) and decision 15.
- `feat/carloku-metered-replicator-20261001` `6249af63`: eighteenth build. Reviews ten to fourteen (Opus accept with fixes, Astra reject) each found the previous build's own addition wanting; the fourteenth build made the link entry one to one and the fifteenth quotes every entry in the inventory's rendering (the drift key), classifies a link by the spelling its entry names, and makes the Accept test tell as-written from cleaned. Review fifteen (Opus accept with fixes, Astra reject on the deep items) found a regression the fifteenth build made: a relative link target was joined and so cleaned, which is not how the kernel resolves a `..` after a link, so a link to a directory outside the tree passed in silence; the sixteenth build concatenates uncleaned, with the fixture both asked for. Review sixteen (both) found that fixed and one bound left (the concatenated spelling could outgrow PATH_MAX); the seventeenth build `bffc76b5` stat'ed the target by itself against the link's directory, and **failed the gate and CI on its own fixture** (sized for a long temp root only), which review seventeen (Opus accept with fixes, Astra reject) had worked out, together with a worse defect in the same fix: the directory was opened by path with Go's default flags, so a FIFO a tenant swaps in would block the watch and Close. The eighteenth build (`e8211fc6`, `6249af63`) opens the directory as a directory and nothing else, sizes the fixture from the temp root, compares the rendering across sections, and corrects the comments, the test name and the outstanding item Astra listed; three mutants killed. Gate (exit 0, three cross builds) and CI passed on `6249af63`. Review eighteen: Opus accept with three P3s, Astra reject on the deep items. The nineteenth build `53e3dcd8` answered them (gate exit 0, three cross builds; CI passed). Review nineteen: Opus accept, Astra reject on the deep items. The twentieth build `c9ec11eb` makes the bounded changes (a tree claim refuses what a file claim refuses; the fixture's guard reachable; the no-recorder refusal quoted) and separates them in its dispositions from the deferred items; `c9ec11eb`: gate exit 0 with three cross builds (09:52Z), CI passed. Review twenty: Opus accept with fixes, Astra reject on the deep items. `e1280811` answers it with comments, a fixture and dispositions only (no behaviour change; gate running; not sent for another round): the two refusals Opus named as widening what stops a whole box are listed as decisions (11 and 12 in the decisions file), not made as changes. The deep items stay open and are listed in `READINESS.md`; none is minor, and the branch cannot be wired until they are closed or decided (the walk by directory descriptor, litestream's opens by path, durable transition state, the uid binding under approval H, the box-wide refusal decision).
- `feat/carloku-storage-sole-holder-20261001` `eaf6e63e`: round 9 both accept; CI passed; needs approval K and a cutover date.
- `fix/carloku-observe-routes-cleanup-20261001` `023e106c`: both accept; CI passed; merged into this branch at `47c97fa6`; the gate on the launch tip `b953fae4` passed (exit 0, three cross builds).
- `feat/carloku-billing-layout-20261001` `c1ae91a0`: merged into the currency branch; its two-form page was replaced by one form.
-- `feat/carloku-billing-operator-cli-20261002` `51ef27ac`: `carlos billing`, a client for the four operator doors. Its first review (Opus accept with fixes, Astra reject) is answered; gate running at 22:21 (`logs/gate-opcli-51ef27ac.txt`); second review not started. Its section in `docs/site/cli.md` is new public copy, unreviewed: it does not merge before Paul reads it.
-- `feat/carloku-principal-inventory-20261002` `d61f4f27`: the AWS principal inventory for the store-transfer meter. Built, unwired, unreviewed, never run against AWS; gate not yet run. Needs decision 14 and one IAM permission.
+- `feat/carloku-billing-operator-cli-20261002` `31731fdd`: `carlos billing`, a client for the four operator doors. Two Astra reviews answered (`57f70c16`, `f155e543`); gates passed on `51ef27ac` and `31731fdd`; Opus's second reading and Astra's third are running. Its section in `docs/site/cli.md` is new public copy, unreviewed: it does not merge before Paul reads it.
+- `feat/carloku-principal-inventory-20261002` `199a9736`: a report of who in the AWS account reaches a store bucket name, for a person. Its first review (Astra reject) showed one listing cannot be the ledger's proof, and it no longer offers to be; what the proof needs is decision 14 (an enforced rule; minted bucket names). Gate not yet run; Astra's second review running; Opus not yet read; never run against AWS.
- `feat/carloku-late-request-fencing-20261001` `1b61de82`, `feat/carloku-bucket-hour-evidence-20261001` `0aa1fbec`: unchanged (rejected / needs approval J).
- Site `feat/paid-pricing-20260916` (GitHub) `4026231`: `build` and `check` render from the export before the draft check (a stale page cannot be published past a newer export); a floor that is not whole cents is refused rather than shown as `$1.20.5`; after `c12318d`: every amount from the platform's export; country band wiring; exact rates; honest link parameters, static links included; a draft book cannot be published by `check` or `build`; `bands.p3` carries the approved currency explanation; every priced slot, in every currency and band, and every banded inclusion equals its exported value; a figure is a whole number token on both sides (21 tests pass: `node --test test/*.test.mjs`).
**NEEDED:**
-- **Start here: `implementation/carloku-paid-launch/DECISIONS-FOR-PAUL.md`.** Fourteen numbered choices in five groups (a refused purchase; people who leave a team; who is Free; the replicator; whose principals are the platform's), each with a proposal and what it unblocks, so they can be answered together. The lettered approvals A to M are separate and listed below.
+- **Start here: `implementation/carloku-paid-launch/DECISIONS-FOR-PAUL.md`.** Fifteen numbered choices in five groups (a refused purchase, including a dead subscription naming one; people who leave a team; who is Free; the replicator; how a store bucket is proven the tenant's alone), each with a proposal and what it unblocks, so they can be answered together. The lettered approvals A to M are separate and listed below.
- Paul, commercial: approve the 36 amounts as an `approved` book version (approval L) together with the USD/GBP overage rates and floors in `OVERAGE-RATES-PROPOSAL.md`, or state other figures; the HALF code word; the proration policy (B); the partial-month rule (C).
- Paul, copy: the console billing page's 40 strings; the store-refusal copy (`OUTSTANDING.md` 19g). `bands.p3` is done: the approved currency explanation replaced the converted-euro sentence (site `e091e3f`, 07:0x); it now reads the same as the note under the currency selector.
- Paul, rulings: evidence for a held bucket-hour (J); storage on a bucket a store has left (K); the cutover note (M: purchases before the book stay legacy EUR; binary first, variables second).
- Scoped approvals, prepared as plans only: Stripe test mode (E) for the fence test and the rehearsal; Stripe live provisioning (F) after the approved book; the Cost and Usage Report export and the scratch-object write (G); Path B on a dev box (H).
-- Reviews on disk: the currency branch's twenty-first (`logs/opus-currency-review21.md`, `astra-currency-review21.md`), being answered; the operator CLI's first (`logs/opus-opcli-review1.md`, `astra-opcli-review1.md`), answered.
+- Reviews on disk: the currency branch's twenty-second (`logs/opus-currency-review22.md`, `astra-currency-review22.md`), answered in `2618403f`; the operator CLI's first and Astra's second, answered; the inventory's first (Astra), answered in `199a9736`.
- Branch `feat/carloku-flush-only-class-20261002` `5f43a0e4` (gate and CI green; second review: both accept with fixes, fixed here, unread). It does not implement the Free plan's durability: its first review showed the class's durability contract is itself a decision (10a in the decisions file): against the vendored litestream "wake and sleep only" is not what a long interval gives. Nothing of the options is built; the class is a word the column may hold, withdrawn from offer. The inherited `Replicator.Close` defect the review found is forge discussion 200, not fixed.
- Paul, rulings for the retirement design (five, its last section): may money ever be accepted without the purchase recording (the design says no); how contradictory provider evidence is adjudicated; the buyer's copy under review; the settlement predicate for a paid refused purchase; whether a never-bound session may be kept. Rulings for quantity reduction at renewal (`feat/carloku-quantity-reduction-20261002`, design rejected by Astra on four P1s; its last section): a member replaced before the renewal (window, schedule or immediate); a missed reduction's remedy; reductions behind both switches.
@@ -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 22:21: the gate on the operator CLI tip `51ef27ac` (`logs/gate-opcli-51ef27ac.txt`), alone. Queued: the gate on the inventory tip `d61f4f27`; the answer to round twenty-one on the currency branch (uncommitted work will be in `~/.cache/tmp/claude-1001/currency-wt`); then round twenty-two. Detached `setsid` processes. A gate must be started with `logs/run-gate.sh`, which uses the default build cache: a scratch cache deleted mid-run is what failed the gate on `43d326b5`.
+Running at 23:22: the gate on the currency tip `2618403f` (`logs/gate-currency-2618403f.txt`, alone); round twenty-three on it (`logs/opus-currency-review23.md`, `astra-currency-review23.md`); the operator CLI's third review on `31731fdd` (`opus-opcli-review3.md`, `astra-opcli-review3.md`); the inventory's second review on `199a9736` (`astra-inventory-review2.md`; its Opus reading, `run-opus-inventory-2.sh`, waits for an Opus slot). Queued: the gate on the inventory tip `199a9736`. Detached `setsid` processes. A gate must be started with `logs/run-gate.sh`, which uses the default build cache: a scratch cache deleted mid-run is what failed the gate on `43d326b5`.
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/DECISIONS-FOR-PAUL.md b/implementation/carloku-paid-launch/DECISIONS-FOR-PAUL.md
index 9c9900f80..ffaa1ae64 100644
--- a/implementation/carloku-paid-launch/DECISIONS-FOR-PAUL.md
+++ b/implementation/carloku-paid-launch/DECISIONS-FOR-PAUL.md
@@ -1,6 +1,6 @@
# Decisions for Paul, in one place
-Written 2026-10-02, 11:02 Dublin; items 2 and 10a revised 11:04; the state of stage 1 and of the flush-only branch corrected 16:43. Item 14 and the state of stage 1 added 22:21. Each item is a choice only Paul can make, with what was proposed and what it unblocks. Nothing here is decided. Billing is off; nothing was deployed. The lettered approvals A to M (copy, proration, partial month, test mode, live provisioning, the book, the cutover note, and the meters' G, H, J, K) are in `OUTSTANDING.md` and `ENABLEMENT.md` section 8 and are not repeated here.
+Written 2026-10-02, 11:02 Dublin; items 2 and 10a revised 11:04; the state of stage 1 and of the flush-only branch corrected 16:43. Item 14 and the state of stage 1 added 22:21; item 15 added and item 14 reworded 23:22. Each item is a choice only Paul can make, with what was proposed and what it unblocks. Nothing here is decided. Billing is off; nothing was deployed. The lettered approvals A to M (copy, proration, partial month, test mode, live provisioning, the book, the cutover note, and the meters' G, H, J, K) are in `OUTSTANDING.md` and `ENABLEMENT.md` section 8 and are not repeated here.
Answer by number. "As proposed" is a complete answer to any of them.
@@ -12,7 +12,9 @@ Context: when a checkout is refused (wrong currency, a hand-made subscription),
2. **What "settled" requires.** Before a refused purchase that took money, or that a hand-made subscription was attached to, can be closed. Proposed: for every subscription attached to the case (the checkout's own and any made by hand), the payment refunded in full (a refund that has succeeded, not one pending), the subscription canceled, no open or collectible invoice on it; the operator names each refund and subscription; the console checks each subscription is canceled and holds the case while a refund is pending. Canceling a subscription is not by itself settling it.
3. **Stripe contradicting itself** about one checkout (expired, then paid; or its account changed). Proposed: hold the account and let a person close it only after a fresh read of Stripe agrees with what they are closing it as; no exception for a checkout whose account stays wrong (it stays held).
4. **A checkout the console never bound** (its creation answer was lost, and it was found paid later). May it be kept as the purchase? Proposed: no; it can be closed (expired or settled), never kept.
-5. **What the buyer sees** while their purchase is under review. Proposed copy, for review: "we are checking this purchase. nothing more will be charged. we will email you."
+5. **What the buyer sees** while their purchase is under review.
+
+15. **A dead subscription naming a purchase.** The protocol now records every subscription seen naming a checkout and lets no checkout go while one is unaccounted for. If the provider ever makes a subscription before the checkout completes and then abandons it (`incomplete_expired`: the first invoice never paid, voided by the provider), an honest buyer's checkout is held with nothing a person can do in stage 1. Whether the provider does this is the first check of the test-mode rehearsal (`ENABLEMENT.md` section 6, step 2). If it does: may a subscription the provider reports `incomplete_expired`, with no paid invoice, be treated as nothing owed, so that it neither holds an expiry nor disputes a purchase? Proposed: yes, on a fresh read of the subscription and of its invoices showing none paid; anything else stays held. Proposed copy, for review: "we are checking this purchase. nothing more will be charged. we will email you."
## B. People who leave a team (quantity reduction at renewal; team plans cannot be sold without it)
@@ -43,9 +45,7 @@ Context: `feat/carloku-metered-replicator-20261001` has had twenty builds; Opus
Context: a store bucket's transfer is billed to its tenant only if the ledger can show nobody else had access to the bucket. On AWS that needs a list of every principal whose policy reaches the bucket's name. That list is now built (`feat/carloku-principal-inventory-20261002`, unwired, never run against AWS).
-14. **Which principals are the platform's own.** The host role (it creates and deletes store buckets; it cannot read objects) and any administrator role reach every store bucket. Counted as outsiders, they mean no bucket is ever provably the tenant's alone, and the meter never bills. AWS charges transfer by bucket and does not say who moved the bytes, so if staff download from a tenant's bucket, that transfer lands on the tenant. Proposed: the platform's own principals are declared one by one, by ARN, in the deployment's configuration and written into each ledger's evidence; only the host role and roles that need account administration to assume may be declared; staff do not read tenant buckets, and if support ever requires it the platform credits the bytes.
-
-It also needs one permission (approval, not a decision): `iam:GetAccountAuthorizationDetails` for the console's role, which reads every policy document in the account and which the host module withholds today. The alternative is an operator running the listing by hand for each new store.
+14. **How a store bucket is proven to be the tenant's alone, and who else may reach one.** The first build tried to prove it by listing the account's principals; its review showed (rightly) that one listing of an eventually consistent account cannot prove it: a policy attached a moment before can be missing, a role set aside as the platform's is also everyone its trust policy lets assume it, and a bucket absent now can be created by someone else before the grant creates it. So the listing is now a report for a person, and the proof needs two things the account enforces, each a design and an infrastructure change for your approval: (a) a rule (an organization policy, or a required permissions boundary plus an account rule) that denies S3 on the store bucket prefix to every principal except the store users and a short list named by ARN; (b) bucket names the grant mints with a random part recorded before any provider call, and a grant that refuses a bucket that already exists for any reason. And the decision proper: who is on the named list. The host role (it creates and deletes store buckets; it cannot read objects) and administrator roles reach every store bucket; AWS charges transfer by bucket and does not say who moved the bytes, so if staff download from a tenant's bucket, that transfer lands on the tenant. Proposed: only the host role and roles that need account administration to assume, named one by one with each role's trust policy part of the record; staff do not read tenant buckets, and if support ever requires it the platform credits the bytes; and approve the direction of (a) and (b) or say what should stand in their place. The report itself can be run by an operator with their own credentials and needs no console permission.
## What each answer unblocks
@@ -57,4 +57,5 @@ It also needs one permission (approval, not a decision): `iam:GetAccountAuthoriz
| 9 | the Free entitlement, the app cap, per-plan idle, storage refusal |
| 10a | the flush-only class's contract. The branch has the class with a ten-year interval, which both reviews showed does not give "wake and sleep only" and can leave sleep not durable; the hourly backstop is a proposal and is **not built** |
| 10 to 13 | the replicator's design for the deferred items, then wiring, then the replication-writes meter |
-| 14 | wiring the principal inventory (with the IAM permission), then the attestation of the four existing stores, then the store-transfer meter (which also needs the Cost and Usage Report export, approval G) |
+| 14 | the design of the enforced rule and the minted bucket names, then their build and review, then the attestation of the four existing stores, then the store-transfer meter (which also needs the Cost and Usage Report export, approval G) |
+| 15 | nothing until the test-mode rehearsal answers its question; if the provider does make such subscriptions, the code that reads an attached subscription's status before stage 1 can be enabled |
diff --git a/implementation/carloku-paid-launch/ENABLEMENT.md b/implementation/carloku-paid-launch/ENABLEMENT.md
index 108148f91..bb5e3a14c 100644
--- a/implementation/carloku-paid-launch/ENABLEMENT.md
+++ b/implementation/carloku-paid-launch/ENABLEMENT.md
@@ -161,7 +161,16 @@ rehearsal question; the console accepts any subset.
path, signature verification and rotation, and every parameter the plan
lists as unverified at `2025-02-24.acacia` (`adaptive_pricing[enabled]`,
`currency` on a session, `discounts[0][coupon]`, `tax[validate_location]`,
- portal `name`).
+ portal `name`). **A gate inside the rehearsal, before anything else**:
+ whether Checkout ever creates a Subscription before its session
+ completes (an authentication abandoned; a card declined and another
+ tried on the same session; a delayed debit). The retirement protocol
+ records every subscription that names an intent and lets no intent go
+ while one is unaccounted for; if the provider leaves a dead subscription
+ on an honest checkout, that buyer is held with no stage-one outcome.
+ If the answer is yes, decision 15 in `DECISIONS-FOR-PAUL.md` is needed
+ before step 6, and the code must read an attached subscription's status
+ (not built). If no, the rule costs an honest buyer nothing.
3. Publish the approved book version; rebuild; deploy again with billing
off.
4. Get the live scoped approval (F) and provision live, steps 1 to 6 of the
diff --git a/implementation/carloku-paid-launch/OUTSTANDING.md b/implementation/carloku-paid-launch/OUTSTANDING.md
index 443c7807d..dffcb7c46 100644
--- a/implementation/carloku-paid-launch/OUTSTANDING.md
+++ b/implementation/carloku-paid-launch/OUTSTANDING.md
@@ -33,7 +33,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.
-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, an IAM principal inventory in the AWS provisioner (**built, unwired**, on `feat/carloku-principal-inventory-20261002` `d61f4f27`: identity policies only, for a name no bucket holds; needs decision 14 in `DECISIONS-FOR-PAUL.md` and one IAM permission; unreviewed, never run against AWS), and the bucket ownership attestation for stores that already exist (designed, not built).
+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, an IAM principal inventory in the AWS provisioner (on `feat/carloku-principal-inventory-20261002` `199a9736`: **a report for a person, not the proof**; its first review showed one listing cannot support the ledger's claim, so what the claim needs is now decision 14: a rule the account enforces and minted bucket names, neither designed in detail; never run against AWS), and the bucket ownership attestation for stores that already exist (designed, not built).
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**.
@@ -59,7 +59,7 @@ Each is concrete. None is waived.
15. Free tier. **Absent**: no Free entitlement, no app cap, no storage refusal, no per-plan idle, no flush-only class. Scoped 2026-10-02: the entitlement record already carries what the spec's step 13 needs (`Runtime.IdleSeconds`, `MaxApps`, `MaxMembers`, `Replication` with `hibernate-flush`, `StatusFree`, `PlanFree`), and **nothing consumes any of it**: `deriveEntitlement` returns a hold for Free, and no code in the console, the activator or a box reads `MaxApps`, `IdleSeconds` or the replication class from an entitlement. The Free caps (3 apps, 2-minute idle) are in the approved spec and not in `plans.json` (which has Free's pooled resources only). Building it is four pieces, each on its own reviewed branch: (a) the caps in the terms (a new terms version, since a published version is not edited) and a Free record from `deriveEntitlement`; (b) the console's app-creation gate on `MaxApps`; (c) the box reading idle and the replication class from the published entitlement, with `hibernate-flush` added to the activator's classes (the unset value means stream there today, the opposite of Free's intent); (d) storage refusal at the cap. **One decision is Paul's before (a)**: who is Free on the day it is switched on. Proposed policy for review: every account with no paid subscription and no house marker is Free from an announced date; accounts over a Free cap on that date keep what they have and can add nothing until under it (no app is stopped or archived by the switch); house accounts are unaffected. Without that ruling (a) would apply caps to every existing unpaid account on the flagship.
16. Dormancy archive and warnings; recognised-revenue pool accounting; the books site. **Absent.**
17. Per-line tax codes for a month spanning two tax codes (it holds with a review today).
-18. A `carlos` verb and documentation for the operator doors (**built, not merged**: `feat/carloku-billing-operator-cli-20261002` `51ef27ac`, first review answered, second not started, its public reference section is unreviewed copy); a statement rebuild door for a closed month; an operator verb to backfill bucket ownership.
+18. A `carlos` verb and documentation for the operator doors (**built, not merged**: `feat/carloku-billing-operator-cli-20261002` `31731fdd`, gate passed, two Astra reviews answered, Opus's second and Astra's third running; its public reference section is unreviewed copy); a statement rebuild door for a closed month; an operator verb to backfill bucket ownership.
### Process
diff --git a/implementation/carloku-paid-launch/READINESS.md b/implementation/carloku-paid-launch/READINESS.md
index 74b380f57..052c21f72 100644
--- a/implementation/carloku-paid-launch/READINESS.md
+++ b/implementation/carloku-paid-launch/READINESS.md
@@ -14,7 +14,7 @@ Log files are under `/home/paulca/.local/share/carloku-paid-launch-20260930/logs
| Branch | Tip | Gate | CI | Reviews | State |
| --- | --- | --- | --- | --- | --- |
-| `feat/carloku-multi-currency-20261001` | `b260ac8e` (round twenty answered by making the evidence invariant structural: every provider read of a session or subscription goes through three recording methods, a parser test forbids any other; before it `43d326b5` (round nineteen answered as one evidence invariant; before it `59666bab`, stage one of the retirement protocol; before it `15041ca2`: round eighteen's bounded findings fixed; round eighteen's and the three design reviews' reports in the tree) (`68f6ee23`: the seventeenth review's findings: the review filed before the expiry on both paths, the `keep` door's replay, nil billing and purchase check, the rejected listing's account, order and bound, two new tests; reviews ten to seventeen's reports in the tree) | passed on every code tip through `db130cfc` (`gate-currency-db130cfc.txt`, exit 0, three cross builds, clean tree); `68f6ee23`: passed (09:17Z, `gate-currency-68f6ee23.txt`, exit 0, three cross builds, clean tree); the console, plans and billingstripe packages passed in full on the same tree before the commit (console 525 s). `15041ca2`: passed (10:06Z, `gate-currency-15041ca2.txt`, exit 0, three cross builds); `59666bab`: passed (13:20Z, `gate-currency-59666bab.txt`, exit 0, three cross builds); `43d326b5`: **failed** (exit 2, `gate-currency-43d326b5-FAILED-e2e-build-toolchain-error.txt`): three root-package tests that build the binary failed with "is not in std" and "open …/gocache/…: no such file". Cause established: that gate inherited a scratch build cache (`~/.cache/tmp/gocache`) from the shell that started it, and the directory was deleted and recreated while it ran (its birth time is 17:15:07, after the 17:06 failures). Not a defect of the tree; `run-gate.sh` now unsets `GOCACHE` and prints the cache it uses. Not rerun on that tip. `b260ac8e`: **passed** (21:13Z, `gate-currency-b260ac8e.txt`, exit 0, three cross builds, default cache, run alone); the console, plans and billingstripe packages passed in full on the same tree before the commit (console 596 s, `currency-stage1-run3.txt`). Void or superseded logs, not evidence: `gate-currency-a9304f16.txt`, `gate-currency-f269365a-VOID-dirty-tree.txt`, `gate-currency-25487506-ended-on-28dc2629-reports-added-during-run.txt`, `gate-currency-db130cfc-VOID-dirty-tree-second-run.txt` (started by mistake on staged, uncommitted changes and stopped) | passed on every pushed tip through `b260ac8e` (`43d326b5` included) | **Round 21 (on `b260ac8e`): Opus accept with fixes (one P2, three P3), Astra reject (three P2, two P3). Not accepted.** Both closed every round-twenty finding and both found the same new P2, opened by round twenty's own fix: a refusal can now be filed on an intent that never had a session, the 25-hour cleanup of such an intent ignores the review, and `retire` then passes with a subscription attached. Astra also: a subscription seen before any refusal vanishes when an ordinary purchase consumes the intent; the held currency and customer are not rechecked in the transaction that creates an intent (two consoles); a listing's first page is dropped when a later page fails; refusal retries are not fair beyond the budget. Opus also: a bind can move an intent under review onto another session; a hand-made subscription naming an intent whose session is open is retried, never reviewed; the store keys on the answer's id. Reports `logs/opus-currency-review21.md`, `astra-currency-review21.md`. **Review eighteen's P2 stays open.** Round 20 (on `43d326b5`): Opus accept with fixes, Astra reject; answered in `b260ac8e` (43 mutants in a tree copy, four survived the first run and have tests now). Rounds 1 to 9: Opus accept with fixes, Astra reject. Rounds 10 to 13: both accept with fixes (P3s). Round 14: Astra reject on a P2 (a reconciliation paused on the provider read while the operator resolved the review recorded the retired purchase), fixed in `abd1b76e`. Rounds 15 and 16: both accept with fixes, each closing what the previous fix left open in the intent's lifecycle (15: nothing records under an open review, the resolution retires or keeps; 16: `keep` only for an intent whose bound session is complete with a subscription, the outcome written, replay-compared and audited). Each fix has a test that fails without it and a killed mutant (dispositions, one section per round). Round 17 at `db130cfc`: Opus accept with fixes (four P3s on the `keep` door and the rejected listing), Astra reject on a P2: both sites that expire a bound session expired first and filed the review second, so a pass reading the expired session in between, or a crash between the two, retired the intent with no record; fixed in `68f6ee23` by filing first (a two-path race test runs the store's retirement inside the fake's expiry and wants the conflict; it fails with either site's order put back), with the P3s, two new tests (an older resolutions table migrates with `retire`; the listing's 200-row bound, newest first, account on each row) and the comments and design sentence both named. The first form of the listing's account fix looked the account up under open rows and deadlocked the store's one connection in the test; rows are read to the end first. Round 18 at `68f6ee23`: Opus accept with fixes, Astra reject, on the same P2: with the review now filed before the expiry, an operator's `retire` can delete the intent while its bound session is still open and payable (the expiry failed; nothing retries it; the resume path still offers the URL). The supervisor ruled that this is not fixed by moving calls again but by a durable protocol (recorded refusal authoritative; the session's fate proven from provider evidence and recorded; atomic operator completion; a paid session settled by a separate disposition) with one bounded design review before another implementation cycle. Revision 1 of that design (`8c72e88b`) was rejected by Astra (four P2s), and revision 2 (`b4ff6b72`) too (five P2s: the hand-made subscription's own obligations at `retire`; the settlement predicate; observation times against cached answers; which evidence a dispute's resolution makes authoritative; the migration barrier). Revision 3 (`15041ca2`) was rejected a third time (four P2s, each with a conservative hold as its smallest change); revision 4 applies those holds and is built as **stage one** in `59666bab` (`billingretirement.go`): the operator's `retire` is accepted only for a session proven expired and unpaid by a provider read with nothing attached and nothing contradictory; `keep` only for a completed, paid session with no subscription attached but its own; a paid session that is not kept, any case a hand-made subscription touched, any contradicted case and every review from before the build are held; the door requests the expiry and answers 503 while it is unproven; the pass retries on a schedule; a click under review gets no URL; contradictions are disputes; a delete barrier stops an older binary. Eight tests, one per interleaving; eleven existing tests reworked; seventeen mutants killed. **Round nineteen did not accept it**: Opus accept with fixes (one P2, six P3s), Astra reject (three P2s): a subscription on the purchase's own terms was never attached, so `keep` could release the review beside it; the refusal and its subscription were two transactions; the keep gate's fresh read was not recorded as evidence; contradictions arriving after a retirement or a kept purchase's record, or read by an actor with a stale view, were dropped. These are answered in `43d326b5` as one invariant (every provider observation about a refused purchase classified and recorded in one store transaction against the purchase as it stands, retired, or kept and consumed; a refusal and its subscription one transaction; a caller records before it answers; nothing dropped), with seven counterexample tests, four reworked, and twenty mutants killed. Round twenty (Opus and Astra) is reading it. **Review eighteen's P2 stays open and blocks the merge until a round accepts this code.** No test runs two console processes against one database; the interleavings are driven through the store and provider hooks, and the dispositions say so. The bounded findings of round eighteen are fixed there with tests and four killed mutants (attribution of a retired session's completion beside a replacement; a `keep` decided during the gate answered by the replay comparison; the nil-billing and tie-break tests). The findings since round ten were not minor: each was a real gap in the lifecycle of an intent under review, and the rounds have converged on the operator's door rather than the money path | integrated end to end; not merged; the merge waits on a round ending with both accepting and nothing left to fix, and CI on the tip |
+| `feat/carloku-multi-currency-20261001` | `2618403f` (round twenty-two answered: the rule's edges; before it `05ccec07`, round twenty-one answered as one rule: a subscription that names an intent is recorded from the first read, and nothing deletes an intent past one; before it `b260ac8e` (round twenty answered by making the evidence invariant structural: every provider read of a session or subscription goes through three recording methods, a parser test forbids any other; before it `43d326b5` (round nineteen answered as one evidence invariant; before it `59666bab`, stage one of the retirement protocol; before it `15041ca2`: round eighteen's bounded findings fixed; round eighteen's and the three design reviews' reports in the tree) (`68f6ee23`: the seventeenth review's findings: the review filed before the expiry on both paths, the `keep` door's replay, nil billing and purchase check, the rejected listing's account, order and bound, two new tests; reviews ten to seventeen's reports in the tree) | `05ccec07`: **passed** (22:04Z, `gate-currency-05ccec07.txt`, exit 0, three cross builds, alone, default cache); `2618403f`: started 22:18Z (`gate-currency-2618403f.txt`). passed on every code tip through `db130cfc` (`gate-currency-db130cfc.txt`, exit 0, three cross builds, clean tree); `68f6ee23`: passed (09:17Z, `gate-currency-68f6ee23.txt`, exit 0, three cross builds, clean tree); the console, plans and billingstripe packages passed in full on the same tree before the commit (console 525 s). `15041ca2`: passed (10:06Z, `gate-currency-15041ca2.txt`, exit 0, three cross builds); `59666bab`: passed (13:20Z, `gate-currency-59666bab.txt`, exit 0, three cross builds); `43d326b5`: **failed** (exit 2, `gate-currency-43d326b5-FAILED-e2e-build-toolchain-error.txt`): three root-package tests that build the binary failed with "is not in std" and "open …/gocache/…: no such file". Cause established: that gate inherited a scratch build cache (`~/.cache/tmp/gocache`) from the shell that started it, and the directory was deleted and recreated while it ran (its birth time is 17:15:07, after the 17:06 failures). Not a defect of the tree; `run-gate.sh` now unsets `GOCACHE` and prints the cache it uses. Not rerun on that tip. `b260ac8e`: **passed** (21:13Z, `gate-currency-b260ac8e.txt`, exit 0, three cross builds, default cache, run alone); the console, plans and billingstripe packages passed in full on the same tree before the commit (console 596 s, `currency-stage1-run3.txt`). Void or superseded logs, not evidence: `gate-currency-a9304f16.txt`, `gate-currency-f269365a-VOID-dirty-tree.txt`, `gate-currency-25487506-ended-on-28dc2629-reports-added-during-run.txt`, `gate-currency-db130cfc-VOID-dirty-tree-second-run.txt` (started by mistake on staged, uncommitted changes and stopped) | passed on every pushed tip through `05ccec07`; `2618403f` pending | **Round 22 (on `05ccec07`): Opus accept with fixes, Astra reject. Not accepted.** Opus: the named-subscription rule holds, review eighteen's P2 is closed for deletion and consumption; one P2 on what the rule costs an honest buyer whose provider left a dead subscription (answered as a test-mode gate, `ENABLEMENT.md` section 6 step 2, and decision 15, not as code); four P3s. Astra: three P2s at the rule's edges (account retirement under an open checkout dispute; a session-only refusal filed after another console recorded the purchase; a click racing a filing), one P3; all answered in `2618403f` with tests and nine mutants. Round 23 running on `2618403f`. Round 21 (on `b260ac8e`): Opus accept with fixes, Astra reject; answered in `05ccec07` (27 mutants; one defect found there by neither reviewer, a later event of a recorded subscription consuming the standing intent its metadata named). **Round 21 (on `b260ac8e`): Opus accept with fixes (one P2, three P3), Astra reject (three P2, two P3). Not accepted.** Both closed every round-twenty finding and both found the same new P2, opened by round twenty's own fix: a refusal can now be filed on an intent that never had a session, the 25-hour cleanup of such an intent ignores the review, and `retire` then passes with a subscription attached. Astra also: a subscription seen before any refusal vanishes when an ordinary purchase consumes the intent; the held currency and customer are not rechecked in the transaction that creates an intent (two consoles); a listing's first page is dropped when a later page fails; refusal retries are not fair beyond the budget. Opus also: a bind can move an intent under review onto another session; a hand-made subscription naming an intent whose session is open is retried, never reviewed; the store keys on the answer's id. Reports `logs/opus-currency-review21.md`, `astra-currency-review21.md`. **Review eighteen's P2 stays open.** Round 20 (on `43d326b5`): Opus accept with fixes, Astra reject; answered in `b260ac8e` (43 mutants in a tree copy, four survived the first run and have tests now). Rounds 1 to 9: Opus accept with fixes, Astra reject. Rounds 10 to 13: both accept with fixes (P3s). Round 14: Astra reject on a P2 (a reconciliation paused on the provider read while the operator resolved the review recorded the retired purchase), fixed in `abd1b76e`. Rounds 15 and 16: both accept with fixes, each closing what the previous fix left open in the intent's lifecycle (15: nothing records under an open review, the resolution retires or keeps; 16: `keep` only for an intent whose bound session is complete with a subscription, the outcome written, replay-compared and audited). Each fix has a test that fails without it and a killed mutant (dispositions, one section per round). Round 17 at `db130cfc`: Opus accept with fixes (four P3s on the `keep` door and the rejected listing), Astra reject on a P2: both sites that expire a bound session expired first and filed the review second, so a pass reading the expired session in between, or a crash between the two, retired the intent with no record; fixed in `68f6ee23` by filing first (a two-path race test runs the store's retirement inside the fake's expiry and wants the conflict; it fails with either site's order put back), with the P3s, two new tests (an older resolutions table migrates with `retire`; the listing's 200-row bound, newest first, account on each row) and the comments and design sentence both named. The first form of the listing's account fix looked the account up under open rows and deadlocked the store's one connection in the test; rows are read to the end first. Round 18 at `68f6ee23`: Opus accept with fixes, Astra reject, on the same P2: with the review now filed before the expiry, an operator's `retire` can delete the intent while its bound session is still open and payable (the expiry failed; nothing retries it; the resume path still offers the URL). The supervisor ruled that this is not fixed by moving calls again but by a durable protocol (recorded refusal authoritative; the session's fate proven from provider evidence and recorded; atomic operator completion; a paid session settled by a separate disposition) with one bounded design review before another implementation cycle. Revision 1 of that design (`8c72e88b`) was rejected by Astra (four P2s), and revision 2 (`b4ff6b72`) too (five P2s: the hand-made subscription's own obligations at `retire`; the settlement predicate; observation times against cached answers; which evidence a dispute's resolution makes authoritative; the migration barrier). Revision 3 (`15041ca2`) was rejected a third time (four P2s, each with a conservative hold as its smallest change); revision 4 applies those holds and is built as **stage one** in `59666bab` (`billingretirement.go`): the operator's `retire` is accepted only for a session proven expired and unpaid by a provider read with nothing attached and nothing contradictory; `keep` only for a completed, paid session with no subscription attached but its own; a paid session that is not kept, any case a hand-made subscription touched, any contradicted case and every review from before the build are held; the door requests the expiry and answers 503 while it is unproven; the pass retries on a schedule; a click under review gets no URL; contradictions are disputes; a delete barrier stops an older binary. Eight tests, one per interleaving; eleven existing tests reworked; seventeen mutants killed. **Round nineteen did not accept it**: Opus accept with fixes (one P2, six P3s), Astra reject (three P2s): a subscription on the purchase's own terms was never attached, so `keep` could release the review beside it; the refusal and its subscription were two transactions; the keep gate's fresh read was not recorded as evidence; contradictions arriving after a retirement or a kept purchase's record, or read by an actor with a stale view, were dropped. These are answered in `43d326b5` as one invariant (every provider observation about a refused purchase classified and recorded in one store transaction against the purchase as it stands, retired, or kept and consumed; a refusal and its subscription one transaction; a caller records before it answers; nothing dropped), with seven counterexample tests, four reworked, and twenty mutants killed. Round twenty (Opus and Astra) is reading it. **Review eighteen's P2 stays open and blocks the merge until a round accepts this code.** No test runs two console processes against one database; the interleavings are driven through the store and provider hooks, and the dispositions say so. The bounded findings of round eighteen are fixed there with tests and four killed mutants (attribution of a retired session's completion beside a replacement; a `keep` decided during the gate answered by the replay comparison; the nil-billing and tie-break tests). The findings since round ten were not minor: each was a real gap in the lifecycle of an intent under review, and the rounds have converged on the operator's door rather than the money path | integrated end to end; not merged; the merge waits on a round ending with both accepting and nothing left to fix, and CI on the tip |
| `feat/carloku-billing-layout-20261001` | `c1ae91a0` | (templates only; gated inside the currency branch) | passed | none of its own | merged into the currency branch at `5047494b`; its two-form layout was replaced by one form in `8958392b` |
| `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 |
@@ -22,8 +22,8 @@ Log files are under `/home/paulca/.local/share/carloku-paid-launch-20260930/logs
| `feat/carloku-paid-launch-20260916` (launch) | this commit: documents only on top of `3d47602b`; last code change the merge of the observe-routes fix (`47c97fa6`) | 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 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` | `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 | `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`) | `0f507bff` failed (the same test); `51ef27ac` pending | 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 | not merged. **Its `docs/site/cli.md` section is new public copy and is unreviewed**: it does not merge before Paul reads it |
-| `feat/carloku-principal-inventory-20261002` | `d61f4f27` (off the launch branch at `542dd6f6`): the AWS principal inventory (`internal/objstore/principals.go`): who in the account has an identity policy reaching a bucket name. **Unwired: nothing constructs it** | not yet run (queued behind the operator CLI gate); `go test ./internal/objstore` passes; 26 mutants in a tree copy | not yet run | none yet | first step of the store-transfer meter (`OUTSTANDING.md` 2). Needs decision 14 (which principals are the platform's own) and one IAM permission the host module withholds; answers only for a name no bucket holds; never run against AWS |
+| `feat/carloku-billing-operator-cli-20261002` | `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 | `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`) | `0f507bff` failed (the docs gate); later tips not read | 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 | not merged. **Its `docs/site/cli.md` section is new public copy and is unreviewed**: it does not merge before Paul reads it |
+| `feat/carloku-principal-inventory-20261002` | `199a9736`: **a report for a person** (`PrincipalReport.BucketPrincipals`: who reaches a name, through which policies, and who each role's trust policy lets assume it), **not a `GranteeProber`** and a test says so; before it `d61f4f27`, which offered itself as the ledger's proof | not yet run (queued behind the currency gate); `go test ./internal/objstore` passes; 40 mutants in a tree copy, one equivalent | not yet run | 1 at `d61f4f27`: Astra reject (three P1: a listing is not an instant; an exempted role is everyone who can assume it; an absent bucket is not one this grant creates; two P2; one P3). Answered in `199a9736` by making it a report; Astra's second review running; Opus not yet read | what a completeness claim needs is now decision 14 (an enforced rule; minted bucket names); the report can be run by an operator with their own credentials; never run against AWS
| site `feat/paid-pricing-20260916` (GitHub) | `01b62f7` (the money renderer a module the test calls); before it `4026231` (`build` and `check` render from the export before the draft check, so a stale page cannot be published past a newer export; a floor that is not whole cents is refused by the renderer rather than shown as `$1.20.5`; after `c12318d`: `bands.p3` replaced by the approved explanation, every priced slot, inclusion band and figure token pinned exactly) | `node --test test/*.test.mjs`: 21 pass (09:1xZ) | n/a | read-only by the currency reviews (section K); rounds four, five, ten, twelve to seventeen's site findings fixed | preview served at `http://100.119.180.57:38009` from the tree (rebuilt with the `bands.p3` change) |
## The flow, behaviour the tests establish (2026-10-02)