carlos / platform Public

plan: claim Plan 7 rev 2, flag-off ignores the handle header as today

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev cde34eeaba26feb44ed029a1e1599ef322281055 parent 139378b
1 file changed, +10 −5
  • docs/superpowers/plans/2026-10-05-host-lifecycle-claim-7-pull-door.md +10 −5

CI cancelled — superseded by a newer push — run details

diff --git a/docs/superpowers/plans/2026-10-05-host-lifecycle-claim-7-pull-door.md b/docs/superpowers/plans/2026-10-05-host-lifecycle-claim-7-pull-door.md
index 978ab6f67..214c5e160 100644
--- a/docs/superpowers/plans/2026-10-05-host-lifecycle-claim-7-pull-door.md
+++ b/docs/superpowers/plans/2026-10-05-host-lifecycle-claim-7-pull-door.md
@@ -952,7 +952,9 @@ func TestDoorPlanHTTPTruncationResumeAndFlagOff(t *testing.T) {
if !ranged {
t.Fatal("missing pinned range audit", events)
}
- // A different flag-off console refuses a previously issued v2 handle.
+ // A flag-off console ignores the handle header exactly as today (R1):
+ // it serves the coordinate and never echoes the handle, so a v2 client
+ // rejects the response (Task 1's acknowledgement check).
// Keep startup configuration immutable while either server is running.
legacy := dbFixture(t)
req, err := http.NewRequest("GET", legacy.url(dbdoor.GetPath("bab", "titogo", dbTestHost, 0, 1, 1)), nil)
@@ -967,8 +969,11 @@ func TestDoorPlanHTTPTruncationResumeAndFlagOff(t *testing.T) {
}
io.Copy(io.Discard, res.Body)
res.Body.Close()
- if res.StatusCode != 409 {
- t.Fatal("flag-off accepted pinned request", res.StatusCode)
+ if res.StatusCode != 200 {
+ t.Fatal("flag-off changed its answer to a request carrying a handle header", res.StatusCode)
+ }
+ if res.Header.Get(dbdoor.HandleHeader) != "" {
+ t.Fatal("flag-off console echoed a handle it cannot enforce")
}
}
```
@@ -1315,7 +1320,7 @@ s=replace(s,'"github.com/carlosframework/platform/internal/dbdoor"','"github.com
s=replace(s,'type dbRequest struct {','type dbRequest struct {\n\tclaim hostclaim.Observed')
s=replace(s,'rd, err := s.dbReplica(ctx, prefix)','if s.cfg.HostClaim {\n\t\tg := dbRequest{acct: acct, actor: actor, app: app, host: host}\n\t\tif s.cfg.DBVersions == nil {\n\t\t\tjsonError(w, http.StatusServiceUnavailable, "this console has no versioned database reader")\n\t\t\treturn dbRequest{}, false\n\t\t}\n\t\tg.claim, err = s.dbClaim(ctx, g, *rec)\n\t\tif err != nil { s.dbClaimFailure(w, r, g, err); return dbRequest{}, false }\n\t\tg.prefix = g.claim.Claim.Holder.Location\n\t\treturn g, true\n\t}\n\trd, err := s.dbReplica(ctx, prefix)')
s=replace(s,'itr, err := g.rd.LTXFiles(r.Context(), level, 0, false)','if s.cfg.HostClaim {\n\t\tout, err := s.listDBVersions(r.Context(), g, level)\n\t\tif err != nil { s.dbClaimFailure(w, r, g, err); return }\n\t\tw.Header().Set("Cache-Control", "no-store")\n\t\twriteJSON(w, http.StatusOK, out)\n\t\treturn\n\t}\n\titr, err := g.rd.LTXFiles(r.Context(), level, 0, false)')
-s=replace(s,'rangeHdr := r.Header.Get("Range")','var pinned *dbVersionReader\n\tif s.cfg.HostClaim {\n\t\tpinned, err = s.pinnedDBReader(r, g, level, minTXID, maxTXID)\n\t\tif err != nil { s.dbClaimFailure(w, r, g, err); return }\n\t\tg.rd = pinned\n\t} else if r.Header.Get(dbdoor.HandleHeader) != "" {\n\t\tjsonError(w, http.StatusConflict, "this console cannot enforce a pinned database read")\n\t\treturn\n\t}\n\trangeHdr := r.Header.Get("Range")')
+s=replace(s,'rangeHdr := r.Header.Get("Range")','var pinned *dbVersionReader\n\tif s.cfg.HostClaim {\n\t\tpinned, err = s.pinnedDBReader(r, g, level, minTXID, maxTXID)\n\t\tif err != nil { s.dbClaimFailure(w, r, g, err); return }\n\t\tg.rd = pinned\n\t}\n\trangeHdr := r.Header.Get("Range")')
s=replace(s,'if !s.dbStreams.acquire(g.actor) {','if pinned != nil {\n\t\tif _, err := dbVersionRange(pinned.handle.Size, offset, size); err != nil {\n\t\t\tjsonError(w, http.StatusRequestedRangeNotSatisfiable, "unsupported range")\n\t\t\treturn\n\t\t}\n\t}\n\tif !s.dbStreams.acquire(g.actor) {')
s=replace(s,'w.Header().Set("Content-Type", "application/octet-stream")','if pinned != nil {\n\t\tif err := dbVersionHeaders(w, r, pinned.handle.Size, offset, size); err != nil {\n\t\t\tjsonError(w, http.StatusRequestedRangeNotSatisfiable, "unsupported range")\n\t\t\treturn\n\t\t}\n\t}\n\tw.Header().Set("Content-Type", "application/octet-stream")')
put(p,s)
@@ -1595,5 +1600,5 @@ A handle is valid only on the console that shares its persisted signing key, und
Plan-author verification: the complete Go blocks and all three source-edit scripts were extracted from this document and checked against the compiled overlay. The overlay used `origin/main` plus the real Plan 1 package, without creating implementation files in this repository. All added test files compiled; deterministic claim/handle/protocol/range/flag tests passed with `-race`. The test-only overlay without implementation failed with the expected missing fields/functions. Full `go build ./...` passed on Linux, Darwin, Windows and Linux/arm64. The IAM check failed before the edit and passed afterward; `tofu fmt -check` passed on both edited module files. The default Go cache was read-only, so verification used the existing shared on-disk `$TMPDIR/gocache`. Go also emitted a nonfatal module-stat-cache write warning; the reported build commands still exited zero.
-The HTTP restore/authorization/truncation tests compiled but could not execute: the sandbox refused `httptest`'s loopback listener with `socket: operation not permitted`. They and the unchanged flag-off HTTP regressions remain runtime checks for the implementation environment. Vet and the full repository test gate were not claimed as passing; overlay tests used `-vet=off` because overlay-only package directories are not physical working directories for vet. A separate `gpt-6-astra` authority review (Opus unavailable) checked the complete plan and the added range/truncation tests. Its handle-acknowledgement, generation-selection, metadata-pinning and test-config race findings were addressed. Implementation-branch full gates and final authority review remain required.
+The HTTP restore/authorization/truncation tests compiled but could not execute: the sandbox refused `httptest`'s loopback listener with `socket: operation not permitted`. They and the unchanged flag-off HTTP regressions remain runtime checks for the implementation environment. Vet and the full repository test gate were not claimed as passing; overlay tests used `-vet=off` because overlay-only package directories are not physical working directories for vet. A separate `gpt-6-astra` authority review (Opus unavailable) checked the complete plan and the added range/truncation tests. Its handle-acknowledgement, generation-selection, metadata-pinning and test-config race findings were addressed. Rev 2 (controller) answers the independent review's P2: a flag-off console ignores `X-Carlos-DB-Handle` exactly as today and never echoes it; the v2 client's acknowledgement check rejects that response. Implementation-branch full gates and final authority review remain required.