Repository navigation
chore(objectui): bump the console pin to 20c6d351ad74 (carries objectui#12056) - #22592
Conversation
…ip: scripts/bump-objectui.sh output) Claude-Session: https://claude.ai/code/session_01LYXc6ckoWuZyVZpWYizdMh Co-authored-by: Claude <noreply@anthropic.com>
…0c6d351ad74; re-measure the first pin citations (wip) Claude-Session: https://claude.ai/code/session_01LYXc6ckoWuZyVZpWYizdMh Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LYXc6ckoWuZyVZpWYizdMh Co-authored-by: Claude <noreply@anthropic.com>
…the spec pin-citation changeset Claude-Session: https://claude.ai/code/session_01LYXc6ckoWuZyVZpWYizdMh Co-authored-by: Claude <noreply@anthropic.com>
…re-citation Claude-Session: https://claude.ai/code/session_01LYXc6ckoWuZyVZpWYizdMh Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LYXc6ckoWuZyVZpWYizdMh Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 6 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 140 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 9ae75989da7b0f8c8ad4b6d5ceeb7f483a4f4748 && git checkout 9ae75989da7b0f8c8ad4b6d5ceeb7f483a4f4748
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 5495331fccb4dc1ff884c485ea66e682eae61402 0b3e83ce57bfe9617addf02930965fbf86d14997 && git checkout -B drift-repro 5495331fccb4dc1ff884c485ea66e682eae61402 && git merge --no-ff 0b3e83ce57bfe9617addf02930965fbf86d14997
node scripts/docs-audit/affected-docs.mjs --json 5495331fccb4dc1ff884c485ea66e682eae61402
|
Contract reviewServed-tier: PR #22592 for card #22476, judged on the head's net diff against its merge base with ① Derived judgmentsEvery accept-set and public-surface change the diff implies, each judged:
② Semver level
③ Boundary flagsDev report
Check-runs on Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #22476
Clause-②: no
This moves the bundled Console's objectui pin from
47b1f0bb7174(PR #22496) to20c6d351ad74d2b14a93becdc134d51b91b2d2e6, which was objectuimainwhen this bump was cut (2026-10-10T00:23:41Z). The maintainer ordered it, in thedomain:devxseat 1's session: 「22476 插队, objectui 更新到最新版。」 and 「22476 objectui 更新到当前的最新版」. The new pin contains objectui2a48bd408dab, the merge of objectstack-ai/objectui#12064, which carries objectstack-ai/objectui#12056's change: Studio's page designer writeselement:repeater's object and limit into the node-leveldataSource. Ruling6051498447on #11509 orders the work this way ("objectui first (…, the designer writes the node-leveldataSource, …), and the spec retirement ships with the pin bump that carries it"). The retirement itself is PR #22421 (#11509), not this PR: no key retires here, no schema shape changes, and no conversion or lint rule changes.The bump follows the repo's own procedure, as PR #22412 did:
scripts/bump-objectui.sh, thenpnpm objectui:buildandnode scripts/gen-sdui-manifest-node.mjs, then the gates they derive. It adds no step to that procedure.This is not a release act. The Version Packages PR is untouched, and this diff edits neither
packages/console/CHANGELOG.mdnorpackages/console/package.json. The console's release input is the new.changeset/console-20c6d351ad74.md.Range and acceptance
mainread20c6d351ad74d2b14a93becdc134d51b91b2d2e6at the cut, 2026-10-10T00:23:41Z (git ls-remote, andorigin/mainof a fresh full clone).compareon objectstack-ai/objectui (base...head, head = the new pin):2a48bd408dab...20c6d351ad74:status: ahead,ahead_by: 7,behind_by: 0. The pin contains that merge. This is the card's acceptance.47b1f0bb7174...20c6d351ad74:ahead, 24 ahead, 0 behind. The pin moves forward frommain's.8a55f0ccda...20c6d351ad74:ahead, 5 ahead, 0 behind (objectui#12059; its checklist amendment platform-checklist: retire the drag-reorder step and acceptance clause of platform-core.shell-nav-personalization — end users do not reorder the runtime sidebar (maintainer ruling 2026-10-09) #22487 landed as9411faa1ba).47b1f0bb7174..20c6d351ad74has 24 commits, 0 merges and 320 changed paths (72 added, 2 deleted, both test files)./i18ndispatcher domain answers an anonymous caller —handleI18nRequestmakes noshouldDenyAnonymouscall, unlike every other dispatcher domain (ADR-0056 D2); with an objectui companion for the Console sign-in page #22432) merged at 2026-10-10T00:22:34Z, before this branch had any commit. This branch then tookmain, so.objectui-shais written by one open PR only.mainhas moved since the cut, tod758f2f20dd1(read 2026-10-10T01:36Z). This bump does not chase it: the ruling namesmainat cut time.The range's notable commits (the two breaking
plugin-listchanges first)3fd862510(objectui#6152 round 14), breaking. The list renderers stop reading the list-view keys every door already refuses: the pre-objectui#2231 aliases (kanban.groupField/cardFields,gallery.imageField,timeline.dateField,calendar.dateFieldas a timeline axis),calendar.defaultView,tree.titleField,options.grid, and any undeclared key of a per-kind block.ListView's projection collectors stop asking the server for the fields those keys named.025341692(objectui#6152 round 15), breaking. Achartlist view binds only an ADR-0021dataset. The legacy inline axes and theirname/valuefloors are retired on every route. A chart view that names no dataset now showsObjectChart's "Chart category axis required" refusal. (Onmain, feat(spec)!: atype: 'chart'list view whose effective binding names no dataset is refused at every list-view door #22528 refuses such a view at every list-view door.)3c3115e38(objectui#5144), annotated breaking: list views readuserActions.editInlinewith the spec's own default,false, folding a booleaninlineEditinto it. A grid that declares neither key no longer offers the inline-edit toggle, and the console toggle no longer writes to the view.c7b30bd66(objectui#12063):UnifiedViewConfig.chartretires in@object-ui/types(types only).8a55f0ccd(objectui#12059): the runtime sidebar menu is not user-reorderable; the pinned section keeps the user's order.2a48bd408(objectui#12056): the page designer writes the repeater's query intodataSource, and the repeater arm takes the spec gate'sobjectwaiver.7282c6a51(objectui#12055, the upload adapter no longer sendspathas the storage scope),e4c0b5432(objectui#5250,objectui validate/checkjudge through the strict face),1f1c4b526andd32869883(objectui#6349 batches 4 and 6, type renames).e97a0e2d1(a declaredtype: 'flow'action starts its flow throughPOST /api/v1/actions/:object/:action, a route this repo serves),9b6c19ef6(the Attachments panel offers Upload and delete only with thesys_attachmentgrant),2571a3eb9(a caller without Studio access is told so),5275d1f37(search on the Studio landing),d99b731f0/a368ccb1a/20c6d351a(approval requests through the standardprovider: 'api'door, a record card and the decision panel),e391f8768(an activity row names its actor fromactor_id),acc432806(plugin-view's gallery reads its nested block),d03b0227c(ObjectChartrefuses before it fetches).b4e0787d5,c0c0a0d56(objectui#6349 batches 5 and 7),55e90fd38,972e56659.The bump's digest: 33 releasing changesets across 24 non-merge commits, 0 release-nothing, 1 commit with no changeset (
972e56659, docs). None declaresmajor; six carry the author's breaking annotation. The highest declared level isminor, so the console changeset isminor. Itsadr-0087: TODOplaceholder is answerednot-required (no-migration-prescription), each of the six annotated entries and the three!subjects named in it.objectstack-side metadata the breaking commits could hit
Measured on this tree (
git grepoverexamples/**,packages/**without tests, fixtures andpackages/spec,content/docs/**withoutreferences/andreleases/, andskills/**):board,cards,calendar,timeline,gantt,map,chart), the showcase project views (by_status,budget_chart), the showcase and platformorg_charttree views (labelField, nevertitleField), and the CRMactivitycalendar andlead/opportunitykanban views.content/docs/protocol/objectui/layout-dsl.mdx:815-816(cardTitle/cardFieldson anobject-kanbancomponent node),content/docs/ui/pages.mdx:157-158(categoryField/valueFieldon a page chart component),content/docs/protocol/objectui/concept.mdx:198(a dashboard widget), and object-levelimageField/ flowdateFieldkeys.chartand project viewbudget_chart, both bind a dataset. Both render at the new pin (below).griddeclaresinlineEdit: trueand keeps its toggle. Grids that declare neither key lose the toggle. That is the spec's declared default (editInline: z.boolean().default(false)), not a break.So the rendered lists do not change for any metadata this repo ships.
Console build and browser smoke
turbo run build --concurrency=2 --filter=@objectstack/client --filter=@objectstack/spec --filter=@objectstack/sdui-parser(34 tasks, exit 0). Thenpnpm objectui:build(exit 0, lock held 7m13s), withOBJECTUI_ROOTat a full scratch clone of objectui, so no worktree was registered in the sibling checkout. Its log reports the bundle canaryimport/jobspresent, exactly one zod version literal, "Console bundle carries THIS tree's @objectstack/spec, and only it", and "@objectstack/console dist ready (64164 KB) from objectui@20c6d351ad74"./opt/pw-browsers/chromium, headless, 1440x900) againstpnpm dev -- --fresh -p 38917on this branch, serving that dist (check:console-shagreen at boot)./_console/lands on the sign-in page. A deep link to a showcase list redirects to/_console/login?redirect=…. The only API reads areruntime/config,auth/me/localization,auth/get-session(the expected 401),auth/configandauth/bootstrap-status. The sign-in page reads no/api/v1/i18n.Pinbutton, and none is draggable. Pinning "Capability Map" puts it in a new pinned section ("Favorites") at the top.summarizeFieldtotals), Cards (Gallery), Calendar (October 2026), Activity Timeline, Schedule (Gantt) and Hours by Status (Chart) all render. The chart draws its bars from theshowcase_task_metricsdataset, with no refusal.demotiles.maplibre.org: an environment limit, not this bump.gridoffers "Edit records inline (click a cell to edit)"; All Tasks does not.favicon.ico404 and the signed-out session 401.What changed here
.objectui-shaOBJECTUI_ROOT=… scripts/bump-objectui.sh 20c6d351ad74… --no-commit.changeset/console-20c6d351ad74.mdcheck-adr-0087-registration,check:objectui-changesetscripts/sdui-manifest.record.jsonnode scripts/gen-sdui-manifest-node.mjsover.cache/objectui-20c6d351ad74check-sdui-manifest.mjspackages/sdui-parser/objectui-lockstep.jsonnode scripts/check-sdui-lockstep.mjs --update,OBJECTUI_ROOTat the same built treecheck:sdui-locksteppackages/spec/src(the generatedmigrations/registry.tsamong them), plus three quoted anchors of the datedview.zod.tsmap recordregistry.tsbygen:migration-registrycheck:objectui-pin-citations(and--verify-anchors).changeset/objectui-pin-citations-20c6d351ad74.md@objectstack/specpatchcontent/docs/references/ui/view.mdxgen:docscheck:docssdui.manifest.jsonis byte-identical across the range: the generator rewrote it to the same bytes (sha256097ae3cbcf95…, 107 components), so only its record moves. objectui's workspace version stays 17.7.0.0131f27cf86d), 25 diagnostic codes and containment predicate76c18fb95d1f, all unchanged. objectui'spackages/sdui-parseris untouched by the range, so no port is owed.main, generated files included.How the citations were re-measured
47b1f0bb7174and intersected with the range's 320 changed paths. Every anchor in a changed file was mapped throughgit diff -U0 47b1f0bb7174 20c6d351ad74and its text compared at both pins. A record whose cited files are all byte-identical (git diff --quiet) gains that sentence and no re-pointing.ListView.tsx,ObjectTimeline.tsx, plugin-view'sObjectView.tsx,objectql.ts,objectql.zod.ts,KanbanImpl.tsx,plugin-grid/src/index.tsx,ActionRunner.ts,data-objectstack/src/index.ts,previews/block-config.ts, and theen/zh/depacks (whosecalendar.configRequiredstrings did not change).KanbanImpl.tsx:668/:681->:671/:684;ActionRunner.composeSuccessMessage1504->1498;object-timelineread points,:306-:565each by +1 (:30and:591on held);data-objectstack'stranslateFilterArrayarm5042-5053->5048-5059;resolveListMapConfig147->200,case 'map':in plugin-view'sObjectView.tsx2340->2461,ObjectMapConfigSchema2513->2523(still.strict());case 'timeline'/case 'map'arms moved by 50 / 52.case 'calendar'andcase 'gantt'arms: their raw spreads and the calendar'sdefaultViewlift retired; the date bindings stay conditional, with no floor;ObjectTimeline.tsx's start-date chain:589-591: lost the nestedtimeline.dateFieldrung, still ends without a literal rung;resolveTimelineDateBinding634->686: its alias rung retired;previews/block-config.ts: the two inspectors re-read,311-345->311-351, with the repeater's rows now writingdataSource.OBJECT_TREE_FLAT_CONFIG_GUIDANCEdocblock inui/component.zod.tskeepstitleFieldin the flat tree key set becauseListView.tsx:3927resolvedtreeCfg.titleFieldintolabelField. objectui3fd862510removed that rung; the arm now emitslabelField: treeCfg.labelField || 'name'(:3986). The record's hop sentence says so, and its paragraph and the key set are left as they are: changing the key set is a schema decision this re-read does not make. The guidance still prescribes the right key (tree.labelField) for a flattitleField, so nothing an author sees is wrong.git grep -o -F. That method first reproduced every47b1f0bb7174number: 8281 files,objectstack17980,@objectstack/spec7523,useState2630,timeout1674,RuntimeConfig337,resourceLimits2,window4449,period249,interval213,metrics455,Span517,SpanSchema57,TTL184 andtenant1338.objectstack18047,@objectstack/spec7545,useState2630,timeout1694,RuntimeConfig337,resourceLimits2 (the same twopackages/app-shellprose hits),window4470,period249,interval213,metrics456,Span517,SpanSchema57,TTL184 andtenant1340.plugin-lifecycle-advanced.zod.ts,tracing.zod.tsandmetrics.zod.ts, plus every named key) still read zero.For the contract review: changed lines in
packages/spec/src/**that are neither a comment nor a string fragmentThere are none. Measured mechanically: each changed file was parsed with the TypeScript compiler at
mainand at the head, JSDoc dropped, comments skipped, and every string, template and regular-expression literal replaced by one placeholder token. The remaining token sequences are identical in 12 of the 15 files. The other three:18.system-metrics-jsdoc-durations-unit-in-key.tsand18.system-tracing-otel-exporter-durations-unit-in-key.tseach gain one+joining one new string fragment into theirreasonstring.migrations/registry.tsmirrors both.No identifier, key, value or export moves. The one shipped
describethat changes isFormField.span's, and only its sha moves.Gates and tests
Everything below ran at head
0b3e83ce5, the merge oforigin/main96e4be482, after a full workspace build at that head (turbo run build --concurrency=2, 72 tasks, exit 0). Exit codes were captured before any pipe.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 127 commands from 21 changed paths against merge base96e4be482. All 127 ran and exited 0. The--ranreconciliation reads "127 derived famil(ies) accounted for — 127 run, 0 NOT-MEASURED (a DERIVED zero — all 127 recorded an exit code and none of them is 3)".check:objectui-pin-citations: "55 asserting objectui pin citation(s) match .objectui-sha (20c6d351a), 145 historical citation(s) recorded and not checked, across 1946 spec source(s)." With--verify-anchors(OBJECTUI_ROOTat a full objectui clone): "13 anchor content assertion(s) verified against objectui at 20c6d351a".check:sdui-lockstep: "OK — this copy is byte-identical to objectui@20c6d351ad74 … over 214 grammar line(s) [blob 0131f27cf86d], agrees on all 25 diagnostic code(s) and on thenot-a-containerpredicate".check-sdui-manifest.mjs: "present, intact (sha256 097ae3cbcf95…, 107 components) and recorded at the live objectui pin 20c6d351ad74…".check:console-sha: "Console dist matches the objectui pin (objectui@20c6d351ad74)".check:console-injection: "the dist carries this tree's copy, and not the published one".check-adr-0087-registration --base origin/main: "1 declared-breaking changeset(s), each carrying an ADR-0087 disposition".check-changeset-no-major --base origin/main: "This diff introduces nomajorbump".check:generated: "All 15 generated artifacts are up to date".check:migration-registry: "src/migrations/registry.ts is current (412 semantic, 247 retired-key, 222 retired-def)".check:api-surface: "public API surface + factory signatures unchanged".check:nul-bytes: OK, no raw control bytes.@objectstack/specvitest (itstestscript,--project local): 638 files, 19014 passed, 1 todo.@objectstack/spectypecheck, the scripts and test-layer checks included: exit 0.@objectstack/sdui-parser: 14 files, 225 passed; typecheck exit 0.@objectstack/lintvalidate-jsx-pages.production-witness.test.ts: 5 passed.@objectstack/metadata-protocolprotocol.runtime-authoring-gate.test.ts: 133 passed.@objectstack/cli, unit tier (sdui-manifest,console.sha-drift,validate-build-gate-parity,console-resolve): 4 files, 108 passed. The integration tier is declared to CI: this diff touches no integration-tier file and no spawn entry.--no-inline-config) over the 15 changed TS files underpackages/spec/src: 0 errors, 0 warnings, 15 files by the--format jsoncount. The population is theeslint.config.mjsblock that lints everytsfile (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-widepnpm lintis CI's run.mainafter the last merge.origin/maingained25be87612(fix(plugin-security): explain composes a lifecycle verb's row-level security as the door does #22570,plugin-securityonly) after0b3e83ce5. It touches no file of this diff, so there is no further merge here; CI and the merge queue judge the merge.Acceptance notes
functional-completeness.ts, thekanbanandtreerows. They carry no asserting citation, and they still describegroupByField || groupField || detectStatusField(objectDef)andlabelField || titleField || 'name', with a sentence saying both were re-read at the pin. At this pinListViewreads neither alias (3fd862510). Theview/layout-without-bindingmessage those rows feed is still true: with no block, the board detects a status field and the tree labels byname. Only the docblock's rung list is stale. Noted here only, carrier: none.OBJECT_TREE_FLAT_CONFIG_GUIDANCErationale (above): stale rationale, correct prescription. Carrier: none.mainmoved tod758f2f20dd1after the cut. The next bump picks it up.check-plugin-teardown-shape.mjs --self-testfirst exited 3 because this checkout could not read its pinned fixture commit621a48760788. That commit was fetched (git fetch --depth=1 origin 621a487…, objects only) and the self-test re-ran to exit 0. A prerequisite, not a red.scripts/pm/fleet-write/dispatch.mjs(pr_create, draft), and its assignee set throughscripts/pm/label-write.mjs. No label was written,skip-changesetincluded: the path and size labels come frompr-automation.yml. No MCP write was used.Generated by Claude Code