carlos / platform Public

The handoff and the outstanding list record the fencing branch's first review: rejected, and its premise does not bound a whole request

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 551e32c9ce90e37a83ab3ac49b8b621abcdbce92 parent c1cf882
2 files changed, +13 −13
  • .claude/HANDOFF.md +10 −10
  • implementation/carloku-paid-launch/OUTSTANDING.md +3 −3

CI passed — run details

diff --git a/.claude/HANDOFF.md b/.claude/HANDOFF.md
index d7781f9f1..8e28737a6 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 09:40 Dublin on 2026-10-01. Three things, kept apart.
+Written 09:52 Dublin on 2026-10-01. Three things, kept apart.
1. Draft copy to review, not approved: pricing http://100.119.180.57:38009 (name form http://docs-t1.tail5fd3ba.ts.net:38009), console billing page http://100.119.180.57:45033 (name form http://docs-t1.tail5fd3ba.ts.net:45033).
2. A demo to click through: http://100.119.180.57:41881, real console handlers with Keymail and Stripe simulated. It is not Stripe proof.
@@ -19,21 +19,21 @@ Preview readiness with billing off is not launch readiness, and a review that ac
Billing is OFF, the quantity worker is OFF (two switches, both unset), nothing attests, nothing was deployed, and no live Stripe or AWS write was made.
-Tip when this was written: `bac513f6`. This file does not claim what later commits contain; read `git log bac513f6..` for that.
+Last gated tip when this was written: `bac513f6` (handoff-only commits sit on top). This file does not claim what later commits contain; read `git log bac513f6..` for that.
- `cd8821c6` is the last commit that changes product code (round seventeen's fixes). Local gate on it: build, vet, gofmt, `make test` with 61 packages ok on the second run (`logs/gate-cd8821c6.txt` in the run directory; the first run failed one `internal/activator` test, log kept as `logs/gate-cd8821c6-run1-failed.txt`); cross builds for darwin, linux arm64 and windows (`logs/cross-cd8821c6.txt`). Amadan CI passed on `cd8821c6`.
-- `bac513f6` changes one test file only: it fixes that activator test. Its recording script wrote a file with a shell redirect, which creates the file empty before the content arrives, and the test could read it in that moment. The file is now renamed into place whole. Under the same load, 55 failures in 1,280 runs before and none after. Local gate on `bac513f6`: 61 packages ok, first run (`logs/gate-bac513f6.txt`). CI had not run on it when this was written.
-- Amadan CI sat queued all night, first ran at 07:34 Dublin, and has passed on `1395f7bf`, `d0a21aa1`, `d5705a63`, `973a9f15`, `abc9f781`, `86a1849d` and `cd8821c6`. The local gate is not offered in CI's place.
+- `bac513f6` changes one test file only: it fixes that activator test. Its recording script wrote a file with a shell redirect, which creates the file empty before the content arrives, and the test could read it in that moment. The file is now renamed into place whole. Under the same load, 55 failures in 1,280 runs before and none after. Local gate on `bac513f6`: 61 packages ok, first run (`logs/gate-bac513f6.txt`). CI passed on `c1cf8822`, which is `bac513f6` plus this file.
+- Amadan CI sat queued all night, first ran at 07:34 Dublin, and has passed on `1395f7bf`, `d0a21aa1`, `d5705a63`, `973a9f15`, `abc9f781`, `86a1849d`, `cd8821c6` and `c1cf8822`. The local gate is not offered in CI's place.
Independent review. No review of the whole branch has passed. GPT-6 Astra rejected rounds 1 to 16; the AGENTS-required Opus production review accepted with fixes in rounds 2 to 16. Each round found the round before closed for its reported shapes and found neighbouring ones, in the object-store walks (`internal/objstore`) and their readers since round seven. Round seventeen read only the diff since round sixteen: Opus accepted, Astra accepted with fixes (one P2). That P2 and Opus's small items are fixed in `cd8821c6` and have not been read by a reviewer. Open items the reviews left are in `OUTSTANDING.md` 19a to 19i. Nothing lands until the whole branch has been read and accepted. Dispositions, round by round: `docs/superpowers/specs/CODEX-DISPOSITIONS-carloku-paid-launch-overnight.md`.
-Two open defects, both with their paths disabled, neither offered as a risk to accept: a quantity request that runs after Stripe has forgotten its key, and a late invoice-line request that can leave a finalized invoice with a wrong total a customer could pay. The design that removes both is `docs/superpowers/plans/2026-10-01-late-request-fencing.md`.
+Two open defects, both with their paths disabled, neither offered as a risk to accept: a quantity request that runs after Stripe has forgotten its key, and a late invoice-line request that can leave a finalized invoice with a wrong total a customer could pay. The design meant to remove both is `docs/superpowers/plans/2026-10-01-late-request-fencing.md`; its first review found that, as designed, it does not (below).
-Side branches, all on the forge, each with the full local gate passing on the named tip (base `d5705a63`), none reviewed, none run through CI, nothing on the launch branch calls them:
+Side branches, all on the forge, each with the full local gate passing on the named tip (base `d5705a63`), none run through CI, nothing on the launch branch calls them:
-- `feat/carloku-late-request-fencing-20261001` (`1772e840`): a Stripe request cannot outlive its connection. A first review by both reviewers was started at 09:35 (run directory `logs/astra-fencing-review1.md`, `logs/opus-fencing-review1.md`). It also voids a wrong-total invoice; that is remediation, and its limits are pinned by tests there. The gate caught, and a commit fixed, a timeout the new transport reported as a network fault.
-- `feat/carloku-metered-replicator-20261001` (`ebab1a37`): path B, first build. A metered replication store with no unmetered fallback, an owner for every database the box replicates, a fleet store that refuses anything it cannot meter. Nothing attests. Code map: run directory `notes/path-b-replicator-code-map.md`.
-- `feat/carloku-bucket-hour-evidence-20261001` (`58c1870c`): the operator evidence door for a store's partial first hour. The hour still holds by default; the door releases only that hour, only for the owner the ledger names, on a named person's recorded evidence.
+- `feat/carloku-late-request-fencing-20261001` (`a64517ba`): a Stripe request cannot outlive its connection, and a void for a wrong-total invoice (remediation only). Reviewed once by both reviewers at `1772e840`: both rejected it. Two shared findings are fixed in `a64517ba` (a send deadline is one absolute instant fixed before the lease or authorization, on both paths). The rest is open in `DISPOSITIONS-late-request-fencing.md` on that branch. One finding limits the design: the provider's idle-connection limit bounds when a request can begin to be written, not when a whole request is received. As designed the branch does not close the two defects.
+- `feat/carloku-metered-replicator-20261001` (`ebab1a37`, not reviewed): path B, first build. A metered replication store with no unmetered fallback, an owner for every database the box replicates, a fleet store that refuses anything it cannot meter. Nothing attests. Code map: run directory `notes/path-b-replicator-code-map.md`.
+- `feat/carloku-bucket-hour-evidence-20261001` (`58c1870c`, not reviewed): the operator evidence door for a store's partial first hour. The hour still holds by default; the door releases only that hour, only for the owner the ledger names, on a named person's recorded evidence.
- `feat/carloku-scoped-attestation-20261001` (`058ea506`): path A, parked. It cannot prove an exclusive writer. Replication-write completeness is a launch blocker, not waived.
**NEEDED:**
@@ -41,7 +41,7 @@ Side branches, all on the forge, each with the full local gate passing on the na
- Scoped approvals, prepared as plans only: Stripe test mode, to run `TestSandboxQuantityFence`; the `rk_live` restricted key and Stripe catalog; the Cost and Usage Report export; one scratch-object write to check S3's conditional delete. Exact scopes are in the approvals table of `OUTSTANDING.md`.
**RECOMMENDED:**
-- Read the fencing branch's first review and fix what it finds on that branch.
+- Decide what bounds a complete late request at Stripe (a documented server-side request timeout, or a design that does not depend on one). Until then the fencing branch's remaining findings are worth fixing only for the void and the tests.
- Have the whole launch branch read again at its tip, not a diff, before anything is called accepted.
- Review the other two gated side branches (metered replicator, bucket-hour evidence).
- Then, each on its own branch: the agent wiring and restore path for path B, the evidence door for a box's first minutes, quantity reduction at renewal, the storage pass using the holder inventory (19i), the AWS principal inventory and the bucket ownership attestation door, Free-tier enforcement, dormancy and pool accounting.
diff --git a/implementation/carloku-paid-launch/OUTSTANDING.md b/implementation/carloku-paid-launch/OUTSTANDING.md
index a67c7d412..7dc5663b2 100644
--- a/implementation/carloku-paid-launch/OUTSTANDING.md
+++ b/implementation/carloku-paid-launch/OUTSTANDING.md
@@ -42,9 +42,9 @@ Each is concrete. None is waived.
5. **No catalog, portal configuration, webhook endpoint or runtime key exists.** The plan and a print-only script are written. Needs scoped approval, then a test-mode rehearsal, then a real purchase.
6. **The quantity worker's fence is unverified against Stripe.** It rests on documented idempotency rules, modelled by a fake. `TestSandboxQuantityFence` must pass in a Stripe sandbox, under both proration policies, before `CONSOLE_BILLING_QUANTITY_FENCE` is set. Test mode is not authorized, so it has not been run. A pass is not enough by itself: check 5b logs what the worker's own update does with a declining card, and that log has to be read and decided on, because the worker records an addition as charged on any success and sends no `payment_behavior`. Two things it cannot settle and that stay open after it: what Stripe does with a key across an API key rotation, and how Stripe later reconciles a request it answered with a 500.
6a. **An ended subscription's operation may need a person every time.** If Stripe refuses the fence request on a canceled subscription's item (the sandbox run logs what it answers), every canceled team subscription with an unconfirmed operation waits on a resolved review, and until then the account's quantity work is held, under a later subscription too. That needs a code decision from the sandbox log before the worker is switched on.
-7. **Defect, open: an old quantity request can run after Stripe has forgotten its key.** Stripe forgets keys after 24 hours. A sender frozen longer than that can still land a request for an operation that was retired and replaced. On the launch branch that is only detected after the write (`billing_quantity_lowered`), which is not a fix. The fix is **partial, unwired into this branch**, on `feat/carloku-late-request-fencing-20261001` (`1772e840`, on the forge; the full local gate passes on it, after the gate caught and a commit fixed a timeout that the new transport reported as a network fault; design in `docs/superpowers/plans/2026-10-01-late-request-fencing.md`): a transport in which a request cannot outlive its connection, with tests. Its one premise, the provider's idle limit, is unmeasured. The path that could cause the defect, the quantity worker, stays disabled until that is reviewed, merged and measured in a Stripe sandbox. Nobody is asked to accept this risk.
+7. **Defect, open: an old quantity request can run after Stripe has forgotten its key.** Stripe forgets keys after 24 hours. A sender frozen longer than that can still land a request for an operation that was retired and replaced. On the launch branch that is only detected after the write (`billing_quantity_lowered`), which is not a fix. The fix is **partial, unwired into this branch**, on `feat/carloku-late-request-fencing-20261001` (`a64517ba`, on the forge; the full local gate passes on it; design in `docs/superpowers/plans/2026-10-01-late-request-fencing.md`): a transport in which a request cannot outlive its connection, with tests. Its first review (both reviewers, at `1772e840`) rejected it. Two shared findings are fixed on the branch (a send deadline is now one absolute instant fixed before the lease or authorization, on both the quantity and the invoice path). The rest is open there (`DISPOSITIONS-late-request-fencing.md` on that branch), and one finding limits the design itself: the provider's idle-connection limit bounds when a request can begin to be written, not when a complete request is received (a sender frozen after the headers and before the body, or bytes already in the kernel, are not covered). So this branch does not close this item as designed. The path that could cause the defect, the quantity worker, stays disabled until there is a supported provider-side bound on a complete request, or a design that does not need one. Nobody is asked to accept this risk.
8. **Stripe's treatment of a proration date outside the period** is assumed from documentation. Same sandbox run.
-9. **Defect, open: a late invoice-line request can leave a finalized invoice with a wrong total.** Past Stripe's key memory a stale line request runs as new. If it lands between the engine's line check and the finalize, the invoice is finalized with a duplicate line. The engine flags it and will not charge it, but a finalized invoice is open at Stripe, and an open invoice can be paid by the customer from Stripe's hosted page or the portal. That is customer-payable exposure and it is treated as such. Prevention is the same transport as item 7, at the same stage (**partial, on the fencing branch**). That branch also voids such an invoice when it finds one; that is remediation after the fact, its limits are pinned by tests there (the invoice is payable until the void lands, and a customer who pays first is owed a refund), and it does not close this item. Billing stays OFF, so invoice writes are disabled until the prevention is proven.
+9. **Defect, open: a late invoice-line request can leave a finalized invoice with a wrong total.** Past Stripe's key memory a stale line request runs as new. If it lands between the engine's line check and the finalize, the invoice is finalized with a duplicate line. The engine flags it and will not charge it, but a finalized invoice is open at Stripe, and an open invoice can be paid by the customer from Stripe's hosted page or the portal. That is customer-payable exposure and it is treated as such. Prevention is the same transport as item 7, at the same stage and with the same limit its first review found (**partial, on the fencing branch, rejected at first review**): as designed it bounds when a request can begin to be written, not when it is received whole. That branch also voids such an invoice when it finds one; that is remediation after the fact (the invoice is payable until the void lands, and a customer who pays first is owed a refund), the review found faults in the void itself that are open there, and it does not close this item. Billing stays OFF, so invoice writes are disabled until the prevention is proven.
### Decisions that are Paul's
@@ -73,7 +73,7 @@ Each is concrete. None is waived.
19c. **S3's conditional delete is unverified on a real backend.** The store walks and the app purge delete a record only as the generation they read. That has run against the directory store and an HTTP stub. No `If-Match` delete has been sent to AWS or to an S3-compatible store, and a backend that ignored the header would delete unconditionally. It needs one write to a scratch object, which is a production-adjacent write nobody has approved.
19d. **The signing-time fence has been observed on AWS only.** An S3-compatible deployment or store endpoint has not been probed for its window.
19a. **A retained teardown finishes only when someone runs it again.** Nothing runs it. A store that left a bucket to another account keeps its record until then. Until then its scanning shows no coverage and its storage is held each day, for its own account only, not measured: the bucket's bytes are the other account's. A day written as held stays held for that account; there is no rebuild door (item 18).
-20. **Amadan CI has passed on `1395f7bf`, `d0a21aa1`, `d5705a63`, `973a9f15`, `abc9f781`, `86a1849d` and `cd8821c6`.** It sat queued on every tip all night and first ran at 07:34 Dublin on 2026-10-01. Any later code tip needs its own run; the local gate (build, vet, gofmt, `make test`, cross builds) is not CI and is not offered in its place. An agent account can neither see nor manage the runners. The hub's `carlos/platform` repository also answered 500 on and off through the night; bundles of every tip are in the run directory.
+20. **Amadan CI has passed on `1395f7bf`, `d0a21aa1`, `d5705a63`, `973a9f15`, `abc9f781`, `86a1849d`, `cd8821c6` and `c1cf8822`.** It sat queued on every tip all night and first ran at 07:34 Dublin on 2026-10-01. Any later code tip needs its own run; the local gate (build, vet, gofmt, `make test`, cross builds) is not CI and is not offered in its place. An agent account can neither see nor manage the runners. The hub's `carlos/platform` repository also answered 500 on and off through the night; bundles of every tip are in the run directory.
21. **A scanner backend that calls a provider must be fenced like the walks.** Today's scanner (ClamAV) makes no provider call at teardown. A native one would, and its client would need the fenced signer.
## Approvals to ask for, each with its exact scope