Skip to content

docs(plans): name the membership predicate the server actually calls - #1951

Merged
lilyshen0722 merged 1 commit into
mainfrom
kai/docs-membership-predicate-name
Sep 27, 2026
Merged

lilyshen0722 merged 1 commit into
mainfrom
kai/docs-membership-predicate-name

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Wren's ruling from 74721. Five lines across the two connector plans state the server's rule in the present tense and name isPodMember — the creator-inclusive spelling those pages were written against, and one that no enforcement site calls any more.

Retargeted to isListedPodMember

file:line states
docs/plans/d8-phase-2-gate-surface.md:92 a gate key must name a pod the owner is a member of
docs/plans/d8-phase-2-gate-surface.md:94 the install verb, a gate key and PATCH { podId } all check it "and nothing else"
docs/plans/connector-as-installable-app.md:346 isPodMember(pod, installer) — the #1297 write gate, reused
docs/plans/connector-as-installable-app.md:381 the chosen pod is gated by it (write predicate, no admin read-bypass)
docs/plans/connector-as-installable-app.md:385 it + identity-derived targets, nothing else

The name is real on main today and is the one the gates call: routes/integrations.ts, routes/installables.ts, routes/podInvites.ts, routes/activity.ts, controllers/pgMessageController.ts, server.ts, services/connectorRelayPolicy.ts and the bridges all destructure isListedPodMember from utils/isPodMember. The permissive isPodMember is still exported on main with zero production callers; #1949 deletes it. So this docs change is consistent before or after that merge.

Left as history, per the ruling

  • docs/plans/connector-as-installable-app.md:224 — "gated the pod by isPodMember while uninstall had no matching gate" (Vera, 2026-09-02). Past tense, describing what the old gate did.
  • docs/development/agent-experience-audit.md:3988 — the entry that records the two-functions-one-name collision. It is the record of the old name, and it stays.

What this is and is not

Not a safety fix, and the body should not claim one. A stale identifier in prose fails loudly: require('./utils/isPodMember')() throws, and a destructured isPodMember is undefined and then throws. Nothing here was silently permissive — which is Vera's argument (74719) for not spending a PR on the name alone, and it is why this PR does not add a guard for doc prose.

What was actually wrong is narrower: d8:94's claim that the pod list "shows exactly what the server would accept" was false while the creator clause counted as membership, because the list is built from pod.members and the gate accepted one more principal. The page now names the rule that makes its own sentence true.

Witness: __tests__/unit/scripts/docReferences.test.js 6/6 — that suite deliberately excludes docs/ prose (its own header says docs are the docs room's inventory), so I am recording that no automated arm covers these five lines rather than implying one does. The referenced symbol's existence is asserted by #1949's export-shape arm, not by this PR.

One judgement disclosed: no "renamed from isPodMember" note was added beside the new name. The old spelling stays discoverable in the two history lines above, and the plans are dated records rather than a learning surface.

Wren (74721): five lines in the connector plans state the server's rule in the
present tense and name `isPodMember` — the creator-inclusive spelling, which is
what those pages were written against and which no enforcement site calls any
more. Retargeted to `isListedPodMember`, the predicate every gate in
`routes/integrations.ts`, `installables.ts`, `podInvites.ts`, `activity.ts` and
the bridges actually calls.

- d8-phase-2-gate-surface.md:92 — a gate key must name a pod the owner is a member of
- d8-phase-2-gate-surface.md:94 — the install verb, a gate key and `PATCH { podId }` all check it
- connector-as-installable-app.md:346, :381, :385 — the write gate, the chosen pod, the target derivation

Kept as history, per the ruling: connector-as-installable-app.md:224 (Vera,
2026-09-02, describing what the old gate did) and the AX-audit entry that records
the two-functions-one-name collision.

Not a safety fix and not sold as one: a stale identifier in prose fails loudly —
a bare `require(...)()` throws, a destructured name is `undefined` and then
throws — so nothing here was silently permissive. What was wrong is narrower and
worth fixing: d8:94's "the list shows exactly what the server would accept" was
false while the creator clause counted as membership, and the page now names the
rule that makes it true.
@lilyshen0722
lilyshen0722 added this pull request to the merge queue Sep 27, 2026
Merged via the queue into main with commit 55fa29d Sep 27, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant