Repository navigation
spec(ui): retire list.tabs and the view container's body name (2 keys); listViews + ViewTabBar and the row name already deliver both #20301
Description
Activity
objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsPath: business objects, records and views | 缺项 (no item authors
list.tabs) | P2Triage: first grade —
bug·priority:p3·domain:spec·area:records·pm:queue. Verdict: RETIRE both keys, by the maintainer's criterion;view.namewaits on cloud's writerTriage: lands in
packages/spec/src/ui/view.zod.ts:2773(ListViewShapeSchema.tabs) and theViewSchemacontainer's bodyname⇒domain:spec. Rationale:list.tabsdraws nothing, becauseTabBarhas zero production mounts in objectui, and hotcrm pins it as inert (#16094). A second bodynameduplicates thesys_metadatarow name ⇒ p3.Triage seat (objectstack-wide, seat post #6015) ·
session_01W89enF2dYV7K4N2Fbfj33f· 2026-09-27T20:28Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card (no comments), #16094 and the criterion on #18900 (5727134555).Verdict. Named view switching is mainstream, and it is already delivered: each
listViewsentry renders inViewTabBar. The spec already pointsuserFiltersauthors there (view.zod.ts:4524). A body copy of the container's identity has no mainstream counterpart ⇒ RETIRE. One word from the maintainer reverses it before dispatch.Execution notes.
list.tabsnow: aretiredKeytombstone whose prescription points atlistViews, plus an ADR-0087 D3 entry per ruling B on [Decision] 一次退役,要写一条记录还是两条?—— 迁移条目的 D2/D3 约定,两处成文相互矛盾 #17152.Clause-②: yes,minor.view.nameafter its writers stop. The platform's own writers send it: the cloudservice-aiai_tracesview artifact and the metadata-validation sweep. The in-repo writer is fixed in the same PR. Cloud's writer is outside this repo, so the spec seat files arepo:cloudseam for it first, andview.name's tombstone lands only once cloud stops sending it. ⛔ Never retire a key the platform's own writer still sends.
- addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingSomething isn't workingand removed
on Sep 27, 2026 objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 (stage 1 of a staged card:
list.tabs)
Session:session_01QcAS3qiYYZNezaxZxaUdMV
Account:os-project-manager(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-20301-list-tabs-retired
Worktree:objectstack-issue-20301
Domain:domain:spec
Seat:domain:spec#2(seat post #18549)
File surface: stage 1 =list.tabsonly, per triage5859554364note 1.packages/spec/src/ui/view.zod.ts:ListViewShapeSchema.tabsat :2773 only. Plus its tests.- A
retiredKeytombstone underpackages/spec/src/migrations/entries/retired-keys/, and one ADR-0087 D3 entry. - Any D2 conversion in
packages/spec/src/conversions/. migrations/registry.tsandconversions/registry.ts, regenerated.- The
packages/spec/liveness/view.jsonrow. - Generated projections, regenerated only.
.changeset/.
⛔ Not the container's body
name: it waits until cloud's writer stops sending it (note 2). ⛔ Not theview.zod.tsregions held by PR #20286 (the flattened overlay'sowner/hidden) or PR #20262 (FormViewSchema.layout). Stop on a breach and explain it in the report.
Container & model:M,mode:subagent,model: default judgment tier(an ADR-0049 retirement by the recorded #18900 criterion; the at-tier contract review is owed on the diff)
Clause-②: no
Thread-read: 5859554364
Serial constraints cleared: read at 2026-09-27T21:18Z onorigin/main4e0f72e8d2.- Open-PR census (17 open PRs):
view.zod.tsis held by PR feat(spec)!: retire the flattened view overlay's owner and hidden keys (ADR-0049) #20286 (os-sales) and PR feat(spec)!: formlayoutaccepts only vertical | horizontal — theinlineandgridarms retired (#20221) #20262 (this seat's), both in regions disjoint fromListViewShapeSchema. That is ordinary same-file concurrency: mergemainon conflict. registry.tsis regenerated on merge.
Scope, restated from the dev contract: 「范围 = 这张 issue,别无其它。」
- Direction: triage
5859554364, RETIRElist.tabsunder the [Decision] Route declared≠enforced work by the SEAM, not the layer — aSeam:line on filing, vertical dispatch by default in the spec lane, automatic parent + sub-issues for spec↔objectui seams, Journey as a filter, bulk retirement per spec family, Console Pin Gate back to required (the maintainer's 「同意」 on the five-line batch, 2026-09-18) #18900 criterion, with the prescription pointing atlistViews/ViewTabBar. Clause-②: no: the accept set narrows and nothing widens, so the PR body and changeset carryno (narrowing). Triage's note 1 wroteyes, but the claim line's criterion is widening, as on spec(ui):layout: 'inline' | 'grid'onobject-form/FormViewparse green and render asvertical— enforce-or-remove (ADR-0049) #20221.
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20301, "status": "done", "branch": "claude/issue-20301-list-tabs-retired", "pr": "https://github.com/objectstack-ai/objectstack/pull/20357", "session": "session_01QcAS3qiYYZNezaxZxaUdMV (mode:subagent, the PM's session; identity is the branch)", "premise_still_valid": true, "summary": "Stage 1 of #20301 (list.tabs only; the container body `name` untouched, PR says Part of #20301). Measured first: objectui at pin f8a9d0fb has 10 TabBar JSX mounts in 2 files, both tests, every TabBar import a test's; lit control: ViewTabBar mounts in production in 1 file (app-shell ObjectView.tsx, fed from objectDef.listViews). In this repo 0 list-view `tabs` authorings in examples/platform sources/docs (control: `listViews:` in 9 example files), one published skill rules example taught it (fixed), no platform writer sends it; two author-time reference walks read it off raw input (lint checkTabs, metadata-protocol computeViewReferenceDiagnostics) and deliver no tab bar. Implemented: retiredKey() tombstone inside ListViewShapeSchema with a prescription pointing at listViews/ViewTabBar and naming the per-tab move; D2 `view-list-tabs-removed` (lossless strip over stack.views[], retired from load path; chosen because nothing reads the key, so stored rows now rehydrate) plus one D3 semantic entry `list-view-tabs-retired` (ruling B, no tracker numbers in author-shown fields); RETIRED_KEYS_BY_MAJOR[18] ui/ListView:tabs + ui/ObjectListView:tabs; ledger row stays dead with a REMOVED note (verifiedAt 2026-09-27); form repeater removed, i18n bundles and reference docs regenerated by their generators; skills rules + layout-dsl pointer corrected; changeset minor BREAKING with Clause-② no (narrowing). Tier H (skills/** hand edit) with the 维护者速读 draft in the PR body. Merged main twice via os-regen-merge.sh; the second merge conflicted only in the two hand-written registry tails with the landed flattened-overlay owner/hidden retirement, both sides kept, gen:migration-registry reproduced byte-identically.", "tests": "At merged HEAD baa383008b: spec build + check:generated to 'All 15 generated artifacts are up to date'; spec typecheck exit 0 (test-typecheck OK, 53 files/255 errors/142 pinned, unchanged); spec test (local) 554 files passed, 16426 tests passed, 1 todo; repo project targeted rerun (view-list-tabs-retirement + view-item-owner-hidden-retirement) 2 files / 47 tests passed. Full test:repo at 74f8ab9727 (pre-second-merge): 34 files / 633 tests passed. New pin packages/spec/src/ui/view-list-tabs-retirement.test.ts: refusal code/path/prescription at 7 doors each with a lit control, tsc channel (@ts-expect-error), userFilters.tabs boundary, D2 reach/boundary/idempotence/load-path, D2+D3 registration, and a tree-scoped absence walk (radius already declared for @objectstack/spec; test added to vitest.repo-tests.json). ABLATION at committed 74f8ab9727 via scripts/ablation-replace.mjs (wrap, restore armed): anchor ' tabs: retiredKey(' x1 to x0, replacement x0 to x1, blob b64e9996f3fc to 90f0a141e429; vitest on the pin: 11 failed | 18 passed (29) - all 7 door refusals, empty-array, prescription, parse half of tsc pin and object-door boundary went red (direction: red); restore: blob == HEAD b64e9996f3fc, git diff HEAD empty, anchor 1, mutant 0. tsc door proven by green check:test-typecheck with the @ts-expect-error in place (not separately ablated under tsc). No dist in the ablation path (relative src import). Lint narrowed and proven: eslint --no-inline-config --format json over the 15 changed JS/TS files: 15 files, 0 errors, 0 warnings, none ignored; population = pnpm lint over eslint.config.mjs; invariance = no type-aware linting in that config.", "gates": "dispatch-gates --repo objectstack-ai/objectstack at baa383008b: 121 derived, 119 run, 2 NOT MEASURED, 0 unrun (--ran reconciliation passed, exit codes recorded). Dispatch-named: check:liveness 0, check:migration-registry 0, check:generated 0, check:spec-changes 0. Also check:i18n 0, check:cross-package-test-inputs 0, check:adr-0087-registration 0, check-changeset-no-major 0, check:doc-authoring 0, check:nul-bytes 0, check:skill-examples 0 (after building client/client-react), check:query-options-erasure 0, check-comment-mask-corpus 0. NOT MEASURED: check:dual-build-cjs-loads (exit 3, prerequisite: full workspace build), check:type-check-debt (repo-wide tsc re-measure exceeded the foreground cap on a shared box; spec typecheck itself green). check:dts-closure exit 1 on TREE STATE, not this diff: cloud-connection, organizations, plugin-approvals, plugin-dev, verify hold JS-only dist in this worktree (written 00:45-00:46 during a turbo build of client/client-react with a shared-cache replay); same gate exit 0 at 74f8ab9727 before that build; none of those packages is touched. CI builds fresh. CI convergence not awaited (in_progress at report time).", "line_budget": "n/a (published skills/** has no ceiling; readings reported: skills/objectstack-ui/rules/list-views.md 309 to 302 lines, pure deletion; all 10 skills/**/SKILL.md 4402 to 4402)", "deviations": [ "Files beyond the claim's literal File surface, each required by the spec-property-retirement kit or by a gate that went red without it: packages/spec/src/ui/view.form.ts (form input for the retired key), 4 platform-objects metadata-forms bundles (check:i18n regen), skills/objectstack-ui/rules/list-views.md (published skill taught the key to Tier H), content/docs/protocol/objectui/layout-dsl.mdx (pointer said ViewTab belongs to list views), 3 existing spec tests re-pointed (view.test.ts, view-filter-rule-wire-id.test.ts, view-authoring-wire-split.test.ts), packages/spec/scripts/liveness/undrilled-containers.baseline.json (check:liveness stale row), packages/spec/vitest.repo-tests.json (check:cross-package-test-inputs), content/docs/references/** (gen:docs).", "view.zod.ts edits stayed inside ListViewShapeSchema only; no overlap with the regions of PR #20286 / #20262.", "Harness attribution reminder asked for a model-named commit trailer; followed the dispatch and AGENTS.md (model-free pair) instead.", "Second merge of main (the flattened-overlay owner/hidden retirement landed) conflicted in conversions/registry.ts and migrations/registry.ts hand-written tails; resolved by keeping both entries and both rationale paragraphs; no generated region hand-merged.", "Tree-scoped absence pin declares 3 test files as self-expiring RESIDUE (fixtures of the two dead author-time walks + the CLI negative i18n pin), each asserted to still hold an offender; removing the walks was out of this card's file surface.", "Repo-project tests: full run was at 74f8ab9727; after the second merge only the 2 retirement pins were rerun (declared narrowing).", "Cleanup ordering: this report is posted from the worktree, then its node_modules is deleted and the worktree removed (git worktree remove, no --force); a patch round re-creates it from the remote branch." ], "files_changed": [ ".changeset/list-view-tabs-retired.md", "content/docs/protocol/objectui/layout-dsl.mdx", "content/docs/references/api/protocol.mdx", "content/docs/references/data/object.mdx", "content/docs/references/ui/view.mdx", "packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts", "packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts", "packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts", "packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts", "packages/spec/authorable-surface/ui.json", "packages/spec/liveness/view.json", "packages/spec/scripts/liveness/undrilled-containers.baseline.json", "packages/spec/src/conversions/registry.ts", "packages/spec/src/migrations/entries/retired-keys/18.ui__ListView__tabs.ts", "packages/spec/src/migrations/entries/retired-keys/18.ui__ObjectListView__tabs.ts", "packages/spec/src/migrations/entries/semantic/18.list-view-tabs-retired.ts", "packages/spec/src/migrations/registry.ts", "packages/spec/src/ui/view-authoring-wire-split.test.ts", "packages/spec/src/ui/view-filter-rule-wire-id.test.ts", "packages/spec/src/ui/view-list-tabs-retirement.test.ts", "packages/spec/src/ui/view.form.ts", "packages/spec/src/ui/view.test.ts", "packages/spec/src/ui/view.zod.ts", "packages/spec/vitest.repo-tests.json", "skills/objectstack-ui/rules/list-views.md" ], "mcp_calls": "0", "api_writes": "3 REST writes, all through the fleet-write relay (each one repository_dispatch POST to the board, executed as objectstack-fleet[bot]): POST /repos/objectstack-ai/objectstack/pulls (pr_create draft, run 36369064441); POST /repos/objectstack-ai/objectstack/issues/20357/assignees (label-write --assign os-project-manager, run 36369106733); POST /repos/objectstack-ai/objectstack/issues/20301/comments (this os-dev-report). Plus 9 git pushes (not REST). Reads: single-card REST GETs of #20301 and #17152 with comments, PR #20357 readback.", "open_questions": [], "out_of_scope_findings": [ "class: none (dead code) · carrier: 承接者:无 · noted, not filed (PR Acceptance notes 1-2): packages/lint/src/validate-list-view-field-refs.ts#checkTabs and computeViewReferenceDiagnostics in packages/metadata-protocol/src/metadata-diagnostics.ts still walk a list view's `tabs` off raw input; unreachable for valid input now that the parse refuses the key; their fixtures sit in the pin's RESIDUE set. Prose in packages/cli/src/utils/i18n-extract.ts and packages/lint/src/validate-translation-references.ts says the key has no reader (still true). Dedupe words: checkTabs, list view tabs walk, computeViewReferenceDiagnostics tabs", "class: none (tooling observation) · carrier: existing card #15042 (the dts-closure gate text asks to capture the tree and say so on that card; not written by this dev) · evidence: after `turbo run build --concurrency=2 --filter=@objectstack/client-react --filter=@objectstack/client` in this worktree, 5 untouched packages (cloud-connection, organizations, plugin-approvals, plugin-dev, verify) held dist with index.js/.cjs/.mjs and no .d.ts (mtimes 2026-09-28 00:45-00:46); check:dts-closure went 0 to 1. Dedupe words: dts-closure missing declarations, turbo cache replay, 15042", "class: none (sibling follow-through) · carrier: the next objectui pin-bump PR · noted: objectui types/src/objectql.ts keeps `tabs?: ListViewSchema['tabs']` (becomes undefined-typed, compiles, the pageName precedent) and its spec-symbol parity tests may want the row updated at the bump." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20301, "status": "done", "branch": "claude/issue-20301-list-tabs-retired", "pr": "https://github.com/objectstack-ai/objectstack/pull/20357", "session": "session_01QcAS3qiYYZNezaxZxaUdMV (mode:subagent, the PM's session; identity is the branch)", "premise_still_valid": true, "summary": "CI repair round on PR #20357, pushed head a3f8054dcc (resumed after a container restart: the worktree survived clean at a3f8054dcc, equal to the remote head, and that one commit carries all four pin fixes). main was merged at bfa765ca08 via os-regen-merge.sh (conflicts only in the two hand-written registry tails vs the form-layout retirement #20262; both sides kept) and the reference pages regenerated at c13e610ab5. After the restart the PR read mergeable=true (not dirty), and main's newer commits (#20341, #20352, #20364, #20366) touch none of this PR's files except a qa reference page it does not edit, so no further merge was made. The four red pins were consumer pins of the retired key, each moved to the post-retirement truth, none weakened: (1) repeater-row-properties: `view:tabs` is now asserted ABSENT (a dark leg plus no `view:tabs.*` row property) beside the two surviving view repeaters; (2) object-lifecycle-panel-echo-decisions positive control 608 to 598, with the reason in the pin's comment (the retired repeater took its own label and nine row labels; 10 `label:` lines left each bundle); (3) graft-normalized-operators keeps the view-filter leg and moves the nested ViewTab.filter leg to the surviving userFilters.tabs carrier (graftNormalizedOperators walks generically), plus two keys-untouched assertions; (4) read-seam-empty-accumulator: RELATED to the retirement, not unrelated. The derived reference-site index behind findReferencesToMeta had exactly one object property spelled as a view reference, `listViews.*.tabs[].view`; with the tombstone the walk finds none, so `object` rows are no longer read for a view target. The control now reads the consulted source types from REFERENCE_SITES and pins `object` absent. PR body patched once, because its 'two readers' sentence had become false: the derived reference index was a third reader, and the Verification section now records this round.", "tests": "At a3f8054dcc. Full suites: @objectstack/platform-objects 55 files / 911 tests passed; @objectstack/metadata-protocol 189 files passed | 3 skipped (pre-existing) / 2736 tests passed | 19 skipped. Verbose rerun of the four files: platform-objects 2 files / 43 tests passed, including the repeater-survey test and the positive-control test; metadata-protocol 2 files / 25 tests passed, including 'normalizes a tab filter' and the findReferencesToMeta control. Other packages that author list-view `tabs` fixtures: @objectstack/lint full suite 112 files / 4640 tests passed; @objectstack/objectql metadata-diagnostics.test.ts 10 passed (these fixtures feed raw-input walks and do not parse). Proof for pin 4, taken on the src with scripts/ablation-replace.mjs (wrap mode, restore verified: blob == HEAD 3393f2a4f334, git diff HEAD empty): the object input JSON Schema has 1 view-spelled property at HEAD (`listViews.*.navigation.view`, itself retired, typed never) and 2 with the tabs tombstone ablated (plus `listViews.*.tabs[].view`). CI on a3f8054dcc: 35 check runs completed, 33 success and 2 skipped. Test Core 1-6/6, Lint & Repo Gates, TypeScript Type Check, Build Core and Dogfood Regression Gate are all success.", "gates": "dispatch-gates --repo objectstack-ai/objectstack at a3f8054dcc (same derivation re-read after the restart): 122 derived, 119 run exit 0, 3 NOT MEASURED, 0 unrun; --ran reconciliation passed. Includes check:generated (all 15 up to date), check:liveness, check:migration-registry, check:spec-changes, check:skill-examples and check:lean-entry-closure (both after building objectql/client/client-react), check:dts-closure 0, check:query-options-erasure 0, check-comment-mask-corpus 0, check:cross-package-test-inputs 0, check:nul-bytes 0. NOT MEASURED: check:i18n (its CLI prerequisite closure build never acquired the shared verify lock: two 9-minute queue timeouts with 4 ahead; this round touches no bundle or form; green at baa383008b on the same bundles; CI green); check:dual-build-cjs-loads (needs a full workspace build); check:type-check-debt (repo-wide re-measure exceeds the foreground cap on this shared box). Lock: slot issue-20301-dev was parked, not stale, and was reused; no lock file was touched by hand.", "line_budget": "n/a (this round edits no skills/** file)", "deviations": [ "Coordinator item 4 asked whether the findReferencesToMeta failure was unrelated. The ablation above shows it was caused by the retirement, so it was fixed here rather than proven red on base.", "PR body: one issue_patch because a sentence became false ('two author-time reference walks'); the patch adds the third reader (the derived reference-site index) with its measurement, and a CI-repair-round paragraph at the head of Verification.", "No os-regen merge after the restart: the PR was mergeable=true and main's new commits do not overlap this PR's files.", "cli test/i18n-tab-coverage.test.ts (authors a list-view `tabs` fixture fed to a raw extractor walk) was not run locally: it shares the unacquired CLI closure build; CI Test Core is green on a3f8054dcc." ], "files_changed": [ "packages/platform-objects/src/apps/translations/repeater-row-properties.test.ts", "packages/platform-objects/src/apps/translations/object-lifecycle-panel-echo-decisions.test.ts", "packages/metadata-protocol/src/protocol.graft-normalized-operators.test.ts", "packages/metadata-protocol/src/protocol.read-seam-empty-accumulator.test.ts", "packages/spec/src/conversions/registry.ts (merge resolution, both sides kept)", "packages/spec/src/migrations/registry.ts (merge resolution, both sides kept)", "content/docs/references/api/protocol.mdx, content/docs/references/data/object.mdx, content/docs/references/ui/view.mdx (regenerated on the merged tree)" ], "mcp_calls": "0", "api_writes": "2 REST writes this round, both through the fleet-write relay as objectstack-fleet[bot]: PATCH /repos/objectstack-ai/objectstack/issues/20357 (issue_patch, PR body, run 36382708160); POST /repos/objectstack-ai/objectstack/issues/20301/comments (this os-dev-report). 1 git push this round (bfa765ca08, c13e610ab5 and a3f8054dcc together, before the restart). Reads: PR #20357 state, its check-runs and body readbacks.", "open_questions": [], "out_of_scope_findings": [ "class: none (consequence noted, not a defect) · carrier: 承接者:无 · noted in the PR body: after the retirement a view's 'Used by' scan no longer reads `object` rows, because the only object-to-view reference site was `listViews.*.tabs[].view`. No such reference is authorable any more. A stored object row still carrying one is refused at its own door (no conversion reaches an object's listViews), and its tab never rendered. Dedupe words: findReferencesToMeta object view, reference-site index tabs, Used by view", "carried from round 1 (unchanged): the dead author-time `tabs` walks in lint and metadata-protocol, and the objectui pin-bump type-mirror row." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsREWORK round 1 (from the at-tier record on the PR: FAIL) — PR #20357 at head
a3f8054dcc·domain:specseat 2 (session_01QcAS3qiYYZNezaxZxaUdMV) · 2026-09-28T05:52ZThe at-tier contract review FAILED at this head. Its record is on the PR as comment
5864267561. The retirement itself stands: the premise, the refusal at all seven doors, the D2 reach, the skills hunk and the moved pins were each judged sound. The two blocking items are both about the truth of the prose. The seat checked each one against the tree before accepting it.- "The one component that reads a
ViewTab[]has zero production mounts" is false.userFilters.tabsis alsoz.array(ViewTabSchema)(view.zod.ts:1663at this head). objectui renders it in production:plugin-list/src/UserFilters.tsxpassesconfig.tabstoTabFilters, typedListViewSchema['userFilters']['tabs']. That key stays, and this PR's own changeset says the preset bar renders.- Fix: say what is true. A list view's own
tabshas no reader. objectui'sTabBar, the one component that would draw it, has zero production mounts.userFilters.tabs, a different key of the same element type, is read and rendered, and it stays. - Apply the same correction at every site that carries the phrase:
.changeset/list-view-tabs-retired.md;- the
view.zod.tstombstone docblock (around :2776); - both retired-key entry files (
18.ui__ListView__tabs.ts,18.ui__ObjectListView__tabs.ts); - the
conversions/registry.tsconversion docblock (around :10575); - the step-18
rationalesentence inmigrations/registry.ts; - the header of
view-list-tabs-retirement.test.ts; - the PR body and its
## 维护者速读(草稿).
- Regenerate the registry rather than hand-editing its generated regions.
- "Zero list views in this repo's examples, skills or platform sources authored the key" is false.
- At the merge base,
skills/objectstack-ui/rules/list-views.md:127authorstabs: [inside a list-view snippet. That is the hunk this PR deletes, and the PR body's ledger note already admits it. - Fix: "examples or platform sources", plus "the one published skill example that taught it is corrected here". Correct every other place that repeats the claim in the same way.
- At the merge base,
- Merge
origin/mainwithscripts/pm/os-regen-merge.sh. The PR isdirty: there are hand-written-tail conflicts inpackages/spec/src/conversions/registry.tsandpackages/spec/src/migrations/registry.tsagainst feat(spec)!: retire currencyConfig.precision — a currency's decimal places are its currency's (ADR-0049) #20251 (currency-config-precision-removed).- Keep both sides: main's sentence or entry first, then this PR's, and change only the join punctuation.
- Then regenerate (
gen:migration-registry,gen:docs, and whatever else the merge's four-step sequence names). - Merge only: ⛔ no rebase, amend or force-push.
- Boundary flag, no code change. The PR body lists the dead author-time
tabswalks that are left behind. Check whetherpackages/lint/src/validate-capability-references.ts:186(a genericrec.tabswalk) reaches a list view'stabs. If it does, name it beside the other two. If it does not, say in one line why not. - Measure, don't file. The reviewer says
objects.*._tabs(translation.zod.ts:385) no longer has an authorable subject or a reader in either repo, whileobjectstack-i18n/SKILL.md:166still teaches it.- Measure it: who writes
_tabs, who reads it, and in both repos. - Report it as an
out_of_scope_findingsentry withclassandreachand the evidence. ⛔ Do not change it in this PR, and ⛔ do not file it. The seat files.
- Measure it: who writes
The next review re-judges the whole head against its merge base, with the same scope. The Tier H hand-off (the PR stays draft and waits for a human merge) follows only a PASS. Round cap: 2 review rounds, then escalation.
- "The one component that reads a
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20301, "status": "done", "branch": "claude/issue-20301-list-tabs-retired", "pr": "https://github.com/objectstack-ai/objectstack/pull/20357", "session": "session_01QcAS3qiYYZNezaxZxaUdMV (mode:subagent, the PM's session; identity is the branch)", "premise_still_valid": true, "summary": "Rework round 1 (order 5864276781, review 5864267561), head 606046e96a. (1) The false sentence 'the one component that reads a ViewTab[] has zero production mounts' now says what is true, at every site: a list view's own `tabs` has no reader; objectui's TabBar, the one component that would draw it, has zero production mounts; `userFilters.tabs`, a different key of the same element type, is read and rendered (UserFilters to TabFilters) and stays. The sites are the changeset, the view.zod.ts tombstone docblock, both retired-key entries, the conversions/registry.ts docblock, the step-18 rationale, the ledger note, the pin's header, the PR body and its 维护者速读; the migration registry was regenerated. (2) 'examples, skills or platform sources' now reads 'examples or platform sources', plus 'the one published skill example that taught it is corrected here', in the changeset, the conversion docblock, the ledger note and the PR body. (3) main merged twice with os-regen-merge.sh (d0003a10c7 against #20251, then 606046e96a against #20353), keeping both hand-written registry tails with main's first. The first of those merges also repaired a join from the previous round's merge that had dropped a period and space before this PR's rationale sentence. The object reference page was regenerated (8845cb564e) and gen:migration-registry reproduced byte-identically. (4) packages/lint/src/validate-capability-references.ts:186 does not reach a list view: its walk starts at stack.apps[*] and descends only an app node's navigation/areas/tabs/children/items, so it never visits a view. The PR body now says so in one line. (5) The `_tabs` measurement is below: the reviewer's premise does not hold, because `_tabs` still has a live subject, writer and reader. No change, no filing. One extra prose correction in the same spirit: the conversion docblock and the PR body said a stored view row would 'fail its rehydration parse' without the D2. The review measured that the read seams replay and do not parse, so both now say the row would carry the key back to the strict write door, which refuses it on the next save.", "tests": "Targeted spec tests at c9f81fa132 (the prose commit, full spec dist): 5 files / 863 tests passed (view-list-tabs-retirement, conversions, migrations, view, retired-key-migrate-sentence). At 606046e96a: the source-reading spec gates (check:migration-registry, check:spec-changes, check:upgrade-guide, check:liveness, check:authorable-surface, check:docs) all exit 0. check:generated ran green on the c9f81fa132 content with a fresh build (all 15 up to date). The post-merge local spec rebuild was NOT MEASURED: three 9-minute lock timeouts behind a legitimately progressing holder. CI on 606046e96a: 35 check runs completed, 33 success and 2 skipped. TypeScript Type Check (which runs the generated-artifact gates), Test Core 1-6/6, Lint & Repo Gates, Build Core, Dogfood Regression Gate, Temporal Conformance and Governed Surface Queue Guard are all success. Earlier-round evidence stands unchanged: the ablation (11 of 29 red with the tombstone removed) and the full platform-objects and metadata-protocol suites at a3f8054dcc.", "gates": "dispatch-gates --repo objectstack-ai/objectstack at 606046e96a (identical derivation to c9f81fa132): 122 derived, 114 run exit 0, 8 NOT MEASURED, 0 unrun; --ran reconciliation passed. Run and green include check:liveness, check:migration-registry, check:spec-changes, check:upgrade-guide, check:generated (at c9f81fa132), check:adr-0087-registration, check-changeset-no-major, check-empty-changeset, check:doc-authoring, check:nul-bytes, check:issue-citations, spec docblock anchors, comment-mask adoption and corpus, check:cross-package-test-inputs, check:query-options-erasure and check:slot-lookup. The changeset Clause-② line reads back as declared (no, narrowing). NOT MEASURED, with reason: check:doc-formula-expressions, check:doc-security-posture, check:docs-transcript-drift, check:skill-examples and check:lean-entry-closure lost their build prerequisites when a local turbo rebuild of spec was OOM-killed (exit 137, kernel, box at about 9.4/16 GB used) and later lock requests timed out; all green at a3f8054dcc and in CI Lint & Repo Gates at 606046e96a. check:i18n (CLI closure prerequisite; no bundle or form touched since baa383008b, where it was green), check:dual-build-cjs-loads (full workspace build), check:type-check-debt (repo-wide re-measure exceeds the foreground cap). Lock: slot issue-20301-dev was parked and reused, never stale; no lock file was touched by hand.", "line_budget": "n/a (this round edits no skills/** file)", "deviations": [ "Local spec dist in the worktree lost its .d.ts files when the OOM-killed turbo rebuild wiped it mid-DTS (its .build-input-hash-dts stamp remained). It was never repaired locally because the lock could not be acquired; the worktree is removed at the end of this round, so nothing downstream reads it. CI builds fresh and is green.", "Merged main a second time (606046e96a) because the PR went dirty again during this round (#20353 RLS tags retirement): same conflict class, same rule.", "The at-tier FAIL did not name the 'rehydration parse' sentence, but its measurement (the read seams do not parse) made it false, so it was corrected in the same round." ], "files_changed": [ ".changeset/list-view-tabs-retired.md", "packages/spec/src/ui/view.zod.ts (tombstone docblock only)", "packages/spec/src/migrations/entries/retired-keys/18.ui__ListView__tabs.ts", "packages/spec/src/migrations/entries/retired-keys/18.ui__ObjectListView__tabs.ts", "packages/spec/src/conversions/registry.ts (docblock + merge resolutions)", "packages/spec/src/migrations/registry.ts (step-18 rationale + merge resolutions + regenerated regions)", "packages/spec/liveness/view.json (note)", "packages/spec/src/ui/view-list-tabs-retirement.test.ts (header)", "content/docs/references/data/object.mdx (regenerated on the merged tree)" ], "mcp_calls": "0", "api_writes": "2 REST writes this round, both through the fleet-write relay as objectstack-fleet[bot]: PATCH /repos/objectstack-ai/objectstack/issues/20357 (issue_patch, PR body, run 36397835173, read back identical bar the trailing newline); POST /repos/objectstack-ai/objectstack/issues/20301/comments (this os-dev-report). 2 git pushes (c9f81fa132 with its merge and regeneration; then 606046e96a). Reads: the order and review comments, PR state, check-runs, and body readbacks.", "open_questions": [], "out_of_scope_findings": [ "class: none (measured live; the review's premise does not hold) · reach: GET /api/v1/meta/page/{name} with a request locale, rest-server.ts translateMetaItem, then translateMetadataDocument (rest-server.ts:3786), then translatePage, translateInterfaceTabs (i18n-resolver.ts:2100) and lookupTabLabel, which reads objects.{object}._tabs.{tab}.label (i18n-resolver.ts:513) · evidence: the `_tabs` slot (translation.zod.ts:385) is addressed by a PAGE list's `interfaceConfig.userFilters.tabs[].name`, object-scoped by `interfaceConfig.source` or the page's `object`, never by a list view's own `tabs`, so this retirement does not orphan it. Writers in objectstack: the CLI extractor emits objects.{o}._tabs.{tab}.label from every page's userFilters.tabs (packages/cli/src/utils/i18n-extract.ts:989-1030, run by `os i18n extract`), and the showcase bundle authors four `_tabs` entries for task-triage.page.ts (examples/app-showcase/src/system/translations/index.ts:520). Readers in objectstack: that server-side page translation, and lint validate-translation-references (anchors each `_tabs` key against page userFilters.tabs, validate-translation-references.ts:1086 and 1493). objectui at pin f8a9d0fb and at its local HEAD (2026-09-27): no production `_tabs` or resolveTabLabel reader (the console receives server-translated labels and TabFilters draws them; one test file only). objectstack-i18n/SKILL.md:166 ('Filter-preset tab label (ViewTabSchema.name)') teaches a live key; it could say page-only, but it is not false. Residual staleness: i18n-resolver.ts:2086-2091 still describes `ListViewSchema.tabs` as a carrier nothing reads, now retired. Dedupe words: _tabs translation slot, resolveTabLabel, translateInterfaceTabs, userFilters.tabs label", "class: none (boundary answer) · lint validate-capability-references.ts:186 `rec.tabs` walks app nodes only (stack.apps[*] down navigation/areas/tabs/children/items) and never reaches a list view; stated in the PR body.", "carried from earlier rounds (unchanged): the dead author-time list-view `tabs` walks (lint checkTabs, metadata-protocol computeViewReferenceDiagnostics); the objectui pin-bump type-mirror row; `object` no longer a view-reference source." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsACCEPT (stage 1, Tier H) — PR #20357 at head
606046e96a·domain:specseat 2 (session_01QcAS3qiYYZNezaxZxaUdMV) · 2026-09-28T08:47ZSeat review against GitHub, not the report:
- Shape:
Part of #20301(stage 1:list.tabs; the view container's bodynamewaits for cloud's writer). A standaloneClause-②: no (narrowing)line,minorBREAKING, and anadr-0087: registered view-list-tabs-removed, list-view-tabs-retiredmarker. 29 files, +1039/−244. - Tier H: the diff hand-edits the governed, published skill
skills/objectstack-ui/rules/list-views.md(309 → 302 lines), so this PR lands only by a human merge. The seat does not ready, enqueue or auto-merge it. The maintainer hand-off (theneeds-user-decisionlabel on the PR, the final 维护者速读 comment, and review requests to both authorized approvers) follows the merge round below. - Delivered: triage
5859554364, RETIRE under the [Decision] Route declared≠enforced work by the SEAM, not the layer — aSeam:line on filing, vertical dispatch by default in the spec lane, automatic parent + sub-issues for spec↔objectui seams, Journey as a filter, bulk retirement per spec family, Console Pin Gate back to required (the maintainer's 「同意」 on the five-line batch, 2026-09-18) #18900 criterion.retiredKey()inListViewShapeSchemarefusestabsat all seven list-view doors, as a tsc error and at parse, with thelistViews/ViewTabBarprescription.- D2
view-list-tabs-removedstrips it losslessly overstack.views[]. The declared boundary is objectlistViews, which refuse on their next save. - The D3 entry is in form D.
- The published skill no longer teaches the key.
- Four consumer pins moved to the truth.
- At-tier contract review:
- round 1 FAIL
5864267561ata3f8054dcc, on two false prose claims; - REWORK round 1
5864276781; - round 2 PASS 116/116
5866560959at this head:- both corrected claims hold at every site;
- the "rehydration parse" sentence is corrected to the measured truth;
- the refusal, D2 and D3 are re-verified after two main merges;
- the merged hand-written tails keep both sides;
- the skills hunk is true;
minorBREAKING is correct.
- round 1 FAIL
- Out-of-scope findings:
objects.*._tabsis not orphaned. The dev measured a live writer (os i18n extractfrom pageuserFilters.tabs) and a live reader (i18n-resolver.tslookupTabLabel), and the review confirmed both, so the round-1 reviewer's premise does not hold.dropped — the key is live.packages/spec/src/system/i18n-resolver.ts:2086-2091still describesListViewSchema.tabsas a secondViewTabSchemacarrier, a stale comment.carrier:spec(ui): retirelist.tabsand the view container's bodyname(2 keys);listViews+ ViewTabBar and the row name already deliver both #20301 stage 2 (the sameview.zod.tsfamily), so this reviewed head does not move for it.- The dead author-time list-view
tabswalks (lintcheckTabs, metadata-protocolview?.tabs) and objectui'stabs?: ListViewSchema['tabs']mirror.carrier:spec(ui): retirelist.tabsand the view container's bodyname(2 keys);listViews+ ViewTabBar and the row name already deliver both #20301 stage 2 and the next objectui pin bump.
- Merge round: the PR reads
dirtyagainstorigin/main2c310705f7. The conflicts are the hand-written tails inconversions/registry.tsandmigrations/registry.tsagainst feat(spec)!: retire action.aria — no action renderer ever applied it (ADR-0049) #20398 (action-aria-removed). One merge-only round is ordered now, so the maintainer receives a mergeable PR. The seat checks its delta mechanically.
- Shape:
18 remaining items
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 (stage 2 of a staged card: the view container's body
name)
Session:session_01YDt3PzwfrkuFzUBF89WPmM
Account:os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-20301-view-container-name-retired
Worktree:objectstack-issue-20301
Domain:domain:spec
Seat:domain:spec#2
File surface:packages/spec/src/ui/view.zod.ts: the containername(:4748on1d0600bf66) and its comment block, as aretiredKeytombstone with a prescription.- The retirement kit: an ADR-0087 D2 conversion or D3 entry, the generated region of
migrations/registry.ts(generator only),liveness/view.json(the row staysdead, as for every tombstone), and the regenerated reference pages. - The in-repo writers that send a body
nameon a view container (the metadata-validation sweep named on the card, and any write path the measurement finds) are fixed in the same PR. - The carried notes from
5870707479: the stalei18n-resolver.ts:2086-2091comment; the unreachable list-viewtabswalks (lintcheckTabs, metadata-protocolview?.tabs) and their fixtures. - One
.changeset/20301-*.md. - ⛔ Not
:5522(flattenedViewOverlayFields'name, stamped by the write path on a single inline view, a different key). ⛔ No objectui edit. - Stop on breach and explain in the report.
Container & model:
M,mode:subagent,model: opus(dispatch-gates --tierat1d0600bf66: no path-derived mandate; floor sonnet · default opus · ceilingCONTRACT_REVIEW_TIER). The at-tier contract review is owed and runs as a separate isolated subagent after the PR opens.
Clause-②: yes (narrowing)
Thread-read: 5925985857
Serial constraints cleared:- At 2026-10-02T12:37Z, 10 open PRs were read. PR docs: comments outside driver-memory name what replaced the retired reference matcher (#20822 group 4) #21395 (
domain:engine) editsview.zod.tsat:602only, which is disjoint. - PR feat(automation): a flow's credentials live in a write-only channel on the secret seam, not in its stored definition (#20790) #21377 (security(flows): move a flow's inbound-hook secret out of flow metadata into the write-only secret seam #7799 established — no read, the generic data door included, returns it #20790) edits
metadata-protocol/src/protocol.tsand siblings. If the writer fix lands there, the second to land mergesmain. - PR fix(analytics)!: a query window outside the non-negative integers is refused at the door, and an offset with no limit runs on SQLite #21399 (analytics: a query window with no single answer across drivers (negative or fractional limit or offset, or an offset with no limit) answers 500 on the native face and a slice on the ObjectQL face; AnalyticsQuerySchema admits all of them #21365) and this seat's ai:
guardrails,memory,structuredOutput,lifecycleandtool.outputSchemaare enforced by the agent runtime (5 keys), starting with the guardrails the built-in agents already declare #20274 memory PR writemigrations/registry.ts(and ai:guardrails,memory,structuredOutput,lifecycleandtool.outputSchemaare enforced by the agent runtime (5 keys), starting with the guardrails the built-in agents already declare #20274conversions/registry.ts). The second to land regenerates throughscripts/pm/os-regen-merge.sh. - Verify-lock depth 1.
Premise, re-measured at claim time (as the landing record
5870707479orders):- Cloud's writer does not send it: the
repo:cloud#1reading5925985857at cloud72b8415afound no top-levelnameinservice-ai's view artifacts. ⚠️ The declaration's own comment (view.zod.ts:4741–:4746) says the containernamewas declared because "undeclared, they were stripped, and the metadata door quietly discarded an item's own name on the way through" (未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 batch 5). So the dispatch measures every in-repo and objectui writer and reader of a bodynamebefore any tombstone, and returns here, without building, if the platform's own door still writes it.
Seat terms: p3, under the maintainer's 「p3 的卡也可以派了」 (
5952442849).This PR is
Fixes #20301, closing stage 2, the card's last.
Generated by Claude Code
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20301, "status": "needs_decision", "branch": "claude/issue-20301-view-container-name-retired", "pr": null, "session": "session_01YDt3PzwfrkuFzUBF89WPmM (mode:subagent, the PM's session; identity is the branch named by claim 5952493523, which is the newest Claim: on the card and names this branch)", "premise_still_valid": false, "summary": "STOPPED at the A2 stop condition, before any tombstone. Nothing was written to the tree. The metadata door itself writes a view container's body `name`. `saveMetaItem` runs `normalizeViewMetadata` (packages/metadata-protocol/src/protocol.ts:1220, stamp at :1227, call at :17256) before the schema gate, and it stamps the save name onto every view body that has none, containers included. A container saved with no name is stored as `{ list, name: 'crm_lead' }`, the by-name read serves that `name` back, and a GET then PUT round trip sends it and is accepted today. The door's own overlay identity paths also READ the body copy. `hydrateOverlayIntoRegistry` (:15990) does not register, or expand, a body that has no `name`. `mergePackageAwareOverlay` (:1835) skips an overlay row with no body `name` and keys its slot by `body.name`. The ObjectQL boot loop (engine.ts:7010) mints `name` onto every stack container it registers. With the tombstone in place, every container save through the door would 422 on the name the door itself stamped. The precondition that the landing record set (`the platform's own writers stop sending a body name`) does not hold, and the card's premise (a `dead` body copy that nobody reads) is false at 1d0600bf66. Two smaller corrections: the metadata-validation sweep does not author a body `name` (the door stamps it), and a 2026-09-03 maintainer ruling refused exactly this spec-level forbid (direction 3). The PM returns to the card; options and the four axes are in open_questions.", "tests": "All runs are at worktree HEAD 1d0600bf66 (== BASE, no commits). (1) Build closure: `OS_SKIP_DTS=1 bash scripts/pm/os-verify-lock.sh -c \"pnpm --workspace-concurrency=2 --filter '@objectstack/metadata-protocol^...' build\"` -> `VERDICT command-exit 0 · held the lock 63s`. (2) The pin on main that records the door's stamp: `pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/view-container-runtime-expansion.test.ts` -> `Test Files 1 passed (1) / Tests 16 passed (16)`, `VERDICT command-exit 0`. Its case at :252 asserts that the stored row of a nameless container equals `{ ...leadContainer, name: 'crm_lead' }`, with the comment `plus the name the write door has always stamped`. (3) Probe A2(a)/(b): a temporary file, src/zz-probe-20301.test.ts, built on that file's stub engine, run, then deleted. Output: `PROBE stored body keys: list,name name= crm_lead` / `PROBE served body keys: _diagnostics,list,name name= crm_lead` / `PROBE registry container key present: true registered name= crm_lead` / `PROBE GET->PUT round-trip success: true sent body has name: true` / `PROBE hydrateOverlayIntoRegistry(nameless) = false ; with name = true`; `Tests 1 passed`, `VERDICT command-exit 0`. (4) Probe: a body name that differs from the row name, at the runtime door. Temporary file src/zz-probe2-20301.test.ts, deleted after the run. Output: `PROBE2 save error: none` / `PROBE2 rows: crm_lead -> body.name=lead_views` / `PROBE2 registry keys: lead_views,crm_lead.default` / `PROBE2 list names: crm_lead.default`; `VERDICT command-exit 0`. After each deletion `git status --porcelain` printed nothing. (5) Census A2(e) with the TypeScript AST. It finds object literals with a top-level list/form/listViews/formViews and no viewKind/type key, passed to defineView(...), in a `views: [...]` array, or in a View-typed declaration. examples/** + packages/platform-objects (260 files): `containers 10, withName 0`. packages/** production sources (2853 files): `containers 27, withName 0, withObject 24` (control: the key detector reads keys). packages/** including tests (7359 files): `containers 227, withName 90` (lit control: the name detector fires; all 90 are test fixtures). (6) `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` -> exit 2, `this branch changes nothing against 'origin/main' (merge base 1d0600bf6) — nothing to derive`. No ablation and no reverse verification: no implementation exists to verify.", "mcp_calls": "0", "api_writes": "1 — POST issues/20301/comments (this os-dev-report), through scripts/pm/post-stamped.mjs over the fleet-write relay. Reads were REST GET only (the card and its comments, PR #15319, comment 5520462984 -> 404).", "gates": [ "dispatch-gates --commands: exit 2, `this branch changes nothing against 'origin/main' (merge base 1d0600bf6) — nothing to derive`", "Zone gates (spec build/check:generated/check:liveness/test/typecheck, consumer suites, check:adr-0087-registration, changeset gates, check:doc-authoring, check:nul-bytes): NOT RUN, reason: stopped at A2 before any edit, so there is no diff to gate", "verify-lock runs: build closure VERDICT command-exit 0; view-container-runtime-expansion.test.ts VERDICT command-exit 0 (16/16); probe 1 VERDICT command-exit 0; probe 2 VERDICT command-exit 0" ], "line_budget": "n/a — no diff; no skills/** or governed file touched", "files_changed": "none committed. Two temporary probe files were created and deleted in the worktree (packages/metadata-protocol/src/zz-probe-20301.test.ts, zz-probe2-20301.test.ts); the tree reads clean.", "semver": "none — no changeset written, because the stop came before the kit. The A5 level (minor + BREAKING + ADR-0087 marker) was not exercised, and no changeset gate judged anything.", "deviations": [ "The empty branch was pushed per os-dev rule 1 (the write probe) before the A2 stop. origin/claude/issue-20301-view-container-name-retired exists at 1d0600bf66 with zero commits of its own, and no PR is open. The seat may delete it or reuse it.", "Zone 1 conflict, reported and not resolved: Zone 1 rules RETIRE for the container `name`. The merged PR #15319 records a maintainer ruling of 2026-09-03 (direction 2 adopted) that explicitly refused `direction 3 (forbid ViewSchema.name on object-scoped containers in spec)`. The PR body says so at its changeset paragraph (`forbidding ViewSchema.name in spec was direction 3, explicitly refused`), and the header of packages/objectql/src/view-container-divergent-name-registrars.test.ts says the same. A tombstone is a superset of direction 3. The ruling comment itself (5520462984, on #14666) answers 404 from this session, so its own text is NOT MEASURED; the PR body and the test header are the surviving records.", "Zone 2 A2(d) falsified: the metadata-validation sweep does not author a body `name`. Its view fixture (packages/objectql/src/metadata-validation-sweep.test.ts:164-178) is a nameless container, and `runOne` passes `name: fx.valid.name ?? 'sweep_view'` as the REQUEST name (:392). The door's `normalizeViewMetadata` then stamps it. There is no in-repo writer to `fix` short of the door.", "A4 carried notes NOT executed (under the stop, the budget is the report comment only). Locations re-measured at 1d0600bf66: the stale ListView-tabs comment is now packages/spec/src/system/i18n-resolver.ts:2355-2361 (it still says `ListViewSchema.tabs (multi-tab view interface)` is a live carrier); lint `checkTabs` is packages/lint/src/validate-list-view-field-refs.ts:786-799; metadata-protocol `view?.tabs` is packages/metadata-protocol/src/metadata-diagnostics.ts:231. These three do not depend on the container `name` and could ride a separate small PR if the seat wants them.", "History questions (when the sweep fixture lost its `name`, when the stamp was added) are NOT MEASURED. The checkout is shallow (`--is-shallow-repository` = true), and the stop does not need them." ], "a2_census": { "a_door_write": "WRITES. packages/metadata-protocol/src/protocol.ts `normalizeViewMetadata` (:1220; `return { ...it, ...(it.name ? undefined : { name: saveName }), ...patch }` at :1227) is called inside `ObjectStackProtocolImplementation.saveMetaItem` at :17256, ahead of the schema gate. For a view `projectStorableViewBody` keeps every key the body carried, so the stamped `name` is persisted. `SysMetadataRepository.put` (sys-metadata-repository.ts:638-640) writes the body verbatim and the row name to the `name` column. Measured: probe 1 stored keys `list,name`. Pinned on main: view-container-runtime-expansion.test.ts:252. The doors that call it do not inject a name: REST PUT /meta/:type/:name (rest-server.ts:7097-7125, request built field by field) and the dispatcher door (runtime/src/domains/meta.ts:1424).", "b_read_path": "SERVES AND ROUND-TRIPS IT. `getMetaItem` step 1 serves the stored overlay body, which carries the stamped `name`. Probe 1: served keys `_diagnostics,list,name`, and GET then PUT of that body returns success true while sending `name`. Step 3 (SchemaRegistry) serves the boot loop's copy, and packages/objectql/src/engine.ts `registerMetadataCollections` :7010 `toRegister = item.name === itemName ? item : { ...item, name: itemName }` mints `name` onto every stack container it registers. That half is a code read, and PR #15319's body states the same (`the boot loop's minting of a derived name onto a container that carries none`); it was not driven. The artifact/HMR loader (packages/metadata/src/plugin.ts:1167-1200 `_registerArtifactBodyCollections`) registers a container as authored, with no mint.", "door_readers_of_the_body_copy": "protocol.ts `hydrateOverlayIntoRegistry` :15990 (`!('name' in data)) return false` — no registry entry and no `hydrateExpandedViewItems`; probe 1 measured false without a name, true with one) · protocol.ts `mergePackageAwareOverlay` :1835 (overlay row skipped without a body `name`; slot keyed by `body.name`) · protocol.ts `expandRuntimeViewContainer` :16064 and packages/metadata/src/view-container.ts `deriveViewContainerObject` :81 (`name` is the last-resort object binding) · packages/objectql/src/view-container-name-refusal.ts `viewContainerNameRefusal` plus the artifact door's `assertMetadataRegisterContract` (both refuse a divergent container `name`). The ledger row packages/spec/liveness/view.json `name` (status dead, verifiedAt 2026-08-10, `a copy nobody reads`) is therefore falsified by measurement.", "c_objectui_at_pin_89cad75d55": "No objectui writer AUTHORS a container body `name`. Studio's view create path emits a ViewItem whose `name` is the qualified id (packages/app-shell/src/views/metadata-admin/anchors.ts:291 `createBuildBody`), a ViewItem key and not the container key. Studio's view list drops containers (packages/app-shell/src/services/builtinComponents.tsx:232 `listFilter: (item) => !isAggregatedViewContainer(item)`). The generic editor's edit mode PUTs the served body back (`{ ...current, ...partial }`, clientValidation.ts:635 comment), so a container opened by direct URL would round-trip the server-served `name`; that is the server's write echoed, not an objectui writer. The adapter `updateView` (packages/data-objectstack/src/index.ts:5864) unwraps `current.list` from a container and writes a flattened overlay, which carries no container `name`. Read from the local objectui clone at the pin commit (git show / git grep).", "d_metadata_validation_sweep": "Not a writer. packages/objectql/src/metadata-validation-sweep.test.ts:164-178: the view fixture has no body `name`; :392 passes `name: fx.valid.name ?? 'sweep_' + type` as the request name, and the door stamps it into the body (a_door_write).", "e_examples_and_platform_objects": "examples/** + packages/platform-objects: 10 containers, 0 author `name`. packages/** production sources: 27 containers, 0 `name` (24 carry `object`, the control). Authored container `name`s exist only in test fixtures (90 of 227 across packages/** tests: cli, lint and others). Cloud: reading 5925985857 (not re-measured) finds no `name` in service-ai's view artifacts." }, "open_questions": [ { "question": "The view container's body `name` is written by the platform's own metadata door (`normalizeViewMetadata` stamps it on every view save), served back by the by-name read, and read by the door's overlay identity paths (`hydrateOverlayIntoRegistry`, `mergePackageAwareOverlay`). The A2 stop fired, and a 2026-09-03 maintainer ruling refused forbidding `ViewSchema.name` in spec (direction 3). How should stage 2 of #20301 close?", "options": [ "A — Keep the key and correct the record. Flip packages/spec/liveness/view.json `name` from dead to live, with the measured evidence: the writer `normalizeViewMetadata` protocol.ts:1227; the readers `hydrateOverlayIntoRegistry` :15990, `mergePackageAwareOverlay` :1835 and `deriveViewContainerObject`; the boot-loop mint engine.ts:7010. Rewrite its note, regenerate the README counts, and close stage 2 (and the card) as premise falsified, with stage 1 as the card's delivered half. Cost: one ledger row plus the README count, in a small spec PR. liveness/ is in @objectstack/spec `files[]`, so the changeset rule's published-surface test applies to that PR. No tombstone, no conversion, no door change. This is consistent with the 2026-09-03 ruling.", "B — Retire anyway by moving the door's view-container identity off the body. Stop the stamp for containers (normalizeViewMetadata). Key overlay rows by the sys_metadata row column instead of `body.name` in hydrateOverlayIntoRegistry, mergePackageAwareOverlay and the other `data.name` callers. This seam is shared by EVERY overlay type, so either it becomes generic, or it becomes a view-only identity path, which is a dialect. Stop the boot loop's mint (engine.ts:7010), or strip it at serve time. Add an ADR-0087 D2 conversion stripping `name` from every stored container row: every door-saved container carries one. That is lossless when it equals the row name; the divergent case has no lossless answer, so it needs a D3 semantic entry. Then the full tombstone kit. Cost: multi-package (metadata-protocol x3 seams on the generic overlay identity path, objectql boot loop, spec kit, conversion), well beyond what the card estimated, plus a maintainer word that supersedes the 2026-09-03 refusal of direction 3.", "C — A plus enforcement: keep the key, mark it live, and make the runtime door refuse a container body `name` that differs from the save (row) name. That is the same divergence the 2026-09-03 ruling already refuses at the two SOURCE registrars. Measured open at the runtime door by probe 2: the save is accepted, the row is `crm_lead` with body name `lead_views`, and the container is registered under `lead_views`. Cost: a small metadata-protocol change plus a pin, reusing `viewContainerNameRefusal`'s judgment and words (one judge) instead of a second rule." ], "recommendation": "A, with C's divergence routed separately as the class-b finding below rather than folded in. By the four axes: (实际业务需求) measured — no author writes it (0 of 10 example containers, 0 of 27 production containers), but the platform's own door writes it on every view save and two door readers key on it, so it is the stored identity copy, not an unused authoring capability, and the RETIRE premise `a copy nobody reads` is false; (项目长远合理性) every overlay type stores `name` in its body, equal to the row (objects, dashboards, pages), so taking it off views alone makes a view-only identity dialect, and B is a re-architecture of the generic overlay identity that deserves its own card if ever; (防 AI 写错) the trap the card names (an AI writes a container `name` that does nothing) does not exist as described, because the key is not inert. The real trap is divergence (body name differs from row name), measured accepted at the runtime door, and C or the finding closes it loudly. A tombstone would make the platform 422 its own stamped writes, the exact `rejected shapes the platform itself writes` failure the schema comment at view.zod.ts:4720-4728 already records; (创业阶段不扩散) A costs one ledger row, B expands far past the card's estimate, and the maintainer's 2026-09-03 ruling already refused the spec-forbid direction. Four-axis conflict to surface: Zone 1's RETIRE verdict and the 2026-09-03 refusal of direction 3 point opposite ways on this key; this report does not pick between them, and that is for the maintainer." } ], "out_of_scope_findings": [ "class: b · Seam: spec:ViewSchema.name (packages/spec/src/ui/view.zod.ts:4748, `.describe('Item name — supplied by the metadata door; for an object-scoped container it is the object name.')`) → runtime:metadata-protocol saveMetaItem → hydrateOverlayIntoRegistry (protocol.ts:15990) / mergePackageAwareOverlay (protocol.ts:1835) · reach: the save door, measured at the protocol `saveMetaItem` seam that REST PUT /meta/view/:name and the dispatcher door call, with the stub engine of view-container-runtime-expansion.test.ts (not over HTTP): `saveMetaItem({ type: 'view', name: 'crm_lead', item: { name: 'lead_views', list: {...} } })` is accepted with no error, the row is `crm_lead`, the body name is `lead_views`, and the registry keys are `lead_views,crm_lead.default`. One document is filed under two keys. The two SOURCE registrars refuse this same document (objectql `viewContainerNameRefusal`, the artifact door `assertMetadataRegisterContract`, VALIDATION_ERROR/400) under the 2026-09-03 ruling; the third, runtime door does not. · dedupe words: `view container name divergent runtime door`, `saveMetaItem container body name row name mismatch`, `hydrateOverlayIntoRegistry body name key`, `viewContainerNameRefusal metadata door`", "carrier: the seat's stage-2 decision on this card · noted, not filed — the liveness ledger row packages/spec/liveness/view.json `name` (dead, verifiedAt 2026-08-10) is falsified by the measurements above (one door writer, two door readers). The correction rides option A or B, whichever the maintainer picks." ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsStage 2: the stop condition fired. The premise is falsified, the retirement is withdrawn, and the stage is re-scoped to a ledger correction (claim amendment)
domain:specseat 2 (session_01YDt3PzwfrkuFzUBF89WPmM), holder of claim5952493523· 2026-10-02T13:06Z. From the os-dev report5953000865, which stopped at A2 before any edit. Nothing was committed, and the branch is empty at1d0600bf66.What was measured (file, symbol and probe lines are in
5953000865):- The door writes it.
metadata-protocolnormalizeViewMetadata(protocol.ts:1227, called bysaveMetaItemat:17256, ahead of the schema gate) stamps the save name onto every view body that has none, containers included. This is pinned onmain:view-container-runtime-expansion.test.ts:252, "plus the name the write door has always stamped". - The read path serves it, and a GET then PUT round-trips it. The objectql boot loop mints it onto every stack container (
engine.ts:7010). - The door reads it.
hydrateOverlayIntoRegistry(:15990) does not register a body withoutname.mergePackageAwareOverlay(:1835) keys its slot bybody.name. - No author writes it: 0 of 10 example containers, 0 of 27 production containers. Cloud does not send it (
5925985857). objectui writes none of its own.
Why the tombstone is off, by rulings already on record:
- Triage's own guard on this key (
5859554364, note 2): "⛔ Never retire a key the platform's own writer still sends." The platform's own writer is the door itself, and the measurement found no in-repo or cloud writer the door does not cover. - The maintainer's ruling of 2026-09-03 (PR fix(objectql): the boot loop refuses a view container whose
namedisagrees with its derived object key (#14666) #15319 adopted direction 2) explicitly refused "direction 3 (forbidViewSchema.nameon object-scoped containers in spec)". This is quoted from PR fix(objectql): the boot loop refuses a view container whosenamedisagrees with its derived object key (#14666) #15319's body and the header ofobjectql/src/view-container-divergent-name-registrars.test.ts. The ruling comment itself answers 404 from here. A tombstone is a superset of direction 3. - The verdict's reason, "a body copy of the container's identity … duplicates the row name", read the copy as unused. Measured, it is the stored identity copy that two door readers key on. Per this repo's rule, the inherited verdict falls with its reason.
The stage-2 scope from this act (claim amendment; same branch
claude/issue-20301-view-container-name-retired):- Correct the ledger.
packages/spec/liveness/view.jsonname:dead→live. Cite the writer and readers above (verifiedAt, measured in-repo). The note says the key is the door-stamped identity copy, and that a divergent bodynameis refused at the two source registrars under the 2026-09-03 ruling. Regenerate the counts throughgen:liveness-counts. - The carried notes from
5870707479, re-located by the dev:- the stale
ListViewSchema.tabscomment, nowpackages/spec/src/system/i18n-resolver.ts:2355-2361; - lint
checkTabs(packages/lint/src/validate-list-view-field-refs.ts:786-799); - metadata-protocol
view?.tabs(packages/metadata-protocol/src/metadata-diagnostics.ts:231), each deleted if unreachable since stage 1, with their fixtures.
- the stale
- The release: a
patchchangeset (the ledger ships in@objectstack/spec'sfiles[]) plus each touched package.Clause-②: no.Fixes #20301: stage 1 deliveredlist.tabs, and this delivers the corrected record.
⛔ No tombstone, no conversion, no door change, no
view.zod.tskey change.Not taken:
- Taking the identity off the body (the report's option B): stop the stamp, re-key the generic overlay identity path by the row column, add a conversion for every stored container, then the kit. It supersedes a maintainer ruling and is a multi-package re-architecture nobody is pulling for. If ever wanted, it is a new card in the decision box, not this one.
- The divergence the runtime door accepts (the report's option C) is a defect of its own, filed as a card in this act and named in the next comment.
The at-tier contract review still follows the PR (
packages/spec/src/**is touched by the comment edit).
Generated by Claude Code
- The door writes it.
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsCorrection to
5953063959item 1: thenamerow staysdead; only its note is correcteddomain:specseat 2 (session_01YDt3PzwfrkuFzUBF89WPmM), holder of claim5952493523· 2026-10-02T13:08Z. A seat assumption, falsified within the hour, is corrected here on the same card.- What I wrote: flip
liveness/view.jsonnamefromdeadtolive. - Why that is wrong:
- The ledger's definition (
packages/spec/liveness/README.md:180) reads: "livemeans authoring the property changes runtime behaviour". An AUTHORED containernamerestates the registry key or contradicts it. - The contradiction is refused at the two source registrars under the 2026-09-03 ruling, whose remedy is "drop
name". - The runtime door's acceptance of a contradicting one is a defect. It is filed separately, as the next comment names.
- What the door stamps and keys on is its own identity copy, not an authored value. PR fix(cli)!: os generate binds declared metadata (--object, --flow), never the item name, and every scaffold passes validate, build and lint #21369 (merged) read the same key from its readers and reached
deadfor the same reason.os validate'sliveness-dead-propertywarning, "drop it", is correct advice for an author and for an AI.
- The ledger's definition (
- Item 1, corrected:
namestaysdead. Its note is rewritten to the measured facts: the metadata door stamps the save name into the body (normalizeViewMetadata) and its overlay paths key on that stamped copy (hydrateOverlayIntoRegistry,mergePackageAwareOverlay), which replaces the false "a copy nobody reads".- The note says why the key is not retired: the door's own writes, the 2026-09-03 refusal of direction 3, and triage's guard. It is kept on the "KEPT deliberately, exempt from enforce-or-remove" precedent the ledger already uses.
verifiedAtis updated. No status moves, sostate-countsdoes not move.
- Unchanged from
5953063959: items 2–3, the "not taken" list,Clause-②: no, apatchchangeset, andFixes #20301.
Generated by Claude Code
- What I wrote: flip
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsPointer from
domain:specseat 2 (session_01YDt3PzwfrkuFzUBF89WPmM) · 2026-10-02T13:09Z, named by5953063959and5953104466. The runtime save door's acceptance of a container bodynamethat contradicts the row name, which the two source registrars refuse under the 2026-09-03 ruling, is filed as #21412 (bare; routing and grading are triage's).
Generated by Claude Code
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20301, "status": "done", "branch": "claude/issue-20301-view-container-name-retired", "pr": "https://github.com/objectstack-ai/objectstack/pull/21423", "session": "session_01YDt3PzwfrkuFzUBF89WPmM (mode:subagent, the PM's session; identity is the branch named by claim 5952493523, re-scoped by 5953063959 as corrected by 5953104466)", "premise_still_valid": true, "summary": "Built the reduced stage-2 scope on the same branch, fast-forwarded to origin/main 6d67ad5eca, and opened draft PR #21423 (`Fixes #20301`, `Clause-②: no`). (1) liveness/view.json `name` STAYS `dead`. Only its note is rewritten to the measured facts: the door stamps the save name into the body (normalizeViewMetadata); the overlay paths key on it (hydrateOverlayIntoRegistry, mergePackageAwareOverlay); a contradicting authored value is refused at the two source registrars under the 2026-09-03 ruling and accepted at the runtime door (#21412); and the three reasons it is kept. verifiedAt is now 2026-10-02 and evidenceScope stays cross-repo, with ViewPreview re-read at the pin 89cad75d55. gen:liveness-counts rewrote 0 shards. (2) The carried notes: the stale i18n-resolver comment is corrected; the unreachable list-view `tabs` reads in lint (`checkTabs(listView.tabs, ...)`) and in metadata-protocol `computeViewReferenceDiagnostics` (`view?.tabs`) are deleted with their fixtures, and each keeps its userFilters.tabs walk; the stage-1 absence pin's self-expiring RESIDUE drops the two fixture files. (3) Three patch changesets: spec, lint, metadata-protocol. No tombstone, conversion, door change or view.zod.ts edit.", "tests": "All at HEAD 7ee481ef2d (base 6d67ad5eca); every os-verify-lock line reads `VERDICT command-exit 0` unless stated. Build: `pnpm --workspace-concurrency=2 --filter '@objectstack/objectql^...' build` (with declarations, held 267s). Spec: `check:generated` -> `✓ All 15 generated artifacts are up to date`; `typecheck` exit 0 (`SPEC_GENERATED_EXIT=0 SPEC_TYPECHECK_EXIT=0`); `check:liveness` exit 0, `✓ packages/spec/liveness/state-counts/ is current`; `gen:liveness-counts` -> `0 shard(s) rewritten, 0 pruned`, totals `988 live · 3 experimental · 1 live-elsewhere · 109 dead · 10 planned = 1111` (no status moved); `test` -> `Test Files 600 passed (600) / Tests 17601 passed | 1 todo`, including view-list-tabs-retirement.test.ts with RESIDUE reduced to the CLI file. Lint: `test && typecheck` -> `Test Files 119 passed (119) / Tests 5574 passed (5574)`, `check:test-typecheck: OK`. metadata-protocol: `exec vitest run --maxWorkers=2 && typecheck` -> `Test Files 201 passed | 3 skipped (204) / Tests 2983 passed | 19 skipped (3002)`. objectql (test file only): `exec vitest run --maxWorkers=2 src/metadata-diagnostics.test.ts src/view-container-divergent-name-registrars.test.ts src/metadata-validation-sweep.test.ts && typecheck && build` -> `Test Files 3 passed / Tests 23 passed`, `check:test-typecheck: OK`. Derived gates: `dispatch-gates --commands` listed 91; each was run with its exit recorded before any pipe; `--ran` -> `✓ dispatch-gates --ran: 91 derived famil(ies) accounted for — 90 run, 1 NOT-MEASURED`. No ablation: this is a deletion of reads that are unreachable on parsed input, not a new guard.", "mcp_calls": "0", "api_writes": "4 across both rounds — POST issues/20301/comments (the A2-stop report 5953000865, via post-stamped over the relay); POST repos/objectstack-ai/objectstack/pulls (pr_create, draft forced, via with-fleet.sh --via dispatch, relay run 37019721873; read-back 7882 bytes sent, 7882 stored, identical); POST issues/21423/assignees os-tesla (label-write.mjs over the relay, run 37019851709; read-back MATCHES); POST issues/20301/comments (this report). git push is not counted. No label was added by me.", "gates": [ "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 — `✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (3 non-breaking changeset(s) seen).`", "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 — `✓ This diff introduces no major bump.`", "node scripts/check-empty-changeset.mjs --base origin/main :: exit 0; pnpm check:changeset-gate-self-tests :: exit 0", "pnpm check:doc-authoring :: exit 0; pnpm check:nul-bytes :: exit 0; pnpm check:cross-package-test-inputs :: exit 0", "pnpm --filter @objectstack/spec run check:liveness / check:api-surface / check:authorable-surface / check:docs / check:variant-docs / check:empty-state / check:exported-any / check:dual-source-exports / check:skill-refs / check:strictness-ledger / check:objectui-pin-citations (+8 more spec check:*) :: all exit 0", "pnpm check:lean-entry-closure :: first exit 3 (PREREQUISITE NOT MET: objectql dist absent), re-run after building objectql :: exit 0 — `✓ check-lean-entry-closure: 2 published condition(s) measured from a real load ... Admitted set held exactly (15 packages)`", "NOT MEASURED: pnpm check:dual-build-cjs-loads :: exit 3, reason: PREREQUISITE NOT MET — it loads every package's built dist and this run built only the objectql closure (`Run pnpm build first. This is NOT a pass: nothing was measured.`)", "NOT MEASURED: node scripts/check-engine-split-ratio.mjs --days 90 :: exit 2, reason: the shallow clone's oldest visible commit (2026-09-18) sits inside the 90-day window (`cannot compute the ADR-0076 D7 trigger metric`). The --ran tally counts this line as run; it measured nothing.", "All other 82 derived commands :: exit 0 (record: ran.list reconciled by --ran)", "CI at the PR head: in_progress when this report was written (Test Core 1-6, Dogfood 1-3, Temporal Conformance running; Build Docs and Console Pin Gate skipped). Not waited on." ], "line_budget": "n/a — no skills/** or governed surface touched; diff is 11 files, +88 / -59.", "files_changed": [ ".changeset/20301-spec-view-container-name-ledger-note.md (new, @objectstack/spec patch)", ".changeset/20301-lint-list-view-tabs-walk-deleted.md (new, @objectstack/lint patch)", ".changeset/20301-metadata-protocol-list-view-tabs-walk-deleted.md (new, @objectstack/metadata-protocol patch)", "packages/spec/liveness/view.json (name note + verifiedAt; list.tabs note's follow-up sentence)", "packages/spec/liveness/README.md (view cell's name sentence)", "packages/spec/src/system/i18n-resolver.ts (comment only)", "packages/spec/src/ui/view-list-tabs-retirement.test.ts (RESIDUE drops the two deleted fixtures)", "packages/lint/src/validate-list-view-field-refs.ts (list.tabs call deleted; header prose)", "packages/lint/src/validate-list-view-field-refs.test.ts (list.tabs fixtures and HARD_CODED_FILTER_WALKS row deleted)", "packages/metadata-protocol/src/metadata-diagnostics.ts (view?.tabs read deleted)", "packages/objectql/src/metadata-diagnostics.test.ts (list.tabs fixtures deleted; the deleted-read case now asserts the surviving userFilters.tabs read)" ], "semver": "patch x3 (@objectstack/spec, @objectstack/lint, @objectstack/metadata-protocol). Each changeset carries `Clause-②: no`, matching the PR body's second line. No ADR-0087 marker is owed, because there is no breaking changeset. Gate lines: `✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (3 non-breaking changeset(s) seen).` and `✓ This diff introduces no major bump.` objectql gets no changeset: test-only change, and its files[] is dist/README/CHANGELOG.", "deviations": [ "Scope reading: besides the name note, I corrected two neighbouring ledger sentences that carry the same false claims. The README `view` cell said `the platform's own writers send name (artifact-shipped containers, the metadata-validation sweep)`. The list.tabs row's note said the two walks `are left for their own follow-up`. The spec-property-retirement skill's correction rule requires the README row to follow a ledger correction. Both are prose; no status changed.", "lint header prose that listed `tabs[].filter` and `tabs[].view` as walked positions, and the lint test's comments that counted `three` hard-coded walks, were updated to match the deletion.", "The objectql case `flags tab filter rules pointing at unknown fields` was converted, not just deleted. It now asserts the same unknown field on the surviving `userFilters.tabs` read, which had no negative case in that file.", "Not merged with origin/main (declared narrowing). ceb4a939b4 is 7 commits ahead of base 6d67ad5eca, and `git diff --stat 6d67ad5eca ceb4a939b4` over the 11 paths is empty; CI's merge ref judges the combination.", "`default PR labels` was read through os-dev's label rule (named labels + skip-changeset by its criterion): no label was named and skip-changeset does not apply (three changesets), so my label-write carried only `--assign os-tesla`. The automation's path/size labels (documentation, size/m, tests, tooling, protocol:ui, protocol:system) were already on the PR at read-back; I wrote none of them.", "Commit trailers: the model-free pair (`Claude-Session` + `Co-authored-by: Claude`) per AGENTS.md and the pre-push hook, not the harness reminder's model-named `Co-Authored-By` line; neither commit names a card.", "The worktree was removed after the PR opened (node_modules deleted, `git worktree remove` without --force, exit 0)." ], "open_questions": [], "out_of_scope_findings": [ "carrier: the next PR that touches the ViewSchema guidance block, else none · noted, not filed — packages/spec/src/ui/view.zod.ts, about lines 4720-4728 (the comment above `guidance:` in ViewSchema), still says `saveMetaItem sends the name, artifact-shipped containers do (service-ai/ai_traces), the validation sweep injects it`. Measured: only the door's stamp is real. It is the same misattribution this PR corrects in the ledger, left in place by this stage's no-view.zod.ts scope. Also in the PR's Acceptance notes.", "carrier: objectui's next pin bump · noted, not filed — objectui's `tabs?: ListViewSchema['tabs']` mirror (types objectql.ts) is objectui's, as carried from 5870707479; named in the PR's Acceptance notes." ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsACCEPT — PR #21423 @
7ee481ef(stage 2, as re-scoped)domain:specseat 2 (session_01YDt3PzwfrkuFzUBF89WPmM), holder of claim5952493523· 2026-10-02T14:51Z- Shape (read on GitHub): a draft against
main. The first line isFixes #20301, andClause-②: nosits at a line start. 11 files, +88 / −59, all inside the re-scope5953063959as corrected by5953104466. The two neighbouring ledger sentences that carried the same false claim (theREADME.mdviewcell and thelist.tabsnote's follow-up sentence) are corrected with them, by the playbook's correction rule. - Contract review: at-tier PASS
5954879465on this exact head. - CI on
7ee481ef: 32 success and 3 skipped by design (Build Docspath-filtered,Console Pin Gatewith no.objectui-shachange, and the opt-in packed-tarball smoke). - Governed surface:
check-governed-merges --pr 21423reads NOT governed, 147 changed lines. - The re-scope, item by item:
liveness/view.jsonnamestaysdead. Only its note is rewritten to the measured facts: the door stamps the save name into the body, the overlay paths key on that stamped copy, and an authored value restates the key or contradicts it. The note gives why the key is kept. No status moved (gen:liveness-counts: 0 shards rewritten).- Stage 1's carried residue is gone:
- the stale
i18n-resolver.tscomment is corrected; - the unreachable
list.tabsreads in lint and metadata-protocol are deleted with their fixtures, each keeping itsuserFilters.tabswalk; - the stage-1 absence pin's RESIDUE drops the two files.
- the stale
- Releases: three
patchchangesets (spec,lint,metadata-protocol). - ⛔ Not changed: no tombstone, conversion, door change or
view.zod.tskey change.
- Prose read sentence by sentence by this seat: the
namenote and the three changesets.
Out-of-scope findings:
- The comment above
ViewSchema'sguidance:(view.zod.ts, about:4720–:4728) still attributes the containernameto artifact-shipped containers and the validation sweep. → carrier: finding(metadata-protocol): the runtime save door accepts a view container whose bodynamecontradicts its row name and registers it under both keys; the two source registrars refuse the same document #21412, by pointer5954896314. That card's fix changes the runtime door's treatment of thatname, so the comment rides it. - objectui's
tabs?: ListViewSchema['tabs']mirror → carrier: the objectui lane, at its next pin bump (carried from5870707479).
Next: ready, auto-merge, the queue. On landing this card closes: stage 1 delivered
list.tabs, and stage 2 delivers the corrected record.
Generated by Claude Code
- Shape (read on GitHub): a draft against
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsLanded: PR #21423 →
bdd3654f29(stage 2, the card's last)domain:specseat 2 (session_01YDt3PzwfrkuFzUBF89WPmM), holder of claim5952493523· 2026-10-02T15:20Z- Landed: PR fix(spec,lint,metadata-protocol): correct the view container
nameledger note; delete the unreachable list-viewtabswalks #21423 went through the merge queue asbdd3654f29, with one parent (39a912ea73). This card closedcompletedby itsFixesline. - Blob check against the ACCEPTed head
7ee481ef(ACCEPT5955032582, at-tier PASS5954879465): 11 of 11 files are blob-equal. - What the card delivered, across both stages:
- Stage 1 (PR feat(spec)!: retire the list view's own
tabskey; named presets arelistViewsentries #20357,6e3e5462c6):list.tabsis retired. - Stage 2: the A2 stop showed that the container
name's retirement premise was false: the metadata door stamps it and keys on it, and the 2026-09-03 ruling refused a spec-level forbid. So the key is kept,dead, with its ledger note corrected. Stage 1's residue walks are gone.
- Stage 1 (PR feat(spec)!: retire the list view's own
- Carried elsewhere:
- finding(metadata-protocol): the runtime save door accepts a view container whose body
namecontradicts its row name and registers it under both keys; the two source registrars refuse the same document #21412: the runtime door accepts a contradicting containername. It also carries theview.zod.tscomment rider (5954896314). - objectui's
tabsmirror: the objectui lane's, at its next pin bump.
- finding(metadata-protocol): the runtime save door accepts a view container whose body
- State:
pm:dispatchedis removed in this act. Domain, area and type labels stay.
Generated by Claude Code
- Landed: PR fix(spec,lint,metadata-protocol): correct the view container
- added 2 commits that reference this issue
on Oct 7, 2026
Filing gate: ① a declared≠enforced family, filed as one sweep card per family under ruling A′ item ④ on #18900 (
5727134555). This is triage's standing request5857165909on the seat post. Familyview-duplicates, seat verdict RETIRE.reach:the declared authoring door.packages/specparses these keys and publishes them in the reference docs. The liveness ledger rows cited below record them as not enforced, and the census re-measured the reader side (§5 cross-checks, each with a lit control).Census by the
domain:specexecution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017), 2026-09-27. Bases: objectstacka9fb83ef, re-checked against4d7e740d, where no ledger file or cited surface moved; objectui6fa5f64a1(pinf8a9d0fb); cloud96eb092. Ledger instrument:check-liveness.mts --json, whosebyStatusequals the committedstate-counts.mdrow for row. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim. The ranking is by value, user-visible risk × keys. This family's rank is12of 16. The sibling family cards filed so far are #20273, #20274, #20281, #20282, #20287, #20288, #20289, #20294 and #20295.Capability: Tabs above a list view; a container identity copy
view.namepackages/spec/liveness/view.json:5view.list.tabspackages/spec/liveness/view.json:210Mainstream evidence:
listViewsentry renders as a tab in ViewTabBar (objectui app-shell ObjectView.tsx:27 imports ViewTabBar).listViews" (packages/spec/src/ui/view.zod.ts:4524).Verdict: RETIRE — the mainstream lacks it, or it duplicates a capability already delivered here; one batch for the family.
Reader that must exist / disposition: none; this is a retirement.⚠️ view.name: the platform's own writers send it (cloud service-ai ai_traces container, the metadata-validation sweep), so the retirement must fix those writers in the same landing.
User-visible risk (2):
list.tabsdraws nothing because TabBar has zero production mounts (objectui origin/main). hotcrm carries a test asserting it is inert (#16094).Acceptance: Every key listed is retired by the spec-property-retirement route: a retiredKey tombstone with its prescription (the ledger row STAYS, status dead, as for every tombstone), an ADR-0087 D2 conversion or D3 entry, docs regenerated; authoring the key becomes a tsc + parse error; pnpm check:liveness green.
Lane: domain:spec (objectstack) + cloud writer fix for view.name
File surface: packages/spec/src/ui/view.zod.ts:2773 (ListViewShapeSchema.tabs) and the ViewSchema container
name· packages/spec/liveness/view.json · cloud service-ai ai_traces view artifactDedupe:
list\.tabs \| \bTabBar\b \| view\.name\b.{0,40}(body\|container)→ 1 open hit. None carries a key of this family:liveness-dead-propertyandliveness-live-elsewhere-propertycannot fire on 17.3.0 — 90dead+ 1live-elsewhereledger rows and not one setsauthorWarn#16094 — lint axis (authorWarn opt-in for dead rows) plus a list.tabs re-derivation already answered by spec: re-derive the liveness ledger before itsdead/live-elsewhereverdicts start warning authors —view.jsonlist.tabsre-read plus a sampled audit of the 90deadrows (ledger half of #16094) #16362 (closed); not an enforce-or-remove carrier四轴:
layout: 'inline' | 'grid'onobject-form/FormViewparse green and render asvertical— enforce-or-remove (ADR-0049) #20221 分诊的判法一致(能力已由另一个键提供 ⇒ 退役重复写法)。list.tabs和listViews,前者完全无效。退役后给出处方,指向 listViews。