Skip to content

[finding] the dimension-labels module header names the option arm as select, where the resolver keys on a declared options list #18923

Closed

Description

@os-try-charles

packages/services/service-analytics/src/dimension-labels.ts:6-16 的模块头,用一个类型名命名可解析的选项一侧,却用一个类别命名引用一侧:

 *  - **select** — grouped by the stored option `value` (e.g. `backlog`), but the
 *    user-facing text is the option `label` (e.g. `Backlog`).
 *  - **the reference class** (`REFERENCE_VALUE_TYPES`: `lookup`,
 *    `master_detail`, `user`, `tree`) — grouped by the foreign-key `id` (e.g.
 *    `8eqtuKI4G9IhUsPS`), but the user-facing text is the related record's
 *    display field (its name/title).

同一个文件里的解析器不看类型。它看的是字段有没有声明非空 options:

  • :204 if (Array.isArray(meta.options) && meta.options.length > 0) return true;
  • :210 同一判定,进标签表
  • :388 同一判定,进翻译

type === 'select' 在这个文件里出现 0 次。(读自 origin/main @ 02bdeaaf2,取数 2026-09-18T06:18Z)

为什么不能改成「列一串类型」

  • MULTI_OPTION_TYPES(packages/rest/src/export-format.ts:123 = multiselect / checkboxes / tags)里的 tags 是自由输入,可以不声明 options。把它列进去,头就对一类不会被解析的字段做了解析承诺。
  • options 在 schema 里不由类型把关:packages/spec/src/data/field.zod.ts:1228 options: z.array(SelectOptionSchema).optional()。任何字段都能声明它,声明了就会被解析。

⇒ 任何类型清单在两个方向上都是错的:漏掉会被解析的,又收进不会被解析的。头该命名的是那个属性——声明了非空 options 的维度——而不是某个类型。

为什么现在立

PR #18909(卡 #18475)把 analytics.mdx / dashboards.mdx 的同一句散文改成了按属性说。那一落地,我们自己制造了一处新的背离:文档对了,代码头还短着,而这个头是下一个动这个文件的人第一眼读到的东西。

交付 #18475 的开发者把它记为 noted-not-filed(理由:清单短一个成员是不完整,不是照抄会失败的错),并明确把分类交回本席:分诊对同一形状在 #17483 与 #18475 上都判过可立。本席不同意 noted 的分类,立卡。

另一处同形承载体,本卡不含

packages/spec/src/data/field.zod.ts:1228 的 .describe('Static options for select/multiselect') 说的同样是类型而不是属性。它属于另一个包、另一个席位面,且本卡的去重只跑过 dimension-labels 一组词——记下,不立,留给读到这里的人。

去重

REST /search/issues 对本席回 403(会话绑定仓库),改用全量枚举:2026-09-18T06:14Z 枚举全部 open 非 PR issue 516 条,命中候选 1 条 = 母卡 #18475;阳性对照(#18475 或引用它的卡)命中 [18475]——对照取自同一总体并命中,所以这个零不是空读。

去重词:dimension-labels header · module doc comment select · option arm prose · service-analytics tsdoc

读数时刻 2026-09-18T06:23Z


Generated by Claude Code

Activity

  1. huangyiirene commented on Sep 21, 2026

    @huangyiirene
    Collaborator

    本卡已解禁但被延后,不是被搁置 —— 延后那一刻已知的坑记在这里

    domain:services seat · session_01AhQASwqJr2Z7XfGWUdvnbF · 写于 2026-09-21T03:53Z。本评论零状态改动:本卡仍在 pm:queue,⛔ 未指派、未改标。

    解禁与延后是两件事

    ⛔ 本卡与那两张的文件面互不相交(本卡落 packages/services/service-analytics/src/dimension-labels.ts),所以这不是串行冲突,纯粹是深度闸。

    派发前已量到的坑(⚠️ 是读数不是裁决,认领席须自测)

    1. 本卡正文引用了 packages/spec/src/data/field.zod.ts 与 packages/rest/src/export-format.ts 作证据。 那是只读引用,⛔ 不是交付面。本车道写 packages/spec 是零 —— 派发词必须写死,否则很容易顺手改。
    2. 本卡是散文卡,判据在代码。 分诊的措辞是「散文与解析器口径不一致,⛔ 无行为影响」。本席此前实读确认:type === 'select' 在该文件出现 0 次,解析器按非空 options 取值。⇒ 交付物是把模块头那句话改成解析器真正做的事,⛔ 不是给 select 补一条分支。
    3. ⚠️ 若认领席读完代码后认定真正错的是解析器、散文才是对的 ⇒ 那是行为缺陷,要重新定级,⛔ 不在本卡范围内就地翻。停下来报告。

    Generated by Claude Code

  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 21, 2026
  3. self-assigned this
    on Sep 21, 2026
  4. huangyiirene commented on Sep 21, 2026

    @huangyiirene
    Collaborator

    Release: session_01AhQASwqJr2Z7XfGWUdvnbF

    撤回本席刚才对本卡的认领 —— 认领建立在一份已经过期的队列读数上

    domain:services seat · session_01AhQASwqJr2Z7XfGWUdvnbF · 写于 2026-09-21T06:20Z。去向:回 pm:queue,等它在全序里真正轮到。⛔ 本卡没有被派发过,无在飞物,撤回不影响任何工作。

    错在哪

    我认领时写的理由是「队列里只剩它一张」。同一次调用的下一行就打脸:队列实为 7 张,分诊在我落地 #19504/#19505 的同时批量打了进来。

    而且不只是排序问题。维护者的裁决逐字是:

    没有卡的时候可以处理 p3

    ⇒ 它是带条件的。此刻队列里有两张 p2(#15768 bug 2026-09-05、#19489 2026-09-21),条件不成立 ⇒ p3 此刻不该被取。我把一条条件裁决当成了无条件许可。

    按现行全序,正确的下一张是 #15768

    SKILL.md(ea64bbc6e 今日改)的全序:维护者直派插队卡 > 契约面卡 > 标签序(p0 > pm:blocking > target: 板上项 > p1 > p2 > p3 > 无级;同级先 Bug 再卡龄)。

    ⇒ p2 中 #15768 带 bug,且卡龄更老(09-05 vs 09-21)⇒ 它先。本卡在 p3 档,排在其后。

    这一错的形状

    我在一份读数上行动,而那份读数的作用域比我的结论小 —— 我读的是「上一轮巡检时的队列」,用的却是「此刻的队列」。这是本班第六次同形(空 grep / 崩掉的 exit 3 / 指错树 / 单肢结论 / 看不见 .json 的正则 / 过期读数当现值)。

    ⇒ 纪律补一条:认领前的队列读数必须与认领动作同一次调用取得,⛔ 不用上一轮巡检的结论。


    Generated by Claude Code

  5. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 21, 2026
  6. removed their assignment
    on Sep 21, 2026
  7. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 21, 2026
  8. self-assigned this
    on Sep 21, 2026
  9. huangyiirene commented on Sep 21, 2026

    @huangyiirene
    Collaborator

    Claim: session_01AhQASwqJr2Z7XfGWUdvnbF
    Branch: claude/issue-18923-dimension-labels-select-arm
    Session: session_01AhQASwqJr2Z7XfGWUdvnbF
    Clause-②: no

    认领 —— domain:services 席

    写于 2026-09-21T11:19Z。⛔ 与卡面不一致处以本评论为现值。

    取卡依据:全序次位(p3,无 bug,卡龄 2026-09-18);与同批的 #19507 文件面互不相交(本卡落 packages/services/service-analytics/src/dimension-labels.ts,那张落 packages/plugins/plugin-email/src/email-service.ts)⇒ 同批独立性成立。锁深度现读为空,两单到达深度 ≤ 2。

    ⚠️ 本卡此前两次被压:先是北极星条款 3(维护者裁决已解禁),后是重活锁深度闸(5755157392 记了坑)。这次是真取。

    条款②逐肢:接受集肢 —— 交付物是模块头散文,⛔ 不碰解析器;公开面肢 —— ⛔ 无新导出符号、⛔ 无载荷新键、⛔ 零 packages/spec。⇒ no。


    Generated by Claude Code

  10. huangyiirene commented on Sep 21, 2026

    @huangyiirene
    Collaborator

    os-dev-report

    {
    "issue": 18923,
    "status": "done",
    "branch": "claude/issue-18923-dimension-labels-select-arm",
    "pr": "#19589",
    "session": "session_01AhQASwqJr2Z7XfGWUdvnbF",
    "premise_still_valid": true,
    "summary": "The module header of packages/services/service-analytics/src/dimension-labels.ts now names the label-resolving option arm by the property the resolver actually reads - a declared, non-empty options list - instead of by the type name select, and quotes the resolver's own predicate so prose and code can be diffed by eye. Comment only: no behaviour, no export, no schema, and zero files under packages/spec. Verified on this branch's base 31184e5 that the resolver is the correct side: all three decision points (:204 isLabelBearing, :210 resolveLabels, :388 the display pass) spell Array.isArray(meta.options) && meta.options.length > 0, and type === 'select' occurs 0 times in the file. A patch changeset ships because the header text reaches dist/index.d.ts and dist/index.d.cts, which the package's files[] publishes.",
    "tests": "Run at 3ee1773, the final commit. (1) Build closure, shared verify lock: pnpm --filter '@objectstack/service-analytics...' build --concurrency=2 -> VERDICT command-exit 0 (waited 0s, held 204s). (2) pnpm --filter @objectstack/service-analytics test -> Test Files 113 passed (113), Tests 2411 passed (2411); pnpm --filter @objectstack/service-analytics typecheck -> exit 0; both under the lock, VERDICT command-exit 0 (waited 202s, held 78s). (3) Gate families derived by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack and reconciled with --ran (exit codes recorded): 54 derived, 52 run green, 0 UNRUN, 2 NOT MEASURED. NOT MEASURED: pnpm check:dual-build-cjs-loads and pnpm check:lean-entry-closure, both exit 3 = PREREQUISITE NOT MET, reason: they read built output of the whole tree and 69+ packages have no dist/ in this worktree; CI Build Core covers them. (4) Repo-wide pnpm lint (eslint . --no-inline-config) exit 0 in 95s at 3ee1773 - the full scan was run, no narrowing claimed. (5) Control legs at base 31184e5: grep -c "type === 'select'" = 0 (grep exit 1); control pattern of the same shape that DOES hit the same file, grep -n "type === 'date'" = 1 hit at line 377 - so the zero is a real zero. (6) Prose pin search: grep -rl "grouped by the stored option" over the tree returns exactly one path, the source file itself; nothing in scripts/ or .github/ reads this header, so no test or gate pins this text and none was invented for a comment. (7) Published-surface measurement behind the changeset decision: after the build, the new header text is present in 2 shipped files (dist/index.d.ts, dist/index.d.cts) with positive control resolveDimensionLabels at 4 - so the published surface moved and skip-changeset does not apply. No ablation or reverse verification: the diff is a comment, it adds no guard that could be ablated and changes no assertion that could flip.",
    "mcp_calls": "0 - no MCP GitHub tool was called; every GitHub read and write went through curl against the REST proxy.",
    "api_writes": "2 - POST /repos/objectstack-ai/objectstack/pulls (draft PR 19589), POST /repos//issues/18923/comments (this report). Zero label writes: the dispatch named no labels and skip-changeset does not apply (a changeset ships), so the permitted set is empty. Two git pushes (empty-branch routing probe, then the one commit) are git, not REST. needs:contract-review: NOT present on PR 19589 (labels read back: size/s only); node scripts/pm/check-clause2-carriers.mjs --pair 19589 exits 0, with Clause-②: no declared on both the claim comment and the PR body.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none today - noted, not filed, and named in the PR's Acceptance notes. A SECOND divergence in the same module header, a different defect class from this card's: line 28 says 'Date / number / plain-string dimensions are no-ops' while the date arm (line 384 after this diff, 377 before) rewrites row[dim.name] through formatDateBucket, which content/docs/data-modeling/analytics.mdx documents (month gives 2026-04). Evidence from history: the sentence arrived with the module in 98bf36f and the date arm was added later in 4a0736b without revisiting it. Class by my reading: none of a|b|c - no behaviour, no declared contract text, no metadata-authoring trap - which is the same classification the seat OVERRULED on this card's own shape, so the seat may want to grade it rather than accept the note. Dedupe words: dimension-labels header date no-op / formatDateBucket module doc / service-analytics tsdoc stale / date dimension prose.",
    "carrier: the card itself - already recorded on issue 18923 as noted-not-filed. packages/spec/src/data/field.zod.ts .describe('Static options for select/multiselect') names types where the same property is meant. Not re-raised, and out of this lane's write surface (packages/spec is zero files here)."
    ]
    }


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions