Skip to content

docs(spec): kanban.lanes TSDoc states what the board draws; checkKanbanLanes docblock names its option map - #28343

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-wo9wxu
Oct 31, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-wo9wxu

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Fixes #28319

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:kanban.lanes 的 TSDoc 去掉「看板暂不读这个键」那段过时说明,改成如实描述:只画列出的泳道、按作者写的顺序,未列出的值落进 Uncategorized,不写该键则每个选项一条泳道;lint 的 checkKanbanLanes 注释补一句:将来若扩展 groupByField 可带的内联选项,必须并入它读的选项表。
  • 为什么改:feat(ui): kanban board draws only the declared lanes, in their order #28291 合入后看板已经按 kanban.lanes 画泳道,旧说明会让读参考文档的作者(包括 AI)以为这个键没用而不去用它;写错一句给 AI 看的文档等于产品缺陷。
  • 风险与回滚:只改注释文字,不改 schema、不改行为;生成产物无变化(check:generated 全绿)。回滚即 revert 本 PR。
  • 先看:packages/spec/src/ui/view.zod.ts 中 lanes 的 TSDoc 末段;packages/lint/src/validate-list-view-field-refs.ts 中 checkKanbanLanes 的注释;.changeset/28319-kanban-lanes-tsdoc.md。
  • 两分钟验证:git grep -n "Lands ahead of its reader: the board draws one lane" origin/main -- packages/spec 在 main 上有一处命中,本分支零命中。
  • 需要你做的:无,席位落地(TSDoc 属于 spec 源码,先走契约复审)。

What changes

  • packages/spec/src/ui/view.zod.ts: the last paragraph of the KanbanConfigSchema.lanes TSDoc said the board drew one lane per option until the Console read the key. It now says what the board draws: the listed lanes and no others, in the order the author wrote them; a record whose value is not listed lands in Uncategorized; without the key, one lane per option in the options' own order. The .describe() text was checked and already says this (no "ahead of its reader" clause), so it is unchanged.
  • packages/lint/src/validate-list-view-field-refs.ts: the checkKanbanLanes docblock gains the line review rider S2 asked for: the rule reads only the option map built from inline options[].value, and a future FieldSchema key that widens the inline options a groupByField may carry must join that map, or a lane naming a widened option is reported as unknown.
  • .changeset/28319-kanban-lanes-tsdoc.md: a patch for @objectstack/spec, because the TSDoc ships in the package (dist chunks and src/**/*.zod.ts are in its files). @objectstack/lint gets no changeset entry: its built dist carries none of the edited docblock (measured below).

No schema, type, export or behaviour change.

Why

Since #28291 the board draws only the declared kanban.lanes, in order. The TSDoc still told authors, and agents reading the spec source, that the board ignores the key, so an author would not use a live key.

Tests

  • pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 validate-list-view-field-refs.test.ts: Test Files 1 passed, Tests 171 passed.
  • pnpm --filter @objectstack/spec run typecheck and pnpm --filter @objectstack/lint run typecheck: exit 0.

Verification

Local gates at head fb157ea7 (the last commit; nothing pushed after).

Derived gate families: 74 derived, 73 run green, 1 NOT MEASURED
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 74 commands against the diff (2 source files + the changeset). Each ran with stdin closed and its exit code recorded before any pipe.
  • dispatch-gates.mjs --repo objectstack-ai/objectstack --ran reconciles: "74 derived famil(ies) accounted for — 73 run, 1 NOT-MEASURED".
  • NOT MEASURED: pnpm check:dual-build-cjs-loads exits 3 (prerequisite: it needs every package's dist, a whole-workspace build; this diff changes comments only). CI runs it.
  • First attempts that exited 3 and were re-run green after their prerequisite was met: check-plugin-teardown-shape.mjs --self-test (after fetching its pinned fixture commit) and pnpm check:lean-entry-closure (after building @objectstack/objectql).
  • Doc-authoring gates named by the order: pnpm check:doc-authoring, pnpm check:issue-citations, node scripts/check-issue-citations.mjs, pnpm check:spec-docblock-symbol-anchors: all exit 0.
Generated artefacts and the order's per-card gates
  • pnpm --filter @objectstack/spec build then pnpm --filter @objectstack/spec check:generated: exit 0, every artefact up to date (including check:docs over content/docs/references/** and check:authorable-surface over the JSON schemas). The TSDoc does not reach a generated reference, so nothing was regenerated.
  • git grep for the old sentence across the tree (including content/docs) found it only in view.zod.ts.
  • node scripts/check-sdui-manifest.mjs: exit 0.
Changeset measurement (which package ships the edited text)
  • After pnpm --filter @objectstack/spec build, the new TSDoc sentence is in packages/spec/dist/chunk-*.mjs and chunk-*.js, and the old one is in no dist file; src/**/*.zod.ts also ships. So @objectstack/spec publishes it: patch.
  • After building @objectstack/lint, neither the new docblock line nor the neighbouring existing docblock sentence is in packages/lint/dist, while a message string from the same function is (positive control: is not an option of in dist/runtime.js and dist/index.cjs). So lint publishes nothing new.

Acceptance notes

  • The order also asked to check .describe() for the stale clause: it never carried one, so it is unchanged.
  • Rider S2 asked for "a note on the module docblock"; the card and the order place it on the checkKanbanLanes docblock, which is where it went. The module's kanban.lanes section is unchanged.
  • A contract review is owed (the TSDoc is spec source); the seat routes it.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm exec eslint --no-inline-config over the two edited files exits 0 (the repo-wide pnpm lint is CI's).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.
  • The Before Submitting list in CONTRIBUTING.md is done.

Generated by Claude Code

…lock names the option map

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibxLWeJZCXoRVU2rMLD
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation protocol:ui tooling labels Oct 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

2 anchor(s) derived from 2 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see
  • the SDK route bridge reached 59 of 211 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

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

Which tree this was computed on

This run read content/docs from 9209480b119e087ae317fc0d96d54a1c932764f8 — the merge of head fb157ea75512ac8c1057763339dee196c6a88a6a into base a0f865491d365d1447e45d1efd27a251e6e6c181, which is what actions/checkout gives a pull_request run. Not the PR head.

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

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 9209480b119e087ae317fc0d96d54a1c932764f8 && git checkout 9209480b119e087ae317fc0d96d54a1c932764f8
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin a0f865491d365d1447e45d1efd27a251e6e6c181 fb157ea75512ac8c1057763339dee196c6a88a6a && git checkout -B drift-repro a0f865491d365d1447e45d1efd27a251e6e6c181 && git merge --no-ff fb157ea75512ac8c1057763339dee196c6a88a6a

node scripts/docs-audit/affected-docs.mjs --json a0f865491d365d1447e45d1efd27a251e6e6c181

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

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract-review-claim: session_01L9qibw58ehQ2gRHP2h2Puz · head fb157ea75512ac8c1057763339dee196c6a88a6a · 2026-10-31T07:14Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract review

Served-tier: TIER_DEFAULT
Head-sha: fb157ea75512ac8c1057763339dee196c6a88a6a
Local-runs: none

Inputs: card #28319 (body: the two observed lines and the Wanted list; triage 6539265480 grading p2 domain:spec with the one-PR exception for the packages/lint docblock; the seat's claim 6539460810; the dev report 6539704957), PR #28343 (body, the docs-drift comment 6539707198, the file list of 3 files, the diff of 49 lines against main, the two commits from the merge-base 501c864), the 49 check-runs on this head (read 2026-10-31T07:16Z: all 49 runs completed, none failed, none cancelled, none in progress; success: Auto Label, Build & E2E UI, Build Core, Build UI Deps, Check Changeset, Check PR Size, Dogfood Regression Gate, Flag docs affected by code changes, Governed Surface Queue Guard, Lint & Repo Gates, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · scoped · tooling self-tests, Live E2E UI, PR-body guards (claim · duplicate · Part-of · single-writer path), Plan Test Core shards, Spec property liveness, Test Core, Test Core (all 8), Test UI, Type Check UI, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, TypeScript Type Check, filter; skipped: 18.x upgrade harness (opt-in), Build Docs, Dogfood Regression Gate (matrix shard/3), Dogfood Verify CLI, Lint UI, Packed-tarball smoke (opt-in), Schedule gate · skip when a green push run covers the commit, Temporal Conformance (live PG + MySQL), Test UI (matrix shard/16), UI Published Artifacts), and the tree on main for view.zod.ts (the lanes TSDoc at :2069 to :2098 and its .describe() at :2102 to :2108), validate-list-view-field-refs.ts (the optionValues map at :1060 to :1078 and checkKanbanLanes at :1080 to :1106) and ui/packages/core/src/utils/kanban-declared-lanes.ts (the #28211 producer). The head is mergeable and clean against today's main (merge-tree clean); view.zod.ts moved on main since the merge-base, in hunks the diff does not touch.

① Derived judgments

  • The new TSDoc paragraph is true of the renderer - right. Since feat(ui): kanban board draws only the declared lanes, in their order #28291 (85a1b9d8) kanbanDeclaredLanes maps the declared list onto columns in the author's order, an unlisted value falls into Uncategorized, and an absent or empty list returns undefined so the board keeps one lane per option in the options' own order. The paragraph says exactly that, and the .describe() text at :2102 already said it, so the shipped reference page does not change (docs-drift found no hand-written anchor to move; check:generated is green in Lint · docs & code guards).
  • The lint docblock line is true of the rule - right. checkKanbanLanes reads only optionValues, which is built from each field's inline options[].value and nothing else, so a future FieldSchema key that widens what groupByField may carry would report a lane naming a widened option as unknown until it joins that map. That is rider S2 of record 6528382115 on Kanban board draws only the declared lanes, in their order: ObjectKanban reads kanban.lanes #28211, placed on the function docblock as the card and the order asked.
  • Accept-set: nothing an author writes moves - right. No schema, type, export, message string or refinement changes; the diff is two comment hunks and a changeset. Clause-②: no and Metadata-protocol: none are right.
  • Check-runs as gate verdicts - read as above; every run on this head completed and none is red, cancelled or in progress at the read.

② Semver level

  • @objectstack/spec patch, no @objectstack/lint entry - accepted. The lane's precedent for a TSDoc-only change whose text ships in the built package (dist chunks and src/**/*.zod.ts are in files[]). The lint docblock is not in its built dist by the dev's measurement (a message string from the same function is, as the positive control), and this review does not re-measure it; if the lint build ever starts preserving docblocks the omission is a changeset gap, not a contract gap.

③ Boundary flags

  • Serial overlap on view.zod.ts - main moved the file after the merge-base (other keys); the merge is clean and no hunk is shared, so nothing is owed beyond the usual merge of main before landing.
  • The seat lands - domain:ui#1 holds the card under the cross-area rule; no Tier H path (no docs/adr, no skills/**, 49 lines), no human gate, no name approval owed.
  • Nothing further - the stale sentence has no other copy in the tree (the dev's git grep and this review's read of content/docs agree).

Verdict reasoning. A false sentence about a live key is replaced by the behaviour the merged producer has, matching the describe text that already ships; the lint docblock gains the one line a prior review asked for; a patch entry covers the one shipped surface; the head is clean against main and every check is green or skipped.

Implemented-by: claude/project-thread-wo9wxu
Reviewed-by: session_01L9qibw58ehQ2gRHP2h2Puz

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-tesla · session_01L9qibzC6RxMfB59EsgAoNN

席位核对

ACCEPT · seat domain:ui#1 · head fb157ea7 · 2026-10-31T07:17Z

席位意见:看板 kanban.lanes 的说明原来还写着「看板还没读这个键」,#28291 合并后这句已经不对了。现在改为说明看板实际怎么画:只画列出的泳道,按作者写的顺序,值不在列表里的记录落到「未分类」,不声明时每个选项各一列。lint 规则的注释也补了一句,提醒以后放宽选项来源时要同步更新它读的选项表。只改了注释,没有行为变化。

  1. Shape: Fixes #28319, draft, base main, 3 files, +19/−2. The KanbanConfigSchema.lanes TSDoc paragraph in packages/spec/src/ui/view.zod.ts changes; the .describe() already said this and is unchanged. One docblock line on checkKanbanLanes in packages/lint/src/validate-list-view-field-refs.ts (rider S2). A patch changeset for @objectstack/spec. Clause-②: no, Metadata-protocol: none.
  2. Seat read: the paragraph matches kanbanDeclaredLanes on main. No @objectstack/lint entry is needed: its dist carries no docblock text, and Check Changeset is green.
  3. Contract review: PASS at this head, record 6540517274 (TIER_DEFAULT), by the contract-review lane, not the drafter. No should-fix.
  4. Gates / check-runs: on fb157ea7: 39 success, 10 skipped, 0 failure. mergeable_state clean.
  5. Landing: check-governed-merges --pr 28343 reports NOT governed, 21 changed lines ≤ 3000. The seat readies the PR and arms auto-merge, on the maintainer's 「按 pm-dispatch 审过的pr你可以自主落地」 (seat thread, 2026-10-30T14:19Z). This is the seat's last cross-lane card, per the maintainer's 2026-10-31T06:04Z 「已经在处理的可以继续」.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 31, 2026 07:18
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit ef0f6a1 Oct 31, 2026
50 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-wo9wxu branch October 31, 2026 07:40
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 protocol:ui size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spec: kanban.lanes TSDoc still says the board ignores the key; lint checkKanbanLanes docblock owes its option-map line

1 participant