Uh oh!
There was an error while loading. Please reload this page.
docs(types): declare the gantt dependencyField deprecation on both faces - #6826
Merged
Merged
Conversation
`ObjectGanttSchema` declares two spellings of one thing and reads them with a `||`. `dependenciesField` is the spec's key; the singular `dependencyField` has no spec counterpart, and until #6051 it was the only one declared — so the published type taught the non-spec spelling and hid the canonical one. Mark the singular `@deprecated` on both published faces (the TS interface and its zod mirror), naming the plural as canonical, following the idiom `KanbanConfig`'s pre-#2231 aliases already carry. Nothing is removed: the `||` read stays, both spellings still parse, and two pins hold that in place. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This was referenced Aug 29, 2026
os-sam
marked this pull request as ready for review
August 30, 2026 06:17
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#6470
Authored by the
domain:uiexecution seat, sessionsession_01CRJge11jso9TpXRWFt1Z49.Verified on
7d9607b7f— every number below was read from a run on that commit.The ranking was missing, not the behaviour
ObjectGanttSchemadeclares two spellings of one thing, andgetGanttConfig'sflat branch reads them with a
||:dependenciesFieldis the spec's key (@objectstack/specGanttConfigSchema.dependenciesField). The singulardependencyFieldhas nospec counterpart, and until #6051 declared the plural it was the only
dependencies spelling this interface carried — so for the whole time the alias
existed, the published type taught the non-spec key and hid the canonical one.
What a reader could not resolve was the ranking. The two were declared as
equals: nothing on either face said which one to author, so an author — or an AI
writing metadata, which is the reader this project optimises for — had a coin
flip between a spec key and pre-spec vocabulary. This PR turns that coin flip
into a fact the type itself carries.
What landed
Both published declaration faces now mark the singular:
packages/types/src/objectql.ts—@deprecatedJSDoc on the member, namingdependenciesField, and stating that the||read keeps it working so nobodyreads the tag as a removal notice. The canonical key's own docblock twenty
lines down now points back at it.
packages/types/src/zod/objectql.zod.ts—/** @deprecated legacy alias for the spec's dependenciesField */plus.describe('Deprecated alias for dependenciesField').The zod half is the one that is machine-readable:
.describe()is a runtimestring on the schema object, so a gate or a generated form can ask, where a
JSDoc only reaches an editor.
This adopts a ruled idiom rather than inventing a second one.
KanbanConfig's pre-#2231 aliases (groupField,cardFields, andGalleryConfig.imageField/TimelineConfig.dateField) already carry exactlythis pair of markers for exactly this shape — a published objectui alias whose
spec counterpart is spelled differently.
dependencyFieldnow reads the same way,and a pin asserts the description matches that convention's prefix so a future
divergence is a decision instead of a drift.
The interaction with #6822 was checked, and they should NOT share a shape
The dispatch order asked for this before a mechanism was picked. #6822 (open; the
PR for #6674, which remains open and is untouched here) adds
ComponentDeprecation/AuthoringSurfaceandRegistry.deprecationFor(type, surface)to@object-ui/core. Read in full. Itis a different mechanism for a different thing, and converging them would be
wrong on two independent counts:
deprecated (
div,span) — a statement about a registration, which is why itlives on the registration. This card is about one key inside a schema. There
is no registration to hang it on.
ComponentDeprecationlivesin
@object-ui/core.@object-ui/typesis the protocol package —AGENTS.md §3, "Zero deps. No React." — and
coredepends ontypes, not theother way round. A schema key in
typescannot consume acoretype withoutinverting the monorepo's dependency graph.
So this is not a third spelling of "this is deprecated" — it is the existing
key-level spelling, applied to a key, while #6822 introduces the type-level
spelling for types. Nothing here contradicts #6822's design, and its central
design decision (scope travels with the declaration, so no consumer re-derives an
exemption locally) does not have an analogue here: a schema key has one authoring
surface, not two.
Nothing was removed, and two pins hold that
⛔ The card's title fences this: deprecate in place, removal excluded, deferred
to enforce-or-remove. The
||limb is untouched, both spellings still parse, andthe accept set is byte-for-byte what it was. The pins fail in both directions,
because a deprecation has two opposite failure modes:
packages/types/src/__tests__/gantt-dependency-field-deprecated-alias.test.ts(15 tests) — the marker is present, tagged, and names the replacement; and the
alias is still declared on both faces, still parses green alone and alongside the
canonical key, and is still type-validated (
dependencyField: 5is stillrefused). A
@ts-expect-errorpins the TS member: delete it and it resolves toanythroughBaseSchema's index signature, the directive goes unused, and thebuild fails TS2578 naming the removal. Controls assert the canonical key is not
marked, and that the doc-block anchor cannot drift onto a twin.
packages/plugin-gantt/src/ObjectGantt.dependencyAlias.test.tsx(6 tests) — thetwo spellings resolve to the same config. The fixture points them at different
record fields (
legacy_predsvscanonical_preds) so the resolved config isvisible in the rendered tasks; a fixture using one field could only prove
something resolved, not which limb produced it. Also pinned: the canonical key
wins when both carry a value, and — recorded, not designed — an empty
dependenciesFieldfalls through to the alias, which is a property of||that??would not have. The enforce-or-remove card inherits the real acceptsemantics instead of re-deriving them.
Reverse verification, both legs rebuilt and confirmed on disk
Run from the committed state, so the restore leg had a real reference.
|| schema.dependencyField— mutation confirmed on disk before therun (injected text
grep -c= 1, deleted text = 0, blob hash 9c336e71 vsHEAD's b8e552ad). Result: 3 failed | 3 passed, and the three that failed
are exactly the singular-dependent cases; the canonical-read, canonical-wins
and neither-authored cases stayed green. A blanket red would have been the
weaker signal.
@deprecatedtag — mutation confirmed the same way (hash39a1b475 vs HEAD's 7ab4ca93). Result: 1 failed | 14 passed, failing on
tags that block @deprecatedalone.Both restores proved by observation, not exit code:
git diff HEADempty,working blob hash equal to the HEAD blob, and the deleted text present again.
Does anything in-repo author the singular? Measured: nothing does
The dispatch order asked, because the count decides how urgent eventual removal
is. Full-tree grep excluding
node_modules,distand.git, with the plural asa positive control (23 files — the walk works):
Exactly one in-repo site authored the singular, and it was documentation:
packages/plugin-gantt/README.md'sObjectGanttSchemaexample. Every other hitis a declaration, a read site, or prose about the alias. Specifically zero
authoring in runtime code, example apps, or the authored-metadata corpus — all
three gantt schemas under
examples/schema-catalog/src/schemas/plugin-gantt/usethe plural, as does
content/docs/plugins/plugin-gantt.mdxand the README's sevenother mentions.
That one README example is migrated here, with the alias named as legacy beside
it. It is in-scope rather than scope creep on two counts: it is the same defect
the card names — a published surface teaching the non-spec spelling — and
AGENTS.md #2 makes the package README part of done for a change like this. Its
correct form was not a judgement call: the same file already authored the plural
seven times.
After it, the only authoring-shaped occurrences left in the repo are the fixtures
inside the two pin tests above, which exist precisely to prove the alias still
works.
So in-repo urgency for removal is nil. The half that cannot be measured from
here is the one that licenses deleting a key from a published package: whether
anything outside this repository authors it. The deprecation window is the answer
to that half — it turns a silent break into a warned one.
Verification
Union run on
7d9607b7f, the final commit.vitest run packages/types/ packages/plugin-gantt/pnpm --filter @object-ui/types --filter @object-ui/plugin-gantt type-checkDone(each runstsc --noEmitandtsc -p tsconfig.test.json)check:doc-snippetsSemantic phase: 267 of 267 block(s) judged, 0 failedcheck:readme-exportsOK (… 383 self-imports judged, 383 real, 0 wrong-path, 0 fabricated)check:control-bytes·check:doc-fences·check:doc-types·check:vi-mock-specifiers·check:spec-symbols·changeset:checkcheck-changeset-presence4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)check:lint-coverage46/46 packages linted, 0 with outstanding errorsThe typecheck really covers the new tests — not assumed.
tsc -p tsconfig.test.json --listFileswas grepped for each new file in its own package:1 hit each. A
type-checkthat excluded them would have said nothing about the@ts-expect-errorpin.Both doc gates first returned PRECONDITION NOT MET on an unbuilt tree
(
check:doc-snippetsexit 2, saying in its own words "this is 'I could not run',NOT 'I ran and found errors'";
check:readme-exportsreporting a collapsedpopulation). Those were not findings and are not reported as such — the packages
were built and both gates re-run to the greens quoted above.
ESLint was narrowed to the changed files, and the narrowing is declared. Not
pnpm lintover the repo, which CI runs anyway. Three pieces of evidence, so thisreads as a measurement rather than a skip: (1) the judged population came from
ESLint's own config resolution, not a guess about which files count; (2) the count
came from
--format json— 4 lintable files changed, 4 judged, 0 errors,23 warnings; (3)
eslint.config.jsdeclares noprojectService, noparserOptions.projectand noproject:, so type-aware linting is off and thisdiff cannot move the verdict on any file it did not touch. Of the 23 warnings, 19
are pre-existing
no-explicit-anyinobjectql.ts(none near the edited lines)and 4 are in the new test's mock props — the sibling
ObjectGantt.blockPrecedence.test.tsxcarries 13 of the same, andcheck-lint-coverage.mjsrecords that--max-warningsis deliberately unset.CI was not waited on: per the dispatch order the merge queue is not scheduling
merge_groupjobs, and the report is delivered at draft-PR time.Generated by Claude Code
Generated by Claude Code