From a45e601f6e73f7abf2a0fd817db4491dd17f8ef2 Mon Sep 17 00:00:00 2001 From: Ryan Dombrowski Date: Wed, 22 Jul 2026 11:49:39 -0400 Subject: [PATCH 1/2] p1e: A3 gate emits every shadcn worked example; consume dspack-emit 0.3.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The studio side of P1.E: build.ts's shadcn branch emitted only examples[0], which is exactly why two nominally-mapped sub-families (table, card) could refuse for months without any gate noticing — the example that would have caught it was never emitted. Every worked example now emits (exit 4 on refusal, per-example labeling on warnings); the set grows with the contract through check:sync. Fail-first, against the published dspack-emit 0.3.1: shadcn surface emission failed (ex.support-ticket-queue): unknown component 'table-caption': not a mapped component of the 'shadcn/ui — A2UI catalog (compiled from dspack)' profile build exit code: 4 dspack-emit 0.3.2 (feat/profile-parity, merged) adds the subTable and subFlatten parent strategies plus the subCoverage completeness invariant. The dependency is pinned to 0.3.2 here; lockfile follows once the package is published (publishing is owner-gated — no trusted-publishing workflow in dspack-emit). Co-Authored-By: Claude Fable 5 --- packages/contracts/package.json | 2 +- packages/contracts/src/build.ts | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/contracts/package.json b/packages/contracts/package.json index ba8e58e..927e33d 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -19,7 +19,7 @@ "typecheck": "tsc -p tsconfig.json" }, "dependencies": { - "@aestheticfunction/dspack-emit": "0.3.1" + "@aestheticfunction/dspack-emit": "0.3.2" }, "devDependencies": { "@astryxdesign/cli": "0.1.4", diff --git a/packages/contracts/src/build.ts b/packages/contracts/src/build.ts index 038ea54..cc37f39 100644 --- a/packages/contracts/src/build.ts +++ b/packages/contracts/src/build.ts @@ -94,22 +94,28 @@ for (const version of ["0.9.1", "1.0"] as A2uiVersion[]) { // owner-authored upstream extension (intents beyond destructive-action); // the catalog emission and gates run today. const shadcnDoc = JSON.parse(readFileSync(join(root, "shadcn-ui.dspack.json"), "utf8")) as DspackDoc; -const shadcnExample = (shadcnDoc as any).examples?.[0]; -if (!shadcnExample?.surface) { +const shadcnExamples = ((shadcnDoc as any).examples ?? []) as Array<{ id: string; surface: unknown }>; +if (shadcnExamples.length === 0 || !shadcnExamples[0]?.surface) { console.error("shadcn contract has no worked example surface; A3 would be vacuous"); process.exit(1); } +// EVERY worked example must emit (P1.E): the example set is the contract's +// own definition of "expressible", and a nominally-mapped component whose +// sub-family refuses only surfaces when its example is actually emitted. +// examples[0] additionally feeds the A3 instance gate below. let shadcnSurfaceMessages: unknown = { messages: [] }; -try { - const emitted = emitSurface(shadcnExample.surface as DspackSurface, shadcnDoc, { profile: shadcnProfile }); - shadcnSurfaceMessages = { messages: emitted.messages }; - for (const w of emitted.warnings) console.log(` [shadcn surface warn] ${w.code}: ${w.message}`); -} catch (err) { - if (err instanceof EmitSurfaceError) { - console.error(`shadcn surface emission failed: ${err.message}`); - process.exit(4); +for (const [i, example] of shadcnExamples.entries()) { + try { + const emitted = emitSurface(example.surface as DspackSurface, shadcnDoc, { profile: shadcnProfile }); + if (i === 0) shadcnSurfaceMessages = { messages: emitted.messages }; + for (const w of emitted.warnings) console.log(` [shadcn surface warn] ${example.id} ${w.code}: ${w.message}`); + } catch (err) { + if (err instanceof EmitSurfaceError) { + console.error(`shadcn surface emission failed (${example.id}): ${err.message}`); + process.exit(4); + } + throw err; } - throw err; } for (const version of ["0.9.1", "1.0"] as A2uiVersion[]) { const { catalog, validation, report } = transform(shadcnDoc, version, shadcnSurfaceMessages, shadcnProfile); From fe46d8e1b08c7265cc0106fdde7e5da311cb111c Mon Sep 17 00:00:00 2001 From: Ryan Dombrowski Date: Wed, 22 Jul 2026 12:32:54 -0400 Subject: [PATCH 2/2] deps: consume published dspack-emit 0.3.2 Verified against the npm tarball (subTable/subFlatten in the compiled emitter, subCoverage in the profile). Lockfile delta is solely the dspack-emit 0.3.1 -> 0.3.2 lines. Gates on the published package: contracts build:catalogs with the all-examples A3 gate green (ticket-queue emits with three per-cell badge-flatten warnings + the composition summary), drift-check and check:sync clean, pnpm -r typecheck/test green, local Playwright 106 passed / 4 skipped, production config 86 passed. All six P1.1 recordings emit through the published package: five at 4 columns x 3 rows, the skeletal fifth at 1x1. Co-Authored-By: Claude Fable 5 --- pnpm-lock.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 960b8e4..a04e311 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -218,8 +218,8 @@ importers: packages/contracts: dependencies: '@aestheticfunction/dspack-emit': - specifier: 0.3.1 - version: 0.3.1 + specifier: 0.3.2 + version: 0.3.2 devDependencies: '@astryxdesign/cli': specifier: 0.1.4 @@ -319,6 +319,9 @@ packages: '@aestheticfunction/dspack-emit@0.3.1': resolution: {integrity: sha512-0vCFP5rvWGoIPvnBlB3puXkhoJhEyq/FQHrfj3JfPwf37WfASZb5ZOK3tPzB8ZhZTFkxvhjrvHeEYgRDOGm04w==} + '@aestheticfunction/dspack-emit@0.3.2': + resolution: {integrity: sha512-jkygjjByRJWeUbfGygcz7fkYQ7mTx9lRswCwE/zWNj/ChOiBhjvoEEQGOvrFbOw/J0m4o2REvKQKIhXV55ytdA==} + '@aestheticfunction/dspack-gen@0.1.2': resolution: {integrity: sha512-u64Khv8+/HsIDwC5ciyW2gTNFmgrRH+CjQFbFBlj1s1veZQAifwE/gQXN23QmcdPKdEwDVMJuIhEYXirfV82Mg==} engines: {node: '>=20.0.0'} @@ -2176,6 +2179,11 @@ snapshots: ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) + '@aestheticfunction/dspack-emit@0.3.2': + dependencies: + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + '@aestheticfunction/dspack-gen@0.1.2(zod@4.4.3)': dependencies: '@aestheticfunction/dspack-emit': 0.3.1