Blocked-by: objectstack-ai/objectstack#11485
Filed by the domain:cli execution seat as the downstream half of #11485 (PR #11615), per the
multi-repo rule that the seat accepting a PR files the consumer-side follow-up rather than trusting
it to memory.
Named reader: the repo:hotcrm execution seat, at its per-round patrol. This card is the reason
that seat will see the finding before a red gate does.
⚠️This card belongs in objectstack-ai/hotcrm, not here. Issues live in the repo where the
fix lands, and this fix is HotCRM metadata. It is filed in objectstack as a seam card because
the filing session's GitHub scope does not reach the hotcrm repo. The repo:hotcrm seat should
move it (transfer, or re-file with an origin header and close this one as moved) as its first
action, not work it from here.
What changes for HotCRM
#11485 gives @objectstack/cli a flow bucket in its i18n coverage taxonomy. Before it,
collectExpectedEntries had no pass over flows, so os lint's i18n/missing-* family could not
report a screen-flow copy gap at all and os i18n extract never scaffolded the keys.
The measurement that motivated the card was taken on HotCRM: it reported 0 i18n/missing-*
issues on a tree whose six screen dialogs rendered English in all four locales. The gate was
green because the surface was invisible to it, not because the app was translated.
Once the new CLI reaches this repo, those strings become reportable:
flows.<flow>.label
flows.<flow>.screens.<node_id>.title
flows.<flow>.screens.<node_id>.fields.<field>.label
flows.<flow>.screens.<node_id>.fields.<field>.placeholder
Severity is warning, so nothing breaks by default — the exit code only moves under
--i18n-strict. This is a card, not an incident.
What "done" looks like
Two honest endings, and the seat picks by measurement rather than by which is cheaper:
- Translate them.
os i18n extract now scaffolds the whole flows.<flow>.screens.<node>.…
skeleton for every requested locale, so the vocabulary is discoverable for the first time — an
author previously had no way to even learn the key names. This is the ending that matches the
charter: a sample app that ships untranslated wizard copy teaches every AI that copies it to do
the same. - Record the debt deliberately, if translating four locales of wizard copy is out of appetite
right now — but as an explicit, visible ledger entry with a date and a reason, never as silence.
⛔ What is not an ending: turning the bucket off, filtering i18n/missing-flow out of the
report, or narrowing the locale set to make the count zero. The finding is the point.
Boundary — this is HotCRM's work, not a platform gap
Per the hotcrm charter (maintainer 2026-08-20: 「平台相关的功能应该在平台中实现」), the platform half
is already done in #11485 and needs nothing further. If working this card surfaces something the
platform cannot express — a screen-copy key the resolver reads but the extractor cannot scaffold,
say — that is a platform card filed at destination in objectstack, with this card flipped
pm:blocked behind it. ⛔ Do not work around it inside the sample app.
Related
Blocked-by: objectstack-ai/objectstack#11485Filed by the
domain:cliexecution seat as the downstream half of #11485 (PR #11615), per themulti-repo rule that the seat accepting a PR files the consumer-side follow-up rather than trusting
it to memory.
Named reader: the
repo:hotcrmexecution seat, at its per-round patrol. This card is the reasonthat seat will see the finding before a red gate does.
What changes for HotCRM
#11485 gives
@objectstack/cliaflowbucket in its i18n coverage taxonomy. Before it,collectExpectedEntrieshad no pass overflows, soos lint'si18n/missing-*family could notreport a screen-flow copy gap at all and
os i18n extractnever scaffolded the keys.The measurement that motivated the card was taken on HotCRM: it reported 0
i18n/missing-*issues on a tree whose six screen dialogs rendered English in all four locales. The gate was
green because the surface was invisible to it, not because the app was translated.
Once the new CLI reaches this repo, those strings become reportable:
Severity is
warning, so nothing breaks by default — the exit code only moves under--i18n-strict. This is a card, not an incident.What "done" looks like
Two honest endings, and the seat picks by measurement rather than by which is cheaper:
os i18n extractnow scaffolds the wholeflows.<flow>.screens.<node>.…skeleton for every requested locale, so the vocabulary is discoverable for the first time — an
author previously had no way to even learn the key names. This is the ending that matches the
charter: a sample app that ships untranslated wizard copy teaches every AI that copies it to do
the same.
right now — but as an explicit, visible ledger entry with a date and a reason, never as silence.
⛔ What is not an ending: turning the bucket off, filtering
i18n/missing-flowout of thereport, or narrowing the locale set to make the count zero. The finding is the point.
Boundary — this is HotCRM's work, not a platform gap
Per the hotcrm charter (maintainer 2026-08-20: 「平台相关的功能应该在平台中实现」), the platform half
is already done in #11485 and needs nothing further. If working this card surfaces something the
platform cannot express — a screen-copy key the resolver reads but the extractor cannot scaffold,
say — that is a platform card filed at destination in
objectstack, with this card flippedpm:blockedbehind it. ⛔ Do not work around it inside the sample app.Related
validate-translation-referenceshas noflowsleg — an authored key naming a flow, screen node or field that does not exist warns nobody #11608 —packages/lint'svalidate-translation-referenceshas noflowsleg, so a bundle naminga nonexistent flow, screen node or field reports nothing. Independent of this card; relevant if a
hand-authored bundle is written here rather than scaffolded.
TranslationData.flows— a screen flow still renders its authored English in every locale (the runner half #7646 deferred) #11287 — where the bundle'sflowsgroup and its resolver came from.