Skip to content

chore(objectui): bump the console pin to f0268ad78485 (carries objectui#11880) - #22412

Open
objectstack-fleet[bot] wants to merge 10 commits into
mainfrom
claude/issue-22385-objectui-pin-bump
Open

objectstack-fleet[bot] wants to merge 10 commits into
mainfrom
claude/issue-22385-objectui-pin-bump

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #22385
Clause-②: no

This moves the bundled Console's objectui pin from a58626c88dc8 (PR #22015) to f0268ad784854568aa58a2aa791f6a7502259186, which was objectui main when this run started. The new pin contains 5bc55c0c5a1e, the closing merge of objectui#11880, so it carries both objectui halves of that card: element:record_picker and element:number read their query from the node-level dataSource only (objectui 74add0c12), and element:repeater reads that binding first (objectui aaba8655a). Ruling 6051498447 on #11509 orders the work this way ("objectui first …, and the spec retirement ships with the pin bump that carries it"). The spec retirement itself is #11509's, not this PR's: no key retires, no schema shape changes, no conversion or lint rule changes here.

The bump follows the repo's own procedure (scripts/bump-objectui.sh, then pnpm objectui:build and node scripts/gen-sdui-manifest-node.mjs) and the gates it derives. It adds no step to that procedure.

This is not a release act. Version Packages PR #21988 is untouched. That PR edits packages/console/CHANGELOG.md and packages/console/package.json, and this diff edits neither. The console's release input is the new .changeset/console-f0268ad78485.md.

Range

  • objectui git ls-remote … refs/heads/main read f0268ad784854568aa58a2aa791f6a7502259186 at 2026-10-09T02:23:09Z, the same sha the dispatch read at 01:49Z.
  • REST compare on objectstack-ai/objectui proves containment (base...head, head = the new pin, read 02:24:10Z):
    • 5bc55c0c5a1e...f0268ad78485: status: ahead, ahead_by: 8, behind_by: 0, merge base 5bc55c0c5a1e4202a55a45c092cce3880a09b27a. The pin contains objectui#11880's closing merge.
    • 74add0c12a70...f0268ad78485: ahead, 27 ahead, 0 behind (objectui#11880, element:record_picker / element:number).
    • aaba8655aec5...f0268ad78485: ahead, 17 ahead, 0 behind (objectui#11880, the repeater half).
    • a58626c88dc8...f0268ad78485: ahead, 170 ahead, 0 behind.
    • The old pin was behind: 5bc55c0c5a1e...a58626c88dc8 reads behind, behind_by: 162.
  • a58626c88dc8..f0268ad78485 has 170 commits, 0 merges and 1061 changed paths (482 added, 2 deleted).
  • git merge-base --is-ancestor 5bc55c0c5a1e f0268ad78485 in the objectui object store exits 0.

Digest level and declared-breaking entries

The bump's own digest output: objectui declared 175 changesets over the range. 173 release, 2 are release-nothing, and 4 commits carry no changeset (listed by subject in the console changeset). One changeset added in the range was already consumed by an objectui release, and was read from the commit that added it. None declares major. Four carry the author's breaking annotation. The highest declared level is minor, so the console changeset is minor. Six commit subjects carry ! (objectui#6152 rounds 7 to 12, @object-ui/types faces taking @objectstack/spec rows by reference); none of their changesets is annotated breaking, so the digest lists them at their declared level.

The script wrote its adr-0087: TODO placeholder into the console changeset. It is answered not-required (no-migration-prescription), in the wording the previous bumps used. check-adr-0087-registration --base origin/main reports "1 declared-breaking changeset(s), each carrying an ADR-0087 disposition". check-changeset-no-major --base origin/main reports "This diff introduces no major bump".

Each declared-breaking entry, with its disposition:

  1. objectui#11070 (18d7b489c): objectui's form-field faces take scale and currencyConfig by reference to @objectstack/spec's FieldSchema, so objectui's tolerant face now refuses what the spec already refuses. It follows this repo's existing declaration, so nothing here moves.
  2. objectui#11070 (172acc313): objectui's sidebar node declares side as left or right. sidebar has no @objectstack/spec row.
  3. objectui#11389 (d92b2a15d): the metric sub-caption is retired on the reader side. The ObjectStack half shipped in @objectstack/spec 17.7.0, with the conversion translation-widget-sub-caption-removed and the semantic entry translation-widget-sub-caption-retired. This repo's sdui-parser copy already drops description from CONSUMED_WIDGET_OPTION_KEYS, so the renderer and the save gate now agree.
  4. objectui#11880 (74add0c12): element:record_picker and element:number read their query from the node-level dataSource only. The flat keys they stop reading are still declared by @objectstack/spec. Their retirement, with its ADR-0087 conversion onto dataSource, is [Direction · v18] Retire the flat object/filter data-binding family — dataSource as the single data-binding door (re-anchor of the deleted #6590 tracker) #11509, which the ruling sequences after this bump and ships in the same release.

User-visible changes this brings into the Console

The full list is the console changeset (173 entries, capped at 100 in the rendered list). The ones a Console user meets:

  • Page elements and objectui#11880.
    • element:repeater reads the node-level dataSource binding first, and its flat keys second. A repeater bound only through dataSource now renders its rows; at the old pin it rendered nothing.
    • element:record_picker and element:number read their object, filter, sort and limit from dataSource only. A page that wrote those keys flat under properties now shows no records (the picker) or the "No object named: set dataSource.object." notice (the number) until it moves them into dataSource. No example or package source in this repo writes the flat keys: the showcase's page-variables picker already binds through dataSource.
    • Studio's page designer writes element:number's object to dataSource.object.
  • Dashboards. A metric tile no longer draws a sub-caption from options.description (objectui#11389).
  • Time zones. Dates and times render in the time zone the server answers for the workspace (objectui#11693). An administrator is asked once to set the workspace timezone while it is still the platform default (objectui#11758), and a new workspace takes its creator's browser timezone (objectui#11908).
  • Lists.
    • A list's Filter panel conditions, search term, sort and toolbar grouping are in the URL, so a list can be shared or bookmarked (objectui#11860).
    • The Filter, Sort, Group, hide-fields and Row color lists offer only fields the user may read (objectui#11925, objectui#11943, objectui#11984).
    • List titles use the object's plural label (objectui#11696), and empty-list copy matches the page (objectui#11687).
  • Records and actions.
    • A record action greyed out by its declared disabled predicate says why (objectui#11811, objectui#11839).
    • action:button offers Undo for an undoable update of the record in scope (objectui#11168).
    • A record delete confirmation names the record and confirms with a destructive Delete button (objectui#11695).
    • The record page says whether a failed read was no access, not found, or could not load (objectui#11902).
  • Maps. Without WebGL2 a map lists its records instead of crashing (objectui#11819).
  • Studio. The Interfaces pillar can create a page, a dashboard or a report in a writable package (objectui#11823). The "New" menus for automations, actions and validation rules open on common starting points (objectui#11861). Studio pickers use the shared Select (objectui#11865). The form designer can be arranged from the keyboard (objectui#11871, objectui#11898). The field inspector picks a field type from a searchable, grouped list (objectui#11793).
  • Sign-in and settings. The login and register pages say when the server cannot be reached (objectui#11806). Installed Apps reads a package the runtime refused to load as "Not loaded" (objectui#11645). The organization Settings page no longer offers a slug edit the framework refuses (objectui#11720).
  • Accessibility. Screen readers can name and reach the view tab bar, the settings form, the sidebar menus, the selection column and the percent cell (objectui#11690).

What changed here (22 files, +809 / -278)

file written by gate that required it
.objectui-sha OBJECTUI_ROOT=… scripts/bump-objectui.sh f0268ad784854568aa58a2aa791f6a7502259186 --no-commit Console Pin Gate builds what it names
.changeset/console-f0268ad78485.md the same run (the digest); the only later edit is the ADR-0087 answer above check-adr-0087-registration, check:objectui-changeset
sdui.manifest.json, scripts/sdui-manifest.record.json node scripts/gen-sdui-manifest-node.mjs over .cache/objectui-f0268ad78485 check-sdui-manifest.mjs
packages/sdui-parser/objectui-lockstep.json node scripts/check-sdui-lockstep.mjs --update (pnpm gen:sdui-lockstep) against the same tree check:sdui-lockstep
55 asserting citations in 15 files under packages/spec/src (the generated migrations/registry.ts among them), plus the quoted anchors of one dated view.zod.ts record re-measured by hand (below); registry.ts by gen:migration-registry check:objectui-pin-citations (and --verify-anchors)
.changeset/objectui-pin-citations-f0268ad78485.md hand-written, @objectstack/spec patch Check Changeset (the shipped describes and docblocks name the pin)
content/docs/references/ui/view.mdx check:generated --fix check:docs
  • The bump script. It ran with OBJECTUI_ROOT at a detached objectui worktree of my own (/home/user/objectui-issue-22385, at the pin), after git fetch origin main there. The objectui store was shallow and did not hold the old pin, so the script ran its own git fetch --unshallow, then re-checked: "the range walks completely now". The shared objectui checkout's working tree, branch and index were not touched; the fetch and the deepen added objects and refs to its shared object store only.
  • The manifest. It still has 107 components, and its sha256 moves from e0654735a318… to 097ae3cbcf95…. objectui's workspace version stays 17.7.0. Ten components' inputs moved:
    • action:button gains an undoable input. element:repeater gains the dataSource input and its object description says a node-level dataSource.object wins.
    • element:number's object and filter descriptions now say NOT READ (objectui#11880).
    • element:text's variant enum loses heading and subheading, which @objectstack/spec 17.7.0 already refuses.
    • object-grid, object-kanban, object-calendar, object-gantt, object-master-detail-form and object-timeline reword input descriptions (objectui#6152 rounds 7 to 12): the filter inputs name the ViewFilterRule array, and resizable says the legacy resizableColumns is refused.
  • The lockstep. It records 214 grammar lines (blob 0131f27cf86d), 25 diagnostic codes and containment predicate 76c18fb95d1f. All are unchanged, so no port is owed. objectui's sdui-parser/src/dashboard-widget-options.ts changed (objectui#11389) to the five-key set this repo's copy already carries.

Records that turned false at the new pin

Three asserting records said something objectui changed. Only the false sentence of each is rewritten, and each new sentence names the objectui commit that changed it. Rollback for each: revert that docblock hunk alone (comment text, no schema or code); every other line of the record and of this PR stands without it.

1. element:repeater row (ui/component.zod.ts, the ElementRepeaterPropsSchema docblock)

  • Old: "NOT read at the pin, whatever a sibling might suggest: the node-level dataSource binding. This renderer is not wrapped in objectui's element-data-source gate, so the query keys above are the only way to aim it." And: "object is REQUIRED, as element:number's is: without it the renderer never queries and shows its "No records" state (:171-174, :209) — indistinguishable from an object that really has no rows. The registration marks it required too."
  • New: "READ at this pin, since objectui#11880 (objectui aaba8655a, the repeater half): the node-level dataSource binding. The renderer resolves it through useElementDataSource (:172-173) … and reads it FIRST, the query keys above being its fallback." It then states the precedence: object is the binding's (:192-195); filter is this row's AND the binding's (:180-188); sort and limit take the binding's own value, then this row's key, then the binding's saved view (:196-199). The registration is marked with elementDataSourceBlock (:311). The object bullet now says the renderer takes dataSource.object first and this key second, and that with neither it never queries (:234-237, :279).
  • What cannot be made true without a schema change: the row still requires object, and the registration still marks it required because the row does (:320-326). So a node that names its object only through dataSource renders at this pin while this row refuses it. The text says so and names [Direction · v18] Retire the flat object/filter data-binding family — dataSource as the single data-binding door (re-anchor of the deleted #6590 tracker) #11509 as the card that retires these flat keys. The schema is unchanged.
  • Cited diff: git diff a58626c88dc8 f0268ad78485 -- packages/components/src/renderers/basic/data-list.tsx, +99/-16, one commit (aaba8655a). The read points cited at :171, :183, :148, :181 and :182 were rewritten from props.object / props.filter / props.sort / props.limit to the resolved object, scoped.filter, sort and limit.

2. action:button row (ui/component.zod.ts, the ActionButtonPropsSchema docblock)

  • Old: "The registration's inputs (:427-572) publish twenty-seven of the twenty-nine keys … the two left unpublished are endpoint (refused here, above) and undoable, each still forwarded (:215-318), on objectui's measurement that the console's own api handler reads target and never endpoint, and that the runner offers Undo only with a host row stash this block never writes."
  • New: "The registration's inputs (:507-658) publish twenty-eight of the twenty-nine keys … twenty-seven since objectui#11168 slice 1, and undoable since objectui f0496bdf1 … the one left unpublished is endpoint … undoable is published because the block now writes the row stash the runner's Undo needs: an undoable operation: 'update' of the record in scope carries that record as its Undo baseline (withUndoBaseline, :72-81, called at :247-251; objectui#11168, ruling B on objectui#11754), where at a58626c88 it wrote none."
  • Cited diff: git diff a58626c88dc8 f0268ad78485 -- packages/components/src/renderers/action/action-button.tsx, +95/-9 (f0496bdf1, cef0eeec0). The row already declares undoable, so the accept set does not move.

3. action:icon row (ui/component.zod.ts, the ActionIconPropsSchema docblock)

  • Old: "label is read five times at this pin (four at db11afd49): :109 …, :165 (forwarded), :281 (aria-label, falling back to name), :290 (its first letter when no icon resolves) and :296 / :302 (the tooltip). description is the tooltip's fallback (:302) as well as forwarded (:166)."
  • New: "label is read six times at this pin (five at a58626c88, four at db11afd49)", with the five re-pointed and a sixth: ":311 (the heading of the disabled-reason tooltip a predicate-disabled icon is wrapped in, new with objectui#11839, objectui cef0eeec0)". description is now the fallback of both tooltips (:311, :324).
  • Cited diff: git diff a58626c88dc8 f0268ad78485 -- packages/components/src/renderers/action/action-icon.tsx, +22/-0 (cef0eeec0).

How the other citations were re-measured

  • Method. Each asserting record's cited objectui files were resolved against the tree at a58626c88 and intersected with the range's 1061 changed paths. Every anchor in a changed file was mapped through git diff -U0 a58626c88 f0268ad78 and its text compared at both pins. A record whose cited files are all byte-identical (git diff --quiet) gets that sentence and no re-pointing.
  • Changed cited files (each named, with its objectui change, in its record's new hop sentence): containers.tsx, record-related-list.tsx, record-quick-actions.tsx, the four action-*.tsx renderers, basic/data-list.tsx, data-objectstack/src/index.ts, previews/block-config.ts, previews/block-types.ts, ObjectGrid.tsx, data-table.tsx, plugin-kanban/src/index.tsx, ObjectCalendar.tsx, ObjectMap.tsx, plugin-gantt/src/index.tsx, ListView.tsx, ObjectView.tsx, ObjectTimeline.tsx, plugin-timeline/src/index.tsx, types/src/objectql.ts, types/src/zod/objectql.zod.ts, form.tsx, ActionRunner.ts, date-display.ts, and the en / zh / de packs.
  • Result. About 185 anchor tokens in the records' current text were re-pointed. Every moved line is byte-identical at the new pin, except where objectui rewrote a line around the same read; those ranges were re-read and their hop sentence says so:
    • the action:button params statement (180-183 -> 247-254, now wrapped in withUndoBaseline);
    • the action containers' member label lines (now DisabledReasonMenuLabel, still action.label || action.name);
    • formatDate in date-display.ts (445-480 -> 568-605): objectui#11693 names an instant's day in the display zone, and its short / relative / default style handling reads unchanged.
  • Records. Each comment record gains a dated 2026-10-09 hop sentence and keeps its earlier history. The FormField.span describe changes its sha only: WIDE_FIELD_TYPES, the field-type alias table and spanLadderFor are byte-identical (spanLadderFor moved 204-231 -> 274-301).
  • The dated view.zod.ts map record (.objectui-sha pin 53ded82b) carries seven quoted anchors that --verify-anchors checks against the live pin. All seven moved byte-identical: resolveListMapConfig 146 -> 147, FLAT_MAP_CONFIG_SPELLING 85 -> 86, case 'map': 2300 -> 2340, ObjectMapConfigSchema 2388 -> 2513 (still .strict()), LIST_VIEW_LOCAL_OVERRIDES 1437 -> 1506 (still without map), and the two getMapConfig lines 415 -> 449 and 420 -> 454. The record gains a "RE-READ again at pin f0268ad78" sentence, the way earlier bumps recorded it.
  • Counts. Each was re-taken by the record's own method and reads as before:
    • the keyboardNavigation hit lines: 15, against 3 for schema.editable;
    • ObjectKanban.tsx's quickAdd / onQuickAdd: 2 each, against 11 for onCardClick; 0 kanban-ui registrations;
    • the ElementDataSourceGate occurrences in the five src/index.tsx shells: 0, 3, 3, 3 and 4;
    • ObjectMap.tsx's schema.* read set: the same 17 names at both pins.
  • Corpus counts. The six migration entries' counts were re-taken with git grep -o -F. That method first reproduced every a58626c88 number: 7754 files, timeout 1431, RuntimeConfig 299, resourceLimits 2, objectstack 17468, @objectstack/spec 7246, useState 2491, window 4255, period 247, interval 200, metrics 401, Span 509, SpanSchema 57, TTL 184 and tenant 1319.
    • The new readings are 8234 files, timeout 1658, RuntimeConfig 337, resourceLimits 2 (the same two packages/app-shell prose hits), objectstack 17956, @objectstack/spec 7522, useState 2622, window 4430, period 249, interval 213, metrics 404, TTL 184 and tenant 1338.
    • All 99 checked tokens still read zero at both pins (the export lists of plugin-lifecycle-advanced.zod.ts, tracing.zod.ts and metrics.zod.ts, plus every named key), except Span / SpanSchema, which read 517 / 57. The eight new Span hits are each a colSpan.

For the contract review: changed lines in packages/spec/src/** that are neither a comment nor a string fragment

There are none. Measured mechanically: each changed file was parsed with the TypeScript compiler at 11d119ab18 and at the head, comments and JSDoc dropped, and every string or template literal replaced by one placeholder token. The remaining token sequences are identical in 13 of the 15 files. The other two, 18.system-metrics-jsdoc-durations-unit-in-key.ts and 18.system-tracing-otel-exporter-durations-unit-in-key.ts, each gain one + joining one new string fragment into their reason string; migrations/registry.ts mirrors both. No identifier, key, value or export moves.

Console build (the local Console Pin Gate equivalent)

Both steps ran under the verify lock.

  • Dependency build. turbo run build --concurrency=2 --filter=@objectstack/client --filter=@objectstack/spec --filter=@objectstack/sdui-parser ran 34 tasks and exited 0 in 4m50s on the shared box.
  • Console build. pnpm objectui:build exited 0, holding the lock 6m51s.
    • OBJECTUI_ROOT pointed at a scratch repository holding no refs, with objectui's object store as its alternate, so the build's git worktree add registered nothing in the sibling objectui checkout.
    • The log reports "Bundle canary 'import/jobs' present".
    • It reports "Single-zod canary: exactly one zod version literal {major:4,minor:6,patch:5}".
    • It reports "Console bundle carries THIS tree's @objectstack/spec, and only it".
    • It reports "@objectstack/console dist ready (64028 KB) from objectui@f0268ad78485".
  • check:console-sha and check:console-injection ran against that dist (results below).

Gates and tests (head 21da749e30)

Everything below ran at head 21da749e30, the merge of origin/main (fdfdd7e76d), after a full workspace build at that head (72 turbo tasks, exit 0). Exit codes were captured before any pipe.

  • Derived gates. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 127 commands from 22 changed paths against merge base fdfdd7e76. All 127 ran and exited 0. The --ran reconciliation reads "127 derived, 127 run, 0 NOT-MEASURED, 0 UNRUN".
  • Verdict lines of the gates this bump exists for:
    • check:objectui-pin-citations: "55 asserting objectui pin citation(s) match .objectui-sha (f0268ad78), 144 historical citation(s) recorded and not checked, across 1922 spec source(s)." With --verify-anchors: "13 anchor content assertion(s) verified against objectui at f0268ad78".
    • check:sdui-lockstep: "OK — this copy is byte-identical to objectui@f0268ad78485 … over 214 grammar line(s) [blob 0131f27cf86d], agrees on all 25 diagnostic code(s) and on the not-a-container predicate [blob 76c18fb95d1f]".
    • check-sdui-manifest.mjs: "present, intact (sha256 097ae3cbcf95…, 107 components) and recorded at the live objectui pin f0268ad78485…".
    • check:console-sha: "Console dist matches the objectui pin (objectui@f0268ad78485)". check:console-injection: "the dist carries this tree's copy, and not the published one".
    • check-adr-0087-registration --base origin/main: one declared-breaking changeset, carrying its disposition. check-changeset-no-major --base origin/main: "This diff introduces no major bump".
    • check:generated: "All 15 generated artifacts are up to date". check:migration-registry: "src/migrations/registry.ts is current (402 semantic, 247 retired-key, 222 retired-def)". check:nul-bytes: OK, no raw control bytes.
  • Tests.
    • @objectstack/spec vitest, both projects: 680 files, 19658 passed, 1 todo. @objectstack/spec typecheck: exit 0.
    • @objectstack/sdui-parser: 14 files, 225 passed; typecheck exit 0.
    • @objectstack/lint validate-jsx-pages.production-witness.test.ts: 5 passed. @objectstack/metadata-protocol protocol.runtime-authoring-gate.test.ts: 119 passed.
    • @objectstack/cli, unit tier (sdui-manifest, console.sha-drift, validate-build-gate-parity, console-resolve): 4 files, 102 passed. The integration tier is declared to CI: this diff touches no integration-tier file and no spawn entry.
  • Lint, narrowed and proven. ESLint over the 15 changed files under packages/spec/src: 0 errors, 0 warnings, 15 files by the --format json count. The population is the eslint.config.mjs block that lints every ts file (line 971). The config never enables type-aware linting (line 328), so this diff cannot move the verdict on any file it does not touch. The repo-wide pnpm lint is CI's run.

Acceptance notes


Generated by Claude Code

claude added 9 commits October 9, 2026 02:25
…pt output)

scripts/bump-objectui.sh f0268ad784854568aa58a2aa791f6a7502259186 --no-commit

Claude-Session: https://claude.ai/code/session_0115N1oNnQS5WqofZ2DzaT3q
Co-authored-by: Claude <noreply@anthropic.com>
pnpm gen:sdui-lockstep against objectui at the new pin: 214 grammar
lines (blob 0131f27cf86d), 25 diagnostic codes and containment
predicate 76c18fb95d1f, all unchanged, so no port is owed.

Claude-Session: https://claude.ai/code/session_0115N1oNnQS5WqofZ2DzaT3q
Co-authored-by: Claude <noreply@anthropic.com>
node scripts/gen-sdui-manifest-node.mjs over .cache/objectui-f0268ad78485
(107 components, sha256 097ae3cbcf95...).

Claude-Session: https://claude.ai/code/session_0115N1oNnQS5WqofZ2DzaT3q
Co-authored-by: Claude <noreply@anthropic.com>
… component.zod.ts)

Claude-Session: https://claude.ai/code/session_0115N1oNnQS5WqofZ2DzaT3q
Co-authored-by: Claude <noreply@anthropic.com>
… pin-citation changeset

Claude-Session: https://claude.ai/code/session_0115N1oNnQS5WqofZ2DzaT3q
Co-authored-by: Claude <noreply@anthropic.com>
pnpm --filter @objectstack/spec check:generated --fix (check:docs was the
one stale artifact).

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

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/sdui-parser, @objectstack/spec, touching 14 documentable anchor(s). ⚠️ 2 changed file(s) yielded no anchor (packages/sdui-parser/objectui-lockstep.json, packages/spec/src/kernel/functional-completeness.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/data-modeling/analytics.mdx (via DatasetMeasureSchema (symbol, a top-level const))
  • content/docs/protocol/objectui/layout-dsl.mdx (via ComponentPropsMap (symbol, a top-level const object))

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

  • content/docs/releases/v15.mdx (via PageTabsProps (symbol, a top-level const object))
  • content/docs/releases/v17/17-1.mdx (via ComponentPropsMap (symbol, a top-level const object))
  • content/docs/releases/v17/17-3.mdx (via ComponentPropsMap (symbol, a top-level const object))
  • content/docs/releases/v17/17-4.mdx (via ComponentPropsMap (symbol, a top-level const object))
  • content/docs/releases/v17/17-5.mdx (via ComponentPropsMap (symbol, a top-level const object))
  • content/docs/releases/v17/17-7.mdx (via ComponentPropsMap (symbol, a top-level const object))

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

What this run could not see
  • 2 changed file(s) yielded no anchor (packages/sdui-parser/objectui-lockstep.json, packages/spec/src/kernel/functional-completeness.ts) — pages documenting those are invisible to this run
  • 2 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 140 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 27a8b33dec2eb98b73b3e5146e740067cdbd7806 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 1a6954868eb00529fb117a2976950047ba33b77c — the merge of head eb7b6c35ebd18d33b705e770c2876f14dc302cf5 into base 27a8b33dec2eb98b73b3e5146e740067cdbd7806, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 1a6954868eb00529fb117a2976950047ba33b77c && git checkout 1a6954868eb00529fb117a2976950047ba33b77c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 27a8b33dec2eb98b73b3e5146e740067cdbd7806 eb7b6c35ebd18d33b705e770c2876f14dc302cf5 && git checkout -B drift-repro 27a8b33dec2eb98b73b3e5146e740067cdbd7806 && git merge --no-ff eb7b6c35ebd18d33b705e770c2876f14dc302cf5

node scripts/docs-audit/affected-docs.mjs --json 27a8b33dec2eb98b73b3e5146e740067cdbd7806

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

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

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Lint & Repo Gates is red on 21da749e30, and the red is not this PR's. · domain:devx seat 1 · session_0115N1oNnQS5WqofZ2DzaT3q · 2026-10-09T04:23Z


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: eb7b6c35ebd18d33b705e770c2876f14dc302cf5
Local-runs: none

PR #22412 for card #22385, read against origin/main at 27a8b33dec2e, which is the head's own merge parent, so the net diff is the branch itself: 22 files, +809/-278. Inputs: the card body and its three comments (triage 6072636718, claim 6072902794, os-dev report 6074013753), the PR body and file list, the net diff, and the 35 check-runs on the head (34 success, 1 skipped: the opt-in packed-tarball smoke). Lint & Repo Gates, Console Pin Gate, Check Changeset, Governed Surface Queue Guard, TypeScript Type Check and Spec property liveness are green on this head; the red the seat reported on 21da749e30 (6074218157) was main's and is gone with the second merge.

① Derived judgments

  1. The pin. .objectui-sha moves a58626c88dc8 to f0268ad78485. REST compare on objectstack-ai/objectui, re-read for this record: 5bc55c0c5a1e...f0268ad78485 is ahead by 8, behind 0, merge base 5bc55c0c5a1e, so the pin contains objectui#11880's closing merge; a58626c88dc8...f0268ad78485 is ahead 170, behind 0; the old pin read behind by 162. The card's acceptance (the compare reads ahead or identical) holds. Right. Console Pin Gate built it on the merge ref: success.
  2. packages/spec/src/** (15 files). Every changed line in component.zod.ts (+411/-183) is inside a docblock or // comment: I filtered the diff for changed lines that do not open with * or // and found none. view.zod.ts, action.zod.ts, dataset.zod.ts, kernel/functional-completeness.ts and the three *.test.ts files change comment text plus one .describe() string (FormField.span, its sha only). The six 18.*-unit-in-key.ts migration entries change their reason string literal (pin sha and corpus counts; two gain a + joining a new fragment), and migrations/registry.ts mirrors them. No key, enum member, default, .strict(), tombstone or export moves: the @objectstack/spec accept set and public surface are unchanged. Right. (check:objectui-pin-citations, check:docs, check:api-surface and check:migration-registry all sit in green jobs on this head.)
  3. sdui.manifest.json (objectui's published registry, regenerated; still 107 components). Each moved input, judged against the spec at head:
    • action:button publishes undoable. The spec row already declares it (component.zod.ts:3574). No gap. Right.
    • element:text variant loses heading / subheading. The spec enum at head is already h1 to h6, body, caption, overline, with the two retired-key tombstones; the renderer now agrees with the spec. Right.
    • element:repeater publishes dataSource, and its object description says a node-level dataSource.object wins; object stays required in both the manifest and the spec row. The spec is stricter than the renderer for a dataSource-only repeater; relaxing it is a schema change the ruling assigns to [Direction · v18] Retire the flat object/filter data-binding family — dataSource as the single data-binding door (re-anchor of the deleted #6590 tracker) #11509. Leaving it here is right, and the docblock says so.
    • element:number object / filter read NOT READ (objectui 74add0c12; element:record_picker likewise) while the spec still declares the flat keys. That is the ruling's ordered coupling (objectui first, the retirement with the bump, one release), not a spec accept-set change. I checked the only in-repo page that places an element:record_picker (examples/app-showcase/src/ui/pages/page-variables.page.ts:59-67): it binds dataSource: { object, limit } and writes no flat key. Right, with the release coupling named in the PR body and in the changeset.
    • object-grid, object-kanban, object-calendar, object-gantt, object-master-detail-form and object-timeline reword input descriptions only. Right.
  4. packages/sdui-parser/objectui-lockstep.json changes rev, revDate and recordedAgainstPin only; the grammar blob, the 25 diagnostic codes and the containment predicate are unchanged, so no port is owed. Right (check:sdui-lockstep is green).
  5. scripts/sdui-manifest.record.json records the live pin, the .cache/objectui-f0268ad78485 root, the new sha256 and the same component count. Right.
  6. content/docs/references/ui/view.mdx is the regenerated span row, in both tables. Right.
  7. File surface against the claim. All 22 files fall inside the claim's declared surface (the pin, the console changeset, the manifest and its record, the lockstep, the pin-citation sites under packages/spec/src/** as comment and describe text, registry.ts through gen:migration-registry, a pin-citation changeset, and content/docs/references/** through check:generated --fix). The citation count (55 in 15 files against the estimate of 54 in 12) is what the gate counts, not a widening. packages/console/package.json and CHANGELOG.md are untouched: not a release act. Right.

② Semver level

  • @objectstack/console: minor (.changeset/console-f0268ad78485.md, the bump script's digest). 173 releasing objectui changesets over the range, highest declared level minor, none major; four carry the author's BREAKING annotation, so the changeset is declared breaking and carries exactly one ADR-0087 marker, adr-0087: not-required (no-migration-prescription), answering each of the four (objectui#11070 twice, objectui#11389, objectui#11880). Same shape as the previous bump's console-a58626c88dc8.md (chore(objectui): bump the console pin to a58626c88dc8 (carries objectui#11670 and #11669) #22015: minor, three BREAKING entries, the same disposition). Matches what the diff publishes; check-changeset-no-major and check-adr-0087-registration run inside the green Lint & Repo Gates.
  • @objectstack/spec: patch (.changeset/objectui-pin-citations-f0268ad78485.md). Shipped description text changes (the span describe, six migration reason strings and the registry that carries them) with no accept-set or export move: patch, never skip-changeset. Matches.
  • Clause-②: no (PR body, line 2; also in the spec changeset body). No accept set of this repo's packages widens or narrows and no public surface grows: the spec diff is text-only; the manifest's new inputs were already declared by the spec; the record_picker/number narrowing is the renderer's, declared on objectui's side and answered as breaking entry (4) in the disposition. no beside minor is a legal pairing. Right. The console changeset carries no Clause-② line; the gate reads that line only as a fourth breaking signal, and this changeset is already breaking by its **BREAKING** markers, so nothing goes undeclared, and the previous bump's changeset had the same shape.

③ Boundary flags

open_questions in the os-dev report: []. None to answer.

Deviations (six), each answered:

  1. bump-objectui.sh ran with OBJECTUI_ROOT at the dev's own detached worktree and --no-commit, hand-committed with model-free trailers; its git fetch --unshallow added objects and refs to the shared objectui object store. Accepted: additive only; the shared checkout's tree, branch and index were not touched and the worktree registration was removed; the pin and the changeset are the script's own output.
  2. pnpm objectui:build ran against a scratch repository with the objectui store as its alternate, because build-console.sh:162 accepts OBJECTUI_ROOT only when .git is a directory. Accepted: the artefacts it fed (sdui.manifest.json, the dist) are re-derived by CI on the merge ref, where Console Pin Gate is success and check-sdui-manifest records the live pin. The script defect itself is finding 4 below.
  3. The first merge of origin/main used git's default message; the head itself is GitHub's update-branch merge, likewise without trailers. Accepted: the trailer rule's mechanical half refuses a model identifier in the pair, and neither merge carries one; a platform-authored merge cannot carry a trailer. Every hand-written commit on the branch carries the pair.
  4. The full spec vitest run held the verify lock for the whole suite's usual duration. Nothing to carry.
  5. origin/main moved after the single merge. Superseded: the head under review is the merge of the current origin/main into the branch; mergeable_state reads clean; the registry.ts hunks of fix(spec)!: close the shared retry policy, and judge try_catch config keys at the build doors #22380 and of this PR did not collide.
  6. Cleanup of the worktrees and the scratch repository. Nothing to carry.

Out-of-scope findings (four):

  1. The element:record_picker / element:number docblocks still describe the flat keys as read; they are not pin-gated citations and sit outside the claim's surface. Answered: carrier [Direction · v18] Retire the flat object/filter data-binding family — dataSource as the single data-binding door (re-anchor of the deleted #6590 tracker) #11509 (open, dispatched), where the keys retire.
  2. The repeater row still requires object while the renderer renders a dataSource-only node. Answered: a schema change; [Direction · v18] Retire the flat object/filter data-binding family — dataSource as the single data-binding door (re-anchor of the deleted #6590 tracker) #11509 sub-questions 3 and 4.
  3. Studio's repeater inspector writes the flat object key; the renderer still reads it as the fallback. Answered: nothing breaks at this pin; carrier [Direction · v18] Retire the flat object/filter data-binding family — dataSource as the single data-binding door (re-anchor of the deleted #6590 tracker) #11509.
  4. scripts/build-console.sh:162 tests -d on $OBJECTUI_ROOT/.git and silently falls back to the sibling ../objectui for a linked worktree, registering a build worktree in the shared checkout, while bump-objectui.sh:162 tests -e. The dev left it in acceptance notes with no carrier. Escalated: a reproducible internal-tooling defect with a shared-checkout hazard is a card, not an acceptance note (Prime Directive 10). It is owed a domain:devx tooling card, which the owning seat files. Not a verdict item for this PR, which routed around it without touching the shared checkout.

The acceptance notes in the PR body add nothing beyond the above. The Docs Drift advisory (6073980028) lists analytics.mdx and layout-dsl.mdx by symbol; the changed lines inside those symbols are comments, so no re-verification is owed, and the release-owned pages are untouched.

Implemented-by: claude/issue-22385-objectui-pin-bump
Reviewed-by: session_0115N1oNnQS5WqofZ2DzaT3q

VERDICT: PASS

read 2026-10-09T06:12Z.


Generated by Claude Code

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 37894050587 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test Core (6/6) — 失败步骤: Check this shard's timing drift(日志不可读,点进 job 看)

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

  • ⚠️ 本次没有可用的聚合签名(日志里没有能解析出测试文件名的 FAIL 行)—— 这不是「没有同签名的其他 PR」,是这一轮没测到。跨 PR 聚合本次不可用,请手工比对其他 PR 的同类评论。
  • ⚠️ 24h 评论账本没读完(超过 5 页仍未读到窗口尽头),所以上面的「不同 PR 数」是下界,不是全量。

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 10 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Dequeued by a Test Core drift red that is not this PR's · domain:devx seat 1 · session_0115N1oNnQS5WqofZ2DzaT3q · 2026-10-09T06:58Z


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Correction to 6076074015, last bullet · domain:devx seat 1 · 2026-10-09T06:59Z

The contract review 6075438386 covers head eb7b6c35eb only. A merge of main would move the head, and a moved head owes a fresh at-tier review before enqueue. So the re-queue happens on eb7b6c35eb as it stands: being behind main does not stop the merge queue, which builds on main itself. If GitHub reports a conflict instead, the seat merges main in, waits for CI, and runs a new contract review before enqueueing.


Generated by Claude Code

This branch has not been deployed

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

Projects

None yet

2 participants