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

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 (58) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +25 -0
  3. package/README.md +13 -4
  4. package/agents/a2ui-builder.corpus.json +35 -0
  5. package/agents/a2ui-builder.md +37 -0
  6. package/agents/component-author.corpus.json +40 -0
  7. package/agents/component-author.md +10 -1
  8. package/agents/framework-reviewer.corpus.json +35 -0
  9. package/agents/{framework-verifier.md → framework-reviewer.md} +16 -7
  10. package/agents/release-builder.corpus.json +39 -0
  11. package/agents/release-builder.md +39 -0
  12. package/agents/routing-corpus.json +39 -39
  13. package/bin/sidecar-prewrite-guard +17 -0
  14. package/bin/site-postwrite-derivation-gate +180 -0
  15. package/commands/release.md +5 -3
  16. package/hooks/hooks.json +4 -0
  17. package/package.json +1 -1
  18. package/references/contracts/a2ui-mcp-surface.md +1 -1
  19. package/skills/adia-a2ui/SKILL.md +27 -6
  20. package/skills/adia-a2ui/evals/routing-corpus.json +36 -29
  21. package/skills/adia-a2ui/references/zettel-calibration.md +5 -5
  22. package/skills/adia-author/SKILL.md +15 -8
  23. package/skills/adia-author/evals/routing-corpus.json +39 -218
  24. package/skills/adia-author/references/authoring-cycle.md +19 -0
  25. package/skills/adia-author/references/code-style.md +0 -1
  26. package/skills/adia-author/references/llm-bridge.md +7 -0
  27. package/skills/adia-author/references/worked-example.md +18 -2
  28. package/skills/adia-deploy/SKILL.md +33 -18
  29. package/skills/adia-deploy/evals/routing-corpus.json +33 -142
  30. package/skills/adia-dogfood/SKILL.md +11 -4
  31. package/skills/adia-dogfood/evals/routing-corpus.json +30 -142
  32. package/skills/adia-dogfood/references/admin-shell-anatomy.md +1 -1
  33. package/skills/adia-dogfood/references/visual-probe-triage.md +1 -5
  34. package/skills/adia-gen-review/SKILL.md +18 -7
  35. package/skills/adia-gen-review/evals/routing-corpus.json +30 -142
  36. package/skills/adia-gen-review/scripts/gen-review-decompose.mjs +5 -0
  37. package/skills/adia-llm-internals/SKILL.md +10 -6
  38. package/skills/adia-llm-internals/evals/routing-corpus.json +33 -142
  39. package/skills/adia-llm-internals/references/bridge-facade.md +2 -2
  40. package/skills/adia-llm-internals/references/streaming-sse.md +1 -1
  41. package/skills/adia-release/SKILL.md +40 -17
  42. package/skills/adia-release/evals/routing-corpus.json +35 -0
  43. package/skills/adia-release/references/changelog-discipline.md +14 -8
  44. package/skills/adia-release/references/cut-procedure.md +48 -28
  45. package/skills/adia-release/references/independent-package-release.md +1 -1
  46. package/skills/adia-release/scripts/insert-stub.mjs +1 -1
  47. package/skills/adia-release/scripts/release-pack.mjs +42 -14
  48. package/skills/adia-site-docs/SKILL.md +6 -1
  49. package/skills/adia-site-docs/evals/routing-corpus.json +35 -173
  50. package/skills/adia-ssr/SKILL.md +32 -14
  51. package/skills/adia-ssr/evals/routing-corpus.json +32 -136
  52. package/skills/adia-ssr/references/consumer-workarounds.md +33 -15
  53. package/skills/adia-ssr/references/failure-shapes.md +49 -7
  54. package/skills/adia-ssr/references/guard-patterns.md +41 -0
  55. package/skills/adia-ssr/references/status-ledger.md +5 -7
  56. package/skills/adia-ssr/references/test-without-linkedom.md +28 -12
  57. package/agents/a2ui-engineer.md +0 -26
  58. package/agents/release-engineer.md +0 -26
@@ -4,8 +4,11 @@
4
4
  // Chains the 5 CLI helpers (bump · promote-unreleased · insert-stub ·
5
5
  // tag-lockstep · dispatch-publish) plus the non-helper steps (lockfile ·
6
6
  // pre-flight gates · git commit · F-N1 · push · GH releases · site
7
- // deploy) into one walked sequence with 3 operator checkpoints (before
8
- // tag, before push, before publish) per SKILL.md operator checkpoints.
7
+ // deploy) into one walked sequence with 4 confirmation boundaries (before
8
+ // tag, before push, before publish, before deploy dispatch). Under the
9
+ // single-authorization model (SKILL.md §Authorization, operator ruling
10
+ // 2026-07-17) `--go` auto-confirms all of them — the evidence blocks still
11
+ // print as a log; the granular flags below remain for cautious manual runs.
9
12
  //
10
13
  // MODES (two-phase since 2026-07-16 — invariant 3: release commits land via
11
14
  // PR, so the cut modes stop after the release commit; handoff runs the
@@ -35,22 +38,27 @@
35
38
  // --stub-packages a,b,c : packages getting the lockstep stub
36
39
  //
37
40
  // FLAGS:
41
+ // --go : single-authorization — the operator's cut-start go
42
+ // covers the whole cycle; equals --yes --push --publish.
43
+ // THE standard invocation for an operator-initiated
44
+ // release. An F-N1 warn still refuses auto-confirm at
45
+ // the push boundary (a gate failure, not ceremony).
38
46
  // --dry : preview all commands, no mutation, no prompts
39
- // --yes : auto-confirm CHECKPOINT 1 ONLY (before tagging). Tag
40
- // creation is the least destructive of the three
41
- // mutating boundaries (moving/deleting a local-only
42
- // tag is free); push and publish each need their own
43
- // explicit go — --yes does not cover them (H5/defect-2:
44
- // a single --yes used to flatten all 3 checkpoints).
45
- // --push : auto-confirm CHECKPOINT 2 (before pushing tags)
46
- // --publish : auto-confirm CHECKPOINT 3 (before dispatching publishes)
47
+ // --yes : auto-confirm the tag boundary ONLY. Tag creation is
48
+ // the least destructive of the mutating boundaries
49
+ // (moving/deleting a local-only tag is free); push and
50
+ // publish each need their own flag --yes does not
51
+ // cover them (H5/defect-2: a single --yes used to
52
+ // flatten every boundary).
53
+ // --push : auto-confirm the push-tags boundary
54
+ // --publish : auto-confirm the publish + deploy-dispatch boundaries
47
55
  // --skip-gates : (DEBUG ONLY) skip pre-flight (don't ship anything!)
48
56
  // --skip-site : skip the EXE deploy step (rare; for offline cycles)
49
57
  //
50
58
  // Part of the adia-release skill. Mechanizes the cut procedure from
51
- // references/cut-procedure.md while preserving operator judgment at
52
- // the 3 mutating-checkpoint boundaries. Every checkpoint prints its evidence
53
- // block BEFORE the prompt (H5) — never a bare y/N.
59
+ // references/cut-procedure.md. Every confirmation boundary prints its evidence
60
+ // block BEFORE the prompt (H5) never a bare y/N — whether it waits for input
61
+ // (manual flags) or auto-confirms (--go).
54
62
 
55
63
  import { execSync } from 'node:child_process';
56
64
  import { createInterface } from 'node:readline/promises';
@@ -108,6 +116,14 @@ function parseArgs(argv) {
108
116
  else if (k === '--yes') args.yes = true;
109
117
  else if (k === '--push') args.push = true;
110
118
  else if (k === '--publish') args.publish = true;
119
+ // --go: the single-authorization model (operator ruling 2026-07-17,
120
+ // replacing the 4-checkpoint ceremony after the v0.8.5 cut spent ~40
121
+ // minutes on approval relays that produced zero safety). The operator's
122
+ // cut-start instruction covers the WHOLE cycle; the run stops only on
123
+ // gate failures. Equivalent to --yes --push --publish; the F-N1
124
+ // error hard-stop and the warn-blocks-auto-confirm rule still apply —
125
+ // those are gates, not approvals, and no flag skips them.
126
+ else if (k === '--go') { args.yes = true; args.push = true; args.publish = true; }
111
127
  else if (k === '--skip-gates') args.skipGates = true;
112
128
  else if (k === '--skip-site') args.skipSite = true;
113
129
  else if (k === '-h' || k === '--help') { help(); process.exit(0); }
@@ -144,7 +160,10 @@ function help() {
144
160
  --substantive-packages web-components,web-modules,a2ui/corpus \\
145
161
  --stub-packages llm,a2ui/compose,a2ui/mcp,a2ui/retrieval,a2ui/runtime,a2ui/validator
146
162
 
147
- Flags: --dry (preview all) --yes (auto-confirm checkpoint 1 ONLY tag)
163
+ Flags: --go (single-authorization: the operator's cut-start go covers the
164
+ whole cycle — auto-confirms ALL checkpoints; stops only on
165
+ gate failures. THE DEFAULT for an operator-initiated release.)
166
+ --dry (preview all) --yes (auto-confirm checkpoint 1 ONLY — tag)
148
167
  --push (auto-confirm checkpoint 2 — push tags)
149
168
  --publish (auto-confirm checkpoint 3 — dispatch publishes)
150
169
  --skip-site (skip EXE deploy)
@@ -311,6 +330,15 @@ function step4PromoteAndBump(args) {
311
330
  sh(`node ${SCRIPT_DIR}/bump.mjs --from ${args.previous} --to ${args.version}`, args);
312
331
  sh('npm install --package-lock-only --no-audit --no-fund', args);
313
332
  sh('npm run check:lockstep', args);
333
+
334
+ // Step 4f — pre-tag F-N1 coverage with auto-fix, run with the AUTHORITATIVE
335
+ // matcher (check-release.mjs itself, not the drifted 9-package
336
+ // check-changelog-coverage.mjs). Appends verified Maintenance bullets for
337
+ // any changed-but-unmentioned directory so the post-tag F-N1 (Step 7) is a
338
+ // formality. The v0.8.5 cut lacked this and paid 3 enrichment PRs + 3
339
+ // delete/retag rounds discovering the same gaps only after tagging.
340
+ console.log('\n Step 4f — pre-tag coverage (+auto-fix) with the authoritative F-N1 matcher:');
341
+ sh(`node scripts/release/check-release.mjs --pending-version ${args.version} --fix`, args);
314
342
  }
315
343
 
316
344
  // ── Step 5 — Commit ──────────────────────────────────────────────
@@ -35,7 +35,7 @@ skill routes to it and enforces it, it does not restate it.
35
35
  | Task shape | Do |
36
36
  | --- | --- |
37
37
  | New page in an owned category | Read the convention doc's template section; copy the shared skeleton from a sibling page in the same category (narrative archetype vs. reference/gallery archetype). |
38
- | Callout / "meta content" block | `<alert-ui variant="warning\|info\|...">` with `<div slot="content">` (never `<span>` — the transpiler only treats `p`/`div`/`ul`/`ol` as prose; a `<span>` silently reorders mixed inline content on regen) for rich text — never a bare `data-*` attribute. A whole multi-heading section aimed at a different reader (not a short callout) is NOT `alert-ui`'s job either (wrong shape)currently there's no working distinguishing treatment for this case beyond the heading text itself; see the convention doc's rule 2 for what's been tried and why it doesn't render. |
38
+ | Callout / "meta content" block | `<alert-ui variant="warning\|info\|...">` with `<div slot="content">` (never `<span>` — the transpiler only treats `p`/`div`/`ul`/`ol` as prose; a `<span>` silently reorders mixed inline content on regen) for rich text — never a bare `data-*` attribute. A whole multi-heading section aimed at a different reader (not a short callout) is NOT `alert-ui`'s job either wrong shape — the convention doc's rule 2 carries the working treatment (eyebrow `<tag-ui>` title-row, TKT-0011). |
39
39
  | Tamed admin-shell demo | Add `class="demo-frame"` to the shell instance + a page-local `<style>` block setting only `--demo-frame-height` (and any genuinely page-specific extra). That's `site/site.css`'s `.demo-frame` utility already covering `position`/`border`/`overflow`/`.demo-body` padding. |
40
40
  | A surface needs to read as "its own distinct object" against the page background (a chip, a pill) | Reuse `--a-canvas-well-strong` (`packages/web-components/styles/colors/semantics/core.css`) — verified ≥3:1 (WCAG 2.2 SC 1.4.11) in both schemes. `--a-canvas-well` alone is for a subtly-sunken panel; a new candidate token always runs through `color:color-verify` first. |
41
41
  | "Is this page consistent?" / review request | Check the page against the convention doc's rules 1–4 by name; a finding names the specific rule violated, not just "this looks off." |
@@ -63,6 +63,11 @@ A check that cannot run (missing script, no network for a build step) is a
63
63
  named blocker in the report — flag it and stop; never mark the page done on
64
64
  an assumed pass.
65
65
 
66
+ The fresh-context critic for an authored page is the `framework-reviewer`
67
+ agent (its dogfood visual probe covers rendered site surfaces) — the author
68
+ never certifies their own page's rendered result; the mechanical checks
69
+ above plus that read-only pass together are the review.
70
+
66
71
  Done when the touched page(s) pass the checks above and, for a reviewed
67
72
  page, every finding cites the specific rule in `site-pages-authoring.md` it
68
73
  violates.
@@ -1,176 +1,38 @@
1
1
  {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "name": "adia-site-docs routing accuracy corpus",
4
- "version": "1.0.0",
5
- "purpose": "Routing-eval corpus for adia-site-docs (adia-forge plugin). Each phrase declares whether adia-site-docs SHOULD be the routing target. Scored by the estate's TF-IDF routing-eval runner against the skill's description (heuristic token overlap).",
6
- "scoring_notes": "Heuristic signal, not ground truth. Treat misroutes as a prompt to tighten the skill description, never as a reason to keyword-stuff it. Real harness routing is LLM-driven.",
7
- "license": "internal",
8
- "scope": "adia-site-docs routing does this phrase activate adia-site-docs?",
9
-
10
- "minimums_per_spec": {
11
- "trigger_phrases": 16,
12
- "adversarial_phrases": 6,
13
- "task_shapes_covered": "new-page, review-page, callout-fix, demo-frame-consistency, contrast-token, sibling-boundary",
14
- "adversarial_fraction": "27%"
15
- },
16
-
17
- "phrases": [
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
- "evaluator_notes": "Adversarial phrases 1-2 specifically test the two hardest-to-distinguish fences (component .examples.html vs site/pages/patterns/*.html; site/pages/examples/** vs site/pages/{architecture,getting-started,guides,patterns,reference}/**) — both surfaces are literally *.html under similar-looking paths, so the description must lean on the explicit path lists, not just 'site pages' as a phrase."
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
  }
@@ -2,12 +2,16 @@
2
2
  name: adia-ssr
3
3
  description: >-
4
4
  Answers why an AdiaUI component crashes, drops content, or renders wrong
5
- under SSR (linkedom/Astro consumers) — the three known failure shapes,
5
+ under SSR (linkedom/Astro consumers) — the four known failure shapes,
6
6
  what's fixed vs open, how to test without a linkedom install. Use when
7
- asked "does this work under SSR", "why does X crash/disappear when
8
- server-rendered", or "is this connect-time read safe". ANSWERS only. NOT
9
- for implementing a fix (adia-author) or consumer host/hydration wiring
10
- (adia-host, adia-ui-factory plugin).
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).
11
15
  disable-model-invocation: false
12
16
  user-invocable: false
13
17
  ---
@@ -17,26 +21,40 @@ user-invocable: false
17
21
  Two real consumers (adiav2's `admin-portal-fe` and `factory-dashboard`) server-render
18
22
  AdiaUI's light-DOM components via Astro 5 + `custom-elements-ssr`, which runs on
19
23
  linkedom — a DOM shim with no layout engine and missing browser APIs the framework's
20
- base class assumes exist. Every SSR bug that's surfaced maps onto one of three root-cause
24
+ base class assumes exist. Every SSR bug that's surfaced maps onto one of four root-cause
21
25
  shapes; misclassifying a new report against the wrong shape sends the investigation
22
26
  to the wrong fix (or worse, invents a redundant one). This pack answers "which shape is
23
27
  this" and "what's the state of each shape's fix" — it never carries the fix itself.
24
28
 
25
- ## The three shapes, in one line each
29
+ ## The four shapes, in one line each
26
30
 
27
31
  1. **A browser-only API is called unconditionally → crash.** `attachInternals`,
28
32
  the four Observer constructors, `document.adoptedStyleSheets`. **Fixed** (gh#285).
29
33
  2. **`connectedCallback` destructively re-stamps existing DOM → silent content loss.**
30
- The mechanism is real, but **narrowed to a static audit** (gh#284, 2026-07-17) —
31
- zero shipped components currently pair a non-null template with real light-DOM
32
- content, so nothing is exposed today; a forward audit catches a future regression.
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.
33
47
  3. **A connect-time layout measurement is treated as confirmed, not unknown.** A zero
34
48
  rect (shim, or real pre-layout connect) drives a wrong persistent decision.
35
49
  **Fixed for one component** (gh#286); the general pattern is unswept.
36
50
 
37
- A fourth item, **property-only components can't seed initial state from SSR HTML**
38
- (gh#288), is a feature gap explicitly blocked on shape 2's resolution don't treat it
39
- as its own independent task.
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.
40
58
 
41
59
  Full symptom → root-cause → status detail, cited to the actual shipped/open code:
42
60
  [`references/failure-shapes.md`](references/failure-shapes.md).
@@ -51,7 +69,7 @@ Full symptom → root-cause → status detail, cited to the actual shipped/open
51
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 |
52
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 |
53
71
  | "what's the consumer's current workaround, and can they drop it yet" | [`consumer-workarounds.md`](references/consumer-workarounds.md) |
54
- | "table/chart/select renders empty in the SSR response" | [`failure-shapes.md`](references/failure-shapes.md) §4 — shape 4, blocked on shape 2 |
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 |
55
73
 
56
74
  ## Deviation doctrine
57
75
 
@@ -1,138 +1,34 @@
1
1
  {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "name": "adia-ssr routing accuracy corpus",
4
- "version": "1.0.0",
5
- "purpose": "Routing-eval corpus for adia-ssr (adia-forge plugin). Each phrase declares whether adia-ssr SHOULD be the routing target. Scored by the estate's TF-IDF routing-eval runner against the skill's description (heuristic token overlap).",
6
- "scoring_notes": "Heuristic signal, not ground truth. Treat misroutes as a prompt to tighten the skill description, never as a reason to keyword-stuff it. Real harness routing is LLM-driven.",
7
- "license": "internal",
8
- "scope": "adia-ssr routing does this phrase activate adia-ssr?",
9
-
10
- "minimums_per_spec": {
11
- "trigger_phrases": 12,
12
- "adversarial_phrases": 5,
13
- "task_shapes_covered": "failure-shapes, guard-patterns, status-ledger, test-without-linkedom, consumer-workarounds",
14
- "adversarial_fraction": "~29%"
15
- },
16
-
17
- "phrases": [
18
- {
19
- "id": "ssr-trigger-01",
20
- "phrase": "why does text-ui render empty when we server-render it with Astro",
21
- "should_route_to_ssr": true,
22
- "expected_shape": "failure-shapes",
23
- "rationale": "Canonical shape-2 symptom (projected-text content loss) — the worked example in SKILL.md."
24
- },
25
- {
26
- "id": "ssr-trigger-02",
27
- "phrase": "our SSR pass crashes on attachInternals not being a function",
28
- "should_route_to_ssr": true,
29
- "expected_shape": "guard-patterns",
30
- "rationale": "Directly names the highest-leverage shape-1 crash site the pack documents."
31
- },
32
- {
33
- "id": "ssr-trigger-03",
34
- "phrase": "does select-ui work under linkedom",
35
- "should_route_to_ssr": true,
36
- "expected_shape": "failure-shapes",
37
- "rationale": "The pack's core orienting question — 'does X work under SSR'."
38
- },
39
- {
40
- "id": "ssr-trigger-04",
41
- "phrase": "admin-sidebar snaps collapsed on every server-rendered page load",
42
- "should_route_to_ssr": true,
43
- "expected_shape": "failure-shapes",
44
- "rationale": "Shape-3 symptom (connect-time measurement treated as confirmed) — the gh#286 precedent."
45
- },
46
- {
47
- "id": "ssr-trigger-05",
48
- "phrase": "is gh#284 fixed yet, can we drop the attribute-only SSR registration restriction",
49
- "should_route_to_ssr": true,
50
- "expected_shape": "status-ledger",
51
- "rationale": "Direct status-ledger ask, names the issue and the exact consumer workaround."
52
- },
53
- {
54
- "id": "ssr-trigger-06",
55
- "phrase": "how do we test that a new ResizeObserver guard actually works without installing linkedom",
56
- "should_route_to_ssr": true,
57
- "expected_shape": "test-without-linkedom",
58
- "rationale": "Canonical test-methodology ask this pack's most concrete axis exists for."
59
- },
60
- {
61
- "id": "ssr-trigger-07",
62
- "phrase": "new ResizeObserver() throws under our DOM-shim SSR environment",
63
- "should_route_to_ssr": true,
64
- "expected_shape": "guard-patterns",
65
- "rationale": "Shape-1 crash, observer-construction variant — guard-patterns §1 shape (a)/(b)/(c)."
66
- },
67
- {
68
- "id": "ssr-trigger-08",
69
- "phrase": "table-ui and chart-ui always render empty in our server-rendered HTML even though the data is set",
70
- "should_route_to_ssr": true,
71
- "expected_shape": "failure-shapes",
72
- "rationale": "Shape-4 (property-only components, gh#288), explicitly named as blocked on shape 2."
73
- },
74
- {
75
- "id": "ssr-trigger-09",
76
- "phrase": "what's the actual root cause of the SSR content-loss bug, container CEs losing their nested children",
77
- "should_route_to_ssr": true,
78
- "expected_shape": "failure-shapes",
79
- "rationale": "Shape-2 container-CE symptom, the other half of the worked example's shape."
80
- },
81
- {
82
- "id": "ssr-trigger-10",
83
- "phrase": "can our app finally delete the 110-line browser-API shim now that 0.8.5 is out",
84
- "should_route_to_ssr": true,
85
- "expected_shape": "consumer-workarounds",
86
- "rationale": "Direct ask about a named consumer workaround's deletability."
87
- },
88
- {
89
- "id": "ssr-trigger-11",
90
- "phrase": "is it safe to call getBoundingClientRect() synchronously in connectedCallback",
91
- "should_route_to_ssr": true,
92
- "expected_shape": "guard-patterns",
93
- "rationale": "Shape-3 general-principle ask ('unknown vs confirmed'), independent of any specific component."
94
- },
95
- {
96
- "id": "ssr-trigger-12",
97
- "phrase": "document.adoptedStyleSheets is undefined and our component library crashes on import",
98
- "should_route_to_ssr": true,
99
- "expected_shape": "guard-patterns",
100
- "rationale": "Shape-1 crash, the adoptStyles() call site specifically."
101
- },
102
- {
103
- "id": "ssr-adversarial-01",
104
- "phrase": "add hydration-aware stamping so connectedCallback stops overwriting existing children",
105
- "should_route_to_ssr": false,
106
- "expected_alternative": "adia-author",
107
- "rationale": "This is IMPLEMENTING the gh#284 fix, not asking whether/why something fails — routes to the builder, not this answers-only pack."
108
- },
109
- {
110
- "id": "ssr-adversarial-02",
111
- "phrase": "set up Astro's rendering mode and hydration boundaries for our admin app",
112
- "should_route_to_ssr": false,
113
- "expected_alternative": "adia-host",
114
- "rationale": "Consumer-side host/hydration wiring — explicitly fenced to adia-host in the boundaries section."
115
- },
116
- {
117
- "id": "ssr-adversarial-03",
118
- "phrase": "explain how custom element hydration works in general, independent of any specific framework",
119
- "should_route_to_ssr": false,
120
- "expected_alternative": "general knowledge, no pack",
121
- "rationale": "Generic web-components/SSR theory not grounded in THIS repo's own code/issues — explicitly out of scope per the boundaries section."
122
- },
123
- {
124
- "id": "ssr-adversarial-04",
125
- "phrase": "the icon registry comes back empty because of a workspace-hoisting import.meta.glob path bug",
126
- "should_route_to_ssr": false,
127
- "expected_alternative": "adia-author (gh#287, a bundler/dep-optimizer bug, not one of the three SSR lifecycle shapes)",
128
- "rationale": "gh#287 is explicitly named in status-ledger.md as unrelated to this pack's failure taxonomy — a near-miss adversarial by design."
129
- },
130
- {
131
- "id": "ssr-adversarial-05",
132
- "phrase": "wire up the a2ui generation pipeline to run inside a server-rendered page",
133
- "should_route_to_ssr": false,
134
- "expected_alternative": "adia-a2ui",
135
- "rationale": "A2UI runtime/pipeline concern, not the UIElement lifecycle this pack is scoped to — explicitly fenced in the boundaries section."
136
- }
137
- ]
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
+ }
138
34
  }