Skip to content
Closed
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
11 changes: 11 additions & 0 deletions .changeset/25742-flows-screens-liveness-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@objectstack/spec': patch
---

The liveness ledger's `flows.screens` translation row stops citing a file that no longer names the key

Clause-②: no
Metadata-protocol: none

- `liveness/translation.json`, row `flows.screens`: the evidence pointer at service-automation's `engine.ts#renderFlowTextSlot` is dropped. That file named `screens` only in a comment, and the comment moved to `run-resume.ts` when the engine's resume body was extracted, so the citation no longer said anything about the key. The row's other in-repo pointer, `builtin/screen-nodes.ts#registerScreenNodes`, names the key, and every objectui pointer is unchanged.
- The status stays `live`, `verifiedAt` is unchanged, and no state count moves. No schema changes: what a translation bundle or a `translation` item accepts and refuses is unchanged, and so is every other ledger row.
4 changes: 2 additions & 2 deletions packages/spec/liveness/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@
"status": "live",
"verifiedAt": "2026-10-10",
"evidenceScope": "cross-repo",
"evidence": "packages/services/service-automation/src/builtin/screen-nodes.ts#registerScreenNodes (the `screen` executor asks for `flows.<flow>.screens.<node_id>.title` and, where the screen authors body text, `.description`, spelled by `flowScreenCopyKey`, before it renders either template); packages/services/service-automation/src/engine.ts#renderFlowTextSlot (picks the translated template through the `i18n` service in the run's `AutomationContext.locale`, negotiated by `resolveBundleLocale`, and renders it through `renderTextSlot` in place of the authored one; a miss echoes the key and the authored template renders); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#localizeScreen (the heading through `resolveFlowScreenTitle`, and each field's copy from `bundle[language]?.flows?.[flowName]?.screens?.[screen.nodeId]?.fields`); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#overlayFieldCopy (walks the spec's imported `FLOW_SCREEN_FIELD_COPY_KEYS`, which are `label` / `placeholder` / `inlineHelpText`, and overlays each key on its own, falling back to the authored string); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#activeFlowsBundle (reads the active language's `flows` group out of the i18next `translation` resource tree); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#FlowRunner (draws `shown.title` as the dialog title and hands the localized screen to `ScreenView`); objectui @31971ff1e: packages/app-shell/src/views/ScreenView.tsx#ScreenView (draws each field's `label`, hands `placeholder` to the control, and draws `inlineHelpText` under the control, which names it in `aria-describedby`)",
"evidence": "packages/services/service-automation/src/builtin/screen-nodes.ts#registerScreenNodes (the `screen` executor asks for `flows.<flow>.screens.<node_id>.title` and, where the screen authors body text, `.description`, spelled by `flowScreenCopyKey`, before it renders either template); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#localizeScreen (the heading through `resolveFlowScreenTitle`, and each field's copy from `bundle[language]?.flows?.[flowName]?.screens?.[screen.nodeId]?.fields`); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#overlayFieldCopy (walks the spec's imported `FLOW_SCREEN_FIELD_COPY_KEYS`, which are `label` / `placeholder` / `inlineHelpText`, and overlays each key on its own, falling back to the authored string); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#activeFlowsBundle (reads the active language's `flows` group out of the i18next `translation` resource tree); objectui @31971ff1e: packages/app-shell/src/views/FlowRunner.tsx#FlowRunner (draws `shown.title` as the dialog title and hands the localized screen to `ScreenView`); objectui @31971ff1e: packages/app-shell/src/views/ScreenView.tsx#ScreenView (draws each field's `label`, hands `placeholder` to the control, and draws `inlineHelpText` under the control, which names it in `aria-describedby`)",
"producer": "packages/runtime/src/app-plugin.ts#loadTranslations (hands each bundle's locale data to the i18n service whole, `flows` included); packages/runtime/src/domains/i18n.ts#handleI18nRequest (the translations route answers `getTranslations(locale)` with no group filter); objectui @31971ff1e: apps/console/src/loadLanguage.ts#loadLanguage (fetches the locale's translations and runs `transformSpecTranslations`); objectui @31971ff1e: packages/i18n/src/utils/spec-translations.ts#transformSpecTranslations (forwards every group it does not flatten, `flows` among them, verbatim under the `app` namespace); objectui @31971ff1e: packages/i18n/src/provider.tsx#I18nProvider (adds the loaded payload to the `translation` resource bundle that `activeFlowsBundle` reads)",
"note": "FLIPPED planned → live 2026-09-27 (#20296). It was PLANNED with its container under the #7646 contract-first split: the spec declared the vocabulary and the screen-flow runner half was a downstream objectui card. That half has landed client-side, the side #11287 picked (objectui#5920, FlowRunner's `localizeScreen`), and the `.objectui-sha` pin f8a9d0fb carries it, so every objectui pointer above was read at the pin this repo builds against. Each read is unchanged at objectui main 256b4c9e. Per-screen heading + per-field copy, keyed by `FlowNode.id` / `ScreenFieldConfig.name`, the identifiers the client already holds as `ScreenSpec.nodeId` / `ScreenFieldSpec.name`. Each key falls back to the authored string on its own. The screen `description` and the runner chrome stay untranslated here by ruling. Deeper conventions (`screens.<id>.title`, `screens.<id>.fields.<name>.{label,placeholder,inlineHelpText}`) are governed by the runner and the spec's `FLOW_SCREEN_COPY_KEYS` / `FLOW_SCREEN_FIELD_COPY_KEYS`, not by ledger rows: the one-drill-level boundary this ledger's type note states. MOUNT CHAIN, closed by hand at the pin: `FlowRunner` is mounted by `useConsoleActionRuntime`'s dialogs (the console root `ConsoleShell` renders them, and ObjectView / DeclaredActionsBar each run their own runtime), by `RecordDetailView`, and by the console's `developer/flow-runs` route (`FlowRunsPage`). A `type: 'flow'` action whose run pauses at a screen node opens it with `{ flowName, runId, screen }`. The bundle reaches it through the console root's `I18nProvider loadLanguage` (apps/console main.tsx). ⚠️ NOT flipped with it: the container `flows` keeps `planned` + `authorWarn` for its `label` child, which nothing reads yet (#20318), and its `authorHint` now says that `screens` is read and the flow label is not. That bit is group-level and has two readers: @objectstack/lint's warn map, and the CLI i18n coverage gate (`authorWarnedTranslationGroups` in packages/cli i18n-extract.ts), which holds back the whole `flows.*` demand while it is set. Dropping it before the label has a reader would switch on demand for `flows.<flow>.label` too, so it drops when #20318 lands (seat ruling on #20296). RE-VERIFIED 2026-10-02 (#17306) at the `.objectui-sha` pin 31971ff1e, which carries objectui 81778b955 (REST compare 81778b955...31971ff1e answers `ahead`, `behind_by 0`): the per-field face gained `inlineHelpText` beside `label` and `placeholder`, the screen field's own help-text key. Every objectui pointer in `evidence` and `producer` was re-read at that pin and repinned from f8a9d0fb. `overlayFieldCopy` imports the spec's key list rather than retyping it, so the new key needed no objectui edit, and `ScreenView` draws the help text under the control (objectui#9248). The status is unchanged: this row was already `live`. 2026-10-05: the `⚠️ NOT flipped with it` clause above is superseded. The `label` child is `live` now (objectui's FlowRunner reads it at the pin 0abd4f9f8), so the container flipped to `live` and dropped `authorWarn` and `authorHint`; see the container note. 2026-10-09 (#22507): the per-field face gained `options.<value>` — a screen field's option labels, keyed by each option's value read as text (`flowScreenFieldOptionKey`) and resolved by `resolveFlowScreenFieldOptions`. It is NOT in `FLOW_SCREEN_FIELD_COPY_KEYS` (a map over `options[]`, not one string), so `overlayFieldCopy` does not reach it, and no objectui code reads it at main 20c6d351a: the option labels are declared ahead of their reader, the downstream runner change. The row stays `live` for the heading and the three string keys, which are unchanged; the one-drill-level boundary keeps the option map off a row of its own. 2026-10-10 (#22507, maintainer ruling A): the screen face gained `description`, and the screen's heading and body text moved to the ENGINE. Both are `{{ }}` templates the executor renders per run, so the `screen` executor picks each translated template in the run's locale through the one `i18n` channel the refusal message is read through, before it fills the holes; the served `ScreenSpec` arrives translated, and the authored template renders when the bundle has none. The body text is translated only where the screen authors one. objectui's `localizeScreen` still overlays the heading through `resolveFlowScreenTitle` at the `.objectui-sha` pin 20c6d351a; that overlay is retired by the ruling's consumer half (filed into objectui#12075). Until it lands the runner replaces a served heading with the translated template, which draws a hole literally exactly where it did before this change, so the window adds no regression. The per-field copy stays client-side, read by `overlayFieldCopy` as cited. The row stays `live`: the engine reads both screen keys in-repo, and objectui reads the field keys. objectui's `FlowRunner` overlay of `flows.<flow>.screens` on the screen it draws was read at objectui @f8a9d0fb (the citation moved out of packages/spec/src/system/i18n-resolver.ts, #23434)."
"note": "FLIPPED planned → live 2026-09-27 (#20296). It was PLANNED with its container under the #7646 contract-first split: the spec declared the vocabulary and the screen-flow runner half was a downstream objectui card. That half has landed client-side, the side #11287 picked (objectui#5920, FlowRunner's `localizeScreen`), and the `.objectui-sha` pin f8a9d0fb carries it, so every objectui pointer above was read at the pin this repo builds against. Each read is unchanged at objectui main 256b4c9e. Per-screen heading + per-field copy, keyed by `FlowNode.id` / `ScreenFieldConfig.name`, the identifiers the client already holds as `ScreenSpec.nodeId` / `ScreenFieldSpec.name`. Each key falls back to the authored string on its own. The screen `description` and the runner chrome stay untranslated here by ruling. Deeper conventions (`screens.<id>.title`, `screens.<id>.fields.<name>.{label,placeholder,inlineHelpText}`) are governed by the runner and the spec's `FLOW_SCREEN_COPY_KEYS` / `FLOW_SCREEN_FIELD_COPY_KEYS`, not by ledger rows: the one-drill-level boundary this ledger's type note states. MOUNT CHAIN, closed by hand at the pin: `FlowRunner` is mounted by `useConsoleActionRuntime`'s dialogs (the console root `ConsoleShell` renders them, and ObjectView / DeclaredActionsBar each run their own runtime), by `RecordDetailView`, and by the console's `developer/flow-runs` route (`FlowRunsPage`). A `type: 'flow'` action whose run pauses at a screen node opens it with `{ flowName, runId, screen }`. The bundle reaches it through the console root's `I18nProvider loadLanguage` (apps/console main.tsx). ⚠️ NOT flipped with it: the container `flows` keeps `planned` + `authorWarn` for its `label` child, which nothing reads yet (#20318), and its `authorHint` now says that `screens` is read and the flow label is not. That bit is group-level and has two readers: @objectstack/lint's warn map, and the CLI i18n coverage gate (`authorWarnedTranslationGroups` in packages/cli i18n-extract.ts), which holds back the whole `flows.*` demand while it is set. Dropping it before the label has a reader would switch on demand for `flows.<flow>.label` too, so it drops when #20318 lands (seat ruling on #20296). RE-VERIFIED 2026-10-02 (#17306) at the `.objectui-sha` pin 31971ff1e, which carries objectui 81778b955 (REST compare 81778b955...31971ff1e answers `ahead`, `behind_by 0`): the per-field face gained `inlineHelpText` beside `label` and `placeholder`, the screen field's own help-text key. Every objectui pointer in `evidence` and `producer` was re-read at that pin and repinned from f8a9d0fb. `overlayFieldCopy` imports the spec's key list rather than retyping it, so the new key needed no objectui edit, and `ScreenView` draws the help text under the control (objectui#9248). The status is unchanged: this row was already `live`. 2026-10-05: the `⚠️ NOT flipped with it` clause above is superseded. The `label` child is `live` now (objectui's FlowRunner reads it at the pin 0abd4f9f8), so the container flipped to `live` and dropped `authorWarn` and `authorHint`; see the container note. 2026-10-09 (#22507): the per-field face gained `options.<value>` — a screen field's option labels, keyed by each option's value read as text (`flowScreenFieldOptionKey`) and resolved by `resolveFlowScreenFieldOptions`. It is NOT in `FLOW_SCREEN_FIELD_COPY_KEYS` (a map over `options[]`, not one string), so `overlayFieldCopy` does not reach it, and no objectui code reads it at main 20c6d351a: the option labels are declared ahead of their reader, the downstream runner change. The row stays `live` for the heading and the three string keys, which are unchanged; the one-drill-level boundary keeps the option map off a row of its own. 2026-10-10 (#22507, maintainer ruling A): the screen face gained `description`, and the screen's heading and body text moved to the ENGINE. Both are `{{ }}` templates the executor renders per run, so the `screen` executor picks each translated template in the run's locale through the one `i18n` channel the refusal message is read through, before it fills the holes; the served `ScreenSpec` arrives translated, and the authored template renders when the bundle has none. The body text is translated only where the screen authors one. objectui's `localizeScreen` still overlays the heading through `resolveFlowScreenTitle` at the `.objectui-sha` pin 20c6d351a; that overlay is retired by the ruling's consumer half (filed into objectui#12075). Until it lands the runner replaces a served heading with the translated template, which draws a hole literally exactly where it did before this change, so the window adds no regression. The per-field copy stays client-side, read by `overlayFieldCopy` as cited. The row stays `live`: the engine reads both screen keys in-repo, and objectui reads the field keys. objectui's `FlowRunner` overlay of `flows.<flow>.screens` on the screen it draws was read at objectui @f8a9d0fb (the citation moved out of packages/spec/src/system/i18n-resolver.ts, #23434). 2026-10-25 (#25742): the `evidence` pointer at service-automation's `engine.ts#renderFlowTextSlot` is dropped. That (entry, file) pair anchored only through a comment, which #25734 moved to `run-resume.ts`; `engine.ts` now keeps a delegating `renderFlowTextSlot` over `node-text-rendering.ts`. The `screen-nodes.ts#registerScreenNodes` pointer names the key and still anchors. `verifiedAt` is unchanged: nothing else on this row was re-read."
},
"refusals": {
"status": "live",
Expand Down
Loading