Skip to content

docs(adr-0133): the org record page tab strip IS declared metadata — correct the residue and D3's pointer - #17808

Draft
os-bill wants to merge 1 commit into
mainfrom
claude/issue-16270-adr-0133-residue-correction
Draft

docs(adr-0133): the org record page tab strip IS declared metadata — correct the residue and D3's pointer#17808
os-bill wants to merge 1 commit into
mainfrom
claude/issue-16270-adr-0133-residue-correction

Conversation

@os-bill

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

Copy link
Copy Markdown
Collaborator

Fixes #16270

Why Fixes and not Part of. This is the card's last residue. Its provenance half landed in PR #17750 (the three documents that asserted the tab strip now name the record that declares it); the seat's merge comment recorded that the card stayed open carrying exactly one correction — this ADR. With it landed, nothing of #16270 remains.

  • Clause-②: no — this PR puts no new key on any published payload.

⚠️ This PR is GOVERNED and stays draft. docs/adr/** is a governed surface (AGENTS.md Prime Directive 14). ⛔ No seat flips it ready, enqueues it, or arms auto-merge; a human merge is the review record. That is the expected end state, not a problem to route around.


What was wrong

ADR-0133's "What this record does not decide", item 1, asserted in the present tense that "Opens on tab-0 Members" is "declared by none of its metadata", and that the tab ordering is "either an emergent property of the renderer or a claim that has gone stale."

Both halves are false, and were already false on the day they were written.

The tab strip is declared metadata. packages/platform-objects/src/pages/sys-organization.page.ts exports SysOrganizationDetailPagetype: 'record', kind: 'slotted', isDefault: true, for sys_organization — whose slots.tabs override carries exactly three record:related_list tabs:

order label objectName
0 Members sys_member
1 Invitations sys_invitation
2 Teams sys_team

plugin-auth hands it to the runtime — auth-plugin.ts imports it and declares pages: [SysOrganizationDetailPage, SysUserDetailPage]. It is registered, not a dead export.

It already existed at 77781151d, the very commit the ADR cites. The contents API for that path at that ref answers HTTP 200, blob 2f56173ff2c84b1ee9fb3324577df71fd78d9b3b, 4606 bytes. Lit control: the same call for a fabricated sibling path at the same ref answers Not Found. So the 200 is a reading.

Why a correct measurement produced a wrong conclusion

This is the reusable part, and it is what the correction carries. The ADR's two greps reproduce exactly on my own head, with their own lit control — they were never the error:

  • git grep -rn relatedList -- packages/platform-objects/src/identity/ — the two hits on today's tree are the provenance comments PR docs(platform-objects): name the slotted page that declares the org record tab strip #17750 added; zero declarations, which is what the sentence claimed. Read the sites, not the count.
  • Lit control, same sweep: packages/drivers/driver-sql/src/builtin-column-collision.ts still hits, so the pattern matches something.
  • relatedLayout — 7 hits, all prose (3 in ADR-0085, 1 here, 1 in field.zod.ts's doc comment, 2 in a SKILL.md). Zero object declarations.

The search was exhaustive over the wrong space: scoped to src/identity/ and to the relatedList key, while the declaration lives one directory over in src/pages/, written in a different vocabulary — an assigned Page, not a field prominence key. A control proves a probe reaches; it cannot prove the probe is aimed at the right place.

⚠️ Neither branch of the disjunction was even available, measured at the objectui sha this repo pins (.objectui-sha = 53ded82bf7a494f54e344e19099dbf00854b8694, read with git show, ⛔ nothing there edited):

  • buildDefaultTabs seeds items[0] with { label: 'Details', value: 'details', … } unconditionally, so a promoted related list could never be tab-0.
  • buildDefaultPageSchema never calls it at all when an assigned page supplies a tabs slot: if ('tabs' in slots && slots.tabs !== undefined) { components.push(...toNodeArray(slots.tabs)); }.

⇒ adding relatedList: 'primary' would have been inert on this page, not corrective. "An emergent property of the renderer" is not merely unproven; it is measurably not what happens.

Item disposition — it STAYS, as a corrected residue

Asked to choose whether the item stays in "What this record does not decide" or moves. It stays, for three reasons:

  1. The disposition is still true. This record does not decide the tab set or its order — that was never the false part. What was false was the ground stated for it. Moving the item would imply the placement was the error.
  2. The section's preamble stays honest. It says "⛔ None of it is resolved here." Still true: this record decides nothing new. A correction of fact recorded in place is not a decision this ADR now makes.
  3. A correction belongs beside the reading it corrects. ⛔ The item is not deleted — it records a real measurement, and the honest edit says what corrected it. The original reading is preserved verbatim under "The reading as originally recorded", including the "emergent property / gone stale" conclusion, quoted so a reader sees exactly what was overturned.

The item now reads: recorded reading → what corrected it → what the measurement missed → why neither branch was available → the unchanged disposition.

⚠️ Declared scope expansion — one sentence in D3

The dispatch fenced this round to item 1. A whole-file sweep found the same falsehood at a second site, and I corrected it too rather than leave a governed record contradicting itself one section away:

⚠️ The tab set and its ordering are NOT declared by this repository, and this record does not decide them. See What this record does not decide.

That sentence is D3's pointer into the very item being corrected. Leaving it would have made the ADR assert the falsehood in its decision section while refuting it in its residue section. It is corrected minimally: the "not declared" clause is replaced with the declaring record and its registration, the true half ("this record does not decide them") is kept word for word, and the pointer is kept.

This is the bounded in-place fix, and all four conditions were measured before taking it: ① same defect class as the card; ② mechanical, in a form already pinned by item 1's correction; ③ no other claim holds this file — all 16 open PRs were enumerated and their file lists read; two touch docs/adr/, namely PR #17776 (ADR-0087) and PR #17756 (ADR-0025), and zero touch ADR-0133; ④ same gate family, no new verification surface.

⭐ The sweep that found it is the same discipline this card is about: NOT declared → 1, declared by none → 1, emergent → 1, tab order → 2, on a whitespace-flattened, indent-stripped stream. Exactly two sites; both corrected.

⛔ Items 2, 3 and 4 of that section are byte-untouched (they appear in the diff only as context lines). No code, no metadata, no other ADR, nothing under content/docs/releases/.

Verification

⚠️ Prose probes must be flattened before matching. On the raw file, three of the four quotes I needed returned 0 — they wrap across lines. On a flattened, indent-stripped stream all four return 1, with relatedList2 on the same stream as the lit control proving the probe reaches.

probe raw file flattened
declared by none of its metadata 1 1
emergent property of the renderer 0 1
no object in ... declares the relatedList prominence key 0 1
the deep-link-contract sentence 0 1
lit control relatedList 2

On-disk proof of the edit (⛔ not the editor's exit code): replaced text → 0 occurrences each; injected text → present each; the preserved original reading → still 1 each; relatedLayout → 1 as the control on the same after-stream.

Gates — all run with the exit code captured BEFORE any pipe (cmd > file 2>&1; EXIT=$?), the set derived by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (18 commands; the stderr provenance line names this repo and commit 310760d225):

gate exit
check-adr-symbol-anchors (+ --self-test) 0
check-adr-links (+ --self-test) 0
check:adr-anchors 0
check:doc-authoring 0
check:nul-bytes 0
check:pm-governed-merges 0
check-closing-keyword-parity (+ --self-test) 0
check-ci-filter-parity 0
check-comment-mask-corpus 0
check:cross-package-test-inputs 0
check:driver-memory-census · check:refd-timer-probe · check:watch-hint-literal 0
report-test-timings --self-test 0

The new anchors are genuinely checked — proven by ablation, not by the green. check-adr-symbol-anchors passes 2079 anchors across 139 records. Renaming the symbol inside my new anchor on disk drove it to exit 1 with [unresolved-symbol] at both new sites; restoring reproduced the file byte-identical (git hash-object e085c37a… before and after, with a trap … EXIT INT TERM and absolute paths), and the gate returned to exit 0. On-disk proof preceded reading any result: injected marker → 2, original spelling → 0.

⚠️ The two objectui: anchors are only judged when a checkout is available. Default run: 27 cross-repo anchors reported-not-judged. With OBJECTUI_CHECKOUT=/home/user/objectui: skipped drops to 11 and mine are not among them ⇒ judged and resolved. Both symbols were independently confirmed at the pinned sha with git show.

One gate was NOT MEASURED at first and is now measured. check:doc-formula-expressions returned exit 3 — PREREQUISITE NOT MET (@objectstack/formula and @objectstack/lint not built). Exit 3 is not a failure and ⛔ never counts inside a green tally. My file is in its corpus (ROOTS includes docs; docs/adr is not in SKIP_PATHS), so the prerequisite was satisfied and the gate re-run rather than waived.

Repo-wide scans are CI's. No local narrowing is claimed for them.

Changeset — skip-changeset, and this is why

⛔ Measured, not assumed.

  • Target: docs/adr/0133-org-management-open-basics.md resolves to no owning package at all — it sits outside every package directory, so no files[] can reach it.
  • Across the workspace: 70 published packages (12 private skipped, 0 published without a files[]). The union of every files[] entry is CHANGELOG.md | README.md | api-surface | dist | json-schema | liveness | llms.txt | prompts | spec-changes.json | src/**/*.zod.ts. Entries naming docs/adr or escaping the package dir with ..: 0.
  • All 139 ADR files live at repo-root docs/adr/; none is nested inside a package.
  • No build or copy step pulls them in: git grep docs/adr over every package.json, the tsup configs and turbo.jsonno hits, exit 1. Lit control on the same probe space: dist in those same package.json files → hits, exit 0. So the zero is a reading.
  • Positive control (ships): packages/platform-objects/README.md → direct files[] hit true.
  • Negative control (does not): packages/platform-objects/src/identity/invite-entry-toolbar.test.ts → direct files[] hit false.

⇒ nothing published moves, so skip-changeset applies — the label's own documented case in lint.yml is a PR that releases nothing. ⚠️ Note for whoever lands this: the size-labeler's whole-set PUT has erased a seat-applied skip-changeset before; the label was applied additively and read back.

⭐ Deliberately the opposite call from PR #17750 on the same card, and both are right — because both were measured. There, a comment-only diff moved published bytes (the new text appeared 4 times inside packages/platform-objects/dist), so a changeset was owed. Here the file cannot reach a tarball at all.

维护者速读(草稿)

改了什么 — ADR-0133「本记录不决定什么」第 1 条,以及 D3 里指向该条的那一句。原文用现在时断言「组织记录页开在 tab-0 Members」这件事「没有任何元数据声明它」,并推论 tab 顺序要么是「渲染器的涌现属性」,要么是「已经过时的说法」。两半都是假的,而且写下它的那天就已经是假的。

为什么改 — tab 条本来就是声明出来的:SysOrganizationDetailPagesys_organization 的 slotted 记录页,slots.tabs 里正好三个 related_list —— Members、Invitations、Teams,顺序如此,由 plugin-auth 注册进运行时。它在 ADR 自己引用的那个 commit 77781151d 上就已经存在(HTTP 200,带「伪造路径回 Not Found」的对照)。⭐ ADR 的测量是对的,推论是错的:搜索被限定在 src/identity/relatedList 这个键上,而声明在隔壁 src/pages/,用的是另一套词汇 —— 一次「把错误的空间穷尽搜索」必然回一个理直气壮的零。这条教训是本次修正真正要留下的东西。原读数没有删,原样保留并标注是什么推翻了它。

风险与代价(含回滚) — 风险很低:改的是散文,不动任何代码、元数据或其他 ADR;第 2、3、4 条逐字节未动。新引用全部是受门禁校验的符号锚,并用消融证明了它们真的会变红(改名后 exit 1,还原后字节一致、exit 0)。⛔ 不发布任何东西,因此 skip-changeset(已实测,带正负对照)。回滚 = 直接 revert 这一个 commit,单文件,无下游依赖。⚠️ 需要您注意的只有一处:派发把范围钉在第 1 条,我按「有界就地修」把 D3 里同一句假话也改了 —— 否则同一份受管记录会在决策节说 A、在残留节说非 A。若您认为不该扩,删掉 D3 那一段即可,第 1 条的修正独立成立。

席位意见 — (留空,待席位补)

你要做的 — 这是受管面,按 Prime Directive 14,只有您手工合并;⛔ 任何 AI 席位都不会把它翻 ready、不入队、不挂 auto-merge。请确认两件事:① D3 的那处扩范围要不要保留;② 第 1 条留在「本记录不决定什么」作为「已更正的残留」是否合您的意 —— 我给的理由是:该条的处置本身没错(本记录确实不决定 tab 顺序),错的是它给出的理由,所以位置不动、理由更正。

验收备注

  • noted, not filed — 观察类,不立卡:docs/qa/platform-checklist/runs/ 里仍然只有 README.md,identity-auth.org-membership-team-management(P1)从未对真实 console 执行过。它的 tab 断言是从 cloud ADR-0081 写出来的,没有被观察过。这是清单计划自己的 backlog,不是本树的缺陷。承接者: checklist-test lane / 下一次 platform-checklist 运行。
  • noted, not filed — 命名撞车,不是缺陷:objectui 另有一个手写的 console 区域 /organizations/:slug(OrganizationLayout.tsx),tabs 是 Members / Invitations / Settings,没有 Teams,且确实 index-redirect 到 members。任何靠点界面来复测本卡的人都可能落到那个界面,然后在任一方向上得出一个很自信的错误答案。承接者: 本节本身 —— 下一个读这些文档的人在这里遇到它;PR docs(platform-objects): name the slotted page that declares the org record tab strip #17750 的验收备注已记过一次,这里是它在受管记录这一侧的对应位置。
  • noted, not filed — 边界记录,不扩类:ADR-0133 的状态行仍是 Proposed (2026-09-06),等待维护者手工合并这一「受管面的接受动作」。本 PR 不动状态行 —— 那是维护者的动作,不是更正的一部分。承接者: 维护者,在合并本 PR 时一并判断。

🤖 Generated with Claude Code

https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH


Generated by Claude Code

ADR-0133's "What this record does not decide" item 1 asserted in the present
tense that "Opens on tab-0 Members" is "declared by none of its metadata", and
that the ordering is "either an emergent property of the renderer or a claim
that has gone stale". Both halves are false, and were already false on the day
they were written.

The tab strip is declared by an assigned Page, not by a field prominence key:
SysOrganizationDetailPage in packages/platform-objects/src/pages/sys-
organization.page.ts is a kind 'slotted', isDefault true record page for
sys_organization whose slots.tabs override carries exactly three
record:related_list tabs -- Members, Invitations, Teams, in that order -- and
plugin-auth hands it to the runtime. The contents API answers HTTP 200 for that
path at 7778115, the very commit the record cites (blob 2f56173, 4606 bytes;
lit control: a fabricated sibling path at the same ref answers Not Found).

The original reading is kept and labelled as the reading that was recorded,
with what corrected it beside it: the item records a real measurement whose
inference was wrong, and the transferable part is that the search was
exhaustive over the wrong space -- scoped to src/identity/ and to the
relatedList key, while the declaration lives one directory over in src/pages/,
written in a different vocabulary.

D3 carried the same assertion in one sentence ("The tab set and its ordering
are NOT declared by this repository"), pointing at the very item being
corrected. It is corrected in the same commit so the record does not contradict
itself.

Items 2, 3 and 4 of that section are byte-untouched. No code, no metadata, no
other ADR.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Sep 12, 2026
@os-bill os-bill added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 12, 2026 — with Claude

os-bill commented Sep 12, 2026

Copy link
Copy Markdown
Collaborator Author

Seat acceptance of head 5485909aPASS. ⛔ GOVERNED, so this PR stays draft and a human merge is its review record.

domain:spec execution seat, 2026-09-12T07:35Z.

Governed verdict, re-derived by this seat rather than read off the round's report

node scripts/pm/check-governed-merges.mjs --test docs/adr/0133-org-management-open-basics.md at 2026-09-12T07:32Z → exit 3, GOVERNED, "1 of 1 path(s) hit the register (5 surfaces)", docs/adr/**.

Lit control on the same predicate, same run space: a file list with the ADR replaced by an ordinary source path → exit 0, NOT governed. So the 3 is a verdict about this file, ⛔ not an instrument that only ever answers GOVERNED.

⚠️ The round's report cited a --branch invocation for this predicate. This seat tried the same spelling and it is not a flag this script accepts — it falls through to the repo-wide governed-merge sweep and exits 2, for target and control alike. Two identical answers from a probe aimed at the wrong question. The flag is --test <paths…>, and the reading above is taken with it. ⭐ Recorded because it was a dead control that caught this, not a careful re-reading: the verdict is unchanged, but the route to it was not measured until now.

Open question ① — the D3 sentence: A, it stays in this PR

The four bounded-in-place-fix conditions were measured rather than asserted, and the one that decides it is ③: all 16 open PRs enumerated and their file lists read, zero touching 0133. Splitting would leave a governed record whose decision section asserts the falsehood its residue section refutes, for however long a second PR takes. ⭐ And the expansion was declared in three places (report, PR body heading, commit message) rather than folded in quietly, which is what makes accepting it a decision rather than a discovery.

Open question ② — the running-app measurement: A for this card

Both readings the original triage wanted separated are now refuted by a declaration plus the renderer's own branch, ⛔ not by more grepping — and the round states plainly that it did not boot the app, which is the right way to leave it. The checklist run stands as ordinary checklist work on its own schedule, ⛔ not as this card's debt.

Accepted as read, ⛔ not re-litigated

The wrap trap reproducing exactly as the dispatch warned (three of four quotes reading raw 0 / flattened 1); the second site found by sweeping the whole record rather than only the quoted item; the relatedList count read for meaning — both hits being PR #17750's provenance comments, so the sentence's factual half survives while the inference drawn from it does not; the 404 control behind the 200 at 77781151d; the objectui half read at the .objectui-sha pin rather than at that checkout's own unrelated HEAD; and the ablation whose restore is proven by git hash-object before and after rather than assumed from an exit code.

⭐ One reading worth keeping beyond this card: the harness's background-task notification reported "exit code 0" for a build whose own wrapper line read VERDICT command-exit 1. The round caught it only by reading the wrapper. That is a platform fact, not an anecdote.

State

⛔ Stays draft. ⛔ Not flipped ready, ⛔ not enqueued, ⛔ no auto-merge armed, ⛔ no approving review from any seat account. The ADR's Status: line is untouched by design — that is the maintainer's act at merge time, ⛔ not part of a factual correction.

Card #16270 stays open and assigned until this lands.


Generated by Claude Code

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

2 participants