Skip to content

docs(adr): ADR-0090 D5 offending bits are platform system permissions, not any systemPermissions - #17814

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-17189-adr-0090-d5-revision
Sep 13, 2026
Merged

docs(adr): ADR-0090 D5 offending bits are platform system permissions, not any systemPermissions#17814
os-zhuang merged 1 commit into
mainfrom
claude/issue-17189-adr-0090-d5-revision

Conversation

@os-bill

@os-bill os-bill commented Sep 12, 2026

Copy link
Copy Markdown
Collaborator

Part of #17189 — the protocol half of phase ①. ⛔ This PR does not discharge the card, and ⛔ carries no closing keyword: #17189 still owes step ②.

Sibling: #17811 carries the packages/spec predicate, its test, the changeset and the two regenerated surface snapshots. The two were one PR until the seat review of head a21ad008; they are split here on the ruling's own instruction.

Why this is its own PR

The ruling (#17189 comment 5615806616, director seat, batch #110) says it twice, verbatim:

ADR-0090 D5 的 offending 清单相应收窄为「平台系统权限;带 package provenance 的应用声明 capability 令牌不计」,ADR 修订走独立受管 PR(draft、请审、人合)

Clause-②: yes(放宽接受集);ADR-0090 修订单独受管 PR

The triage seat had already ruled the same shape: 「那部分必须是独立的受管 PR,⛔ 不得与代码同 diff」.

Measured consequence, not style. scripts/pm/check-governed-merges.mjs --test on this PR's one-file list exits 3 = GOVERNED; on the sibling's five-file list it exits 0 = NOT governed. Bundled, one governed path made the predicate change human-merge-only too. Split, this half waits for its human and the code half takes ordinary landing.

Why the revision is required

Both halves are phase ①, per the ordering note (#17189 comment 5617614086) carrying the maintainer verbatim:

「我们的项目以objectstack 协议为准,文档应该以实际实现为准。协议不正确的应该先修改协议。」

D5's last bullet said any systemPermissions was an offending bit, and describeHighPrivilegeBits implemented that literally — so the protocol, not the implementation, was the half that was wrong. A predicate change without this revision would leave the ADR describing a rule the code no longer applies.

⚠️ Merge order. The maintainer's sentence puts the protocol first. This PR is human-merge-only and the sibling is not, so nothing mechanical keeps the code from landing first; if that order matters to you, merge this one before #17811 is enqueued. Flagging rather than deciding — a draft PR cannot enforce it.

What changed

D5's last bullet now reads "a systemPermissions entry naming a platform system permission", and names an app-declared capability token — one a package declared for itself under ADR-0066 D1, entering sys_capability with managed_by: 'package' + package_id provenance — as not an offending bit.

A dated revision note records:

  • the two unlike token kinds in one list, and the cost that motivated the narrowing (a named downstream consumer binding its baseline set to seven positions by hand, plus one manual grant per new hire);
  • three boundaries, each failing closed — the platform floor is absolute (a platform capability name stays high-privilege however it is declared, so manage_users cannot be laundered by declaring it); the discriminator is provenance, never spelling (⛔ the dotted-name rule was considered and rejected: setup.access is a dotted platform capability today); omission refuses (a caller that cannot enumerate the declarations gets the pre-revision verdict);
  • that the D9 guest tier is untouched — D5 speaks for authenticated members;
  • the ruling's provenance and the landing order, quoted verbatim in the original Chinese;
  • that the consuming callers keep the pre-revision behaviour until they supply the declared list.

The revision text is byte-identical to what stood on a21ad008 before the split — verified by diffing this branch's file against that branch's. Removing the code hunks made no sentence of it false: nothing in the note claims the predicate ships in this PR.

Clause ②

Recorded, not re-declared here: the card's declaration is Clause-②: yes(放宽接受集)per the ruling's 执行 line, and the needs:contract-review carrier is already hung by the seat on card #17189 and on the code PR #17811. This half is prose only — it puts no key on any published payload and moves no accept set by itself. Whether the carrier is also owed on this PR is the seat's call; ⛔ this round writes no labels.

Verification

  • Content: unchanged from the reviewed head, byte-for-byte (see above). The engineering behind it was accepted in the seat review of a21ad008 and is ⛔ not re-litigated here.
  • check-governed-merges.mjs --test docs/adr/0090-permission-model-v2-concept-convergence.md → exit 3 (GOVERNED). Control, the sibling's five-file list → exit 0 (NOT governed), so the 3 is a verdict about this file rather than an instrument that only ever says 3.
  • ADR gate family on this branch: check-adr-links, check-adr-symbol-anchors, check:adr-anchors, check-adr-0087-registration --base origin/main, check:nul-bytes, check:pm-governed-prose, check:doc-authoring — exit codes captured before any pipe, reported in the round's report.
  • No changeset: docs/adr/** is in no package's files[], and a phrase unique to this revision note occurs in 0 built files under packages/spec/dist — the negative control measured in the sibling PR's changeset decision.

⚠️ Governed surfacedocs/adr/**. Draft only, and it stays draft: ⛔ not flipped ready, ⛔ not enqueued, ⛔ no auto-merge, ⛔ no approving review. A human merge is the review record.


Generated by Claude Code

…, not any systemPermissions

D5's last bullet made any non-empty `systemPermissions` an offending bit for an
`everyone` anchor binding, and the shared predicate implemented it literally.
That list conflates two unlike tokens: the platform's own powers, and a
capability a package declared for itself under ADR-0066 D1.

The bullet is narrowed to a `systemPermissions` entry naming a PLATFORM system
permission, with a dated revision note recording the two token kinds, the three
fail-closed boundaries (the absolute platform floor, provenance rather than
spelling, and omission refusing), that the D9 `guest` tier is untouched, and
that the consuming callers keep the pre-revision behaviour until they supply the
declared list.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH

Copy link
Copy Markdown
Collaborator

skip-changeset applied by the PM seat — audit note.

Acting on a maintainer instruction given in live PM chat, 2026-09-13, verbatim: 「红的你要帮我解决啊」 (a direct instruction to clear the red CI on the stale open PRs, this one among them).

Why this label and not a changeset. Check Changeset (job 103520053663, head a8dfc166) exited 1 with its own prescription:

This PR adds no changeset. If it releases nothing (including any 'skills/**' change -- see #5947), apply the 'skip-changeset' label; otherwise run 'pnpm changeset' and name the packages.

Measured rather than assumed: this PR's file list is exactly one path — docs/adr/0090-permission-model-v2-concept-convergence.md. docs/adr/** is in no package's files[], so the diff releases nothing. That is the same reading the sibling PR #17811 took for its own changeset decision, where a phrase unique to this revision note measured 0 occurrences across packages/spec/dist.

⇒ route 1 (skip-changeset) is correct here and route 2 (a changeset) would be wrong — it would name a package this diff does not ship.

Scope of this write. The label set was read, the single addition applied, and the union read back. documentation and size/s are untouched; assignees was empty before and after. ⛔ No other label was written — in particular this seat did not hang needs:contract-review, which the PR body correctly leaves to the owning seat's call.

⛔ Nothing else on this PR moved: still draft, not enqueued, no auto-merge, no approving review. docs/adr/** is governed surface and a human merge remains the review record. The merge-order note in the PR body still stands — this half lands before #17811 is enqueued.

⚠️ If Check Changeset does not re-run on the labeled event, it needs a re-run (or the next push) to turn green; the label alone does not retroactively repaint the old run.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 13, 2026 14:45
@os-zhuang
os-zhuang requested a review from hotlong as a code owner September 13, 2026 14:45
@os-zhuang
os-zhuang enabled auto-merge September 13, 2026 14:46
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 13, 2026
Merged via the queue into main with commit ff1e771 Sep 13, 2026
39 of 40 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-17189-adr-0090-d5-revision branch September 13, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants