Skip to content

Commit 42b0ab5

Browse files
committed
test(metadata-protocol): pin the unshipped-locale write on a fresh install, before the pair is ensured
Claude-Session: https://claude.ai/code/session_01Utp6CYeyrEJGAte4R8B7un Co-authored-by: Claude <noreply@anthropic.com>
1 parent 04f36b6 commit 42b0ab5

1 file changed

Lines changed: 48 additions & 3 deletions

File tree

‎packages/metadata-protocol/src/protocol.named-base-overlay-write.test.ts‎

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,12 @@ function matches(row: Row, where: Record<string, unknown> = {}): boolean {
105105
});
106106
}
107107

108-
function makeProtocol() {
108+
/**
109+
* `pairInstalled: false` boots the base with no pair yet: a fresh install,
110+
* before anything ensured `<base>.custom` (the ensure door, or the ceremony's
111+
* step 1, creates it on the first write that needs it).
112+
*/
113+
function makeProtocol({ pairInstalled = true }: { pairInstalled?: boolean } = {}) {
109114
const tables = new Map<string, Row[]>();
110115
const table = (n: string) => {
111116
if (!tables.has(n)) tables.set(n, []);
@@ -116,7 +121,8 @@ function makeProtocol() {
116121
const hit = SHIPPED.find((i) => i.type === type && i.name === name);
117122
return hit ? { ...ITEMS.find((i) => i.type === type && i.name === name)?.body(PACKAGED), name, label: PACKAGED, _packageId: hit.pkg, _provenance: 'package' } : undefined;
118123
};
119-
const packageRecord = (id: string) => (MANIFESTS[id] ? { manifest: { id, ...MANIFESTS[id] } } : undefined);
124+
const installed = (id: string) => MANIFESTS[id] !== undefined && (pairInstalled || id !== PAIR);
125+
const packageRecord = (id: string) => (installed(id) ? { manifest: { id, ...MANIFESTS[id] } } : undefined);
120126
const engine: any = {
121127
// A booted code package is read-only (`isWritablePackage` reads `manifests` first).
122128
manifests: new Map([[BASE, {}], [NO_PAIR_BASE, {}], [NO_PAIR_ID_BASE, {}], [NO_VERSION_BASE, {}]]),
@@ -161,7 +167,7 @@ function makeProtocol() {
161167
getItem: (type: string, name: string) => artifact(type, name),
162168
getObject: () => undefined,
163169
getPackage: packageRecord,
164-
getAllPackages: () => Object.keys(MANIFESTS).map(packageRecord),
170+
getAllPackages: () => Object.keys(MANIFESTS).filter(installed).map(packageRecord),
165171
isPackageDisabled: () => false,
166172
getArtifactItem: artifact,
167173
applyNavContributions: (a: unknown) => a,
@@ -433,6 +439,45 @@ describe('CONTROLS: every step the fix takes, failing, leaves the write naming t
433439
});
434440
});
435441

442+
describe('a fresh install, the pair not yet ensured: an email template at a locale the base does not ship stays open (ADR-0146 D11)', () => {
443+
// The close asks the override write gate about the declared body written
444+
// into the pair. Before the pair exists, that question is the one the
445+
// ensured pair would meet (its closure: the base and what the base
446+
// reaches), never "no such package, not concerned" read as "admitted".
447+
const email = ITEMS.find((i) => i.type === 'email_template')!;
448+
const unshipped = (label: string) => ({ ...email.body(label), locale: 'fr-FR' });
449+
450+
it('the package-less save is accepted and served as the environment\'s own member', async () => {
451+
const { protocol, rows } = makeProtocol({ pairInstalled: false });
452+
453+
const saved = await protocol.saveMetaItem({ type: email.type, name: email.name, item: unshipped('Bienvenue') });
454+
455+
expect(saved).toMatchObject({ success: true });
456+
expect(rows(email.type, email.name)).toEqual([{ package_id: null, state: 'active', label: 'Bienvenue' }]);
457+
});
458+
459+
it('the save naming the base is accepted, as it is with the pair installed', async () => {
460+
const { protocol, rows } = makeProtocol({ pairInstalled: false });
461+
462+
const saved = await protocol.saveMetaItem({ type: email.type, name: email.name, item: unshipped('Bienvenue'), packageId: BASE });
463+
464+
expect(saved).toMatchObject({ success: true });
465+
expect(rows(email.type, email.name)).toEqual([{ package_id: BASE, state: 'active', label: 'Bienvenue' }]);
466+
});
467+
468+
it('CONTROL: a member the base ships is still closed onto the pair, naming it, with the pair not yet ensured', async () => {
469+
const { protocol, rows } = makeProtocol({ pairInstalled: false });
470+
471+
const packageless = await thrown(() => protocol.saveMetaItem({ type: email.type, name: email.name, item: email.body('Mine') }));
472+
const namedBase = await thrown(() => protocol.saveMetaItem({ type: email.type, name: email.name, item: email.body('Mine'), packageId: BASE }));
473+
474+
expect(resolveThrownHttpError(packageless)).toMatchObject({ status: 403, code: 'NOT_OVERRIDABLE' });
475+
expect(String(packageless.message)).toContain(`'${PAIR}' (?package=${PAIR})`);
476+
expectClosed(namedBase, email.type, email.name, 'save');
477+
expect(rows(email.type, email.name)).toEqual([]);
478+
});
479+
});
480+
436481
describe('the commit doors: restoring a row bound to the base is closed, removing one stays open (#29390)', () => {
437482
/** Each commit a second apart, so the package rollback's "strictly newer" reads an order. */
438483
let clock = Date.parse('2026-11-02T00:00:00.000Z');

0 commit comments

Comments
 (0)