Skip to content

studio: machine names and raw ids shown where a label exists — Explain access principal, permission-set list, nav editor items, Changes panel #11862

Description

@objectstack-fleet

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 (and onBehalfOf.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

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

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Oct 8, 2026
  2. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    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 asked

    Triage 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 objectui main 4e7dd56ed1.

    • Why p3: the values are right; the author reads ids where a label exists. Filed on the maintainer's word (「所有地方以标签为主,机器名只作为次要信息」).
    • Direction:
      • show the label (or a user's name and email) as the primary text, with the machine name or id as secondary text
      • fall back to the name only when no label exists
    • Related: studio(data): the Objects rail lists a draft-only object by its bare API name, not the label its draft declares #11843 (the Objects rail, the same rule for draft-only objects) is graded separately.
    • Clause-②: no. Patch changeset in objectui.
  3. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8
    Session: session_01DrKzdPdyLLBW3qpZ4vtk7z
    Account: huangyiirene
    Branch: claude/issue-11862-labels-first
    Worktree: objectui-issue-11862
    Domain: domain:ui
    Seat: domain:ui#1
    File surface (line numbers on d4c39de), under packages/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:
      • the Changes list (about :1669);
      • NavTree's item text (from :1856);
      • StudioNavItemInspector's title;
      • the Access pillar's permission-set list (from :6117).
    • At most one new module-private name-display helper or component in studio-design/ (label plus optional secondary name).
    • New engine.studio.* rows of metadata-admin/i18n.ts (en and zh), only if a secondary-text label needs one.
    • The tests beside these, and .changeset/11862-*.md.

    ⛔ Not on it:

    • Seat 3's objectui#11823 step 2 (claim 6052347323): InterfacesPillar's New dashboard / New report entries and their create handler, and CreateItemDialog.tsx.
    • Seat 3's objectui#11786: useDraftAutoSave, the pillars' doSaves, doPublish and their refusal strips.
    • How nav item ids are minted (AppNavCanvas.tsx addItem) and what is saved. A label is never written where the author typed none.
    • objectui#11843 (the Objects rail's draft-only label): its own card, serial behind this seat's objectui#11799.
    • packages/i18n/** and packages/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/objectui over 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 filer
    Thread-read: 6051871527
    Serial constraints cleared: none blocking.

    • The nav inspector region objectui#11884 (objectui#11847) held has landed (4373484).

    • area:studio in flight:

      • seat 3's objectui#11823 step 2 (InterfacesPillar create flows; it fences NavTree and StudioNavItemInspector off its own surface) and objectui#11786;
      • seat 2's objectui#11803;
      • this seat's objectui#11871 (ObjectFormDesigner.tsx) and objectui#11799 (PR objectui#11892: three load effects, in InterfacesPillar and AutomationsPillar).

      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-tree is owed at review. Read 2026-10-08T05:06Z.

    • This seat: dispatch is parallel, batch 3 working devs, on the maintainer's word in this session's chat (「改为并行派发,batch 3」, 「继续派发」), paced by the shared hourly write budget.

      • objectui#11799's dev has finished (PR objectui#11892), which freed this slot.

    Why Clause-②: no: display text only. No export, prop, @object-ui/types member, accepted input or saved value changes.

  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat ruling on the dev's two open questions (report 6053465616) · claim amendment

    domain:ui seat 1 · session_01DrKzdPdyLLBW3qpZ4vtk7z · read on main 09821b1, 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

    • Measured: the only list of draft-only items is GET /meta/_drafts, and ListDraftsResponseSchema declares no label. SysMetadataRepository.listDrafts already 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.
    • Why A: one producer field serves every consumer: both rails, the Changes list and Home's preview bar, with no extra query. Each consumer stops deciding on its own which label wins. B would be a per-surface read for a label, which the dispatch ruled out, and a consumer-side workaround for a platform gap, which this seat does not take. C ignores the maintainer's word for exactly the rows an author is building.
    • objectui waits. No per-surface read is added in the meantime. The draft-only rows stay pinned as the "no label in hand" controls in objectui#11906.

    Question 2: the two sites outside the claim. Split by who holds the file

    Claim amendment

    The file surface of claim 6052722965 gains:

    • 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. ⛔ Not addItem (about :329) and not any saved value: ids are minted as before, and no label is ever written.
    • The tests beside it.

    The rest of the claim stands, Clause-②: no included.

    What happens on merge

    objectui#11906 stays Refs #11862. When it lands, this card goes to pm:blocked, with a Blocked-by: objectstack-ai/objectstack#22200 line naming the remainder:

    • draft-only rows in the rails and the Changes list read the header's label after the pin bump that carries it;
    • the Changes list also waits on objectui#11807 (seat 2) for its file.

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  7. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT as a partial landing — PR objectui#11906 (head 386bb41)

    domain:ui seat 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 reports 6053465616 (round 1) and 6053848415 (round 2), read 2026-10-08T06:29Z.

    • Shape: draft → main. The first line is Refs #11862 (…), naming the remainder, and Clause-②: no starts the next line.
    • Scope: 15 files, +753/−41, inside claim 6052722965 as amended by the ruling 6053526025. Everything is under packages/app-shell/src/views/.
      • AccessExplainPanel.tsx: the Principal line (and onBehalfOf) shows the person's name and email, with the id as secondary text. The person comes from the picked row, or else from one sys_user find through the data adapter for ids not yet known. An unanswered id still reads as the id.
      • StudioDesignSurface.tsx: one module-private StudioNameLabel, used by the permission-set rail and NavTree (label primary, name secondary). An entry with no target reads the existing untitled wording "Item N", never nav_item_N, and so does the inspector's Label placeholder.
      • AppNavCanvas.tsx (round 2): navLabel gives an entry with no label and no target the positional engine.appNav.item wording. addItem, the ids it mints and every saved value are unchanged.
      • Four new pin files. Five existing pins move from nav_item_N to the positional wording on this ruling, and two guard suites scope their set_a queries to the pillar's panel. Plus one changeset.
    • Clause-② re-read: no +export line. No prop, type member, accepted input or i18n key changes (engine.appNav.item already exists in EN and ZH). no holds.
    • Governed surface: 0 paths governed, 794 changed lines. That is an ordinary queue landing.
    • The rulings held:
    • Deviation, accepted: the principal line's one sys_user find 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.
    • Tests:
      • Local union on 386bb41 (with main 09821b1 merged in): 240 files and 2,221 tests green across studio-design/, AccessExplainPanel*, metadata-admin/previews/, the view-cache guard and the console's StudioRoute*. The type-check, eslint on the 14 touched files (no new warnings against their base versions) and the derived check:* set are green.

      • Reverse checks:

        • A1–A4 (round 1, one per site) were red exactly as predicted.
        • A5 (round 2, navLabel's no-target line) gave 8 failed and 40 passed, as predicted.

        Each restore was proven by blob hash.

    • Overlap: an in-memory git merge-tree against main 3683591 is clean.
    • CI at 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.
    • On merge: the card goes to pm:blocked, with Blocked-by: objectstack-ai/objectstack#22200, as the ruling 6053526025 set. 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.
    • Noted, not filed: the nav-item inspector's object picker writes label (name) even when the two are equal. That is polish, in the PR's Acceptance notes.

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed (partial): PR objectui#11906 → main 0feabe8 · card blocked on the producer

    Release: session_01DrKzdPdyLLBW3qpZ4vtk7z (domain:ui seat 1, account huangyiirene) releases claim 6052722965 (amended by 6053526025). Reason: a partial landing, Refs #11862, as accepted in 6053877463. Next: pm:blocked with 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.

      • CI on head 386bb41 before 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:

      • 0feabe8 is one squash commit on parent 72f5c60. It changes 15 files, +753/−41, the same as the PR.
      • 14 files are blob-identical to the reviewed head 386bb41.
      • StudioDesignSurface.tsx differs only because main moved under it. Its -U0 patch-id matches (d0925e3e…), and so does the whole diff's (03ea7560…), against the PR's base 09821b1.
    • What landed: labels first, with the machine name or id as secondary text, wherever the label is already in hand:

      • the Explain access principal line (a person's name and email);
      • the permission-set rail;
      • the nav tree and the nav editor's edit-mode cards (an entry with no target reads "Item N", never nav_item_N);
      • the nav inspector's Label placeholder.

      It is display only: nothing saved changes.

    • The remainder, for the next claim:

    • Noted, not filed: the nav-item inspector's object picker writes label (name) even when the two are equal.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked audit: objectstack-ai/objectstack#22200 closed, so the card moves pm:blocked → pm:on-hold. The remainder's hold is now only the install face

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-09T12:04Z. ⛔ Not a claim, ⛔ not a dispatch.

    Thread-read: 6054565160

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:on-holdpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions