From 17a7215ef3b87b6ac804d39462704ca6705deae8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 10:43:04 +0000 Subject: [PATCH] =?UTF-8?q?docs(liveness):=20designer=20previews=20count?= =?UTF-8?q?=20as=20consumers=20=E2=80=94=20re-grade=20four=20docs-shaped?= =?UTF-8?q?=20rows=20(#7131)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ledger recorded "no runtime consumer" for job.label, job.description, translation.label and translation.name. objectui's metadata-admin previews had been rendering all four to a human the whole time. Per the maintainer ruling of 2026-08-10, a designer preview that renders a key to a human is a runtime consumer. The four rows re-grade dead -> live with realm-marked, commit-pinned objectui evidence (@aeb8424b) and a `producer` naming the registerMetadataPreview call plus the surface that resolves it — a preview no registry hands a draft to is a read point that never runs. Nothing about enforce-or-remove moves: all four remain docs-shaped, deliberately KEPT under ADR-0033, and still not authorWarn'd. The README gains the methodology section the ruling asked for, dividing against the existing "an authoring/preview renderer is NOT a runtime consumer" section on what the property CLAIMS rather than on what the surface is. The 2026-07 sweep's ten corrections are not reopened. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016R9de1FqP7NvwKvqXi92Gh --- .../liveness-previews-count-as-consumers.md | 35 +++++++++++ packages/spec/liveness/README.md | 59 +++++++++++++++++++ packages/spec/liveness/job.json | 18 ++++-- packages/spec/liveness/translation.json | 18 ++++-- 4 files changed, 118 insertions(+), 12 deletions(-) create mode 100644 .changeset/liveness-previews-count-as-consumers.md diff --git a/.changeset/liveness-previews-count-as-consumers.md b/.changeset/liveness-previews-count-as-consumers.md new file mode 100644 index 0000000000..7df82d8a95 --- /dev/null +++ b/.changeset/liveness-previews-count-as-consumers.md @@ -0,0 +1,35 @@ +--- +"@objectstack/spec": patch +--- + +docs(liveness): designer previews count as consumers — re-grade four docs-shaped rows dead → live and write the principle into the ledger methodology (#7131) + +The ledger said `job.label`, `job.description`, `translation.label` and +`translation.name` had **no runtime consumer**. objectui's metadata-admin +previews had been rendering all four to a human the whole time: +`JobPreview.tsx` takes `label`/`description` off the job draft and renders them +as the preview card's title and subtitle, and `TranslationPreview.tsx` takes +`label` — falling back to the body `name` — and renders it as the item's title. + +Per the maintainer ruling of 2026-08-10, a designer preview that renders a key +to a human **is** a runtime consumer, so the four rows re-grade to `live` with +realm-marked, commit-pinned objectui evidence, and each carries a `producer` +naming the `registerMetadataPreview` call and the surface that resolves it — a +preview no registry ever hands a draft to is a read point that never runs. + +Nothing about enforce-or-remove moves: all four keys remain docs-shaped, +deliberately KEPT under the ADR-0033 exemption, and still not `authorWarn`'d. +`job.label` is `live` because a human sees it in the designer; the scheduler +still stores name and schedule only, and the row now says so explicitly. + +The README gains the methodology section the ruling asked for, so the next sweep +asks the question mechanically instead of rediscovering it: enumerate a type's +registered preview read points **before** writing "no runtime consumer", and +record their absence when there are none. It divides against the existing +"an authoring/preview renderer is NOT a runtime consumer" section on what the +property claims rather than on what the surface is — for a **display** key the +render is the whole of the declared effect, while for a **behavioural** key a +panel echoing the value back still proves nothing. The 2026-07 sweep's ten +corrections are explicitly not reopened. + +Ledger and documentation only; no schema, no runtime behaviour. diff --git a/packages/spec/liveness/README.md b/packages/spec/liveness/README.md index 2cbff08f4f..b38a1156c7 100644 --- a/packages/spec/liveness/README.md +++ b/packages/spec/liveness/README.md @@ -240,6 +240,13 @@ means "the realms named in the evidence", never "everywhere". ### ⚠️ An authoring/preview renderer is NOT a runtime consumer +> **Scope narrowed 2026-08-10 (#7131) — read the next section with this one.** What +> follows holds for a property that claims to **do** something: gate, bind, route, +> filter, enforce. It does *not* settle a property whose declared effect is simply +> to **be shown**, where the render is not a stand-in for the behaviour but *is* the +> behaviour. None of the thirteen re-verifications below is reopened by that split — +> all thirteen are behavioural keys. + `live` means **authoring the property changes runtime behaviour**. A Studio `*.form.ts` input or a `metadata-admin/previews/*Preview.tsx` panel merely *echoes back what the author typed* — it proves the property round-trips, never @@ -281,6 +288,58 @@ enforced" warning for a month while it worked, which is an invitation to skip a shipped feature. Erring toward `dead` is the right default *and* a debt to re-verify. +### Designer previews count as consumers (maintainer ruling, 2026-08-10, #7131) + +The section above is the *over-claim* guard. It also produced an under-claim, and +the maintainer settled it directly: + +> **Maintainer ruling (2026-08-10, directed in session `session_01BPWqbmEFU8gJepBJTHESXd`): previews count as consumers.** +> +> A designer preview that renders a key to a human is a runtime consumer — the ledger's "no runtime consumer" verdict must include metadata-admin preview read points. The affected docs-shaped rows (`job.label`/`job.description`, `translation.label`/`.name`) re-grade from dead to live, and the ledger methodology note records the principle so the next sweep asks the question mechanically. + +**The mechanical rule, for the next sweep.** Before writing `"no runtime +consumer"` — or any wording that means it — **enumerate the metadata-admin preview +read points** for the type, in objectui, and say what you found. The population is +small, enumerable, and registered by type name, so this is a lookup and not a +search: + +```bash +# 1. does this type have a preview at all? +git -C ../objectui grep -n "registerMetadataPreview(''" origin/main +# 2. what does that preview read off the draft? +git -C ../objectui show origin/main:packages/app-shell/src/views/metadata-admin/previews/Preview.tsx \ + | grep -n 'd\.' +``` + +An absent preview is a finding to record, not a step to skip — "the type has no +registered preview" is exactly the sentence a later sweep needs, and it is the one +`translation.label`'s superseded *"no runtime consumer **in this repo**"* was +missing. That hedge was never false; the cross-repo look simply was not taken, +which is the blind spot `evidenceScope` (#4895) exists to expose. + +**Why this does not contradict the section above.** The two rules divide on what +the property claims, not on what the surface is: + +| The property's declared effect | Does a preview render settle it? | +|---|---| +| **Display** — docs-shaped annotation, `label` / `description` / a title fallback | **Yes.** Being shown to a human is the whole of the claimed effect. There is no second layer where the "real" consumer would live, so the preview is not standing in for anything. | +| **Behaviour** — gates, bindings, routes, filters, permissions | **No.** The 2026-07 sweep's verdict stands unchanged: 10 of 13 preview-cited entries were wrong. A panel echoing `shortcut` back is not a keybinding, and echoing `permissions` back is not a gate. | + +So the failure the section above records — a preview citation used as evidence +that *something acts on* the value — is untouched. What is corrected is the +opposite move: taking a preview's **absence from the search** as proof that +*nothing reads* the value, for a key whose only job was ever to be read by a +person. + +**What `live` does and does not mean on a re-graded row.** `job.label` is `live` +because a human sees it in the designer; the scheduler still stores name/schedule +only, and the row says so. A re-grade is **not** an ADR-0033 change: these four +rows are docs-shaped, deliberately KEPT, and still not `authorWarn`'d — nothing +about enforce-or-remove moves. Cite the preview the way any cross-repo evidence is +cited: realm marker, pinned objectui commit, and a `producer` naming the +`registerMetadataPreview` call plus the surface that resolves it — a preview no +registry hands a draft to is a read point that never runs. + ### How to verify a claim without fooling yourself Three false conclusions were published during this sweep, all from the same diff --git a/packages/spec/liveness/job.json b/packages/spec/liveness/job.json index 02e63c09f4..99b0e3938a 100644 --- a/packages/spec/liveness/job.json +++ b/packages/spec/liveness/job.json @@ -9,14 +9,20 @@ "note": "scheduling identity; a job without one is skipped loudly." }, "label": { - "status": "dead", - "verifiedAt": "2026-08-02", - "note": "display metadata; no runtime consumer (sys_job stores name/schedule only). Docs-shaped annotation, deliberately KEPT and not authorWarn'd — the hook.label/description precedent, exempt from enforce-or-remove (ADR-0033)." + "status": "live", + "verifiedAt": "2026-08-10", + "evidenceScope": "cross-repo", + "evidence": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/JobPreview.tsx:257 takes `label` off the job draft with the job's own `name` as fallback, and packages/app-shell/src/views/metadata-admin/previews/JobPreview.tsx:313 renders it as the preview card's title", + "producer": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/index.ts:62 registers JobPreview against the `job` metadata type, and packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx:949 resolves that registration and hands the component the draft being edited — the read point is reachable, not merely present", + "note": "display metadata, and it IS displayed: the metadata-admin job preview shows it as the card title, falling back to the job `name` when unset. RE-GRADED dead → live 2026-08-10 (#7131) under the maintainer ruling that a designer preview rendering a key to a human is a runtime consumer — see README, 'Designer previews count as consumers'. The superseded wording, 'no runtime consumer (sys_job stores name/schedule only)', was true about the SCHEDULER and false as a whole-system claim: for a docs-shaped key the display IS the runtime effect, so sys_job was never the surface that could falsify it. UNCHANGED by the re-grade: still docs-shaped annotation, deliberately KEPT and not authorWarn'd — the hook.label/description precedent, exempt from enforce-or-remove (ADR-0033). `live` here does not mean the scheduler acquired a use for it." }, "description": { - "status": "dead", - "verifiedAt": "2026-08-02", - "note": "same as `label`: docs-shaped, deliberately kept, no warning." + "status": "live", + "verifiedAt": "2026-08-10", + "evidenceScope": "cross-repo", + "evidence": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/JobPreview.tsx:258 takes `description` off the job draft, and packages/app-shell/src/views/metadata-admin/previews/JobPreview.tsx:316 renders it beneath the title whenever it is non-empty", + "producer": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/index.ts:62 registers JobPreview against the `job` metadata type, and packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx:949 resolves that registration and hands the component the draft being edited", + "note": "same as `label`: docs-shaped, deliberately kept, no warning — and displayed under the title in the same preview card. Re-graded dead → live with `label` on 2026-08-10 (#7131), same ruling, same ADR-0033 KEPT status." }, "schedule": { "status": "live", diff --git a/packages/spec/liveness/translation.json b/packages/spec/liveness/translation.json index 5cba3a86aa..633e0ecfb6 100644 --- a/packages/spec/liveness/translation.json +++ b/packages/spec/liveness/translation.json @@ -3,14 +3,20 @@ "_note": "TranslationItemSchema (#3778 — one locale's translations, the SAME groups the file-authored bundles use). NO LONGER A PIPE: the schema was a z.preprocess wrapping the retired object-first-dialect guard, which the gate's walker could not see through until #4488 fixed unwrap() to take the OUT side of a transform-input pipe — `translation` was literally unwalkable before this ledger. #4001 closed the shape with `.strict()` and folded the guard's ten prescriptions into the unknown-key `guidance`, so the preprocess is gone and the registered schema is a plain strict object. Consumer chain: runtime-authored items sync into the i18n adapter's authored layer (packages/core/src/fallbacks/authored-translation-sync.ts — at kernel:ready, on metadata:reloaded, and on translation mutations; #2591 closed the publish dead-end), file bundles load via service-i18n; both merge into ONE tree read by the spec resolvers (packages/spec/src/system/i18n-resolver.ts), the REST localization layer (translateMetaItem/translateMetaTypes), objectui's client resolvers (useObjectLabel/useSettingsLabel), and plugin-audit's summary localizer. WALK BOUNDARY: every group is a z.record keyed by target names — the drill sees each record's VALUE shape one level; the deeper per-key conventions (objects..fields..label, settings..keys..options., …) are governed by the resolvers cited per row, not by ledger rows. Note also the sync merges the RAW stored payload (authored-translation-sync.ts:155, not a schema re-parse), so the declared groups below are the CONTRACT while undeclared keys technically flow through on rows already stored — the resolvers read only the declared conventions. Since #4001 no NEW row can acquire one: the metadata door rejects an undeclared key instead of stripping it, so that residue is a finite set that only shrinks. 10 of 11 groups live; the one dead group (`validationMessages`) is pointed at by #3778's own legacy-key migration table, making it a shipped false signpost. Seeded 2026-08-01 (#4488).", "props": { "name": { - "status": "dead", - "verifiedAt": "2026-08-01", - "note": "Item identity, declared in #4001 and dead as a BODY key — which is the honest reading of a copy nobody reads. The row's `name` column is the live one: the metadata door takes it from the URL (`saveMetaItem({ name })`, rest-server.ts:3903), and `authored-translation-sync` reads `row.name` as the locale fallback for pre-#3778 rows (:140-148) while explicitly destructuring the body copy back out before merging (:154-159). Declared anyway, and deliberately not authorWarn'd, for two reasons: the platform's own create seed sends it (`metadata-create-seeds.ts`, whose stated contract is that EVERY seed carries placeholder identity), so a warning would fire on our own shape; and `translation` being the one registered type of 25 without a `name` is exactly the irregularity an AI author trips on. Undeclared it was silently stripped, which is how the seed gate — the canonical 'designer create shape ≠ spec' guard — passed for years while two thirds of the seed it validated was being thrown away." + "status": "live", + "verifiedAt": "2026-08-10", + "evidenceScope": "cross-repo", + "evidence": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/TranslationPreview.tsx:67 falls back to the draft's BODY `name` when `label` is unset, and packages/app-shell/src/views/metadata-admin/previews/TranslationPreview.tsx:100 renders the result as the preview card's title", + "producer": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/index.ts:50 registers TranslationPreview against the `translation` metadata type, and packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx:949 resolves that registration and hands the component the draft being edited", + "note": "Item identity, declared in #4001. RE-GRADED dead → live 2026-08-10 (#7131), and the re-grade supersedes exactly ONE clause of the old note: 'dead as a BODY key — the honest reading of a copy nobody reads'. The body copy has a measured reader — objectui's metadata-admin translation preview uses it as the display fallback when `label` is unset — so under the maintainer ruling that a designer preview rendering a key to a human is a runtime consumer (see README, 'Designer previews count as consumers') the copy is read. THE REST OF THIS ROW STANDS UNCHANGED AND IS THE SUBSTANCE, including its door/row-column analysis: the row's `name` column is the live one on the SYNC path, and the body copy is still not what the sync reads — the preview reads it, the sync does not. The metadata door takes it from the URL (`saveMetaItem({ name })`, rest-server.ts:3903), and `authored-translation-sync` reads `row.name` as the locale fallback for pre-#3778 rows (:140-148) while explicitly destructuring the body copy back out before merging (:154-159). Declared anyway, and deliberately not authorWarn'd, for two reasons: the platform's own create seed sends it (`metadata-create-seeds.ts`, whose stated contract is that EVERY seed carries placeholder identity), so a warning would fire on our own shape; and `translation` being the one registered type of 25 without a `name` is exactly the irregularity an AI author trips on. Undeclared it was silently stripped, which is how the seed gate — the canonical 'designer create shape ≠ spec' guard — passed for years while two thirds of the seed it validated was being thrown away." }, "label": { - "status": "dead", - "verifiedAt": "2026-08-01", - "note": "Display metadata with no runtime consumer in this repo. Not authorWarn'd: the README's rule is that pure display annotation (`description`, `tags`, `icon`) must not warn, and the `job.label` precedent is exactly this — docs-shaped, deliberately kept, ADR-0033 exempt from enforce-or-remove. Shipped with `name` in the create seed for the same reason." + "status": "live", + "verifiedAt": "2026-08-10", + "evidenceScope": "cross-repo", + "evidence": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/TranslationPreview.tsx:67 takes `label` off the translation draft as the first choice of the display chain, and packages/app-shell/src/views/metadata-admin/previews/TranslationPreview.tsx:100 renders the result as the preview card's title", + "producer": "objectui @aeb8424b: packages/app-shell/src/views/metadata-admin/previews/index.ts:50 registers TranslationPreview against the `translation` metadata type, and packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx:949 resolves that registration and hands the component the draft being edited", + "note": "Display metadata — and the display exists, one repo over: the metadata-admin translation preview renders it as the item's title. RE-GRADED dead → live 2026-08-10 (#7131) under the maintainer ruling that a designer preview rendering a key to a human is a runtime consumer — see README, 'Designer previews count as consumers'. Read the superseded wording carefully: 'no runtime consumer IN THIS REPO' was literally accurate and remains so — what changed is that the cross-repo look was finally taken, which is exactly the blind spot `evidenceScope` exists to make visible (#4895). UNCHANGED: not authorWarn'd — the README's rule is that pure display annotation (`description`, `tags`, `icon`) must not warn, and the `job.label` precedent is exactly this — docs-shaped, deliberately kept, ADR-0033 exempt from enforce-or-remove. Shipped with `name` in the create seed for the same reason." }, "locale": { "status": "live",