From 70fe76cd6b1bd8d2574de8bfa80b4b3fe3672f28 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 20 Oct 2026 01:14:04 +0000 Subject: [PATCH] fix(dogfood): the wall /packages case's operator package declares the CRM dependency its view binds The case "/packages: each of the thirteen write doors refuses A ..." saved a draft list view bound to crm_lead into a package created with no dependencies. Since the save door judges a package's list view against the package's closure, publish-drafts refuses that view (200, success: false, publishedCount: 0) and the case read 0 commits three lines later. The operator's package now declares com.example.crm, the package that ships crm_lead, and the publish line asserts the receipt (success, outcome published, publishedCount 1), so a refused publish fails where it breaks, naming its cause. Claude-Session: https://claude.ai/code/session_01LmjU2x1faLZ39DVTFyVca6 Co-authored-by: Claude --- ...nvironment-metadata-refusal.dogfood.test.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/qa/dogfood/test/wall-environment-metadata-refusal.dogfood.test.ts b/packages/qa/dogfood/test/wall-environment-metadata-refusal.dogfood.test.ts index bc88ea803a9..16c8fd8a20f 100644 --- a/packages/qa/dogfood/test/wall-environment-metadata-refusal.dogfood.test.ts +++ b/packages/qa/dogfood/test/wall-environment-metadata-refusal.dogfood.test.ts @@ -84,6 +84,8 @@ function packageBody(id: string, version: string, objects: unknown[] = []) { const META_AUTHOR = 'em_meta_author'; const CATALOG_PKG = 'com.em.catalog'; +/** The package that ships `crm_lead` (`examples/app-crm/objectstack.config.ts`, `manifest.id`). */ +const CRM_PKG = 'com.example.crm'; interface Harness { stack: VerifyStack; @@ -234,9 +236,21 @@ for (const posture of ['isolated', 'group'] as const) { it("/packages: each of the thirteen write doors refuses A 403 PERMISSION_DENIED, and B reads the operator's package unchanged", async () => { const pkg = `com.em.${p}.op`; const pv = `crm_lead.em_${p}_pv`; - await ok(await h.stack.apiAs(h.operator, 'POST', '/packages', { id: pkg, name: 'op', version: '1.0.0', type: 'app' }), 201); + // The operator's package DECLARES the CRM package as a dependency: a + // package's draft publish judges a list view against the package's + // closure and refuses a binding outside it + // (`list-view-object-outside-closure`, #24563), and `crm_lead` is the + // CRM package's object. + await ok(await h.stack.apiAs(h.operator, 'POST', '/packages', + { id: pkg, name: 'op', version: '1.0.0', type: 'app', dependencies: { [CRM_PKG]: '*' } }), 201); await ok(await h.stack.apiAs(h.operator, 'PUT', `/meta/view/${pv}?package=${pkg}&mode=draft`, view(pv, 'c1'))); - await ok(await h.stack.apiAs(h.operator, 'POST', `/packages/${pkg}/publish-drafts`, {})); + // A 200 is not a publish: a refused batch answers 200 with `success: false` + // in `data`, so the receipt is read here, where a refusal names its cause. + const published = await h.stack.apiAs(h.operator, 'POST', `/packages/${pkg}/publish-drafts`, {}); + await ok(published); + const receipt = ((await published.json()) as { data?: Record }).data; + expect({ success: receipt?.success, outcome: receipt?.outcome, publishedCount: receipt?.publishedCount }, JSON.stringify(receipt?.failed)) + .toEqual({ success: true, outcome: 'published', publishedCount: 1 }); const commits = (((await (await h.stack.apiAs(h.operator, 'GET', `/packages/${pkg}/commits`)).json()) as any).data?.commits ?? []) .map((c: { id: string }) => c.id); expect(commits.length).toBeGreaterThan(0);