Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/23394-branding-logo-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
'@objectstack/spec': patch
---

fix(spec): the liveness ledger reads `app.branding.logo` as `live`, citing the console's `AppMark` reader (#23394)

Clause-②: no

**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.

**What changes.**

- `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.
- `liveness/state-counts/app.md` is regenerated: `app` moves from `live 50 · planned 1` to `live 51 · planned 0`.

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.
11 changes: 6 additions & 5 deletions packages/spec/liveness/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,15 @@
"note": "the tab icon while the app is active."
},
"logo": {
"status": "planned",
"verifiedAt": "2026-09-27",
"status": "live",
"verifiedAt": "2026-10-16",
"evidenceScope": "cross-repo",
"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)",
"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."
"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)",
"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)",
"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."
}
},
"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."
"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."
},
"active": {
"status": "live",
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/liveness/state-counts/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ committed anywhere: `check:liveness` sums the shards when it reads them.

| Type | live | exp | elsewhere | dead | planned | classified |
|---|---|---|---|---|---|---|
| `app` | 50 | 0 | 0 | 8 | 1 | 59 |
| `app` | 51 | 0 | 0 | 8 | 0 | 59 |
Loading