Skip to content

Track the @objectstack family at 17.0.0-rc.6 — the adaptation surface beyond what objectstack#7100 could carry #4167

Description

@yinlianghui

Filed from objectstack#7100, whose PR (#4169) bumps @objectstack/* from ^17.0.0-rc.5 to ^17.0.0-rc.6 because the global_nav retirement it implements cannot compile at rc.5. The bump turned out to be far more than a lockfile move. This card holds what that PR does not close.

Scale of the release, measured

Diffing the resolved dist/ui/index.d.ts of rc.5 against rc.6: 40 exports removed, 29 added. Four deliberate moves, not scatter:

  1. Every …Input alias retired, and the bare name moved onto the input side. ActionInput, AppInput, PageInput, DashboardInput, ThemeInput, ReportInput, ReportChartInput, DatasetInput, ReportSortInput, NavigationContributionInput, InlineActionInput, JoinedReportBlockInput, DatasetDimensionInput, DatasetMeasureInput. Where rc.5 had X = z.infer / XInput = z.input / XParsed = z.infer, rc.6 has X = z.input / XParsed = z.infer. Re-pointing by NAME silently swaps parsed for input; each binding has to be re-pointed by SIDE.
  2. The standalone i18n vocabulary retired — I18nObject, LocaleConfig, PluralRule, DateFormat, NumberFormat + …Schema twins — and I18nLabel widened from string to string | Record< string, string >, with InlineLocaleMap and resolveI18nLabel added. Consumer story: I18nLabel now admits an inline per-locale map — audit every read the compiler cannot see, and give Studio a way to author one #4163.
  3. The widget-manifest vocabulary retired — WidgetManifest, WidgetSource, WidgetProperty, WidgetEvent, WidgetLifecycle + twins. Unlock: spec rc.6 vacated WidgetManifest / WidgetSource — the Runtime… prefixes may be reclaimed #4164.
  4. Refinements added to schemas this repo derives from, which zod 4 refuses to .extend(). Contract conflict: spec rc.6 refines a date GlobalFilter.defaultValue to reject { preset } — the exact shape objectui's normalizer produces and stored dashboards carry #4165.

Plus, outside ui: SharingRuleSchema gained the seven ADR-0010 envelope keys, ActionSchema gained description, FlowNodeSchema became pipe-wrapped, element:record_picker lost displayField/searchFields/multiple to ADR-0087 D2 tombstones, and page:footer/page:section/page:sidebar moved from EmptyProps to the shared PageContainerProps.

Already repaired in PR #4169 — do not redo

Full workspace build green (turbo run build, 44/44). Full suite: 14,609 / 14,615 passing.

Compile fallout: types/theme.ts (ThemeInput→Theme), types/spec-report.ts (four aliases re-pointed by side), types/index.ts (five dead i18n re-exports dropped), core/ActionRunner.ts (ActionInput→Action), 8 render sites for the widened I18nLabel, types/zod/complex.zod.ts (.extend→spread, see #4165).

Runtime fallout: both flow-schema access paths, clientValidation.optOuts (inverted — the create door now accepts a stamped _packageId), clientValidation.viewDiagnostics (fixture + a new leaf-union pin), components record-picker parity fixture, console registry parity carve-out (SPEC_SHAPE_EMPTY_ON_THE_PIN deleted per its own instruction), the i18n residue ratchet, SPEC_ACTION_KEYS (+description), and two spec-parity lists.

What is left — this card

1. check:spec-symbols — 13 name collisions. Wired into ci.yml's Type Check job, currently the main red. rc.6 published 9 names this repo already declares locally, plus 4 pre-existing:

@object-ui/app-shell  MetadataState, resolveI18nLabel
@object-ui/core       DATE_RANGE_PRESETS
@object-ui/fields     AddressValue
@object-ui/layout     BreakpointColumnMap, BreakpointOrderMap
@object-ui/react      MetadataState, NavigationMode, resolveI18nLabel
@object-ui/types      DateRangePreset, KanbanConfig, CalendarConfig, GanttConfig

Each is objectstack#4115-class triage with three possible outcomes (derive by reference / rename to a declared dialect + tripwire / ALLOW with a reason), and the right answer differs per symbol — resolveI18nLabel in particular is a genuine name clash over two DIFFERENT vocabularies (objectui's translation-key ref vs the spec's inline locale map), which is a naming decision rather than a derivation.

2. Two stale exemptions in apps/console/src/__tests__/registry-inputs-spec-parity.test.ts. rc.6 now declares keys the exemption list still covers, and element:record_picker does not publish three keys the spec declares:

carries no stale exemption:  page:header.recordChrome, page:header.showStar, page:header.showCopyId,
                             page:accordion.variant, page:tabs.tabStyle,
                             element:record_picker.labelField/valueField/label,
                             page:card.children, page:section.children,
                             page:footer.children, page:sidebar.children
record_picker publishes:     sort, limit, emptyText

Mostly mechanical (delete the exemption, publish the input with a description), but each published input is an authoring-surface addition that wants its own read — the same class objectui#3808/#3830 handled one key at a time.

3. #4165 blocks ready — the GlobalFilterSchema refinement vs the { preset } form stored dashboards carry. Maintainer + spec owner.

Ownership, one line each

Sequencing note

objectstack#7100 and objectstack#6955 both need rc.6 underneath. As measured, the bump is a chore(deps) card the size of objectui#3560 / PR #3568 ("track the @objectstack family at 17.0.0-rc.5 and restore green", whose changeset ran to 105 lines of FROM→TO prose). Folding it into a retirement card was reasonable on the information available at dispatch — objectui's ^17.0.0-rc.5 ranges already admitted rc.6, so the move looked lockfile-only. It is not reasonable now: the bump should be its own card, and #7100's removals should ride on it. PR #4169 currently carries both, because splitting them today would only manufacture the red intermediate state the coupling exists to avoid.

Activity

  1. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Triage: pm:blocked, with the machine half appended to the body (Blocked-by: #4165) so the unlock sweep can find it — the body's own sequencing section states "#4165 blocks the whole bump", and #4165 is now a filed needs-user-decision card (the GlobalFilter.defaultValue refinement vs the { preset } form objectui produces and stores). The other rc.6 red-test items listed here (flow-node schema access strategy, the sharing_rule create door, the bare Invalid input diagnostics, ActionSchema.description) ride behind the same bump, so the card blocks as a unit.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. self-assigned this
    on Aug 10, 2026
  3. yinlianghui commented on Aug 10, 2026

    @yinlianghui
    CollaboratorAuthor

    Claim: PM loop round 6 (rolling slot refill; the #7100 dev's inventory marks this self-contained and needing no ruling — dispatched to shorten the v17 critical path while #4165 waits)
    Session: session_017Qqyix2QcnpUC9XeYVDzx3 · Branch: claude/issue-4167-rc6-adaptation-remainder · Worktree: objectui-issue-4167
    File surface: per-symbol renames/triage for the 13 check:spec-symbols collisions + the console registry-inputs-spec-parity exemption-list refresh (12 stale entries, 3 newly-declared record-picker inputs). Serial constraints: STACKS on claude/issue-7100-global-nav-studio-retire (PR #4169, draft) — this card's premise (rc.6 resolved) only exists on that branch; do NOT branch off main. Risk accepted and recorded: if #4165 resolves as route A (rc.7 rebuild), this work rebases onto the new bump — the symbol collisions are rc.6-introduced and expected to persist into rc.7 unless upstream renames, so the work survives either route.
    Container & model: M, mode:subagent, model: opus

    Scope guard: the 13 collisions get the objectstack#4115-class PER-SYMBOL triage (which side renames, or alias-and-deprecate — read that precedent's method; do not blanket-rename). The parity exemptions: each of the 12 stale entries removed WITH the declaration that obsoletes it verified; the 3 new record-picker inputs declared per the #3830/#4041 worked shape. ⛔ Nothing from #4163/#4164/#4165's territory rides along.


    Generated by Claude Code

  4. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    CollaboratorAuthor

    Measured delta from #4223 (an unrelated app-shell card that merged current main): three red surfaces beyond items 1 and 2, all from the same rc.6 bump. Items 1 and 2 reproduce exactly as this card describes — same symbol list, same key lists — so this is additive, not a re-report.

    Measured on main merged into a feature branch, @objectstack/spec resolving to 17.0.0-rc.6:

    a. scripts/__tests__/quick-reference-current-release-4143.test.ts — 3 failures. QUICK_REFERENCE.md's "Current Release" block still quotes ^17.0.0-rc.5 for both @objectstack/spec and @objectstack/client, while the manifests it derives from now declare ^17.0.0-rc.6:

    AssertionError: QUICK_REFERENCE.md must state the client range as "^17.0.0-rc.6":
      expected '`@objectstack/client` ^17.0.0-rc.5 (declared by `apps/console/package.json`
      and `packages/data-objectstack/package.json`)' to contain '^17.0.0-rc.6'
    
    AssertionError: QUICK_REFERENCE.md's "Current Release" block states
      ["^17.0.0-rc.5","^17.0.0-rc.5"], which no manifest in this tree produced.
      Derived values are: ["17.4.0","^17.0.0-rc.6","≥22","≥9","10.31.0","18.x","19.x","≥5.0"]
    

    Pure documentation follow-through — the test names its own fix.

    b. packages/plugin-detail/src/__tests__/recordDetailsInputs.spec-parity.test.ts:123 — 1 failure. record:details — the spec really takes OBJECT sections — the id-list spelling is gone, not unioned in, asserting expected false to be true. Same family as item 2 (a registry-vs-spec parity pin), different package, so it is not covered by the apps/console carve-out work.

    c. packages/app-shell/src/utils/resolveActionParams.test.ts — 3 type errors, in the tsconfig.typetests.json project. The widened I18nLabel reaches one more site than the eight render sites the card records as repaired:

    src/utils/resolveActionParams.test.ts(245,39): error TS2322:
      Type 'ActionParam' is not assignable to type 'RawActionParam'.
        Types of property 'label' are incompatible.
          Type 'string | Record< string, string > | undefined'
            is not assignable to type 'string | undefined'.
    

    Also at 345,28 and 358,11. Worth flagging separately because pnpm --filter @object-ui/app-shell type-check runs tsc --noEmit && tsc -p tsconfig.typetests.json — the first command is clean and only the second fails, so a check that stops at tsc --noEmit reads green.

    Attribution evidence

    Each of these was isolated by reverting the unrelated card's diff to main and re-running on the identical tree:

    with the feature diff:     Tests  6 failed | 60 passed (66)
    with the diff removed:     Tests  6 failed | 60 passed (66)   ← identical
    

    and the same for the typetests errors (byte-identical output either way). Independently, main itself is red: the Type Check job failed on Verify spec-named symbols are derived, not hand-written at both 38ab5054f and a9a67ec5b, the latter being the base of the PR that measured this.

    Why this is worth a line here

    Every PR opened against current main inherits all of it, and the shape is confusing: Lint is green, Type Check is red, and two of four test shards are red — a mix that reads like the PR's own breakage until the shard logs are opened and every failure turns out to be in a package the PR never touched. Until this card lands, a red Type Check plus red shards 2 and 3 is the expected baseline rather than a signal about the change under review.


    Generated by Claude Code

  5. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    CollaboratorAuthor

    Measured from #4211's dispatch (PR #4224), which inherited this red — adding the items "What is left" does not currently enumerate, so PR #4189 landing does not leave main green by surprise.

    Method: origin/main @ a9a67ec5b checked out standalone in a detached comparison worktree, pnpm install (resolves @objectstack/spec@17.0.0-rc.6), no PR commit present. Every item below reproduces there byte-for-byte identically to the PR branch, so none of it is #4224's.

    Already covered here — confirming, not adding. Item 1 (check:spec-symbols) reproduces; CI reports 8 collisions across @object-ui/react and @object-ui/types where this card lists 13, the difference presumably being the dist state of the packages the gate reads. Item 2 reproduces with exactly the key list quoted above, both halves.

    Not enumerated above — four test failures and three tsc errors. The 14,609 / 14,615 line records that six cases were knowingly left failing, but only two of the six (the console parity pair, item 2) appear in the worklist. The other four, plus a tsc failure that is not a name collision:

    1. scripts/__tests__/quick-reference-current-release-4143.test.ts — 2 cases. QUICK_REFERENCE.md still states the client range as ^17.0.0-rc.5 while the manifests now derive ^17.0.0-rc.6. The test's own message names the fix and the reason it is a test rather than a doc nit:

      QUICK_REFERENCE.md must state the client range as "^17.0.0-rc.6": expected
      '`@objectstack/client` ^17.0.0-rc.5 (d…' to contain '^17.0.0-rc.6'
      
      QUICK_REFERENCE.md's "Current Release" block states ["^17.0.0-rc.5","^17.0.0-rc.5"],
      which no manifest in this tree produced. … Derived values are:
      ["17.4.0","^17.0.0-rc.6","≥22","≥9","10.31.0","18.x","19.x","≥5.0"].
      

      Purely mechanical, and it is the one item here that any dev can close without a judgment call.

    2. packages/plugin-detail/src/__tests__/recordDetailsInputs.spec-parity.test.ts — 2 cases, at :123 and :124 (the objectForm.data?.sections?.[0] assertion). Same family as item 2's console parity but a different package, so a fix scoped to apps/console will not reach it.

    3. packages/app-shell/src/utils/resolveActionParams.test.ts — 3 tsc errors, and this one is a different kind of item from everything in the worklist — a type-assignability break, not a name collision:

      src/utils/resolveActionParams.test.ts(245,39): error TS2322: Type 'ActionParam' is not assignable to type 'RawActionParam'.
      src/utils/resolveActionParams.test.ts(345,28): error TS2322: …
      src/utils/resolveActionParams.test.ts(358,11): error TS2322: …
      

      It reads as fallout from move 1 in the "Scale of the release" section — X = z.infer / XInput = z.input becoming X = z.input / XParsed = z.infer — i.e. a binding that still needs re-pointing by side, in a package whose entry in the item-1 collision list (MetadataState, resolveI18nLabel) would not lead anyone to look here. Worth naming explicitly because it fails the same Type Check job as check:spec-symbols: the gate runs first and exits non-zero, so these three are invisible until the collisions are triaged, and would surface as a "new" red the moment PR fix(deps): triage the 14 rc.6 spec-symbol collisions and refresh the console parity exemptions (#4167) #4189 goes green.

    Ordering consequence, one line: Type Check cannot go green on check:spec-symbols alone — item 3 sits behind it in the same job.

    No new issue filed: this card plus PR #4189 already own the surface, and a same-hour twin would be objectui#4949-class scatter.


    Generated by Claude Code

  6. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    CollaboratorAuthor

    ACCEPT — train-finisher review of record (objectui seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3) — PR #4208, now READY and queued. One squash delivers #4189's content (this card) + #4163 part 1 + the rc.6 residuals, restoring main to green.

    Three findings in this delivery deserve the record. (1) The semantic conflict: main's #4222 had extracted AddressValue into a new address-format module while the train imports the type from @objectstack/spec/data — taking main's side alone MOVES the spec-symbols red rather than fixing it (measured: the guard flags the relocated local declaration), so the resolution is a hybrid where the module imports the type from the spec and AddressField re-exports THROUGH the module — the relative-path from clause being load-bearing for the guard's re-export exemption. (2) The recordDetailsInputs diagnosis: the failure was never about sections — both fixtures carried layout: 'custom', a key rc.6 rejects by name, and the GREEN fixture was green for a reason unrelated to its assertion (the parse died on layout before ever reaching sections). Dropped the key, both verdicts back on sections, plus a PATH assertion because a bare error code cannot tell the two rejections apart — a vacuous-green made loud. (3) The prediction correction on the reverse verification is stated rather than smoothed (reverting the fixture necessarily removes the new assertion with it).

    Measured red set on the combined tree before fixes: spec-symbols RED, typetests GREEN (the train's own content, as designed), quick-reference RED×3, recordDetailsInputs RED×1 — after: ALL GREEN, on a full ladder (build 44/44, type-check 78/78 with typetest receipts, 871 test files / 10524 tests, i18n gates, changesets arbitrated as already-covering). On landing: #4189 closes unmerged (its content rides here — note already posted there), #4231 (main-health tracker) closes, the four held PRs (#4223/#4224/#4226/#4228) get flipped and queued, then the #4165 migration dispatches, then #6955 closes v17.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions