# Findings on the suite sharing doctrine, revision 3

**Verdict: request changes.** Reviewed by Fable 5.1, 2026-09-05, against the doctrine at `HEAD` of this worktree (`76bdc26`), `CODEX-FINDINGS.md`, `CODEX-REVIEW-BRIEF.md`, `git diff 0c4f098..HEAD`, and the sibling specs on disk. The doctrine has not been edited. Findings only.

## 1. My stake, and what it disqualifies me from judging

I am the model that drafted revision 1, and in the consultation after the GPT-6 review I recommended what became rulings 12, 13 and 14. Revision 3 itself is also Fable-authored text, by a different session. So:

- **Not independent:** whether rulings 12, 13 and 14 are the right decisions, and whether their "rejected" columns are honest. I have checked their *factual claims* against the sibling specs, because a citation is either right or wrong regardless of who recommended it, and I report where those claims fail. I have not tried to judge whether the rulings themselves are wise; a reader should discount anything approving I say about them and weight only the defects.
- **Independent:** ruling 15 and §4.2, which I had never seen; §7's envelope, §7.1's split, §7.3, §5.3's three new rules, all nine gates, Appendix A's new text, and the twelve findings answered in place. None of that text is mine.
- **A structural caveat** the status block should carry: `AGENTS.md` says the author of a draft cannot be its reviewer. Two of the three reviews of this document, and this one, are by the same model family that drafted it. A same-model reviewer shares the drafter's blind spots. This pass should not be counted as the "third pass" §14 waits on unless Paul decides it is.

Every citation below was read at: home `trunk` worktree `2b68301` (newer than the `5a42f2d` GPT-6 read — the §2.2 amendment has since landed), activity design in the same worktree, memoria main checkout (spec at 1459 lines, 21 gates, decisions to 12) and its `tensorx-provider` worktree where noted, Docs `2026-08-30-docs-design.md` and `internal/docs/app.go`, Sheets `2026-08-30-sheets-design.md`, `PRODUCT.md`, `AGENTS.md`, calendar `calendar-first-screens` worktree, Pegamento `e7442c2`, rastrillo `v0.23.0` in the module cache.

## 2. The sixteen findings

"Closed" means the document now survives the failure sequence the finding described. "Partial" means the mechanism is stated but the sequence, or the fixture the finding asked for, still gets through.

| # | Finding | Status | Why, in one line |
|---|---|---|---|
| 1 | Instance-token route around step-up | **Partial** | Own record and "call 2 cannot write membership" close the route; but gate 5 has no upsert/revoke/delayed-replay-under-instance-token fixture, which the finding asked for, and the drain-seeded first owner needs a person ref the drain cannot mint without the pepper (N6). |
| 2 | Compromised-home bound false | **Partial** | Ruling 13, §5.5 and §9.4 say the right thing. But the false sentence lives in **home §2 itself** — "a compromised directory grants nothing. A compromised home costs the graph and a convenience outage. It does not cost a document." — and A.1 leaves it standing. The doctrine also misattributes: it says revision 1 widened home §2's *directory* sentence to *home*; home §2 says both, so the widening is the home spec's, not revision 1's. |
| 3 | No provenance contract on writes | **Partial** | Envelope shape and the refuse-unverifiable rule are real. But the check "still authorize the *asker*" cannot run on an S3 fetch (no asker) or a link view (no roster subject), "loses that passage" is undefined once a person has edited a CRDT body, and STALE on a saved answer is unstated. N2, N3. |
| 4 | Commit protocol and sender-side check | **Closed** | Receipt/commit split, body fixed server-side, single redemption, browser and person binding, destination checked before render, gate 7 through the real middleware. |
| 5 | Failed refetch and rewind | **Partial** | Failed refetch has a rule, but it keeps serving admitted sessions (30-day framework default, sliding renewal), so the removed member the paragraph cites keeps access anyway (N5). The rewind rule is defeated by epoch-number reuse after a restore (N4). No time bound on the TTL, still "measured later". |
| 6 | Copies retained after visibility change | **Partial** | Ruling 14 and the rewritten §0 are right in shape. But §0 promises retirement "within one feed pull plus its stated retention (§4.2)" and §4.2 states no retention; and memoria's gate 8 circuit breaker purges nothing on a wholesale purge — the exact case the finding named — so the honest instance does not retire within one pull (N7). |
| 7 | Gate 5 silently offboards guests | **Closed** | "Holding no other grant" and the guest fixture. |
| 8 | "Costs a correct consumer nothing" | **Partial** | Cost paragraph corrected. The transition fixture is mentioned in a parenthetical and appears in no gate. "Custody denial must dominate revision diagnostics in S2 and S6 (`STALE(cell)`, `NON_NUMERIC`)" is not addressed anywhere (N10). |
| 9 | Hand-off needs middleware changes | **Closed** | §7.1's bill and A.2 match what is pinned (`form-action 'self'` at rastrillo v0.23.0 `serve.go:399`; `csrf.Protect` at Docs `app.go:412`). |
| 10 | Call 8 paging | **Partial** | Epoch-bound cursor, staging, refusal and "empty is not nobody" are stated. The wire example is still `GET /roster?team=&epoch=` → `{epoch, members}` with no cursor, cap or completion field, and gate 5 has no concurrent-change or failed-middle-page fixture. |
| 11 | Source-behind revision | **Partial** | `UNKNOWN` is the right value and A.4 carries it. No forward/backward revision fixture in §11, which the finding asked for. |
| 12 | Epoch claim and home §5.4 | **Closed** | Own exception, argued from "the instance decides nothing from it", recorded in A.1. |
| 13 | Leak list omissions | **Closed** | §9 items 8–10, gate 8 rewritten. |
| 14 | Amendments leave contradictions | **Partial** | A.2's shape sentence, A.4's §11/fixtures/decision 7 are fixed. A.3 still misses Sheets `PRODUCT.md` **principle 3** (line 170: "Never design a flow that implies data can move to another instance"), which is the sentence memoria §13's blocker names — so A.4's "close the blocker against A.1 to A.3" cannot close it. A.1 misses home §2, §2.1 and §10 (N6). |
| 15 | Two positions misattributed | **Closed** | Docs §11.2 read correctly as "ships customer documents to a third party"; Sheets `AGENTS.md` kept. |
| 16 | Citation currency | **Closed** | Any normative change bumps; revision checked against commit. |

Closed 7, partial 9, open 0. The status block's "Revision 3 answers all sixteen" is the same kind of claim GPT-6 flagged in revision 2's "no new machinery": true of the citations, not of the failure sequences.

## 3. New findings, by severity

P1: a trust boundary or promised property is broken, or a normative rule cannot be built as stated. P2: a contract, adoption or verification defect. P3: accuracy.

### N1. P1 — Ruling 15's "edit" link and §7.3 contradict a Paul ruling in Sheets and Docs §8.2, and cite neither

**What is wrong.** Sheets §1 ruling 12: *"Link sharing is viewer-or-commenter, never editor"*, rejected alternative *"Anonymous link editing"*, **Paul, 2026-08-30**. Sheets §8.3: an anonymous editor "would write unattributed rows into version history". Docs §8.2: *"Link shares are a per-document capability, viewer or commenter, never editor. Anything that writes is attributed, and attribution is what mints membership."* Doctrine ruling 15 makes a link "view or edit", and §7.3 builds the actor Sheets rejected by name — *"the honest actor is the link capability itself"* — and calls it a satisfaction of ruling 9. §7.3 cites neither spec; A.2 and A.3 amend neither §8.2 nor §8.3.

**Why it matters.** This is not a drift between restatements; it is a new ruling overturning a settled one without saying so, in the document whose one rule is that a ruling lives once. The moment Docs adopts A.2, Docs §8.2 and suite §7.3 disagree and gate 9 has nothing to say about it. It also weakens ruling 9: "a write names its real actor" becomes "a write names a bearer token", which is what ruling 9's rejected column calls a write capability without an identity.

**The product requirement does not need it.** "Anyone with the link can edit" is already how Docs builds its commenter link: the link is a capability to *obtain* a grant — the holder signs in, attribution mints a guest member, and from then on they are on the `granted` rung with a person ref. That gives Paul all four product states, keeps every write attributed to a person, keeps S2's asker a roster subject with no special case, and deletes §7.3 and leak item 11's "the app cannot name them" — because it can, after the first write.

**Confidence:** high that the contradiction is real and uncited. High that the sign-in-mints-guest shape satisfies the requirement; whether Paul wants anonymous editing anyway is his call, in which case ruling 15 must name Sheets ruling 12 as overturned and A.3 must amend it.

**Smallest correction.** Ruling 15: "view, or edit after sign-in — an edit link is a capability to obtain a guest grant (Docs §8.2, Sheets §8.3), never an anonymous actor." Delete §7.3. Leak item 11 loses "or writes".

### N2. P1 — The provenance envelope has no rule for a viewer who is not a roster subject, which makes a link on a Doc a link on the Sheet it quotes

**What is wrong.** §7: on every disclosure path the receiver "checks that the sources still authorize the asker, through S2 to each app of record". A link holder has no asker subject (§3, §7.3). So for a Doc carrying an envelope, viewed through a link, the check cannot be made — and the doctrine says nothing about what happens then.

**Why.** Ana saves a memoria answer quoting a team-visible Sheet into a Doc, then link-shares the Doc to a contractor. If Docs shows the Doc, the contractor reads Sheets content nobody granted; the link has laundered the cell through one hop, which is the exact thing §4.3's transitivity rule forbids. If Docs refuses, link-sharing a Doc containing any saved answer silently stops working, and nothing says so. Guests are half-covered by accident: S2 to Sheets for a Docs-only guest returns `NOT_VISIBLE`, so the passage is withheld — but the doctrine should say that too, because it is a product surprise ("my guest cannot see the table I pasted").

**Confidence:** high.

**Smallest correction.** One rule in §7: an item carrying an envelope discloses envelope-derived passages only to an asker every source can be asked about; to anyone else — link holders, and under N1 any un-signed-in visitor — those passages are withheld loudly and the rest of the item renders. One fixture in gate 6b: link view of the item from gate 6b's own scenario, expect the passage withheld.

### N3. P1 — §7's check cannot run on an S3 fetch, so gate 6b cannot be written as stated

**What is wrong.** §7 lists "an onward S3 fetch" among the disclosure paths that check "the asker". S3 carries no person (§6, memoria §6.1). Gate 6b asserts "its S3 answer … lose[s] that passage and name[s] the app" — S3 answers a body or a 404 (memoria §6.1) and has no representation for "withheld loudly, app named". And there is no person-less call by which B can ask A whether a source is still team-visible.

**Why.** §11's first line: a gate that cannot be written as stated is a spec bug. This one cannot. Worse, the thing that *would* work is already in the contract and unnamed: S3 itself is the custody probe — B fetches `(id, revision)` from A; 200 means team-visible, 404 means not.

**Confidence:** high.

**Smallest correction.** In §7, split the disclosure paths by what they carry: per-person paths (read, export, activity) check S2 for the asker; the custody path (S3) serves envelope-derived passages only for sources B has probed team-visible at the app of record, and strips the rest silently — S3 is custody-only and must not become loud, or gate 3's "404, never 403" gains a third status. Gate 6b's "revoke the source in A" becomes two fixtures: "take the source below the `team` rung" (S3 loses it) and "revoke the asker's grant while the source stays `team`" (read and export lose it; S3 does not).

Two adjacent gaps in the same rule, both P2 on their own: **what "loses that passage" means once Ana has edited the saved answer** — a CRDT body has no separable passage after the first edit, so either the saved answer is an immutable quoted block that is withheld as a unit, or provenance attaches to the whole item and the whole Doc is withheld, or the rule stops at a person's deliberate act; the doctrine must choose. And **what `STALE` does to a saved answer**: under memoria §4.1 any edit to the Sheet makes the saved revision stale, memoria regenerates but Docs cannot, so a saved answer decays on the source's first edit; say so, or say Docs treats `STALE` as `VISIBLE`-with-a-notice, which is a different rule from memoria's.

### N4. P1 — The rewind rule is defeated by epoch-number reuse, and a home that loses `memberships` has no rebuild path

**What is wrong.** §5.3: an instance refuses an epoch below the one it holds "until the home passes its own high-water mark". The home does not know the high-water mark — it was in the backup it lost. Sequence: instance holds 11; home restored at 10; owner adds someone → home is at 11 with a *different* set; the instance sees an equal epoch and, per §5.3, does not refetch; the next write → 12 → accepted, and everyone removed between old-10 and old-11 is readmitted. Finding 5's sequence, delayed by two writes.

**Second half.** Home §10: *"Losing this database loses credentials, not access. The directory rebuilds as instances re-upsert."* Under ruling 12 the roster does not rebuild — call 2 cannot write membership, no channel runs home→instance, and instances hold the only copies. A home that loses `memberships` loses every team's roster suite-wide, and with no owner in the table nobody can write it. A.1 does not amend §10's sentence, and no recovery is written.

**Confidence:** high on the collision; medium on the fix shape.

**Smallest correction.** Epoch is `(generation, counter)`, the generation minted at each home restore; an instance seeing a generation it has not seen treats the home as unavailable until an operator verb re-seeds `memberships` and marks the generation trusted. Write the re-seed into home gate 8's restore drill (each instance's call-8 copy is a candidate source, which is a reason to keep those copies rather than treat them as disposable). Amend home §10 in A.1.

### N5. P1 — The stale-roster rule pays availability for a property it does not buy

**What is wrong.** §5.3: past the TTL with no successful fetch, the instance "keeps serving people it has already admitted for the length of their session" — then says the alternative it rejected is "an unreachable home lets a removed member keep their access for as long as the outage lasts". Those are the same thing for anyone already signed in. Instance sessions are rastrillo's 30-day default (memoria §13 says so of memoria; nothing in Docs or Sheets overrides it) and home §2.1 asks for *sliding* renewal, so "the length of their session" is unbounded during an outage. §5.4's promise — removed "within one epoch, and on an instance that admits nobody, within the roster TTL" — has an exception the stale rule creates and does not name.

**What the rule does cost:** during any home outage longer than the TTL, every instance answers `UNKNOWN` on S2, so memoria withholds every sibling passage for every member for the outage, and no one new signs in — which the home outage already prevents (home §2.1), so that half buys nothing either.

**Confidence:** high.

**Smallest correction.** Either refuse team-standing-based requests for *all* sessions past the TTL (which is what "costs availability on purpose" already claims), or state that existing sessions are bounded by the instance session TTL, put a number on that TTL in the contract module with its reason, and write the exception into §5.4. Either way the cost paragraph should stop claiming the rejected alternative is different from the chosen one.

### N6. P2 — Ruling 12 makes the home hold and enforce a person-level entitlement, and A.1 does not amend the sentences that forbid it

**What is wrong.** Both factual claims in ruling 12 are true against trunk `2b68301`: home §6 says "`kind` is member or guest", §10's `directory` table is `person ref, app, team sqid, host, kind`, and §7's sentence is quoted accurately (from the fast-path paragraph). But the new table's *writer* rule — "written only by an owner" — is the home deciding "may this person write the roster", and home ruling 19 says the home answers "never 'may this person'", home §7 says "It never forms an opinion about whether a person is entitled to anything", and home §2.2's "what you may *do* is the instance's business" is the stated ground for home ruling 15 rejecting a per-team 2FA floor. §5.2's "is this person on this team is a fact about its records" does not cover "may this person add a member". A.1 amends §7's "never learns" sentence and nothing else in that argument.

Also unamended by A.1, each now false or stale:

- Home §2 bullet 1 (finding 2's sentence; see the table).
- Home §2.1 "Losing it costs a convenience, not access — for the directory": under §5.3, a home outage past the TTL now costs access at every instance.
- Home §10 "loses credentials, not access" (N4).
- "Complete ruling 18's pending change of *never renders* to *never stores*" — landed at `2b68301`; A.1 asks for a change that is done.
- §5.3 says call-2 and call-5 responses carry the roster epoch; A.1 only adds the assertion claim and call 8.
- The seeded first owner arrives as a **sealed address** (home §7); `memberships` keys on a person ref; minting a person stub needs the blind index and therefore the pepper (home ruling 4: the home hashes). The drain runs outside the home process (§7). Who hashes is unstated.
- "Move *step-up for instances* to built-when" — home §14's row is an instance-side `RequireFresh` round trip; the roster write is a directory-origin flow. Defensible since the directory obtains sessions like a consumer (§4), but A.1 should say that is the reading.

**Confidence:** high on every item; they are literal.

**Smallest correction.** A.1 lists ruling 19's second half, §7's "never forms an opinion", §2's bullet 1, §2.1's line, and §10's sentence as amended, states who hashes the seeded owner's address, and drops the already-landed item.

### N7. P2 — §0's retirement promise cites a retention that is stated nowhere and is false for memoria's wholesale case

**What is wrong.** §0: an honest instance retires "within one feed pull plus its stated retention (§4.2)". §4.2 states no retention; S1's per-consumer TTL is the *feed's* retention, not the consumer's purge delay. Ruling 14: "what it must *retire* is stated and timed" — neither. And memoria gate 8: "a wholesale `NOT_VISIBLE` or 404 response states an anomaly and purges nothing"; §5.1's enumeration diff "deletes nothing on a timeout … or partial page". A team folder made private produces a wholesale `gone` in one pull; whether the breaker fires on `gone` rows is unstated, and if it does the honest instance retires nothing — the case finding 6 named explicitly.

**Confidence:** medium-high; it turns on memoria's breaker semantics, which the doctrine adopts by citation.

**Smallest correction.** §4.2 names the bound (one S1 pull plus a purge delay with its reason in the module). A sentence that `gone` rows are applied even when wholesale — the breaker is for S2/S3 anomalies, not for the feed — or the promise in §0 shrinks to what the breaker allows.

### N8. P2 — The ladder's `team` predicate has no rung for "team minus exclusions", which Sheets already has

**What is wrong.** §4.2's predicate is "readable by every roster member by virtue of team standing alone". Sheets §4.5's join is "rows this team can see, plus rows granted to me individually, **minus rows I have been removed from**". A team-visible sheet with one member excluded is readable by every member but one. Under the predicate as written it is not `team`, so custody excludes it and the whole team loses it in memoria because one person was removed; or Sheets' predicate function calls it `team` and the exclusion is enforced by S2 — which is what the two-rule design intends, and is what the doctrine should say. Same question for calendar, whose team calendar is "a grant everyone holds" (§2), which reads as `granted` under the table.

**Confidence:** high that it is unstated; the intended answer is clear.

**Smallest correction.** Predicate: "team standing alone suffices for a member who has not been individually excluded; exclusions are S2's business, not custody's". A.5 says calendar's `Kind = team` maps to the `team` rung.

### N9. P2 — Link changes and the feed are unstated

The brief asked. Under ruling 15 the coherent answer is that a link created or revoked on a `team` item is invisible to S1 — not `gone`, not a revision — and a link on any other rung was never announced. The doctrine does not say it, and the leak is real if an app bumps `touched_at` or `revision` on link creation: S1 carries no visibility flag by design, and a metadata bump on link creation is "this team item was just link-shared" through the side door. One sentence in §4.2; one assertion in gate 3 (create and revoke a link on the `team` fixture, expect no feed row).

### N10. P2 — S6's diagnostic values can reopen the existence distinction (finding 8's second half)

S6 returns `STALE(cell)`, `NON_NUMERIC(cell)`, `MIXED_UNITS` (memoria §6.1). §6's S6 row says "the custody intersection, as S2" but nothing says `NOT_VISIBLE` dominates every other value, and gate 3 covers only S2. A cell in a `private` sheet answering `NON_NUMERIC` tells a sibling the sheet exists. One sentence in §4.3; one S6 fixture in gate 3.

### N11. P2 — Four memoria citations resolve only in an unmerged worktree

"memoria decision 13, Paul, 2026-09-05" (§8), "Decisions 13 and 14 stand" (A.4), "memoria §8.4, gate 26" (§6's S2 row), and leak item 7's "memoria §3.2" rendered-page entry all exist in `memoria/.claude/worktrees/tensorx-provider` and not on memoria's main checkout, which has 21 gates and decisions to 12. The citations are accurate to that worktree — gate 26 is "every passage id in a model prompt is one S2 returned `VISIBLE` for in this same request" — but the doctrine presents them as memoria's spec. Gate 9 checks app→doctrine currency; nothing checks doctrine→app. Smallest: a sources table like `CODEX-FINDINGS.md`'s, naming the commit read per sibling and marking these as pending merge.

### N12. P2 — Gates that still cannot be written as stated

- **Gate 5** "after one epoch" still has no observation condition (GPT-6's words, unchanged). Writable as "after the instance's next call-8, driven by a differing claim on the fake clock". No fixture for finding 1's instance-token replay, finding 10's failed middle page, or finding 8's transition.
- **Gate 6b**: N3.
- **Gate 7** "the absent and `null` origin cases decided explicitly" is not an assertion; say refused.
- **§7.3 has no gate at all** (moot under N1).
- **§11's preamble** says gates live in the contract module; gates 5, 8 and 9 cannot — 8 is a home-repo database test, 9 is a script over five repos. Say which gates are fixtures and which are app-side obligations.

### N13. P3 — `UNKNOWN` now has four meanings and no reason code

Unsupported subject kind (§3, whole call), sibling past deadline (§6.3), source-behind revision (§4.3, per item), stale roster (§5.3, scope unstated). The consumer's honest move differs — re-ingest, retry, nothing. An additive `reason` on the wire. And say stale-roster `UNKNOWN` is whole-call: per-item, a stale instance would answer `NOT_VISIBLE` for private and deleted items and `UNKNOWN` for team ones, and gate 3's byte-for-byte promise should hold during staleness too.

### N14. P3 — Small mis-citations, mostly carried from revision 2

- §7.1: "Home call 6, whose shape this borrows, carries two protections (home §5.6)". §5.6 is the sign-in redirect protocol; call 6 is §8. The protections are real, the section is wrong.
- §6.3: "a consumer pre-warms on its own wake (memoria §6.5, activity design §6)". Memoria §6.5 does; activity §6 has a minimum pull interval and no pre-warm.
- §5.6: "Docs has none yet". Docs §8.2 has viewer and commenter for links, and §7.4 comments.
- Ruling 13's rejected column, on home §2: see finding 2.

## 4. Verdict

**Request changes.** N1 through N5 are each a trust-boundary or build-as-stated defect in text no reviewer has seen, and N1 contradicts a Paul ruling in a sibling repo without naming it. Nine of the sixteen prior findings are partial, mostly where a mechanism is stated and the fixture the finding asked for is not.

Ruling 15 in particular should not go to Paul as written: the sign-in-mints-guest shape satisfies his four states and needs no new actor, and he ruled against anonymous editing on 2026-08-30. If he wants to reverse that, the row must say so.

## 5. Worse than revision 2

1. **A new contradiction with a settled ruling.** Revision 2 had no link rung and was consistent with Sheets ruling 12 and Docs §8.2. Revision 3's §7.3 builds the alternative that ruling rejected by name, and the document whose one rule is "cite, never restate" does not cite it (N1).
2. **A wrong rule where there was a gap.** Revision 2 was silent on provenance across a write; revision 3 states a rule that names an asker on a person-less call and lists disclosure paths one of which cannot perform it (N3). Under §10, A.2 will carry that rule into Docs as a citation, so it propagates rather than drifts.
3. **A lockout mode where there was lag.** Revision 2's stale roster was lag. Revision 3's is refusal below a high-water mark the home cannot observe, exited by a condition number reuse satisfies falsely (N4), plus suite-wide `UNKNOWN` on S2 during any outage past the TTL for a property the same paragraph gives back (N5).
4. **A promise in §0 with a citation to nothing.** Revision 2's §0 was instantaneous and false. Revision 3's is bounded by "its stated retention (§4.2)", and §4.2 states none (N7). A false absolute is at least legible; a bounded promise pointing at an empty section reads as kept.
5. **The same overclaim GPT-6 caught, one revision later.** "Revision 3 answers all sixteen" in the status block, §12 step 0, §14 and the README, where nine are partial. Revision 2 said "no new machinery"; the doctrine now records that as a defect and repeats its shape.

Nothing in revision 3 is worse than revision 2 on the twelve findings answered in place except where noted above; the hand-off (§7.1), the epoch claim (§5.3), the leak list (§9) and the Docs §11.2 reading (§8) are clean improvements.

---

### Appendix — gates, refreshed

| Gate | Writable as stated? |
|---|---|
| 1 Fixture conformance | Yes; call 8's paged shape and S8's write shape still need golden fixtures before it means anything. |
| 2 S2 total decoder | Yes. |
| 3 Custody per rung | Yes for S3 and S2; missing S6 (N10), the link-change no-feed-row assertion (N9), and finding 8's transition. |
| 4 No cross-team dial | Yes. The hand-off destination check is a different code path (form render, not the client); fine to share a gate, say so. |
| 5 Roster | Not yet: "after one epoch" needs an observation; no instance-token replay, no failed-middle-page, no existing-session case for the stale rule (N5), no generation-change case (N4). |
| 6 Write-as-self | Yes. |
| 6b Provenance | No: the S3 clause (N3); no link-view case (N2); "revoke" ambiguous between rung change and grant change. |
| 7 Hand-off | Yes, once "decided explicitly" becomes "refused". |
| 8 Publish the database | Yes, in the home repo, not the contract module. |
| 9 Citation currency | Yes for the arithmetic and commit check; "any normative change" is a judgment the script cannot make, which is fine if the doctrine says a reviewer makes it. |
