Skip to content

Commit 3fed1eb

Browse files
spec(liveness): app.branding.logo is live — objectui AppMark renders it at the pin (#23830)
Fixes #23394 Clause-②: no ## What changes `packages/spec/liveness/app.json`, `app.branding.children.logo` flips from `planned` to `live` (`verifiedAt` 2026-10-16, `evidenceScope: "cross-repo"`). - **Reader, read at the `.objectui-sha` pin this tree carries (`daeb77fc84`):** objectui `packages/app-shell/src/layout/AppMark.tsx#AppMark` reads `branding.logo` and draws it as an `object-contain` image (it falls back to the `icon` tile when the key is absent or the image fails to load). It is mounted by `AppSwitcher#AppSwitcher` at 22 px, on the top-bar app pill and on every switcher row (the switcher is mounted in `AppHeader`), and by `UnifiedSidebar#UnifiedSidebar` at 26 px, in the phone drawer header. All three are cited in `evidence`. - **`producer`:** kept and re-pinned to `daeb77fc`. The designer's `AppCreationWizard`, `BrandingEditor` and `EditAppPage` still write or pre-fill `branding.logo` at the pin. - **`note`:** rewritten to say what renders it. The "PLANNED, carrier objectui#10827" and "Flip to `live`" wording is gone, and so is the paragraph about objectui's top-level `logo`, because objectui has since retired that second spelling. The ONE SPELLING paragraph stays, because it is still true: `AppSchema` declares only `branding.logo`, and the alias table answers an app-level `logo` with `branding` (`packages/spec/src/ui/app.zod.ts`). - **`branding` container `note`:** only the sentence about `logo` is changed. It now says `logo` reached nothing mounted at the 2026-09-27 drill and has since gone `live` through `AppMark`. - **`state-counts/app.md`:** regenerated with `gen:liveness-counts`. Before: `live 50 · planned 1`. After: `live 51 · planned 0`. `classified` stays 59. - **Changeset:** a `patch` changeset for `@objectstack/spec`. `liveness/` is in the package's `files[]`, so the ledger ships. No schema, objectui file or `.objectui-sha` changes. ## Verification At head `0a6dbaf4`: - `pnpm --filter @objectstack/spec check:liveness`: exit 1 before the regeneration (the expected count drift, `| app | 50 | 0 | 0 | 8 | 1 | 59 |` to `| app | 51 | 0 | 0 | 8 | 0 | 59 |`), then exit 0 after `gen:liveness-counts`. Every `live` entry's repo-local evidence resolves, and `state-counts/` is current. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 62 commands for this diff. 59 exited 0, `pnpm --filter @objectstack/spec run check:generated` among them, after a spec build. 3 exited 3 because a prerequisite was missing (NOT MEASURED, left to CI): `check:dual-build-cjs-loads` and `check:lean-entry-closure` need a full workspace build, and `check-plugin-teardown-shape.mjs --self-test` needs an unshallowed clone. `--ran` reconciles: 62 derived, 59 run, 3 NOT-MEASURED, 0 UNRUN. ## Acceptance notes - The ledger file's top-level `_note` still has the dated 2026-09-27 sentence "`branding` is now DRILLED: `logo` is `planned` with carrier objectui#10827". It records history and sits outside this card's claimed file surface (the row and the container note only), so it is left as it was. - `docs/audits/2026-06-appschema-property-liveness.md` lists `branding.logo` among the unimplemented keys. It is a dated audit snapshot, not a current-state page, and it is left as it was. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01PfJqaHVFSJ1Znqb9vBPZe2 --- _Generated by [Claude Code](https://claude.ai/code/session_01PfJqaHVFSJ1Znqb9vBPZe2)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0cfd0c4 commit 3fed1eb

3 files changed

Lines changed: 23 additions & 6 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
fix(spec): the liveness ledger reads `app.branding.logo` as `live`, citing the console's `AppMark` reader (#23394)
6+
7+
Clause-②: no
8+
9+
**What was wrong.** The liveness ledger shipped with `@objectstack/spec` graded `app.branding.logo` `planned`, with a note saying no mounted component rendered it. The console now does: objectui's `AppMark` draws `branding.logo` as the app's square icon on the top-bar app pill, on each App Switcher row and in the phone drawer header.
10+
11+
**What changes.**
12+
13+
- `liveness/app.json`: `branding.logo` reads `live`, citing `AppMark` and the two shell components that mount it at the `.objectui-sha` pin. The designer pages that write the key stay cited as its `producer`. The `branding` container's note says the same.
14+
- `liveness/state-counts/app.md` is regenerated: `app` moves from `live 50 · planned 1` to `live 51 · planned 0`.
15+
16+
Unchanged: what `AppSchema` accepts and refuses (an app-level `logo` is still refused, and the refusal still points at `branding`), and every other ledger row.

‎packages/spec/liveness/app.json‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@
5353
"note": "the tab icon while the app is active."
5454
},
5555
"logo": {
56-
"status": "planned",
57-
"verifiedAt": "2026-09-27",
56+
"status": "live",
57+
"verifiedAt": "2026-10-16",
5858
"evidenceScope": "cross-repo",
59-
"producer": "objectui @f8a9d0fb: packages/plugin-designer/src/AppCreationWizard.tsx#AppCreationWizard (writes `branding.logo`, with a preview); objectui @f8a9d0fb: packages/plugin-designer/src/BrandingEditor.tsx#BrandingEditor (writes it, with a preview); objectui @f8a9d0fb: packages/plugin-designer/src/pages/EditAppPage.tsx#EditAppPage (pre-fills the editor from it)",
60-
"note": "PLANNED, carrier objectui#10827 (a mounted component renders `branding.logo`: the `UnifiedSidebar` header or `AppShell`'s branding). AUTHORED, RENDERED BY NOTHING THAT SHIPS, measured at the `.objectui-sha` pin f8a9d0fb and again at objectui main fb91ac9b0. The designer writes it (`producer`), and the published `@object-ui/app-shell` CHANGELOG tells authors to set it. The one component that ever read it was AppSidebar, which was never mounted; the console's branding handoff (`ConsoleLayout` into `AppShell`) passes `primaryColor`, `accentColor` and `favicon` and never `logo`, and `AppShellBranding` has no logo field. The nearest thing to a read: objectui's `wizardDraftToAppSchema` (packages/types) copies a wizard draft's `branding.logo` into a TOP-LEVEL `logo`, and `AppSchemaRenderer`'s `InternalSidebar` renders that top-level `logo`. So a wizard-authored logo can surface in an `AppSchemaRenderer` host while this key itself has no runtime reader. ONE SPELLING: `AppSchema` declares only `branding.logo`. An app-level `logo` is REFUSED by the strict app shape (`unrecognized_keys`), and the refusal suggests `branding` through the alias table; it is not folded or rewritten, and no ADR-0087 conversion carries it. Not `authorWarn`'d, on the `field.useGrouping` precedent and README rule 1: a logo URL is display metadata, an author who sets it today loses nothing and is not misled about behaviour, and the value takes effect the moment the carrier lands with no re-authoring. Flip to `live` citing that reader at the pin that carries it. The triage direction on #20146 is ENFORCE (a declared key with measured producers is an implementation gap), not retire."
59+
"evidence": "objectui @daeb77fc: packages/app-shell/src/layout/AppMark.tsx#AppMark (reads `branding.logo` and draws it as an `object-contain` image at the surface's size, falling back to the `icon` tile when it is absent or fails to load); objectui @daeb77fc: packages/app-shell/src/layout/AppSwitcher.tsx#AppSwitcher (`AppMark` at 22 px on the top-bar app pill and on every switcher row; the switcher is mounted in `AppHeader`); objectui @daeb77fc: packages/app-shell/src/layout/UnifiedSidebar.tsx#UnifiedSidebar (`AppMark` at 26 px in the phone drawer header)",
60+
"producer": "objectui @daeb77fc: packages/plugin-designer/src/AppCreationWizard.tsx#AppCreationWizard (writes `branding.logo`, with a preview); objectui @daeb77fc: packages/plugin-designer/src/BrandingEditor.tsx#BrandingEditor (writes it, with a preview); objectui @daeb77fc: packages/plugin-designer/src/pages/EditAppPage.tsx#EditAppPage (pre-fills the editor from it)",
61+
"note": "the app's one square (1:1) icon, an image URL: objectui's `AppMark` renders it on the top-bar app pill, on each App Switcher row and in the phone drawer header, each at its own size, and an app without it gets its `icon` on a tile. Read at the `.objectui-sha` pin daeb77fc. 2026-10-16: FLIPPED from `planned` — the reader shipped under objectui#12201, after the 2026-09-27 drill found `branding.logo` authored by the designer (`producer`) and rendered by nothing mounted. ONE SPELLING: `AppSchema` declares only `branding.logo`. An app-level `logo` is REFUSED by the strict app shape (`unrecognized_keys`), and the refusal suggests `branding` through the alias table; it is not folded or rewritten, and no ADR-0087 conversion carries it."
6162
}
6263
},
63-
"note": "Drilled 2026-09-27 (#20146), because `logo` diverged from its siblings once the evidence was re-read: `primaryColor`, `accentColor` and `favicon` reach the console through `ConsoleLayout` into `AppShell`, and `logo` reaches nothing mounted. Until then this row carried one `live` verdict over all four children, citing `AppSidebar.tsx` (never mounted) for `logo` and `primaryColor`, and it was recorded in `undrilled-containers.baseline.json`; that baseline row is deleted with this drill."
64+
"note": "Drilled 2026-09-27 (#20146), because `logo` diverged from its siblings once the evidence was re-read: `primaryColor`, `accentColor` and `favicon` reach the console through `ConsoleLayout` into `AppShell`, and `logo` then reached nothing mounted; it has since gone `live` through objectui's `AppMark` (see that row). Until then this row carried one `live` verdict over all four children, citing `AppSidebar.tsx` (never mounted) for `logo` and `primaryColor`, and it was recorded in `undrilled-containers.baseline.json`; that baseline row is deleted with this drill."
6465
},
6566
"active": {
6667
"status": "live",

‎packages/spec/liveness/state-counts/app.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ committed anywhere: `check:liveness` sums the shards when it reads them.
1212

1313
| Type | live | exp | elsewhere | dead | planned | classified |
1414
|---|---|---|---|---|---|---|
15-
| `app` | 50 | 0 | 0 | 8 | 1 | 59 |
15+
| `app` | 51 | 0 | 0 | 8 | 0 | 59 |

0 commit comments

Comments
 (0)