Commit 88a35c2
* test(cli,plugin-dev): ledger the i18n auto-detect's option-B loss, RED first (#15232)
The by-shape sweep found this site, not the #15004 pin, so `OPTION_B_LOSSES`
carries no row for it. This commit adds the row and nothing else: the reader
is deliberately still top-level-only, so the pin goes RED naming a subsystem
that loses a collection the ledger does not carry. The fix, and the deletion
of the row, land in the next commit — a row that never existed is a row
nobody can check the fix against.
The row calls the SHIPPED decision rather than re-reading `stack.translations`:
`devI18nPluginOptions` is extracted from `DevPlugin.init`'s 3b block, verbatim
in behaviour, and exported so the probe measures what the plugin itself
decides. `packages/cli` reaches it through an anchored vitest alias to source
(the sanctioned remedy — `KNOWN_UNALIASED_TEST_IMPORTS` is shrink-only) and a
star-less `paths` rule, so the run and the type verdict agree about which
artifact is under test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
* test(cli): ledger the plugin-dev i18n loss so the fix has something to check against (#15232)
The row added in the previous commit went RED naming a subsystem the ledger
does not carry — the exact failure #15004 exists to make loud:
B2 · plugin-dev I18nServicePlugin auto-detect over the caller-supplied
stack · translations
This records it, which turns the pin green at 25 rows and makes the loss a
measured fact rather than an argument. The next commit fixes the reader and
deletes this line again, so `OPTION_B_LOSSES` ends this branch exactly as it
started it — the ledger never grows.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
* fix(plugin-dev): the i18n auto-detect resolves `translations` from `packages[]` (#15232)
`DevPlugin.init`'s 3b block read `options.stack.translations` alone, so a
multi-package app under ADR-0130 D4's option-B shape — every definition
carried once inside `packages[]`, no flattened top level — was read as
declaring no copy at all. `I18nServicePlugin` was never registered and `os dev`
served message keys, or last release's strings, from the core in-memory
fallback. Nothing threw and nothing logged.
The detection now reads the flattened top level FIRST and consults each
package body only where that came back falsy, in the order
`resolveArtifactPackageOrder` (`@objectstack/core`, ADR-0130 D4+D5) registers
them. Today's additive artifact answers bit-identically: the original
expression `Array.isArray(t) && t.length > 0` is preserved rather than
re-expressed, and it short-circuits before `packages[]` is touched. A stack
with no `packages` key never reaches the traversal at all, so its
`translations` is still read exactly once. A malformed `packages` raises the
same ADR-0112 envelope the registration path raises for it.
The ledger row added two commits ago goes green and is deleted, so
`OPTION_B_LOSSES` ends this branch at the 24 rows it started with.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
* test(plugin-dev): drop the redundant driver-memory mock the census ledger locks (#15232)
`check:driver-memory-census` counts `vi.mock` as a DECLARATION, and that
package's consumer set is locked by maintainer ruling (#5499 froze investment,
#5704 / #6664 ruled each remaining consumer at two). The mock copied in from
this package's sibling harnesses made this file a third consumer.
⛔ Not ledgered — MIGRATED, which here means deleted: the line was redundant.
`dev-plugin.ts` has exactly one `import('@objectstack/driver-memory')` and it
sits inside `if (enabled('driver'))`, while both boots in this file pass
`services: { driver: false }`, so the specifier was never reached. Measured
rather than argued: with the line gone the suite is unchanged at
`7 passed (7) / 68 passed (68)`, both BOOT cases green (5ms / 1ms), and the
census gate returns to `OK — 2 ruled consumers` with its ledger untouched.
A comment stands where the mock was, so the next author copying the sibling
harness does not re-add it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
* fix(plugin-dev): degrade on a refused package list, ask the cheap limbs first, document what throws (#15232)
Contract review (#15282) measured three things wrong with the first cut, and
this is all three:
1. REACHABILITY. "Today's artifacts never reach the packages[] pass" was FALSE.
The flattened read short-circuits only when `translations` is non-empty, so
every multi-package stack that does not translate reaches the gate on every
boot. The claim is corrected wherever it appeared and pinned by a case that
counts the reads (2 when the gate is reached, 0 when it short-circuits).
2. A REPRODUCED REGRESSION. A package manifest still carrying authoring glob
`objects` is refused by `ArtifactPackageSchema` by design; such a project
boots today and would have stopped booting on this reader — thrown from the
block whose only job is deciding whether to register a translation service,
while `new AppPlugin(...)` twenty lines above degrades the very same refusal
to a log line. That inversion is indefensible, so `DevPlugin` now catches,
prints its own line naming the METADATA defect and carrying the envelope
verbatim, and boots on the in-memory fallback. ⛔ Not `reportOptionalLoadFailure`
(it names a PACKAGE — the #7926 mis-attribution) and ⛔ never silent.
`dev-plugin.ts`'s AppPlugin try/catch is untouched: whether DevPlugin should
refuse malformed metadata at all is a separate maintainer question.
3. EVALUATION ORDER. The three limbs are now asked cheapest-first, so a stack
that already declares its locales in `i18n` is no longer refused over a
`packages` list its answer never needed. `||` is commutative — the answer is
unchanged, only what can throw is.
Both functions gain `@throws`, including the BARE `Error` (no code, no status)
`resolvePluginOrder` raises for a dependency cycle, now asserted by a case.
The guard divergence with the sibling reader (`Array.isArray` vs absent-key) is
recorded as a program-level split rather than unilaterally aligned.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8a1bad8 commit 88a35c2
10 files changed
Lines changed: 802 additions & 11 deletions
File tree
- .changeset
- packages
- cli
- test/fixtures
- plugins/plugin-dev/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
129 | 129 | | |
130 | 130 | | |
131 | 131 | | |
| 132 | + | |
132 | 133 | | |
133 | 134 | | |
134 | 135 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
62 | 63 | | |
63 | 64 | | |
64 | 65 | | |
| 66 | + | |
65 | 67 | | |
66 | 68 | | |
67 | 69 | | |
| |||
364 | 366 | | |
365 | 367 | | |
366 | 368 | | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
367 | 384 | | |
368 | 385 | | |
369 | 386 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
154 | 161 | | |
155 | 162 | | |
156 | 163 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
618 | 618 | | |
619 | 619 | | |
620 | 620 | | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
621 | 638 | | |
622 | 639 | | |
623 | 640 | | |
| |||
0 commit comments