Skip to content

docs(analytics): key the label-resolution prose on the field carrying options, not on the select type - #18909

Merged
os-try-charles merged 1 commit into
mainfrom
claude/issue-18475-option-arm-prose
Sep 18, 2026
Merged

os-try-charles merged 1 commit into
mainfrom
claude/issue-18475-option-arm-prose

Conversation

@os-try-charles

@os-try-charles os-try-charles commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #18475

Both docs sentences named select as what makes the analytics label-resolution
option arm fire. The implementation keys on the field carrying options
instead, so a radio axis resolves its label while the docs said it did not.

The measurement

packages/services/service-analytics/src/dimension-labels.ts, read on this
branch at 84ba4a847 (identical to origin/main at dispatch):

:204  if (Array.isArray(meta.options) && meta.options.length > 0) return true;
:210  if (Array.isArray(meta.options) && meta.options.length > 0) {
:388  if (Array.isArray(meta.options) && meta.options.length > 0) {

occurrences of `type === 'select'` in that file: 0

The firing control is taken from the probed file itself and reads 0 there;
it appears nowhere in this diff, which touches only content/docs/**.

Why a property, and not a type list

The card left open whether an option-side noun exists or whether the prose
must grow a type enumeration. Two readings settle it against the enumeration:

  • options is an ordinary optional key on the field schema
    (packages/spec/src/data/field.zod.ts:1228) — it is not gated on type,
    so a field of any type that carries options enters the arm.
  • MULTI_OPTION_TYPES (packages/spec/src/data/field-value.zod.ts:145)
    includes tags, which that file documents as free-form. A tags field
    need not declare options at all.

So an enumeration would be wrong in both directions: it would over-claim on
tags and under-claim on anything else carrying options. Naming the property
the implementation names is the only formulation that matches the resolver, and
it is the same move the sibling half took — name what the implementation already
names rather than growing a list.

What this deliberately does not say

The prose states what makes the arm fire, and stops there. It does not
assert a per-type outcome — in particular it does not claim what a multi-valued
stored value resolves to. That behavioural question is named by the card as a
different question it did not measure, and it stays unmeasured here.

Scope held to the two sentences. packages/services/service-analytics/** and
every schema are untouched: the resolver accepts the wider set and is correct;
narrowing it would shrink a published accept set, which is another class of
change entirely.

Acceptance notes

  • content/docs/releases/v9.mdx and content/docs/releases/v17/17-0.mdx carry
    the same select-only phrasing. Release-owned and never edited in a code PR;
    they are also accurate as historical records of what those releases said.
    Noted, not filed.
  • The module header of dimension-labels.ts (:8) describes the same arm as
    select only, one layer up from the two sentences repaired here. Out of the
    file surface this PR was dispatched with, so it is reported rather than
    touched. Dedupe words: dimension-labels header, module doc comment select,
    option arm prose, service-analytics tsdoc. The seat disagreed with the
    noted-not-filed grading and filed it separately; it is now tracked on its own
    card, [finding] the dimension-labels module header names the option arm as select, where the resolver keys on a declared options list #18923 (named without a closing keyword on purpose — this PR does not
    deliver it). Nothing in this PR waits on it.
  • content/docs/data-modeling/import-mappings.mdx names select / multiselect
    for label-to-value resolution on import. That is the opposite direction
    through a different subsystem, not this arm. Noted, not filed.

Verification

No changeset: measured, nothing published moves. No package's files[]
mentions content/docs (0 of the workspace manifests); its only consumer
@objectstack/docs is private: true. Positive control: the same reader
returns @objectstack/spec's non-empty files[], so the absence is a reading
and not a broken probe.


Generated by Claude Code


Generated by Claude Code

…ng field, not the `select` type

Both bullets named `select` as the option arm's trigger. The resolver keys on
the field carrying a non-empty `options` list instead — `dimension-labels.ts`
tests `Array.isArray(meta.options) && meta.options.length > 0` at all three
sites and never tests `type === 'select'`. A `radio` axis therefore resolves a
label while the docs said it did not.

The prose now names the property the implementation names ("carries `options`")
rather than growing a type enumeration. An enumeration would be wrong in both
directions: `options` is an untyped optional key on the field schema, and
`MULTI_OPTION_TYPES` includes the free-form `tags`, which need not declare
options at all.

Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
@os-try-charles os-try-charles added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 18, 2026 — with Claude
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Sep 18, 2026
@os-try-charles
os-try-charles marked this pull request as ready for review September 18, 2026 06:24
@os-try-charles
os-try-charles added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit 54145cc Sep 18, 2026
52 checks passed
@os-try-charles
os-try-charles deleted the claude/issue-18475-option-arm-prose branch September 18, 2026 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants