diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..db1c0b7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: release + +# Publishes @aestheticfunction/dspack-emit to npm when a version tag is pushed. +# +# Auth: npm trusted publishing (OIDC) — no NPM_TOKEN secret in the repo. +# One-time setup on npmjs.com (package settings -> Trusted publisher): +# repository aestheticfunction/dspack-emit, workflow release.yml. +# Provenance attestations are generated automatically for trusted publishes. +# +# Guards: +# - tag must equal the package.json version (prevents accidental mismatches) +# - full test suite runs before publish (in addition to prepublishOnly) +# - publishing an already-published version fails the job (npm rejects dupes) + +on: + push: + tags: + - "v*" + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # OIDC for npm trusted publishing / provenance + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + # Node 24 bundles npm >= 11.5, the minimum for OIDC trusted + # publishing. Node 20's npm 10 skips the token exchange entirely + # and the unauthenticated PUT fails as E404 (v0.1.1's first run). + node-version: 24 + cache: npm + registry-url: https://registry.npmjs.org + - name: Verify tag matches package.json version + run: | + pkg="$(node -p "require('./package.json').version")" + tag="${GITHUB_REF_NAME#v}" + if [ "$pkg" != "$tag" ]; then + echo "tag v$tag does not match package.json version $pkg" >&2 + exit 1 + fi + - run: npm ci + - run: npm test + - run: npm run build + - name: Publish (public, with provenance) + run: npm publish --access public diff --git a/RELEASE-0.6.0.md b/RELEASE-0.6.0.md new file mode 100644 index 0000000..dba8427 --- /dev/null +++ b/RELEASE-0.6.0.md @@ -0,0 +1,48 @@ +# dspack-emit 0.6.0 — the representation program + +0.6.0 ships the full surface-representation model built and measured on top of +the 0.5.0 foundation. It is **additive and backward-compatible**: every v1 +profile emits byte-for-byte as it did under 0.5.0 (19 byte-neutrality pins + +the v2 keystone byte-identity gate prove it), so 0.5.0 consumers upgrade with +no behavior change and opt into the new capabilities per profile. + +## New: the v2 profile language (`profileVersion: "2"`) + +A closed, load-validated primitive vocabulary — Identity / Routing / +Repetition — that lets a profile express compound-composition shapes A2UI +supports but 0.5.0's directives could not: + +- **T1 — transparent identity + control donation.** A boundary component + emits no instance; its children rise, and a dissolving field's label + donates onto its single eligible control. Ratified root-transparency. +- **T2 — item-mode collection.** A repeated sub-family becomes an array of + records (`radio-group-item`, `select-item`). +- **T3 — declared key joins.** A repeated family pairs with a sibling family + by declared keys — never position, adjacency, or similarity — with a + slot-valued joined field (tabs trigger↔content). +- **T4 — multi-slot compounds.** `sub(x).children → slot:name` routes a named + region's children as instances (dialog/sheet/popover). +- **Layered dissolution contexts.** A dissolving boundary shadows but does not + erase enclosing compound contexts; dispositions resolve through the + ancestor chain. + +Every edge fails closed at load or emit with a pathed reason; every +transformation is recorded in the fidelity ledger; `--strict-surface` gates +on fidelity class. + +## Also since 0.5.0 + +- Sub-component coverage derived from the internal model and enforced. +- Surface fidelity reporting (`EmitSurfaceResult.fidelity`, `maps-cleanly / + synthesis-defaults / lossy / cannot-represent`). +- `scaffoldProfile` rewritten on the v2 vocabulary. +- Functions in the profile/catalog path. + +## Compatibility & rollback + +- v1 profiles: byte-frozen. No consumer action required. +- Rollback: pin `@aestheticfunction/dspack-emit@0.5.0` — still on npm, + unchanged. +- Measured against the production shadcn v3 contract (34 components): 86 of + 104 sub-components resolved, 11 of 14 worked examples emit, every loss + recorded. See `eval/`. diff --git a/package.json b/package.json index a354267..6f2f537 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@aestheticfunction/dspack-emit", - "version": "0.5.0", + "version": "0.6.0", "type": "module", "description": "dspack emitters: compile a dspack design-system contract and dspack surfaces into protocol targets \u2014 an A2UI catalog + surface messages (gates A1-A3) and json-render catalog/registry modules + specs (gates J1-J3).", "license": "Apache-2.0",