oficina / suite Public

Correct reset proposal to retain corpus until verified reannouncement

Paul Campbell pushed by paul@keymail.dev e016d6f239957215a00f5a7687d5f7e3666abbe5 parent 0dc16b0
1 file changed, +9 −5
  • docs/superpowers/specs/2026-09-07-producer-protocol-proposal.md +9 −5

CI passed — run details

CI log
=== gate ===
ok  	amadan.net/oficina/suite	0.008s
ok  	amadan.net/oficina/suite/conformance	0.005s
diff --git a/docs/superpowers/specs/2026-09-07-producer-protocol-proposal.md b/docs/superpowers/specs/2026-09-07-producer-protocol-proposal.md
index db53c68..de27ddb 100644
--- a/docs/superpowers/specs/2026-09-07-producer-protocol-proposal.md
+++ b/docs/superpowers/specs/2026-09-07-producer-protocol-proposal.md
@@ -41,7 +41,11 @@ Mutation, item revision and feed event commit together. Feed anchors use a persi
For an authenticated invalid/expired/rewound cursor, answer HTTP409 with exactly {"code":"CURSOR_RESET"}. Do not include the rejected cursor or distinguish reasons on the wire. Invalid bearer still answers401 before parsing the cursor. Other409 bodies remain ordinary failures. Existing Memoria safely stops on409 today; it must gain the typed reset decoder before this protocol is usable through expiry.
-On typed reset, Memoria persists a source reset state before clearing its cursor, and withholds that source until a fresh enumeration completes. Proposed implementation deletes the source's indexed documents and derived dependencies using its existing provenance deletion path, in bounded resumable batches. Only after the source purge completes does it request empty cursor. An interrupted purge resumes; a failed HTTP call never initiates deletion; absence from a page never does. The typed reset is an authenticated explicit command to discard that consumer's source corpus, not an enumeration diff. The product cost is temporary loss of otherwise readable source results during rebuild; review must explicitly accept it.
+Correction after root review: Memoria main b9e5de9 design §4.1, “Post-restore reconciliation, and the phantom chunks”, already settles retention until a complete re-announcement. The earlier purge-on-reset proposal contradicted it and is withdrawn. Reset, restore and an incomplete enumeration authorize no retirement.
+
+On typed reset, Memoria persists reconciling state, excludes this source from ranking, and retains its old sealed corpus. It stages the new item/revision set separately. Proposed response headers, leaving Feed JSON unchanged: Suite-Reannounce-ID identifies one stable snapshot; Suite-Reannounce-Phase is open, page or close; Suite-Reannounce-Count is present only on close and equals the number of distinct items announced. The open and close markers are separate empty pages with advancing cursors; page rows are members of that snapshot, not delta events. Cursor and headers bind to the same snapshot identity. A zero-item snapshot still requires open then close(count0). Unknown, missing, repeated or out-of-order phases, snapshot changes and count mismatch fail the reconciliation; they cannot retire existing data. The shared Feed transport must preserve and strictly decode these headers before producer adoption.
+
+Only a verified close permits comparison with the retained corpus and retirement of omitted items through the durable tombstone path required by Memoria §4.1 and §7.4. Stage exact-revision fetched replacements during enumeration; failed fetches do not permit a completed/current claim. Publish the reconciliation atomically, or keep persistent reconciling state across resumable retirement/replacement batches until the full operation succeeds. An interrupted enumeration or unreachable source retains the sealed corpus, remains excluded from ranking and makes no freshness claim. Delta processing resumes from the snapshot boundary after close; later custody changes remain protected by S2. No reset handler deletes held documents.
No second reset endpoint, background ACK write or new successful Feed fields are needed. Rejected alternative: silently return a fresh snapshot for an invalid cursor. Current Poll would retain items absent from the snapshot indefinitely. Rejected alternative: delete on any non-2xx or short page. Current failure discipline must remain intact.
@@ -64,9 +68,9 @@ When a previously indexed item becomes empty, current Poll increments Empty with
## Implementation and review order
-1. Review this proposal with actual Memoria Poll owner and Docs/Sheets owners; decide reset purge cost, config limits and each first projection. No approved doctrine text changes here.
+1. Review this proposal with actual Memoria Poll owner and Docs/Sheets owners; verify staged reconciliation against §4.1, decide config limits and each first projection. No approved doctrine text changes here.
2. Add shared reset/auth/cursor fixtures and an adaptable conformance harness. Harness seeds real app records and accepts app-specific fixture IDs/body expectations; it must not swap the production router for a fake responder. Existing fixture defaults remain additive-compatible.
-3. Implement Memoria typed reset and empty-success retirement against a real producer; current raw-text mode can precede typed passages. Keep typed coordinates explicitly unsupported until decoder/storage/citations are implemented.
+3. Implement Memoria staged reset reconciliation and empty-success retirement against a real producer; current raw-text mode can precede typed passages. Keep typed coordinates explicitly unsupported until decoder/storage/citations are implemented.
4. Implement each approved app projection, custody state and atomic revision/feed. Run repository checks and exact-head CI; independent spec/branch review and deployed same-team HTTPS canary precede merge. Existing bds.oncarlos.com canaries fail the settled sibling hostname guard and are not an end-to-end suite transport substitute.
## Required gates
@@ -75,9 +79,9 @@ When a previously indexed item becomes empty, current Poll increments Empty with
|---|---|
| Config/auth | Wrong team, duplicate/retired token, two-epoch handover, no-token disabled mode, browser session cannot authenticate S2, bearer cannot write as a person. Logs contain no raw credential or cursor. |
| Feed | Page retry before/after partial application, response loss, independent consumers, empty tip stable cursor, max-page More, mutation rollback, TTL, restore-ahead and equal-sequence divergent anchors, cross-consumer cursor rejection. |
-| Reset |409 typed reset withholds then purges/rebuilds; failure during purge/rebuild resumes.401/403/429/500, malformed409, timeout and truncated page do not purge. Downgrade/deletion during reset never reintroduces custody-ineligible data. |
+| Reset |409 typed reset withholds and retains corpus; complete open/page/close count permits retirement. Missing close, count mismatch, cross-snapshot page, interrupted publication,401/403/429/500, malformed409 and timeout retain existing corpus and cannot claim freshness. Downgrade/deletion during reconciliation never reintroduces custody-ineligible data. |
| Freshness | Concurrent mutation between S1/S3, unavailable old revision followed by guaranteed newer event, source-behind S2 UNKNOWN, successful empty current revision retires old body/dependencies,404 does not. |
| Body | Raw mode enters existing parser as text; typed mode cannot enter raw parser; malformed/unknown coordinate, mismatched revision, oversized payload and silent truncation refused. Stable cell/block citation survives unrelated edits. |
| Real adoption | Shared custody fixtures drive real Docs and Sheets routers/storage, including existing grants and links. Memoria indexes, edits/refetches, withholds and revokes against these servers through suite transport. |
-Mutations must demonstrate failure when cursor acknowledgement precedes applied rows, cursor binding/anchor validation is removed, generic failures trigger purge, old content survives successful empty replacement, or JSON is fed to the raw-text chunker. None of the proposed gates is claimed as implemented by this draft.
+Mutations must demonstrate failure when cursor acknowledgement precedes applied rows, cursor binding/anchor validation is removed, reset or incomplete enumeration retires held data, old content survives successful empty replacement, or JSON is fed to the raw-text chunker. None of the proposed gates is claimed as implemented by this draft.