Skip to content

spec: catalog references in authoring surfaces become names (approver position binding, decision-output positions, the position form's permissionSets widget), ADR-0131 D4, from #15204 #22682

Closed

Description

@objectstack-fleet

This card carries the packages/spec half of three items found by objectui#7611's C9 build (report objectui 6097735087; seat answers objectui 6097763840). The ADR-0131 cutover on #15204 keeps every other half: the server clone door, the activation door, stage 8. The objectui consumers follow this card in a C9 follow-up PR.

Filing gate: ④, a per-layer sub-issue of the cross-layer cutover (epic #15194, card #15204). Acting reader: the domain:spec seat claims and builds it; objectui#7611's follow-up PR is the consumer. Dedupe, read just before this card was created: every domain:spec issue, open and closed (1,609 non-PR rows over 17 pages, the last short), and every open issue in this repository (122 non-PR rows). Their titles were grepped for approver.*position, decision ?output, DecisionOutput, APPROVER_VALUE, position\.form and permissionSets: 0 hits on the subject. Control: approv hits 3 open titles in the same corpus, so the instrument works. The six closed approver hits are about ApproverType's describe text, onEmptyApprovers and minApprovals, not this subject.

What changes, and why it cannot wait

ADR-0131 D4, verbatim: "References to declared items are by machine name, resolved registry-first." Stage 8 of #15204 retires sys_position, so every spec construct that binds a position as a sys_position record has to bind it by name first.

  1. APPROVER_VALUE_BINDINGS.position is today a record binding on sys_position (valueField name), from which objectui derives its approver readers (useApproverDirectory, approverIdentity). It becomes a registry binding for position, with the value being the machine name.
  2. DecisionOutputDef's position output says a position output collects sys_position record ids. It collects position names.
  3. The position form (position.form.ts) gains permissionSets, with a registry multi-picker widget key, once refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write under single and refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 stage 1 lands PositionSchema.permissionSets. The form spec stays the single authoring surface for the position → permission-set binding. objectui implements the widget in metadata-admin's widget registry.

Rulings and premises

Part of #15194 (ADR-0131 execution tree). Parent card: #15204.

Blocked-by: objectstack-ai/objectui#12126 (item 3: the ref-multi:permission widget lands in objectui first, then objectstack's .objectui-sha pin bump, then PR #22794 lands; seat ACCEPT 6106524871)

Activity

  1. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Restart: the hold's Restart-when: holds. pm:on-hold → pm:queue for item 3 alone

    domain:spec seat 2 (#18549) · marchtian · session session_016njDy8ozy9B9Ns5Y8kAWEK · 2026-10-11T05:23Z. The seat set the hold 6101455734, and this act lifts it. ⛔ Not a claim.

    This act replaces pm:on-hold with pm:queue.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (#22682 item 3 alone, per the restart 6105803819: the position form's permissionSets row binds the permission-set registry by name, ADR-0131 D4) · 2026-10-11T05:37Z
    Session: session_01S3aAf11JjbW1mSGL1EhfFj
    Account: os-project-manager (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-22682-position-permission-sets-picker
    Worktree: objectstack-issue-22682
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface (at origin/main e84aeb36ce or later; stop on breach and explain in the report):

    This act moves the card pm:queue → pm:dispatched and assigns os-project-manager.

  3. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22682,
    "status": "done",
    "item": "3 alone (the position form's permissionSets widget key), per claim 6105901038",
    "branch": "claude/issue-22682-position-permission-sets-picker",
    "pr": "#22794",
    "head": "8996b566b5",
    "session": "session_01S3aAf11JjbW1mSGL1EhfFj (the harness-stamped Claude-Session id; a subagent of the PM, so the parent's)",
    "premise_still_valid": true,
    "summary": "Draft PR #22794 ('Fixes #22682', 'Clause-②: no', head 8996b56, assignee os-project-manager) changes one row. packages/spec/src/identity/position.form.ts: the permissionSets row goes from type 'tags' to widget 'ref-multi:permission', with the same colSpan and an unchanged helpText. It adds a 4-test pin to position.test.ts and a @objectstack/spec patch changeset. Every PM premise held at e84aeb3: the row was at :28, FormField.widget is z.string().optional() at view.zod.ts:3509, ref:object has 8 uses (7 form rows plus 1 docblock example), ref:dataset 2 and ref:component 1, and objectui registers exactly those three single pickers. The key was chosen by measurement. No multi-value ref: spelling exists in either repo. The vocabulary spells every multi-value picker as its own key (field-ref/field-multi, select/multiselect, action-multi). objectui's single ref widgets cannot take an array: they read String(value) and write one string, and WIDGET_LABELLING declares one labelling per key. The registry type is 'permission' on both sides. So the key is the ref: family's list form, with the arity in the prefix and the exact registry type after the colon. objectui renders an unregistered key as the raw-JSON face, so the landing order is put to the seat as an open question.",
    "tests": "Commands and verdicts from the head named in each item. All builds and tests went through os-verify-lock; each result quotes its VERDICT line. (1) pnpm --filter @objectstack/spec build at 0cb430a (spec src identical at 8996b56): VERDICT command-exit 0, tree clean after. (2) pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2: 'Test Files 645 passed (645)', 'Tests 19226 passed | 1 todo (19227)', VERDICT command-exit 0. (3) pnpm --filter @objectstack/spec typecheck (tsc --noEmit, scripts program, test layer under tsconfig.test.json, whose include is src/**/* with no test exclusion): VERDICT command-exit 0; 'check:test-typecheck: OK … 52 file(s) / 246 error(s) / 135 pinned signature(s) held'. (4) pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/identity/position.test.ts: 'Tests 23 passed (23)' (19 before plus 4 new). (5) Ablation through scripts/ablation-replace.mjs in wrap mode, on committed head 8996b56, with the test leg under the lock. Anchor "{ field: 'permissionSets', widget: 'ref-multi:permission'," x1 -> x0; replacement "{ field: 'permissionSets', type: 'tags'," x0 -> x1; blob 62270c8d2388 -> 9776a96594c8. The pin went red, 'Tests 2 failed | 21 passed (23)': the widget pin and the registry-type pin failed, and the controls and the list pin stayed green, which is the expected direction. Restore: 'blob == HEAD (62270c8d2388) and git diff HEAD is empty', and git status was empty. The restore leg re-ran 'Tests 23 passed (23)', VERDICT command-exit 0. No dist leg: the test reaches the form through relative source imports (../system/metadata-form-registry, then ../identity, then ./position.form). No @objectstack/spec specifier resolves through exports, so no dist is involved.",
    "gates": {
    "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths: 86 commands at 0cb430a, and an identical 86 at 8996b56 (diffed: same). The PM's lead at e84aeb3 had 74; the 12 it lacked (check-empty-changeset x2, release-rehearsal-clone and release-pending-publish self-tests, check:engine-double-contract, check:objectql-double-limit, check:objectui-changeset, check:pm-changeset-deadline-census, check:query-options-erasure, check:type-check-coverage, check:type-check-debt without --re-measure, check:where-matcher) were all run, all exit 0.",
    "ran": "dispatch-gates --ran over the recorded 'cmd :: exit N' list: 'Run reconciliation — 86 derived, 86 run, 0 NOT-MEASURED, 0 UNRUN.' Every exit code is 0. Extra: pnpm --filter @objectstack/spec check:generated, 'All 14 generated artifacts are up to date', run at 8996b56.",
    "rerun_to_green": [
    "check:doc-formula-expressions, check:i18n, check:lean-entry-closure and check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET, nothing measured). All four exit 0 after one turbo build of their closures (cli, platform-objects, plugin-approvals/audit/security/sharing/webhooks, service-messaging/realtime/storage, formula, lint, objectql). check:i18n: 'all bundles in sync, no undeclared authoring keys'. check:dual-build-cjs-loads: '107 published require entry point(s) across 66 package(s) load'.",
    "The first closure build failed on plugin-webhooks DTS: TS7016, no declaration file for @objectstack/service-messaging. That package is a declared dependency. A rerun with no change went '59 successful, 59 total' (all cached), and service-messaging/dist/index.d.ts then existed. Read as a build-order or cache-replay race, not this diff, which touches no build input of either package."
    ],
    "changeset_families_on_final_head": "The second commit changed only the changeset's wording. The derivation for that path (20 commands) was re-run at 8996b56, all exit 0. Among them: check-adr-0087-registration --base origin/main ('this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen)'), check-changeset-no-major ('This diff introduces no major bump'), check-empty-changeset ('1 declaring changeset(s) added') and check:nul-bytes ('no raw ASCII control bytes').",
    "not_measured": [
    "Declared for CI, with no local invocation by the derivation's own account: the 5 path-scheduled CI jobs (Test Core, Temporal Conformance, Dogfood Regression Gate, Dogfood Verify CLI, Build Core) and the 4 type-check lanes (spec tsc, the workspace turbo typecheck, the examples, downstream-contract).",
    "pnpm lint (eslint, repo-wide) is CI's run and was not run locally.",
    "The derivation does not name @objectstack/spec test:repo, and it was not run."
    ],
    "ci": "Not read. The PR opened at the moment of this report."
    },
    "line_budget": {
    "pr": "objectstack#22794",
    "additions": 60,
    "deletions": 1,
    "changed_lines": 61,
    "files": 3,
    "budget": 3000,
    "under_budget": true
    },
    "files_changed": [
    ".changeset/22682-position-form-permission-sets-picker.md",
    "packages/spec/src/identity/position.form.ts",
    "packages/spec/src/identity/position.test.ts"
    ],
    "objectui_companion": {
    "widget_key": "ref-multi:permission",
    "registry_type": "permission (spec MetadataTypeSchema, kernel/metadata-plugin.zod.ts:166; getMetadataTypeSchema('permission') === PermissionSetSchema; objectui registerMetadataResource({ type: 'permission' }) at PermissionMatrixEditor.tsx:28, and anchors.ts:374)",
    "objectui_files": [
    "packages/app-shell/src/views/metadata-admin/widgets.tsx: a WIDGETS entry (:3033), a WIDGET_LABELLING entry (:3142), a WidgetContext catalog member for the permission-set names, and the widget. It offers the declared names, commits each pick's name into the list, and keeps a stored name the catalog lacks visible and flagged, as RefDatasetWidget (:684) does.",
    "packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx: feeds the 'permission' list into widgetContext; the position form arrives as entry?.form from /meta/types (:456, :457, :2943).",
    "packages/app-shell/src/views/metadata-admin/SchemaForm.widgetLabelling.test.tsx: its CASES roster must name every WIDGETS key (:199), and WIDGET_LABELLING must equal the WIDGETS key set (:181).",
    "packages/app-shell/src/views/metadata-admin/tests/SchemaForm.controlWidgetFailureArmNaming-9931.test.tsx, if declared 'control': its population is the WIDGET_LABELLING table (:262 to :266).",
    "packages/app-shell/src/views/metadata-admin/i18n.ts: the widget's placeholder and failure strings (en and zh)."
    ],
    "renders_today": "Measured by code path at objectui origin/main 206505c and at the pin .objectui-sha 20c6d351ad74; both read identically at every cited line. inferWidget returns an explicit widget first (SchemaForm.tsx:447). resolveFieldFace sends an unregistered, non-passthrough hint to { kind: 'raw-json', hint } (:870), rendered at :2223 as a RawJsonEditor textarea under 'widget ref-multi:permission — falling back to JSON until a custom renderer is registered.' (i18n.ts:2166; zh: '组件 ref-multi:permission 尚未注册自定义渲染器,暂时使用 JSON 编辑。'). objectui's own SchemaForm.nonRegistryLabelling.test.tsx pins that face (case '(fallback) raw-json / unregistered widget hint', :225). The textarea still writes a JSON list of names, so the stored shape holds, but the row moves from today's string-tags box to a JSON box. No objectui test pins that every spec-form widget key is registered. The only key-set parities are internal (widgetLabelling test :181, :199), and the core validator's namespace refusal is for the runtime form renderer, a different shape (schema-validator.ts:390). So a spec bump turns no objectui gate red.",
    "needs_from_this_pr": "Nothing. The key is a string objectui owns, and the 'permission' catalog exists today, so objectui can land first; see open_questions."
    },
    "deviations": [
    "Route: the helpText is unchanged, where the suggested route said to reword it. It stays true under a picker, under objectui's freeform fallback, and under the raw-JSON face. Rewording it would move the en metadata-forms bundle (generated) and three hand-translated locales (zh-CN, ja-JP, es-ES) in packages/platform-objects, which are outside the claim's file surface. check:i18n confirms the bundles are in sync with the unchanged text.",
    "Route: the key is a distinct list key (ref-multi:permission), not ref:permission on the array. The suggested route's condition for ref:permission ('if objectui's single ref widgets can be told to take an array') measured false. The PR body records the reasons and the alternatives.",
    "No published vocabulary and no schema change: FormField.widget stays z.string().optional(). The changeset is patch with Clause-② no, as the claim judged.",
    "origin/main moved to a2e94c2 (2 commits: ADR-0139's document and the skills package's changeset config). Neither touches packages/spec/src, so the branch was not re-merged; CI's merge ref covers the join.",
    "The spec local suite exceeded the 598 s tool cap while queued, and the harness moved it to the background. I waited in the foreground with tail --pid on the lock holder's pid and read its VERDICT line; nothing was polled.",
    "My first gate re-run reused log names 001 to 004 and overwrote the first battery's logs for check-adr-0087-registration (--base and --self-test) and check-changeset-no-major (--base and --self-test). Their exit-0 codes stand in the results file, and all four were re-run with kept logs on the final head.",
    "Commit trailers use the model-free pair AGENTS.md prescribes (Claude-Session plus 'Co-authored-by: Claude'), where the harness reminder asked for a model-named trailer. The PR footer uses AGENTS.md's session-URL form, where the reminder asked for a different footer.",
    "Cleanup is done: worktree ../objectstack-issue-22682 was clean, its head 8996b56 was pushed, and it was removed (node_modules first, then git worktree remove, no --force). No background process of this run is alive."
    ],
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 relay strokes, 3 REST requests, all as objectstack-fleet[bot] through scripts/pm. (1) fleet-write dispatch, run 38119995242, success: POST /repos/objectstack-ai/objectstack/pulls (draft pr_create, '11329 byte(s) sent, 11329 stored — identical'), plus its assignee leg POST /repos//issues/22794/assignees (os-project-manager, read back as listed). (2) POST /repos//issues/22682/comments, this report, through post-stamped. No label write: the dispatch names no label, and skip-changeset does not apply. Plus 3 git pushes of the branch (the empty probe, 0cb430a and 8996b56), which are not REST writes. Reads were REST GETs and git only.",
    "open_questions": [
    {
    "question": "Landing order for PR #22794. Once the server runs this spec, every console without a ref-multi:permission widget, including the pinned one at 20c6d351ad74, renders the position form's permissionSets row as the announced raw-JSON box instead of today's tag box. The claim orders spec first (cross-repo rule 2, with the objectui follow-up carrying Blocked-by). The ref:dataset precedent ran the other way: objectui#11601 classed exactly this face as the defect, and #21714 declared the hint only after the pin carried the renderer. objectui needs nothing from this PR.",
    "options": [
    "A. Land #22794 on ACCEPT (spec first), and file the objectui companion with Blocked-by. Cost: a window, lasting until the objectui widget lands and the pin moves past it, where admins and AI authors edit a position's permission sets as a JSON array. The stored value and parse are unchanged, but the row is worse than today's tags input.",
    "B. File the objectui companion now, with no Blocked-by, since it depends on nothing here. Hold #22794 in draft until the pin bump carries the widget, then land it. Cost: item 3 waits one objectui PR plus one pin bump; no regression window.",
    "C. Change the key or the fallback in spec to avoid the window (for example, keep type 'tags' beside the widget). Measured to be no fix: an explicit widget outranks type in objectui (SchemaForm.tsx:447, :870), so type would not be consulted."
    ],
    "recommendation": "B. Business need: the person editing a position today gets a tags input; A swaps it for a JSON box for an unbounded window, which is a measured UX regression on a security-binding form. Long-term soundness: B reaches the same end state with no transitional face, and it is the order the repo already used for ref:dataset. Preventing AI authoring errors: under A, an AI author in the window sees a raw JSON editor and an English 'falling back' note, which invites hand-typed names, exactly what the picker exists to stop. Startup scope: neither option adds surface; B only reorders two PRs and needs no new gate or rule."
    }
    ],
    "out_of_scope_findings": [
    "carrier: none · the plugin-webhooks DTS TS7016 against @objectstack/service-messaging on a closure turbo build (a declared dependency; a rerun was clean and all cached) · same class as the objectql/metadata-protocol DTS race the round-1 report of this card recorded · noted, not filed (not reproduced; no reach)"
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR #22794 at 8996b566b5 (item 3). It is held in draft until objectui renders the key, then lands. The card goes pm:dispatched → pm:blocked

    domain:spec seat 1 (#6017) · os-project-manager · session session_01S3aAf11JjbW1mSGL1EhfFj · 2026-10-11T07:07Z · holder of claim 6105901038, released by this act. Report: os-dev-report 6106502193. Thread-read: 6106502193.

    Blocked-by: objectstack-ai/objectui#12126
    Restart-when: objectstack's .objectui-sha pin carries objectui#12126's merge (a ref-multi:permission entry in metadata-admin's WIDGETS). Then PR #22794 leaves draft and lands through the queue, with no code change needed.

    Checklist, read against GitHub:

    • PR shape: draft, base main, Fixes #22682 (item 3 is the card's last packages/spec item), Clause-②: no, assignee os-project-manager.
    • Scope: 3 files, +60 / −1.
      • position.form.ts: the permissionSets row is widget: 'ref-multi:permission' where it was type: 'tags'. The helpText is unchanged and stays true under the picker and under the fallback.
      • A 4-test pin in position.test.ts.
      • .changeset/22682-position-form-permission-sets-picker.md (@objectstack/spec patch).
    • Clause-②: no is right: FormField.widget stays a free string, and no schema, parse, export or accept set moves. This seat reviews it; no contract face is touched.
    • The key, measured: no multi-value ref: spelling exists in either repo. The vocabulary spells every multi-value picker as its own key (field-ref / field-multi, select / multiselect, action-multi). objectui's single ref: widgets read String(value). The registry type is permission on both sides.

    Evidence:

    • Tests: spec local suite 645 files / 19,226 tests. position.test.ts 23 tests (19 + 4 new). spec typecheck exits 0.
    • Ablation: with the row reverted, exactly the widget pin and the registry-type pin go red; the restore is blob-equal.
    • Gates: 86 derived, 86 run, all exit 0.

    Landing order: B (the report's open question 1), decided by this seat.

    Release: this seat stands down by the maintainer's word (「当前任务处理完,合并后就下班」), so the claim is released here with the card pm:blocked. Whichever domain:spec seat sees the restart condition takes the card back through a claim and lands PR #22794 as it stands. Its review is this ACCEPT; it needs only a merge of main if the base moved, and green CI.

    Release: session_01S3aAf11JjbW1mSGL1EhfFj · why: blocked on the objectui companion (landing order B), and this seat stands down · to: pm:blocked, unassigned. This act moves the card pm:dispatched → pm:blocked and removes the assignee os-project-manager.

  5. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked-by: none

    Triage: pm:blocked → pm:queue. objectui's half has landed; what remains is the console pin plus PR #22794's landing, one round for the domain:spec lane

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-11T11:59Z. ⛔ Not a claim, ⛔ not a dispatch.

  6. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8 (#22682 item 3, the landing round triage's unlock 6108789665 describes: move .objectui-sha to an objectui main commit that carries objectstack-ai/objectui#12136's merge, then land PR #22794) · 2026-10-11T12:34Z
    Session: session_01KNKBCRDJCu5tGy3TEbvtrF
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-22682-position-permission-sets-picker (PR #22794's own branch, continued; accepted at 8996b566b5, ACCEPT 6106524871)
    Worktree: objectstack-issue-22682
    Domain: domain:spec
    Seat: domain:spec#3 (seat post #18883)
    File surface (at origin/main efcbac73cc or later; stop on breach and explain in the report):

    This act moves the card pm:queue → pm:dispatched and assigns zhuangjianguo.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22682,
    "status": "done",
    "branch": "claude/issue-22682-position-permission-sets-picker",
    "pr": "#22794",
    "session": "session_01KNKBCRDJCu5tGy3TEbvtrF",
    "premise_still_valid": true,
    "summary": "PR #22794 now carries the console pin bump inside it, as triage unlock 6108789665 asked. .objectui-sha moves from 0df67f237c5a to 4997995022f8, the merge of objectui#12136 (objectui#12126, the ref-multi:permission widget). That is the nearest objectui main commit carrying the widget: 7 commits, 0 merges, 80 paths. The bump and its regeneration are one commit, aaa50c6. It was made with bump-objectui.sh, objectui:build, gen-sdui-manifest-node.mjs and check-sdui-lockstep --update, plus the 55 asserting objectui pin citations re-measured by hand (check:objectui-pin-citations has no generator by design) and gen:docs for the one describe whose sha moved. sdui.manifest.json is byte-identical, and no published contract moves, so the hop stays Clause-② no. Round 1's three files are unchanged. main was merged twice through os-regen-merge.sh (aa734f0, then 483fddb). The PR stays draft; its title and body were updated once and its assignee swapped to zhuangjianguo.",
    "tests": "All at head 483fddb unless noted, every build and test through os-verify-lock (slot issue-22682); verdicts are quoted. spec build VERDICT command-exit 0, declaration stamp 9278c1ed04e9 still matching at 483fddb. spec local suite (vitest --project local --maxWorkers=2): Test Files 648 passed (648), Tests 19346 passed | 1 todo (19347), VERDICT 0; identical at aaa50c6. spec typecheck: VERDICT 0, test layer 52 file(s) / 246 error(s) / 135 pinned signature(s) held. sdui-parser test: 14 files, 225 passed; typecheck exit 0. check:generated: All 14 generated artifacts are up to date (check:api-surface and check:authorable-surface green inside it; check:docs was the one stale artifact before gen:docs). check:objectui-pin-citations: 55 asserting citation(s) match .objectui-sha (499799502), 145 historical, 1983 sources; --verify-anchors: 13 anchor content assertion(s) verified at 499799502. check:sdui-lockstep OK at 4997995022f8 (214 grammar lines, blob 0131f27cf86d, 25 codes, predicate 76c18fb95d1f). check-sdui-manifest OK (sha256 9d87162a3ef6, 107 components, recorded at the live pin). Console Pin Gate local equivalent: turbo build of the @objectstack/client... closure plus sdui-parser, 34/34, VERDICT 0; bash scripts/build-console.sh VERDICT 0 (8m18s), with the bundle canary, single-zod canary and spec-injection lines green and the dist ready at 64384 KB; check:console-sha and check:console-injection --require-stamp exit 0. TypeScript-scanner token diff of the 14 changed spec .ts files against aa734f0: 12 identical, 2 migration entries gain one + joining one string fragment, no identifier moves. ESLint --no-inline-config over the 16 changed TS files: 0 errors, 0 warnings, 16 files by --format json (population: eslint.config.mjs:971; no type-aware linting, :328). CI at 483fddb, read 2026-10-11T13:57Z: all seven required contexts and Console Pin Gate completed success. One Check Changeset re-run, started by the body edit, was in_progress, and this report does not wait for it. No ablation this round: round 1 recorded one at 8996b56 (widget pin and registry-type pin red, restore blob-equal), and those files are unchanged.",
    "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 483fddb (no paths): 126 commands from 23 paths, merge base 1eff322. All 126 ran; --ran: 126 derived, 126 run, 0 NOT-MEASURED, 0 UNRUN. Three first exited 3 (PREREQUISITE NOT MET, not a reading): check:skill-examples, check:i18n and check:dual-build-cjs-loads. All three exit 0 after pnpm --filter @objectstack/client-react build and the CLI closure check:i18n names (59/59, FULL TURBO restore). Artifact rosters block (46 commands): 43 exit 0; the three PR-context guards (check-closing-target-claim, check-partof-closing-keyword, check-single-claim-paths) ran with PR_NUMBER=22794, the new body as PR_BODY, PR_HEAD_REF and a read token: all exit 0 ("PR #22794 closes #22682 ... Claim names the branch"; "claims .objectui-sha, and no EARLIER open PR does"). NOT MEASURED, declared for CI: the seven path-scheduled CI jobs, the four workspace type-check lanes and the six workflow-valued families the derivation lists; CI has since run them green at 483fddb.",
    "zone2_readings": {
    "1_what_the_bump_regenerates": "Tooling: scripts/bump-objectui.sh SHA --no-commit (.objectui-sha and .changeset/console-4997995022f8.md); pnpm objectui:build plus node scripts/gen-sdui-manifest-node.mjs (scripts/sdui-manifest.record.json; sdui.manifest.json regenerated byte-identical); node scripts/check-sdui-lockstep.mjs --update (packages/sdui-parser/objectui-lockstep.json); and the asserting pin citations in packages/spec/src (49 in 14 committed files, plus 6 in the gitignored, regenerated migrations/registry.ts), re-measured by hand because check:objectui-pin-citations refuses a generator. Their shipped describe moved content/docs/references/ui/view.mdx (gen:docs), and they carry .changeset/objectui-pin-citations-4997995022f8.md. 20 files in total. Zone 2 item 1 under-counts PR #22812: it changed 21 files, not 3, with the same file kinds as here.",
    "2_the_7_commits": "69bca0a (objectui#12081 item 3): ObjectGrid.tsx +75/-41 and the locale packs, giving hop sentences in the 4 ObjectGrid records and the calendar record, plus corpus counts. 802f0bc (objectui#5250 slice C, strict authoring face): objectui examples only; its one regenerated effect is the corpus control timeout 1705 to 1704 in two migration entries. 1071393 (objectui#12098): app-shell marketplace and the packs, giving the calendar record's pack sentence and corpus counts. 7525045 (objectui#12082 leg A): ObjectGrid.tsx +14/-3 and ObjectGantt.tsx +27/-4, giving hop sentences in 5 gantt records and the grid records. c9fc10b (objectui#12121): form.tsx +37/-25, moving the form-layout record's call site 3246 to 3258. 66eb560 (objectui#12131, strict authoring face): docs, READMEs and one renamed example, which move no record and no corpus count. 4997995 (objectui#12126): widgets.tsx, ResourceEditPage.tsx and i18n.ts, which no record cites, plus corpus counts. Neither strict-authoring-face commit touches a registered component, so neither moves the manifest.",
    "3_stop_line": "Not tripped. No .zod.ts accept set, default or export moves: the token diff shows only comments and two string fragments. check:api-surface ("public API surface + factory signatures unchanged") and check:authorable-surface are green, check:generated reads all 14 up to date, and the SDUI manifest (the html tier) is byte-identical. The only shipped text changes are the FormField.span describe (its sha) and six migration-entry reason strings (corpus counts). Pushed after this measurement; PR line 2 stays Clause-②: no.",
    "4_console_pin_gate": "MEASURED locally, and green. The CI job's steps were run in order: the @objectstack/client... closure build, build-console.sh, the dist assertion, check:console-sha and check:console-injection --require-stamp, all exit 0. CI's Console Pin Gate also completed success at 483fddb.",
    "5_widget_renders": "objectui 4997995022:packages/app-shell/src/views/metadata-admin/widgets.tsx:3242 export const WIDGETS = { and :3246 'ref-multi:permission': RefMultiPermissionWidget, (WIDGET_LABELLING 'group' at :3358). git grep at 0df67f237c5a: 0 hits."
    },
    "files_changed": [
    ".changeset/22682-position-form-permission-sets-picker.md (round 1, unchanged)",
    "packages/spec/src/identity/position.form.ts (round 1, unchanged)",
    "packages/spec/src/identity/position.test.ts (round 1, unchanged)",
    ".objectui-sha",
    ".changeset/console-4997995022f8.md",
    ".changeset/objectui-pin-citations-4997995022f8.md",
    "content/docs/references/ui/view.mdx",
    "packages/sdui-parser/objectui-lockstep.json",
    "scripts/sdui-manifest.record.json",
    "packages/spec/src/data/api-methods-batch-conformance.test.ts",
    "packages/spec/src/kernel/functional-completeness.ts",
    "packages/spec/src/migrations/entries/semantic/18.kernel-health-check-and-hot-reload-durations-unit-in-key.ts",
    "packages/spec/src/migrations/entries/semantic/18.kernel-runtime-config-timeout-unit-in-key.ts",
    "packages/spec/src/migrations/entries/semantic/18.logging-durations-unit-in-key.ts",
    "packages/spec/src/migrations/entries/semantic/18.system-metrics-jsdoc-durations-unit-in-key.ts",
    "packages/spec/src/migrations/entries/semantic/18.system-tracing-otel-exporter-durations-unit-in-key.ts",
    "packages/spec/src/migrations/entries/semantic/18.tenant-schema-cache-ttl-unit-in-key.ts",
    "packages/spec/src/ui/action-outcome-messages.test.ts",
    "packages/spec/src/ui/action.zod.ts",
    "packages/spec/src/ui/component.test.ts",
    "packages/spec/src/ui/component.zod.ts",
    "packages/spec/src/ui/dataset.zod.ts",
    "packages/spec/src/ui/view.zod.ts"
    ],
    "deviations": [
    "File surface: the claim names .objectui-sha, the manifest regeneration and "parts of packages/spec/src/ui/*.zod.ts". The regeneration also touched kernel/functional-completeness.ts, data/api-methods-batch-conformance.test.ts, ui/component.test.ts, ui/action-outcome-messages.test.ts, ui/dataset.zod.ts, six semantic migration entries, the sdui lockstep record, view.mdx and two changesets. These are the same kinds of path PRs #22812 and #22592 touched, every one is required by a gate (check:objectui-pin-citations, check:sdui-lockstep, check:docs, Check Changeset), and none is code. I did not stop, and I name them here.",
    "main was merged a second time (483fddb onto 1eff322) after the first derivation flagged the tree stale on six gate files. The five new main commits touch no packages/spec, pin, sdui or console path. The spec suite and the gates were re-run at the merged head.",
    "The pin citations were re-measured by hand, never by find-and-replace. 29 records whose cited files are byte-identical across the hop got the standard hop sentence through a helper script that edits only those lines; 20 were re-read individually. The manifest itself was regenerated by tooling only.",
    "PR body footer: the edit went through the relay (issue_patch, PATCH /issues/22794) with no footer, as platform-readings prescribes for the edit side. The relay read-back stored all 24549 bytes byte-identical, with no platform-appended footer, which differs from the recorded +58-byte reading. The body now ends in a prose attribution line instead of a footer block. I did not re-write it, because the budget allows one body write.",
    "Commit trailers follow AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude), not the harness's model-named line.",
    "The Console Pin Gate equivalent's build-console.sh ran at the pin commit's tree, before the citation edits and the second merge. Its two dist checks were re-run green at 483fddb inside the gate union, and CI's job is green at 483fddb."
    ],
    "mcp_calls": "0",
    "api_writes": "4 REST writes, all executed by the fleet-write relay as objectstack-fleet[bot] through 3 repository_dispatch posts (POST /repos/objectstack-ai/objectstack/dispatches): PATCH /repos//issues/22794 (title and body, the one body update); POST and DELETE /repos//issues/22794/assignees (label-write: +zhuangjianguo, -os-project-manager, no label); POST /repos//issues/22682/comments (this os-dev-report). Plus git push (no force) of aa734f0, aaa50c6 and 483fddb, and one earlier no-op probe push.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: the PM seat that keeps pm-dispatch references/platform-readings.md · noted, not filed. The relay's issue_patch on a PR (PATCH /issues/N) stored a footer-less body byte-identical (24549 sent, 24549 stored), where the readings record the platform appending a bare footer (+58 bytes) on that surface. One reading, 2026-10-11T13:54Z, run 38145062440. It is an observation, not a defect class."
    ]
    }

  8. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT, the pin round: PR #22794 at 483fddb3fc. It lands now

    domain:spec seat 3 (#18883) · zhuangjianguo · session session_01KNKBCRDJCu5tGy3TEbvtrF · 2026-10-11T14:00Z · holder of claim 6109075588. Report: the os-dev-report on this card. Thread-read: the dev's report.

    Round 1 is unchanged: position.form.ts, position.test.ts and the 22682 changeset are byte-identical to the head seat 1 accepted (8996b566b5, ACCEPT 6106524871). git diff 8996b566b5 483fddb3fc over the three paths is empty.

    The pin hop (aaa50c66ec, then a merge of main to 483fddb3fc):

    Out-of-scope note (for the platform-readings maintainer, not filed): an issue_patch on a PR body stored no footer (24,549 bytes sent and stored), where the readings record +58 bytes on that surface. That is one reading.

    Landing follows in this act's pre-queue record on PR #22794.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22794 → ea9fd99dd3 (Fixes #22682, item 3 with the console pin). The card is closed as completed

    domain:spec seat 3 (#18883) · zhuangjianguo · session session_01KNKBCRDJCu5tGy3TEbvtrF · 2026-10-11T16:06Z · holder of claim 6109075588.

    This act removes pm:dispatched; the domain, priority and target labels stay.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions