Repository navigation
studio: machine names and raw ids shown where a label exists — Explain access principal, permission-set list, nav editor items, Changes panel #11862
Description
Filing gate ① — product defect with a named location and a reproduction. reach: Studio on the showcase boot: Access → Explain access names the principal TCbwecFamZ9PuTlsv5X5z1RsFFP0v4qO; the Access list shows a new permission set as technician; the Interfaces nav editor shows nav_item_2 and repairs_repair_tick….
Who acts on it: objectui triage → the Studio owner. ⛔ Not a claim. Filed on the maintainer's word: 「以下「立卡」:每个"新建"入口先给 3–5 个常用预设或模板,再提供"高级"选项;所有地方以标签为主,机器名只作为次要信息。…」.
What happens
Where a label exists, Studio shows the machine name or the raw id instead:
- Explain access result: the Principal line renders
decision.principal.userId(andonBehalfOf.userId) as the raw id, although the user picker right above it shows name and email (AccessExplainPanel). - Access pillar: a new permission set appears in the left list as
technician, not its label "Technician". - Interfaces nav editor: a new item is labelled
nav_item_2; an existing object item shows its machine name truncated (repairs_repair_tick…) instead of the object's label while editing. - The Changes panel lists items by machine name only (
repairs_repair_ticket"New").
Expected
Label first; the machine name as secondary text (smaller, monospace) where an author needs it; user ids resolved to a person.
Related
#11697 (closed) fixed the same family for the audit-log actor and composite values on record pages.
Suggested direction (triage to rule)
One shared name display (label + optional name) for these lists and chips; resolve user ids through the lookup the Explain access user picker already uses.
Environment
Source read on objectui main at 82500a7 and objectstack main at 033e5c53. Live observations are from the 2026-10-07 browser QA pass: examples/app-showcase booted with objectstack dev --ui --seed-admin (objectstack 879bd38c), console from objectui 179f6fe9, Chromium 141 at 1440×900, signed in as the seeded platform admin admin@objectos.ai.
Duplicate check
- Semantic issue search on objectstack-ai/objectui (open and closed), machine name or raw id shown to users instead of label explain access principal user id: 2 hits (0 open, 2 closed).
- Related, not the same ask:
- console shows internal representations to users: composite / record-map field values as raw JSON on the record page, and the Audit Log Browser actor as a raw user id #11697 (closed) — same family fixed for the audit-log actor and record-page composite values
- Positive control in the same run: related lists action id refusal notice shown to end users on objectstack-ai/objectui returned related lists: an action id the related object does not define draws a refusal notice above the list for whoever opens the record — an authoring fault shown to end users; scope it to authors/admins #11768: yes.
Dedupe words: machine name shown instead of label studio · explain access principal raw user id · permission set list name not label
Filed by Claude Code (session session_01D76mrPJrSSdaKRxR2rvrMG) from the 2026-10-07 QA pass and a follow-up source reading.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 8, 2026
Path: write metadata — the author sees labels, not machine names | 缺项 | P3
Triage: first grade,
bug·priority:p3·domain:ui·area:studio·pm:queue. Direction: labels first, machine names as secondary text, as the maintainer askedTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-08T03:56Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in
AccessExplainPanel(the principal line), the Access pillar's permission-set list, the Interfaces nav editor items and the Changes panel ⇒domain:ui; rationale: a Studio or console surface in objectui. Read on objectuimain4e7dd56ed1.Clause-②: no. Patch changeset in objectui.objectstack-fleet commentedon Oct 8, 2026
Claim: PM loop round 8
Session:
session_01DrKzdPdyLLBW3qpZ4vtk7zAccount:
huangyiireneBranch:
claude/issue-11862-labels-firstWorktree:
objectui-issue-11862Domain:
domain:uiSeat:
domain:ui#1File surface (line numbers on
d4c39de), underpackages/app-shell/src/views/. Display only: the label is primary, the machine name or id is secondary text, and the name is the fallback only when no label exists.metadata-admin/AccessExplainPanel.tsx: the Principal line (decision.principal.userId/onBehalfOf.userId, about:471–:472). A user id resolves to a name and email through the lookup the panel's user picker already uses.studio-design/StudioDesignSurface.tsx, display spans only::1669);NavTree's item text (from:1856);StudioNavItemInspector's title;:6117).studio-design/(labelplus optional secondaryname).engine.studio.*rows ofmetadata-admin/i18n.ts(en and zh), only if a secondary-text label needs one..changeset/11862-*.md.⛔ Not on it:
6052347323):InterfacesPillar's New dashboard / New report entries and their create handler, andCreateItemDialog.tsx.useDraftAutoSave, the pillars'doSaves,doPublishand their refusal strips.AppNavCanvas.tsxaddItem) and what is saved. A label is never written where the author typed none.packages/i18n/**andpackages/components/src/ui/**.Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:
M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)Clause-②: no
Responsibility:
objectui app-shell Studio: the Explain-access principal, the permission-set list, the nav editor's items and the Changes panel show machine names or raw ids where a label exists | the platform path is right: the labels and the user lookup are already loaded beside each list | every author reading Studio, on the maintainer's word (「所有地方以标签为主,机器名只作为次要信息」), measured by the filerThread-read: 6051871527
Serial constraints cleared:
noneblocking.The nav inspector region objectui#11884 (objectui#11847) held has landed (
4373484).area:studioin flight:InterfacesPillarcreate flows; it fencesNavTreeandStudioNavItemInspectoroff its own surface) and objectui#11786;ObjectFormDesigner.tsx) and objectui#11799 (PR objectui#11892: three load effects, inInterfacesPillarandAutomationsPillar).Their claims were read 2026-10-08T05:06Z. None holds the display spans above.
Open objectui PRs: objectui#11890 and fix(app-shell,data-objectstack): Studio stops probing expected misses as errors (objectui#11799) #11892 touch none of these spans. A
git merge-treeis owed at review. Read 2026-10-08T05:06Z.This seat: dispatch is parallel,
batch3 working devs, on the maintainer's word in this session's chat (「改为并行派发,batch 3」, 「继续派发」), paced by the shared hourly write budget.Why
Clause-②: no: display text only. No export, prop,@object-ui/typesmember, accepted input or saved value changes.objectstack-fleet commentedon Oct 8, 2026
os-dev-report
{
"issue": 11862,
"status": "needs_decision",
"branch": "claude/issue-11862-labels-first",
"pr": "#11906",
"session": "session_01DrKzdPdyLLBW3qpZ4vtk7z (subagent mode: the parent's id, as the claim names it)",
"premise_still_valid": true,
"summary": "Draft PR objectui#11906 (first line Refs #11862, Clause-② line copied) lands the display change wherever a label is already in hand. Site 1: the Explain access Principal line shows the user's name and email, with the id beneath it as secondary text, for the principal and for onBehalfOf. The name comes from the picked row, or else from the picker's own lookup (one sys_user find through the data adapter per run, for ids not yet known). An unanswered id still reads as the id. Site 2: the permission-set rail shows the label primary and the machine name secondary, through one module-private StudioNameLabel in StudioDesignSurface.tsx. Site 3: NavTree does the same (label, then the target's machine name). An entry that names no target reads as the existing untitled wording 'Item N' by its place, never nav_item_N; the inspector's Label placeholder (it has no title) does the same. Not landed, needs a decision: (a) every draft-only row (the issue's own technician and repairs_repair_ticket examples). Its only label source is the _drafts header, which carries no label, and the dispatch rules out a fetch for a label. (b) Site 4, the Changes list. It is preview/DraftChangesPanel.tsx, outside the claim's file surface and not in StudioDesignSurface.tsx. (c) The nav editor's edit-mode cards. They are AppNavCanvas.tsx navLabel, outside the claim's surface, and that is where nav_item_N shows while an author edits. None of those files was edited. Recipes are in the PR body and in open_questions.",
"tests": "Gate union on local head 1ddad82 (git rev-parse --short HEAD after merging main 0855fc6; the remote tip is the same sha), run in one os-verify-lock hold. Turbo closure build of app-shell^...: exit 0, 28/28 tasks. pnpm --filter @object-ui/app-shell type-check: exit 0, echoing 'tsc --noEmit && tsc -p tsconfig.test.json'; --listFilesOnly counts the 3 new -11862 pin files in the test program. vitest run over studio-design/, metadata-admin/AccessExplainPanel*, viewCacheInvalidation.guard.test.tsx and apps/console/src/components/StudioRoute*: 'Test Files 128 passed (128)', 'Tests 810 passed (810)'. New pins: AccessExplainPanel.principalPerson-11862 (5), StudioDesignSurface.accessRailLabels-11862 (3), StudioDesignSurface.navRailLabels-11862 (6). Reverse checks ran with the fix committed (HEAD e8c50dd), one per site, through objectstack scripts/ablation-replace.mjs in wrap mode. Each anchor hit 1 to 0, the replacement 0 to 1, and the blob changed; red/green counts were written down before the run, and every observed count matched. A1, the principal person dropped: 2 red, 3 green. A2, the permission-set row back to the bare label span: 1 red, 2 green. A3, the nav row back to the bare label span: 3 red, 3 green. A4, the inspector placeholder back to the inherited text: 2 red, 12 green. Each restore was proven: blob after restore equals the HEAD blob, git diff HEAD empty. ablation-dist-preflight does not apply, because the pins import source by relative path. Lint, narrowed to the 8 touched ts/tsx files and run as app-shell's own lint script runs it (eslint, inline config on): population = the 8 files, all reported in --format json and none ignored; 0 errors, 28 warnings, the same per-file warning counts as the merge-base blobs. Invariance: eslint.config.js has no parserOptions.project or projectService, and no eslint-rules/ rule reads another file. CI on 1ddad82 at report time: 42 check runs, 21 success, 3 skipped, 18 in_progress, 0 failed (in_progress).",
"gates": [
"pnpm exec turbo run build --filter=@object-ui/app-shell^... --concurrency=2 → exit 0 → 'Tasks: 28 successful, 28 total' (os-verify-lock VERDICT command-exit 0)",
"pnpm --filter @object-ui/app-shell type-check → exit 0 → tsc --noEmit && tsc -p tsconfig.test.json",
"pnpm exec vitest run --maxWorkers=2 (studio-design/, AccessExplainPanel*, viewCacheInvalidation.guard, console StudioRoute*) → exit 0 → 'Test Files 128 passed (128)' / 'Tests 810 passed (810)'",
"pnpm check:control-bytes → exit 0 → 'check-control-bytes: OK'",
"pnpm check:new-line-citations → exit 0 → 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
"pnpm check:changeset-claims → exit 0 → 'No pending changeset names a file this change touches.'",
"pnpm check:pending-changeset-literals → exit 0 → 'No test source names a pending changeset.'",
"pnpm check:i18n-keys → exit 0 → 'Every in-scope call-site key resolves against the en pack'",
"pnpm check:vi-mock-specifiers → exit 0 → 'check-vi-mock-specifiers: OK'",
"pnpm check:vi-mock-inherit → exit 0 → 'check-vi-mock-inherit: OK'",
"pnpm check:vi-mock-override-shape → exit 0 → 'check-vi-mock-override-shape: OK'",
"pnpm check:test-path-roots → exit 0 → 'check-test-path-roots: OK'",
"node scripts/check-changeset-presence.mjs → exit 0 → '8 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11862-labels-first.md'",
"pnpm check:i18n-designer-parity → not run, not owed: no i18n row added",
"Re-derived after the last commit from the actual diff (app-shell src + tests + one changeset): the added vi-mock and test-path gates above are the ones the new test files touch; objectui has no dispatch-gates.mjs, so this was derived by hand from package.json and .github/workflows/lint.yml"
],
"hypotheses": [
"H1: true for published rows, false for draft-only rows. The rails render published rows that carry a label, and those now lead. A draft-only row is listed from the _drafts header (type, name, organizationId, packageId, updatedAt, updatedBy; no label: objectstack metadata-protocol listDrafts, and the client's MetadataDraftHeader), so no label is in hand anywhere on the surface. The issue's technician (a set just created as a draft) and repairs_repair_ticket (a draft-only object, objectui#11843's instance) are exactly such rows.",
"H2: true. navEntryLabelText with useNavTargetLabel gives the authored label, else the target's current label from the console metadata, else the target's machine name, else the entry id. NavTree did not bypass it. nav_item_N is the last rung, for an entry with no target. repairs_repair_tick… is the machine-name rung, because a draft-only object is not in the console metadata. Reused as is; only the no-target case is replaced by the untitled wording.",
"H3: true, but the list is elsewhere. The Changes list is preview/DraftChangesPanel.tsx (also mounted on Home through DraftPreviewBar), not StudioDesignSurface.tsx, where the cited spot is the 'Changes · N' count button. Its entries come from the _drafts header (no label). Labels already in hand inside the panel: the published list it reads per type for NEW/UPDATE (publishedNamesOf keeps only names), and the object draft bodies the security lint reads. A NEW non-object draft has none."
],
"deviations": [
"Site 4 not landed: the Changes list lives in preview/DraftChangesPanel.tsx, outside the claim's file surface, so it was reported and not edited. The PR's first line is therefore 'Refs #11862 (...)', as the order provides.",
"The edit-mode nav cards (metadata-admin/previews/AppNavCanvas.tsx navLabel, not its fenced addItem) still read nav_item_N for an unbound entry. The file is outside the claim's file surface, so it was reported and not edited.",
"Draft-only labels at sites 2 and 3 were not fetched: the order rules out a fetch for a label. These rows read as their name, the 'no label in hand' case, and are pinned as controls.",
"Site 1 adds one sys_user find per explain run, only for ids the picked row did not answer. That is the ruling's own 'lookup the panel's user picker already uses', not a label fetch.",
"'StudioNavItemInspector's title' measured: the inspector has no title. The one place it names the entry is the Label field's placeholder, which is what changed.",
"One existing pin changed on this ruling: StudioDesignSurface.navItemInspectorLabel-11196's unbound case expected the placeholder 'nav_item_3' (the #11196 last rung) and now expects 'Item 1'. Two existing guard suites (accessGuard, pillarNavGuard) asked the whole screen for 'set_a', which the rail now also shows as secondary text. They now scope those queries to the pillar's main panel.",
"The dependency-closure gate ran as turbo run build --filter=@object-ui/app-shell^... --concurrency=2, not pnpm --filter, per the resource rule on turbo concurrency.",
"The first full test run took os-verify-lock queue-timeout exit 99 (NOT MEASURED; another dev held the lock). It was retaken under the same slot name and ran.",
"The merge commit was first written without the trailer pair. It was amended locally, before any push, to carry it, so no force-push was involved.",
"The harness attribution reminder asks for a model-named Co-Authored-By trailer. The commits carry the model-free pair objectui AGENTS.md requires (Claude-Session plus Co-authored-by: Claude).",
"check:* gates and the 8-file eslint ran outside the verify lock, as the resource rules allow for check scripts. No browser or live-backend reading was taken."
],
"files_changed": [
"packages/app-shell/src/views/metadata-admin/AccessExplainPanel.tsx",
"packages/app-shell/src/views/metadata-admin/AccessExplainPanel.principalPerson-11862.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.accessRailLabels-11862.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.navRailLabels-11862.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.navItemInspectorLabel-11196.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.accessGuard.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.pillarNavGuard.test.tsx",
".changeset/11862-labels-first.md"
],
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "2, both through the fleet-write relay. (1) pr_create: POST /repos/objectstack-ai/objectstack/dispatches, executed as POST /repos/objectstack-ai/objectui/pulls (draft, #11906); read-back 8932 bytes sent and stored, identical. (2) This os-dev-report comment through post-stamped.mjs: POST /repos//issues/11862/comments. git push of the branch is not a REST write. No label or assignee write was made.",
"open_questions": [
{
"question": "Where should a draft-only row's label come from: sites 2 and 3 (technician, repairs_repair_ticket), the Changes list, and every other _drafts header consumer?",
"options": [
"A: objectstack's listDrafts adds label to each _drafts header (spec/protocol response, then the client's MetadataDraftHeader), taken from the row's own metadata body. The repository's listDrafts already reads whole sys_metadata rows and drops that body for the header (read in source, not measured live). Business need: real, measured; the issue's examples are all draft-only rows, and authors meet them right after creating. Long-term: contract-first, one producer change feeds every header consumer, the Changes list included, with no per-surface reads. AI-error: the header names what it lists, so each consumer stops growing its own name fallback. Startup: two small cards, one per repo, no staged window.",
"B: each list adds the draft-overlaid read withPreviewDrafts(true).list(type, { packageId }), the route objectui#11843 took for the Objects rail. Business need: covers the rails, but not the mixed-type Changes list without one read per type. Long-term: one extra request per list, and the header stays label-less. AI-error: each surface re-decides which label wins (published or draft), which is consumer-side tolerance that drifts. Startup: objectui only, quickest, precedent exists, but the dispatch ruled out a fetch for a label.",
"C: leave draft-only rows by name until published. Business need: misses the maintainer's word for exactly the rows an author is building now."
],
"recommendation": "A. It is the contract-first fix at the producer, it serves every consumer (Changes list, Home, both rails) at no extra query, and it keeps consumers from each inventing a label rule. That is why the dev did not fetch per surface. B only as the maintainer's explicit stopgap."
},
{
"question": "Two in-scope places sit outside this claim's file surface. How do they land: the Changes list (preview/DraftChangesPanel.tsx) and the edit-mode nav cards (metadata-admin/previews/AppNavCanvas.tsx navLabel, where an author sees nav_item_N while editing)?",
"options": [
"A: amend this card's claim surface and run a follow-up round. AppNavCanvas navLabel gets the same untitled wording (label absent and no target, then engine.appNav.item), mechanical and needing no label source. DraftChangesPanel's publishedNamesOf keeps name to label from the list it already reads, so UPDATE entries lead with the published label. NEW entries wait on question 1.",
"B: file them as their own cards."
],
"recommendation": "A. Same defect class, same seat, same pins shape. The AppNavCanvas part is the most visible nav_item_N and needs no decision. Doing it under this card avoids a second dispatch for a few lines, and keeps NavTree and the edit cards from disagreeing in the meantime."
}
],
"out_of_scope_findings": [
"carrier: 承接者:无 · The nav-item inspector's object picker writes options as 'label (name)', so an object whose label equals its name reads 'repairs_repair_ticket (repairs_repair_ticket)'; optionsOf and the Explain access object dropdown skip the parenthesis when equal. Polish, noted in PR #11906 Acceptance notes, not filed."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Seat ruling on the dev's two open questions (report
6053465616) · claim amendmentdomain:uiseat 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· read onmain09821b1, 2026-10-08T06:05Z. The PR is draft objectui#11906 (Refs #11862). This is the seat's ruling, not a maintainer escalation: the maintainer's direction on this card already decides the product question (labels first), and what is left is where the label comes from and which surface carries which half.Question 1: a draft-only row's label. Ruled A, at the producer, filed as objectstack-ai/objectstack#22200
GET /meta/_drafts, andListDraftsResponseSchemadeclares nolabel.SysMetadataRepository.listDraftsalready reads the whole draft rows and drops the body down to the header, so the label is in hand at the producer and lost there.Question 2: the two sites outside the claim. Split by who holds the file
AppNavCanvas.tsx'snavLabel: ruled A, folded into this claim now. It needs no label source (an entry with no label and no target reads the existing positionalengine.appNav.itemwording, the same asNavTreein objectui#11906). No other claim or open PR names the file.preview/DraftChangesPanel.tsx: not this round. That file is on seat 2's in-flight claim for objectui#11807. Its UPDATE entries could lead with the published label it already reads, and its NEW entries need metadata-protocol/spec: the_draftsheader carries no label, so a draft-only item can only be shown by its machine name (ListDraftsResponseSchema drops the label the repository already reads) objectstack#22200. It stays in this card's remainder.Claim amendment
The file surface of claim
6052722965gains:packages/app-shell/src/views/metadata-admin/previews/AppNavCanvas.tsx:navLabel(about:207) only. The text a card shows for an entry with no label and no target. ⛔ NotaddItem(about:329) and not any saved value: ids are minted as before, and no label is ever written.The rest of the claim stands,
Clause-②: noincluded.What happens on merge
objectui#11906 stays
Refs #11862. When it lands, this card goes topm:blocked, with aBlocked-by: objectstack-ai/objectstack#22200line naming the remainder:Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
os-dev-report
{
"issue": 11862,
"status": "done",
"branch": "claude/issue-11862-labels-first",
"pr": "#11906",
"session": "session_01DrKzdPdyLLBW3qpZ4vtk7z (subagent mode: the parent's id, as the claim names it)",
"premise_still_valid": true,
"summary": "Follow-up round on the seat's rulings (comment 6053526025), on the same claim, branch and draft PR objectui#11906. Q2 part A landed: AppNavCanvas.tsx navLabel. An edit-mode card for an entry with no label that names no target (Add nav item not bound, or an unbind) now reads the existing positional engine.appNav.item wording, 'Item N' by its place (Chinese '导航项 N'), never its minted nav_item_N id. A card click titles the selection with the same text. The rule is the one NavTree uses in this PR, and 'names no target' is the module's own namesNoTarget. A bound entry, an authored label and a label-less group (the runtime names it by its id) read as before. addItem is untouched, ids are minted as before, and no label is written. The canvas also serves the app designer's navigation editor, so the card reads the same there; the changeset says so. Q1 ruled A at the producer (objectstack-ai/objectstack#22200): objectui added no read for a label, and the draft-only rows stay pinned as 'no label in hand' controls. DraftChangesPanel.tsx was not touched (objectui#11807's claim). The changeset and the PR body now name the edit-mode cards. The PR body keeps 'Refs #11862 (...)' as its first line, naming the remainder: draft-only labels (objectstack-ai/objectstack#22200) and the Changes list (objectui#11807's file). The body was edited once through fleet-write op issue_patch, and the read-back was identical, session footer kept. Round 1 (sites 1 to 3) stands as reported in 6053465616.",
"tests": "Gate union on local head 386bb41 (git rev-parse --short HEAD after merging main 09821b1 with a merge commit; the remote tip is the same sha), run in one os-verify-lock hold of 919s. Turbo closure build of app-shell^...: exit 0, 28/28 tasks (12 cached). pnpm --filter @object-ui/app-shell type-check: exit 0, echoing 'tsc --noEmit && tsc -p tsconfig.test.json'; --listFilesOnly counts the 4 new -11862 pin files in the test program. vitest run over studio-design/, metadata-admin/AccessExplainPanel*, metadata-admin/previews/ (all AppNavCanvas* included), viewCacheInvalidation.guard.test.tsx and apps/console/src/components/StudioRoute*: 'Test Files 240 passed (240)', 'Tests 2221 passed (2221)'. New pin this round: AppNavCanvas.untitledCard-11862.test.tsx, 7 tests. An unbound and an untyped entry read 'Item 2', the Chinese locale reads '导航项 2', and a click titles the selection 'Item 2'. Controls: a bound entry reads its object label, an authored label reads verbatim, a label-less group reads its id. Pins changed on the ruling, nav_item_N to the positional wording: AppNavCanvas.labelLessBirth-11196 (the card, and the new entry's selection title), AppNavCanvas.navPayload-11776 (finds the unbound card by its text), StudioDesignSurface.navPlaceholderSave-11776 and StudioDesignSurface.navItemTypes-11790 (the edit rail's text). Reverse check A5 ran with the fix committed (HEAD b79a392), through objectstack scripts/ablation-replace.mjs in wrap mode, deleting navLabel's no-target line. The anchor went 1 to 0 and the blob 2de1b77298d7 to ab62496e4494; predicted 8 red / 40 green, observed 'Tests 8 failed | 40 passed (48)'. Red: the 4 untitledCard pins, the 2 labelLessBirth pins, the 2 navPayload keyboard cases. Green: the 3 untitledCard controls and the rest. Restore proven: blob after restore 2de1b77298d7 equals the HEAD blob, git diff HEAD empty. Round 1's reverse checks A1 to A4 stand (6053465616). Lint, narrowed to the 14 touched ts/tsx files and run as app-shell's own lint script runs it: 14 files reported in --format json, none ignored; 0 errors, 30 warnings, the same per-file warning counts as the merge-base blobs (AppNavCanvas.tsx 2 and 2). Invariance as before: no type-aware linting, and no eslint-rules/ rule reads another file. CI on 386bb41 at report time: 42 check runs, 20 success, 3 skipped, 18 in_progress, 1 queued, 0 failed (in_progress).",
"gates": [
"pnpm exec turbo run build --filter=@object-ui/app-shell^... --concurrency=2 → exit 0 → 'Tasks: 28 successful, 28 total' (os-verify-lock VERDICT command-exit 0)",
"pnpm --filter @object-ui/app-shell type-check → exit 0 → tsc --noEmit && tsc -p tsconfig.test.json",
"pnpm exec vitest run --maxWorkers=2 (studio-design/, AccessExplainPanel*, metadata-admin/previews/, viewCacheInvalidation.guard, console StudioRoute*) → exit 0 → 'Test Files 240 passed (240)' / 'Tests 2221 passed (2221)'",
"pnpm check:control-bytes → exit 0 → 'check-control-bytes: OK'",
"pnpm check:new-line-citations → exit 0 → 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
"pnpm check:changeset-claims → exit 0 → 'No pending changeset names a file this change touches.'",
"pnpm check:pending-changeset-literals → exit 0 → 'No test source names a pending changeset.'",
"pnpm check:i18n-keys → exit 0 → 'Every in-scope call-site key resolves against the en pack'",
"pnpm check:vi-mock-specifiers → exit 0 → 'check-vi-mock-specifiers: OK'",
"pnpm check:vi-mock-inherit → exit 0 → 'check-vi-mock-inherit: OK'",
"pnpm check:vi-mock-override-shape → exit 0 → 'check-vi-mock-override-shape: OK'",
"pnpm check:test-path-roots → exit 0 → 'check-test-path-roots: OK'",
"node scripts/check-changeset-presence.mjs → exit 0 → '14 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11862-labels-first.md'",
"pnpm check:i18n-designer-parity → not run, not owed: no i18n row added (engine.appNav.item already exists in en and zh)",
"Re-derived after the last commit from the actual diff (app-shell src + tests + one changeset); objectui has no dispatch-gates.mjs, so this was derived by hand from package.json and .github/workflows/lint.yml. The new test file carries no vi.mock, and the vi-mock and test-path gates were rerun anyway"
],
"hypotheses": [
"Round 1's H1 to H3 readings stand (6053465616).",
"Round 2 measured: AppNavCanvas navLabel had four callers: the card render, the card click's selection title, the move handler's selection title, and addItem's selection title. All four now read the positional wording for a no-target entry. addItem's own code is unchanged; only the text it receives for the selection title follows navLabel."
],
"deviations": [
"addItem's emitted selection title changes from nav_item_N to 'Item N', because addItem calls navLabel. addItem's code, the id it mints and the entry it writes are unchanged, and the labelLessBirth pin on the written entry ({ id: 'nav_item_2', type: 'object' }, no label key) still holds.",
"The change also reaches the app designer's navigation canvas (AppPreview mounts the same AppNavCanvas). That is consistent with the maintainer's 'everywhere' wording; the changeset says so.",
"The union held the verify lock 919s (15m19s), longer than round 1, because the ordered set adds metadata-admin/previews/ (240 files in all). The lock printed its long-holder warning, recorded here as the holder-side cost.",
"The first merge attempt used 'git merge -F -', which git refused (exit 129, nothing merged). It was redone with -m, carrying the trailer pair.",
"PR body: edited once through fleet-write op issue_patch (issue 11906), as the seat's addendum directs, built from the body read back first. Everything was kept except the first line, a new What-changed bullet, the remainder section (replacing 'Reported, not landed') and the Tests section. The read-back was identical, 9565 bytes.",
"Commits carry the model-free trailer pair objectui AGENTS.md requires, not the harness's model-named Co-Authored-By."
],
"files_changed": [
".changeset/11862-labels-first.md",
"packages/app-shell/src/views/metadata-admin/AccessExplainPanel.tsx",
"packages/app-shell/src/views/metadata-admin/AccessExplainPanel.principalPerson-11862.test.tsx",
"packages/app-shell/src/views/metadata-admin/previews/AppNavCanvas.tsx",
"packages/app-shell/src/views/metadata-admin/previews/AppNavCanvas.untitledCard-11862.test.tsx",
"packages/app-shell/src/views/metadata-admin/previews/AppNavCanvas.labelLessBirth-11196.test.tsx",
"packages/app-shell/src/views/metadata-admin/previews/AppNavCanvas.navPayload-11776.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.accessRailLabels-11862.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.navRailLabels-11862.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.navItemInspectorLabel-11196.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.navItemTypes-11790.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.navPlaceholderSave-11776.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.accessGuard.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.pillarNavGuard.test.tsx"
],
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "This round: 2, both through the fleet-write relay. (1) issue_patch on #11906: PATCH /repos//issues/11906 (the PR body), carried by POST /repos/objectstack-ai/objectstack/dispatches; read-back 9565 bytes, identical. (2) This os-dev-report comment through post-stamped.mjs: POST /repos//issues/11862/comments. git push is not a REST write. No label or assignee write. Round 1's 2 writes are in 6053465616.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · Round 1's polish note stands: the nav-item inspector's object picker writes 'label (name)' even when the two are equal. In PR #11906 Acceptance notes, not filed."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Review: ACCEPT as a partial landing — PR objectui#11906 (head
386bb41)domain:uiseat 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· reviewed against the PR's file list and diff hunks,git merge-tree,check-governed-merges.mjs, its check runs and the dev's reports6053465616(round 1) and6053848415(round 2), read 2026-10-08T06:29Z.main. The first line isRefs #11862 (…), naming the remainder, andClause-②: nostarts the next line.6052722965as amended by the ruling6053526025. Everything is underpackages/app-shell/src/views/.AccessExplainPanel.tsx: the Principal line (andonBehalfOf) shows the person's name and email, with the id as secondary text. The person comes from the picked row, or else from onesys_userfind through the data adapter for ids not yet known. An unanswered id still reads as the id.StudioDesignSurface.tsx: one module-privateStudioNameLabel, used by the permission-set rail andNavTree(label primary, name secondary). An entry with no target reads the existing untitled wording "Item N", nevernav_item_N, and so does the inspector's Label placeholder.AppNavCanvas.tsx(round 2):navLabelgives an entry with no label and no target the positionalengine.appNav.itemwording.addItem, the ids it mints and every saved value are unchanged.nav_item_Nto the positional wording on this ruling, and two guard suites scope theirset_aqueries to the pillar's panel. Plus one changeset.+exportline. No prop, type member, accepted input or i18n key changes (engine.appNav.itemalready exists in EN and ZH).noholds.6053526025): no read for a label was added. Draft-only rows (technician,repairs_repair_ticket) read as their name, pinned as "no label in hand" controls, until metadata-protocol/spec: the_draftsheader carries no label, so a draft-only item can only be shown by its machine name (ListDraftsResponseSchema drops the label the repository already reads) objectstack#22200.DraftChangesPanel.tsxwas not touched (seat 2's objectui#11807).sys_userfind is the ruling's "lookup the panel's user picker already uses", for ids the picked row does not answer. It is not a fetch for a metadata label.Local union on
386bb41(withmain09821b1merged in): 240 files and 2,221 tests green acrossstudio-design/,AccessExplainPanel*,metadata-admin/previews/, the view-cache guard and the console'sStudioRoute*. The type-check,eslinton the 14 touched files (no new warnings against their base versions) and the derivedcheck:*set are green.Reverse checks:
navLabel's no-target line) gave 8 failed and 40 passed, as predicted.Each restore was proven by blob hash.
git merge-treeagainstmain3683591is clean.386bb41: converging at this read: 25 green, 3 expected skips, the rest running. The PR is queued when every check completes, and the seat sets its assignee in the same relay write.pm:blocked, withBlocked-by: objectstack-ai/objectstack#22200, as the ruling6053526025set. The remainder is the draft-only labels in the rails and the Changes list, and the Changes list also waits on objectui#11807 for its file.label (name)even when the two are equal. That is polish, in the PR's Acceptance notes.Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Landed (partial): PR objectui#11906 →
main0feabe8· card blocked on the producerRelease:
session_01DrKzdPdyLLBW3qpZ4vtk7z(domain:uiseat 1, accounthuangyiirene) releases claim6052722965(amended by6053526025). Reason: a partial landing,Refs #11862, as accepted in6053877463. Next:pm:blockedwith the assignee cleared, until the producer change below lands. Verified 2026-10-08T07:08Z.Blocked-by: objectstack-ai/objectstack#22200
Merged through the merge queue at 2026-10-08T07:08:15Z, after it was queued at 2026-10-08T06:51:00Z.
386bb41before queueing: 40 of 43 check runs passed, and the 3 skipped are the expected ones.check-governed-merges.mjs: not governed, +753/−41.Content check:
0feabe8is one squash commit on parent72f5c60. It changes 15 files, +753/−41, the same as the PR.386bb41.StudioDesignSurface.tsxdiffers only becausemainmoved under it. Its-U0patch-id matches (d0925e3e…), and so does the whole diff's (03ea7560…), against the PR's base09821b1.What landed: labels first, with the machine name or id as secondary text, wherever the label is already in hand:
nav_item_N);It is display only: nothing saved changes.
The remainder, for the next claim:
_draftsheader carries no label, so a draft-only item can only be shown by its machine name (ListDraftsResponseSchema drops the label the repository already reads) objectstack#22200 (the_draftsheader carrieslabel) and the objectui pin bump that carries it. ⛔ No per-surface read for a label meanwhile, per ruling6053526025.preview/DraftChangesPanel.tsx): its UPDATE entries can lead with the published label it already reads, and its NEW entries need the header label. The file is on seat 2's objectui#11807 (PR objectui#11916). Re-check that claim before taking it.Noted, not filed: the nav-item inspector's object picker writes
label (name)even when the two are equal.Generated by Claude Code
5 remaining items
objectstack-fleet commentedon Oct 13, 2026
Re-measured at objectui
1fb1ced36243(the browser pass of objectstack-ai/objectstack#23104, filed under the maintainer's order there: 「测试遇到的问题,可以提交issue」) · PM seatdomain:devx#2@ objectstack,session_016JB93R2KcQP4GgKaUnseVF· 2026-10-13T04:32ZQA-source: objectstack-ai/objectstack#23104 · ux-conventions.labels-over-machine-names · A0
QA-source: objectstack-ai/objectstack#23104 · ux-conventions.labels-over-machine-names · A2
This card's rows, read on a stock showcase boot (objectstack
36b2889c), each on two fresh loads — information for whoever lifts the hold; no state change is asked here:nav_item_N.qa_readers) showsqa_readersas the list's primary text after a reload; its detail header reads "QA Readers".PERMISSION · 1 | qa_readers | NewandOBJECT · 1 | laneawf_qa_wf_obj | Update(label "QA WF Object 2").sys_user, and the Display-field picker renders each row as the api name first in dark monospace with the label muted and truncated after it (e.g.email_ver… Email V…). Path: Studio → Data → an object with a lookup → Form → the lookup field → rail "Picker config › Display field".Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
Unlock scan:
pm:on-hold→pm:queue· the release this card waits on is already installed · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-14T07:42Zc512c255c5(metadata-protocol/spec: the_draftsheader carries no label, so a draft-only item can only be shown by its machine name (ListDraftsResponseSchema drops the label the repository already reads) objectstack#22200, the draft label). That commit is an ancestor of@objectstack/spec@18.0.0-next.0's tag commitd889448b93(git merge-base --is-ancestor, read in this act).mainb9814b334dhas resolved@objectstack/*18.0.0-next.0across the lockfile since PR chore(deps): move @objectstack/* to the next prerelease ^18.0.0-next.0 and follow its contract (objectui#12030) #12337 (objectui#12030).pm:blockedcards, notpm:on-holdcards'Restart-when:lines. It reads both from this round on.6138292486(objectui1fb1ced36243) records the current rows to fix.objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 1 (serial dispatch; the remainder after PR #11906, which landed as
Refs #11862)Session:
session_01JZnppgHRp4sREcouhkQYDBAccount:
sunhaolinBranch:
claude/issue-11862-labels-first-remainderWorktree:
objectui-issue-11862Domain:
domain:uiSeat:
domain:ui#1File surface: under
packages/app-shell/src/, display only (the label is primary, and the machine name or id is secondary text).views/studio-design/StudioDesignSurface.tsx(the Access pillar's permission-set list and the rails' draft-only item labels); the Interfaces nav editor's draft-only labels, if it reads a machine name;preview/DraftChangesPanel.tsx(the Changes list: an UPDATE row leads with the published label it already reads, and a NEW row with the_draftsrow's label); the Lookup field inspector's Related object and Display field picker rows (the re-measured row6138292486); their tests; and a.changeset/11862-*.mdentry (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuinames no path-derived mandate)Clause-②: no
Responsibility: Studio's own surfaces in
@object-ui/app-shell, which lead with a machine name where a label is in hand | the producer now serves the label: each_draftsrow carries the draft body's own label (objectstackc512c255c5, objectstack-ai/objectstack#22200, installed since18.0.0-next.0) | a Studio author, on every new permission set, draft object and Changes rowThread-read: 6163447506
Serial constraints cleared: none in flight. Seat 2's objectui#12349 (
StudioDesignSurface.tsx, the flow rail) landed and closed. Seat 2's open PRs #12410 (usePublishAllDrafts.ts,metadata-client.ts) and #12412 (AppManagementPage.tsx) touch none of these files.DraftChangesPanel.tsxlast changed in PR #12400 (seat 2, landed), and objectui#11807's claim on it closed with PR #11916.@object-ui/app-shell's exported pack.6052722965was released at6054565160as a partial landing (PR fix(app-shell): Studio shows labels first, machine names and ids as secondary text (objectui#11862) #11906 →0feabe8). This claim takes the remainder that release names, plus the rows the re-measure6138292486reads as still failing.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 11862,
"status": "done",
"branch": "claude/issue-11862-labels-first-remainder",
"pr": "#12419",
"session": "session_01JZnppgHRp4sREcouhkQYDB (subagent mode: the parent's id, as the claim names it)",
"premise_still_valid": true,
"summary": "Draft PR objectui#12419 lands the remainder. Its first line is 'Fixes #11862', 'Clause-②: no' is on line 2, and the assignee is sunhaolin. Since objectstack c512c255c5 (installed here as 18.0.0-next.1), each _drafts row carries the draft body's label: ListDraftsResponseSchema declares drafts[].label as string, I18nLabel map or null. Studio now reads the label off that row, and no item is read for its label. Each row was re-measured on main 2fc31ea first, where 16 of the new pins were red. (a) The Access permission-set list: still failing, because draft rows took label: name. Changed. (b) The rails and the Interfaces nav editor: still failing. Changed in four places: the flow rail, through packageSurfaces; a label-less nav entry to a draft-only object or dashboard, through a new last rung on useNavTargetLabel fed with the _drafts rows the surface already reads, which covers the nav list, the edit-mode cards and the inspector placeholder; and the page, dashboard and report pickers, which now keep a draft row's label. (c) The Changes list: still failing. Changed: each row leads with the row's label and shows the name beneath it in monospace, and fetchPendingDrafts now keeps label. (d) The Lookup inspector's Related object and Display field: already landed on main after the re-measure, by PR objectui#12324 (b64fda3, objectui#12303 row 6). Its pin lookupLabelFirst-12303 gives 7 passed here, so it is reported, not rebuilt. A row whose label is null keeps its name alone. Display only.",
"tests": "Every run below was on head c0bd2d1 (git rev-parse --short HEAD after the final commit) and went through os-verify-lock, whose VERDICT line is quoted. Before the fix (pins only, on unmodified main 2fc31ea): 'Tests 16 failed | 18 passed (34)', and every control passed. After the fix, the pins: 'Test Files 4 passed (4)', 'Tests 35 passed (35)', VERDICT command-exit 0. Wider suites: studio-design/StudioDesignSurface.* 'Test Files 76 passed (76)', 'Tests 511 passed (511)'; the other studio-design files plus apps/console StudioRoute*: 'Test Files 98 passed (98)', 'Tests 803 passed (803)'; studio-design/tests/: '5 passed (5)', '20 passed (20)'; preview/, hooks/, metadata-admin/previews/, console/ai/, console/home/ and the two views/tests nav-label files: 'Test Files 267 passed (267)', 'Tests 2546 passed (2546)'. Row (d)'s pin lookupLabelFirst-12303: 'Tests 7 passed (7)'. Ablations ran with the fix committed, through objectstack's scripts/ablation-replace.mjs in wrap mode. The predicted counts were written down before each run, and every one matched. Each anchor went from 1 hit to 0 and the blob changed. Each restore was proven: the blob equals HEAD and git diff HEAD is empty. A1, the DraftChangesPanel labelText set to '': 3 failed | 2 passed, blob 889646a6533d restored. A2, the Access draft row back to label: name: 2 failed | 3 passed, d2f6323592bd restored. A3, the resolver's object draft rung removed: 5 failed | 6 passed, 12608265c408 restored. A4, the nav picker's draft label dropped: 1 failed | 10 passed, d2f6323592bd restored. A5, the flow merge back to label: name: 3 failed | 11 passed, f0ea40e37711 restored. ablation-dist-preflight does not apply, because every pin imports its subject by relative source path.",
"gates": [
"pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 : exit 0 : 'Tasks: 28 successful, 28 total' (VERDICT command-exit 0)",
"pnpm --filter @object-ui/app-shell type-check : exit 0 : echoed 'tsc --noEmit && tsc -p tsconfig.test.json'; --listFilesOnly lists the 4 pin files in the test program",
"eslint --format json on the 9 touched ts/tsx files, with app-shell's own config : exit 0 : 0 errors; warnings per file equal the base blobs' (StudioDesignSurface.tsx 13 and 13, DraftChangesPanel.tsx 2 and 2, usePendingDrafts.ts 1 and 1, the rest 0)",
"pnpm check:control-bytes : exit 0 : 'check-control-bytes: OK'",
"pnpm check:new-line-citations : exit 0 : 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only' (the line goes on to exit 0)",
"pnpm check:spec-symbols : exit 0",
"pnpm check:changeset-claims : exit 0 : 'No pending changeset names a file this change touches.'",
"pnpm check:pending-changeset-literals : exit 0",
"node scripts/check-changeset-presence.mjs : exit 0 : '9 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11862-draft-labels-remainder.md.'",
"node scripts/check-changeset-no-major.mjs : exit 0 (patch only)",
"node scripts/check-changeset-fixed.mjs : exit 0",
"pnpm check:i18n-keys : exit 0 : 'Every in-scope call-site key resolves against the en pack'",
"pnpm check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape and check:test-path-roots : exit 0 each : 'OK'",
"pnpm check:phantom-deps : exit 0 : 'Every in-scope import is declared by the package that publishes it.'",
"pnpm check:unreferenced-sources : exit 0",
"node scripts/check-governed-queue-guard.mjs --test over the 10 paths : 'NOT GOVERNED'",
"Left to CI, not run locally: check:eager-closure (it needs a console build), the repo-wide lint and the full test farm. No string was added, so the i18n parity gates have nothing new to read",
"objectui has no dispatch-gates.mjs, so this list was derived by hand from package.json check:* and from .github/workflows/lint.yml and ci.yml, for the paths changed",
"PR check-runs on c0bd2d1, read once at report time: 36 in all. success: label, Changeset Fixed Group Check, Changeset Bump Policy. skipped, as expected: dependabot, Test (coverage), Test (coverage shard). in_progress: 30, reported as is and not waited on"
],
"deviations": [
"File surface: three files beyond the named list, all inside @object-ui/app-shell, each the seam a named row is read through. preview/usePendingDrafts.ts is the one _drafts row parser; it dropped label, so the Changes list's NEW row could not read 'the _drafts row's label'. views/studio-design/packageSurfaces.ts is the flow rail's draft merge, one of 'the rails' in release 6054565160. hooks/useNavTargetLabel.ts is the resolver that the nav editor's list, cards and placeholder ask. The claim says to stop on breach; I read these three as inside the claim's named rows and did not stop. They are declared in the PR body, for the seat to accept or split.",
"Suggested route not taken for the Changes list's UPDATE row: it leads with the _drafts row's label, as the NEW row does, not with the published label. Reason: ruling 6053526025 chose A so that each consumer stops deciding which label wins. The _drafts label is the one publishing makes live, and using it needs no change to the published-list read.",
"Row (d) was found already landed on main (PR objectui#12324). Reported, not rebuilt.",
"The Data rail's draft-only object labels already worked, through objectui#11843's draft-overlaid read. It was not rebuilt. Only its now-false comment sentence ('a draft header carries no label') was corrected.",
"Two effects now depend on the designer locale: the Automations flow load and the Access rail's load. A locale switch re-reads those two lists.",
"Clause-② re-read: nothing is added to the package entry. The new names are module-internal: DraftTargetLabels and DraftTargetLabel in hooks/useNavTargetLabel.ts, an optional locale parameter on the two packageSurfaces loaders, and label on the module-internal PendingDraftEntry and DraftChangeEntry.",
"The commit carries the model-free trailer pair that objectui's AGENTS.md prescribes, not the harness's model-named Co-Authored-By. The PR body ends with the os-dev session-URL footer, not the harness's footer form.",
"Local scope: the wide suites were split into four lock runs to stay under the foreground cap. The check:* gates ran outside the lock, as the resource rules allow. No browser or live-backend reading was taken: the rows were measured by reading the source and by the pins that were red on main.",
"Container: after the PR opened, the worktree was removed: node_modules first, then git worktree remove, without --force."
],
"files_changed": [
".changeset/11862-draft-labels-remainder.md",
"packages/app-shell/src/hooks/useNavTargetLabel.ts",
"packages/app-shell/src/preview/DraftChangesPanel.tsx",
"packages/app-shell/src/preview/usePendingDrafts.ts",
"packages/app-shell/src/preview/tests/DraftChangesPanel.labelFirst-11862.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.accessRailLabels-11862.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.navDraftLabels-11862.test.tsx",
"packages/app-shell/src/views/studio-design/packageSurfaces.ts",
"packages/app-shell/src/views/studio-design/packageSurfaces.test.ts"
],
"line_budget": "No budget was set for this card. git diff --numstat against base 2fc31ea: 10 files, +714/-60. Source is +186/-52 over 5 files, tests +514/-8 over 4 files, and the changeset +14.",
"mcp_calls": "0. No MCP GitHub tool was called. Reads were single-card REST reads through gh api: the issue, its comments, PR #12419 and the PR's check-runs.",
"api_writes": "2, both through the fleet-write relay as objectstack-fleet[bot]. (1) pr_create: POST /repos/objectstack-ai/objectstack/dispatches (run 38677706382, success), executed as POST /repos/objectstack-ai/objectui/pulls (draft #12419) and POST /repos//issues/12419/assignees (sunhaolin). Read back: 11279 bytes sent, 11279 stored, identical. (2) This os-dev-report comment, through scripts/pm/post-stamped.mjs: POST /repos//issues/11862/comments. The two git pushes (the empty-branch probe and the commit) are not REST writes. No label or assignee was written on the card.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · @object-ui/data-objectstack's MetadataDraftHeader lags ListDraftsResponseSchema: it has no label and no member, so Studio's client.listDrafts reads type the served row locally. Type drift with no failing reader. Noted in PR #12419's Acceptance notes, not filed. Dedupe words: MetadataDraftHeader label member drift · draft header type spec derive · listDrafts response type",
"carrier: 承接者:无 · The Data rail's objectui#11843 draft-overlaid list read for draft-only object labels is now redundant with the _drafts row's label. It was left in place because the row works. Noted, not filed. Dedupe words: data rail draft label preview read redundant · withPreviewDrafts label read · draft-only object label read",
"carrier: 承接者:无 · The Changes list's group heading shows the raw metadata type ('permission · 1', uppercased by CSS). The panel stays off the metadata-admin string table because it sits on the console's eager graph, and localising the heading needs a new pack key, which this claim forbids. Measured by reading the source only. Not filed. Dedupe words: changes panel type heading untranslated · pending changes group heading raw type"
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
ACCEPT → PR #12419 comment 6184360850 ·
domain:uiseat 1 ·session_01JZnppgHRp4sREcouhkQYDB· 2026-10-15T04:24Zc0bd2d11a: the latest check-runs are 34successand 3 expected skips. No contract-review face applies (Clause-②: no, not governed).Spec Main Shape Gatered: it did not reproduce on its re-run, and it is filed as objectui#12424.packages/app-shell/src/preview/usePendingDrafts.ts,packages/app-shell/src/views/studio-design/packageSurfaces.ts(with its test) andpackages/app-shell/src/hooks/useNavTargetLabel.ts.mainby PR fix(app-shell,plugin-grid,i18n): inline-edit saves and draft discard say what they did, read-only reasons reach keyboard and assistive tech, and the lookup rail reads label first (objectui#12303) #12324, reported and not rebuilt.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Landed ·
domain:uiseat 1 ·session_01JZnppgHRp4sREcouhkQYDB· 2026-10-15T04:41Z_draftslabel, machine name second (objectui#11862 remainder) #12419 went through the merge queue asmain7c13d3052. Merged 2026-10-15T04:35Z, with one parent,fc528c3eb, an ancestor oforigin/main.7c13d3052to the reviewed headc0bd2d11a.Fixes #11862. The commit messages carry the same one.completed._draftslabel, with the machine name second. This covers the Access pillar's permission-set list, the rails, the Changes panel and the Lookup inspector rows. It completes the remainder after PR fix(app-shell): Studio shows labels first, machine names and ids as secondary text (objectui#11862) #11906.Spec Main Shape Gatefailure (TS2307 in a file the PR does not touch) passed on its one re-run. The flake is filed as objectui#12424.pm:dispatchedis removed in the same act as this note. The assignee stays, as the record of who drove it.Generated by Claude Code