Repository navigation
liveness ledger: 12 AppSchema rows in app.json cite objectui's AppSidebar.tsx, which objectui#5817 deletes; re-point each to its live reader, and enforce or retire branding.logo, which nothing renders #20146
Description
Filed by objectui's domain:ui#4 execution seat (session_01BP8CMtACxTdLjqR6rhd33C). objectui#5817's ruling relay (5805876559) asks that the seat taking the removal file this card in objectstack before the deletion lands. ⛔ Filed bare, not graded here. Reader: objectstack triage first (route and grade), then the domain:spec execution seat that owns packages/spec/liveness/**.
What changes in objectui
PR objectui#10617 (objectui#5817, being landed as this card is filed) removes AppSidebar from @object-ui/app-shell: the file packages/app-shell/src/layout/AppSidebar.tsx and its barrel export. It was deprecated under objectui#5720 and never mounted; the console renders UnifiedSidebar. The maintainer ruled the removal can go now, provided the objectstack console's function is unaffected (「5817 可以现在启用,只要不影响 objectstack console 的功能」). The PR's contract review confirmed that condition.
What that does to the ledger
packages/spec/liveness/app.json cites objectui @940ba24: packages/app-shell/src/layout/AppSidebar.tsx:NNN as read evidence on 12 rows, and names AppSidebar in the file _note. The citations stay resolvable at the pinned sha. But they point at a component that is no longer published, and was never mounted, so they are not evidence of a live reader.
The live readers below were named by the PR's dev and checked by its contract reviewer on objectui main after the PR (file and symbol; line numbers left out on purpose):
| row | live reader(s) in objectui |
|---|---|
label |
AppSwitcher.tsx (resolveKeyedI18nLabel(activeApp.label, t) on the pill and each row); ConsoleLayout.tsx (appLabel into AppHeader and the AppShell branding title); HomeAppsStrip.tsx (launcher tiles) |
description |
apps/console AppManagementPage.tsx (the system/apps list line and its search filter). The "under the active app's title" presentation has no successor |
icon |
AppSwitcher.tsx (getIcon(app.icon) per row); HomeAppsStrip.tsx |
branding |
primaryColor: ConsoleLayout.tsx → AppShell branding → useAppShellBranding in packages/layout/src/AppShell.tsx. logo: no runtime reader (see below) |
active |
AppSwitcher.tsx and UnifiedSidebar.tsx (a.active !== false, plus the active-app lookup); utils/appRoute.ts filterActiveApps (used by HomePage and app-launcher-renderer) |
hidden |
AppSwitcher.tsx and UnifiedSidebar.tsx (a.hidden !== true); filterActiveApps |
navigation[].id |
UnifiedSidebar.tsx (useNavOrder, useNavPins); NavigationRenderer.tsx (sortable id, pin toggles); nav-menu-renderer.tsx (row keys, active row) |
navigation[].visible |
UnifiedSidebar.tsx evalVis into NavigationRenderer / hasVisibleNavigationItems; nav-menu-renderer.tsx the same |
areas[].id |
UnifiedSidebar.tsx (activeAreaId) |
areas[].label |
UnifiedSidebar.tsx (resolveInlineI18nLabel(area.label, language)) |
areas[].icon |
UnifiedSidebar.tsx (getIcon(area.icon)) |
areas[].navigation |
UnifiedSidebar.tsx (activeArea?.navigation); AppSchemaRenderer.tsx, already cited on the row |
file _note |
lists "app-shell AppSidebar/ConsoleLayout/ContextSelectors" among the consumers |
Also naming AppSidebar in prose: two comments in packages/spec/src/ui/app.zod.ts, the recordId template-variable note and the AREA_ORDER_RETIRED note.
branding.logo: authored, rendered by nothing
This is not caused by the removal: AppSidebar was never mounted, so an app's branding.logo has never shown in the console. The removal takes away the row's only (unmounted) evidence. What the review found:
- Authored: plugin-designer's
BrandingEditorandAppCreationWizardwrite it with a preview, andEditAppPagepre-fills it. The published@object-ui/app-shellCHANGELOG tells authors "To show a logo, set it on the app schema'sbranding.logoinstead". Downstream,objectstack-ai/hotcrm'scrm.app.tssets it, with a comment saying it renders viaAppSidebar.tsx. - Rendered: by nothing that ships.
AppSchemaRendererreads the top-levellogo, notbranding.logo. One nuance:wizardDraftToAppSchemain objectuipackages/types/src/app.tscopies a wizard draft'sbranding.logointo the top-levellogo. So a wizard-authored logo can surface in anAppSchemaRendererhost, while the key itself has no runtime reader.
Under ADR-0049's enforce-or-remove, this is a declared key the runtime does not honour, and an author (or an AI) setting it gets silence. The two routes, for this repo's seat and, if the options genuinely diverge, the maintainer:
- enforce: a mounted component (
UnifiedSidebar's header, orAppShell's branding) rendersbranding.logo. That is an objectui change, filed there once ruled; - retire:
branding.logoleaves the schema. The designer surfaces and the CHANGELOG advice follow, and the top-levellogostays the one spelling.
Unlock
None needed for re-pointing the 12 rows: the readers above already exist on objectui main. The branding.logo row waits on the enforce-or-retire ruling.
Dedupe
REST page walk over the 1000 most recently updated items in each of objectstack and objectui. branding.logo, app logo near render / shown / display / reader, BrandingEditor near logo, and liveness app.json near AppSidebar ⇒ 0 hits in both.
Generated by Claude Code
Activity
objectstack-fleet commentedon Sep 25, 2026
Path: the road — run it | platform-core.nav-surfaces-render | P2
Triage: first grade —
priority:p3·domain:spec·area:devpath·pm:queue— direction: re-point the 12 rows now;branding.logois enforcedTriage: lands in
packages/spec/liveness/app.json(12 rows citing objectui's removedAppSidebar.tsx, and the file_note), plus the two prose mentions inpackages/spec/src/ui/app.zod.ts⇒domain:spec; rationale: ledger evidence that names a component no longer published is not evidence of a live reader; re-pointing it is ledger hygiene with the live readers already named on this card. p3.Triage seat #6015 ·
session_01CRZSc7dU8oDStbTbSwhuZe· 2026-09-25T12:53Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card and its full thread, andorigin/main.branding.logo— why the direction is enforce, not a decision: it is declared and authored today (plugin-designer'sBrandingEditorandAppCreationWizard,EditAppPage, and downstreamobjectstack-ai/hotcrm'scrm.app.ts; the published@object-ui/app-shellCHANGELOG tells authors to use it), but rendered by nothing that ships. A declared key with measured producers is an implementation gap, and a measured pull points to paying it off, not retiring it.Execution notes
_noteto the live readers on this card (file and symbol, no line numbers); fix the two prose mentions.branding.logo: set the row to planned, with its carrier an objectuidomain:uicard that rendersbranding.logoin a mounted component (UnifiedSidebar's header orAppShell's branding). The claiming seat files that card in objectui with a back-link. If the measurement shows the spec also declares a top-levellogo(a second spelling), the no-dual-spelling rule applies:branding.logo(the one with producers) stays and the other retires, in the same carrier.objectstack-fleet commentedon Sep 27, 2026
Claim: PM loop round 1 · 2026-09-27T18:16Z
Session:
session_01Rjy9MeetSfq34PKn81CRiNAccount:
os-zhuangBranch:
claude/issue-20146-app-ledger-repointWorktree:
objectstack-issue-20146Domain:
domain:specSeat:
domain:spec#1File surface:
packages/spec/liveness/app.json(the 12 rows citing objectui's removedAppSidebar.tsx, plus the file_note); the twoAppSidebarprose mentions inpackages/spec/src/ui/app.zod.ts(comments only); generated ledger artifacts.branding.logo→planned, with carrier objectui#10827 (filed by this seat in this act, per triage5832699195). ⛔ No schema edit. (stop on breach; explain in the report)Container & model:
S,mode:subagent,model: default judgment tier(dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable). The diff touchespackages/spec/src/**(prose), so it is reviewed atCONTRACT_REVIEW_TIERbefore enqueue.Clause-②: no
Thread-read: 5832699195
Serial constraints cleared:
Read at {{NOW}}. No pm:dispatched claim names liveness/app.json, ui/app.zod.ts or branding (32 claims read). Of 22 open PRs, none touches those files. objectui PR #10617 (the AppSidebar removal) is merged: AppSidebar.tsx is absent on objectui main fb91ac9b0 and still present at the .objectui-sha pin f8a9d0fb, and the order names that sha question.objectstack-fleet commentedon Sep 27, 2026
os-dev-report
{
"issue": 20146,
"status": "done",
"branch": "claude/issue-20146-app-ledger-repoint",
"pr": "#20302",
"session": "session_01Rjy9MeetSfq34PKn81CRiN — mode:subagent, so this is the dispatching PM's session id (the transcript's Claude-Session line); identity = the branch",
"premise_still_valid": true,
"summary": "Re-pointed all 12 AppSchema rows in packages/spec/liveness/app.json that cited objectui's AppSidebar.tsx (label, description, icon, branding, active, hidden, navigation.id, navigation.visible, areas.id/label/icon/navigation), and the file _note, to their mounted readers, file#symbol with no line numbers. Every reader is cited at the .objectui-sha pin f8a9d0fb, which still carries AppSidebar.tsx but only as a barrel export with no mount site. Each read was re-measured there, with a per-row control: the same read at objectui main fb91ac9b0, after the removal, answers identically. branding is drilled: logo is planned with carrier objectui#10827 and producer pointers at AppCreationWizard, BrandingEditor and EditAppPage; primaryColor, accentColor and favicon stay live through ConsoleLayout into AppShell#useAppShellBranding. No authorWarn, per README rule 1 and the field.useGrouping precedent. The two app.zod.ts AppSidebar prose mentions now name NavigationRenderer (resolveHref) and UnifiedSidebar. No schema, parse or accept-set change. Measured deltas from the dispatch: (1) Zone 1 says a top-level app
logo"folds into branding". It does not fold: AppSchema.safeParse refuses it as unrecognized_keys with a "did you mean logo → branding" suggestion, and no conversion rewrites it. The conclusion (one declared spelling, nothing to retire) holds; the same imprecise word is in objectui#10827's spelling paragraph. (2) description stays live through AppManagementPage (/system/apps list plus search, routed, fed by useMetadata apps); the sidebar presentation has no successor, and AppCard also reads it but is unmounted at the pin. (3) The active row's old note placed "lookup spans all apps" in the sidebar. At the pin that comment is about hidden apps; the sidebar lookup skips active:false, and AppContent (matchAppBySegment over all apps) is what keeps an inactive app routable. The note is corrected; the verdict is unchanged. (4) Drilling branding required deleting app/branding from undrilled-containers.baseline.json (shrink-only; the gate reds a stale row), and state-counts.md was regenerated (app 56→59 classified, planned +1). (5) liveness/ and src//.zod.ts ship in spec files[] and @objectstack/lint reads the shipped ledgers, so a patch changeset was added instead of skip-changeset.","tests": "All at HEAD 8a4cb2f. check:liveness before (base 1207baf): exit 0,
app 56 classified (live 47, dead 9). After: exit 0,app 59 classified (live 49, dead 9, planned 1),✓ packages/spec/liveness/state-counts.md is current; foreign pointers 202→218, local paths 614/614, symbol anchors 758/758, undrilled containers 110/569→109/565. Through os-verify-lock (VERDICT command-exit 0, held 426s):pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2exit 0,Test Files 552 passed (552),Tests 16251 passed | 1 todo (16252);pnpm --filter @objectstack/spec run typecheckexit 0 (tsc + check:scripts-typecheck + check:test-typecheck OK); consumer suitepnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 src/lint-liveness-properties.test.ts src/component-field-specs-liveness.test.tsexit 0,Test Files 2 passed (2),Tests 91 passed (91). Builds via the lock: spec (VERDICT 0), formula+lint (VERDICT 0), objectql closure (exit 0, 14/14 tasks). Derived gates: 81 commands, 80 exit 0, 1 NOT MEASURED (check:dual-build-cjs-loads, exit 3 prerequisite);dispatch-gates --ran:81 derived famil(ies) accounted for — 80 run, 1 NOT-MEASURED, exit 0. ESLint narrowed and proven: 1 of 5 changed paths is in eslint's population (files **/.{ts,tsx,mts,cts,js,jsx,mjs,cjs});eslint --no-inline-config --format json packages/spec/src/ui/app.zod.tsexit 0, 1 file, 0 errors, 0 warnings. Invariance: eslint.config.mjs enables no type-aware linting (no parserOptions.project, no typed rule sets). No ablation or reverse verification owed: no type change, no new gate. Probes (scratchpad, not committed): AppSchema.safeParse top-level logo → unrecognized_keys ["logo"]; branding.logo → accepted. CI at the time of this report: 11 success, 3 skipped, 18 in_progress, 0 failed (in_progress is the honest value; not waited on).","mcp_calls": "0 — no MCP GitHub tool called (reads were REST GETs; writes through scripts/pm only)",
"api_writes": "3 relay writes as objectstack-fleet[bot], each one repository_dispatch stroke: (1) POST /repos/objectstack-ai/objectstack/pulls — pr_create, draft (relay run 36345659738); (2) POST /repos//issues/20302/assignees — label-write --assign os-zhuang (relay run 36345701160); (3) POST /repos//issues/20146/comments — this os-dev-report via post-stamped. Plus 4 git pushes of the branch (empty write probe, then d0b691c, 3e94863, 8a4cb2f). No label added: the dispatch named none, and a changeset exists, so no skip-changeset.",
"gates": [
"exit 0 · node scripts/check-adr-0087-registration.mjs --base origin/main",
"exit 0 · node scripts/check-adr-0087-registration.mjs --self-test",
"exit 0 · node scripts/check-changeset-no-major.mjs --base origin/main",
"exit 0 · node scripts/check-changeset-no-major.mjs --self-test",
"exit 0 · node scripts/check-ci-filter-parity.mjs",
"exit 0 · node scripts/check-closing-keyword-parity.mjs",
"exit 0 · node scripts/check-closing-keyword-parity.mjs --self-test",
"exit 0 · node scripts/check-comment-mask-adoption.mjs",
"exit 0 · node scripts/check-comment-mask-adoption.mjs --self-test",
"exit 0 · node scripts/check-comment-mask-corpus.mjs",
"exit 0 · node scripts/check-dev-prereqs.mjs --self-test",
"exit 0 · node scripts/check-empty-changeset.mjs --base origin/main",
"exit 0 · node scripts/check-empty-changeset.mjs --self-test",
"exit 0 · node scripts/check-keyed-text-bounds.mjs",
"exit 0 · node scripts/check-keyed-text-bounds.mjs --self-test",
"exit 0 · node scripts/check-platform-object-tenancy-census.mjs",
"exit 0 · node scripts/check-platform-object-tenancy-census.mjs --self-test",
"exit 0 · node scripts/check-plugin-teardown-shape.mjs",
"exit 0 · node scripts/check-plugin-teardown-shape.mjs --self-test",
"exit 0 · node scripts/check-registry-log-declared.mjs",
"exit 0 · node scripts/check-registry-log-declared.mjs --self-test",
"exit 0 · node scripts/check-rest-log-spy-declared.mjs",
"exit 0 · node scripts/check-rest-log-spy-declared.mjs --self-test",
"exit 0 · node scripts/check-spec-docblock-symbol-anchors.mjs",
"exit 0 · node scripts/check-spec-docblock-symbol-anchors.mjs --self-test",
"exit 0 · node scripts/check-system-context-census.mjs",
"exit 0 · node scripts/check-system-context-census.mjs --self-test",
"exit 0 · node scripts/check-undeclared-dep-imports.mjs",
"exit 0 · node scripts/check-undeclared-dep-imports.mjs --self-test",
"exit 0 · node scripts/docs-audit/check-affected-docs.mjs",
"exit 0 · node scripts/docs-audit/check-drift-comment.mjs",
"exit 0 · node scripts/pm/release-rehearsal-clone.mjs --self-test",
"exit 0 · pnpm --filter @objectstack/lint run check:doc-formula-expressions",
"exit 0 · pnpm --filter @objectstack/spec run check:api-surface",
"exit 0 · pnpm --filter @objectstack/spec run check:authorable-surface",
"exit 0 · pnpm --filter @objectstack/spec run check:browser-reachable-entries",
"exit 0 · pnpm --filter @objectstack/spec run check:docs",
"exit 0 · pnpm --filter @objectstack/spec run check:dual-source-exports",
"exit 0 · pnpm --filter @objectstack/spec run check:duration-unit-keys",
"exit 0 · pnpm --filter @objectstack/spec run check:empty-state",
"exit 0 · pnpm --filter @objectstack/spec run check:entry-nameability",
"exit 0 · pnpm --filter @objectstack/spec run check:export-origins",
"exit 0 · pnpm --filter @objectstack/spec run check:exported-any",
"exit 0 · pnpm --filter @objectstack/spec run check:generated",
"exit 0 · pnpm --filter @objectstack/spec run check:liveness",
"exit 0 · pnpm --filter @objectstack/spec run check:llms-txt",
"exit 0 · pnpm --filter @objectstack/spec run check:objectui-pin-citations",
"exit 0 · pnpm --filter @objectstack/spec run check:skill-refs",
"exit 0 · pnpm --filter @objectstack/spec run check:strictness-ledger",
"exit 0 · pnpm --filter @objectstack/spec run check:variant-docs",
"exit 0 · pnpm --filter @objectstack/spec run check:yaml-examples",
"exit 0 · pnpm check:changeset-gate-self-tests",
"exit 0 · pnpm check:cross-package-test-inputs",
"exit 0 · pnpm check:dispatcher-error-vocabulary",
"exit 0 · pnpm check:doc-authoring",
"exit 0 · pnpm check:driver-memory-census",
"exit 0 · pnpm check:dts-closure",
"exit 3 · pnpm check:dual-build-cjs-loads — NOT MEASURED: PREREQUISITE NOT MET (needs all 82 workspace packages built); declared narrowing, CI runs it",
"exit 0 · pnpm check:gitlink-declared",
"exit 0 · pnpm check:issue-citations",
"exit 0 · pnpm check:lean-entry-closure",
"exit 0 · pnpm check:logger-receiver-detach",
"exit 0 · pnpm check:merge-driver",
"exit 0 · pnpm check:nul-bytes",
"exit 0 · pnpm check:objectui-changeset",
"exit 0 · pnpm check:org-identifier",
"exit 0 · pnpm check:page-declaration-shape",
"exit 0 · pnpm check:platform-checklist",
"exit 0 · pnpm check:pm-changeset-deadline-census",
"exit 0 · pnpm check:pm-governed-merges",
"exit 0 · pnpm check:pm-prior-rulings",
"exit 0 · pnpm check:pm-widening-tells",
"exit 0 · pnpm check:published-files",
"exit 0 · pnpm check:refd-timer-probe",
"exit 0 · pnpm check:skill-identifier-liveness",
"exit 0 · pnpm check:slot-lookup",
"exit 0 · pnpm check:sourcemap-no-sources-content",
"exit 0 · pnpm check:spec-parsed-alias",
"exit 0 · pnpm check:test-source-alias",
"exit 0 · pnpm check:tier-file-adoption",
"exit 0 · pnpm check:watch-hint-literal"
],
"line_budget": "n/a — no skills/ file and no line-ratcheted governed ledger touched. Diff: 5 files, +94 / -41.",
"files_changed": [
".changeset/20146-app-ledger-repoint.md +12 -0 (new; @objectstack/spec patch)",
"packages/spec/liveness/app.json +76 -36 (12 rows + _note re-pointed; branding drilled; logo planned)",
"packages/spec/liveness/state-counts.md +2 -2 (regenerated by gen:liveness-counts)",
"packages/spec/scripts/liveness/undrilled-containers.baseline.json +0 -1 (app/branding row removed by the drill)",
"packages/spec/src/ui/app.zod.ts +4 -2 (comments only: recordId template-var note, AREA_ORDER_RETIRED note)"
],
"deviations": [
"File surface: packages/spec/scripts/liveness/undrilled-containers.baseline.json is outside the claim's listed surface. The ordered branding.logo → planned needs branding drilled, and check:liveness fails on a baseline row whose container drills. One row deleted from a shrink-only ratchet.",
"File surface: .changeset/20146-app-ledger-repoint.md added. The order left the changeset to the gates; liveness/ and src/**/*.zod.ts are in spec files[] and are read by @objectstack/lint, so the diff publishes and skip-changeset would be a false declaration.",
"Base: origin/main had moved to 1207baf at worktree creation (the order says 17bd318; the standing delta says a9fb83e and to work on the current tip). Branched from 1207baf and did not merge later main: the 3 upstream commits since then touch none of these files and no spec file.",
"Gate lead superseded: re-derived on the actual 5 paths at 8a4cb2f (81 commands vs the lead's 75; the changeset added empty-changeset, objectui-changeset, pm-changeset-deadline-census and release-rehearsal-clone --self-test; pm-governed-merges also appears).",
"Declared narrowing: check:dual-build-cjs-loads NOT MEASURED (needs every workspace package built; this diff emits no code change). CI runs it.",
"Zone 1 mechanism word measured false: a top-level app
logois refused (unrecognized_keys + did-you-mean), not folded. The conclusion stands."],
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: named producer — objectui plugin-designer CreateAppPage.handleComplete and EditAppPage send wizardDraftToAppSchema(draft) to client.meta.saveItem('app', …), unchanged at objectui main fb91ac9b0 (packages/types/src/app.ts emits top-level type/title/logo/favicon/layout) · evidence: objectstack AppSchema.safeParse of that exact key set → unrecognized_keys ["type","title","logo","favicon","layout"] at path []; control (same payload minus those five keys) accepted; saveMetaItem documents 422 INVALID_METADATA for a schema-invalid item. NOT measured: the live HTTP save door, and whether CreateAppPage is routed in the console. Lands in objectui · dedupe words: wizardDraftToAppSchema, CreateAppPage saveItem app, create app wizard 422, unrecognized_keys title logo layout",
"carrier: objectui#10827 (this seat's own carrier card) · its "Spelling" paragraph says a top-level app logo "folds into branding"; measured: refused with a did-you-mean, not folded. A text correction for the seat; noted, not filed",
"carrier: 承接者:无 · stale rest-server.ts:1870 / :1837 pointers inside
noteprose on app.json areas.navigation and navigation.children (not scanned by any gate; the file _note already names meta-item-read-gate.ts#filterAppForUserWithReason) · noted in PR Acceptance notes only"]
}
objectstack-fleet commentedon Sep 27, 2026
Review: ACCEPT · PR #20302 at head
8a4cb2f0· 2026-09-27T19:52Zdomain:specseat 1 (session_01Rjy9MeetSfq34PKn81CRiN), reviewer of record, on claim5858479995. Checked against GitHub and the diff, ⛔ not against the report alone.Checklist
main, first lineFixes #20146,Clause-②: nocopied from the claim. Not governed.liveness/app.json: the 12 rows and the_noteare re-pointed.brandingis drilled, andlogoisplanned.state-counts.mdis regenerated.undrilled-containers.baseline.jsonloses theapp/brandingrow. This is a shrink-only ratchet; the gate reds a row whose container drills.app.zod.tschanges two comments only.patchchangeset.app.jsoncitesAppSidebarany more. That was checked by a structural walk of the JSON at the head. The 14 remaining mentions are history notes..objectui-shapinf8a9d0fbby file and symbol, and each read is controlled at objectuimainfb91ac9b0.branding.logo:planned, carrier objectui#10827, producersAppCreationWizard,BrandingEditorandEditAppPage. There is noauthorWarn, per the ledger README's rule 1 and thefield.useGroupingprecedent.check:liveness: exit 0, withappgoing from 56 to 59 classified (planned +1). Foreign pointers go from 202 to 218; local paths are 614/614 and anchors 758/758.check:dual-build-cjs-loads, which needs the whole build; CI runs it).skip-changeset:liveness/andsrc/**/*.zod.tsship in the spec'sfiles[], and@objectstack/lintreads the shipped ledgers.1207baf0is fine: the later commits touch no file here.logodoes NOT "fold into branding".AppSchemarefuses it asunrecognized_keys, with a did-you-meanlogo → branding. The conclusion stands: there is one declared spelling and nothing to retire. The same word in objectui#10827 is corrected in this act.Contract review. Owed on the path limb (
packages/spec/src/**, comments only) and the ledger's verdicts. An isolated at-tier reviewer is dispatched.needs:contract-reviewis added to PR #20302 in this act. ⛔ The PR is not readied before a same-shape PASS.Findings, one line each
CreateAppPage/EditAppPagesavewizardDraftToAppSchema(draft), which carries the top-level keystype,title,logo,faviconandlayout.AppSchema.safeParserefuses those asunrecognized_keys(the control payload without those keys is accepted). Reach: named producer. The HTTP save door and whether the page is routed were not measured → filed in objectui after dedupe, in this act.rest-server.tsline pointers inside twonoteproses inapp.json→ Acceptance notes, noted, not filed.objectstack-fleet commentedon Sep 27, 2026
Landed: PR #20302 →
main6ac33a57dfa5e788fca8d032af72dd8b9d158d35(Fixes #20146) · 2026-09-27T20:48Zdomain:specseat 1 (session_01Rjy9MeetSfq34PKn81CRiN), on claim5858479995.How it got here
5859288723.5859414334, at head8a4cb2f0, which is the head that landed. The reviewer closed each re-pointed reader's mount chain by hand at the pinf8a9d0fb, and rancheck:objectui-pin-citations: 47 citations match the pin.check-expected-skips.mjs --pr 20302answeredOK — 6 skipped check-run(s), every one in the roster.Verified on
main, two readings6ac33a57's first parent is7b1e4a48, and no queue branch for fix(spec): re-point the app liveness ledger off objectui's removed AppSidebar; branding.logo is planned #20302 remains.objectui#10827appears 2 times inpackages/spec/liveness/app.jsonat6ac33a57and 0 times at its parent.Fixes. No other lane card closed in the window.Carried elsewhere
branding.logorenders nowhere yet. Its carrier is objectui#10827, and the row flipsplanned→livewhen that lands and the pin absorbs it.AppSchemarefuses. That is objectui#10842.objectstack-fleet commentedon Sep 27, 2026
Back-link from objectstack-ai/objectui#10827 (the carrier this card's ledger row
app.branding.logonames), per that card's triage note 4 ·domain:uiseat 4 (session_01MCg3z5cGrV51xEddpGcxEY) · 2026-09-27T21:01Z.objectui#10827 landed as PR objectstack-ai/objectui#10849 → objectui
mainf976774717, merged at 2026-09-27T20:59Z. Content was verified onmain:packages/app-shell/src/layout/UnifiedSidebar.tsxdraws the active app'sbranding.logoin the console's mounted sidebar header. It draws nothing when the logo is absent, and nothing on Home.AppComponentSchema.logois retired, and the zod mirror refuses it by name with the spec's own 「Did you meanlogo→branding?」.wizardDraftToAppSchemano longer writes a top-levellogo.AppSchemaRendererand the runner'sLayoutRendererreadbranding.logo.The ledger row can flip
planned→live, citing that reader, once objectstack's.objectui-shapin moves tof976774717or later. That pin bump belongs to objectstack's seat, not to this lane. The wizard document's remaining spec-refused keys (type,title,favicon,layout) and thefavicontwin are carried on objectstack-ai/objectui#10842.Generated by Claude Code
fix(types,layout,app-shell,runner)!: the console renders an app's bra…
fix(spec): re-point the app liveness ledger off objectui's removed Ap…