db-region-forward: Astra round 4 findings, unedited
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+56
−0
docs/superpowers/specs/CODEX-FINDINGS-DB-REGION-FORWARD-R4.md+56 −0
diff --git a/docs/superpowers/specs/CODEX-FINDINGS-DB-REGION-FORWARD-R4.md b/docs/superpowers/specs/CODEX-FINDINGS-DB-REGION-FORWARD-R4.md| new file mode 100644 |
| index 000000000..1a200ca85 |
| --- /dev/null |
| +++ b/docs/superpowers/specs/CODEX-FINDINGS-DB-REGION-FORWARD-R4.md |
| @@ -0,0 +1,56 @@ |
| +| Finding | Disposition | Evidence and remaining work | |
| +|---|---|---| |
| +| **1. Incarnation check** | **FIXED; DECLINED-AGREE** on version pinning | [§8.2:618](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:618) brackets every download and replan before releasing output. Record identity is checked against its path in [provision.go:2777](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/provision/provision.go:2777); incarnation includes creation identity in [claim.go:192](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/hostclaim/claim.go:192). This closes the reported recreation race without version pinning. | |
| +| **2. Socket on stdin** | **FIXED** | [§8.3:661](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:661) explicitly supplies socket stdin/stdout and journal stderr, replacing the incompatible output configuration in [claimunit_template.go:19](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/host/claimunit_template.go:19). | |
| +| **3. Progress versus completion acknowledgement** | **FIXED** | [§9.1:750](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:750) removes both acknowledgement routes. The terminal-ack semantics of [apirunsfollow.go:287](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apirunsfollow.go:287) are no longer being reused for progress. | |
| +| **4. Late writes after `lost`** | **FIXED** | [§5.5:347](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:347) permits abandoned box output without another reader or console terminal writer. No storage fence is claimed; conditional creation still operates on individual keys, as [store.go:787](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/release/store.go:787) implements. | |
| +| **5. Cleanup reopens election** | **FIXED** | [§5.9:479](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:479) retains `picked` beyond the acceptance window. [store.go:794](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/release/store.go:794) provides the required conditional create. | |
| +| **6. “Showed none” after rejection** | **FIXED** | [§5.5:337](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:337) buffers and verifies before stdout, avoiding the irreversible writes at [db.go:427](/home/paulca/amadan.net/carlos/platform-db-region-forward/db.go:427). | |
| +| **7. Stored-ciphertext bound** | **PARTLY — P3** | The retention correction in [§5.7:429](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:429) accounts for versioning and removes the hard deletion deadline. However, “ciphertext … at most the output cap” at line 439 remains inaccurate: [crypto.go:215](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/appconfig/crypto.go:215) adds the authentication tag, sender key, nonce and encoding. **Fix:** distinguish the 64 MiB plaintext-row limit from stored ciphertext and framing overhead. This is separate from provisional ruling 1. | |
| +| **8. Disk reservations and restart recovery** | **PARTLY — P2** | Reservation ownership and orphan blocking are fixed in [§5.7:445](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:445). But [§8.3:698](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:698) incorrectly says context cancellation stops every restore. The pinned file client returns an ordinary file without checking context ([replica_client.go:135](/home/paulca/go/pkg/mod/github.com/benbjohnson/litestream@v0.5.14/file/replica_client.go:135)); the compactor’s page-reading and writing functions explicitly ignore context ([compactor.go:177](/home/paulca/go/pkg/mod/github.com/superfly/ltx@v0.5.1/compactor.go:177), [line 199](/home/paulca/go/pkg/mod/github.com/superfly/ltx@v0.5.1/compactor.go:199)). Cancellation during local compaction therefore need not stop it promptly. **Fix:** make local restore I/O cancellation-aware or explicitly terminate the worker after a bounded grace period. Keep reservations until actual unit termination; test disconnect during local compaction, after download. | |
| +| **9. Worker readiness** | **FIXED** | [§7.1:516](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:516) requires a real worker probe and reserves its third connection. It extends the armed-worker precedent at [movesoffline.go:254](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/host/movesoffline.go:254). | |
| +| **10. Incomplete snapshot evidence** | **FIXED** | [§7.1:542](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:542) gives incomplete evidence precedence over both refusals. This matches the separate completeness flags at [snapshot.go:137](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/edgesfile/snapshot.go:137), [line 182](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/edgesfile/snapshot.go:182) and [line 219](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/edgesfile/snapshot.go:219). | |
| +| **11. Separate store endpoints** | **DECLINED-AGREE** | [§12:920](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:920) limits support to the existing endpoint model. Both constructors use the shared configuration: [store.go:712](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/release/store.go:712), [endpoint.go:146](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/lease/endpoint.go:146). | |
| +| **12. Census classifications** | **FIXED** | [§13:945](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:945) requires supported classifications, both runner callers, removal rows and rulings. These match [plan14_root_reads_test.go:465](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/provision/plan14_root_reads_test.go:465) and [line 480](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/provision/plan14_root_reads_test.go:480). | |
| +| **13. Completion deletes terminal evidence** | **FIXED** | [§5.3:221](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:221) removes completion deletion and later terminal synthesis. The retained-state recovery used by [apirunsfollow.go:126](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apirunsfollow.go:126) is unnecessary for this request-only protocol. | |
| +| **14. Cleanup removes follow identity** | **FIXED** | [§9.1:750](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:750) removes follow entirely. No later request needs the identity checked by [apirunsfollow.go:80](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apirunsfollow.go:80). | |
| +| **15. Full db gate hides `record-changed`** | **FIXED** | [§9.1:750](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:750) runs eligibility once and returns the box’s refusal in the same response. Later record changes cannot trigger the admission refusals at [apidb.go:132](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apidb.go:132) again. | |
| +| **16. Lazy expiry strands a read** | **FIXED** | No console expiry transition remains. [§5.4:251](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:251) adds nonce-based pickup read-back, matching the recovery principle in [host/runs.go:270](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/host/runs.go:270). | |
| +| **17. Abandoned reads hold admission** | **FIXED** for reservation ownership | [§5.7:423](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:423) releases counts through handler defers, following [apidb.go:395](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apidb.go:395). The separate claim about prompt progress delivery needs finding 19 below. | |
| +| **18. Forgery claim contradicts sealing** | **FIXED** | [§5.6:368](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:368) withdraws authenticated-authorship claims. This matches public-key sealing at [crypto.go:206](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/appconfig/crypto.go:206) and deployment-bucket write authority at [region-host/main.tf:166](/home/paulca/amadan.net/carlos/platform-db-region-forward/infra/modules/region-host/main.tf:166). | |
| + |
| +| Invariant | Disposition | Mechanism and mapping check | |
| +|---|---|---| |
| +| **J1 — One request** | **FIXED** | §§5.5 and 9.1 provide no follow, resume or later terminal route. The best-effort `cancel` is the stated exception. This closes mappings **3, 4, 13, 14 and 15**. Late box output has no subsequent reader. | |
| +| **J2 — Write once** | **FIXED** | Every listed protocol object is created conditionally; no protocol replacement or deletion remains. The serial bump is outside `db-reads/`. This supports mapping **5**. | |
| +| **J3 — One owner** | **FIXED** | An ambiguous create permits execution only after reading back the same attempt nonce. A failed read-back sacrifices availability, not exclusive ownership. This closes **16** for cooperating participants; **18** correctly states that compromised deployment writers remain trusted. | |
| +| **J4 — Store-only deletion** | **FIXED** | Lifecycle eligibility starts long after the request and pickup windows. Independent object expiry can no longer reopen a follow or console terminal transition. Mappings **5, 13 and 14** hold. Mapping **7** closes retention, but its ciphertext-size wording still needs the correction above. | |
| +| **J5 — Admission follows the work** | **FIXED** as an ownership invariant | Console counts belong to handlers; box slots and reservations remain until units stop. Mapping **17** holds. Mapping **8** is incomplete: retaining a reservation safely does not make the local restore cancellable or establish prompt orphan shutdown. | |
| + |
| +Conditional creation is supported by the documented S3 semantics and MinIO’s conditional-write tests: [https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html), [https://github.com/minio/minio/blob/master/cmd/erasure-object-conditional_test.go](https://github.com/minio/minio/blob/master/cmd/erasure-object-conditional_test.go). Lifecycle expiration is asynchronous and distinguishes current from noncurrent versions: [https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-expire-general-considerations.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-expire-general-considerations.html). |
| + |
| +The cited long-request settings match the code: public edge listeners have only header timeouts ([edge.go:3357](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/edge/edge.go:3357)); Unix/TCP proxies have no response-header or overall timeout ([edge.go:2377](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/edge/edge.go:2377)); the console has a five-minute read timeout ([main.go:586](/home/paulca/amadan.net/carlos/platform-db-region-forward/cmd/console/main.go:586)); ordinary CLI requests have thirty seconds ([auth.go:403](/home/paulca/amadan.net/carlos/platform-db-region-forward/auth.go:403)). After body EOF, Go starts its background read and clears the read deadline ([server.go:687](/home/paulca/.local/go-dist/src/net/http/server.go:687)). Thus the five-minute timeout is not itself a response deadline. The new handler should explicitly enforce its overall context deadline. |
| + |
| +19. **P2 — Progress writes are not guaranteed to leave the console.** |
| + |
| + **Spec:** [§5.2:198](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:198), [§5.5:323](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:323). |
| + |
| + The design promises a progress line every fifteen seconds but specifies only writes under renewed deadlines, using `dbStream` as its precedent. That helper calls `Write`, without flushing each chunk ([apidb.go:475](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apidb.go:475)); its caller flushes only at the end ([apidb.go:459](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apidb.go:459)). Go buffers small response writes ([server.go:1061](/home/paulca/.local/go-dist/src/net/http/server.go:1061)). |
| + |
| + During planning, small wait lines can therefore remain buffered for minutes. They neither provide the promised wire activity nor exercise the downstream write-stall deadline. There is also a timeout omitted from the path audit: traffic arriving through another edge can use backhaul, whose `ResponseHeaderTimeout` is **30 seconds** ([edge.go:2958](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/edge/edge.go:2958)). Buffered response headers can lose that request before its first progress line reaches the client. |
| + |
| + **Fix:** flush the initial response and every progress line explicitly with `ResponseController.Flush`, under the write deadline, and handle flush errors. Test that a real CLI receives progress within fifteen seconds during a quiet restore, including through backhaul. |
| + |
| +20. **P2 — The result can overtake the final chunk in the console’s polling sequence.** |
| + |
| + **Spec:** [§5.5:323](/home/paulca/amadan.net/carlos/platform-db-region-forward/docs/superpowers/specs/2026-10-22-db-region-forward-design.md:323). |
| + |
| + The console lists chunks, reads the result, and finishes with the result line. A valid interleaving is: LIST returns through chunk N; the box commits N+1 and then `result.json`; the console reads that result and ends the response without N+1. The CLI correctly rejects the incomplete answer, but an otherwise successful query fails. |
| + |
| + The existing run transport explicitly documents this race and reads the result **before** listing chunks ([apirunsfollow.go:101](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apirunsfollow.go:101), implemented at [line 139](/home/paulca/amadan.net/carlos/platform-db-region-forward/internal/console/apirunsfollow.go:139)). Confirming chunk PUTs before publishing the result does not make an earlier LIST include those chunks. |
| + |
| + **Fix:** read the result before the corresponding listing, and require delivery of every contiguous sequence through `last_seq` before emitting the terminal result line. Test publication of the last chunk and result between the console’s LIST and GET. |
| + |
| +Reviewed at `010d29f632ee9c7040154d09e85e8f921b0b3d02`. Static review; no files changed or runtime acceptance tests run. Both cited platform module tags were inspected. Current flagship refs, claim activation and deployment-event assertions remain unverified: GitHub retrieval failed, and the available infrastructure checkout is dated October 6. |
| + |
| +**REVISE** |
| \ No newline at end of file |