Part of #14122 · blocks #14512 · split out of #15210 (the by-shape sweep record — read it for the sweep method and the triaged false positives) · acceptance pin is #15004.
Reader half of the program ruled on #14512 (comment 5528589044). The artifact stays additive through this card.
The site
file:line |
Reads |
What an option-B artifact does to it |
packages/plugins/plugin-dev/src/dev-plugin.ts:526 |
options.stack.translations |
the I18nServicePlugin auto-detect never fires, so a multi-package app boots os dev with the in-memory i18n fallback instead of the file-based service |
Reached through the documented construction new DevPlugin({ stack: config }) (packages/plugins/plugin-dev/src/index.ts:36).
What the failure looks like
Not a crash and not an empty screen — the app boots and serves. Translations resolve against the in-memory fallback instead of the file-based service, so a developer sees keys or stale strings where the app declared real copy, on the os dev path specifically. It reads as "the translations are wrong" rather than "a collection went missing", which is what makes it worth a card rather than a footnote.
The pin, already on main
#15004 merged. Read all three before writing implementation:
packages/cli/test/fixtures/option-b-collection-zoo.ts
packages/cli/test/fixtures/option-b-reader-probe.ts
packages/cli/test/option-b-reader-acceptance.pin.test.ts
⚠️ This site has no row in OPTION_B_LOSSES today — the by-shape sweep found it, not the pin. So this card does both halves: add the row that ledgers the loss, then fix the reader and delete it. Do it in that order and say so in the PR — a row that never existed is a row nobody can check you against.
The pin asserts by set equality: adding a row for a loss already fixed goes red just as surely as leaving a row for one that is not. ⛔ Never weaken the pin to pass — do not relax set equality, stop asserting a subsystem, or add rows to silence a red.
Acceptance
Sibling cards: #15005 (@objectstack/runtime), #15006 (@objectstack/cli), #15007 (@objectstack/plugin-security, landed as PR #15226), #15229 (5/4, @objectstack/verify). Emitter half: #14512.
Part of #14122 · blocks #14512 · split out of #15210 (the by-shape sweep record — read it for the sweep method and the triaged false positives) · acceptance pin is #15004.
Reader half of the program ruled on #14512 (comment 5528589044). The artifact stays additive through this card.
The site
file:linepackages/plugins/plugin-dev/src/dev-plugin.ts:526options.stack.translationsI18nServicePluginauto-detect never fires, so a multi-package app bootsos devwith the in-memory i18n fallback instead of the file-based serviceReached through the documented construction
new DevPlugin({ stack: config })(packages/plugins/plugin-dev/src/index.ts:36).What the failure looks like
Not a crash and not an empty screen — the app boots and serves. Translations resolve against the in-memory fallback instead of the file-based service, so a developer sees keys or stale strings where the app declared real copy, on the
os devpath specifically. It reads as "the translations are wrong" rather than "a collection went missing", which is what makes it worth a card rather than a footnote.The pin, already on main
#15004 merged. Read all three before writing implementation:
packages/cli/test/fixtures/option-b-collection-zoo.tspackages/cli/test/fixtures/option-b-reader-probe.tspackages/cli/test/option-b-reader-acceptance.pin.test.tsOPTION_B_LOSSEStoday — the by-shape sweep found it, not the pin. So this card does both halves: add the row that ledgers the loss, then fix the reader and delete it. Do it in that order and say so in the PR — a row that never existed is a row nobody can check you against.The pin asserts by set equality: adding a row for a loss already fixed goes red just as surely as leaving a row for one that is not. ⛔ Never weaken the pin to pass — do not relax set equality, stop asserting a subsystem, or add rows to silence a red.
Acceptance
translationsthroughresolveArtifactPackageOrder(@objectstack/core, ADR-0130 D4+D5, since fix(metadata): register a packages[] artifact per package at the metadata door so every object has one owner across every door (#14599) #14643) — flattened top level first, so today's additive artifact answers bit-identically andpackages[]only supplies what the top level lacks.config.packagesdirectly — a second traversal is a second ordering.DevPlugintakes its stack from a caller-supplied object (options.stack), not from a load boundary this repo owns. Check whether the auto-detect should also fire when a caller passes an already-composed multi-package config, and say what you found — the enumeration in A multi-package artifact serializes its metadata twice — the flattened top level and everypackages[i]body carry the same definitions #14512 comment 5523741937 lists this as one of three construction sites with no load step to fold at.composeStacks,packages/spec/src/stack.zod.ts, or what any command emits.content/docs/releases/.Sibling cards: #15005 (
@objectstack/runtime), #15006 (@objectstack/cli), #15007 (@objectstack/plugin-security, landed as PR #15226), #15229 (5/4,@objectstack/verify). Emitter half: #14512.