# Findings on the suite sharing doctrine, revision 2

**Verdict: request changes.** Reviewed by GPT-6 (Codex), 2026-09-05, independently of the draft and revision-2 authors. These are findings and proposed corrections, not new rulings. The doctrine has not been edited.

The review covers the whole doctrine at `0c4f098`, including `git diff 609394e..HEAD`, and the sibling sources identified below. P1 means a trust boundary or promised security property is broken or lacks an enforceable design. P2 means a contract, adoption, or verification defect that needs correction before implementation.

## Verdicts on the three priority changes

| Change | Is the defect real? | Is the correction right? | Consequences |
|---|---|---|---|
| S2 intersects authorization with custody, §4.3 | Yes. A previously ingested id lets a consumer distinguish a private item still granted to the asker from a deleted item. The unintersected join in memoria §4.1 permits this. | Yes, for the stated current-visibility privacy guarantee. A determinate non-custodial item must not produce `VISIBLE` or an existence-revealing alternative. | The claim that correct consumers lose nothing is false. They can hold legitimately ingested items when visibility changes. See finding 8. The fix also does not erase those copies: finding 6. |
| Typed asker on S2 and S6, §3 | Yes. Provisioning intent alone does not ensure that the two endpoints interpret the subject identically. | Yes. `{kind, value}` distinguishes a configuration mismatch from an authorization denial; `UNKNOWN` is the correct failure class. | Clean verdict on this change. Both request types and their fixtures must adopt it. Unknown or unsupported kinds must fail before item-dependent results; an unknown value of a supported kind can still be an ordinary denial. No extra network round trip is inherent in the tag. It does not prove shared authority or shared membership, and should not be claimed to do so. |
| Hand-off checks `Origin` and asks for confirmation, §7.1 | Yes. Same-site cookies permit a sibling page to submit a credentialed form without a deliberate create action. | The two protections are appropriate, but the commit protocol is incomplete. The home citation supplies a return-host check and login-state binding, not an already specified document-confirmation protocol. | The receiving and committing requests need different rules. Existing middleware and content policy also block the proposed flow, and confirmation adds a round trip. See findings 4 and 9. |

## Findings, ordered by severity

### 1. P1 — Making directory rows authoritative leaves an instance-token route around roster step-up

**Where:** doctrine §5.1, lines 221–225; §5.4, lines 279–283; §6, line 327; A.1. Home §6 and §9; Docs §9.1.

**What is wrong:** §5.1 says the roster is the existing directory rows with `kind = member`, made authoritative. The doctrine also says home calls 1–6 are unchanged. Home call 2 lets an instance upsert and revoke its directory rows under a consumer token. Docs spells out the submitted `kind` at lines 607–608. That was safe only while directory rows were hints.

**Why:** an instance can announce an attacker-controlled address as a member, or replay a queued pre-removal announcement. If call 8 derives the roster from those rows, the attacker becomes a team member without the owner action or fresh assertion required by §5.4. Conversely, instance-scoped deletion can affect membership if directory-row lifetime also defines roster lifetime. A table that serves both purposes needs a write-authority distinction; changing the reader does not create one.

**Confidence:** high; this follows from the specified writers and the proposed source of truth, without assuming a broken token check.

**Smallest correction:** give authoritative `(team, person, role)` membership its own owner-controlled record or equivalent protected provenance. Make call-2 rows projections/hints that cannot grant or revoke team standing. Amend the home-owned contract by citation after recording that boundary there. Test a member upsert, revoke, and delayed replay under an instance token against the authoritative roster.

### 2. P1 — The compromised-home bound is false, including its claim of unavoidable evidence

**Where:** doctrine §5.5, lines 292–301; §6.1, lines 359–361; §9 item 4, lines 502–503. Home §5.3–§5.5; activity design §2.2(b) and §5.1.

**What is wrong:** the doctrine concedes that a compromised home can add members but says it still cannot read documents or act silently. It names owner step-up and the instance's cached roster as bounds on that compromise.

**Why:** an added member can read team-visible content by definition. The attacker can use an account it controls after inserting that account into the roster. If compromise includes the credential origin and signing key, the attacker can also mint an assertion for an existing owner. The receiving grants join then authorizes that owner's actual rights; it cannot distinguish impersonation by the identity authority. The home spec explicitly identifies hostile `sub` as account takeover. This latter risk predates ruling 4.

Step-up performed by the compromised authority does not constrain it. Nor is a directory row or notification unavoidable when the attacker controls the process that writes or sends it. Existing-identity impersonation need not create a membership row at all. The activity design already acknowledges that call 7 removes an observable distinction between normal home traffic and exfiltration (§2.2(b)).

**Confidence:** high. A directory-origin XSS alone has a narrower scope; the doctrine must distinguish it from live directory-server or credential-origin compromise.

**Smallest correction:** separate those threat models and disclose the resulting membership and impersonation capabilities in §5.5 and §9. Describe notifications as evidence produced by honest execution, unless an independent, enforceable audit mechanism is designed. Do not claim that an instance's grants join defeats compromise of the authority that names the grantee.

### 3. P1 — The new writes have no contract for preserving or checking their source authority

**Where:** doctrine §4.3, lines 185–188; §7.1–§7.2; §11; A.4. Memoria §5.2, §9.1, §10 gates 9, 17 and 19, and §12.

**What is wrong:** transitive provenance is required, but the hand-off describes a document body and S8 describes actor and destination constraints. Neither defines how source identities and revisions survive a write into another app, or how that app enforces them on ordinary reads, exports, activity, and onward copies.

**Why:** save an answer derived from a Sheet into Docs, then revoke or edit the Sheet. Docs' own grant to Ana is insufficient to authorize the saved answer under §4.3. Merely assigning the newly created Doc a Docs id must not reset authority. The generic declaration does not tell Docs how to recognize or check this case.

There is also a concrete missing endpoint: an answer can include memoria-owned uploads or Notion material. Docs would need to check that source authority. Memoria decision 7, §9.1, and gate 17 explicitly prohibit sibling-facing endpoints; its §12 requires a new decision and leak entry before adding one. A.4 does not amend those clauses. A browser confirmation establishes the writer's intent, not an exemption from provenance.

**Confidence:** high that the required contract is missing. A particular implementation might enforce the general rule correctly, but the proposed fixtures and amendments do not establish that it can.

**Smallest correction:** define a bounded provenance envelope for both write paths, retain the original source authority, and require source checks on every disclosure path. Add the required memoria authorization surface through an explicit amendment, or defer hand-offs containing sources that the receiver cannot check. Add a two-hop write/read fixture with mixed authorities and a source revocation. Do not implicitly turn “save” into permanent republication.

### 4. P1 — A confirmation page does not specify a protected commit, and a receiver check is too late to prevent cross-team transmission

**Where:** doctrine §4.1, §7.1 lines 395–428, and §11 gate 7. Home §5.5–§5.6.

**What is wrong:** the new rule describes the initial POST's origin check and a confirmation screen, but does not bind the final mutation to the reviewed pending body, the receiver's browser/session, or a single redemption. Applying the sibling-origin rule to both POSTs would also reject the final same-origin Docs form unless Docs unnecessarily had a consumer row for itself.

**Why:** a bare second POST with a `confirm` flag can be submitted by the same allowed sibling that submitted the first. A screen appearing somewhere in the flow is not evidence that this browser reviewed this body. A nonce carried only in a URL is not itself browser binding; home §5.6 separately requires that binding to prevent login CSRF.

The sending side needs a boundary too. If memoria's form action is misconfigured to another team's Docs host, the body has already reached that instance before its `Origin` check rejects it. §4.1's sibling HTTP-client guard does not automatically govern an HTML form action. This contradicts §0's literal “a byte … reaches an instance” test even when the receiver refuses to save it.

**Confidence:** high that both obligations are unstated; this is a design gap, not a claim that a deployed hand-off is exploitable.

**Smallest correction:** distinguish the draft-receipt and commit phases. Validate the exact same-team destination before rendering the sending form. Accept allowed sibling origins only at draft receipt; commit through a receiver-origin form against bounded, expiring, single-use pending state bound to the browser and authenticated person, with the reviewed body fixed server-side. Preserve safe rendering and framing restrictions. Gate forged commits, replay, changed bodies, session changes, absent/null origins, and a foreign-team destination before transmission. OWASP likewise treats same-site subdomains and actual request validation as distinct concerns ([CSRF prevention](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html)).

### 5. P1 — Roster expiry does not yet bound revocation, and rollback can restore admission

**Where:** doctrine §5.3 lines 249–275; §5.4 lines 285–286; §5.5 lines 298–299; §11 gate 5.

**What is wrong:** a TTL triggers a refetch, but the doctrine never says what happens when that refetch fails. It still says requests enforce from the local copy and characterizes an outage or rollback as lag rather than admission.

**Why:** cache epoch 10, remove Ana at epoch 11, then make the home unreachable. Retrying at expiry while continuing to enforce epoch 10 admits Ana indefinitely. Refusing stale membership decisions bounds that exposure, but costs availability and produces `UNKNOWN` for S2, not the gate's universal `NOT_VISIBLE`.

A home restored to epoch 10 can also return Ana as a member to a receiver that already applied 11 unless lower epochs are rejected. An instance restored from backup must refresh before using its restored roster. A TTL alone does not settle either direction of rewind. “Within one epoch” is not an elapsed-time bound for an instance that has not learned the new epoch.

**Confidence:** high; these are direct failure sequences for the specified cache.

**Smallest correction:** state the usable-age limit and behavior after an unsuccessful refresh, including existing sessions and sibling reads. Publish a new roster only after a complete fetch and validation. Specify rewind detection/recovery and refresh-before-admission after restore. Express the revocation bound in time, including request deadline or grace if any; use a fake clock in gate 5 and separate successful revocation from unavailable authority. The TTL is an availability/security choice, not merely a sentence tightening or a number derivable from cold-wake latency.

### 6. P1 — The “inside” invariant and leak bound ignore copies retained after visibility changes

**Where:** doctrine §0 lines 38–41; §4.2; §9 item 1. Memoria §5.2, §6.1, §7.4 and §8.1.

**What is wrong:** §0 describes current custody as an invariant, and §9 says a compromised sibling cannot read private items. The pull design necessarily retains formerly team-visible content after a source makes it private or deletes it.

**Why:** memoria ingests revision 7 while team-visible; Docs then makes it private; memoria has not yet pulled `gone`. Publishing memoria's holdings now reveals content the team cannot currently read in Docs. S2 can prevent honest rendering, but cannot remove stored bytes. A compromised consumer can retain previously received content permanently. Memoria's snapshots, delayed pulls, and explicit circuit breaker against wholesale purges make it especially important not to equate denial at render with erasure of custody.

This also limits the existence-hiding claim: `gone` can conceal the distinction between deletion and privatization; it cannot erase knowledge that an item existed before.

**Confidence:** high; no implementation bug or malicious source is required for the initial retention window.

**Smallest correction:** distinguish authorized acquisition, current authorization to render, and eventual retirement of honest cached copies. State the synchronization/retirement bound and restore obligation by citation. In §9 include historical content acquired while eligible and the inability to recall it from a compromised consumer. Rewrite §0's test to match those guarantees rather than promise instantaneous distributed erasure. Also scope the “across” test to suite-mediated flows: existing export/upload features cannot prevent a person deliberately copying material between teams.

### 7. P2 — Gate 5 silently changes what removal means for guests and individual grants

**Where:** doctrine §5.2 lines 227–237; §5.4; §11 gate 5, lines 569–572. Home §5.5; activity design §4–§5.2; Sheets §8.2; Docs §8.2.

**What is wrong:** the gate requires every removed member to receive an empty call-7 response from every instance. The doctrine preserves instance-owned individual/guest grants and says nothing about guests changes.

**Why:** remove Ana's team standing while leaving a valid grant to one document. The instance still owns that grant, and call 7 is specified to evaluate it. Returning its activity is correct under the cited contract. Returning empty solely because Ana is off the team roster revokes a right §5.2 leaves instance-side. S2's custody filter does not change the separate call-7 contract.

**Confidence:** high. If complete offboarding is intended, that is an additional rule, not the current meaning of roster removal.

**Smallest correction:** make gate 5's removed-person fixture explicitly have no remaining independent grants, and add a guest fixture that retains only its granted activity. Alternatively, specify a distinct complete-offboarding operation and its effect on instance grants. Do not implement that policy by asserting the desired empty list in a test.

### 8. P2 — The S2 correction is right, but “costs a correct consumer nothing” is false

**Where:** doctrine §4.3 lines 194–208; A.4. Memoria §4.1 and §6.1.

**What is wrong:** the correction justifies its zero-cost claim using visibility at ingestion, even though its own attack depends on a later visibility change.

**Why:** memoria correctly ingested a document when team-visible. It is now private but still granted to Ana; its `gone` row has not reached memoria, or an answer already being processed still contains it. Before this change, S2 could return `VISIBLE` for Ana. After it, S2 returns `NOT_VISIBLE`. Ana loses the passage and any derived answer requiring it in memoria, while direct access in the source app remains valid. Asking S2 about previously ingested content is exactly how a correct consumer checks current authorization.

**Confidence:** high. This is a necessary product restriction under the chosen indistinguishability guarantee, not an argument to undo the intersection.

**Smallest correction:** replace the zero-cost paragraph with that explicit consequence and a source-app fallback. Add a transition fixture: ingest, downgrade while retaining Ana's grant, query before feed catch-up, receive `NOT_VISIBLE`. Keep the private/deleted response equality. Require custody denial to dominate revision-specific diagnostics in S2 and S6; otherwise `STALE(cell)` or a numeric diagnostic can reopen an existence distinction.

### 9. P2 — The hand-off needs middleware changes and an additional round trip

**Where:** doctrine §7.1 lines 401–428; A.2 lines 710–713. Docs `internal/docs/app.go:406–445`; memoria `cmd/memoria/main.go:24,75–77`; their rastrillo pins.

**What is wrong:** “no new machinery” and “neither costs a round trip” obscure actual consumer work. The proposed form cannot traverse the current sender and receiver unchanged.

**Why:** memoria uses rastrillo v0.23.0's default `Content-Security-Policy`, whose `form-action 'self'` blocks a form targeting Docs. Docs places rastrillo v0.22.0's `csrf.Protect` above every route; its `SameOrigin` rejects `Sec-Fetch-Site: same-site` even with the legitimate memoria `Origin`. Its session middleware also refuses an unauthenticated POST rather than preserving its body through sign-in. Finally, for an already signed-in person, receipt → confirmation → commit requires a second POST where revision 1 committed on the first.

**Confidence:** high. A temporary probe against Docs' actual pinned `csrf.Protect` produced `204` for a same-origin request and `403` for the proposed same-site request. Sender CSP and session behavior were checked in source, not exercised in a browser.

**Smallest correction:** name the narrowly scoped sender `form-action` allowance, dedicated receiving route and its replacement origin guard, pending-body/sign-in handling, and additional confirmation round trip. Preserve the normal same-origin write protections elsewhere. Extend gate 7 through the real middleware and browser policy, including a successful same-team flow. A handler-only fixture would miss both blockers.

### 10. P2 — Call 8 has no coherent paginated snapshot contract

**Where:** doctrine §5.3 lines 244–247 and 269–271; §6 call 8.

**What is wrong:** the review adds pagination but leaves the wire example unpaged, specifies no cap or cursor behavior, and says S2 and S6 already have cursors. They do not: their caps bound caller-supplied batches.

**Why:** fetch page one at epoch 10, change the roster, then fetch page two at epoch 11. Combining the pages can produce a membership set that never existed, skip a removal, or omit an owner. Publishing a partial response has a similar effect. Neither the example nor the citation tells the client which snapshot it received or how to restart.

**Confidence:** high, verified against memoria §6.1's signatures and §4.1's multiple-batch rule.

**Smallest correction:** specify a bounded page shape with epoch-bound cursor, completion indication, and invalidated-cursor response. Require staging and atomic replacement only after all pages of one epoch arrive. Name restart behavior on epoch change and refusal to treat partial/failing results as an empty roster. Add concurrent-change and failed-middle-page fixtures. Replace the inaccurate comparison to S2/S6 pagination.

### 11. P2 — The adopted S2 result vocabulary still lacks the source-behind case

**Where:** doctrine §4.3 and §6's adoption of memoria §4.1; §11 gates 1–2. Memoria §4.1 lines 484–514 and its acknowledged §13 defect.

**What is wrong:** the doctrine adopts four values without correcting the cited definition of `STALE`, which only covers a source that has moved past the requested revision.

**Why:** memoria has revision 7 and a restored source has revision 5. Returning `VISIBLE` would serve an unverified revision; returning `NOT_VISIBLE` silently represents synchronization failure as a denial. The total decoder only checks response completeness and shape. It cannot repair a validly encoded wrong classification. Memoria already records this exact unresolved defect in §13.

**Confidence:** high.

**Smallest correction:** define the nonmatching-revision outcome for both directions, with a recovery distinction if needed. Preserve a loud failure whenever current revision authority cannot be established, while keeping determinate private/deleted denial indistinguishable. Add forward and backward revision fixtures and include the correction in A.4.

### 12. P2 — The roster epoch does not pass the home claim test as cited

**Where:** doctrine §5.3 lines 251–256; A.1 lines 687–691. Home §5.4.

**What is wrong:** the doctrine says the epoch passes the existing test because a failed match is treated as absent. The home test requires non-identity claims to validate against a closed enumerated set and be cosmetically failable. A changing roster epoch is neither a closed cosmetic choice nor merely presentation data.

**Why:** if “failed match” means a different valid epoch, discarding it suppresses the very refresh this feature needs. If it means a malformed claim, the text needs to say so. More fundamentally, suppressing a refresh can leave an old membership decision in force until TTL expiry. Refetching rather than trusting a claimed role is a useful safeguard, but it does not make this the same kind of claim as theme.

**Confidence:** high about the citation mismatch. The bounded-staleness design can still be sound after finding 5 is resolved.

**Smallest correction:** record a narrow invalidation-hint exception in the home-owned test, distinguishing invalid encoding from a valid differing epoch. Make call 8 authoritative and its freshness bound independent of the claim. Cite that exception here instead of saying the unchanged test already passes.

### 13. P2 — The suite leak list omits new roster information and already-disclosed activity costs

**Where:** doctrine §5.1, §5.3, §9, and §11 gate 8. Home §6/§10 and activity design §2.2 and §7.

**What is wrong:** the list omits consequences of the features it adopts, and gate 8 claims the roster adds no column class.

**Why:** home's existing directory `kind` distinguishes member from guest; it does not distinguish owner from member. The new `role` does. If stored openly, publishing the database now identifies team owners. If sealed, the disclosure and test need to say that. Call 8 also distributes the complete team roster and those roles to each instance, rather than just the people known to that instance under the old local models.

The activity design explicitly discloses two suite effects in §2.2: a fine-grained signal of a person's front-door visits sent to their instances, and the loss of outbound-home traffic as a compromise signal. Neither appears in §9. Its §7 also retains last activity in RAM briefly after removal. Those are relevant alongside the existing title-in-RAM entry. Findings 2 and 6 identify two further bounds that need correction, rather than additional reassuring prose.

**Confidence:** high; the old directory schema and the activity disclosures are explicit.

**Smallest correction:** add citations for these costs in §9, choose the roster-role storage/disclosure treatment, and amend gate 8's expected disclosure accordingly. Exercise the actual persisted schema and failure paths; one roster fixture cannot prove that an entire database has no additional information class. An audit of column types alone also misses new information encoded in existing columns.

### 14. P2 — The consuming amendments preserve contradictions and introduce restatements

**Where:** doctrine §10; §12 steps 1–3; Appendix A; repository `AGENTS.md`.

**What is wrong:** the prescribed amendments do not produce the cited, consistent specs that §12 says unblock implementation.

**Why:** several concrete leftovers survive them:

- A.2's proposed Docs sentence names sibling service “in suite shape”; §3 and §12 explicitly require Docs and Sheets to serve lone peers before the home exists. The amendment must name the independent sibling-token switch or cite it without narrowing the scope.
- A.4 leaves memoria §11's explicit person-ref/home dependency on slice 1, its no-inbound-surface decision and gate, and its stale S7 admission gate. Replacing §4.3 alone does not remove those contradictions. Finding 3 makes the inbound-surface conflict operational rather than editorial.
- A.1–A.3 prescribe paragraphs paraphrasing boundaries, membership, and egress. That is the practice `AGENTS.md` and §10 say to replace with ruling-and-commit citations. Adding a citation after another copy of a rule still leaves another copy to drift.

**Confidence:** high; these are literal mismatches between the proposed replacements and the surviving source text.

**Smallest correction:** revise Appendix A as a complete list of consuming sections and gates to replace with citations, including the independent shape/token switch, memoria sequencing, admission fixtures, and required new authority surface. Keep locally owned behavior local. Do not declare slice 1 unblocked until the resulting specs agree; the doctrine itself can remain findings-only in this review.

### 15. P2 — Two stated sibling positions are not what their cited text says

**Where:** doctrine §2, §8 lines 474–479, §10 lines 523–527, A.2 §11.2, and A.3's AGENTS amendment.

**What is wrong:** the doctrine supplies a new reason for Docs' conversion-API rejection and treats Sheets' local spec-synchronization rule as a cross-repository rule.

**Why:** Docs §11.2, lines 929–931, rejects conversion APIs because they send customer documents to a third party. It does not say the provider was unnamed or the sending unavoidable. A per-team optional converter with a named provider could satisfy suite §8, so the narrower reason is a policy qualification, not verification that the old rejection already meant it. The ruling may authorize that qualification; the cited passage does not establish its historical premise.

Sheets `AGENTS.md`, lines 5–7, says that where **that file** disagrees with **its design spec**, the spec wins and the file must be fixed in the same commit. Both files are in Sheets. It does not demand one atomic commit spanning five repositories. Replacing that rule would remove a useful local consistency obligation to solve a problem it did not create.

**Confidence:** high for both readings.

**Smallest correction:** identify the Docs change as an intentional qualification under suite ruling 6, with its prior reason accurately cited. Retain Sheets' local same-commit rule and add a separate suite-citation requirement. Do not attribute the new positions to the earlier text.

### 16. P2 — Citation currency can stay green across binding changes

**Where:** doctrine §11 gate 9, lines 584–590; §10; Appendix A's introduction.

**What is wrong:** the new measurable revision only has to increase for changes to §1 or §6. Binding behavior also lives in §3–§5 and §7–§8.

**Why:** change the hand-off commit rule or roster stale-cache policy in its owning section, leave §6's citation untouched, and the prescribed revision can remain unchanged. A consumer of the old behavior passes currency indefinitely. The gate also does not specify checking that a claimed revision actually belongs to the cited commit. The appendix still asks only for a commit, although the new gate requires both.

**Confidence:** high.

**Smallest correction:** bump the revision for every normative contract change, wherever it lives; derive or verify revision from the cited commit; and update the consuming-section format consistently. A one-revision grace period is measurable, but remains a deliberate compatibility allowance, not proof that a consumer follows current security requirements.

## Gate-by-gate assessment

These are assessments of the proposed tests. No contract module exists here, so none of its gates was executed.

| Gate | Can it be written as stated? |
|---|---|
| 1. Fixture conformance | The harness can be written. Complete golden requests/responses still need the missing call-8/write shapes and error precedence resolved. Generic conformance must distinguish the calls each app actually serves; S6, for example, belongs to Sheets. |
| 2. S2 total decoder | Yes as a bounded decoder property, including an unsupported subject kind. It does not prove correct authorization or revision semantics: findings 8 and 11 need semantic fixtures. |
| 3. Custody | Yes with clarified fixtures. “Grant on a deleted item” should mean a former grantee or retained grant row, not require a dangling live grant contrary to an app's schema. Compare responses for the same requested id in private/deleted alternative states. Add the transition in finding 8. |
| 4. No cross-team dial | Literal zero connections for a server-issued redirect is impossible: the client must connect to the allowed first host to receive the redirect. Require zero connections for an initially forbidden host and zero **follow-up** connections after an allowed host redirects. Use two fixture servers or an instrumented transport. |
| 5. Roster | Not yet. “After one epoch” lacks an observation/time condition; failed refresh and retained guest grants have conflicting expected results. See findings 5, 7 and 10. The lone-instance no-home-network assertion is independently testable. |
| 6. Write-as-self | Yes for the three stated access checks, but derive actor identity from the authenticated consumer and test attempted actor spoofing. Actor/destination checks alone do not exercise provenance; finding 3 needs its own gate. |
| 7. Hand-off | Not as a complete proof yet. Define receipt/commit states and test through actual middleware plus browser policy. A screen-render fixture cannot establish user-confirmed mutation. See findings 4 and 9. |
| 8. Publish database | A seeded database disclosure test is feasible. The unchanged-information premise is false or at least undecided for owner roles, and a roster response fixture does not establish at-rest behavior. See finding 13. |
| 9. Citation currency | Arithmetic is feasible; normative coverage and commit/revision agreement are missing. See finding 16. |

## Sources and verification limits

Paths below identify the exact local documents used. Section and line references in the findings refer to those files as read on 2026-09-05.

| Source | Checkout and commit |
|---|---|
| [Doctrine](docs/superpowers/specs/2026-09-05-suite-sharing-doctrine.md) | This worktree, `0c4f098`; all sections read, revision-1 diff inspected. |
| [Home design](/home/paulca/amadan.net/oficina/home/.claude/worktrees/trunk/docs/superpowers/specs/2026-08-30-home-design.md) | `home/.claude/worktrees/trunk`, `5a42f2d`. The supplied primary checkout is on older `domain/oficina-works` at `462df84`, which lacks rulings 17–21; those citations were checked against `main` instead. |
| [Activity design](/home/paulca/amadan.net/oficina/home/.claude/worktrees/design-activity-pull/docs/superpowers/specs/2026-09-05-activity-pull-design.md) | `design-activity-pull`, `c9274bf`; still explicitly awaiting independent review. Adoption in principle is not approval of all its protocol details. |
| [Memoria design](/home/paulca/amadan.net/oficina/memoria/docs/superpowers/specs/2026-09-03-memoria-design.md) | `617eb2a`; relevant contracts, grants, ingestion, snapshots, gates and acknowledged open defects inspected. |
| [Docs design](/home/paulca/amadan.net/oficina/docs/docs/superpowers/specs/2026-08-30-docs-design.md) | `f6cf5c2`; also checked router/session integration and the v0.22.0 rastrillo CSRF implementation. |
| [Sheets design](/home/paulca/amadan.net/oficina/sheets-core/docs/superpowers/specs/2026-08-30-sheets-design.md) | `bad02cb`; grants join, roles, home contract, PRODUCT.md and AGENTS.md checked. |
| [Calendar design](/home/paulca/amadan.net/oficina/calendar/.claude/worktrees/calendar-first-screens/docs/superpowers/specs/2026-09-02-calendar-design.md) | `calendar-first-screens`, `f18898b`; no spec exists at the brief's primary-checkout path. The worktree spec and `internal/calendar/models.go` confirm the team-calendar grant model and absence of a commenter role. |

The module-path claim in §10 is correct for the checked `go.mod` files: Docs alone still uses `github.com/carlosframework/docs`. The S4/S5 resolution is supported by memoria §6.1. The home really does specify return-host allowlisting and browser-bound login state; finding 4 concerns the additional document-write protocol, not the existence of those protections.

Browser-request reasoning was checked against the [Fetch Standard's Origin handling](https://fetch.spec.whatwg.org/#origin-header) and [OWASP's CSRF guidance](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html). The middleware probe ran from a temporary file, using the installed dependency without network access; it made no live HTTP request. No end-to-end browser test or deployment was performed. Cross-repository discussions were not sent, and claims about Paul's private brainstorm or discussion 33's full contents were not treated as independently verified evidence.
