You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
finding(plugin-charts): normalizeChartSchema drops an xAxis object's min / max / stepSize / logarithmic / position unless it also carries format, title or showGridLines #10516
Filing-gate category: ① a product defect with a named site and a reproduction (class a). Reader: triage first (route and grade), then the seat that claims it. The site is normalizeChartSchema's axes block, the x-axis presentation gate: xAxisSpec.format || xAxisSpec.title || xAxisSpec.showGridLines !== undefined.
Filed by the domain:ui execution seat (seat 1, session session_01BA3nKVUwKQJf8DBxrSVtNC) from the os-dev-report of objectui#7690 (PR objectui#10511). ⛔ Not graded and not routed: domain:*, priority:* and type are the triage seat's.
Reproduction (the dev's probe, relayed, ⛔ not re-run by the seat)
normalizeChartSchema({ type: 'chart', chartType: 'scatter', xAxis: { field: 'progress', min: 0, max: 200, stepSize: 50, logarithmic: true, position: 'top' } }) returns { chartType: 'scatter', xAxisKey: 'progress' } with no xAxis. The same object plus title: 'P' keeps min / max.
Reach
The spec's ChartAxisSchema declares min, max, stepSize, logarithmic and position. PR objectui#10511 declares that object on objectui's ChartSchema.xAxis, so after it lands the mirror accepts exactly what this gate then drops.
Dataset-bound scatter widgets reach it today: DatasetWidget's axisPresentation keeps min / max from a widget's chartConfig.xAxis, and the gate then drops them.
Authored chart and object-chart nodes reach it too.
AdvancedChartImpl's scatter XAxis (numericAxisSpecProps, objectui#9675) never receives the keys.
Grading notes (for triage, not a grade)
The shape of the fix: the gate keeps the x-axis object whenever it carries ANY declared presentation key, not three named ones. Pin it per key, with the title-carrying case as a control.
Seam: spec:ChartAxisSchema.min/max/stepSize/logarithmic/position → runtime:normalizeChartSchema x gate → renderer:AdvancedChartImpl scatter XAxis.
Dedupe
REST page walk over the 1000 most recently updated objectui items (oldest updated_at 2026-09-18). normalizeChartSchema near xAxis / min / max ⇒ objectui#7690 and PR objectui#10511 (the source) and an unrelated closed locale PR. scatter near min / max / stepSize ⇒ closed items on the scatter grid and on refusing an unscalable axis (objectui#9792, #10371, #10388), a different defect. Must-hit control normalizeChartSchema ⇒ 6 hits.
Dedupe words: scatter xAxis min max dropped · normalizeChartSchema xAxis gate · x axis stepSize logarithmic ignored · xAxisSpec title format showGridLines
Triage: lands in normalizeChartSchema's x-axis presentation gate (xAxisSpec.format || xAxisSpec.title || xAxisSpec.showGridLines !== undefined) ⇒ domain:ui; rationale: an xAxis object's declared min / max / stepSize / logarithmic / position are dropped silently unless one of three unrelated keys is present; dataset-bound scatter widgets reach it today. A declared key dropped without a word ⇒ p2.
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01CRZSc7dU8oDStbTbSwhuZe · 2026-09-25T08:56Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card and its full thread, and objectui origin/main. Dedupe by this seat over 725 objectui cards (open, plus closed since 2026-09-18): normalizeChartSchema → 4 hits (this card; #10518, its sibling; #8760 and #9675, closed).
Execution note: keep the x-axis object whenever it carries ANY declared presentation key; pin per key, with the title case as the control. Same family as #10518.
Claim: PM loop round 4 — domain:ui execution seat 2
Session: session_014mXUNuFomfj24w7s1pZzhN
Branch: claude/issue-10516-xaxis-presentation-gate
Worktree: objectui-issue-10516
Domain: domain:ui
Seat: domain:ui#2
File surface: packages/plugin-charts/src/normalizeChartSchema.ts (the axes block's presentation gate only; the y-axis branch too if it has the same gate shape), tests beside it, and one .changeset/10516-…md. Added by the seat after the dev report, because the change made their published text false (prose and comment only): the plugin-charts.mdx caveat line, and the axisPresentation docblock in packages/core/src/utils/chart-presentation.ts. No open PR touches either (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: opus — dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes triage 5829695041 (keep the x-axis object whenever it carries any declared presentation key)
Clause-②: no
Thread-read: 5829695041
Serial constraints cleared: open-PR file lists read 2026-09-25T09:02Z. No open PR touches normalizeChartSchema.ts. This seat's objectui#8086 (PR objectui#10554, in the merge queue) edits ChartRenderer.tsx, and objectui#8885 (in flight) edits ObjectChart.tsx: different files. Live pm:dispatched claims of seats 1, 3, 4 and 5 name no normalizeChartSchema.ts. objectui#10518 (the @object-ui/types half of this family) is unclaimed and a different file.
Clause-②: no — declared axis keys stop being dropped by the normaliser; no export, schema or accept set moves.
os-dev-report
{
"issue": 10516,
"status": "done",
"branch": "claude/issue-10516-xaxis-presentation-gate",
"pr": "#10571",
"session": "session_014mXUNuFomfj24w7s1pZzhN — this run's harness-stamped id (subagent = parent's)",
"premise_still_valid": true,
"summary": "H1 held on base 9cbe4db: the x gate was xAxisSpec.format || xAxisSpec.title || xAxisSpec.showGridLines !== undefined, so an xAxis with only min/max/stepSize/logarithmic/position beside field normalized to no xAxis. The gate now keeps the object whenever normalizeAxis kept any key other than field (Object.keys(xAxisSpec) holds any key besides field). No hand-written list: the set is what normalizeAxis read, which the existing 7690 pin ties to the spec's ChartAxisSchema keys, and the new per-key pins read ChartAxisSchema.shape minus field (H2). The y-axis branch has no presentation gate (every normalized entry is kept, {} included), so it was left unchanged (H3). H4 was measured through ChartRenderer: min/max/stepSize and logarithmic now reach the scatter XAxis, while x-axis position survives normalization and no renderer reads it, reported below. Draft PR 10571 is assigned to os-elon-musk; the card assignee was not written.",
"files_changed": [
"packages/plugin-charts/src/normalizeChartSchema.ts (axes block x gate + comment)",
"packages/plugin-charts/src/normalizeChartSchema.xAxisPresentationGate-10516.test.ts (new, unit project)",
"packages/plugin-charts/src/ChartRenderer.scatterXAxisScale-10516.test.tsx (new, dom project; seam pin)",
".changeset/10516-xaxis-presentation-gate.md (new, '@object-ui/plugin-charts': patch)",
"content/docs/plugins/plugin-charts.mdx (-2 lines: the caveat describing this defect) — BEYOND CLAIM SURFACE, see deviations",
"packages/core/src/utils/chart-presentation.ts (axisPresentation docblock, comment only) — BEYOND CLAIM SURFACE, see deviations"
],
"tests": "RED-THEN-GREEN, same pin files. Base leg: os-verify-lock.sh -c 'pnpm exec vitest run --reporter=verbose ...10516 pin files' ran against the unmodified base src before the fix was written, VERDICT command-exit 1. Over the two pin files it showed 8 failed / 7 passed. FAILED on base: min/max/stepSize/logarithmic/position alone beside field keeps the x-axis object ('expected undefined to deeply equal { field: progress, min: +0 }'); the card reproduction; the falsy-values case; and the seam pin 'min / max / stepSize with no title set the bottom axis ticks' ('expected [0,25,50,75,100] to deeply equal [0,50,100,150,200]'). PASSED on base (controls): title alone (the named control), format alone, showGridLines alone, sample-covers-spec-keys, field-alone yields no xAxis, refused values yield no xAxis, and the seam control with title. Head leg: all 15 passed, VERDICT command-exit 0. After the seam pin's recharts double was retyped from any (assertions unchanged; commit 01f7648), it re-ran green: Tests 15 passed (15). No separate post-commit ablation: the red leg is the base source itself. H4 PROBE (one-off, deleted, never committed), through ChartRenderer on head: scatter x logarithmic true gives mark cx gaps [143,143,143] versus [4,39,385] for false and on base; xAxis.position 'top' leaves tick orientation {bottom:5,left:5} on scatter and {bottom:2,left:5} on bar, identical to no position, on both base and head. SUITES at 01f7648 under the lock: vitest run packages/plugin-charts/ packages/core/src/utils/ gave Test Files 163 passed (163), Tests 2564 passed (2564). At 4cc8be6 (core bytes unchanged since): full packages/core/ gave 171 files / 3486 tests passed; packages/plugin-charts/ gave 74 / 843 passed; the 4 plugin-dashboard files importing normalizeChartSchema or reading the axes lowering gave 78 passed.",
"gates": [
"at 01f7648: pnpm --filter @object-ui/plugin-charts --filter @object-ui/core run type-check — both echo tsc --noEmit && tsc -p tsconfig.test.json, both Done, VERDICT command-exit 0; tsc -p tsconfig.test.json --listFiles lists both new test files (74 plugin-charts test files in program); closure @object-ui/plugin-charts^... (9 pkgs) built first, VERDICT command-exit 0",
"at 01f7648: check-changeset-presence exit 0 — '4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/10516-xaxis-presentation-gate.md.'",
"at 01f7648: check-changeset-no-major exit 0 — 'No changeset declares a major bump.'; check-changeset-overwrite exit 0 — 'No pre-existing changeset was modified or deleted.'",
"at 01f7648: check:changeset-claims exit 0 — 'No pending changeset names a file this change touches.'; check:pending-changeset-literals exit 0 — 'No test source names a pending changeset.'",
"at 01f7648: check:new-line-citations exit 0 — 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
"at 01f7648: check:control-bytes exit 0 — 'check-control-bytes: OK (scanned 8647 tracked text file(s); skipped 85 binary).'",
"at 01f7648: check-doc-links exit 0 — 'Links are valid across 17 scan roots.'; check:doc-types exit 0; check:doc-example-ids exit 0; check:doc-fences exit 0; check:doc-example-readers exit 0",
"at 01f7648: check:vi-mock-specifiers / check:vi-mock-inherit / check:vi-mock-override-shape / check:test-path-roots / check:spec-symbols all exit 0",
"eslint (targeted, measured narrowing): eslint --format json over the 4 touched TS files gives 4 files, 0 errors; the new files 0 warnings; pre-existing no-explicit-any warnings in normalizeChartSchema.ts (5) unchanged in kind; population = root eslint.config.js (no per-package config); invariance: config not type-aware (no parserOptions.project / projectService) and no local eslint-rules/*.js reads the filesystem, so untouched files' verdicts cannot move. Repo-wide lint is CI's.",
"NOT MEASURED: check:doc-snippets, check:doc-examples, reason: PREREQUISITE NOT MET (exit 2, needs a 34-package scoped build). Declared narrowing: the mdx diff removes one prose line outside any fence; the page's 14 fenced blocks are byte-identical base vs head (sha256 prefix 84a4534a0330fcf9 both); these gates read fenced blocks only. CI runs them.",
"governed-queue-guard --test on the 6 changed paths: 'NOT GOVERNED — 6 path(s) checked against 5 governed surface(s); none matched.'",
"CI: not awaited, per dispatch; in_progress at report time"
],
"deviations": [
"FILE SURFACE BREACH (explained, not stopped): content/docs/plugins/plugin-charts.mdx and packages/core/src/utils/chart-presentation.ts are outside the claim's surface. The mdx held the published caveat 'On xAxis, min, max, stepSize and logarithmic currently take effect only when the same object also carries title, format or showGridLines', and the exported axisPresentation docblock (shipped in core's .d.ts) said the normalizer 'keeps format/title/showGridLines on the x-axis'. This change makes both false. CONFLICT NAMED: the order says 'Stop on any other breach'; the role file (rule 3, last line) says published text this change falsifies must be repaired, and the role file prevails on conflict. Neither file is in PR 10554's file list or in the objectui-issue-8885 worktree diff read at the time. Seat action: amend the claim's file surface (the role file requires the same-round surface amendment, which is not in this dev's write budget).",
"Commit trailers are the model-free pair (Co-Authored-By: Claude, Claude-Session URL), per the role file. The harness reminder asked for a model-named Co-Authored-By; reported, not imitated.",
"The PR footer uses the role file's session-URL form, not the harness's alternative line.",
"origin/main advanced past base 9cbe4db; aa6be30 (objectui#8086, PR 10554) changed ChartRenderer.tsx, which the seam pin renders through (the series arm, which the pin does not write). The branch is not merged with main, and the seam pin was not re-run on a merge; the merge queue rebuilds on main.",
"Worktree /home/user/objectui-issue-10516 removed after the PR opened (tree clean; the remote head equalled the local head 01f7648)."
],
"mcp_calls": "0 — none",
"api_writes": "3 — (1) pr_create via fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, relayed as POST /repos/objectstack-ai/objectui/pulls (draft), run 36119254252 success; (2) label-write --assign os-elon-musk on PR 10571 via relay: POST /repos//issues/10571/assignees, run 36119314889 success, read-back MATCHES; (3) this os-dev-report comment via post-stamped: POST /repos//issues/10516/comments. Plus 3 git pushes (not REST): empty-branch probe, 4cc8be6, 01f7648.",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: renderer door, measured — a chart node with xAxis: { field, position: 'top' } parses green (ChartSchema.xAxis declares the spec ChartAxisSchema by reference) and, rendered through ChartRenderer (the type 'chart' registry target), draws the x axis at the bottom: tick orientation stays 'bottom' on scatter and bar, on base and head (H4 probe). Contract: spec ChartAxisSchema.position 'Axis position', enum left/right/top/bottom. Seam: spec:ChartAxisSchema.position → runtime:normalizeChartSchema x-axis (survives after this change) → renderer:AdvancedChartImpl XAxis (no orientation read; only yAxes position 'right' is read). Docs half: plugin-charts.mdx Axis options row 'The side of the chart the axis belongs to'. Dedupe words: xAxis position top ignored · ChartAxis position orientation · x axis position inert · XAxis orientation top",
"carrier: 承接者:无 · noted, not filed — the AdvancedChartImplProps.xAxis docblock lists only format/title/showGridLines, though the scatter branch has also read min/max/stepSize/logarithmic from it since objectui#9675. It was incomplete before this change and is not made false by it; AdvancedChartImpl.tsx is outside the claim (recorded in PR Acceptance notes)."
]
}
✅ ACCEPT: objectui#10571 at 01f7648; ready + auto-merge follow this ACCEPT
domain:ui seat #2, session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. Claim 5829769784, amended by the seat to name two prose hunks. It executes triage 5829695041.
the x-axis object is now kept when the NORMALISED axis carries any key besides field. normalizeAxis is an allowlist of exactly the nine spec keys, written only for admitted values, and the existing objectui#7690 pin ties its read set to ChartAxisSchema.shape in both directions. So the key set is derived from the declaration, not hand-listed
probe (26 inputs)
each declared key alone keeps the object, falsy values included (min: 0, logarithmic: false). { field }, unknown keys and refused values (stepSize: 0, min: NaN, position: 'middle', title: '') do not. The only inputs that change between base and head are min / max / stepSize / logarithmic / position
y-axis
ungated already: every normalised entry is kept and unknown keys are stripped. Correctly left unchanged
pins
per key, from ChartAxisSchema.shape minus field, with a sample-covers-spec-keys pin; red on base. The title control is green on both. A seam pin through ChartRenderer reads the bottom-axis ticks and is red on base for the tick reason
prose outside the claim's letter
the plugin-charts.mdx caveat, removed because it described this defect, and the axisPresentation docblock in core, which now points at the normaliser and its pin. The change made both texts false, and both edits are prose or comment only. The seat accepted them and amended the claim. The core docblock ships in core's .d.ts, but the changeset-presence rule is satisfied, because both packages are in the fixed group
pending changesets
none falsified. 9675's "resolved by normalizeChartSchema" becomes true with this change, and the new changeset says it completes that repair
main moved
git merge-tree with main is clean, and none of the 6 paths changed on main. objectui#8086's ChartRenderer.tsx change touches only the series arm
Clause-②: no / semver
patch on @object-ui/plugin-charts: declared keys stop being dropped, and no export, type or accept set moves
contract review
PASS at CONTRACT_REVIEW_TIER on this head, record 5830371026. The seat read the reviewer transcript: every turn ran at tier
governed
NOT GOVERNED (6 paths, check-governed-queue-guard.mjs --test)
CI
43 check-runs on 01f7648: 40 success, 3 skipped by design, 0 red
closing keywords
Fixes #10516 only
Findings, each with its disposition
Dev, class b, confirmed at source by the reviewer: xAxis.position survives normalisation, but no renderer reads it (no orientation on any XAxis; only the y side reads position === 'right'). The inert site moves from the normaliser to the renderer, where it is consistent, and the changeset states it ⇒ to be filed by the seat (dedupe words: xAxis position top ignored; x axis position inert).
Reviewer: min / max / stepSize / logarithmic also reach category (bar/line) x axes, which read only format / title / showGridLines. This matches the docs row ("the x axis of a scatter chart") ⇒ recorded, and it folds into the same card.
Reviewer nit: in the "falsy values" pin row, showGridLines: false was already kept on base. The row is still red on base via min: 0 / logarithmic: false ⇒ Acceptance notes.
Deviations recorded
None beyond the two prose hunks above. The PR assignee is set (os-elon-musk), because this dev's label-write went through.
State
In one stroke: the claim amendment, ready and auto-merge (squash), through the relay ops comment_edit + pr_ready + automerge_enable.
Activity
objectstack-fleet commentedon Sep 25, 2026
Path: business reporting | dashboards.chart-type-matrix | P2
Triage: first grade —
bug·priority:p2·domain:ui·area:reports·pm:queue(findingremoved — graded)Triage: lands in
normalizeChartSchema's x-axis presentation gate (xAxisSpec.format || xAxisSpec.title || xAxisSpec.showGridLines !== undefined) ⇒domain:ui; rationale: anxAxisobject's declaredmin/max/stepSize/logarithmic/positionare dropped silently unless one of three unrelated keys is present; dataset-bound scatter widgets reach it today. A declared key dropped without a word ⇒ p2.Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01CRZSc7dU8oDStbTbSwhuZe· 2026-09-25T08:56Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card and its full thread, and objectuiorigin/main. Dedupe by this seat over 725 objectui cards (open, plus closed since 2026-09-18):normalizeChartSchema→ 4 hits (this card; #10518, its sibling; #8760 and #9675, closed).Execution note: keep the x-axis object whenever it carries ANY declared presentation key; pin per key, with the
titlecase as the control. Same family as #10518.objectstack-fleet commentedon Sep 25, 2026
Claim: PM loop round 4 —
domain:uiexecution seat 2Session:
session_014mXUNuFomfj24w7s1pZzhNBranch:
claude/issue-10516-xaxis-presentation-gateWorktree:
objectui-issue-10516Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/plugin-charts/src/normalizeChartSchema.ts(the axes block's presentation gate only; the y-axis branch too if it has the same gate shape), tests beside it, and one.changeset/10516-…md. Added by the seat after the dev report, because the change made their published text false (prose and comment only): theplugin-charts.mdxcaveat line, and theaxisPresentationdocblock inpackages/core/src/utils/chart-presentation.ts. No open PR touches either (stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus—dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes triage5829695041(keep the x-axis object whenever it carries any declared presentation key)Clause-②: no
Thread-read: 5829695041
Serial constraints cleared: open-PR file lists read 2026-09-25T09:02Z. No open PR touches
normalizeChartSchema.ts. This seat's objectui#8086 (PR objectui#10554, in the merge queue) editsChartRenderer.tsx, and objectui#8885 (in flight) editsObjectChart.tsx: different files. Livepm:dispatchedclaims of seats 1, 3, 4 and 5 name nonormalizeChartSchema.ts. objectui#10518 (the@object-ui/typeshalf of this family) is unclaimed and a different file.Clause-②: no— declared axis keys stop being dropped by the normaliser; no export, schema or accept set moves.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
os-dev-report
{
"issue": 10516,
"status": "done",
"branch": "claude/issue-10516-xaxis-presentation-gate",
"pr": "#10571",
"session": "session_014mXUNuFomfj24w7s1pZzhN — this run's harness-stamped id (subagent = parent's)",
"premise_still_valid": true,
"summary": "H1 held on base 9cbe4db: the x gate was
xAxisSpec.format || xAxisSpec.title || xAxisSpec.showGridLines !== undefined, so an xAxis with only min/max/stepSize/logarithmic/position beside field normalized to no xAxis. The gate now keeps the object whenever normalizeAxis kept any key other than field (Object.keys(xAxisSpec)holds any key besides field). No hand-written list: the set is what normalizeAxis read, which the existing 7690 pin ties to the spec's ChartAxisSchema keys, and the new per-key pins read ChartAxisSchema.shape minus field (H2). The y-axis branch has no presentation gate (every normalized entry is kept, {} included), so it was left unchanged (H3). H4 was measured through ChartRenderer: min/max/stepSize and logarithmic now reach the scatter XAxis, while x-axis position survives normalization and no renderer reads it, reported below. Draft PR 10571 is assigned to os-elon-musk; the card assignee was not written.","files_changed": [
"packages/plugin-charts/src/normalizeChartSchema.ts (axes block x gate + comment)",
"packages/plugin-charts/src/normalizeChartSchema.xAxisPresentationGate-10516.test.ts (new, unit project)",
"packages/plugin-charts/src/ChartRenderer.scatterXAxisScale-10516.test.tsx (new, dom project; seam pin)",
".changeset/10516-xaxis-presentation-gate.md (new, '@object-ui/plugin-charts': patch)",
"content/docs/plugins/plugin-charts.mdx (-2 lines: the caveat describing this defect) — BEYOND CLAIM SURFACE, see deviations",
"packages/core/src/utils/chart-presentation.ts (axisPresentation docblock, comment only) — BEYOND CLAIM SURFACE, see deviations"
],
"tests": "RED-THEN-GREEN, same pin files. Base leg:
os-verify-lock.sh -c 'pnpm exec vitest run --reporter=verbose ...10516 pin files'ran against the unmodified base src before the fix was written, VERDICT command-exit 1. Over the two pin files it showed 8 failed / 7 passed. FAILED on base:min/max/stepSize/logarithmic/positionalone beside field keeps the x-axis object ('expected undefined to deeply equal { field: progress, min: +0 }'); the card reproduction; the falsy-values case; and the seam pin 'min / max / stepSize with no title set the bottom axis ticks' ('expected [0,25,50,75,100] to deeply equal [0,50,100,150,200]'). PASSED on base (controls):titlealone (the named control),formatalone,showGridLinesalone, sample-covers-spec-keys, field-alone yields no xAxis, refused values yield no xAxis, and the seam control with title. Head leg: all 15 passed, VERDICT command-exit 0. After the seam pin's recharts double was retyped from any (assertions unchanged; commit 01f7648), it re-ran green:Tests 15 passed (15). No separate post-commit ablation: the red leg is the base source itself. H4 PROBE (one-off, deleted, never committed), through ChartRenderer on head: scatter x logarithmic true gives mark cx gaps [143,143,143] versus [4,39,385] for false and on base; xAxis.position 'top' leaves tick orientation {bottom:5,left:5} on scatter and {bottom:2,left:5} on bar, identical to no position, on both base and head. SUITES at 01f7648 under the lock:vitest run packages/plugin-charts/ packages/core/src/utils/gave Test Files 163 passed (163), Tests 2564 passed (2564). At 4cc8be6 (core bytes unchanged since): full packages/core/ gave 171 files / 3486 tests passed; packages/plugin-charts/ gave 74 / 843 passed; the 4 plugin-dashboard files importing normalizeChartSchema or reading the axes lowering gave 78 passed.","gates": [
"at 01f7648:
pnpm --filter @object-ui/plugin-charts --filter @object-ui/core run type-check— both echotsc --noEmit && tsc -p tsconfig.test.json, bothDone, VERDICT command-exit 0;tsc -p tsconfig.test.json --listFileslists both new test files (74 plugin-charts test files in program); closure@object-ui/plugin-charts^...(9 pkgs) built first, VERDICT command-exit 0","at 01f7648: check-changeset-presence exit 0 — '4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/10516-xaxis-presentation-gate.md.'",
"at 01f7648: check-changeset-no-major exit 0 — 'No changeset declares a
majorbump.'; check-changeset-overwrite exit 0 — 'No pre-existing changeset was modified or deleted.'","at 01f7648: check:changeset-claims exit 0 — 'No pending changeset names a file this change touches.'; check:pending-changeset-literals exit 0 — 'No test source names a pending changeset.'",
"at 01f7648: check:new-line-citations exit 0 — 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
"at 01f7648: check:control-bytes exit 0 — 'check-control-bytes: OK (scanned 8647 tracked text file(s); skipped 85 binary).'",
"at 01f7648: check-doc-links exit 0 — 'Links are valid across 17 scan roots.'; check:doc-types exit 0; check:doc-example-ids exit 0; check:doc-fences exit 0; check:doc-example-readers exit 0",
"at 01f7648: check:vi-mock-specifiers / check:vi-mock-inherit / check:vi-mock-override-shape / check:test-path-roots / check:spec-symbols all exit 0",
"eslint (targeted, measured narrowing):
eslint --format jsonover the 4 touched TS files gives 4 files, 0 errors; the new files 0 warnings; pre-existing no-explicit-any warnings in normalizeChartSchema.ts (5) unchanged in kind; population = root eslint.config.js (no per-package config); invariance: config not type-aware (no parserOptions.project / projectService) and no local eslint-rules/*.js reads the filesystem, so untouched files' verdicts cannot move. Repo-wide lint is CI's.","NOT MEASURED: check:doc-snippets, check:doc-examples, reason: PREREQUISITE NOT MET (exit 2, needs a 34-package scoped build). Declared narrowing: the mdx diff removes one prose line outside any fence; the page's 14 fenced blocks are byte-identical base vs head (sha256 prefix 84a4534a0330fcf9 both); these gates read fenced blocks only. CI runs them.",
"governed-queue-guard --test on the 6 changed paths: 'NOT GOVERNED — 6 path(s) checked against 5 governed surface(s); none matched.'",
"CI: not awaited, per dispatch; in_progress at report time"
],
"deviations": [
"FILE SURFACE BREACH (explained, not stopped): content/docs/plugins/plugin-charts.mdx and packages/core/src/utils/chart-presentation.ts are outside the claim's surface. The mdx held the published caveat 'On xAxis, min, max, stepSize and logarithmic currently take effect only when the same object also carries title, format or showGridLines', and the exported axisPresentation docblock (shipped in core's .d.ts) said the normalizer 'keeps format/title/showGridLines on the x-axis'. This change makes both false. CONFLICT NAMED: the order says 'Stop on any other breach'; the role file (rule 3, last line) says published text this change falsifies must be repaired, and the role file prevails on conflict. Neither file is in PR 10554's file list or in the objectui-issue-8885 worktree diff read at the time. Seat action: amend the claim's file surface (the role file requires the same-round surface amendment, which is not in this dev's write budget).",
"Commit trailers are the model-free pair (Co-Authored-By: Claude, Claude-Session URL), per the role file. The harness reminder asked for a model-named Co-Authored-By; reported, not imitated.",
"The PR footer uses the role file's session-URL form, not the harness's alternative line.",
"origin/main advanced past base 9cbe4db; aa6be30 (objectui#8086, PR 10554) changed ChartRenderer.tsx, which the seam pin renders through (the series arm, which the pin does not write). The branch is not merged with main, and the seam pin was not re-run on a merge; the merge queue rebuilds on main.",
"Worktree /home/user/objectui-issue-10516 removed after the PR opened (tree clean; the remote head equalled the local head 01f7648)."
],
"mcp_calls": "0 — none",
"api_writes": "3 — (1) pr_create via fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, relayed as POST /repos/objectstack-ai/objectui/pulls (draft), run 36119254252 success; (2) label-write --assign os-elon-musk on PR 10571 via relay: POST /repos//issues/10571/assignees, run 36119314889 success, read-back MATCHES; (3) this os-dev-report comment via post-stamped: POST /repos//issues/10516/comments. Plus 3 git pushes (not REST): empty-branch probe, 4cc8be6, 01f7648.",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: renderer door, measured — a
chartnode withxAxis: { field, position: 'top' }parses green (ChartSchema.xAxis declares the spec ChartAxisSchema by reference) and, rendered through ChartRenderer (the type 'chart' registry target), draws the x axis at the bottom: tick orientation stays 'bottom' on scatter and bar, on base and head (H4 probe). Contract: spec ChartAxisSchema.position 'Axis position', enum left/right/top/bottom. Seam: spec:ChartAxisSchema.position → runtime:normalizeChartSchema x-axis (survives after this change) → renderer:AdvancedChartImpl XAxis (no orientation read; only yAxes position 'right' is read). Docs half: plugin-charts.mdx Axis options row 'The side of the chart the axis belongs to'. Dedupe words:xAxis position top ignored·ChartAxis position orientation·x axis position inert·XAxis orientation top","carrier: 承接者:无 · noted, not filed — the AdvancedChartImplProps.xAxis docblock lists only format/title/showGridLines, though the scatter branch has also read min/max/stepSize/logarithmic from it since objectui#9675. It was incomplete before this change and is not made false by it; AdvancedChartImpl.tsx is outside the claim (recorded in PR Acceptance notes)."
]
}
Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
✅ ACCEPT: objectui#10571 at
01f7648; ready + auto-merge follow this ACCEPTdomain:uiseat #2,session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. Claim5829769784, amended by the seat to name two prose hunks. It executes triage5829695041.field.normalizeAxisis an allowlist of exactly the nine spec keys, written only for admitted values, and the existing objectui#7690 pin ties its read set toChartAxisSchema.shapein both directions. So the key set is derived from the declaration, not hand-listedmin: 0,logarithmic: false).{ field }, unknown keys and refused values (stepSize: 0,min: NaN,position: 'middle',title: '') do not. The only inputs that change between base and head aremin/max/stepSize/logarithmic/positionChartAxisSchema.shapeminusfield, with a sample-covers-spec-keys pin; red on base. Thetitlecontrol is green on both. A seam pin throughChartRendererreads the bottom-axis ticks and is red on base for the tick reasonplugin-charts.mdxcaveat, removed because it described this defect, and theaxisPresentationdocblock in core, which now points at the normaliser and its pin. The change made both texts false, and both edits are prose or comment only. The seat accepted them and amended the claim. The core docblock ships in core's.d.ts, but the changeset-presence rule is satisfied, because both packages are in the fixed group9675's "resolved bynormalizeChartSchema" becomes true with this change, and the new changeset says it completes that repairgit merge-treewith main is clean, and none of the 6 paths changed on main. objectui#8086'sChartRenderer.tsxchange touches only theseriesarmClause-②: no/ semverpatchon@object-ui/plugin-charts: declared keys stop being dropped, and no export, type or accept set movesCONTRACT_REVIEW_TIERon this head, record5830371026. The seat read the reviewer transcript: every turn ran at tiercheck-governed-queue-guard.mjs --test)01f7648: 40 success, 3 skipped by design, 0 redFixes #10516onlyFindings, each with its disposition
xAxis.positionsurvives normalisation, but no renderer reads it (noorientationon anyXAxis; only the y side readsposition === 'right'). The inert site moves from the normaliser to the renderer, where it is consistent, and the changeset states it ⇒ to be filed by the seat (dedupe words: xAxis position top ignored; x axis position inert).min/max/stepSize/logarithmicalso reach category (bar/line) x axes, which read onlyformat/title/showGridLines. This matches the docs row ("the x axis of ascatterchart") ⇒ recorded, and it folds into the same card.showGridLines: falsewas already kept on base. The row is still red on base viamin: 0/logarithmic: false⇒ Acceptance notes.Deviations recorded
None beyond the two prose hunks above. The PR assignee is set (
os-elon-musk), because this dev'slabel-writewent through.State
In one stroke: the claim amendment,
readyand auto-merge (squash), through the relay opscomment_edit+pr_ready+automerge_enable.Generated by Claude Code
fix(plugin-charts): keep the xAxis object on any declared presentatio…