Skip to content

docs(approvals): drop reserved word "role" from lifecycle copy (ADR-0090 D3) - #3132

Closed
os-zhuang wants to merge 1 commit into
mainfrom
fix/role-word-approvals
Closed

docs(approvals): drop reserved word "role" from lifecycle copy (ADR-0090 D3)#3132
os-zhuang wants to merge 1 commit into
mainfrom
fix/role-word-approvals

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes the red Lint & Type Check on main. Docs-only — hence skip-changeset.

What broke

#3113 (25a19be72) added the approval-lifecycle walkthrough, including 4 new occurrences of the reserved word "role" in content/docs/automation/approvals.mdx (5 → 9), without updating scripts/role-word-baseline.json. pnpm check:role-word has failed on every push to main since — the last 4 runs of lint.yml are red — so every open PR inherits a failing ESLint check and real failures are masked.

Why not bump the baseline

Per ADR-0090 D3 the word is reserved-forbidden and new occurrences are banned; --update exists to ratchet the baseline down when a file improves. So the baseline stays at 5 and the copy is reworded.

The fix

Three of the four were a duplicate. The new callout under The request opens, the run pauses restated the already-baselined position vs role callout ~80 lines above it on the same page — which says the same thing in more detail (it names the os lint rule). Removed in favour of a cross-reference.

While rewording I also tightened the claim to match expandApprovers(): an unresolvable approver entry does not leave pending_approvers empty — it falls back to a literal <type>:<value> slot that no user matches, which is why the request stalls.

The fourth documented approverId accepting role:<r>. That literal is real, but it is one of several (team: / department: / position: / role: / manager:), so naming only the role: form was both off-vocabulary and needlessly narrow. Generalized to <type>:<value> with a position:finance_manager example, matching the page’s existing finance_manager sample.

The surviving 5 are the documented D3 exception — the better-auth boundary (sys_member.role), which the role approver type genuinely resolves against via expandRoleUsers(). Left untouched.

Verification

  • pnpm check:role-word → exit 0, approvals.mdx back to 5, role-word-baseline.jsonunmodified.
  • pnpm lint, check:doc-authoring, check:authz-resolver, check:release-notes → all pass.
    (Local eslint OOMs at the default heap on node 25 — an environment artifact, not this change; it is clean under --max-old-space-size=8192, and CI runs node 20.)
  • Rendered the page in the docs site: the <Steps> block keeps all 4 step headings after the callout removal, the reworded approverId sentence renders (<type>:<value> survives MDX as inline code), and the new #3-the-approval-node cross-reference resolves to the right heading — no console or server errors. Worth checking by hand since no CI job validates anchors.

🤖 Generated with Claude Code

…090 D3)
#3113 added the approval-lifecycle walkthrough with 4 new occurrences of the
reserved word "role", taking approvals.mdx from 5 → 9 and turning check:role-word
red. Lint & Type Check has failed on every push to main since, so every open PR
inherits a failing ESLint check.
ADR-0090 D3 bans NEW occurrences — the --update path is for ratcheting the
baseline DOWN — so the baseline stays at 5 and the copy is reworded instead.
Three of the four were a duplicate: the new callout under "The request opens"
restated the baselined `position` vs `role` callout ~80 lines above it, which
already says the same thing in more detail (it names the os lint rule). Replaced
with a cross-reference to it. The claim is also tightened to match
expandApprovers(): an unresolvable entry does not leave `pending_approvers`
empty, it falls back to a literal `<type>:<value>` slot that no user matches.
The fourth documented `approverId` accepting `role:<r>`. That literal is real,
but it is one of several (`team:` / `department:` / `position:` / `role:` /
`manager:` per approval-service.ts), so naming only the `role:` form was both
off-vocabulary and needlessly narrow. Generalized to `<type>:<value>` with a
`position:finance_manager` example, matching the page's existing finance_manager
sample.
The surviving 5 are the documented D3 exception — the better-auth boundary
(`sys_member.role`), which the `role` approver type genuinely resolves against
via expandRoleUsers().
Verified: check:role-word exits 0 at 5 occurrences with the baseline untouched;
eslint, check:doc-authoring, check:authz-resolver and check:release-notes pass;
page rendered in the docs site — Steps block intact and the #3-the-approval-node
cross-reference resolves.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@os-zhuangos-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Jul 17, 2026
@vercel

vercelBot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specBuildingBuildingPreview, CommentJul 17, 2026 12:13pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation size/s labels Jul 17, 2026
@os-zhuang

Copy link
Copy Markdown
ContributorAuthor

Closing as a duplicate of #3122, which fixes the same file for the same reason, was opened ~10 min earlier, and is already fully green.

I missed #3122 before opening this — my mistake. #3122 is also the better fix on the 4th occurrence:

  • Both PRs delete the duplicate type: 'role' is not a position callout (−3), which restates the callout ~75 lines above it.
  • For the 4th, I rewrote approverId accepting role:<r>position:finance_manager. That was wrong. Per contracts/approval-service.ts the identities are literally "their user id, email, and role:<r> entries"role:<r> is one of a person's own identities (their better-auth membership tier) and a genuine ADR-0090 D3 exception. A position: literal is not an identity at all; it only appears as a fallback when position expansion matches nobody. So my version contradicted the sentence's own "cover a person's identities in one call" clause.
  • docs(approvals): drop duplicate role-vs-position callout (unbreak role-word ratchet) #3122 instead trims the surviving callout's duplicated mention of the role approver type (−1) — removing real redundancy without laundering a real boundary literal.

No action needed here; #3122 covers it.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@os-zhuang