@adia-ai/adia-ui-forge 0.8.4 → 0.8.6
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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +27 -2
- package/README.md +13 -4
- package/agents/a2ui-builder.corpus.json +35 -0
- package/agents/a2ui-builder.md +37 -0
- package/agents/component-author.corpus.json +40 -0
- package/agents/component-author.md +10 -1
- package/agents/framework-reviewer.corpus.json +35 -0
- package/agents/framework-reviewer.md +42 -0
- package/agents/release-builder.corpus.json +39 -0
- package/agents/release-builder.md +39 -0
- package/agents/routing-corpus.json +38 -38
- package/bin/release-pretag-docs-gate +226 -0
- package/commands/release.md +5 -3
- package/hooks/hooks.json +10 -0
- package/package.json +1 -1
- package/skills/adia-a2ui/SKILL.md +37 -8
- package/skills/adia-a2ui/evals/routing-corpus.json +36 -29
- package/skills/adia-a2ui/references/pipeline-overview.md +1 -1
- package/skills/adia-a2ui/references/zettel-calibration.md +5 -5
- package/skills/adia-author/SKILL.md +16 -8
- package/skills/adia-author/evals/routing-corpus.json +39 -218
- package/skills/adia-author/references/anti-patterns.md +7 -7
- package/skills/adia-author/references/api-contract.md +9 -9
- package/skills/adia-author/references/authoring-cycle.md +25 -6
- package/skills/adia-author/references/code-style.md +4 -5
- package/skills/adia-author/references/lifecycle-patterns.md +8 -8
- package/skills/adia-author/references/llm-bridge.md +7 -0
- package/skills/adia-author/references/token-contract.md +5 -5
- package/skills/adia-author/references/worked-example.md +34 -18
- package/skills/adia-author/references/yaml-contract.md +1 -1
- package/skills/adia-deploy/SKILL.md +71 -12
- package/skills/adia-deploy/evals/routing-corpus.json +37 -0
- package/skills/adia-deploy/references/deploy-playbooks.md +1 -1
- package/skills/adia-dogfood/SKILL.md +71 -11
- package/skills/adia-dogfood/evals/routing-corpus.json +34 -0
- package/skills/adia-dogfood/references/admin-shell-anatomy.md +1 -1
- package/skills/adia-gen-review/SKILL.md +73 -7
- package/skills/adia-gen-review/evals/routing-corpus.json +34 -0
- package/skills/adia-gen-review/scripts/gen-review-decompose.mjs +5 -0
- package/skills/adia-llm-internals/SKILL.md +10 -6
- package/skills/adia-llm-internals/evals/routing-corpus.json +37 -0
- package/skills/adia-llm-internals/references/bridge-facade.md +2 -2
- package/skills/adia-llm-internals/references/streaming-sse.md +1 -1
- package/skills/adia-release/SKILL.md +43 -13
- package/skills/adia-release/evals/evals.json +24 -0
- package/skills/adia-release/evals/routing-corpus.json +35 -0
- package/skills/adia-release/references/changelog-discipline.md +15 -9
- package/skills/adia-release/references/cut-procedure.md +78 -24
- package/skills/adia-release/references/gates-catalog.md +3 -3
- package/skills/adia-release/references/independent-package-release.md +1 -1
- package/skills/adia-release/references/recovery-paths.md +4 -2
- package/skills/adia-release/scripts/bump.mjs +32 -1
- package/skills/adia-release/scripts/dispatch-publish.mjs +49 -11
- package/skills/adia-release/scripts/gate-roster.mjs +71 -0
- package/skills/adia-release/scripts/insert-stub.mjs +36 -2
- package/skills/adia-release/scripts/promote-unreleased.mjs +35 -1
- package/skills/adia-release/scripts/release-pack.mjs +315 -56
- package/skills/adia-release/scripts/tag-lockstep.mjs +29 -7
- package/skills/adia-site-docs/SKILL.md +6 -1
- package/skills/adia-site-docs/evals/routing-corpus.json +35 -173
- package/skills/adia-ssr/SKILL.md +128 -0
- package/skills/adia-ssr/evals/audit-report.md +63 -0
- package/skills/adia-ssr/evals/routing-corpus.json +34 -0
- package/skills/adia-ssr/references/consumer-workarounds.md +81 -0
- package/skills/adia-ssr/references/failure-shapes.md +164 -0
- package/skills/adia-ssr/references/guard-patterns.md +183 -0
- package/skills/adia-ssr/references/status-ledger.md +33 -0
- package/skills/adia-ssr/references/test-without-linkedom.md +129 -0
- package/agents/a2ui-engineer.md +0 -26
- package/agents/framework-verifier.md +0 -26
- package/agents/release-engineer.md +0 -26
|
@@ -1,176 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"id": "site-docs-review-01",
|
|
20
|
-
"phrase": "review this site docs page for consistency",
|
|
21
|
-
"should_route_to_site_docs": true,
|
|
22
|
-
"expected_shape": "review-page",
|
|
23
|
-
"rationale": "Canonical review-a-page task shape."
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"id": "site-docs-review-02",
|
|
27
|
-
"phrase": "does this callout look like plain text to you",
|
|
28
|
-
"should_route_to_site_docs": true,
|
|
29
|
-
"expected_shape": "callout-fix",
|
|
30
|
-
"rationale": "Symptom description matching Defect 2 (fabricated data-alert)."
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"id": "site-docs-review-03",
|
|
34
|
-
"phrase": "why is the code background not visible on this page",
|
|
35
|
-
"should_route_to_site_docs": true,
|
|
36
|
-
"expected_shape": "contrast-token",
|
|
37
|
-
"rationale": "Symptom description matching Defect 1 (inline-code contrast)."
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"id": "site-docs-new-page-01",
|
|
41
|
-
"phrase": "add a new pattern page under site/pages/patterns",
|
|
42
|
-
"should_route_to_site_docs": true,
|
|
43
|
-
"expected_shape": "new-page",
|
|
44
|
-
"rationale": "Explicit site/pages/patterns path mention."
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"id": "site-docs-new-page-02",
|
|
48
|
-
"phrase": "author a new getting-started guide page",
|
|
49
|
-
"should_route_to_site_docs": true,
|
|
50
|
-
"expected_shape": "new-page",
|
|
51
|
-
"rationale": "getting-started/ is one of this skill's 5 owned categories."
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"id": "site-docs-new-page-03",
|
|
55
|
-
"phrase": "write a new architecture explainer page for the docs site",
|
|
56
|
-
"should_route_to_site_docs": true,
|
|
57
|
-
"expected_shape": "new-page",
|
|
58
|
-
"rationale": "architecture/ is one of this skill's 5 owned categories."
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"id": "site-docs-new-page-04",
|
|
62
|
-
"phrase": "create a reference page documenting the MCP tools",
|
|
63
|
-
"should_route_to_site_docs": true,
|
|
64
|
-
"expected_shape": "new-page",
|
|
65
|
-
"rationale": "reference/ is one of this skill's 5 owned categories."
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"id": "site-docs-demo-frame-01",
|
|
69
|
-
"phrase": "this demo page needs a tamed static frame like the other pattern pages",
|
|
70
|
-
"should_route_to_site_docs": true,
|
|
71
|
-
"expected_shape": "demo-frame-consistency",
|
|
72
|
-
"rationale": "Matches the .demo-frame consolidation rule."
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"id": "site-docs-demo-frame-02",
|
|
76
|
-
"phrase": "add a new admin-shell demo to this patterns page without duplicating the taming CSS",
|
|
77
|
-
"should_route_to_site_docs": true,
|
|
78
|
-
"expected_shape": "demo-frame-consistency",
|
|
79
|
-
"rationale": "Direct match on rule 3 (reuse .demo-frame)."
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"id": "site-docs-review-04",
|
|
83
|
-
"phrase": "is this site page consistent with our authoring conventions",
|
|
84
|
-
"should_route_to_site_docs": true,
|
|
85
|
-
"expected_shape": "review-page",
|
|
86
|
-
"rationale": "Direct convention-compliance ask."
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
"id": "site-docs-review-05",
|
|
90
|
-
"phrase": "audit site/pages/guides for the same callout bug we found elsewhere",
|
|
91
|
-
"should_route_to_site_docs": true,
|
|
92
|
-
"expected_shape": "review-page",
|
|
93
|
-
"rationale": "Explicit guides/ path + defect-class reference."
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"id": "site-docs-callout-01",
|
|
97
|
-
"phrase": "this warning box on the docs page has no background at all",
|
|
98
|
-
"should_route_to_site_docs": true,
|
|
99
|
-
"expected_shape": "callout-fix",
|
|
100
|
-
"rationale": "Symptom description matching the fabricated data-alert defect."
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"id": "site-docs-new-page-05",
|
|
104
|
-
"phrase": "what's the shared skeleton every site docs page should follow",
|
|
105
|
-
"should_route_to_site_docs": true,
|
|
106
|
-
"expected_shape": "new-page",
|
|
107
|
-
"rationale": "Direct ask about the template decomposition this skill carries."
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"id": "site-docs-contrast-01",
|
|
111
|
-
"phrase": "what token should a new chip-like surface use to stay readable against the page background",
|
|
112
|
-
"should_route_to_site_docs": true,
|
|
113
|
-
"expected_shape": "contrast-token",
|
|
114
|
-
"rationale": "Direct match on rule 1 (--a-canvas-well-strong)."
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"id": "site-docs-review-06",
|
|
118
|
-
"phrase": "check the patterns pages for any other unstyled data attributes like data-alert",
|
|
119
|
-
"should_route_to_site_docs": true,
|
|
120
|
-
"expected_shape": "review-page",
|
|
121
|
-
"rationale": "Direct defect-class sweep request."
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"id": "site-docs-new-page-06",
|
|
125
|
-
"phrase": "scaffold a new getting-started/theming-dark-mode.html page",
|
|
126
|
-
"should_route_to_site_docs": true,
|
|
127
|
-
"expected_shape": "new-page",
|
|
128
|
-
"rationale": "Explicit new-file-under-owned-category shape."
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
{
|
|
132
|
-
"id": "site-docs-adversarial-01",
|
|
133
|
-
"phrase": "review this component's own demo gallery in its .examples.html file",
|
|
134
|
-
"should_route_to_site_docs": false,
|
|
135
|
-
"expected_shape": "sibling-boundary",
|
|
136
|
-
"rationale": "packages/web-components/components/*/*.examples.html is adia-author's remit, not this skill's."
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
"id": "site-docs-adversarial-02",
|
|
140
|
-
"phrase": "fix this gen-ui training exemplar page under site/pages/examples",
|
|
141
|
-
"should_route_to_site_docs": false,
|
|
142
|
-
"expected_shape": "sibling-boundary",
|
|
143
|
-
"rationale": "site/pages/examples/** is the pure-primitive-composition training-harvest surface governed by composition-and-examples.md + adia-a2ui, explicitly fenced out."
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
"id": "site-docs-adversarial-03",
|
|
147
|
-
"phrase": "tune the zettel retrieval threshold for the chunk corpus",
|
|
148
|
-
"should_route_to_site_docs": false,
|
|
149
|
-
"expected_shape": "sibling-boundary",
|
|
150
|
-
"rationale": "A2UI pipeline internals belong to adia-a2ui, unrelated to site/pages authoring."
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
"id": "site-docs-adversarial-04",
|
|
154
|
-
"phrase": "add a new prop to the button-ui primitive",
|
|
155
|
-
"should_route_to_site_docs": false,
|
|
156
|
-
"expected_shape": "sibling-boundary",
|
|
157
|
-
"rationale": "Primitive authoring is adia-author's remit."
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
"id": "site-docs-adversarial-05",
|
|
161
|
-
"phrase": "cut the next npm release for the 9 @adia-ai packages",
|
|
162
|
-
"should_route_to_site_docs": false,
|
|
163
|
-
"expected_shape": "sibling-boundary",
|
|
164
|
-
"rationale": "Release engineering is adia-release's remit, unrelated to docs-page authoring."
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
"id": "site-docs-adversarial-06",
|
|
168
|
-
"phrase": "deploy the docs site to ui-kit.exe.xyz",
|
|
169
|
-
"should_route_to_site_docs": false,
|
|
170
|
-
"expected_shape": "sibling-boundary",
|
|
171
|
-
"rationale": "Deploy operations are adia-deploy's remit; this skill authors content, it doesn't ship it."
|
|
172
|
-
}
|
|
2
|
+
"positives": [
|
|
3
|
+
"review this site docs page for consistency",
|
|
4
|
+
"does this callout look like plain text to you",
|
|
5
|
+
"why is the code background not visible on this page",
|
|
6
|
+
"add a new pattern page under site/pages/patterns",
|
|
7
|
+
"author a new getting-started guide page",
|
|
8
|
+
"write a new architecture explainer page for the docs site",
|
|
9
|
+
"create a reference page documenting the MCP tools",
|
|
10
|
+
"this demo page needs a tamed static frame like the other pattern pages",
|
|
11
|
+
"add a new admin-shell demo to this patterns page without duplicating the taming CSS",
|
|
12
|
+
"is this site page consistent with our authoring conventions",
|
|
13
|
+
"audit site/pages/guides for the same callout bug we found elsewhere",
|
|
14
|
+
"this warning box on the docs page has no background at all",
|
|
15
|
+
"what's the shared skeleton every site docs page should follow",
|
|
16
|
+
"what token should a new chip-like surface use to stay readable against the page background",
|
|
17
|
+
"check the patterns pages for any other unstyled data attributes like data-alert",
|
|
18
|
+
"scaffold a new getting-started/theming-dark-mode.html page"
|
|
173
19
|
],
|
|
174
|
-
|
|
175
|
-
|
|
20
|
+
"negatives": [
|
|
21
|
+
"review this component's own demo gallery in its .examples.html file",
|
|
22
|
+
"fix this gen-ui training exemplar page under site/pages/examples",
|
|
23
|
+
"tune the zettel retrieval threshold for the chunk corpus",
|
|
24
|
+
"add a new prop to the button-ui primitive",
|
|
25
|
+
"cut the next npm release for the 9 @adia-ai packages",
|
|
26
|
+
"deploy the docs site to ui-kit.exe.xyz",
|
|
27
|
+
"fix this gen-ui training exemplar page",
|
|
28
|
+
"add a demo to the patterns page for card-ui"
|
|
29
|
+
],
|
|
30
|
+
"_measured": {
|
|
31
|
+
"as_of": "2026-07-18",
|
|
32
|
+
"scorer": "routing_eval.py (nonoun-plugins/forge)",
|
|
33
|
+
"f1": 0.733,
|
|
34
|
+
"precision": 0.786,
|
|
35
|
+
"recall": 0.688,
|
|
36
|
+
"exit_code": 0
|
|
37
|
+
}
|
|
176
38
|
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: adia-ssr
|
|
3
|
+
description: >-
|
|
4
|
+
Answers why an AdiaUI component crashes, drops content, or renders wrong
|
|
5
|
+
under SSR (linkedom/Astro consumers) — the four known failure shapes,
|
|
6
|
+
what's fixed vs open, how to test without a linkedom install. Use when
|
|
7
|
+
asked "does this work under SSR", why a component crashes on
|
|
8
|
+
attachInternals/ResizeObserver/adoptedStyleSheets under a DOM shim, why
|
|
9
|
+
table-ui/chart-ui/select-ui or a container CE renders empty or loses its
|
|
10
|
+
nested children when server-rendered, whether it's safe to call
|
|
11
|
+
getBoundingClientRect() synchronously in connectedCallback, or whether a
|
|
12
|
+
browser-API shim/workaround can finally be deleted after a fix ships.
|
|
13
|
+
ANSWERS only. NOT for implementing a fix (adia-author) or consumer
|
|
14
|
+
host/hydration wiring (adia-host, adia-ui-factory plugin).
|
|
15
|
+
disable-model-invocation: false
|
|
16
|
+
user-invocable: false
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# adia-ssr — does it work under SSR, and why not if it doesn't
|
|
20
|
+
|
|
21
|
+
Two real consumers (adiav2's `admin-portal-fe` and `factory-dashboard`) server-render
|
|
22
|
+
AdiaUI's light-DOM components via Astro 5 + `custom-elements-ssr`, which runs on
|
|
23
|
+
linkedom — a DOM shim with no layout engine and missing browser APIs the framework's
|
|
24
|
+
base class assumes exist. Every SSR bug that's surfaced maps onto one of four root-cause
|
|
25
|
+
shapes; misclassifying a new report against the wrong shape sends the investigation
|
|
26
|
+
to the wrong fix (or worse, invents a redundant one). This pack answers "which shape is
|
|
27
|
+
this" and "what's the state of each shape's fix" — it never carries the fix itself.
|
|
28
|
+
|
|
29
|
+
## The four shapes, in one line each
|
|
30
|
+
|
|
31
|
+
1. **A browser-only API is called unconditionally → crash.** `attachInternals`,
|
|
32
|
+
the four Observer constructors, `document.adoptedStyleSheets`. **Fixed** (gh#285).
|
|
33
|
+
2. **`connectedCallback` destructively re-stamps existing DOM → silent content loss.**
|
|
34
|
+
The ORIGINAL diagnosis, narrowed to a static audit 2026-07-17 (gh#284) — zero
|
|
35
|
+
shipped components currently pair a non-null template with real light-DOM
|
|
36
|
+
content, so this specific mechanism isn't exposed today; a forward audit catches
|
|
37
|
+
a future regression. **Do not stop here** — see shape 2b, the actual live bug
|
|
38
|
+
found investigating the same report.
|
|
39
|
+
2b. **Custom-element upgrade doesn't replay `attributeChangedCallback` for
|
|
40
|
+
pre-existing attributes → reflected properties stuck at their class default.**
|
|
41
|
+
The REAL mechanism behind gh#284's reported symptom. happy-dom and (by strong
|
|
42
|
+
inference) linkedom both skip the custom-elements spec's upgrade-time
|
|
43
|
+
attribute replay (§4.13.5 step 6); any `reflect: true` property seeded only
|
|
44
|
+
from pre-parsed/SSR HTML never initializes. **Fixed 2026-07-18** (gh#284,
|
|
45
|
+
PR #309) — `connectedCallback` now re-syncs every declared property from its
|
|
46
|
+
live attribute before `connected()` runs.
|
|
47
|
+
3. **A connect-time layout measurement is treated as confirmed, not unknown.** A zero
|
|
48
|
+
rect (shim, or real pre-layout connect) drives a wrong persistent decision.
|
|
49
|
+
**Fixed for one component** (gh#286); the general pattern is unswept.
|
|
50
|
+
|
|
51
|
+
A fifth item, **property-only components can't seed initial state from SSR HTML**
|
|
52
|
+
(gh#288), was a feature gap — **CLOSED 2026-07-18**. It was never actually blocked
|
|
53
|
+
on shape 2/2b (table-ui/chart-ui/select-ui all use `static template = () => null`
|
|
54
|
+
too), and the real scope was narrower than filed: `select-ui` already declares
|
|
55
|
+
options via native `<option>` children, `chart-ui` already hydrates `.data` from a
|
|
56
|
+
JSON `data="[…]"` attribute — only `table-ui`'s `.data` had no declarative form,
|
|
57
|
+
now fixed the same way.
|
|
58
|
+
|
|
59
|
+
Full symptom → root-cause → status detail, cited to the actual shipped/open code:
|
|
60
|
+
[`references/failure-shapes.md`](references/failure-shapes.md).
|
|
61
|
+
|
|
62
|
+
## Consult table
|
|
63
|
+
|
|
64
|
+
| Ask | Answer from |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| "why does `<text-ui>`/`<avatar-ui>`/a container lose its content under SSR" | [`failure-shapes.md`](references/failure-shapes.md) §2 — shape 2, NARROWED (doesn't currently reproduce against any shipped component; see the survey before assuming a new report fits this shape) |
|
|
67
|
+
| "why does this crash / throw at construction under SSR" | [`failure-shapes.md`](references/failure-shapes.md) §1 — shape 1, FIXED; the exact guard shape to copy for a NEW instance is [`guard-patterns.md`](references/guard-patterns.md) §1 |
|
|
68
|
+
| "is this connect-time `getBoundingClientRect()`/measurement read safe" | [`failure-shapes.md`](references/failure-shapes.md) §3 + [`guard-patterns.md`](references/guard-patterns.md) §3 — the fixed component's exact shape, and the "unknown ≠ confirmed" principle to apply elsewhere |
|
|
69
|
+
| "what's fixed vs still open for SSR support" | [`status-ledger.md`](references/status-ledger.md) — re-verify against `gh issue view` before trusting it, it drifts |
|
|
70
|
+
| "how do I test an SSR gap — we have no linkedom installed" | [`test-without-linkedom.md`](references/test-without-linkedom.md) — the delete/try/finally pattern, and what it does NOT prove |
|
|
71
|
+
| "what's the consumer's current workaround, and can they drop it yet" | [`consumer-workarounds.md`](references/consumer-workarounds.md) |
|
|
72
|
+
| "table/chart/select renders empty in the SSR response" | [`failure-shapes.md`](references/failure-shapes.md) §4 — shape 5, CLOSED (table-ui's `data="[…]"` attribute); check whether the reporting component is registered server-side first if it still reproduces |
|
|
73
|
+
|
|
74
|
+
## Deviation doctrine
|
|
75
|
+
|
|
76
|
+
Every fix pattern this pack cites ([`guard-patterns.md`](references/guard-patterns.md))
|
|
77
|
+
carries the reasoning for why it looks the way it does — the no-op `ElementInternals`
|
|
78
|
+
shim exists because leaving the field `undefined` would relocate a crash, not remove
|
|
79
|
+
it; deletion-based testing exists because this repo has no `linkedom` devDependency.
|
|
80
|
+
If a new case doesn't fit an existing pattern's reasoning, that's a signal to design a
|
|
81
|
+
new pattern. Route it through `adia-author` — don't force-fit the nearest existing
|
|
82
|
+
shape.
|
|
83
|
+
|
|
84
|
+
## Boundaries
|
|
85
|
+
|
|
86
|
+
- **Implementing any fix — new or matching an existing pattern.** Route to
|
|
87
|
+
`adia-author`. This pack orients and cites; it never edits
|
|
88
|
+
`packages/web-components/core/` or any component source.
|
|
89
|
+
- **Consumer-side SSR/hydration host wiring** (an app's own Astro/Next config, which
|
|
90
|
+
rendering mode to pick, how to structure the hydration boundary). Route to
|
|
91
|
+
`adia-host` (adia-ui-factory plugin) — this pack answers whether the FRAMEWORK's own
|
|
92
|
+
components are SSR-safe, not how a consumer app should be structured around them.
|
|
93
|
+
- **A2UI runtime/generation-pipeline SSR concerns** (if any surface later). Route to
|
|
94
|
+
`adia-a2ui` — this pack is scoped to `UIElement`'s own lifecycle and the
|
|
95
|
+
component/trait/module layer, not the generative pipeline.
|
|
96
|
+
- **Not a general web-components-SSR tutorial.** Every claim here is cited to this
|
|
97
|
+
specific framework's actual code, issues, and PRs — general SSR/custom-elements
|
|
98
|
+
theory that isn't grounded in this repo's own history doesn't belong in this pack.
|
|
99
|
+
|
|
100
|
+
## Worked example — the answer contract
|
|
101
|
+
|
|
102
|
+
**Ask:** "`<text-ui>Adia Admin</text-ui>` renders as an empty tag in our SSR output —
|
|
103
|
+
is this a known issue?"
|
|
104
|
+
|
|
105
|
+
**Answer:** It matches shape 2's SYMPTOM (`connectedCallback` destructively
|
|
106
|
+
re-stamping existing DOM), but shape 2 was narrowed on 2026-07-17 — verify against
|
|
107
|
+
the CURRENT code before reusing the old answer, because this is exactly the case it
|
|
108
|
+
no longer covers. `text-ui`'s `static template` (`packages/web-components/components/text/text.class.js`)
|
|
109
|
+
is `() => null` — `connectedCallback`'s `if (result) stamp(result, this)` never
|
|
110
|
+
enters the branch, so `stamp()` never touches `<text-ui>`'s children at all. This
|
|
111
|
+
component isn't exposed to shape 2; something else is dropping the text — check
|
|
112
|
+
whether `text-ui` is even registered server-side (a different, structural gap: is
|
|
113
|
+
the tag defined before the SSR pass runs?), or whether another mutation (a parent
|
|
114
|
+
re-render, `innerHTML` elsewhere) is clearing it. **The general lesson, not just
|
|
115
|
+
this one component:** before answering "yes, known issue, shape 2" for ANY new
|
|
116
|
+
report, grep the component's own `static template` — if it's the literal
|
|
117
|
+
`() => null`, shape 2 cannot be the cause, no matter how closely the symptom
|
|
118
|
+
matches the old description. [`failure-shapes.md`](references/failure-shapes.md)
|
|
119
|
+
§2 has the full survey (150 components checked) and cites exactly why every
|
|
120
|
+
current children-accepting component is unaffected.
|
|
121
|
+
|
|
122
|
+
## Corpus of record
|
|
123
|
+
|
|
124
|
+
Routing-eval corpus: [`evals/routing-corpus.json`](evals/routing-corpus.json).
|
|
125
|
+
This pack is hand-authored from verified session work (not a research-wave corpus) —
|
|
126
|
+
re-sync it per [`status-ledger.md`](references/status-ledger.md)'s own instructions
|
|
127
|
+
whenever an issue referenced here changes state, rather than letting the ledger and
|
|
128
|
+
reality drift apart silently.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# adia-ssr skill audit (FLOOR)
|
|
2
|
+
|
|
3
|
+
Skill: `packages/plugins/adia-ui-forge/skills/adia-ssr/` · Standards: skill-authoring-standards · Lint: clean
|
|
4
|
+
Verdict: **PASS**
|
|
5
|
+
|
|
6
|
+
Species: knowledge (`disable-model-invocation: false`, `user-invocable: false`) — sibling in
|
|
7
|
+
shape to `packages/plugins/adia-ui-factory/skills/adia-tokens/`, confirmed.
|
|
8
|
+
|
|
9
|
+
| ID | Verdict | Severity | Evidence (file:line) | Fix |
|
|
10
|
+
|----|---------|----------|----------------------|-----|
|
|
11
|
+
| R1 Behavior delta | PASS | — | `SKILL.md:67-73` (caveat: don't invent a component-local workaround for gh#284 — deleting it removes the one line steering Claude away from a plausible wrong answer); `SKILL.md:36-38` (gh#288 dependency on gh#284 — deleting it, Claude could treat #288 as independently actionable); `SKILL.md:51` (test-without-linkedom consult row — deleting it loses the exact routing signal to the one file that explains why the repo's default test env can't reproduce SSR bugs) | none |
|
|
12
|
+
| R2 Trigger fidelity | PASS | — | Description (`SKILL.md:3-10`) phrasings "does X work under SSR", "why does X crash/disappear when server-rendered", "is this connect-time read safe" are the literal `should_route_to_ssr: true` phrases in `evals/routing-corpus.json:20,35,90`; fences ("NOT for implementing a fix (adia-author) or consumer host/hydration wiring (adia-host...)") correctly repel `ssr-adversarial-01/02/05` (routing-corpus.json:104-107, 110-114, 130-135) | none |
|
|
13
|
+
| R3 Species/dial agreement | PASS | — | `SKILL.md:11-12` both dials explicit and correct for knowledge species; name `adia-ssr` follows the established local `adia-*` topic-noun convention (matches sibling `adia-tokens`, `adia-a2ui`) rather than the generic `x-patterns` grammar — acceptable under the project's own precedent | none |
|
|
14
|
+
| R4 Register | PASS | — | Load-bearing lines cite exact file:line, PR, and issue numbers rather than describing generically, e.g. `SKILL.md:63-66` ("`UIElement.connectedCallback`... calls `stamp(result, this)`... currently line 194") — verified accurate, see Notes | none |
|
|
15
|
+
| R5 No restatement | PASS | — | No drift-pair found against `component-token-contract.md` / `component-implementation-patterns.md` / AGENTS.md — none cover SSR. Pack explicitly fences out generic web-components-SSR theory (`SKILL.md:97-99`), so it doesn't restate model-general knowledge either | none |
|
|
16
|
+
| R6 Position | MINOR | minor | Body is only ~108 lines (~2,000 tokens, well inside the 5,000-token survival window, so no practical compaction risk) — but structurally, "Deviation doctrine" and "Boundaries" (`SKILL.md:75-99`, gate-shaped content) sit *after* the "Worked example" (`SKILL.md:55-74`), inverted from the "contracts/gates first, examples last" rule | Move Deviation doctrine + Boundaries above the Worked example on next semantic edit; not urgent given total size |
|
|
17
|
+
| R8 Quantities | PASS | — | `127+ primitives`, `24 component/trait/module files`, `12 files` calling `this.internals.*`, `~110-line shim`, dated `2026-07-17`, gh#284-288 — all load-bearing counts are numeric, none vague | none |
|
|
18
|
+
|
|
19
|
+
R7 (Contracts): N/A — knowledge species, not procedural/command.
|
|
20
|
+
|
|
21
|
+
## Notes — factual grounding (beyond the R1-R8 checklist, but relevant to a knowledge pack's core promise)
|
|
22
|
+
|
|
23
|
+
Spot-checked every concrete claim against the actual repo state rather than trusting the pack's
|
|
24
|
+
own self-description:
|
|
25
|
+
|
|
26
|
+
- `packages/web-components/core/template.js:194` — `export function stamp(result, container)` is
|
|
27
|
+
exactly where `failure-shapes.md` and the Worked example say it is.
|
|
28
|
+
- `packages/web-components/core/element.js` — `attachInternals` shim (`this.internals = typeof
|
|
29
|
+
this.attachInternals === 'function' ? this.attachInternals() : NOOP_INTERNALS`),
|
|
30
|
+
`adoptedStyleSheets` guard (`if (!('adoptedStyleSheets' in document)) return;`), and the
|
|
31
|
+
`connectedCallback` → `stamp()` call all match `guard-patterns.md` and `failure-shapes.md`
|
|
32
|
+
verbatim.
|
|
33
|
+
- `packages/web-modules/shell/admin-sidebar/admin-sidebar.js` — `#syncCollapsedFromWidth` (zero-rect
|
|
34
|
+
`return` before the decision) and `#setupChildResizeObserver` (`typeof ResizeObserver ===
|
|
35
|
+
'undefined'` guard, deferred correction) match `guard-patterns.md` §3's cited code exactly,
|
|
36
|
+
including `SNAP_THRESHOLD`.
|
|
37
|
+
- `packages/web-components/core/element.test.js:259` — the `describe('UIElement — SSR
|
|
38
|
+
browser-API absence (gh#285)'` block matches `test-without-linkedom.md`'s cited delete/try/finally
|
|
39
|
+
pattern.
|
|
40
|
+
- `git log`: PR #292 (gh#285) and PR #290 (gh#286) both merged 2026-07-17, matching every date
|
|
41
|
+
cited in `status-ledger.md` and `consumer-workarounds.md`.
|
|
42
|
+
- No `linkedom` in any `package.json` in the tree — confirms `test-without-linkedom.md`'s central
|
|
43
|
+
claim.
|
|
44
|
+
- Live `gh issue view` for 284-288 today: #284 OPEN, #285 CLOSED, #286 CLOSED, #287 OPEN, #288
|
|
45
|
+
OPEN — matches `status-ledger.md`'s table exactly, row for row, including the "#287 is
|
|
46
|
+
unrelated" framing.
|
|
47
|
+
|
|
48
|
+
Every citable fact in this pack checked out. This is unusually high grounding for a hand-authored
|
|
49
|
+
knowledge pack — worth naming as the standard other `adia-*` knowledge skills should be held to.
|
|
50
|
+
|
|
51
|
+
## Top 3
|
|
52
|
+
|
|
53
|
+
1. **Ship as-is.** Zero blocking or major findings; lint clean; every code/issue citation
|
|
54
|
+
independently verified against the live repo and `gh issue view` — the pack's core promise
|
|
55
|
+
("cited to the actual shipped/open code") is actually true today, not just claimed.
|
|
56
|
+
2. **Routing corpus is well-formed and matches its own spec** — 12 trigger / 5 adversarial phrases
|
|
57
|
+
(29.4% adversarial, spec says ~29%), all 5 reference files covered by `expected_shape`, and the
|
|
58
|
+
3 adversarial near-misses (gh#287 bundler bug, a2ui pipeline, generic hydration theory) are
|
|
59
|
+
genuinely hard boundary cases, not straw men.
|
|
60
|
+
3. **One minor, non-blocking structural nit (R6):** the gate-shaped "Deviation doctrine" and
|
|
61
|
+
"Boundaries" sections trail the "Worked example" instead of leading it. Harmless at this body
|
|
62
|
+
size (~2K tokens, nowhere near the 5K compaction cutoff) — fix opportunistically on the next
|
|
63
|
+
semantic edit to this file, not worth a dedicated pass.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"positives": [
|
|
3
|
+
"why does text-ui render empty when we server-render it with Astro",
|
|
4
|
+
"our SSR pass crashes on attachInternals not being a function",
|
|
5
|
+
"does select-ui work under linkedom",
|
|
6
|
+
"admin-sidebar snaps collapsed on every server-rendered page load",
|
|
7
|
+
"is gh#284 fixed yet, can we drop the attribute-only SSR registration restriction",
|
|
8
|
+
"how do we test that a new ResizeObserver guard actually works without installing linkedom",
|
|
9
|
+
"new ResizeObserver() throws under our DOM-shim SSR environment",
|
|
10
|
+
"table-ui and chart-ui always render empty in our server-rendered HTML even though the data is set",
|
|
11
|
+
"what's the actual root cause of the SSR content-loss bug, container CEs losing their nested children",
|
|
12
|
+
"can our app finally delete the 110-line browser-API shim now that 0.8.5 is out",
|
|
13
|
+
"is it safe to call getBoundingClientRect() synchronously in connectedCallback",
|
|
14
|
+
"document.adoptedStyleSheets is undefined and our component library crashes on import"
|
|
15
|
+
],
|
|
16
|
+
"negatives": [
|
|
17
|
+
"add hydration-aware stamping so connectedCallback stops overwriting existing children",
|
|
18
|
+
"set up Astro's rendering mode and hydration boundaries for our admin app",
|
|
19
|
+
"explain how custom element hydration works in general, independent of any specific framework",
|
|
20
|
+
"the icon registry comes back empty because of a workspace-hoisting import.meta.glob path bug",
|
|
21
|
+
"wire up the a2ui generation pipeline to run inside a server-rendered page",
|
|
22
|
+
"add a new primitive to the component catalog",
|
|
23
|
+
"compose the billing settings screen from the catalog",
|
|
24
|
+
"deploy the latest build to ui-kit.exe.xyz"
|
|
25
|
+
],
|
|
26
|
+
"_measured": {
|
|
27
|
+
"as_of": "2026-07-18",
|
|
28
|
+
"scorer": "routing_eval.py (nonoun-plugins/forge)",
|
|
29
|
+
"f1": 0.957,
|
|
30
|
+
"precision": 1.0,
|
|
31
|
+
"recall": 0.917,
|
|
32
|
+
"exit_code": 0
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# The consumer's current workarounds — what they look like, why they're fragile
|
|
2
|
+
|
|
3
|
+
Two real consumers — adiav2's `admin-portal-fe` and `factory-dashboard` — SSR AdiaUI
|
|
4
|
+
via Astro 5 + `custom-elements-ssr` (linkedom). Each open issue names a workaround
|
|
5
|
+
they currently maintain in their OWN app code (not in this framework). Knowing the
|
|
6
|
+
shape of each matters for two reasons: (1) it tells you what "done" looks like — the
|
|
7
|
+
workaround should become deletable once the underlying gh issue closes; (2) it's the
|
|
8
|
+
concrete evidence for WHY each open issue matters, beyond the abstract description.
|
|
9
|
+
|
|
10
|
+
## The ~110-line browser-API shim (gh#285 — now deletable, unconfirmed)
|
|
11
|
+
|
|
12
|
+
Before every component module import, the consumer's SSR entry point ran a
|
|
13
|
+
prototype-patching shim: stubbed `attachInternals`, defined four no-op Observer
|
|
14
|
+
classes (`ResizeObserver`/`IntersectionObserver`/`MutationObserver`/`PerformanceObserver`),
|
|
15
|
+
and force-assigned `document.adoptedStyleSheets = []`. Two named fragilities:
|
|
16
|
+
- **Fragile import order** — the shim MUST execute before any component module
|
|
17
|
+
loads, or the "deep-render pass" crashes anyway. This already broke once in a
|
|
18
|
+
production bundle (per the issue) — a bundler/tree-shaking change that reordered
|
|
19
|
+
imports silently reintroduced the crash.
|
|
20
|
+
- **A global patch, not scoped** — patching `HTMLElement.prototype` /
|
|
21
|
+
`globalThis.ResizeObserver` affects EVERY component and every other library in the
|
|
22
|
+
same process, not just AdiaUI's.
|
|
23
|
+
|
|
24
|
+
**Status as of gh#285's fix (PR #292, merged 2026-07-17): this shim should no longer
|
|
25
|
+
be necessary** — the framework guards its own call sites now. This pack's own routing
|
|
26
|
+
corpus / the issue thread is where confirmation from the consumer would land; don't
|
|
27
|
+
assume it's been removed without checking the issue's comment thread for that
|
|
28
|
+
confirmation, since a consumer removing a workaround is THEIR change, not something
|
|
29
|
+
this fix does automatically.
|
|
30
|
+
|
|
31
|
+
## Attribute-only SSR registration restriction (gh#284 — likely no longer necessary, unconfirmed)
|
|
32
|
+
|
|
33
|
+
The consumer restricts server-side custom-element registration to components whose
|
|
34
|
+
visible content derives ENTIRELY from attributes — `button-ui text="…"`, `icon-ui
|
|
35
|
+
name="…"`. Every container (`admin-shell`, `admin-sidebar`, `nav-ui`) and every
|
|
36
|
+
projected-text component (`text-ui`, `avatar-ui`, `badge-ui`, and by extension
|
|
37
|
+
anything using `<component>slotted text</component>` markup) must register
|
|
38
|
+
CLIENT-side only, upgrading after first paint.
|
|
39
|
+
|
|
40
|
+
**Status as of gh#284's narrowing (2026-07-17): the STAMP() reason for this
|
|
41
|
+
restriction is gone** — every component it names (and every other shipped
|
|
42
|
+
component with real content) currently derives its visible content from
|
|
43
|
+
properties/attributes only, never from light-DOM children, so `stamp()`'s
|
|
44
|
+
destructive replace never fires against real content for any of them (see
|
|
45
|
+
[`failure-shapes.md`](failure-shapes.md) §2 for the empirical survey). This did
|
|
46
|
+
NOT ship as a `stamp()` fix — it's a narrowing based on the CURRENT shape of the
|
|
47
|
+
component set, backed by a forward static audit
|
|
48
|
+
(`scripts/dev/audit-template-child-conflict.mjs`) that would catch a future
|
|
49
|
+
regression.
|
|
50
|
+
|
|
51
|
+
**UPDATE 2026-07-18 — but there WAS a second, independent, real reason this
|
|
52
|
+
restriction was justified, now also fixed.** Every component this restriction
|
|
53
|
+
names is attribute/property-driven — and until PR #309, attribute-driven
|
|
54
|
+
content was ITSELF broken under a late/SSR upgrade (see `failure-shapes.md` §2's
|
|
55
|
+
"UPDATE 2026-07-18" and `guard-patterns.md` §2b): `attributeChangedCallback`
|
|
56
|
+
never replayed for pre-existing attributes on upgrade, so `<nav-item-ui
|
|
57
|
+
text="Profile">` rendered with an empty label regardless of the stamp()
|
|
58
|
+
question. That's now fixed at the framework level (`element.js`
|
|
59
|
+
`connectedCallback`). So as of the version carrying PR #309, both reasons this
|
|
60
|
+
restriction existed are addressed — not just the one gh#284 originally named.
|
|
61
|
+
|
|
62
|
+
As with gh#285's shim: don't assume the consumer has actually
|
|
63
|
+
relaxed this restriction without checking the issue thread for their confirmation
|
|
64
|
+
— a consumer removing their own workaround is their change, not something this
|
|
65
|
+
narrowing does automatically. If the consumer's linkedom/`custom-elements-ssr`
|
|
66
|
+
setup surfaces something this repo's own repro didn't (a real second-connect
|
|
67
|
+
timing difference, an app-level component not covered by this framework), that's
|
|
68
|
+
new information worth feeding back into the issue, not something to assume away.
|
|
69
|
+
|
|
70
|
+
## gh#288 (property-only components) — CLOSED 2026-07-18, workaround droppable
|
|
71
|
+
|
|
72
|
+
The consumer's PRE-fix behavior for `table-ui`/`chart-ui`/`select-ui` with
|
|
73
|
+
programmatic content was: render empty in the SSR response, then a per-page
|
|
74
|
+
wiring script does `customElements.whenDefined(...) → getElementById → assign
|
|
75
|
+
properties` after hydration. As of the fix, that boilerplate is droppable for all
|
|
76
|
+
three — `select-ui` via native `<option>` children (already worked, pre-existing),
|
|
77
|
+
`chart-ui` via a `data="[…]"` JSON attribute (already worked, pre-existing),
|
|
78
|
+
`table-ui` via the same `data="[…]"` attribute (new) plus `<col-def>` children for
|
|
79
|
+
columns (pre-existing). Don't assume the consumer has removed the wiring script
|
|
80
|
+
without their confirmation — see [`failure-shapes.md`](failure-shapes.md) §4 for
|
|
81
|
+
the full narrative.
|