Skip to content

docs(adr): ADR-0055's Lint bullet gains a dated note stating the narrowed ownerMayEdit lint arm - #26862

Merged
os-zhuang merged 1 commit into
mainfrom
claude/project-thread-gq6be9
Oct 27, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/project-thread-gq6be9

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread

Fixes #26686

Clause-②: no
Metadata-protocol: none

维护者速读

What changes

One file, two inserted lines, nothing rewritten (ADRs are append-only, Prime Directive 13; the card's "reword that one bullet" yields to it, as the triage audit line and the retriage answer on #26686 say):

No gate, spec, lint or other ADR text changes. No changeset: docs/adr/** publishes nothing (skip-changeset sent with the create).

Tests

None owed: a docs-only diff under docs/adr/, no package touched, no tested behaviour changed, so no ablation.

Acceptance notes

  • Acceptance read against bullet + note together: the pair no longer tells a reader that every caller-keyed policy gets the opt-in; owner_id is named as the one column the opt-in admits; check:adr-anchors is green at the head and ADR-0055 declares the same machine-readable decision-letter count at base and head (0 headings, 0 bold leads, 0 table cells on both origin/main 8eef9a8 and the head, by the four grammars check-adr-anchors.mjs reads).
  • Premise re-verified on origin/main 8eef9a8 (the delta's 0ea90c7 has moved on): the Lint bullet is unchanged at line 176, and no open PR names docs/adr/0055*.
  • Symbol anchors in the note are the path#symbol form check:adr-symbol-anchors resolves (pushCbpOwnerPolicyWithoutOptIn, pushCbpCallerPolicyOffOwnerColumn, SECURITY_CBP_OWNER_POLICY_WITHOUT_OPT_IN_EXPLANATION all exist on origin/main).
  • docs/adr/README.md is generated and did not need regenerating: its status column truncates ADR-0055's value before the new entry (check:adr-index --report reads it current).
  • Forced test edits: none.

Verification

Local, in the worktree at head a7fbcca4 (the only commit), after it:

  • Build closure (so the lint-owned gate below could load @objectstack/lint / @objectstack/formula): pnpm turbo run build --filter='@objectstack/lint...' --concurrency=2 under scripts/pm/os-verify-lock.sh: VERDICT command-exit 0 · held the lock 102s.
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (change set derived from git, 1 path vs merge base 8eef9a8d) listed 21 commands; every one ran serially with stdin closed and recorded exit 0: check-adr-links (+ --self-test), check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, ci/plan-test-core-shards --self-test, @objectstack/lint check:doc-formula-expressions, check:adr-anchors, check:adr-index, check:adr-symbol-anchors, check:ci-filter-parity, check:closed-ceremony-text, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:gitlink-declared, check:nul-bytes, check:pm-governed-merges, check:pm-prior-rulings, check:refd-timer-probe, check:watch-hint-literal.
  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.txt: ✓ dispatch-gates --ran: 21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED (a DERIVED zero — all 21 recorded an exit code and none of them is 3).
  • dispatch-gates --tier: MANDATORY docs/adr/** (clause ①, no one-line exit); changed lines 2 (+2 / -0), under the 3000 human-merge threshold.
  • check:adr-symbol-anchors: 2690 anchors across 144 records resolve, the three new path#symbol anchors among them.
  • Every CI family is the PR's own check-runs, read there, not re-run locally.

Generated by Claude Code

…owed opt-in arm

The 2026-10-26 amendment's Lint bullet still says every caller-keyed
update policy on a controlled_by_parent detail is flagged with the
ownerMayEdit opt-in as the fix. Since the lint narrowing landed, the arm
prescribes the opt-in only for an owner_id-keyed policy on a detail that
carries owner_id and has not opted in; every other caller-keyed update
policy is flagged in both states with the owner_id remedy. ADRs are
append-only, so the bullet is kept and a dated note under it states the
arm as main has it, with a matching entry on the Status line.

Claude-Session: https://claude.ai/code/session_01ADHkmPxbS3CePBs6PrwdLc
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 27, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 27, 2026
@github-actions github-actions Bot added size/xs documentation Improvements or additions to documentation labels Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:skills#1 · session_01ADHkmSrRBdu9MdC6fc33Uu · head a7fbcca4 · 2026-10-27T19:00Z

  1. 形态 — Tier H (docs/adr/**): docs/adr/0055-master-detail-controlled-by-parent.md +2/−0 — a dated ⚠️ amendment note directly under the 2026-10-26 amendment's Lint bullet (the file's own in-place form) and the matching Amended entry on the Status line. The bullet's text is untouched (Prime Directive 13). No gate, spec or lint change; no changeset.
  2. 前提实测 — on origin/main: ADR-0055:176 still prescribes the opt-in for every caller-keyed update / all policy; packages/lint/src/validate-security-posture.ts:24 and :500–533 prescribe it only for an owner_id-keyed policy on a detail that carries owner_id and has not opted in, and give every other caller-keyed policy the owner_id remedy (controlledByParent.ownerMayEdit admits only owner_id, but its lint arm prescribes it for any FIELD == current_user.id policy — an app whose accountable person is its own user field stays refused #26591 / PR fix(lint): the controlledByParent owner arm prescribes ownerMayEdit only for an owner_id-keyed policy #26658). The note states that arm and names the open widening question as the maintainer's.
  3. 门禁 check-runs — dev ran the 21 derived commands, all exit 0 (--ran 21/21, 0 NOT-MEASURED, 0 UNRUN); decision-letter count 0 at base and head. CI on the head is read again before landing.
  4. 接受的偏差 — none.
  5. 范围外去向 — none. Contract review at CONTRACT_REVIEW_TIER, effort ≥ xhigh (retriage 6446775539): requested from the director seat.
  6. 落地条款 — governed, Tier H: stays draft until a GOVERNED_APPROVERS approval; then it lands through the queue.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: a7fbcca44378a44c9d15c371a7b302d0fd917061
Local-runs: none
Scope: docs/adr/0055-master-detail-controlled-by-parent.md + packages/lint/src/validate-security-posture.ts, packages/lint/src/rule-explanations.ts, packages/plugins/plugin-security/src/security-plugin-cbp-relation.ts

Director seat (summon #52, ledger objectstack#12708), summoned by the domain:skills#1 seat; effort ≥ xhigh per retriage 6446775539. Read-only at the head above: the diff, card #26686 and its thread (triage audit line 6442600042, retriage answer 6446775539, claim 6450657117, dev report 6450953048), the seat's ACCEPT 6450986862, #26591 and PR #26658 (merged 2026-10-27 12:46Z), ADR-0055 and the lint on origin/main 0ea90c7a, the head's check runs. docs/adr/** is a governed-register row ⇒ the rules face, CONTRACT_REVIEW_TIER; Tier H, lands by the maintainer's hand, not on this record. Served at CONTRACT_REVIEW_TIER. The seat records; it does not approve, ready, queue or merge.

① Derived judgments

  • The note states the arm main carries, symbol for symbol. validate-security-posture.ts:956–958: admittable = detail.ownerColumn && fields.includes(CBP_OWNER_COLUMN); an admittable policy that has opted in is skipped, an admittable one that has not goes to pushCbpOwnerPolicyWithoutOptIn (:503, the opt-in prescribed), and every other caller-keyed policy goes to pushCbpCallerPolicyOffOwnerColumn (:538, severity: 'warning', the verdict naming what the opt-in "admits only", the hint keyed on whether the detail carries the column). carriesCbpOwnerColumn (:490) is the column test. The gate side the note cites — CbpRelation.ownerMayEdit resolving false without the column — is security-plugin-cbp-relation.ts:173 (optedIn && hasOwnerColumn), and the os explain constant SECURITY_CBP_OWNER_POLICY_WITHOUT_OPT_IN_EXPLANATION is rule-explanations.ts:699. Same rule id, same tier; nothing in the note is invented.
  • Append-only, in the file's own two forms. The in-place note is the ⚠️ **Amended YYYY-MM-DD (#N) — …** shape this file already uses at L63, L78, L80, L82, L126 and L130; the Status line gains the paired · **Amended** (date, refs) — … entry every in-place note in this file has. +2 / −0; the 2026-10-26 Lint bullet is byte-identical. The card's "reword that one bullet" rightly yields to Prime Directive [WIP] Add Chinese version of the documentation #13, as the audit line and the retriage answer said.
  • It marks the old sentence without pretending it was never true. "The sentence above is kept as the arm as first landed; ⛔ it is no longer a statement of what the lint prescribes" — the reading a future agent needs, placed where the agent reads (the card's business case: hotclm's owner-field opt-in that silenced the lint and kept the 403).
  • It decides nothing it was not given. The widening of the runtime leg to a named owner field is named as the maintainer's open question on controlledByParent.ownerMayEdit admits only owner_id, but its lint arm prescribes it for any FIELD == current_user.id policy — an app whose accountable person is its own user field stays refused #26591 and left there; the gate, the spec and the lint are stated unchanged, which is true at main.

② Semver level

skip-changeset: docs/adr/** publishes nothing. Correct.

③ Boundary flags

  • Governed path (docs/adr/**, Tier H): draft, no review yet, requested_reviewers hotlong / os-zhuang. This seat's account is not a GOVERNED_APPROVERS member; this record is not an approval.
  • Check runs on a7fbcca4 at this record: 14 success, 23 expected skips (docs-only), 8 still in_progress — among them Lint · docs & code guards (home of check:adr-symbol-anchors, which must resolve the note's three path#symbol anchors) and Lint · repo & tooling gates (check:adr-index). Nothing red; a red there re-opens this record. The dev reports both green locally (2690 anchors across 144 records).
  • docs/adr/README.md not regenerated: the index's status column is truncated before the new Status entry, so the row is unchanged — check:adr-index on the head is the proof, read when it lands.
  • If the maintainer later widens the runtime leg (controlledByParent.ownerMayEdit admits only owner_id, but its lint arm prescribes it for any FIELD == current_user.id policy — an app whose accountable person is its own user field stays refused #26591's card), this bullet changes again with that PR, as the card itself says; nothing here pre-empts it.
  • Dev deviations: none. Scope matches the claim (one file, one note, the paired Status entry the claim allowed "only if the file's own convention has one" — it does).

④ Design judgment

  • The note is the narrowest edit that makes the ADR stop misleading: it keeps the landed sentence, states the live predicate with the symbols that implement it, names the remedy the lint now gives, and marks the one open question as open. For a record whose Lint bullet an agent reads before os lint, that is the right shape. Holds; nothing to break.

Implemented-by: claude/project-thread-gq6be9
Reviewed-by: session_01ADHkmQr732toX135tyo5zs

VERDICT: PASS


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 27, 2026 22:54
@os-zhuang
os-zhuang enabled auto-merge October 27, 2026 22:54
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit eac28c3 Oct 27, 2026
49 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-gq6be9 branch October 27, 2026 23:44
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/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants