@adia-ai/adia-ui-forge 0.8.4 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +16 -2
  3. package/agents/framework-verifier.md +13 -5
  4. package/bin/release-pretag-docs-gate +226 -0
  5. package/hooks/hooks.json +10 -0
  6. package/package.json +1 -1
  7. package/skills/adia-a2ui/SKILL.md +10 -2
  8. package/skills/adia-a2ui/references/pipeline-overview.md +1 -1
  9. package/skills/adia-author/SKILL.md +1 -0
  10. package/skills/adia-author/references/anti-patterns.md +7 -7
  11. package/skills/adia-author/references/api-contract.md +9 -9
  12. package/skills/adia-author/references/authoring-cycle.md +6 -6
  13. package/skills/adia-author/references/code-style.md +4 -4
  14. package/skills/adia-author/references/lifecycle-patterns.md +8 -8
  15. package/skills/adia-author/references/token-contract.md +5 -5
  16. package/skills/adia-author/references/worked-example.md +16 -16
  17. package/skills/adia-author/references/yaml-contract.md +1 -1
  18. package/skills/adia-deploy/SKILL.md +44 -0
  19. package/skills/adia-deploy/evals/routing-corpus.json +146 -0
  20. package/skills/adia-deploy/references/deploy-playbooks.md +1 -1
  21. package/skills/adia-dogfood/SKILL.md +64 -11
  22. package/skills/adia-dogfood/evals/routing-corpus.json +146 -0
  23. package/skills/adia-gen-review/SKILL.md +55 -0
  24. package/skills/adia-gen-review/evals/routing-corpus.json +146 -0
  25. package/skills/adia-llm-internals/evals/routing-corpus.json +146 -0
  26. package/skills/adia-release/SKILL.md +12 -5
  27. package/skills/adia-release/evals/evals.json +24 -0
  28. package/skills/adia-release/references/changelog-discipline.md +4 -4
  29. package/skills/adia-release/references/cut-procedure.md +45 -11
  30. package/skills/adia-release/references/gates-catalog.md +3 -3
  31. package/skills/adia-release/references/recovery-paths.md +4 -2
  32. package/skills/adia-release/scripts/bump.mjs +32 -1
  33. package/skills/adia-release/scripts/dispatch-publish.mjs +49 -11
  34. package/skills/adia-release/scripts/gate-roster.mjs +71 -0
  35. package/skills/adia-release/scripts/insert-stub.mjs +35 -1
  36. package/skills/adia-release/scripts/promote-unreleased.mjs +35 -1
  37. package/skills/adia-release/scripts/release-pack.mjs +284 -53
  38. package/skills/adia-release/scripts/tag-lockstep.mjs +29 -7
  39. package/skills/adia-ssr/SKILL.md +110 -0
  40. package/skills/adia-ssr/evals/audit-report.md +63 -0
  41. package/skills/adia-ssr/evals/routing-corpus.json +138 -0
  42. package/skills/adia-ssr/references/consumer-workarounds.md +63 -0
  43. package/skills/adia-ssr/references/failure-shapes.md +122 -0
  44. package/skills/adia-ssr/references/guard-patterns.md +142 -0
  45. package/skills/adia-ssr/references/status-ledger.md +35 -0
  46. package/skills/adia-ssr/references/test-without-linkedom.md +113 -0
@@ -0,0 +1,113 @@
1
+ # Testing an SSR gap without a real linkedom install
2
+
3
+ This repo has **no `linkedom` devDependency** (checked 2026-07-17: not in
4
+ `package.json` at any workspace level). The test suite runs on `happy-dom`/`jsdom`
5
+ (whichever `vitest` is configured with), and BOTH of those implement most of the APIs
6
+ linkedom lacks — so a naive test using the default environment will not reproduce an
7
+ SSR-shaped bug. Two consequences:
8
+
9
+ 1. **You cannot trust "the tests pass" as proof an SSR fix works** unless the test
10
+ itself removes the API under test. A guard around `attachInternals` that's never
11
+ exercised without `attachInternals` proves nothing.
12
+ 2. **The house pattern is deletion, not mocking** — `delete
13
+ HTMLElement.prototype.attachInternals` (or `delete
14
+ Document.prototype.adoptedStyleSheets`, or `delete globalThis.ResizeObserver`)
15
+ inside a `try { ... } finally { restore }` block, in the SAME test environment the
16
+ suite already runs in. This is a closer approximation of "the API is genuinely
17
+ absent" than a mock that might itself paper over the exact code path that would
18
+ throw — deleting the real thing exercises the REAL `typeof x === 'undefined'` /
19
+ `typeof x === 'function'` check the guard actually uses.
20
+
21
+ ## The pattern (descriptor-based restore — copy this shape for a new test)
22
+
23
+ The shipped test (`packages/web-components/core/element.test.js`, describe block
24
+ `'UIElement — SSR browser-API absence (gh#285)'`) restores via a plain `=` assignment
25
+ (`HTMLElement.prototype.attachInternals = original`). That works there ONLY because
26
+ `original` is always a real function in this repo's test environment (happy-dom always
27
+ provides `attachInternals`) — it never actually exercises the absent-original case.
28
+ **Don't copy that shortcut.** If `original` is ever genuinely `undefined` (a NEW test
29
+ targeting an API this environment doesn't have either), a plain assignment leaves the
30
+ property present with value `undefined` instead of restoring true absence — later
31
+ tests checking `'attachInternals' in HTMLElement.prototype` would wrongly see `true`,
32
+ making pass/fail order-dependent (flagged by review on this pack's own PR #293).
33
+ Use the descriptor-based restore — the exact shape `adoptedStyleSheets` already uses
34
+ below — for every new instance of this pattern:
35
+
36
+ ```js
37
+ it('constructs without throwing when attachInternals does not exist', () => {
38
+ const desc = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'attachInternals');
39
+ delete HTMLElement.prototype.attachInternals;
40
+ try {
41
+ class El extends UIElement {}
42
+ const tag = registerTestElement(El);
43
+ expect(() => mount(tag)).not.toThrow();
44
+ } finally {
45
+ if (desc) Object.defineProperty(HTMLElement.prototype, 'attachInternals', desc);
46
+ }
47
+ });
48
+ ```
49
+
50
+ For a global (not a prototype method), the same descriptor-based restore applies —
51
+ globals are own-properties of `globalThis`, so `Object.getOwnPropertyDescriptor`
52
+ works identically:
53
+ ```js
54
+ const desc = Object.getOwnPropertyDescriptor(globalThis, 'ResizeObserver');
55
+ delete globalThis.ResizeObserver;
56
+ try {
57
+ // ... construct the component, assert it doesn't throw and degrades sanely ...
58
+ } finally {
59
+ if (desc) Object.defineProperty(globalThis, 'ResizeObserver', desc);
60
+ }
61
+ ```
62
+
63
+ For `document.adoptedStyleSheets` (an own-property on `Document.prototype`), delete
64
+ the property descriptor and restore it the same way:
65
+ ```js
66
+ const desc = Object.getOwnPropertyDescriptor(Document.prototype, 'adoptedStyleSheets');
67
+ delete Document.prototype.adoptedStyleSheets;
68
+ try {
69
+ // ... assert ...
70
+ } finally {
71
+ if (desc) Object.defineProperty(Document.prototype, 'adoptedStyleSheets', desc);
72
+ }
73
+ ```
74
+
75
+ ## What this method does NOT catch
76
+
77
+ Deletion proves "the guarded code path doesn't throw when the API is absent." It does
78
+ **not** prove:
79
+ - that linkedom's ACTUAL behavior matches "absent" exactly (linkedom may implement a
80
+ PARTIAL or subtly-wrong version of an API rather than nothing at all — always check
81
+ the consumer's bug report for the exact error, don't assume "missing" when the
82
+ report says something more specific);
83
+ - anything about shape 2 (destructive `stamp()`, gh#284 — narrowed 2026-07-17) or
84
+ shape 4 (declarative data binding, gh#288) — neither is an API-absence bug, so this
85
+ test method doesn't apply. Shape 2's narrowing was verified with exactly the shape
86
+ of test this section describes — a container element given real children (or
87
+ text) BEFORE `document.appendChild()` connects it (simulating server-parsed markup
88
+ that already has content when `connectedCallback` first runs) — confirming
89
+ `nav-ui`/`check-ui` preserve pre-existing content while a synthetic non-null-template
90
+ component loses it (see [`failure-shapes.md`](failure-shapes.md) §2). That
91
+ reproduction was a throwaway, not a shipped permanent test — if shape 2 needs
92
+ re-verifying later (a new component trips `audit-template-child-conflict.mjs`, or
93
+ the consumer reports something new), rebuild it the same way rather than assuming
94
+ the old narrowing still holds.
95
+
96
+ ## Live-browser confirmation is still required, separately
97
+
98
+ The delete/try/finally tests prove the GUARD doesn't crash. They do not prove real
99
+ browsers are unaffected — that's a SEPARATE check, done live (Playwright or the
100
+ Chrome extension), confirming the real API still gets used correctly when it's
101
+ actually present. Both gh#285 and gh#286's fixes were verified this second way before
102
+ shipping (a real `ElementInternals` instance still used and functional; a real
103
+ `ResizeObserver` tick still corrects state) — do both, never one instead of the other.
104
+
105
+ ## If a deeper simulation becomes worth the cost
106
+
107
+ A real `linkedom` install (as a devDependency, used only in a dedicated SSR-simulation
108
+ test file, never in the main suite) would let a test actually import `linkedom`,
109
+ create a document with it, and run REAL component code against REAL absent APIs
110
+ end-to-end — closer to the consumer's actual failure mode than deletion, and the only
111
+ way to test shape 2/4 meaningfully. This has not been done as of 2026-07-17 — it's a
112
+ tooling investment, not a quick addition; raise it as its own decision if shape 2's
113
+ investigation (gh#284) needs it.