chore(console): bump the objectui pin 190fbd01 → 9602dc82 so a stock console build resolves automation:packaged - #12955
chore(console): bump the objectui pin 190fbd01 → 9602dc82 so a stock console build resolves automation:packaged#12955os-elon wants to merge 2 commits into
automation:packaged#12955Conversation
…mation page) feat(app-shell): packaged actions on/off beside the packaged flows (ADR-0126 §8 item 2) (#6415) objectui@9602dc820450dda956843c6cfe5b329bcf88c757 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
Re-derived every cited anchor at the new pin rather than rewriting the sha, per check-objectui-pin-citations' own instruction. - ObjectGrid.tsx 2492-2507 -> 2586-2601 (block byte-identical, shifted) - plugin-dashboard/src/index.tsx 161 -> 204 (object-metric block) - useBulkExecutor.ts 284-288 -> 284-289 (span was truncated since written) - containers.tsx tabs 662-668 / :721 and accordion 851-857 / :898 unmoved, re-read at the new pin rather than inferred from byte-identity - MetricWidget / ObjectMetricWidget / MetricCard / lazy-icon anchors unmoved The two element:button records are deliberately NOT touched: that read point MOVED (objectui#5993) and its shipped .describe() text is now false. Reported rather than re-pointed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
📓 Docs Drift CheckThis PR changes 1 package(s): ⛔ 1 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ef2a0313fd587d66e6552e4ea40349a24f9a7a6a && git checkout ef2a0313fd587d66e6552e4ea40349a24f9a7a6a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f4e741bd194f72c880a99d7af2e6a4faae09d63a 39b05bf821af235c8046064c9cd4e08764cecec8 && git checkout -B drift-repro f4e741bd194f72c880a99d7af2e6a4faae09d63a && git merge --no-ff 39b05bf821af235c8046064c9cd4e08764cecec8
node scripts/docs-audit/affected-docs.mjs --json f4e741bd194f72c880a99d7af2e6a4faae09d63a
|
Fixes #12687
Moves
.objectui-shafrom190fbd01d061to9602dc820450through the repo's dedicatedbump tooling (
scripts/bump-objectui.sh), so a stock vendored-console build can resolvethe
automation:packagedcomponent ref.If you are a tester walking ADR-0126 acceptance item A1
A1 — "admin login → Setup → Packaged automation page exists" — was failing for pin lag, not
for a UI defect. The nav entry was already present and correct in the served metadata (PR
#12491 landed that), which is why the page's absence read like a rendering bug. It was not.
The console SPA this repo vendors was built from an objectui commit that predates the page
entirely, so the ref the metadata names had nothing to resolve to.
Measured, both directions, at the two pin endpoints:
automation:packagedin the treepackages/app-shell/src/views/setup/190fbd01d061(old pin)git grep -cexit 1; control termregisterAppComponenthits 4× in the same file at the same revision, so the search itself works there)9602dc820450(new pin)services/builtinComponents.tsxPackagedAutomationPage.tsxA bundle built from a tree that does not contain the string cannot register the ref. That is
the whole defect, and this pin move is the whole remedy. If you filed a UI bug against A1,
it is a duplicate of this pin lag.
The verification that actually answers the card
Not "the pin string changed and CI is green" — the card's point is that the served metadata is
already correct, so a metadata-side check proves nothing. The check is on the built bundle:
One occurrence, in the app-shell component registry, bound to the minified
PackagedAutomationPage. Negative control (a ref that must not exist) correctly absent;positive control present. This is the
Console Pin Gate's own work, run locally ahead of CI —and it passed.
Target choice — and a correction to the card
The card gives the target as
>= 9602dc8and attributes the page to "objectui#6382 / #6415".Re-measured, that conflates two commits:
b362c1b474b8(objectui#6382, 2026-08-25 19:32) is what actually introduces andregisters
automation:packaged— ADR-0126 §7.4, the Setup page itself. This is the truelowest SHA that resolves the ref.
9602dc820450(objectui#6415, 2026-08-25 22:43, 17 commits later) adds the packagedactions section beside the flows — ADR-0126 §8 item 2.
Pinned at
9602dc820450rather than the lowerb362c1b474b8deliberately. The two are threehours apart, so the lower pin buys no meaningful delta reduction, while
b362c1b474b8wouldship the page with its actions half missing — recreating the very "reads as a UI bug rather
than pin lag" trap this card exists to end, one acceptance item later.
9602dc820450is alsothe card's own stated bar.
Two more corrections, measured
190fbd01d061..9602dc820450:359 non-merge commits, 279 changesets added, of which 188 releasing, 91
release-nothing, and 82 commits carrying no changeset. Still a large, risk-bearing range —
just not 700. (objectui squash-merges, so commits ≈ PRs:
--mergescounts 0 in the range.)packages/console/distis gitignored (packages/console/.gitignore=dist/), andscripts/bump-objectui.shwrites exactly two files —.objectui-shaand thederived changeset. It touches no lockfile and no pnpm override; there are none to carry.
So the diff is 2 files, and the large console delta is a build-time artifact CI produces
and caches, never a committed one.
The ADR-0087 disposition
bump-objectui.shemits the changeset with anadr-0087: TODOplaceholder and states in itsown output that the bump cannot answer it and a human must, before pushing —
check-adr-0087-registration.mjsrejects the placeholder on purpose. That marker is the onething in this PR written by hand, and it is the tooling's own mandated step, not an edit to
generated content.
All 11 declared-breaking entries in the range are judged one at a time against their own
upstream changeset. Disposition:
not-required (no-migration-prescription). The load-bearingre-measurements at this HEAD:
packages/console/package.jsonpublishes a frozen prebuilt SPA —filesis["dist","README.md","CHANGELOG.md"]and the soleexportsentry is./package.json. Itforwards no
@object-ui/*module entry point. This workspace declares no@object-ui/*dependency in any manifest at all.
direction→ordersort retirements are objectui catching up to a refusal thisrepo already enforces:
packages/spec/src/ui/view.zod.tsdeclaresorderas the soleaccepted spelling and already refuses
directionby name (aliases: { direction: 'order' }).ui:icon'sname→iconrename touches no ObjectStack authorable key:packages/specdeclares no
IconSchema, notype: 'icon'node, and the literalui:iconappears nowhereunder
packages/.files here. The two apparent in-repo hits are prose, never imports: every
ActionParamDialogmention names the app-shell implementation that survives objectui#5685 (including the
packages/spec/liveness/action.jsonevidence row), and the singleuseIsWorkspaceAdminmention is a comment in
packages/plugins/plugin-auth/src/auth-manager.ts.The pin bump's second half — ADR-0082 D4
Per AGENTS.md the pin move is the declaration-parity ratchet's only trigger, so it was run:
packages/spec/react-declaration-parity.baseline.jsonis byte-identical before and after(sha256
79c1f51b…62f15both times), and the manifest lands in the gitignored dist — soneither is in this diff.
The container's Playwright browser did not match the revision the pinned objectui expects
(
chromium_headless_shell-1194installed, build1234wanted). That is the exact gapdocs/releases-maintenance.md→ "If the dispatch container's Playwright browser doesn't matchthe revision" records, and its documented scratchpad symlink remedy was applied verbatim —
nothing under
/opt/pw-browserswas touched, andPLAYWRIGHT_BROWSERS_PATHwas overridden forthat one invocation only. Chromium 141.0.7390.37, as the note predicts.
Gates run locally (round 0, head
02ddae3a5)Derived from the actual diff with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(8 families), plus the console pair the path derivation cannot reach —
Console Pin Gateis adorny/paths-filterjob keyed on.objectui-sha, not apull_request: paths:filter, so nopath derivation names it; it was read out of
ci.ymland run by hand instead.check-adr-0087-registration✓ 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition.check-changeset-no-majorcheck-empty-changesetcheck:changeset-gate-self-tests✓ 118 + 212 + 116 assertionscheck:objectui-changeset✓ objectui-range --self-test: all checks passedcheck:pm-half-states✓ check-half-states self-test: 1515 cases pass.release-rehearsal-clone --self-test✓ self-test passedcheck:console-sha✓ Console dist matches the objectui pin (objectui@9602dc820450).check:console-injection✓ the dist carries this tree's copy, and not the published one.check:nul-bytesOK (scanned 7184 text file(s) … no raw ASCII control bytes)scripts/pm/check-half-states.mjscheck-half-states.mjsis a board sweep needing the GitHub API, and this seat's repo-scopedREST answers 403, so it printed its own "no reading at all" text and exited 3. Its self-test
wiring (
check:pm-half-states) is green. Recorded as unmeasured rather than as either colour.pnpm lintwas narrowed, and the narrowing is proven rather than asserted: eslint's ownconfiguration resolution answers "File ignored because no matching configuration was
supplied" for both changed files (
--format json, 2 files submitted, 0 linted, 0 findings).The diff adds no TypeScript and edits no eslint config, so no untouched file's verdict can move
under any configuration.
Generated by Claude Code
Patch round 1 —
check:objectui-pin-citations(head39b05bf82)The first push was red, and it was ours.
Type Check · source gatesfailed onpnpm --filter @objectstack/spec check:objectui-pin-citations: 8 spec sources carriedread-point records asserting
.objectui-sha=190fbd01d, which this PR moves off. Thisis a real consequence of the pin move that the local gate sweep did not name (see the
"gates" note at the end).
TypeScript Type Checkwas NOT a second red. Read, not assumed — the aggregator's ownOS_NEEDS(job 98827675406) shows one lane failing and three green, and its only error lineis
type-check lane 'typecheck-source-gates' concluded 'failure' -- expected 'success'. It isa pure rollup over four lanes with
if: always(), exactly aslint.ymldocuments it.Method — re-measured, never sha-replaced
The gate refuses a mechanical fix by design (no
gen:,NO_GENERATORin thecheck:generatedledger): rewriting the sha alone would make each record claim the new pin while its anchors
still described the old tree. So every anchor was re-derived from the file at
9602dc820450.Byte-identity was used as a first cut, never as proof — and that distinction paid out, once,
in the section below.
190fbd01d→9602dc820450containers.tsxuseBulkExecutor.tslazy-icon.tsx,ObjectMetricWidget.tsx,MetricWidget.tsx,MetricCard.tsxObjectGrid.tsxplugin-dashboard/src/index.tsxbutton.tsx⭐ A measured instance of the #10274 class — the case for the gate's "do not replace the sha" rule
useBulkExecutor.ts:284-288was wrong from the day it was written, and the file isbyte-identical across the pin move. Both halves matter:
label = 'bulk delete', truncating the second of the twoelse ifbranches it exists to name (def.operation === 'update'/=== 'delete', the claimthat the data-plane
bulkprimitive is reachable only by an update/delete bulk def);sha-only rewrite would have preserved the truncation behind a fresh-looking sha, and so would
trusting byte-identity as proof that an unchanged file's anchors are still correct.
It was caught only by re-reading all four cited spans at the new pin instead of inferring them
from identity. That is the gate header's
#10274warning reproduced live, in the exactconfiguration it predicts — now a measured instance rather than a cited one. Widened to
284-289.Per-anchor result — 6 of 8 records repaired
api-methods-batch-conformance.test.ts:64ObjectGrid.tsx2492-2507→2586-2601useBulkExecutor.ts284-288→284-289component.test.ts:281+component.zod.ts:1649containers.tsxaccordion851-857,:898→ unchangedflex items-center gap-1.5wrapper span and the[{ label, icon?, collapsed?, children }]input both verified verbatimcomponent.test.ts:366+component.zod.ts:642containers.tsxtabs662-668,:721→ unchangedmr-1.5 h-3.5 w-3.5 shrink-0 opacity-70+aria-hiddeninsideTabsTrigger, left of the label span, verified verbatimcomponent.zod.ts:2393plugin-dashboard/src/index.tsx161→204Icon (Lucide name)inputs (:132metric-card,:204object-metric); the record's own "on the registeredobject-metricblock" is what disambiguated itObjectMetricWidget.tsx:142/:474,MetricWidget.tsx:312-321/:373-382,lazy-icon.tsx:66-80,MetricCard.tsx:83⛔ 2 records NOT repaired — ruled, tracked as #12968
component.zod.ts:1827andcomponent.test.ts:2440(theelement:buttoniconrecords) stillassert
190fbd01d, so this gate stays red on exactly them. Maintainer ruling, 2026-08-28(option A): the repair is
packages/specauthorable-surface contract prose and belongs to aspec-side card, not to a console pin bump and not to a
domain:devxseat. It is filed with everymeasurement below already recorded, so nothing needs re-deriving there.
objectui#5993 moved the read point.
button.tsxno longer carries its own icon normaliser;it now calls the shared
resolveIconfrom../action/resolve-icon— because the duplicatedalgorithm silently missed a lucide alias every
action:*site received. Measured at the new pin::44-47→:36, and now hops into a different file (resolve-icon.ts:14-24,:30-35):69/:71→:57/:59:82-98→:70-87button.tsx:14-27, cited as the file-local normaliser, is now imports and theforwardRefopeningThe key is still LIVE and the record's verdict still holds. What cannot be fixed by moving
line numbers is the shipped
.describe()string, which tells authors the renderer resolves theicon "using its own PascalCase normaliser and rename map". At
9602dc820450that clause isfalse. Everything else survives —
resolveIconreturnsnullon an unknown name (?? null),so "an unknown name here renders nothing rather than a fallback glyph" and the
LazyIconcontrast both still hold; only the ownership claim broke.
Gates, re-derived on the repaired diff
The family grew 8 → 33 once
packages/spec/src/**entered the diff. All 33 run green onhead
39b05bf82except the two records above, plus these, added by hand because the derivationstill does not name them:
check:objectui-pin-citations— still not derived, even now that the diff edits the veryfiles it scans. It is deliberately unfiltered (
lint.yml: "a paths filter onpackages/spec/**would go dormant on exactly the PR that moves.objectui-sha"), and beingunfiltered is what makes it invisible to path derivation — a gate built to fire when no path
predicts it cannot, even in principle, be named by a path predicate. Filed as [finding] an
.objectui-shadiff derives NO pin-critical gate — the gates a pin bump most needs are the ones structurally excluded from path derivation, and one of them shipped a red on PR #12955 #12956.check:nul-bytes→OK (scanned 7184 text file(s) … no raw ASCII control bytes)@objectstack/spec typecheck→ green, including the test layer, so the edited test files compileviteston both edited test files → 234 passedcheck-dev-prereqsandcheck:doc-formula-expressionsfirst reportedPREREQUISITE NOT METin this fresh worktree — the NOT-MEASURED class, not a red. A full
pnpm build(71 tasks, all successful) turned both into real readings:
✓ 67 package build artifacts presentanddoc-formulaexit 0.The console evidence from round 0 stands unchanged — the pin did not move in this round, and
this round's diff is comment text in
packages/spec/src.check:console-shais not quotedas a fresh green here: this worktree has no
packages/console/dist, where that gatedeliberately prints
ℹ No console dist — skippingand exits 0, which is a vacuous pass ratherthan a measurement.
All edits in this round are comment text only — verified mechanically: every added line in
the diff is a comment line.