Uh oh!
There was an error while loading. Please reload this page.
feat(spec): FLOW_SCREEN_COPY_KEYS resolver family for screen-flow copy (#7646 recommendation B) - #11484
Conversation
#7646 recommendation B) translateFlow / resolveFlowScreenTitle + the FLOW_SCREEN_COPY_KEYS / FLOW_SCREEN_FIELD_COPY_KEYS shared key lists in system/i18n-resolver.ts, mirroring the page family's conventions. Deliberately NOT registered in METADATA_DOCUMENT_TRANSLATORS: that table reaches the REST boundary by itself and would stand up a shipped reader while the flows liveness rows are planned; the runner wiring and the ledger flip ride the downstream cards. Off-spec bundle keys the schema refuses (description, help) are ignored, never overlaid — pinned. export-origins regenerated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T9cDbY2NBiVJWYx3BpWfH2
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T9cDbY2NBiVJWYx3BpWfH2
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin a9b15b5179573c910e4ead8a9b19c032bd4c29ce && git checkout a9b15b5179573c910e4ead8a9b19c032bd4c29ce
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin a58eac3e274f3b85d6ca27d7447d43759756d661 f89b869a7fbdc4ad524aefcdc428d3c470784099 && git checkout -B drift-repro a58eac3e274f3b85d6ca27d7447d43759756d661 && git merge --no-ff f89b869a7fbdc4ad524aefcdc428d3c470784099
node scripts/docs-audit/affected-docs.mjs --json a58eac3e274f3b85d6ca27d7447d43759756d661
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11287
The measurement (why this exists)
TranslationData.flows— the screen-flow copy vocabulary #7646 declared and PR #7763 shipped — had no reader anywhere: the issue's probe showedi18n.t("flows.lead_conversion.screens.screen_1.title", "zh-CN")resolving to转化详情from the real zh-CN bundle while the real wizard rendered "Conversion Details" in every locale. The carrier and the tree already work; only the resolver family was missing (deliberately deferred by #7763 because another change was in flight oni18n-resolver.ts, since landed).What the family covers (the spec half only)
New exports in
packages/spec/src/system/i18n-resolver.ts, mirroring the page family's conventions (PAGE_COMPONENT_COPY_KEYS/translatePage):translateFlow(flow, bundle, opts)— metadata-document overlay: the flow's ownlabel(keyflows.{flow_name}.label), and for everytype: 'screen'node with an id, the screen heading (flows.{flow_name}.screens.{node_id}.title) and per-field copy (…fields.{field_name}.label/.placeholder). The translated title is written toconfig.titleeven when the author relied on the node-label fallback — the executor builds the wire title asconfig.title ?? node.label, so one key covers whichever the runner draws (the schema's own design note). Input never mutated; untouched nodes/fields keep reference identity.resolveFlowScreenTitle(bundle, flowName, screen, opts)— the piecemeal half for a caller already holding aScreenSpec(nodeIdaddressing — the identifier the client is guaranteed to hold, since it correlates a resume to its pause point).FLOW_SCREEN_COPY_KEYS(['title']) andFLOW_SCREEN_FIELD_COPY_KEYS(['label', 'placeholder']) — the one list the overlay and the CLI's future skeleton extractor both import; pinned againstTranslationDataSchemaintranslation.test.tsso neither can drift.FlowLike,FlowNodeLike,FlowScreenLike,FlowScreenFieldLike,FlowScreenCopyKey,FlowScreenFieldCopyKey. Complete TSDoc throughout, matching the module's conventions.Deliberately not covered, measured against the declared vocabulary: screen
descriptionis guidance-refused by the schema (outside the recorded #7646 ruling's enumeration), so the resolver does not read it — the dispatch's measured-surfaces list names it, and per instructions I stopped on that key and reported instead of inventing (see the report's open question). Fieldhelp/optionsand runner chrome (Cancel/Submit/toast) likewise stay out, per the schema face and the #7646 maintainer ruling.Fallback semantics (the sibling families' order, not a new one)
Lookup per key across
localethenfallbackChain(default['en']), key by key — a partially translated locale still falls back per key, exactly likelookupPageComponentCopy. When no locale answers, the authored source string stands (helpers never throw). Off-spec bundle entries carrying keys the schema refuses (description,help) are ignored, never overlaid — pinned by tests, mirroringtranslatePage's retired-submitLabelnegative pin.Why the ledger rows stay
plannedThis PR is resolver-only: no shipped runner reads the group yet, so
flows/label/screensliveness rows keepplanned+authorWarn(untouched here;check:livenessgreen).translateFlowis deliberately not registered intranslateMetadataDocument's dispatch table — that registration reaches the REST metadata boundary by itself (TRANSLATABLE_METADATA_TYPESdrives@objectstack/rest), which would stand up a shipped reader while the rows sayplanned. The absence is pinned by a test so adding it is a deliberate act on the runner card. The runner application (item 2) and the CLI coverage bucket (item 3) are follow-up cards the PM files at ACCEPT; the ledger flip rides the runner card. The lint-walk defect that silencesauthorWarnis tracked separately as #11288 and is untouched here.Verification (union re-run at final commit
f89b869a7f)pnpm --filter @objectstack/spec test→Test Files 419 passed (419) / Tests 11176 passed (11176)atf89b869a7f(verdict lineos-verify-lock: VERDICT command-exit 0).pnpm --filter @objectstack/spec typecheck→ clean; test layercheck:test-typecheck: OK — 55 file(s) / 263 error(s) held in test-typecheck-debt.json(pre-existing shrink-only debt, unchanged).pnpm --filter @objectstack/spec check:generated→✓ All 14 generated artifacts are up to date.atf89b869a7f(aftergen:export-origins+gen:api-surfacefor the new exports — both regenerated artifacts committed).git restore --source=origin/main, trap-guarded restore): with the family reverted, the two pinned test files went red — 11 failed (translateFlow is not a function× the 10 new resolver tests, plus the schema↔list pin) — and restore returned them green. Mutation proven on disk by marker grep (0 with the family removed, 4 restored); the tests resolve./i18n-resolverrelatively fromsrc, no dist in the path, so neither leg needed a rebuild.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, derived atfa3cde3c8a, re-checked content-identical atf89b869a7f): all runnable gates green —check:merge-driver,check:objectui-changeset,check:published-files,check:slot-lookup,check:spec-parsed-alias,check:test-source-alias,check:type-source-resolution,check:changeset-gate-self-tests,check:nul-bytes,check:cross-package-test-inputs,check:query-options-erasure,check:engine-double-contract,check:where-matcher,check:type-check-coverage,check:adr-0087-registration,check-changeset-no-major,check-empty-changeset,check-ci-filter-parity,check-plugin-teardown-shape,check:empty-state,check:variant-docs,check:liveness,check:strictness-ledger,check:doc-formula-expressions(after building its@objectstack/formuladep),docs-audit/check-affected-docs(exit 0). Declared not run locally:check:type-check-debtandcheck-dev-prereqsrequire the full 67-package workspace closure built (fresh worktree; whole-workspace build is CI's run — the spec-package half of the type-check ratchet,check:test-typecheck, ran green above);check:react-declaration-parityneeds objectui'ssdui.manifest.json, which this repo cannot produce (on-demand gate by ruling).minorfor@objectstack/spec(additive surface widening; not breaking —check:adr-0087-registrationgreen with no marker required).Generated by Claude Code