Skip to content

docs(spec): describe objectui's normaliseOptions as it is at the console pin - #24072

Draft
objectstack-fleet[bot] wants to merge 3 commits into
mainfrom
claude/issue-24047-action-param-options-comments
Draft

objectstack-fleet[bot] wants to merge 3 commits into
mainfrom
claude/issue-24047-action-param-options-comments

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #24047
Clause-②: no

What changes

Three comments in packages/spec still said that objectui's normaliseOptions rebuilds each option a field-backed action param inherits as a bare { label, value } pair. At the console pin it keeps every key by spread. This PR rewrites the three comments and adds a prose-only changeset. Nothing else changes.

  • packages/spec/src/ui/action.zod.ts, the ActionParam options docblock. The paragraph that began "What this does NOT fix" said the drop "is tracked in objectui". It now describes objectui at the pin, with file, lines and pin sha. It also gives the reason that is still true for the guidance not prescribing "make it field-backed and inherit": the keys survive the resolver, but nothing in this repo measures a reader of color, icon or disabled on the inherited path.
  • packages/spec/src/ui/action.zod.ts, the comment above the option shape's guidance table. Same correction. It points at the docblock for the pin and line.
  • packages/spec/src/ui/action.test.ts, the comment inside keeps each rejection pointing at where that vocabulary IS real. Same correction.
  • .changeset/24047-action-param-options-comments.md: '@objectstack/spec': patch, prose only (see "Changeset" below).

No guidance string, schema, export or message text changes. All 34 changed lines in packages/spec are * or // comment lines. The mechanical check is under Verification.

The pin reading

.objectui-sha = f8267df93aba8fb09cc1cc0692eadc0c8c5a5e56. I read the files with git show PIN:PATH from the local objectui object store.

  • packages/fields/src/resolveActionParams.ts:503 declares normaliseOptions. Line :515 is return { ...raw, label, value: raw.value };.
  • Lines :650-:651 hold the field-backed branch, authoredOptions ?? normaliseOptions(field.options, ownerName, param.field, ctx.fieldOptionLabel). An authored list still wins over the inherited one.
  • Line :241 is in the resolveOptionLabels docblock. It names objectui fbc23e094 as the change that made normaliseOptions keep keys.

The card quoted :503 at objectui main 94b2489f. At the pin the return is on :515, the line the claim also read.

Readers on the inherited path: a source read at the pin, not a runtime measurement

The card asked for any reader measurement to go here, not into a comment. I read the dialog path at the same pin:

  • packages/app-shell/src/views/ActionParamDialog.tsx:536 re-spreads each option to localise its label ({ ...o, label: pickLocalized(o.label, language) }). Inherited keys survive this step as well.

  • packages/app-shell/src/utils/paramToField.ts:102 passes options: param.options into the widget's field metadata unchanged.

  • The four option widgets build each option from value and optionDisplayLabel(option) and nothing else:

    • packages/fields/src/widgets/SelectField.tsx:227-230
    • MultiSelectField.tsx:191-206
    • RadioField.tsx:134-145
    • CheckboxesField.tsx:152-168

    optionDisplayLabel (packages/core/src/evaluator/optionRules.ts:173) reads only label and value. Each disabled in those four files is the field-level props.disabled (SelectField.tsx:213, MultiSelectField.tsx:201, RadioField.tsx:129, CheckboxesField.tsx:163), never a per-option one. None of the four files reads color or icon.

So at the pin, an inherited option's color, icon and disabled reach the widget, and none of the four widgets reads them. That matches the current guidance texts, so this PR proposes no guidance change; the card puts any such change on a card of its own anyway. This reading has limits. It is a static source read of the four widgets the docblock already names, not a rendered dialog, and no test in this repo pins it. For that reason the comments say "not measured from this repo" and do not say "no reader".

Changeset

The card allowed no changeset, or a prose-only patch changeset if a gate requires one. Check Changeset requires either a changeset or the skip-changeset label. @objectstack/spec's files array ships src/**/*.zod.ts, so the rewritten docblock in src/ui/action.zod.ts goes into the published tarball verbatim. "Publishes nothing" would therefore be false, and the changeset is the accurate declaration. Its body carries Clause-②: no.

Verification

All readings below are on the final head c89eef4e3b (the merge of main) unless marked otherwise. Build and test ran through scripts/pm/os-verify-lock.sh, and each exit code was captured before any pipe.

  • pnpm --filter @objectstack/spec build: exit 0.
  • pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2: exit 0, Test Files 692 passed (692), Tests 20952 passed | 1 todo (20953).
  • pnpm --filter @objectstack/spec typecheck: exit 0, ending check:test-typecheck: OK.
  • action.test.ts alone with --reporter=verbose, on the pre-merge head 56ad5cf153: Tests 150 passed (150), including keeps each rejection pointing at where that vocabulary IS real.
  • pnpm --filter @objectstack/spec check:generated: exit 0, All 14 generated artifacts are up to date. The rewritten docblock reaches no generated artifact. check:api-surface reports public API surface + factory signatures unchanged, and check:docs reports 227 generated files in sync.
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 85 commands. All 85 exit 0. --ran reconciliation: 85 derived, 85 run, 0 NOT-MEASURED, 0 UNRUN. Among them, check:nul-bytes reports OK, check-empty-changeset reports 1 declaring changeset added, and check-changeset-no-major reports no major bump.
  • On the pre-merge head the same sweep had three exit-3 results (PREREQUISITE NOT MET: check:doc-formula-expressions, check:dual-build-cjs-loads, check:lean-entry-closure), because their input packages were not built. After a build of @objectstack/formula, @objectstack/lint and @objectstack/objectql, all three exit 0 on the final head.
  • Local-only family node scripts/check-dev-prereqs.mjs: exit 0.
  • Comment-only check: git diff -U0 origin/main...HEAD -- packages/spec has 34 changed lines, and 0 of them start with anything other than * or //. A control-byte scan of the three files finds nothing.
  • No ablation: the diff changes no tested behaviour.
  • Not run locally, left to CI: test:repo (Test Core), the type-check lanes, and the families dispatch-gates lists outside its runnable set.
  • Since the merge, origin/main has gained two packages/lint-only commits. Neither touches the three files here.

Acceptance notes

  • packages/spec/CHANGELOG.md still describes the old drop in two entries (lines 40254 and 73939). Both are release-owned history. AGENTS.md routes any change to a released entry through a dedicated docs-only PR, so this PR leaves them as they are.
  • The same options docblock has a visibleWhen bullet that says objectui's inline branch "does options: param.options". At the pin, the inline branch returns options: authoredOptions (resolveActionParams.ts:574), which is resolveOptionLabels(param.options, ctx.locale). That call returns the list untouched when every label is already a string, and rebuilds it by spread otherwise. So the bullet's point, that the list is lowered verbatim, still holds; only the quoted expression is out of date. The claim's file surface names only the two comment blocks above, so this PR does not edit the bullet. Carrier: none.

Deviations

  • Labels: none written. The dispatch's write budget names git push, one pr_create and the report comment, and no label write.
  • main was merged once before this PR opened (c89eef4e3b), as AGENTS.md section 10 asks. The incoming commits do not touch any of the three files. Spec was rebuilt and re-verified on the merged head.

Generated by Claude Code

…ole pin

The ActionParam options docblock, the comment above its guidance table and
one action.test.ts comment said objectui's normaliseOptions rebuilds each
inherited option as { label, value }. At the console pin (.objectui-sha
f8267df93aba) it returns { ...raw, label, value: raw.value }
(packages/fields/src/resolveActionParams.ts:515), so inherited keys survive
the resolver. The comments now say so, and give the remaining reason the
guidance does not prescribe inheriting: no reader of color / icon /
disabled on the inherited path is measured from this repo.

Comments only: no guidance string, schema, export or message changes.

Claude-Session: https://claude.ai/code/session_01LFqdRsuM5nkqoJdHd5ztVk
Co-authored-by: Claude <noreply@anthropic.com>
…ns comments

@objectstack/spec ships src/**/*.zod.ts in its files[], so the rewritten
comments in src/ui/action.zod.ts reach the published tarball verbatim.

Claude-Session: https://claude.ai/code/session_01LFqdRsuM5nkqoJdHd5ztVk
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 1 documentable anchor(s).

⛔ 2 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v16.mdx (via ActionParamSchema (symbol, a top-level const))
  • content/docs/releases/v17/17-0.mdx (via ActionParamSchema (symbol, a top-level const))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • the SDK route bridge reached 54 of 206 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 — 142 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 8133cc78052c95b6efd59487b64fe78f69860759 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from dd586522046f69f9dfa3840c87b6a76e747fd7a9 — the merge of head c89eef4e3be9f3f2e58d52a286513a56b1aec0f1 into base 8133cc78052c95b6efd59487b64fe78f69860759, 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 dd586522046f69f9dfa3840c87b6a76e747fd7a9 && git checkout dd586522046f69f9dfa3840c87b6a76e747fd7a9
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 8133cc78052c95b6efd59487b64fe78f69860759 c89eef4e3be9f3f2e58d52a286513a56b1aec0f1 && git checkout -B drift-repro 8133cc78052c95b6efd59487b64fe78f69860759 && git merge --no-ff c89eef4e3be9f3f2e58d52a286513a56b1aec0f1

node scripts/docs-audit/affected-docs.mjs --json 8133cc78052c95b6efd59487b64fe78f69860759

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

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 8133cc78052c95b6efd59487b64fe78f69860759 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

This branch has not been deployed

No deployments
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 tests tooling

Projects

None yet

2 participants