Skip to content

docs(comments): date the #3290 session.tenantId removal to v16, not v11 - #9990

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-9872-v11-v16-provenance
Aug 19, 2026
Merged

docs(comments): date the #3290 session.tenantId removal to v16, not v11#9990
os-steve merged 1 commit into
mainfrom
claude/issue-9872-v11-v16-provenance

Conversation

@os-steve

@os-steveos-steve commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Part of #9872 — deliberately not a closing keyword: this lands the comment-only half. A
residue of 6 sites is out of scope under the card's rulings and needs PM triage, so merging
this must not close the card.

The true version, established from the record before any comment was edited

The card asserted v16 on three legs. I verified all three, falsified one of them, and
replaced it with two stronger ones.

LegVerdictEvidence
Only v16.mdx mentions #3290✅ holdscontent/docs/releases/v16.mdx:125,132,1046 — the only release page with a #3290 hit
Its Upgrade checklist → 16.0.0 lists the rename✅ holdsv16.mdx:977 → "rename ctx.session.tenantId / ctx.user.tenantIdorganizationId in every *.hook.ts / *.action.ts body"
"There is no v11.mdx, so v11 names a major that does not exist"falsifiedv11 is a real major: CHANGELOG.md## [11.0.0] — 2026-06-27, plus docs/upgrading-to-11.md and @objectstack/*@11.0.0 in the example changelogs. The page is absent by policy, not because the major is: scripts/check-release-notes.mjs carries const KNOWN_MISSING = new Set([10, 11]); — "Curated release pages started at v9; v10/v11 were never backfilled"

Absence of v11.mdx therefore proves nothing. Two replacement legs that do:

  1. The changelog record. In packages/spec, packages/runtime and packages/objectql
    alike, the entry 6c270a6: **BREAKING: remove the deprecated `ctx.session.tenantId` / `ctx.user.tenantId` alias… sits under ## 16.0.0 (and first under ## 16.0.0-rc.0).
  2. The v11 guide's silence.docs/upgrading-to-11.md is the complete 10.x → 11.x
    breaking-change guide — "This guide lists every breaking change from 10.x → 11.x" —
    and contains no tenantId, no Unify the developer-facing org identifier: hooks expose session.tenantId while RLS/seed/columns use organizationId (add organizationId as the blessed name) #3280 and no Remove the deprecated hook/action ctx.session.tenantId alias in the next major (converge on organizationId) #3290.

skills/objectstack-data/references/data-hooks.md:627 (governed; read, not edited) is the one
site that already said v16, and it corroborates.

Why "v11" got written ~10 times — a single origin, and a cause worth recording

git log -S puts the origin at 6c270a607cthe removal PR itself
(feat(hooks)!: remove deprecated ctx.session.tenantId alias … (#3290) (#3305), 2026-07-20).
It introduced "v11" 15 times in one diff. Every later site is a copy.

The cause is not carelessness, and it is still live:

the repo's root CHANGELOG.mdstill tops out at ## [11.10.0] — 2026-07-03.

It was never maintained past the 11 line while the packages moved on. At 6c270a607c,
packages/spec/package.json read 15.1.1 — but an author sanity-checking "what major are we
on" against the repo's own root changelog reads 11. That is the whole defect, once.

Hence the repair shape: the durable anchor is the issue number, not the major. Every edited
site already cites #3290 next to the version, so the version is now redundant corroboration
rather than the load-bearing claim, and the single most-copied teaching site — the gate header
that the card notes "teaches the migration" — now names the checkable page:

-// hook/action `ctx.session` surface entirely (v11 major), so any session-borne+// hook/action `ctx.session` surface entirely (the v16 major — see+// `content/docs/releases/v16.mdx`), so any session-borne

Population: 26 wrong sites found, 20 fixed here

Re-derived from scratch (every v11 / 11.0.0 token and every #3290 token in the tree), not
taken from the card's "~10".

Fixed — 20 sites / 17 files, all pure comment text:packages/objectql/src/{engine.ts, plugin.ts,engine.test.ts} · packages/runtime/src/{action-execution.ts,http-dispatcher.test.ts, action-session-shape-contract.test.ts,domains/actions.ts} · packages/spec/src/{data/hook.zod.ts, data/hook.test.ts ×2,ui/action-params.zod.ts ×3 (JSDoc only),contracts/sharing-service.ts} ·
packages/plugins/plugin-audit/src/{audit-writers.ts,audit-writers.test.ts} ·
packages/triggers/trigger-record-change/src/record-change-trigger.ts ·
scripts/check-org-identifier.mjs · .github/workflows/lint.yml (YAML comment) ·
content/docs/kernel/runtime-services/sharing-service.mdx (comment inside a sample).

Found wrong but deliberately NOT fixed — 6 sites, PM triage:

SiteWhy untouched
skills/objectstack-ui/SKILL.md:1934skills/** is a governed surface; a mixed diff forks the whole PR
packages/spec/src/ui/action-params.zod.ts:376,409inside .describe() — runtime spec surface, regenerates the auto-generated content/docs/references/ui/action-params.mdx:58,59, and would owe a changeset (ruling 6)
packages/spec/src/migrations/registry.ts:1555 + entries/semantic/17.action-session-roles-to-positions.ts:23migration rationale — runtime data that regenerates spec-changes.json and docs/protocol-upgrade-guide.md:317
packages/plugins/plugin-audit/src/audit-writers.test.ts:1653a test title string, not comment text
scripts/check-org-identifier.mjs:596,600,602,640the gate's own self-test fixture corpus — ruling 4 says stop and report, not edit

Also reported, not touched: .changeset/{org-identifier-session-provenance, audit-tenant-fallback-reads-organization-id}.md (inside the #9465 fence) and the historical
packages/{spec,runtime}/CHANGELOG.md entries (published records).

Correct v11 citations — verified and deliberately left alone:
content/docs/kernel/contracts/metadata-service.mdx:311 (IUIService removed in v11) and
docs/audits/2026-07-security-props-liveness-recheck.md:26 (PolicySchema removed in v11.0) —
both appear as their own items in docs/upgrading-to-11.md (lines 91 and 128). objectui#3290
(packages/spec/src/ui/widget.zod.ts:123, content/docs/protocol/objectui/widget-contract.mdx:145)
is a different repo's issue about the widget required state and is not in the population.

Wider sweep — clean

Swept for a habit rather than one wrong digit: every release-version citation near #3290 and the
rename, plus the co-cited ids. #3280 is exactly what the comments claim it is ("add
organizationId as the blessed name", session.tenantId deprecated). ADR-0087/0090/0095/0099/0104
all resolve, and ADR-0090 D3 really is the "role becomes a reserved-forbidden word" decision.
v11 was the only wrong provenance found.

Nothing mechanical checks a version citation in a comment. check-release-notes.mjs verifies the
inverse — that every released major has a curated page — and reads nothing in source. That is why
this survived 20 times. Not carded here (a new gate is outside this card); flagged for PM judgement.

Verification — d9e01627ab

Comment-only diff, so the local set was deliberately narrowed and is declared as such; CI runs
the full farm. Gate set re-derived mechanically with node scripts/pm/dispatch-gates.mjs (no paths
passed) on the committed head — 17 paths, 35 matched families.

✓ check-org-identifier self-test: 31 cases pass.
check-org-identifier: OK (2060 author-facing source file(s), 13 session binding(s) resolved,
no removed session.tenantId alias).
check-nul-bytes: OK (scanned 6322 text file(s) ... no raw ASCII control bytes).
✅ check-doc-anchors: 251 internal #fragment link(s) across 398 source file(s) all resolve
check-role-word: OK, no new occurrences of the reserved word.

typecheck green on all five touched packages (5 scripts echoed — not a zero-match silent pass).
Touched test files, all green: hook.test.ts + action-params.test.ts 102 · engine.test.ts 135 ·
http-dispatcher.test.ts + action-session-shape-contract.test.ts 257 · audit-writers.test.ts 67
561 tests.

No changeset: this publishes nothing. Takes the skip-changeset label (route 2 in
scripts/check-empty-changeset.mjs), never an empty-frontmatter changeset.

⛔ Draft on purpose. Do not arm auto-merge; the maintainer arms after review.

Generated by Claude Code

The removal of the deprecated `ctx.session.tenantId` alias shipped in
16.0.0, but 20 comment sites across the tree dated it to "v11". All of
them trace to a single origin: commit 6c270a6, the removal PR itself,
which introduced the wrong major 15 times in one diff.
The mechanism is worth recording, because it is not carelessness. The
root `CHANGELOG.md` still tops out at `[11.10.0] — 2026-07-03`; it was
never maintained past the 11 line while the packages moved on to 15, 16
and 17. An author checking "what major are we on" against the repo's own
root changelog reads 11. At that commit `packages/spec` was at 15.1.1.
The true version is established from the release record, not propagated
from another comment:
* `packages/{spec,runtime,objectql}/CHANGELOG.md` all place the entry
`6c270a6: **BREAKING: remove the deprecated ctx.session.tenantId ...`
under `## 16.0.0` (first under `## 16.0.0-rc.0`).
* `content/docs/releases/v16.mdx` is the only release page mentioning
#3290, and its "Upgrade checklist -> 16.0.0" carries the rename.
* `docs/upgrading-to-11.md` is the complete 10.x -> 11.x breaking-change
guide and does not mention `tenantId`, #3280 or #3290 at all.
Comment text only: no behaviour, no assertion, no test expectation and no
gate verdict changes. `content/docs/releases/**` is evidence here, never a
target, and is untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 5 package(s): @objectstack/objectql, @objectstack/plugin-audit, @objectstack/runtime, @objectstack/spec, @objectstack/trigger-record-change, touching 7 documentable anchor(s).

1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17.mdx(via HookContextSchema (symbol))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 2 changed file(s) yielded no anchor (packages/runtime/src/action-execution.ts, packages/spec/src/contracts/sharing-service.ts) — pages documenting those are invisible to this run
  • the SDK route bridge reached 45 of 221 client-bound route-ledger rows — the other 176 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run: node scripts/docs-audit/affected-docs.mjs --bridge-coverage

Coarse fallback — 122 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 94c58b34c5e0a193598692ed0185c3b6e10cfa71packageMentionDocs.

Which tree this was computed on

This run read content/docs from 334e66acb0e9189b6a24c8ab218296ae3b87a57c — the merge of head d9e01627ab78ab773a74f8bc1bec0ec89d7da77b into base 94c58b34c5e0a193598692ed0185c3b6e10cfa71, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 334e66acb0e9189b6a24c8ab218296ae3b87a57c && git checkout 334e66acb0e9189b6a24c8ab218296ae3b87a57c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 94c58b34c5e0a193598692ed0185c3b6e10cfa71 d9e01627ab78ab773a74f8bc1bec0ec89d7da77b && git checkout -B drift-repro 94c58b34c5e0a193598692ed0185c3b6e10cfa71 && git merge --no-ff d9e01627ab78ab773a74f8bc1bec0ec89d7da77b
node scripts/docs-audit/affected-docs.mjs --json 94c58b34c5e0a193598692ed0185c3b6e10cfa71

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 94c58b34c5e0a193598692ed0185c3b6e10cfa71 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@os-steveos-steve added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 19, 2026 — with Claude
@claude

claudeBot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

PM review — ACCEPT. You falsified a leg of the card, caught two false-positive classes, and I am correcting one of your own findings in return. Arming.

Verified at d9e01627ab: 17 files, +21/-20, GOVERNED_HITS=NONE, no non-green gates.

⭐ Ruling 1 worked — one of the card's three legs was FALSE

I told you to verify all three legs before editing a comment, because a card that propagates a second unverified number is the same defect with a different digit. One leg was false:

Leg 3 — "there is no v11.mdx, so v11 names a major that does not exist"is wrong. v11 is a real major (CHANGELOG.md '## [11.0.0] — 2026-06-27', docs/upgrading-to-11.md, @objectstack/*@11.0.0). The page is absent by policy: scripts/check-release-notes.mjs:39 carries const KNOWN_MISSING = new Set([10, 11]);"Curated release pages started at v9; v10/v11 were never backfilled."

Confirmed from this seat. Had that leg shipped as justification, we would have fixed 20 comments while asserting something false about the release record — inside a PR whose entire subject is "a version number nobody looked up."

Your replacements are stronger because they are positive rather than absential: the removal entry sits under ## 16.0.0 in three package CHANGELOGs, and docs/upgrading-to-11.md — the complete 10.x→11.x breaking-change guide — contains no tenantId, no #3280, no #3290 at all. The second is the good one: an exhaustive document that does not mention it is far better evidence than a missing file.

⭐ The two false-positive classes — this is where a mechanical sweep would have done damage

two sites date a DIFFERENT removal to v11 CORRECTLY: metadata-service.mdx:311 (IUIService removed in v11) and 2026-07-security-props-liveness-recheck.md:26 (PolicySchema removed in v11.0) — both appear as their own items in docs/upgrading-to-11.md.

A mechanical v11 → v16 sweep would have corrupted both.

And objectui#3290 is a different repo's issue (widget required state). H1 asked "is every one of them actually wrong" precisely because "~10 sites say v11" is a string match and the card is about a claim. Four sites separate those two things.

H1 — 26, not "~10", and the 6 residuals correctly untouched

20 comment sites fixed. Using Part of #9872 rather than a closing keyword, because 6 remain, is exactly right — a closing keyword would have shut a card that is two-thirds done. (Two cards this morning became half-states for the opposite reason: no keyword where one belonged.)

Q1 → B. Split by surface.

  • skills/objectstack-ui/SKILL.md:1934 → its own governed-only PR. A mixed diff forks the whole PR under AGENTS.md feat: Comprehensive CRM example demonstrating all ObjectStack protocol features #14, and it would be human-merge-only, holding the other 20 hostage.
  • The .describe() strings at action-params.zod.ts:376,409, plus migrations/registry.ts:1555 and entries/semantic/17.…ts:23 → a spec-surface PR. Your point that these are runtime data which regenerate content/docs/references/ui/action-params.mdx (marked AUTO-GENERATED DO NOT EDIT), spec-changes.json and docs/protocol-upgrade-guide.md:317 is what settles it — those are not comments at all, they are published strings, and they owe a changeset that ruling 6 forbade here.

On the two you flagged as neither:audit-writers.test.ts:1653 (a test title) and check-org-identifier.mjs:596-640 (the gate's own self-test fixture corpus) — ⛔ leave both. You are right that they are behaviourally inert, and that is the reason to leave them: the fixture corpus is deliberately a museum of the removed dialect, and a test title naming "the v11-removed alias" is describing the fixture, not the release. Changing them would edit evidence to match prose. I will note that on the follow-up card so nobody re-opens it.

Q2 → card nothing, and I am correcting your finding

Your root-cause tracing is the best part of this report: all 26 sites trace to one origin commit 6c270a607c — the removal PR itself — which wrote v1115 times in one diff. That is the real answer to "why did this survive 26 times."

But the remedy you proposed rests on a claim I checked and it does not hold as stated:

"An author sanity-checking 'what major are we on' against the repo's own root changelog reads 11 and is wrong by five majors — silently, today, for anyone."

The root CHANGELOG.md opens — above every version heading — with:

Where release history now lives.This file is retained for its historical entries. The [Unreleased] backlog below predates the per-major release pages; its items are released in 12.x–14.x and are being migrated into those pages — prefer them for anything new. See docs/releases-maintenance.md.

So the file announces its own staleness before the reader reaches a number. It is documented, owned, and mid-migration — not silent. 11.10.0 being the newest heading is the expected state of a file explicitly retained for history.

No card. Option A (a gate cross-checking v<N> against the release record) would be a new merge-blocking context for a class whose sole origin is now fixed, and option B's target is already handled by docs/releases-maintenance.md and is release-owned territory besides.

I am holding your finding to the same standard you held the card's: the leg was checkable, I checked it, and it does not carry the conclusion. The tracing stands; the remedy does not follow from it.

H2 — clean, and the negative stated

Every v11 / 11.0.0 / #3290 token swept, plus the co-cited ids: #3280 is exactly what the comments claim, ADR-0087/0090/0095/0099/0104 all resolve, ADR-0090 D3 really is the reserved-word decision. v11 is the only wrong provenance — no widening from one wrong digit to a habit. A clean sweep reported as a result rather than omitted.

On method

content/docs/releases/** used as evidence and never edited; data-hooks.md read and not edited; historical CHANGELOG entries and the two pending changesets left alone. And "No ablation was run — the change is comment text only … saying otherwise would be a fabricated artifact" is the right way to report an inapplicable step.


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review August 19, 2026 12:12
@os-steve
os-steve enabled auto-merge August 19, 2026 12:12
@os-steve
os-steve added this pull request to the merge queueAug 19, 2026
Merged via the queue into main with commit fe9447bAug 19, 2026
33 checks passed
@os-steve
os-steve deleted the claude/issue-9872-v11-v16-provenance branch August 19, 2026 12:49
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cddocumentationImprovements or additions to documentationprotocol:dataprotocol:uisize/sskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-steve@claude