You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
docs(adr),plugin-security: retire the dead audience-anchor binding gate and restate the ADR text that names the C3-retired security modules (ADR-0138, 0094, 0126, 0131, 0103) #23403
SecurityPlugin.assertAudienceAnchorBindingGate guards only sys_position_permission_set, which S8 unregistered, so it has been unreachable since then.
This is a sub-card of #22975 (the epic chain #15194), filed by domain:engine seat 2 (session_01ADzJtzYTLUfgrRZHxkagkX). It is governed by path (docs/adr/**), so it is Tier H: the maintainer approves it.
Scope. Check each item first against what a581c57eae (the ADR sweep that recorded stage 8's retirement) already fixed.
ADR-0138: line 171's anchor to security-plugin.ts#SecurityPlugin.assertAudienceAnchorBindingGate, and the rows at lines 371, 395 and 578 that call that gate the enforcement of the D9 anchor binding tier.
Restate them as true on main: after S8 no binding door exists for an audience anchor, and the gate is retired.
Re-point or drop the anchor.
Then delete the gate, its call site (security-plugin.ts, about :2536) and its cases in security-plugin.test.ts (about :4712–:4729). These go in the same PR, so the anchor gate never sees a dangling anchor.
ADR-0094: the text naming permission-set-projection.ts as its machinery.
ADR-0126: "Three real mechanisms", which names the deleted modules.
ADR-0131: the Consumers line (about :59) and the code list (about :993).
ADR-0103: about :52, assertSystemRowWriteGate in prose.
PermissionSet.description's liveness (its own card).
Acceptance:
every named line is true of main;
check:adr-symbol-anchors exits 0 with the gate deleted;
the gate's deletion carries a changeset (@objectstack/plugin-securitypatch; it is not an entry export) and no behaviour change, since it was unreachable since S8;
the body has a ## 维护者速读(草稿) section.
Order: independent of 8-post. It lands after 7a, because it cites 7a's deletions as done.
Claim: PM loop round 1 · 2026-10-14T05:58Z · a sub-card of #22975 (the ADR-0131 epic chain), inside the epic-only scope (maintainer, 2026-10-13T12:24Z: 「你现在开始只处理和这个 epic 相关的卡片」)
Session: session_01ADzJtzYTLUfgrRZHxkagkX
Account: os-steve (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-23403-adr-c3-restatement
Worktree: objectstack-issue-23403 (in the cloud session's own checkout)
Domain: domain:engine (derived from in-flight #22975)
Seat: domain:engine#2 (seat post #20966)
File surface: docs/adr/0138-*.md, docs/adr/0094-*.md, docs/adr/0126-*.md, docs/adr/0131-*.md, docs/adr/0103-*.md (governed: Tier H); packages/plugins/plugin-security/src/security-plugin.ts (the gate and its call site only), security-plugin.test.ts (its cases only), the anchor JSON it frees, one changeset
Container & model: S, mode:cloud (session_01287UbjvrigpWwNfGDmdwpS, the #22975 build-ahead session), model: default
Clause-②: no
Responsibility: n/a — not a defect card
Thread-read: none
Serial constraints cleared: 7a (PR #23368) is in the queue, and this card lands after it; 8-post (#22975) keeps the gate, so the two do not overlap
{
"issue": 23403,
"status": "done",
"branch": "claude/issue-23403-adr-c3-restatement",
"head": "59761d4a71",
"pr": "https://github.com/objectstack-ai/objectstack/pull/23412",
"session": "session_01287UbjvrigpWwNfGDmdwpS",
"premise_still_valid": true,
"premise": "The gate returned on anything but sys_position_permission_set, which stage 8 unregistered; nothing else called it (grep on main e4ec6ec1a5: only its own call site and three unit cases).",
"summary": "Deleted SecurityPlugin.assertAudienceAnchorBindingGate, its middleware call, its three unit cases and the two imports only it used. Restated ADR-0138 (:171 anchor dropped, item 4, item 5's re-read note, the :578 row), ADR-0094 (three lines a581c57eae left: the banner's 'stays in the tree', the unit-suite citation, the Implementation line), ADR-0126 (a path note on 'Three real mechanisms'), ADR-0131 (dated notes on the :59 Consumers line and the :993 code list) and ADR-0103 (the provenance note). Each was checked against a581c57eae first.",
"line_count": "8 files, +54/-142 (196 lines); Tier H by path (docs/adr); the body carries ## 维护者速读(草稿) with the seat-opinion part empty",
"changeset": ".changeset/23403-audience-anchor-binding-gate-retired.md: @objectstack/plugin-security patch, Clause-②: no; not an entry export; no behaviour change",
"findings_measured": {
"adr_0103": "On main, assertSystemRowWriteGate's map (SYSTEM_ROW_PROVENANCE) holds sys_position and sys_capability only. sys_sharing_rule is deliberately ungated: plugin-sharing's sharing-rule-provenance.ts stamps an edited row customized. The old note's three-object claim was inexact, and it is corrected.",
"anchor_tier_on_main": "describeAnchorForbiddenBits runs for everyone in confirmAudienceBindingSuggestion and readAcceptedEveryoneSets. No door binds a set to guest."
},
"gates": {
"anchor_sweeps": "check:adr-symbol-anchors 0, check:scripts-symbol-anchors 0, check:spec-docblock-symbol-anchors 0, check:adr-links 0",
"plugin_security": "suite 190/190 files, 3,889 passed (45 skipped); typecheck 0; eslint on the changed files 0",
"derived_sweep": "74 derived, 74 run, all exit 0; --ran reconciles 0 NOT-MEASURED, 0 UNRUN. check:dual-build-cjs-loads and check:i18n first exited 3 on an unbuilt tree, and exit 0 after a full build (75/75).",
"not_run": "dogfood and the CLI integration tier: not in this card's targeted list; the change removes an unreachable private method and edits ADR prose"
},
"pr_state": "Draft (relay-forced), not readied, queued or armed. Body line 1 'Fixes #23403', line 2 'Clause-②: no'. Assignee os-steve. main e4ec6ec1a5 at branch time, not re-merged (no conflict). To land after 7a (#23368).",
"out_of_scope_findings": [
"SecurityPlugin.assertSystemRowWriteGate is unreachable for the same reason (both its objects are unregistered since stage 8); left in place, for 8-post's residue or its own card.",
"Prose for 8-post's comment sweep: the declared-capability-context.ts docblock ('all three runtime consumers', the engine re-enforcement on insert) and examples/app-showcase/src/security/permission-sets.ts:360 still describe the deleted gate."
],
"mcp_calls": "0",
"api_writes": "2: pr_create via fleet-write (read-back identical, 5,875 bytes) and this comment. git push of the branch (fast-forward).",
"open_questions": [],
"deviations": []
}
#23412 rebased onto 7a: main 5656c5638a (which contains 7a, dac99c2277) is merged into the branch at bd13bf7808, with no conflict. On this base the projection and its suites are gone, so the ADR text citing 7a's deletions is true of the PR's own base.
Exits on bd13bf7808: check:adr-symbol-anchors 0 · check:scripts-symbol-anchors 0 · check:spec-docblock-symbol-anchors 0 · check:adr-links 0 · plugin-security typecheck 0 · plugin-security suite 0 (185/185 files, 3,773 passed).
#23412 patch: the ADR-0103 sentence now reads "Of the three objects named here, only sys_sharing_rule is still registered on main" (sys_email_template and sys_webhook also carry managed_by). New head 0f2d82aebd; main not merged.
Exits on 0f2d82aebd: check:adr-symbol-anchors 0 · check:adr-links 0. The PR body and its 维护者速读 make no claim about which objects carry the column, so both still describe the final diff.
#23412 comment-only round: the comments that still called the audience-anchor gate live are restated, at new head 64c2e41049 (main not merged). The changed sites are security-plugin.ts :6151, engine.ts :5518/:8859/:20842, dangling-reference-audit.ts :375 plus the same phrase in two test comments, validate-security-posture.ts :37, and the authz-conformance.matrix.ts position-active note (prose, which no test reads). The PR body's Verification and its 速读 line on ADR-0138's enforcement-map row are updated.
Exits on 64c2e41049: check:adr-symbol-anchors 0 · typecheck 0 for plugin-security, objectql, lint and dogfood · authz-conformance.test.ts 61/61.
the dev's report 6162484475 and the patch notes 6163018199 onward.
Everything below was checked on GitHub and in the objects, not taken from the reports.
Form:
a draft to main, off main;
line 1 Fixes #23403;
## 维护者速读(草稿) in the body, updated to the final head.
Scope:
14 files, +79 / −162;
governed by path (docs/adr/**), so Tier H: the maintainer approves it.
The change, read in the diff:
deletes SecurityPlugin.assertAudienceAnchorBindingGate, its call site, its three unit cases and the imports only it used. It is unreachable since S8, because it guarded only sys_position_permission_set. It is not an entry export: @objectstack/plugin-securitypatch.
restates ADR-0138 (the :171 anchor dropped; items 4 and 5; the :578 map row, whose guest tier goes to follow-up F4, a status and not a decision), ADR-0094, ADR-0126, ADR-0131 (:59, :993) and ADR-0103. Each line was checked against a581c57eae.
the comments across five packages that still called the gate live are restated (64c2e41049, comment and prose only, verified by the seat).
Contract review (opus): FAIL 6162991283 at bd13bf7808 (one false sentence in ADR-0103), then the delta review PASS 6163455371 at 0f2d82aebd.
The first record's finding B (the stale comments) is fixed in 64c2e41049. The seat verified that commit is comment-only, apart from one dogfood matrix note string.
Finding C is confirmed: 8-post removes the other three dead gates.
Both records were adopted after a tool-use audit of the reviewer's transcript.
Landing order: whichever of this PR and 8-post lands second merges main; they touch adjacent lines of security-plugin.ts.
Tier H kit, now:needs-user-decision goes on the PR, the final 维护者速读 is posted on the PR, and review is requested from os-zhuang and hotlong. Once an authorized approval is on record and the required contexts are green on the head, the seat clears the label, readies the PR and arms auto-merge.
Merged by the merge queue at 2026-10-14T08:45Z as be50633be13bca7ed0500e8c3f43ad3e48b6ea39, from head 64c2e410492c2d3037c4eabf8cf901ab71352e64. Fixes #23403 closed this card.
Tier H by path (docs/adr/** ×5: ADR-0094, 0103, 0126, 0131, 0138). The seat's ACCEPT is 6163620432. os-zhuang, a GOVERNED_APPROVERS account, approved at 2026-10-14T08:01Z, then readied it and armed auto-merge. It entered the queue at 2026-10-14T08:18Z. No seat readied, queued or armed it.
Squash verified. The squash's diff against its parent 04a314873c equals the head's diff against their merge-base 5656c5638a: the same 14 files, and every file's changed lines identical (+79 / −162).
Activity
objectstack-fleet commentedon Oct 14, 2026
Claim: PM loop round 1 · 2026-10-14T05:58Z · a sub-card of #22975 (the ADR-0131 epic chain), inside the epic-only scope (maintainer, 2026-10-13T12:24Z: 「你现在开始只处理和这个 epic 相关的卡片」)
Session:
session_01ADzJtzYTLUfgrRZHxkagkXAccount:
os-steve(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23403-adr-c3-restatementWorktree:
objectstack-issue-23403(in the cloud session's own checkout)Domain:
domain:engine(derived from in-flight #22975)Seat:
domain:engine#2(seat post #20966)File surface:
docs/adr/0138-*.md,docs/adr/0094-*.md,docs/adr/0126-*.md,docs/adr/0131-*.md,docs/adr/0103-*.md(governed: Tier H);packages/plugins/plugin-security/src/security-plugin.ts(the gate and its call site only),security-plugin.test.ts(its cases only), the anchor JSON it frees, one changesetContainer & model:
S,mode:cloud(session_01287UbjvrigpWwNfGDmdwpS, the #22975 build-ahead session),model: defaultClause-②: no
Responsibility:
n/a — not a defect cardThread-read: none
Serial constraints cleared: 7a (PR #23368) is in the queue, and this card lands after it; 8-post (#22975) keeps the gate, so the two do not overlap
objectstack-fleet commentedon Oct 14, 2026
os-dev-report
{ "issue": 23403, "status": "done", "branch": "claude/issue-23403-adr-c3-restatement", "head": "59761d4a71", "pr": "https://github.com/objectstack-ai/objectstack/pull/23412", "session": "session_01287UbjvrigpWwNfGDmdwpS", "premise_still_valid": true, "premise": "The gate returned on anything but sys_position_permission_set, which stage 8 unregistered; nothing else called it (grep on main e4ec6ec1a5: only its own call site and three unit cases).", "summary": "Deleted SecurityPlugin.assertAudienceAnchorBindingGate, its middleware call, its three unit cases and the two imports only it used. Restated ADR-0138 (:171 anchor dropped, item 4, item 5's re-read note, the :578 row), ADR-0094 (three lines a581c57eae left: the banner's 'stays in the tree', the unit-suite citation, the Implementation line), ADR-0126 (a path note on 'Three real mechanisms'), ADR-0131 (dated notes on the :59 Consumers line and the :993 code list) and ADR-0103 (the provenance note). Each was checked against a581c57eae first.", "line_count": "8 files, +54/-142 (196 lines); Tier H by path (docs/adr); the body carries ## 维护者速读(草稿) with the seat-opinion part empty", "changeset": ".changeset/23403-audience-anchor-binding-gate-retired.md: @objectstack/plugin-security patch, Clause-②: no; not an entry export; no behaviour change", "findings_measured": { "adr_0103": "On main, assertSystemRowWriteGate's map (SYSTEM_ROW_PROVENANCE) holds sys_position and sys_capability only. sys_sharing_rule is deliberately ungated: plugin-sharing's sharing-rule-provenance.ts stamps an edited row customized. The old note's three-object claim was inexact, and it is corrected.", "anchor_tier_on_main": "describeAnchorForbiddenBits runs for everyone in confirmAudienceBindingSuggestion and readAcceptedEveryoneSets. No door binds a set to guest." }, "gates": { "anchor_sweeps": "check:adr-symbol-anchors 0, check:scripts-symbol-anchors 0, check:spec-docblock-symbol-anchors 0, check:adr-links 0", "plugin_security": "suite 190/190 files, 3,889 passed (45 skipped); typecheck 0; eslint on the changed files 0", "derived_sweep": "74 derived, 74 run, all exit 0; --ran reconciles 0 NOT-MEASURED, 0 UNRUN. check:dual-build-cjs-loads and check:i18n first exited 3 on an unbuilt tree, and exit 0 after a full build (75/75).", "not_run": "dogfood and the CLI integration tier: not in this card's targeted list; the change removes an unreachable private method and edits ADR prose" }, "pr_state": "Draft (relay-forced), not readied, queued or armed. Body line 1 'Fixes #23403', line 2 'Clause-②: no'. Assignee os-steve. main e4ec6ec1a5 at branch time, not re-merged (no conflict). To land after 7a (#23368).", "out_of_scope_findings": [ "SecurityPlugin.assertSystemRowWriteGate is unreachable for the same reason (both its objects are unregistered since stage 8); left in place, for 8-post's residue or its own card.", "Prose for 8-post's comment sweep: the declared-capability-context.ts docblock ('all three runtime consumers', the engine re-enforcement on insert) and examples/app-showcase/src/security/permission-sets.ts:360 still describe the deleted gate." ], "mcp_calls": "0", "api_writes": "2: pr_create via fleet-write (read-back identical, 5,875 bytes) and this comment. git push of the branch (fast-forward).", "open_questions": [], "deviations": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
#23412 rebased onto 7a: main
5656c5638a(which contains 7a,dac99c2277) is merged into the branch atbd13bf7808, with no conflict. On this base the projection and its suites are gone, so the ADR text citing 7a's deletions is true of the PR's own base.Exits on
bd13bf7808: check:adr-symbol-anchors 0 · check:scripts-symbol-anchors 0 · check:spec-docblock-symbol-anchors 0 · check:adr-links 0 · plugin-security typecheck 0 · plugin-security suite 0 (185/185 files, 3,773 passed).Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
#23412 patch: the ADR-0103 sentence now reads "Of the three objects named here, only
sys_sharing_ruleis still registered onmain" (sys_email_templateandsys_webhookalso carrymanaged_by). New head0f2d82aebd; main not merged.Exits on
0f2d82aebd: check:adr-symbol-anchors 0 · check:adr-links 0. The PR body and its 维护者速读 make no claim about which objects carry the column, so both still describe the final diff.Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
#23412 comment-only round: the comments that still called the audience-anchor gate live are restated, at new head
64c2e41049(main not merged). The changed sites are security-plugin.ts :6151, engine.ts :5518/:8859/:20842, dangling-reference-audit.ts :375 plus the same phrase in two test comments, validate-security-posture.ts :37, and the authz-conformance.matrix.tsposition-activenote (prose, which no test reads). The PR body's Verification and its 速读 line on ADR-0138's enforcement-map row are updated.Exits on
64c2e41049: check:adr-symbol-anchors 0 · typecheck 0 for plugin-security, objectql, lint and dogfood · authz-conformance.test.ts 61/61.Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
✅ ACCEPT (Tier H, by path): PR #23412 at
64c2e41049·domain:engineseat 2 ·session_01ADzJtzYTLUfgrRZHxkagkX· 2026-10-14T07:52ZBasis:
Everything below was checked on GitHub and in the objects, not taken from the reports.
main, offmain;Fixes #23403;## 维护者速读(草稿)in the body, updated to the final head.docs/adr/**), so Tier H: the maintainer approves it.SecurityPlugin.assertAudienceAnchorBindingGate, its call site, its three unit cases and the imports only it used. It is unreachable since S8, because it guarded onlysys_position_permission_set. It is not an entry export:@objectstack/plugin-securitypatch.a581c57eae.64c2e41049, comment and prose only, verified by the seat).bd13bf7808(one false sentence in ADR-0103), then the delta review PASS 6163455371 at0f2d82aebd.64c2e41049. The seat verified that commit is comment-only, apart from one dogfood matrixnotestring.main; they touch adjacent lines ofsecurity-plugin.ts.Tier H kit, now:
needs-user-decisiongoes on the PR, the final 维护者速读 is posted on the PR, and review is requested fromos-zhuangandhotlong. Once an authorized approval is on record and the required contexts are green on the head, the seat clears the label, readies the PR and arms auto-merge.objectstack-fleet commentedon Oct 14, 2026
Landing record: PR #23412 →
be50633be1·domain:engineseat 2 ·session_01ADzJtzYTLUfgrRZHxkagkX· 2026-10-14T08:46Zbe50633be13bca7ed0500e8c3f43ad3e48b6ea39, from head64c2e410492c2d3037c4eabf8cf901ab71352e64.Fixes #23403closed this card.docs/adr/**×5: ADR-0094, 0103, 0126, 0131, 0138). The seat's ACCEPT is 6163620432.os-zhuang, aGOVERNED_APPROVERSaccount, approved at 2026-10-14T08:01Z, then readied it and armed auto-merge. It entered the queue at 2026-10-14T08:18Z. No seat readied, queued or armed it.04a314873cequals the head's diff against their merge-base5656c5638a: the same 14 files, and every file's changed lines identical (+79 / −162).SecurityPlugin.assertAudienceAnchorBindingGate, dead since S8, is removed with its call site and itssecurity-plugin.test.tscases. The ADR rows that named it or the projector are corrected. C3 #15204 stages 7a ∥ 7b → 8-post, build ahead: delete the permission-set projection and the position write-through that stage 8 leaves unreferenced, then the post-stage-8 catalog gates and residue #22975's 8-post (PR refactor(plugin-security): remove the retired catalog objects' write gates and the walled data door; report positions naming an unresolved set (C3 stage 8-post) #23428) keeps the gate out of its own diff, so the two do not overlap.pm:dispatchedis removed in the same act.Generated by Claude Code