Skip to content

chore(objectui): move the console pin to 9646e2ed2bf3 (objectui#12185, objectui#12183) (#15204 C9) - #23018

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-15204-c9-objectui-pin-9646e2ed2
Oct 12, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-15204-c9-objectui-pin-9646e2ed2

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #15204
Clause-②: no

The console pin hop 088e0f705520 → 9646e2ed2bf3 (objectui main, 9646e2ed2bf315a6ae99b2a1633bc7c7d162f7b9, exactly that commit). This hop exists for objectui#12185 (d928c8394, objectui#12183). Under a wall (isolated / group), Setup's security catalog pages (position, permission set, capability) are read-only for a tenant and say why, while the platform operator keeps write. The server already refuses those writes (#22895, #22935).

Tier: no governed surface (GOVERNED_SURFACES in scripts/pm/check-governed-merges.mjs). 20 files.

The hop: 9 objectui commits, all on objectui main

  • d928c8394, objectui#12185 (objectui#12183): under a wall, the catalog pages are read-only for a tenant and say why;
  • 9646e2ed2, objectui#12193: the fallback email-template form stops offering the retired category / isSystem keys;
  • 5dd583f5e, objectui#12199: a gallery card whose title field is a lookup draws the referenced name;
  • 26b0bd2d1, objectui#12189, and 35a2b59a5, objectui#12180: objectui#6349 batches 12 and 11 (one authority each for the FilterBuilder types, DataSource, DomProps, SchemaNode);
  • 5b20aed39, objectui#12181: a hatch-elevated type's packaged item opens read-only;
  • b0c5f9ddf, objectui#12177: Studio names an environment overlay, not an org overlay;
  • 0f31c3a03, objectui#12186 (CLI test) and 7e30d0b6e, objectui#12182 (docs deploy CI): ship no console code.

The pin round, as #22967's

Console Pin Gate steps, run locally (each exited 0):

  1. Client build: turbo run build --filter=@objectstack/client....
  2. scripts/build-console.sh at the pin.
  3. check:console-sha: "Console dist matches the objectui pin (objectui@9646e2ed2bf3)".
  4. check:console-injection --require-stamp.

Artefacts that travel with the pin:

  • Console changeset. scripts/bump-objectui.sh generated .changeset/console-9646e2ed2bf3.md: @objectstack/console minor, the level chore(objectui): move the console pin to 088e0f705520 (objectui#12175 PR-5, #12174 Q3b) (#15204 B2) #22967 used (also the level the script derived from objectui's own changesets). It has 13 releasing entries and 0 breaking, so there is no ADR-0087 placeholder. One commit carries no changeset and is listed by subject. Clause-②: no was added by hand, as in chore(objectui): move the console pin to 088e0f705520 (objectui#12175 PR-5, #12174 Q3b) (#15204 B2) #22967. check:objectui-changeset passes.
  • SDUI manifest. node scripts/gen-sdui-manifest-node.mjs: sdui.manifest.json is byte-identical across the hop (107 components), and scripts/sdui-manifest.record.json is re-recorded at the pin. check-sdui-manifest passes.
  • Lockstep record. pnpm gen:sdui-lockstep re-records packages/sdui-parser/objectui-lockstep.json at 9646e2ed2bf3. objectui's sdui-parser changed on this hop (objectui#12180's type renames), and check:sdui-lockstep still passes: 214 grammar lines are byte-identical, all 25 diagnostic codes agree, and the not-a-container predicate agrees. No parser port is owed.
  • Pin citations, re-measured for this hop only (re-measure, never find-and-replace):
    • one file that any record cites changed on the hop: plugin-list/src/ListView.tsx (+9/-9, objectui#12189, the FilterBuilder group type's rename). All nine lines were replaced in place (:13, :324, :326, :332, :399, :756, :774, :777, :1558), so no line in the file moved and no cited range contains a changed line. Its case 'kanban' / 'calendar' / 'timeline' / 'gantt' / 'map' / 'tree' arms held at 3762 / 3813 / 3902 / 3959 / 4079 / 4120-4144. resolveListMapConfig :209-214 and resolveTimelineDateBinding :695-699 held too, each ending before the next changed line below it;
    • the records citing it got hand-written hop sentences: the four view-type rows of the functional-completeness table (calendar, gantt, timeline, map), plus the object-gantt and flat-TreeConfig records in component.zod.ts. The kanban row-cap record names ListView.tsx / ObjectView.tsx only as an earlier re-read's record, and its sentence says so;
    • every other record cites only files that are byte-identical across the hop, and each gains a hop sentence saying so. Every cited objectui file was resolved against the tree at the pin and checked with git diff --quiet 088e0f705520 9646e2ed2bf3 -- <path>, one file at a time; bare names (index.tsx, types.ts, button.tsx) were resolved by their record's context. That covers form.tsx, autoLayout.ts, field-type-alias.ts, ObjectCalendar.tsx, the en / zh / de packs, data-objectstack/src/index.ts and the action renderers, so the FormField.span describe's claim holds (pin re-stamped, content/docs/references/ui/view.mdx regenerated by check:generated --fix, the only stale artifact);
    • the six migration entries were recounted with git grep -o -F, which reproduces every 088e0f705520 figure exactly. The corpus is 8540 files, and every retired name each entry counts still reads 0. A superset was counted to be safe: every current export of plugin-lifecycle-advanced.zod.ts, metrics.zod.ts and tracing.zod.ts, plus every key each entry names. Every term is 0 except the unrelated Span 519 / SpanSchema 57, which the tracing entry already explains and which are unchanged. The lit controls moved with the corpus, e.g. objectstack 18400 → 18438, tenant 1365 → 1393;
    • check:objectui-pin-citations --verify-anchors: 55 asserting citations match 9646e2ed2, and the 13 quoted anchors verify against objectui at the pin. gen:migration-registry regenerates the six generated-registry rows;
    • changeset .changeset/objectui-pin-citations-9646e2ed2bf3.md: @objectstack/spec patch, Clause-②: no.

Browser check, against this branch's built console

examples/app-showcase was booted --fresh on this branch's console dist (Playwright, Chromium), once per posture. Harness note: as committed, the showcase cannot boot walled. It does not declare @objectstack/organizations, and the CLI refuses a walled posture without it (ADR-0093 D5). A walled boot also needs OS_PLATFORM_OWNER_EMAIL and a declared OS_AUTH_MEMBERSHIP_POLICY. For the isolated and group runs I added the dependency to the showcase's package.json locally and uncommitted, set OS_PLATFORM_OWNER_EMAIL=admin@objectos.ai and OS_AUTH_MEMBERSHIP_POLICY=invite-only, and reverted both files afterwards. /auth/config served tenancyPosture: isolated / group with degradedTenancy: false.

Tenant fixture (each walled run): tenant@wall.test owns organization "Tenant A". The operator authored a runtime permission set w_meta_author (manage_metadata) and a runtime position wall_demo_pos, and granted w_meta_author to the tenant inside Tenant A. The tenant's /auth/me/permissions carries manage_metadata, and its session reads isPlatformAdmin: false. The server refuses the tenant's PUT /meta/position/wall_probe with 403 FORBIDDEN naming the posture.

position list / editor permission-set list / editor capability list / editor
isolated, tenant no New; catalog-readonly-reason; editor walled-catalog-readonly-banner, no Design / Save / Delete, Delegatable switch disabled no New; reason line; editor perm-walled-readonly, badge "Read-only (the platform operator defines this catalog)", no Save / Clone read-only by the package lock ("locked … com.example.showcase@0.1.0"), the type's own tier, as objectui#12185 specifies for a stock capability
isolated, operator New offered; editor in Design with editable fields and the save / delete affordances New offered; editor offers Save read-only (code-only type: the server refuses a runtime capability for everyone, allowRuntimeCreate=false)
group, tenant as isolated as isolated as isolated
group, operator as isolated; a label edit auto-saved: PUT /meta/position/wall_demo_pos?mode=draft → 200 as isolated as isolated
single, non-operator manage_metadata holder (author@single.test, isPlatformAdmin: false) New offered, editor editable, no wall notes; a label edit auto-saved: PUT …?mode=draft → 200 New offered; editor offers Save read-only (type tier, as before)

The one enabled switch on the tenant's permission-set editor is the matrix's "Only granted" view filter, not a write.

User page grant pickers (single, as the operator, on author@single.test's record): the Positions tab's New opens the grant form, and registry-ref-position lists 17 positions (16 stock plus wall_demo_pos). The Permission Sets tab's New opens registry-ref-permission, which lists 18 permission sets. Picking auditor and showcase_auditor and pressing Create wrote both rows (POST /data/sys_user_position → 201, POST /data/sys_user_permission_set → 201), confirmed through the data API. everyone is still listed among the positions: the open objectui finding #22967 carried, unchanged by this hop.

Also seen, not this hop's: a fresh workspace opens the "Set the workspace timezone" dialog over Setup until it is dismissed.

Verification (local)

  • full turbo run build green (74/74, none cached);
  • check:generated: 14/14 current after the view.mdx regeneration;
  • dispatch-gates --ran: 125 derived families. The sweep was running when this draft opened, and its verdict follows in a comment.

🤖 Generated with Claude Code

https://claude.ai/code/session_018yfmohHttjK9aTbKnZLuDr

@github-actions

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
  • 1 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 111ffff55603f0f9994f6d6a4a43cb1f60580f3d → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 367b1a38d516f1d2d610ce5abc8c9a44e322d233 — the merge of head 724aeda4e3bf2ea117880eede95757c910d18616 into base 111ffff55603f0f9994f6d6a4a43cb1f60580f3d, 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 367b1a38d516f1d2d610ce5abc8c9a44e322d233 && git checkout 367b1a38d516f1d2d610ce5abc8c9a44e322d233
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 111ffff55603f0f9994f6d6a4a43cb1f60580f3d 724aeda4e3bf2ea117880eede95757c910d18616 && git checkout -B drift-repro 111ffff55603f0f9994f6d6a4a43cb1f60580f3d && git merge --no-ff 724aeda4e3bf2ea117880eede95757c910d18616

node scripts/docs-audit/affected-docs.mjs --json 111ffff55603f0f9994f6d6a4a43cb1f60580f3d

⚠️ 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 111ffff55603f0f9994f6d6a4a43cb1f60580f3d → 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

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 724aeda4e3bf2ea117880eede95757c910d18616
Local-runs: none

PR #23018 (card #15204 C9: the console pin hop objectui 088e0f705520 → 9646e2ed2bf3, for objectui#12185), read at 2026-10-12T10:15Z. Inputs and nothing else: the card body and its 177 comments (the hop #2 dispatch and claim 6121141158, the rulings 6119234024 and 6121771692, the Landed record 6121083900); the precedent #22967's body, its FAIL 6119955714 and its delta PASS 6120490239; the PR body, its 20-file list, the net diff against the merge base 74c4b3435e (+259 / −55) and its one comment; objectui at both pins in a scratch clone (--filter=blob:none), read with git only; packages/spec/scripts/check-objectui-pin-citations.ts, scripts/build-console.sh, scripts/bump-objectui.sh, scripts/objectui-changeset-digest.mjs, scripts/gen-sdui-manifest-node.mjs, scripts/check-sdui-manifest.mjs, scripts/check-sdui-lockstep.mjs, scripts/regen-artifacts.mjs, scripts/pm/check-governed-merges.mjs, .github/workflows/ci.yml / lint.yml and .changeset/pre.json on main; the head's check-runs through REST, polled until every one completed. The dev's and the seat's conclusions were read for what they assert and not adopted; every reading below was re-taken from the trees, the diff and the check-runs. Nothing was built, run or re-run.

① Derived judgments

1. The pin and its gate — hold. .objectui-sha reads 9646e2ed2bf315a6ae99b2a1633bc7c7d162f7b9, nothing else. In the scratch clone git merge-base --is-ancestor 088e0f705520 9646e2ed2bf3 exits 0, 9646e2ed2 is itself an ancestor of objectui main (6c437b07e at read time), and git log 088e0f705520..9646e2ed2bf3 is exactly the nine commits the body lists, all squashes, nothing on a side branch: b0c5f9ddf (#12177), 5b20aed39 (#12181), 35a2b59a5 (#12180), 7e30d0b6e (#12182), d928c8394 (#12185, committed 05:18Z, two hours after 088e0f705's 03:19Z, as the dispatch says), 0f31c3a03 (#12186), 26b0bd2d1 (#12189), 5dd583f5e (#12199), 9646e2ed2 (#12193). The hop is 64 paths (+2431 / −384), 14 of them .changeset/*.md. Console Pin Gate on this head is success (run 38234669497, job 114762401765); it did not skip, because the diff moves .objectui-sha and the filter job's console output is not false.

2. The SDUI artefacts — hold; no parser port is owed. sdui.manifest.json is not in the diff; scripts/sdui-manifest.record.json keeps sha256 a799c55a18d6… and components: 107 on both sides and changes only objectuiSha and modulesRoot, so the manifest the generator wrote from the tree built at 9646e2ed2 is byte-identical to main's (107 components), as the body says. That is consistent with the hop: each of its fourteen changesets says the package entry gains no export, prop, type member or input, and the four minor ones rename TypeScript names only. check-sdui-manifest (record = artefact = pin) and check:sdui-lockstep run in Lint & Repo Gates (see 6). Lockstep: objectui's packages/sdui-parser/src DID change on this hop — four files, +24 / −14, all in 35a2b59a5 (objectui#12180): SchemaNode → ParsedSchemaNode at parse.ts:7, :17, :127, :206-207, types.ts:4-24, validate.ts:27, :228 and body-dialect.ts:36, :52, a type rename and its docblock, no grammar and no code. Re-taken against the record: the delimiter /* ---------------------- the JS literal subset (#6614) ---------------------- */ sits at parse.ts:392 of 605 at both pins, the region from it to end of file is 214 lines, a diff of the two regions is empty, and git hash-object of the region at 9646e2ed2 is 0131f27cf86d…, the record's grammarRegion.blob. Each of the 25 recorded diagnostic codes occurs the same number of times at both pins, and the hop adds no code (the whole src diff is the rename). The containment predicate's three lines are identical at both pins: validate.ts:39 export const CHILD_LIST_KEY = 'children';, :63 export function acceptsChildren(…), :341 if (node.children?.length && !acceptsChildren(comp)) — the record's containmentPredicate.text. packages/sdui-parser/objectui-lockstep.json changes exactly rev, revDate (2026-10-12T08:01:27+00:00, the committer date of 9646e2ed2) and recordedAgainstPin; grammarRegion, diagnosticCodes and containmentPredicate are byte-identical to main's.

3. The spec source edits — comments and strings only; no accept-set change. A mechanical filter over the diff (every + / − line under packages/spec/src that does not begin as a comment line or as a + '…' string fragment) leaves exactly two lines: the old and new FormField.span describe in view.zod.ts:3560, which differ in the pin sha alone. component.zod.ts (+113 / −21), action.zod.ts, dataset.zod.ts (+3 each) and functional-completeness.ts (+32 / −4) change comment lines only; the six 18.* migration entries change rationale string fragments only (the pin sha, the corpus count 8519 → 8540 and the lit controls). No key, default, .optional(), required flag, enum member or export moves; nothing is tombstoned. Clause-②: no and the patch level are right in kind; the content of the comments is judged in 4.

4. The citations — the precedent's failure class does not recur.

  • Population. A wrap-safe grep of the asserting spelling (= `9646e2ed2) over packages/spec/src at the head finds 38 citations (30 short, the six entries' full shas, the describe's 9646e2ed2bf3, one wrapped at component.zod.ts:4866) against 38 naming 088e0f705 on main: the whole population moved, none names an old sha, and the bare form occurs 0 times. The gate itself (check:objectui-pin-citations, which runs in Type Check · source gates) is success on this head. The body's "55" is the gate's own census and was not reproduced by that grep; nothing turns on it.
  • Method. 40 records across the eight files carry a 9646e2ed2 hop sentence (action-outcome-messages.test.ts 1, action.zod.ts 1, api-methods-batch-conformance.test.ts 1, component.test.ts 6, component.zod.ts 26, dataset.zod.ts 1, functional-completeness.ts 1 docblock holding the four view-type rows, view.zod.ts 1 plus the describe): 34 carry the boilerplate "every objectui file this record cites is byte-identical across the hop from 088e0f705", 6 are bespoke. Every file-shaped token in each of the 40 blocks was resolved against git ls-tree -r at the pin (8540 paths) and intersected with the hop's 64 changed paths; a bare basename (index.tsx, types.ts, button.tsx, renderer.tsx, autoLayout.ts, form.tsx, ObjectView.tsx) was resolved by its record's context. The ONLY hop path any record names is plugin-list/src/ListView.tsx, and every record naming it says it changed: the calendar, gantt, timeline and map rows of the functional-completeness table, the object-gantt record (component.zod.ts:8657), the flat-TreeConfig record (:8944), and the kanban row-cap record (:6138), whose sentence says ListView.tsx / ObjectView.tsx are named below only as an earlier re-read's record — true: :6321-6327 keep the ListView.tsx:2979 → :3067 and ObjectView.tsx:1638 → :1666 pairs as "that re-read's record only … so this block no longer cites them". The bare index.tsx / types.ts tokens in the nine boilerplate blocks that could have meant fields/src/index.tsx, app-shell/src/types.ts or sdui-parser/src/types.ts all read, in context, plugin-kanban/src/types.ts, the plugin-kanban / plugin-map / plugin-timeline shells or "all five src/index.tsx shells" — each byte-identical. No boilerplate sentence names a changed file.
  • Every cited file, git diff --quiet 088e0f705520 9646e2ed2bf3. The 40 blocks' tokens resolve to 93 candidate paths at the pin; the command exits 0 on 89 and 1 on four: ListView.tsx, and the three bare-basename candidates no record names (fields/src/index.tsx, app-shell/src/types.ts, sdui-parser/src/types.ts, resolved away above). Among the 89, exit 0 on each of: plugin-form/src/autoLayout.ts, plugin-detail/src/autoLayout.ts, fields/src/field-type-alias.ts, components/src/renderers/form/form.tsx, plugin-calendar/src/ObjectCalendar.tsx and index.tsx, i18n/src/locales/en.ts / zh.ts / de.ts, plugin-gantt/src/ObjectGantt.tsx and index.tsx, core/src/utils/record-source.ts, plugin-timeline/src/ObjectTimeline.tsx / renderer.tsx / index.tsx, plugin-map/src/ObjectMap.tsx and index.tsx, plugin-tree/src/ObjectTree.tsx and index.tsx, plugin-kanban/src/ObjectKanban.tsx / index.tsx / types.ts, plugin-grid/src/ObjectGrid.tsx, index.tsx and hooks/useBulkExecutor.ts, data-objectstack/src/index.ts, core/src/registry/public-blocks.ts, core/src/actions/ActionRunner.ts, react/src/hooks/useActionRunner.ts, react/src/SchemaRenderer.tsx, core/src/utils/dataset-format.ts and date-display.ts, components/src/renderers/action/action-bar.tsx / action-button.tsx / action-group.tsx / action-icon.tsx / action-menu.tsx / auto-trigger.ts / static-params.ts, components/src/renderers/basic/data-list.tsx, components/src/renderers/complex/data-table.tsx, components/src/renderers/form/button.tsx, components/src/renderers/layout/containers.tsx, components/src/ui/button.tsx, app-shell/src/views/ObjectView.tsx, plugin-view/src/ObjectView.tsx, app-shell/src/views/metadata-admin/previews/block-config.ts, plugin-detail/src/renderers/record-details.tsx / record-highlights.tsx / record-quick-actions.tsx, types/src/permissions.ts, types/src/objectql.ts, components/src/renderers/action/resolve-icon.ts, components/src/lib/lazy-icon.tsx, core/src/data-scope/element-data-source.ts, react/src/element-data-source/ElementDataSourceGate.tsx. The two records the precedent held false are true this hop: the calendar row names ObjectCalendar.tsx and the three packs byte-identical (they are) and ListView.tsx changed; the §4b record (component.zod.ts:3432) is boilerplate this hop, and its eleven renderer files plus data-objectstack/src/index.ts all exit 0.
  • ListView.tsx, spot-checked. Changed in 26b0bd2d1 alone, +9 / −9, nine one-line hunks at :13, :324, :326, :332, :399, :756, :774, :777, :1558; 6003 lines at both pins, so nothing below :1558 moved. At 9646e2ed2: case 'kanban' :3762, 'calendar' :3813, 'timeline' :3902, 'gantt' :3959, 'map' :4079, 'tree' :4120-4144 with labelField: treeCfg.labelField || 'name' at :4140; function resolveListMapConfig :209-214 and export function resolveTimelineDateBinding :695-699, each ending above the next changed line (:324, :756). The body's and the changeset's figures agree with these (the two list the arms in different orders; the pairs are the same).
  • Other anchors the bespoke sentences name, at 9646e2ed2: plugin-form/src/autoLayout.ts resolveColSpan :154, WIDE_FIELD_TYPES :58-69; form.tsx function spanLadderFor :275 to return ladder.join(' ') :302, its one call :3329; ObjectCalendar.tsx getCalendarConfig :311, if (!calendarConfig) { :1354, tt('calendar.configRequired', …) :1360-1362, en.ts configRequired :949; ObjectGantt.tsx getGanttConfig :612, if (!ganttConfig) { :2330; ObjectTimeline.tsx start-date chain :589-591, refusal arm :974; ObjectMap.tsx getMapConfig :421, hasCoordinateBinding :527, refusal arm :1337; ObjectTree.tsx getTreeConfig :289-302 and the docblock above it :240-261 (both in ObjectTree.tsx, as commit 56bf27affb recorded when they moved there; plugin-tree/src/index.tsx is 111 lines and holds neither — the sentence's byte-identity claim covers both files and is true). The action-group / action-menu record (component.zod.ts:4025) names action-group.tsx, action-menu.tsx and static-params.ts byte-identical: exit 0 on each.
  • The six migration entries. git ls-tree -r counts 8519 and 8540 tracked files. Every figure in the diff reproduces with git grep -o -F at 9646e2ed2: objectstack 18438, @objectstack/spec 7612, tenant 1393, TTL 184, useState 2662, timeout 1707, window 4618, period 251, interval 238, metrics 456, RuntimeConfig 357, resourceLimits 2, Span 519, SpanSchema 57; and at 088e0f705 the same method gives every old figure (18400, 7603, 1365, 184, 2661, 1706, 4615, …). debounceDelay, flushInterval, initialDelay, HttpDestinationConfig, LoggingConfig, schemaCacheTtlSeconds, resourceLimits.timeout, collectionInterval, retention.period and every export of plugin-lifecycle-advanced.zod.ts, metrics.zod.ts and tracing.zod.ts read 0 at the pin, Span / SpanSchema excepted as the tracing entry already explains.
  • content/docs/references/ui/view.mdx changes two rows (the FormField table and the form-view select-option shape, which derive from the same describe); each row's description cell equals the new describe byte for byte once the table's \| escapes are undone, no other sha remains in the file, and content/docs/references/** is the gen:docs / check:docs route in scripts/regen-artifacts.mjs. A regeneration's shape, not a hand edit; Build Docs is success.

5. The three edited tests — comment-only, no assertion moved. The non-comment filter in 3 finds no changed line in api-methods-batch-conformance.test.ts (+4 / −1), action-outcome-messages.test.ts (+3) or component.test.ts (+24 / −6). Each change is a hop sentence inserted into a record that carries an asserting citation: the SINGLE_RECORD_WRITE_ONLY header (ObjectGrid.tsx's bulk door, useBulkExecutor.ts), the file header naming objectui#11344's reader (ActionRunner.ts, useActionRunner.ts), and six describe headers (containers.tsx, the plugin-kanban files, form/button.tsx, resolve-icon.ts, lazy-icon.tsx, the object-* renderers) — every cited file byte-identical across the hop. No expect, fixture, specimen or describe title changed; none weakens an assertion to pass.

6. CI on the head — no red; four runs still in progress at render time (10:33Z), named. 34 check-runs: 29 success, 1 skipped (Packed-tarball smoke (opt-in)), 0 failure, and 4 in_progress: Lint & Repo Gates (job 114762294728 — the job that runs check:sdui-lockstep, check-sdui-manifest and check:objectui-changeset; its verdict on those three is therefore not yet on the head, and ①2 above rests on the trees and the record files, not on it), Test Core (2/6), Test Core (3/6) and Test Core (4/6) (jobs 114762402049, 114762401803, 114762401780; the aggregate Test Core gate follows them). Green by name: Console Pin Gate, Build Core, Build Docs, Check Changeset, Check Documentation Links, Check PR Size, Dogfood Regression Gate and its three shards, Dogfood Verify CLI, Flag docs affected by code changes, Governed Surface Queue Guard, Spec property liveness, Temporal Conformance (live PG + MySQL), Test Core (1/6), (5/6), (6/6), Type Check · source gates (which carries check:objectui-pin-citations), Type Check · workspace / debt ledger / consumer gates, TypeScript Type Check, filter, Auto Label, and the four PR-context guards (No other open PR may claim the same issue, … the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch). This record's PASS is on the diff and the trees; the four pending conclusions are owed before the PR leaves draft, and a red among them is not covered here.

7. The base. The merge base is 74c4b3435e (#22967's merge). origin/main has moved two commits since (147a0d1acc #22931, 6a7eca6868 #22936); neither touches a path in this PR, 088e0f705 survives on main only in the files this PR moves and in the previous hop's two historical changesets, and git merge-tree --write-tree origin/main FETCH_HEAD is clean.

② Semver level

  • .changeset/console-9646e2ed2bf3.md, @objectstack/console minor: the highest level objectui declared over the range (LEVEL_RANK in objectui-changeset-digest.mjs: 6349-batch12-components, 6349-batch12-types, 6349-batch11-fields and 6349-batch11-sdui-parser are minor, the other nine patch), the level chore(objectui): move the console pin to 088e0f705520 (objectui#12175 PR-5, #12174 Q3b) (#15204 B2) #22967 used, under pre.json mode: pre, tag: next. Its header reproduces from the log: 14 changesets added across the nine commits, 12176-ratchet-field-namespace.md has an empty frontmatter (release-nothing, from 0f31c3a03), 7e30d0b6e adds none, so "13 releasing of 14" and the one (no changeset) subject are exact; each of the 13 entries is the opening sentence of the changeset it names, truncated, and each names the commit that added it. "0 breaking" is the digest's own reading: hasBreakingAnnotation flags an emphasis run or block that OPENS with "breaking", and the four batch-11 / 12 changesets write "Type change, breaking for some consumers.", which it does not match — rightly for this package, since they rename TypeScript exports of @object-ui/* (FilterBuilderCondition / FilterGroup → FilterBuilderRow / FilterBuilderRowGroup, FilterBuilderOperator dropped from types, DomProps → FieldDomProps, SchemaNode → ParsedSchemaNode), which no consumer of the prebuilt console dist imports. No subject carries !, so no ADR-0087 marker is owed; both Check Changeset runs are green. Clause-②: no is right for this repository: the hop adds no ObjectStack-authorable key (objectui#12193 narrows a client fallback form to what the spec already refuses; objectui#12185 reads two facts the server already publishes).
  • .changeset/objectui-pin-citations-9646e2ed2bf3.md, @objectstack/spec patch, Clause-②: no: the right level and kind for a comment-and-description re-measure, and every sentence re-takes true on the sweep in ①4 — 64 paths over 9 commits; one cited file changed (ListView.tsx, +9 / −9, 26b0bd2d1, nine lines in place, the last :1558); the six arms and the two helpers at the lines it gives; the records it says cite it are the ones that do; "every other record cites only files that are byte-identical across the hop" (true for all 34 boilerplate records and the other bespoke ones); form.tsx byte-identical; the corpus 8540 and the three lit-control moves; nothing on the accept set moves.
  • The PR body's line 2 reads Clause-②: no, consistent with both.

③ Boundary flags

  • The browser check and its harness deviation — stated honestly, adequate for what the dispatch asked. The premises hold on main: examples/app-showcase/package.json declares no @objectstack/organizations; serve.ts's formatOrganizationsAbsentFatal refuses a walled posture without it (ADR-0093 D5); OS_AUTH_MEMBERSHIP_POLICY is the organizations plugin's own env (membership-policy-gate.ts). Adding the dependency and the two env vars locally is the minimum that boots the showcase walled, the body says both files were reverted, and neither is in the PR's file list. The evidence: /auth/config served isolated / group with degradedTenancy: false; the tenant holds manage_metadata and reads isPlatformAdmin: false; the server's 403 is the control; list and editor of the position and permission-set pages are read-only for the tenant and writable for the operator under both walls, writable under single, and the grant pickers wrote both rows. That is objectui#12185's behaviour for two of the three catalogs. For the capability page the showcase can show only the stock, package-locked capability, so what the tenant saw is the type-tier lock, on both rungs; the wall's own banner on a capability needs an OS_METADATA_WRITABLE-elevated runtime capability, which objectui#12185's own tests cover (walledCatalogReadOnly-12183.test.tsx:322-335: hatch-elevated → read-only by the wall, operator may edit; stock → read-only by its type for everyone, the type named) and the body says so in those words. Not a hold.
  • Carried, unchanged by this hop: everyone listed in the position picker (objectui#12200, the limitation already recorded on chore(objectui): move the console pin to 088e0f705520 (objectui#12175 PR-5, #12174 Q3b) (#15204 B2) #22967); the timezone dialog over Setup on a fresh workspace.
  • The sweep verdict is outstanding. The body says dispatch-gates --ran (125 families) was running and "its verdict follows in a comment"; at read time the PR's only comment is the docs-drift advisory. The owning seat should see that comment before landing; the merge gate is CI, green so far with the four runs ①6 names still pending.
  • Docs drift advisory (6122174164) names analytics.mdx and layout-dsl.mdx through DatasetMeasureSchema and ComponentPropsMap; this diff touches those symbols' files in comment lines only, so nothing is owed, and the release pages it lists are read-only by rule and untouched here.
  • Dev claims not re-run (read-only shape): the four local Console Pin Gate steps, check:objectui-changeset, check:generated 14/14, the gate's "55 asserting citations / 13 quoted anchors" census, the turbo run build 74/74. Nothing this record needed was NOT MEASURED.
  • State. 20 files, none under GOVERNED_SURFACES (docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md); no CHANGELOG.md, no content/docs/releases/**, no file outside the pin round's shape (the same 20-path shape as chore(objectui): move the console pin to 088e0f705520 (objectui#12175 PR-5, #12174 Q3b) (#15204 B2) #22967); head repo is the base repo; draft, auto-merge unarmed; .objectui-sha is claimed for this hop by 6121141158 and the single-writer guard is green. Implemented-by is the dev's session id, as a mode:remote dispatch records it.
  • Independence. Reviewed-by names the seat session that holds the claim; the verdict was rendered by an isolated reviewing subagent of that session with the inputs listed above and no others.

Implemented-by: session_018yfmohHttjK9aTbKnZLuDr
Reviewed-by: session_01Rerax7QTjKMPCUZxQUtPFR

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat ACCEPT: #23018 (the console pin hop objectui 088e0f705520 → 9646e2ed2bf3, carrying objectui#12185) at 724aeda4e3; queued on green

Epic PM session_01Rerax7QTjKMPCUZxQUtPFR (marchtian), seat epic:#15194, 2026-10-12T10:49Z.

What the hop carries: the nine objectui commits b0c5f9ddf … 9646e2ed2, all on objectui main, among them d928c8394 (objectui#12185). That change makes Setup's position, permission-set and capability pages read-only for a walled tenant and say why, while the operator keeps write.

Checklist, read on GitHub, not from the report:

  • PR form: draft, base main; Part of #15204, then Clause-②: no; no closing keyword; assignee marchtian. check-governed-merges --pr reads NOT governed. 20 files, +259/−55, the same 20-path shape as chore(objectui): move the console pin to 088e0f705520 (objectui#12175 PR-5, #12174 Q3b) (#15204 B2) #22967. No CHANGELOG.md, no content/docs/releases/.
  • The pin and its gate: .objectui-sha is 9646e2ed2bf3, a descendant of 088e0f705520. Console Pin Gate is success and did not skip. Locally the developer ran its 4 steps, each exit 0.
  • SDUI:
    • sdui.manifest.json is byte-identical across the hop (107 components; the record's sha256 is unchanged).
    • objectui's sdui-parser changed on this hop (objectui#12180, a type rename only). The review re-took the lockstep: the 214-line grammar region is byte-identical, all 25 diagnostic codes agree, and the containment predicate agrees. No parser port is owed.
  • Spec edits: comments and citation strings only. A mechanical non-comment filter leaves only the FormField.span describe's sha, so no shape, default or export moved. The three edited tests change comments only, and no assertion moved.
  • Citations:
    • The only changed cited file is plugin-list/src/ListView.tsx (+9/−9, objectui#12189). Its nine one-line hunks replace lines in place, so every cited anchor held.
    • Every record naming that file says it changed. All other records cite files that are byte-identical across the hop.
    • The six migration entries reproduce at corpus 8540, and every retired name reads 0.
    • check:objectui-pin-citations is green on the head.
  • Changesets:
  • Browser (the developer, against this dist, walled with a local uncommitted harness change that the body states and that is not in the file list):
  • Gates:
    • dispatch-gates --ran: 125 of 125 derived families run, each exit 0. The developer reported this to the seat at 10:28Z, after the review was rendered.
    • spec 650 files / 19,414 passed; sdui-parser 225 passed; turbo run build 74/74.
  • CI on 724aeda4e3: 35 check-runs: 34 success, 1 skipped (Packed-tarball smoke (opt-in), on the expected-skip roster). Lint & Repo Gates (lockstep, manifest, changeset digest) and all six Test Core shards are green. mergeable_state is clean.

Then: flipped ready and enqueued in this same stroke. On MERGED: a Landed record, and the .objectui-sha claim is released.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 12, 2026 10:50
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 12, 2026 10:50
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit 2acff87 Oct 12, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-15204-c9-objectui-pin-9646e2ed2 branch October 12, 2026 11:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants