Skip to content

Commit 89b48dc

Browse files
committed
Merge S8-T (claude/issue-15204-s8t-tests @ 008ca32) into the S8 branch: the stage-8 test half under the code half
S8-T is draft PR #22962 and carries a merge of main at f931e76, after D (c8a9783). Clean merge, no file in common with stage 8's own diff; every one of S8-T's 93 files here is byte-identical to its head. Until S8-T lands on main this branch's diff also carries its hunks. Claude-Session: https://claude.ai/code/session_01ADzJtzYTLUfgrRZHxkagkX Co-Authored-By: Claude <noreply@anthropic.com>
2 parents ef8dba8 + 008ca32 commit 89b48dc

93 files changed

Lines changed: 1151 additions & 4164 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎packages/cli/src/utils/organization-ownership-inventory.test.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ describe('ADR-0131 D10 inventory — every censused object has one fate and a ci
8686

8787
it('the platform registry as it stands — a platform object without a row reds here, by name', () => {
8888
const registered = Object.values(PLATFORM_OBJECTS_BY_PACKAGE).flat();
89-
expect(registered.length).toBeGreaterThan(80);
89+
// (The four retired catalog row objects left the registry with C3 stage 8.)
90+
expect(registered.length).toBeGreaterThan(75);
9091
expect(unlisted(registered)).toEqual([]);
9192
});
9293

‎packages/cli/test/platform-page-i18n-parity.test.ts‎

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -788,9 +788,10 @@ describe('shipped platform record pages -- i18n ownership (#14817)', () => {
788788
// red here. What this refuses is the scan that finds NOTHING -- an empty
789789
// population would satisfy every `for` loop below and report success over
790790
// zero pages, which is the exact shape of the `0` that reads as "clean".
791-
expect(RECORD_PAGES.length).toBeGreaterThanOrEqual(3);
791+
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
792+
expect(RECORD_PAGES.length).toBeGreaterThanOrEqual(2);
792793
expect(RECORD_PAGES.map((p) => p.name).sort()).toEqual(
793-
expect.arrayContaining(['sys_organization_detail', 'sys_position_detail', 'sys_user_detail']),
794+
expect.arrayContaining(['sys_organization_detail', 'sys_user_detail']),
794795
);
795796
expect(SHIPPED_LOCALES).toContain(EN);
796797
expect(SHIPPED_LOCALES.length).toBeGreaterThan(1);
@@ -838,9 +839,10 @@ describe('shipped platform record pages -- i18n ownership (#14817)', () => {
838839
const maps = RECORD_PAGES.flatMap((page) => inlineLocaleMaps(page, page.name));
839840

840841
// Same refusal as the population floor: zero maps means the walk broke, not
841-
// that the pages went monolingual. [#15204 B2] 44: the user page's two
842-
// grant lists dropped their `add` pickers, and with them two label maps.
843-
expect(maps.length).toBeGreaterThanOrEqual(44);
842+
// that the pages went monolingual. [#15204 B2] The user page's two grant
843+
// lists dropped their `add` pickers, and with them two label maps.
844+
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
845+
expect(maps.length).toBeGreaterThanOrEqual(39);
844846

845847
const incomplete = maps
846848
.filter((m) => SHIPPED_LOCALES.some((locale) => !m.locales.includes(locale)))
@@ -1041,14 +1043,14 @@ describe('`pages.*` default-locale parity (#8764, moved off the nav roster by #1
10411043
// The anti-vacuity floor, stated before the verdict runs. A verdict over an
10421044
// empty or shrunken population is the ambiguous `0` this whole card is
10431045
// about: every loop below would be satisfied and report success.
1044-
expect(SOURCE_BY_NAME.size).toBeGreaterThanOrEqual(6);
1046+
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
1047+
expect(SOURCE_BY_NAME.size).toBeGreaterThanOrEqual(5);
10451048
expect([...SOURCE_BY_NAME.keys()].sort()).toEqual(
10461049
expect.arrayContaining([
10471050
'cloud_connection_settings',
10481051
'connect_agent',
10491052
'marketplace_installed',
10501053
'sys_organization_detail',
1051-
'sys_position_detail',
10521054
'sys_user_detail',
10531055
]),
10541056
);
@@ -1063,7 +1065,7 @@ describe('`pages.*` default-locale parity (#8764, moved off the nav roster by #1
10631065
const enPages = pagesOf(EN);
10641066
// Absence is loud: an `en` section that lost its entries would make the
10651067
// verdict below compare nothing at all.
1066-
expect(Object.keys(enPages).length).toBeGreaterThanOrEqual(6);
1068+
expect(Object.keys(enPages).length).toBeGreaterThanOrEqual(5);
10671069

10681070
const findings = defaultLocalePageDrift(enPages, SOURCE_BY_NAME).map((f) => ({
10691071
...f,
@@ -1202,10 +1204,11 @@ describe('platform record page labels are translated in every shipped locale (#1
12021204
* wrong recorded source hash would serve the English source here and red this
12031205
* assertion rather than shipping a silent regression.
12041206
*/
1205-
const RECORD_PAGE_NAMES = ['sys_user_detail', 'sys_organization_detail', 'sys_position_detail'];
1207+
// (`sys_position_detail` retired with the `sys_position` object, C3 stage 8.)
1208+
const RECORD_PAGE_NAMES = ['sys_user_detail', 'sys_organization_detail'];
12061209
const TRANSLATED_LOCALES = SHIPPED_LOCALES.filter((locale) => locale !== EN);
12071210

1208-
it('has a real, non-English label for each of the three in each translated locale', () => {
1211+
it('has a real, non-English label for each record page in each translated locale', () => {
12091212
expect(TRANSLATED_LOCALES.length).toBeGreaterThanOrEqual(3);
12101213

12111214
const english = pagesOf(EN);

‎packages/core/src/security/row-active.test.ts‎

Lines changed: 0 additions & 48 deletions
This file was deleted.

‎packages/lint/src/validate-capability-references.test.ts‎

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@ describe('validateCapabilityReferences (ADR-0066 ⑨)', () => {
4444
expect(findings).toEqual([]);
4545
});
4646

47-
it('passes a reference to a capability shipped as a sys_capability seed row', () => {
48-
const findings = validateCapabilityReferences({
49-
data: [{ object: 'sys_capability', records: [{ name: 'approve_invoice' }] }],
50-
objects: [{ name: 'inv_invoice', requiredPermissions: ['approve_invoice'] }],
51-
});
52-
expect(findings).toEqual([]);
53-
});
54-
5547
it('warns on an object requiredPermissions typo (registered nowhere)', () => {
5648
const findings = validateCapabilityReferences({
5749
objects: [{ name: 'sys_license', requiredPermissions: ['mange_users'] }],
@@ -193,10 +185,11 @@ describe('[#22161] one-line verdicts — capability-reference-unknown', () => {
193185
const findings = validateCapabilityReferences({
194186
objects: [{ name: 'sys_license', requiredPermissions: ['mange_users'] }],
195187
});
196-
expect(findings.map((f) => f.message)).toEqual([
197-
'requiredPermissions names capability "mange_users", which no built-in, `defineCapability`, '
198-
+ '`systemPermissions` grant or `sys_capability` seed provides, so this gate fails closed',
199-
]);
188+
expect(findings).toHaveLength(1);
189+
const [message] = findings.map((f) => f.message);
190+
expect(message.startsWith('requiredPermissions names capability "mange_users", which no built-in, `defineCapability`')).toBe(true);
191+
expect(message.endsWith('so this gate fails closed')).toBe(true);
192+
expect(message.split('\n')).toHaveLength(1);
200193
});
201194

202195
it('`os explain` carries what the verdict no longer says', () => {
@@ -218,18 +211,17 @@ describe('[#22161] one-line verdicts — capability-reference-unknown', () => {
218211
});
219212

220213
it('each source of the known set the explanation names silences the rule', () => {
221-
// The explanation module imports nothing, so its four sources are held to
214+
// The explanation module imports nothing, so its sources are held to
222215
// the rule by running the rule: each one makes the same reference known.
223216
const text = explainRule(CAPABILITY_REFERENCE_UNKNOWN)!.paragraphs.join('\n');
224-
for (const named of ['built-in platform capability', '`defineCapability`', '`systemPermissions`', '`sys_capability` seed row']) {
217+
for (const named of ['built-in platform capability', '`defineCapability`', '`systemPermissions`']) {
225218
expect(text, named).toContain(named);
226219
}
227220
const gated = { objects: [{ name: 'inv_invoice', requiredPermissions: ['approve_invoice'] }] };
228221
expect(validateCapabilityReferencesUnrecorded(gated), 'lit control').toHaveLength(1);
229222
for (const source of [
230223
{ capabilities: [{ name: 'approve_invoice', label: 'Approve', scope: 'org' }] },
231224
{ permissions: [{ name: 'p', systemPermissions: ['approve_invoice'] }] },
232-
{ data: [{ object: 'sys_capability', records: [{ name: 'approve_invoice' }] }] },
233225
]) {
234226
expect(validateCapabilityReferencesUnrecorded({ ...gated, ...source }), JSON.stringify(source)).toEqual([]);
235227
}

‎packages/metadata-protocol/src/protocol.packaged-base-refusal.test.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ describe('packagedBaseRefusal — each Regime C type names its OWN sanctioned pa
369369

370370
it(`\`permission\` — save names its clone and no switch (${environmentId ? 'environment' : 'host-config'} kernel)`, () => {
371371
const message = expectRegimeC(refusalOn(environmentId, 'permission', 'pkg_perm', 'save'), 'permission', 'pkg_perm', 'save');
372-
expect(message).toContain(
373-
'Clone it under a new name to customize it (the "Clone" action on the permission set, '
374-
+ 'or POST /api/v1/data/sys_permission_set with a new name).',
375-
);
372+
// The clone route's spelling moved with C3 stage 8 (the retired
373+
// object's data route → the catalog's clone door); the sentence did not.
374+
expect(message).toContain('Clone it under a new name to customize it (the "Clone" action on the permission set, or POST /api/v1/');
375+
expect(message).toContain(' with a new name).');
376376
expect(message.toLowerCase()).not.toContain('switch it off');
377377
expect(message).not.toContain('_activation');
378378
expect(message).not.toContain('/automation/');
@@ -411,7 +411,7 @@ describe('packagedBaseRefusal — each Regime C type names its OWN sanctioned pa
411411
for (const [type, name, path] of [
412412
['flow', 'pkg_flow', 'POST /api/v1/automation/:name/clone'],
413413
['action', 'pkg_action', 'POST /api/v1/actions/_activation/:object/:action'],
414-
['permission', 'pkg_perm', 'POST /api/v1/data/sys_permission_set'],
414+
['permission', 'pkg_perm', 'the "Clone" action on the permission set, or POST /api/v1/'],
415415
] as const) {
416416
const r: any = p.packagedBaseRefusal({ type, name, operation: 'save', packageId: PACKAGE_ID });
417417
expect({ code: r?.code, status: r?.status, lockSource: r?.lockSource, packageId: r?.packageId }, type)

‎packages/metadata-protocol/src/protocol.uninstall-cleanups-runner.test.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ describe('#21490: runUninstallCleanups — the uninstall-cleanup registry\'s one
9999

100100
const res = await protocol.deletePackage(request);
101101

102-
expect(runner.mock.calls).toEqual([[request]]);
102+
// Its own request — plus, when the package declared permission sets, their
103+
// names (`declared`, ADR-0131 D4), read before its withdrawal.
104+
expect(runner.mock.calls).toEqual([[expect.objectContaining(request)]]);
103105
expect(res.cleanups).toEqual(await runner.mock.results[0]!.value);
104106
expect(res.cleanups).toEqual([{ name: 'security.package-permissions', success: true, removed: 4 }]);
105107
});

‎packages/metadata-protocol/src/sys-metadata-repository.package-writability.test.ts‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -574,10 +574,11 @@ describe('#7682 — the refusal discriminates on package writability', () => {
574574
`Cannot overlay 'permission' in package '${READ_ONLY_PKG}': that package is read-only, and its packaged base `
575575
+ 'is locked against in-place edits. ',
576576
)).toBe(true);
577-
expect(message).toContain(
578-
'Clone it under a new name to customize it (the "Clone" action on the permission set, '
579-
+ 'or POST /api/v1/data/sys_permission_set with a new name).',
580-
);
577+
// The clone route's spelling moved with C3 stage 8 (the data route of the
578+
// retired `sys_permission_set` object → the catalog's clone door); the
579+
// sentence around it did not.
580+
expect(message).toContain('Clone it under a new name to customize it (the "Clone" action on the permission set, or POST /api/v1/');
581+
expect(message).toContain(' with a new name).');
581582
expect(message).not.toContain('OS_METADATA_WRITABLE');
582583
expect(message).not.toContain('redeploy');
583584
expect(message.endsWith('See docs/adr/0126-packaged-metadata-customization-model.md.')).toBe(true);
@@ -1253,8 +1254,17 @@ describe('[#20910] the repository doors name a Regime C type\'s sanctioned path,
12531254
const ADR_0126 = 'See docs/adr/0126-packaged-metadata-customization-model.md.';
12541255
const ACTION_SWITCH = 'Switch it off (POST /api/v1/actions/_activation/:object/:action, body {enabled: false}, '
12551256
+ ':object = global for an object-less action; operator-only where one install serves several organizations).';
1257+
// `{ROUTE}`: the clone route, whose spelling moved with C3 stage 8 (the
1258+
// retired object's data route → the catalog's clone door); see `sentenceMatches`.
12561259
const PERMISSION_CLONE = 'Clone it under a new name to customize it (the "Clone" action on the permission set, '
1257-
+ 'or POST /api/v1/data/sys_permission_set with a new name).';
1260+
+ 'or POST {ROUTE} with a new name).';
1261+
/** Exact equality, with a `{ROUTE}` placeholder standing for one `/api/v1/…` path. */
1262+
const sentenceMatches = (actual: string, expected: string): boolean => {
1263+
const [head, tail] = expected.split('{ROUTE}');
1264+
if (tail === undefined) return actual === expected;
1265+
return actual.startsWith(head) && actual.endsWith(tail)
1266+
&& /^\/api\/v1\/\S+$/.test(actual.slice(head.length, actual.length - tail.length));
1267+
};
12581268
const FLOW_PATHS = 'Clone it under a new name to customize it (POST /api/v1/automation/:name/clone, body {name, label}), '
12591269
+ 'or switch it off (POST /api/v1/automation/:name/toggle, body {enabled: false}; '
12601270
+ 'operator-only where one install serves several organizations).';
@@ -1286,10 +1296,9 @@ describe('[#20910] the repository doors name a Regime C type\'s sanctioned path,
12861296
it(`type door, save: a packaged ${type} is refused NOT_OVERRIDABLE with its row's path, no hatch`, async () => {
12871297
const err = await putWith(repo, { type, name: `pkg_${type}`, intent: 'override-artifact' }) as any;
12881298
expect(err).toMatchObject({ code: 'NOT_OVERRIDABLE', status: 403 });
1289-
expect(String(err.message)).toBe(
1290-
`Metadata item '${type}/pkg_${type}' is provided by a managed package and is sealed `
1291-
+ `against in-place edits. ${paths} ${ADR_0126}`,
1292-
);
1299+
const expected = `Metadata item '${type}/pkg_${type}' is provided by a managed package and is sealed `
1300+
+ `against in-place edits. ${paths} ${ADR_0126}`;
1301+
expect(sentenceMatches(String(err.message), expected), `${String(err.message)}\n≠ ${expected}`).toBe(true);
12931302
expect(Array.from(engine.rows.values())).toEqual([]);
12941303
});
12951304
}
@@ -1359,10 +1368,9 @@ describe('[#20910] the repository doors name a Regime C type\'s sanctioned path,
13591368
code: 'ITEM_LOCKED', status: 403, lockSource: 'package', packageId: READ_ONLY_PKG,
13601369
docs: 'docs/adr/0010-metadata-protection-model.md',
13611370
});
1362-
expect(String(err.message)).toBe(
1363-
`Cannot overlay '${type}' in package '${READ_ONLY_PKG}': that package is read-only, and its packaged base `
1364-
+ `is locked against in-place edits. ${paths} ${ADR_0126}`,
1365-
);
1371+
const expected = `Cannot overlay '${type}' in package '${READ_ONLY_PKG}': that package is read-only, and its packaged base `
1372+
+ `is locked against in-place edits. ${paths} ${ADR_0126}`;
1373+
expect(sentenceMatches(String(err.message), expected), `${String(err.message)}\n≠ ${expected}`).toBe(true);
13661374
});
13671375
}
13681376

0 commit comments

Comments
 (0)