Skip to content

Fix CI lockfile error by removing @objectstack/spec dependency - #121

Merged
huangyiirene merged 2 commits into
copilot/update-types-data-displayfrom
copilot/fix-254823548-1133319012-04d73c7e-7013-4432-bf2c-db090188fb31
Jan 19, 2026
Merged

huangyiirene merged 2 commits into
copilot/update-types-data-displayfrom
copilot/fix-254823548-1133319012-04d73c7e-7013-4432-bf2c-db090188fb31

Conversation

Copilot AI commented Jan 19, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the CI pipeline failure caused by a mismatch between pnpm-lock.yaml and packages/types/package.json.

Problem

The CI was failing with:

ERR_PNPM_OUTDATED_LOCKFILE  Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with packages/types/package.json

specifiers in the lockfile don't match specifiers in package.json:
* @objectstack/spec (lockfile: workspace:*, manifest: ^0.1.1)

The lockfile expected @objectstack/spec to be a workspace package, but package.json specified it as an external npm dependency (^0.1.1). Additionally, the npm package @objectstack/spec@0.1.1 doesn't export the UIComponent interface that was being imported.

Changes Made

  • Removed dependency: Removed @objectstack/spec from packages/types/package.json
  • Reverted BaseSchema: Restored packages/types/src/base.ts to its original definition where BaseSchema defines type and id properties directly instead of extending UIComponent
  • Updated lockfile: Synchronized pnpm-lock.yaml to reflect the removed dependency

Testing

  • ✅ Frozen lockfile installation works correctly
  • ✅ TypeScript compilation passes
  • ✅ @object-ui/types package builds successfully
  • ✅ All dependencies resolve without errors

The changes restore the types package to its original state, removing the incorrect dependency on an external package that was causing the CI failure.

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21141019742/job/60794817921#step:7:1


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel

vercel Bot commented Jan 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
objectui-docs Error Error Jan 19, 2026 2:57pm

@hotlong

hotlong commented Jan 19, 2026

Copy link
Copy Markdown
Contributor

@copilot 继续

The pnpm-lock.yaml was out of sync with packages/types/package.json.
The @objectstack/spec npm package (v0.1.1) doesn't export UIComponent interface,
so reverting to the original BaseSchema definition without external dependencies.

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>

Copilot AI commented Jan 19, 2026

Copy link
Copy Markdown
Contributor Author

@copilot 继续

Fixed the CI error in commit e423a5f. The issue was that pnpm-lock.yaml referenced @objectstack/spec as a workspace dependency, but the npm package doesn't export the UIComponent interface. I removed the dependency and reverted BaseSchema to its original definition. The frozen lockfile installation now works correctly.

Copilot AI changed the title [WIP] 引用: https://github.com/objectstack-ai/objectui/actions/runs/21141019742/job/60794817921#step:7:1 Fix CI lockfile error by removing @objectstack/spec dependency Jan 19, 2026
Copilot AI requested a review from hotlong January 19, 2026 14:58
@huangyiirene
huangyiirene marked this pull request as ready for review January 19, 2026 15:01
@github-actions

Copy link
Copy Markdown
Contributor

✅ All checks passed!

  • ✅ Type check passed
  • ✅ Tests passed
  • ✅ Lint check completed

@huangyiirene
huangyiirene merged commit 21ca482 into copilot/update-types-data-display Jan 19, 2026
3 of 4 checks passed
os-tesla pushed a commit that referenced this pull request Sep 13, 2026
…zod barrel

Two new exported symbols on `packages/types/src/zod/index.zod.ts`, plus the
ledger rows that record why the other two objectui#8499 arms stay unnamed
(objectui#9067, director seat, decision batch #121 item 5, maintainer
2026-09-12).

The barrel means one name, one node type. `InputShorthandSchema` stands for
two `type` literals and `UiCalendarSchema` for one, so both fit that meaning
and are named. `SemanticElementSchema` and `HtmlElementSchema` are family
schemas keyed by a tag `z.enum` — a name bound to either hands a consumer a
schema accepting every tag in the family — so both stay absent, and splitting
them into per-tag schemas was ruled out in the same record as expansion for a
consumer nobody has measured.

The absence is ledgered rather than left to the changeset that declared it:
`.changeset/*.md` is consumed and deleted at release, and a reason that lives
only there leaves a deliberate non-export looking exactly like a dropped line.
The two rows move to ABSENT_BY_DECISION in
`packages/types/src/__tests__/arm-named-export-8784.test.ts` quoting that
changeset's own sentence, the two named arms lose their rows because exporting
them makes the rows stale, and the non-export is written on the barrel beside
the `layout.zod.js` block the way RetiredKanbanNodeSchema's already is.

No accept set moves in either direction: both schemas already existed, were
maintained and were applied by the union. Only the barrel line is new.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011QreXiyMEqKLN4U5daMPVa
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Sep 17, 2026
…zod barrel (objectstack-ai#9405)

Two new exported symbols on `packages/types/src/zod/index.zod.ts`, plus the
ledger rows that record why the other two objectui#8499 arms stay unnamed
(objectui#9067, director seat, decision batch objectstack-ai#121 item 5, maintainer
2026-09-12).

The barrel means one name, one node type. `InputShorthandSchema` stands for
two `type` literals and `UiCalendarSchema` for one, so both fit that meaning
and are named. `SemanticElementSchema` and `HtmlElementSchema` are family
schemas keyed by a tag `z.enum` — a name bound to either hands a consumer a
schema accepting every tag in the family — so both stay absent, and splitting
them into per-tag schemas was ruled out in the same record as expansion for a
consumer nobody has measured.

The absence is ledgered rather than left to the changeset that declared it:
`.changeset/*.md` is consumed and deleted at release, and a reason that lives
only there leaves a deliberate non-export looking exactly like a dropped line.
The two rows move to ABSENT_BY_DECISION in
`packages/types/src/__tests__/arm-named-export-8784.test.ts` quoting that
changeset's own sentence, the two named arms lose their rows because exporting
them makes the rows stale, and the non-export is written on the barrel beside
the `layout.zod.js` block the way RetiredKanbanNodeSchema's already is.

No accept set moves in either direction: both schemas already existed, were
maintained and were applied by the union. Only the barrel line is new.


Claude-Session: https://claude.ai/code/session_011QreXiyMEqKLN4U5daMPVa

Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Sep 17, 2026
…ot barrel (objectui#9406) (objectstack-ai#9525)

Fixes objectstack-ai#9406

Implements decision batch objectstack-ai#133 item 2, letter (a) (maintainer
2026-09-14, recorded on the card). Nothing here is a judgement call of
this branch's: the ruling names the file, the act, the bump level and
the pin.

## The exact published delta

Two names join **one** list: the root barrel
`packages/types/src/index.ts`, on its existing `export type { ... } from
'./form.js';` clause, from the module `packages/types/src/form.ts`.

| name | declared in | was on `@object-ui/types/form` | was on
`@object-ui/types/zod` | root `@object-ui/types` |
|---|---|---|---|---|
| `InputShorthandSchema` | `form.ts` | yes | yes (objectui#9067 / PR
objectstack-ai#9405) | **added here** |
| `UiCalendarSchema` | `form.ts` | yes | yes (objectui#9067 / PR objectstack-ai#9405)
| **added here** |

**No other export moves.** Measured on the published artifact rather
than asserted: `packages/types` was built at the branch point and at
this head, and `dist/index.d.ts` differs by exactly one line, which
differs by exactly these two names inserted between `CalendarSchema,`
and `FieldValidationRules,`. Nothing else in that file changed, in
either direction.

The dispatch cautioned that this package's emit is not byte-reproducible
(measured on PR objectui#9517), so the comparison carries a
**same-source control**: two consecutive clean builds of byte-identical
source, compared before any normalisation. For `dist/index.d.ts` on this
tree they came back **byte-identical** (raw differing lines 0, sorted
differing lines 0), so the delta above is a reading and not emit noise.
Reported as measured: the instability that card saw on another emitted
file did not appear on this one, which the control establishes rather
than assumes.

The source diff is **one additive hunk**, 16 insertions and 0 deletions
on `index.ts` — two names and the comment that says why they are there.
The comment does not reach the published artifact (the emitted clause is
one comma-joined line), so the published surface change is exactly the
two names.

## Why it mattered more than a missing name

From the root entry point the compiler did not merely fail, it
**suggested a different component**. Reproduced live on this branch by
removing the two lines again and running the package's own `tsc -p
tsconfig.test.json`:

```
error TS2724: '"../index"' has no exported member named 'InputShorthandSchema'. Did you mean 'InputOTPSchema'?
error TS2724: '"../index"' has no exported member named 'UiCalendarSchema'. Did you mean 'CalendarSchema'?
```

`ui:calendar` and `calendar` resolve to different renderers, and
`InputOTPSchema` is not an input at all. An author who accepts the
suggestion writes an import that compiles and means something else.

## The pin derives the gap; it does not assert a pair

`packages/types/src/__tests__/form-barrel-mirror-9406.test.ts`. On every
run it reads `form.ts`'s own export list and the root barrel's
`./form.js` re-export list, and the verdict is the **set difference** —
so the declaration that lands in `form.ts` next month and is forgotten
fails it. A pin asserting "these two names are present" would have
passed that day, which is this class reopening a third time.

- Names deliberately left off carry a **ledger row with the reason**
(`ABSENT_BY_DECISION`), names nobody has ruled on carry one saying so
(`ABSENT_PENDING_DECISION`) — the two-ledger shape
`arm-named-export-8784.test.ts` settled for the zod barrel.
- **Rows cannot rot:** a row whose name `form.ts` no longer declares, or
which has since reached the barrel, fails the file and asks to be
deleted.
- Both populations carry controls, so a dark instrument fails instead of
passing: exactly one `./form.js` clause, the barrel list is a subset of
what the module declares, the four names the card measured all read
non-zero, and a star re-export from either module under the pin fails
rather than silently shortening the denominator.
- `SemanticElementSchema` / `HtmlElementSchema` are recorded as the
ruling asked, with the reason and the ruling that made them so
(objectui#9067, decision batch objectstack-ai#121 item 5), and **checked** — they are
declared in `layout.ts`, not `form.ts`, so they sit outside this pin's
population by construction, and the block fails the day either reaches
the root barrel. They are not added here.

## One finding, ledgered and reported rather than repaired

Running the derived pin over this list surfaced two more names in the
same state: **`CommandItem` and `CommandGroup`** (the element types of
`CommandSchema.groups` and of its `items`), reachable only through the
`/form` subpath while `CommandSchema` sits on the root list. That is
objectui#7697's shape exactly. The ruling authorises exactly two names
and says "additive, no other line moves", so they are ledgered as
**undecided** with the reason and handed to the dispatching seat for
their own card. This PR does not move them.

⚠️ A related correction to the filing card's framing, from the disk at
this branch point: the card reads "re-exports 28 of the 30 interfaces
`src/form.ts` exports", which conflates two populations. `form.ts`
exports 30 interfaces plus 2 type aliases; the barrel's list carried 28
names, of which 26 are interfaces. So the gap was **four** names, not
two — the two this ruling names, plus the pair above. The card's own
two-zero reading is confirmed unchanged: both names read 0 on the barrel
while `CalendarSchema` and `InputSchema` read non-zero in the same pass.

## Checks run before pushing

| check | how | result |
|---|---|---|
| the new pin | `pnpm exec vitest run
packages/types/src/__tests__/form-barrel-mirror-9406.test.ts` | 16
passed |
| the pin, with the change removed | same command, `index.ts` taken back
to the branch point | 1 failed, naming both missing names |
| the type-level leg, with the change removed | `tsc -p
tsconfig.test.json` | exit 2, the two TS2724 lines quoted above |
| package type-check | `pnpm --filter @object-ui/types run type-check`
(all three `tsc` legs) | exit 0 |
| package suite | `pnpm exec vitest run packages/types/` | 190 files,
4345 tests passed |
| package lint | `pnpm --filter @object-ui/types run lint` | exit 0, 0
errors |
| changeset declaration | `check-changeset-presence.mjs`, `pnpm
changeset:check`, `pnpm check:changeset-claims` | exit 0 |
| line citations | `pnpm check:new-line-citations` | exit 0 |
| control bytes | `pnpm check:control-bytes` and a direct sweep of the
diff | exit 0, no hits |

Both ablation legs restored from `HEAD` and verified by blob hash
against the `HEAD` blob, with `git diff HEAD` empty afterwards.
Repository-scale runs (`Lint`, `Type Check`, the test shards, `Build &
E2E`, `Build Docs`) are CI's.

## Changeset

`.changeset/9406-types-root-barrel-two-names.md`, **`minor`** on
`@object-ui/types` — the level the ruling sets, on the ground that this
is a published surface gaining two names, not on the size of the diff.

## For the Clause-2 contract review

The reviewed surface is one clause in one file. The published delta is
the two names in the table above and nothing else, established against
the built `dist/index.d.ts` with a same-source control. Both names were
already published on two other entry points of this same package, so the
third is aligned rather than widened; both subpaths are untouched and
every previously published name is still published. Draft, not enqueued,
no auto-merge, no labels written by this branch.

---
_Generated by [Claude
Code](https://claude.ai/code/session_011QreXiyMEqKLN4U5daMPVa)_

Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Oct 7, 2026
…/ xAxis / yAxis / series follow the spec retirement on the TS face and the dataset read path (objectui#11315) (objectstack-ai#11371)

Fixes objectstack-ai#11315
Clause-②: yes

`@objectstack/spec` 17.5.0 gave the dashboard widget its own chart
config carrier, `DashboardWidgetChartConfigSchema`, which retires
`type`, `xAxis`, `yAxis` and `series` (ADR-0021 · ADR-0049 D2; decision
batch objectstack-ai#121 item 1). objectui's Zod faces already refused the four by
reference. The TypeScript twin still compiled them, and the dashboard's
dataset widget still read three of them. This PR brings both into line.
The react `ObjectChart` tier, where the spec keeps the four authorable,
is unchanged, and it now has a control pin.

## What changed

- **TypeScript twin (`packages/types/src/complex.ts`).**
`DashboardWidgetSchema.chartConfig` keeps its index signature. `type`,
`xAxis`, `yAxis` and `series` are now typed by reference from the spec's
own members, the same way PR objectui#11310 typed `aria`: each is
`NonNullable` of `SpecDashboardWidget['chartConfig']`, indexed at the
key. Each resolves to the spec's retired-key type, so an authored value
is a compile error (TS2322). Only the key names are written here.
Whether a key admits a value is the spec's answer, so a key the spec
re-opened would compile again with no edit to this member.
- **Dashboard read path
(`packages/plugin-dashboard/src/DatasetWidget.tsx`).** The widget no
longer calls `mergeAuthoredPresentation`. It emits the dataset-derived
series and category axis as they are, and spreads no authored axes. A
comparison overlay no longer copies its primary's merged mark and axis,
because there is none. The `combo` entry in `CHART_TYPE_MAP` stays, so a
`combo` widget still draws as a combo, and the renderer picks each
series' mark. The chrome lowering (`chartConfigPresentation`) is
unchanged. `mergeAuthoredPresentation` and its two series types are no
longer re-exported from this module. The package index never exported
them.
- **`@object-ui/core` (`chart-presentation.ts`): comments only.** The
file header now names which keys each carrier may author. It also says
that `mergeAuthoredPresentation` has had no production caller since this
change. The `chartConfigPresentation` docblock no longer calls `aria`
"declared" or "pending objectstack#5175": since 17.5.0 it is a
tombstone. Criterion 2 now notes that the spec refuses
`chartConfig.type` on this carrier. The function's signature and
behaviour are unchanged.
- **Pins.**
-
`packages/types/src/__tests__/chartconfig-structure-retired-11315.test.ts`
follows the shape of the `aria` pin. On the TypeScript side, each key is
declared, is not `any`, and is the retired-key type
(`IsRetiredKeyType`), with `title` as the live control. A
`@ts-expect-error` sits on an authored literal for each key,
`chartConfig.series` among them, and a legal `{ title, showLegend,
colors }` literal is the control. On the Zod side, the twin,
`DashboardComponentSchema`, `safeValidateSchema` and
`StrictAnyComponentSchema` each refuse every key at `chartConfig.KEY`
with `invalid_type` and the spec's own message, read from the spec at
run time. A spec-standing case checks both halves of the carrier split:
the dashboard carrier refuses the four, and the base `ChartConfigSchema`
still admits them.
- `DatasetWidget.comboPresentation.test.tsx` is re-pinned as the
dashboard refusal. A `combo` widget still resolves `combo`. With the
retired combo shape authored, the series are byte-identical to the
derived ones, no axis is spread, the normalized `yAxes` equal the
no-`chartConfig` control, a `bar` widget stays a bar, the chrome still
lowers, and the overlays carry no mark.
- `DatasetWidget.chartConfig.test.tsx`: the REFUSED block now pins all
three structure keys as unread. Its header no longer cites
`ChartConfigSchema` or "pending objectstack#5175". The incidental `type:
'bar'` (a retired key) is dropped from the fixtures of the LOWERED
block.
-
`packages/plugin-charts/src/ObjectChart.inlineComboSeries-11315.test.tsx`
is new. It renders a real `ObjectChart` with inline rows and counts the
recharts marks and axes. An authored `series` draws 1 bar, 1 line and 2
y-axes. An explicit `specType: 'combo'` authoring an area plus a line
draws exactly those. The control with no per-series mark draws 2 bars.
- **Changesets.**
- `@object-ui/types` **minor** (TypeScript break, migration example
included).
- `@object-ui/plugin-dashboard` **minor** (rendering break: stored
widgets that still carry the keys render the derivation).
- An empty-frontmatter declaration for `@object-ui/core` (comments) and
`@object-ui/plugin-charts` (test only).
- Two pending changesets this change made false are corrected here. In
`4044-chartconfig-aria-tombstone.md`, "every other `chartConfig` key
keeps its previous typing" now names the four keys.
`10132-dashboard-i18n-declared-not-resolved.md` gains a note that its
axis-title point no longer reaches a dashboard, and its series-label
aside no longer names `DatasetWidget` as the overriding caller. Both
edits are prose corrections to changesets this PR does not own.
`check-changeset-overwrite` lists them, report-only.

## Zone 2 measurements (dispatch order)

1. **Reproduced on `origin/main` `5638529e67`.**
- TypeScript: a probe of four `DashboardWidgetSchema` literals
(`chartConfig.series` / `xAxis` / `yAxis` / `type`) plus a live control
compiled with `tsc` exit 0. The positive control (`chartConfig.aria`) in
the same probe failed with TS2322, so the probe could fail. After this
change, the same probe exits 2 with four TS2322s, and the control line
still compiles.
- Reader: `mergeAuthoredPresentation(derived, { series, xAxis, yAxis })`
returned `chartType: 'line'`, `yAxis: 'right'`, `axes.xAxis.title` and
two `axes.yAxis` entries.
- Zod: the twin, `DashboardComponentSchema`, `safeValidateSchema` and
`StrictAnyComponentSchema` refuse all four at `chartConfig.KEY` with
`invalid_type`, and a `{ title }` control parses on all four faces.
2. **Another declared home? None.** The installed 17.5.0 dashboard
widget declares `id`, `title`, `description`, `type`, `chartConfig`
(appearance only), `colorVariant`, `requiresObject`, `requiresService`,
`filter`, `compareTo`, `dataset`, `dimensions`, `values`, `layout`,
`options` (`dateGranularity`, `sortBy`, `sortOrder`, `limit` and
`stageOrder` declared, `$loose`), `filterBindings` and
`suppressWarnings`. Retired as tombstones: `actionUrl`, `actionType`,
`actionIcon`, `responsive` and `aria` on the widget, and `aria`, `type`,
`xAxis`, `yAxis` and `series` inside `chartConfig`. Nothing declares a
per-series mark or a second value axis. The `series` tombstone text says
per-series appearance "is not authorable on a dataset-bound widget", and
the `yAxis` one says "A second axis is a second measure, not a second
axis declaration". The spec's liveness ledger (objectstack
`packages/spec/liveness/dashboard.json`, the `series` row) records it as
a ruled cost: "The per-series mark type that made a dataset-bound COMBO
chart authorable goes with the key". The widget `type` enum still
carries `combo`, which this PR keeps rendering. So the dashboard combo
presentation retires on this carrier, and nothing was escalated.
3. **Callers of `mergeAuthoredPresentation`.** It had one production
caller, `DatasetWidget`, plus that module's own re-export, which no
importer used. Two tests also call it directly:
`chart-presentation.axisTitleI18n-10132.test.ts` in core and
`ChartRenderer.axisTitleLocale-10132.test.tsx` in plugin-charts. The
react `ObjectChart` tier never called it. `ObjectChart` hands
`schema.series` / `xAxis` / `yAxis` to `ChartRenderer`, and
`normalizeChartSchema` reads them there. So the carriers needed no
switch, because the caller is the carrier. The dashboard call was
removed, the function keeps its signature, and no second copy of the
merge logic exists. `plugin-report` calls `mergeAuthoredSeries` (not
this function), and `ReportChartSchema.series` is still live, so that
path is unchanged.
4. **The TypeScript face.** ⚠️ The dispatch premise that
`WIDGET_CHART_STRUCTURE_RETIRED` is importable does not hold. In the
installed spec it is a module-private message builder, `(key, carried,
instead) => string`. It is absent from the `@objectstack/spec/ui` export
list and from every `.d.ts`, so nothing can be read from it. The four
keys are therefore typed exactly as PR objectui#11310 typed `aria`: by
reference from `SpecDashboardWidget['chartConfig']`, the exported spec
type whose members those tombstones build. No local list of retired
keys, and no local `never`. Proof: the `@ts-expect-error` pins (they go
stale if a key compiles again, see ablation 2) and the legal-literal
control.
5. **Combo pin: both routes.** The dashboard file is re-pinned as the
refusal, and a new `ObjectChart` control in plugin-charts pins that an
authored `series` still draws a combo.

## Verification (union at head `25e43c3259`, after the last commit)

- **Build:** `pnpm --workspace-concurrency=2 --filter
'@object-ui/plugin-dashboard^...' --filter
'@object-ui/plugin-charts^...' build` → 12 packages built (the `^...`
direction is upstream dependencies). `@object-ui/types`
`dist/complex.d.ts` carries the new members.
- **Type-check:** `@object-ui/types`, `@object-ui/core`,
`@object-ui/plugin-charts` and `@object-ui/plugin-dashboard` all print
`type-check: Done`. Each runs `tsc --noEmit` plus `tsc -p
tsconfig.test.json`, and `--listFilesOnly` confirms the new and edited
tests are in those programs. Downstream consumers of the narrowed face
(`DashboardWidgetSchema` / `DashboardComponentSchema` importers):
`@object-ui/sdui-parser`, `@object-ui/plugin-list` and
`@object-ui/plugin-designer` print `type-check: Done` against the
rebuilt dist. `@object-ui/app-shell` and `examples/schema-catalog` are
left to CI. A grep finds no dashboard `chartConfig` key use in either.
The control: the same grep does hit app-shell's list-view `chartConfig`,
which is a different carrier.
- **Tests:** `pnpm exec vitest run packages/types/
packages/core/src/utils/ packages/plugin-dashboard/
packages/plugin-charts/` → `Test Files 653 passed (653)`, `Tests 12268
passed | 15 skipped (12283)` (lock verdict `command-exit 0`).
- **Reverse verification through a consumer:** a temporary
`packages/plugin-dashboard/src` file typing a `DashboardWidgetSchema`
from `@object-ui/types` (the rebuilt dist) with `chartConfig: { title,
series }` → `tsc` exit 2, `TS2322 … is not assignable to type
'undefined'` at `series` only. The file was removed under a trap, and
`git status` is clean afterwards.
- **Gates:** `check:new-line-citations` (`0 new citation(s)`),
`check:control-bytes` OK, `node scripts/check-changeset-presence.mjs`
(`8 source file(s) of 4 released package(s) changed, and this change
declares 3 changeset(s)`), `changeset:check` OK,
`check:changeset-claims` (the 10 pending bodies naming touched files
were each read; none concerns `chartConfig`),
`check:pending-changeset-literals` OK, `check:test-path-roots` OK,
`check:vi-mock-specifiers` / `-inherit` / `-override-shape` OK,
`type-check:coverage` (43/43), `check:spec-symbols` OK,
`check:installed-pin-claims` OK, `check:unreferenced-sources` OK,
`check:component-surface-parity` (report-only, no finding on
`chartConfig`).
`apps/console/src/__tests__/registry-inputs-spec-parity.test.ts` was not
run, because no registration input text changed.
- **Lint, narrowed:** the 8 changed TypeScript files were linted with
the root config (`eslint --no-inline-config --format json`): 8 files, 0
errors. Warnings per modified file did not rise against the base blobs
(`complex.ts` 9 → 9, `DatasetWidget.tsx` 12 → 11, the combo test 13 → 5,
the chartConfig test 2 → 2). The new plugin-charts test has 2
`no-explicit-any` warnings, from the recharts mock its siblings use. The
config enables no type-aware linting, so this diff cannot move another
file's verdict. The repo-wide `pnpm lint` belongs to CI.

### Ablations

Each ablation ran from committed state through `ablation-replace.mjs`.
The anchor hit was proven, and each restore was proven by the blob
equalling HEAD plus an empty `git diff HEAD`. Every subject is imported
by relative source path, so no `dist` was involved.

1. **The merge put back into `DatasetWidget`** (import plus `series:
mergeAuthoredPresentation(…).series` and
`...mergeAuthoredPresentation(…).axes`). Predicted 7 red, and 7 went
red: 5 in the combo file and 2 in the REFUSED block. The other 14 stayed
green: the `combo` family, the no-`chartConfig` control, the forwards,
and `type` / `aria`.
2. **`series?:` deleted from the TypeScript member** → `tsc -p
tsconfig.test.json` exit 2. The output had `TS2322` on
`seriesTombstoned` and `TS2578` (unused `@ts-expect-error`) on the
authored `series` literal.
3. **`normalizeChartSchema` stops reading `series[].type`**
(`str(raw.chartType) ?? str(raw.type)` → `str(raw.chartType)`).
- On the first run, only the bar-plus-line case went red. The
explicit-`combo` case stayed green, because a combo's positional default
(a bar, then lines) draws the same counts.
- That case now authors an area and a line. The re-run turned both
authored cases red, and the no-mark control stayed green.

## Acceptance notes

- **`mergeAuthoredPresentation` and `axisPresentation` have no
production caller now.** They are published exports of
`@object-ui/core`. They were kept on purpose: the claim's Clause-②
treats the function as staying exported, and deleting it would also
rewrite `ChartRenderer.axisTitleLocale-10132.test.tsx` in plugin-charts,
which is outside this claim's file surface. The comments in this file
say so. Deleting both, and re-homing that render pin onto a chart node
that authors its own axes, is the follow-up. Carrier: none.
- **Comments elsewhere that this change makes stale, left alone because
they are outside the surface.** Carrier: none.
- `packages/types/src/zod/data-display.zod.ts`: "`DatasetWidget` →
`mergeAuthoredPresentation`".
- `packages/plugin-report/src/DatasetReportRenderer.tsx`: two places say
the dashboard makes the same series merge.
- `chart-presentation.axisTitleI18n-10132.test.ts`:
"`mergeAuthoredPresentation` is what `DatasetWidget` calls".
- `ChartRenderer.axisTitleLocale-10132.test.tsx`: "the path a
dataset-bound surface actually takes".
- `content/docs/plugins/plugin-charts.mdx`: "the `ChartAxis` a dashboard
widget's `chartConfig` uses".
- **Comments stale since 17.5.0 that this change does not touch.**
Carrier: none.
- `DashboardRenderer.tsx` (inline relay): "declared as the spec's full
`ChartConfigSchema`", and objectstack#17385 described as still open.
- `DashboardChart.chartConfig-4044.test.tsx`: "objectstack#17385 owns
the precedence … Until it answers".
- `DatasetWidget.chartConfig.dom.test.tsx`: "pending objectstack#5175".
- The pending changeset `dashboard-inline-chartconfig-4044.md`, which
says the same about `ChartConfigSchema` and objectstack#17385.
- Per the seat's ruling, these negative pins are corrected only where
this PR already edits the file.
- **Observation on a combo with `compareTo`.** Every series now takes
the combo's positional mark, overlays included, so an overlay can draw
in a different mark from its own measure. Before this change, the same
happened to any combo that authored no `series`. This is the ruled cost
of the retirement, not a new defect class. No public-entry reading was
taken. Carrier: none.
- **Same-day churn:** `origin/main` moved 3 commits since the branch
point (objectui#11361, objectui#11359, objectui#11346). None touches
this diff's files, and `git merge-tree` is clean, so no merge was
needed.

Dev session: `https://claude.ai/code/session_0122Knsowci76D2rBWReCzzZ`
(dispatched by the `domain:ui` seat 1 PM loop).

---
_Generated by [Claude
Code](https://claude.ai/code/session_0122Knsowci76D2rBWReCzzZ)_

---------

Co-authored-by: Claude <noreply@anthropic.com>

This branch had an error being deployed

1 failed deployment
Preview — e423a5fe Deployed Jan 19, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants