@adia-ai/adia-ui-factory 0.8.0 → 0.8.2
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 +2 -2
- package/.mcp.json +1 -1
- package/CHANGELOG.md +28 -0
- package/agents/app-architect.md +5 -3
- package/agents/consumer-verifier.md +38 -0
- package/agents/routing-corpus.json +32 -2
- package/agents/screen-composer.md +3 -1
- package/bin/adia-info +235 -0
- package/bin/adia-lint +59 -1
- package/bin/adia-probe.mjs +116 -0
- package/bin/adia-scaffold +91 -1
- package/bin/record-lint +142 -0
- package/commands/adia-genui.md +3 -1
- package/commands/adia-info.md +14 -0
- package/commands/adia-migrate.md +9 -3
- package/commands/adia-orient.md +5 -2
- package/commands/adia-scaffold.md +4 -2
- package/commands/adia-verify.md +15 -4
- package/package.json +1 -1
- package/references/a2ui-mcp-tools.md +1 -1
- package/references/llm.md +1 -1
- package/references/migration.md +11 -1
- package/references/project-shapes.md +15 -6
- package/references/shell-admin.md +2 -2
- package/references/shell-chat.md +8 -5
- package/references/ssr-integration.md +1 -1
- package/skills/adia-compose/SKILL.md +71 -2
- package/skills/adia-compose/assets/figma-make/guidelines/Guidelines.md +5 -5
- package/skills/adia-compose/assets/figma-make/guidelines/styles.md +2 -2
- package/skills/adia-compose/evals/routing-corpus.json +216 -0
- package/skills/adia-data/SKILL.md +29 -3
- package/skills/adia-data/evals/routing-corpus.json +172 -0
- package/skills/adia-genui/SKILL.md +24 -6
- package/skills/adia-genui/evals/routing-corpus.json +173 -0
- package/skills/adia-host/SKILL.md +16 -0
- package/skills/adia-host/evals/routing-corpus.json +172 -0
- package/skills/adia-llm/SKILL.md +7 -7
- package/skills/adia-llm/evals/routing-corpus.json +173 -0
- package/skills/adia-migrate/SKILL.md +65 -8
- package/skills/adia-migrate/evals/routing-corpus.json +171 -0
- package/skills/adia-orient/SKILL.md +30 -11
- package/skills/adia-orient/evals/routing-corpus.json +216 -0
- package/skills/adia-project/SKILL.md +6 -4
- package/skills/adia-project/evals/routing-corpus.json +171 -0
- package/skills/adia-shells/SKILL.md +23 -3
- package/skills/adia-shells/evals/routing-corpus.json +167 -0
- package/skills/adia-verify/SKILL.md +23 -2
- package/skills/adia-verify/evals/routing-corpus.json +171 -0
- package/skills/adia-verify/references/verification.md +8 -1
- package/references/verification.md +0 -35
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"name": "adia-project routing accuracy corpus",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"purpose": "Routing-eval corpus for adia-project (adia-ui-factory plugin). Each phrase declares whether adia-project 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-project routing — does this phrase activate adia-project?",
|
|
9
|
+
|
|
10
|
+
"minimums_per_spec": {
|
|
11
|
+
"trigger_phrases": 14,
|
|
12
|
+
"adversarial_phrases": 6,
|
|
13
|
+
"task_shapes_covered": "new-app, add-surface, add-page, add-component, inventory",
|
|
14
|
+
"adversarial_fraction": "30%"
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
"phrases": [
|
|
18
|
+
{
|
|
19
|
+
"id": "project-newapp-01",
|
|
20
|
+
"phrase": "scaffold a new SPA app for this adia-ui project",
|
|
21
|
+
"should_route_to_project": true,
|
|
22
|
+
"expected_shape": "new-app",
|
|
23
|
+
"rationale": "The exact 'scaffold an app' trigger phrase named in the description, canonical new-app mode."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "project-newapp-02",
|
|
27
|
+
"phrase": "set up an SSR app with the Next framework — four-axis dirs and all",
|
|
28
|
+
"should_route_to_project": true,
|
|
29
|
+
"expected_shape": "new-app",
|
|
30
|
+
"rationale": "Names the SSR one-shot (bin/adia-scaffold ssr <name> --framework next) and the four-axis layout directly."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "project-newapp-03",
|
|
34
|
+
"phrase": "help me decide the project shape — single-surface, rollup, or shared-foundation — for this fresh app",
|
|
35
|
+
"should_route_to_project": true,
|
|
36
|
+
"expected_shape": "new-app",
|
|
37
|
+
"rationale": "Names all three project shapes verbatim; this is the shape-decision gate adia-project owns before scaffolding."
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
"id": "project-addsurface-01",
|
|
42
|
+
"phrase": "we're already a rollup — add a new surface under app/ for the billing section",
|
|
43
|
+
"should_route_to_project": true,
|
|
44
|
+
"expected_shape": "add-surface",
|
|
45
|
+
"rationale": "Mode and shape are already decided (rollup); this is the add-surface mode growing an existing shape, adia-project's on-disk-structure job."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "project-addsurface-02",
|
|
49
|
+
"phrase": "grow the shared-foundation with a new sibling app under app/shared",
|
|
50
|
+
"should_route_to_project": true,
|
|
51
|
+
"expected_shape": "add-surface",
|
|
52
|
+
"rationale": "Names shared-foundation and app/shared directly — add-surface mode with shape already settled."
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
"id": "project-addpage-01",
|
|
57
|
+
"phrase": "add a new page to the settings rollup",
|
|
58
|
+
"should_route_to_project": true,
|
|
59
|
+
"expected_shape": "add-page",
|
|
60
|
+
"rationale": "The exact 'add a page' trigger phrase from the description, add-page mode."
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "project-addpage-02",
|
|
64
|
+
"phrase": "decide whether this new page should be trio or DUO form",
|
|
65
|
+
"should_route_to_project": true,
|
|
66
|
+
"expected_shape": "add-page",
|
|
67
|
+
"rationale": "Names the page-form gate (trio vs DUO) verbatim from the skill body."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "project-addpage-03",
|
|
71
|
+
"phrase": "scaffold a page in the reports surface with --duo",
|
|
72
|
+
"should_route_to_project": true,
|
|
73
|
+
"expected_shape": "add-page",
|
|
74
|
+
"rationale": "Direct bin/adia-scaffold page invocation with the --duo flag named in the skill body."
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
"id": "project-addcomponent-01",
|
|
79
|
+
"phrase": "scaffold a new custom element folder in our app for the badge widget",
|
|
80
|
+
"should_route_to_project": true,
|
|
81
|
+
"expected_shape": "add-component",
|
|
82
|
+
"rationale": "add-component mode: a consumer-app custom element folder via bin/adia-scaffold component, not a framework primitive."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "project-addcomponent-02",
|
|
86
|
+
"phrase": "add a component folder via adia-scaffold for the app's local <stat-card> element",
|
|
87
|
+
"should_route_to_project": true,
|
|
88
|
+
"expected_shape": "add-component",
|
|
89
|
+
"rationale": "Explicit adia-scaffold component invocation, app-local element."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "project-addcomponent-03",
|
|
93
|
+
"phrase": "check that the new component's folder name matches its tag per convention",
|
|
94
|
+
"should_route_to_project": true,
|
|
95
|
+
"expected_shape": "add-component",
|
|
96
|
+
"rationale": "Verifies the add-component gate: components/<tag>/<tag>.{js,css} exists, folder = tag."
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
"id": "project-inventory-01",
|
|
101
|
+
"phrase": "audit this existing app's structure — score it against the structure rubric",
|
|
102
|
+
"should_route_to_project": true,
|
|
103
|
+
"expected_shape": "inventory",
|
|
104
|
+
"rationale": "The exact 'audit its structure' trigger phrase from the description, inventory mode."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"id": "project-inventory-02",
|
|
108
|
+
"phrase": "score whether our project shape still matches how the app has actually grown",
|
|
109
|
+
"should_route_to_project": true,
|
|
110
|
+
"expected_shape": "inventory",
|
|
111
|
+
"rationale": "Inventory mode: shape declared & matched is one of the rubric's named gates."
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "project-inventory-03",
|
|
115
|
+
"phrase": "check this rollup for duplicated cross-surface code",
|
|
116
|
+
"should_route_to_project": true,
|
|
117
|
+
"expected_shape": "inventory",
|
|
118
|
+
"rationale": "Names a specific structure-rubric gate ('no duplicated cross-surface code') verbatim."
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
{
|
|
122
|
+
"id": "project-adv-01",
|
|
123
|
+
"phrase": "add a surface for the new claims-review tool — we haven't decided mode or shell yet",
|
|
124
|
+
"should_route_to_project": false,
|
|
125
|
+
"expected_alternative": "adia-orient (adia-ui-factory plugin)",
|
|
126
|
+
"rationale": "Adversarial — the unevidenced handoff the audit flagged: 'add a surface' appears in both adia-orient's and adia-project's descriptions, but with mode/shape/shell still undecided this is cold-start orientation, not structure-laying. adia-project's add-surface mode presumes the shape is already picked."
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "project-adv-02",
|
|
130
|
+
"phrase": "scaffold a plain React app, no AdiaUI components involved",
|
|
131
|
+
"should_route_to_project": false,
|
|
132
|
+
"expected_alternative": "none",
|
|
133
|
+
"rationale": "Adversarial — 'scaffold an app' surface-matches the trigger phrase, but with no adia-ui in scope this is generic framework tooling; no AdiaUI skill should claim it."
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": "project-adv-03",
|
|
137
|
+
"phrase": "restructure the framework monorepo's package layout under packages/web-components",
|
|
138
|
+
"should_route_to_project": false,
|
|
139
|
+
"expected_alternative": "adia-author (adia-ui-forge plugin)",
|
|
140
|
+
"rationale": "Adversarial — adia-project lays out a CONSUMER app's on-disk structure; restructuring the framework monorepo itself is forge-side authoring territory."
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id": "project-adv-04",
|
|
144
|
+
"phrase": "build the actual screen content for the new page we just scaffolded",
|
|
145
|
+
"should_route_to_project": false,
|
|
146
|
+
"expected_alternative": "adia-compose",
|
|
147
|
+
"rationale": "Adversarial — the description's own NOT-fence: 'the UI inside a screen' is adia-compose's job once adia-project has laid out where the page lives."
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"id": "project-adv-05",
|
|
151
|
+
"phrase": "wire the host's SPA registration and CSS cascade for this app",
|
|
152
|
+
"should_route_to_project": false,
|
|
153
|
+
"expected_alternative": "adia-host",
|
|
154
|
+
"rationale": "Adversarial — host bootstrap/registration is explicitly deferred to adia-host in the description's NOT-fence."
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "project-adv-06",
|
|
158
|
+
"phrase": "wire up the state/data pattern for the new surface",
|
|
159
|
+
"should_route_to_project": false,
|
|
160
|
+
"expected_alternative": "adia-data",
|
|
161
|
+
"rationale": "Adversarial — state/data pattern choice is explicitly deferred to adia-data in the references section, distinct from structure/scaffolding."
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
|
|
165
|
+
"evaluator_notes": {
|
|
166
|
+
"current_state": "20 cases (14 trigger + 6 adversarial). Trigger cases: 3 new-app, 2 add-surface, 3 add-page, 3 add-component, 3 inventory (all 5 modes covered).",
|
|
167
|
+
"promotion_criteria": "Promote to a CI gate (warn → hard-fail) when F1 >= 0.85 on this corpus across 3+ consecutive runs without description edits.",
|
|
168
|
+
"review_cadence": "Re-run on every adia-project description edit. Add 1-2 new cases per checkpoint reflecting newly-observed routing failure modes.",
|
|
169
|
+
"known_limitations": "project-adv-01 encodes the audit's flagged unevidenced handoff: 'add a surface' appears verbatim in both adia-orient's and adia-project's descriptions. The heuristic TF-IDF scorer cannot see whether mode/shape were already decided (that context lives in conversation state, not the phrase text alone), so this case is likely to be the corpus's most fragile — an LLM router resolves it on context adia-project's own description doesn't carry; the phrase text alone may false-positive toward adia-project until the description gains an explicit 'mode/shape already decided' qualifier."
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -3,8 +3,9 @@ name: adia-shells
|
|
|
3
3
|
description: >-
|
|
4
4
|
Picks and composes an adia-ui page-chrome shell (@adia-ai/web-modules):
|
|
5
5
|
admin (app frame), chat (LLM), editor (canvas+panes), simple
|
|
6
|
-
(marketing/error
|
|
7
|
-
"sidebar + topbar layout", "embed this surface", or shell markup
|
|
6
|
+
(marketing/error), or embed. Use when asked to "use a
|
|
7
|
+
shell", "sidebar + topbar layout", "embed this surface", or on shell markup
|
|
8
|
+
debugging.
|
|
8
9
|
NOT for screens inside it (adia-compose) or host/SSR wiring (adia-host).
|
|
9
10
|
disable-model-invocation: false
|
|
10
11
|
user-invocable: true
|
|
@@ -36,7 +37,7 @@ A composed shell is done when all five gates hold and the surface renders (`adia
|
|
|
36
37
|
| Gate | Check | Enforcement |
|
|
37
38
|
| --- | --- | --- |
|
|
38
39
|
| Cluster registered | the barrel import is present; JS-bearing children resolve | self-verified |
|
|
39
|
-
| Canonical nesting | parent→child structure matches the shell's reference (e.g. `admin-page` only inside `admin-scroll`;
|
|
40
|
+
| Canonical nesting | parent→child structure matches the shell's reference (e.g. `admin-page` only inside `admin-scroll`; shell children never wrapped in `<col-ui>`/`<row-ui>` — the grid reads tag selectors) | self-verified against the reference |
|
|
40
41
|
| No legacy shapes | no retired data-attribute forms | mechanized: `adia-lint` `LEGACY-SHELL` |
|
|
41
42
|
| No native-primitive leak | controls are `*-ui`, not raw `<button>`/`<input>` | mechanized: `adia-lint` `NATIVE-PRIMITIVE` |
|
|
42
43
|
| One route owner | SSR uses the framework outlet, not `<router-ui>` | self-verified |
|
|
@@ -44,6 +45,25 @@ A composed shell is done when all five gates hold and the surface renders (`adia
|
|
|
44
45
|
The plugin's `bin/adia-lint` mechanizes the two marked gates on write; the other three are
|
|
45
46
|
checked against the per-shell reference before declaring done.
|
|
46
47
|
|
|
48
|
+
## Deliverable — the ShellComposition record
|
|
49
|
+
|
|
50
|
+
Composing a shell emits this record — it materializes the pick table's "decide on a cited
|
|
51
|
+
signal" demand and the five-gate table's results, in the same row order:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
Shell: admin | chat | editor | simple | embed | none — signal: <file / dep / marker, or the user's explicit words>
|
|
55
|
+
Barrel import: <e.g. '@adia-ai/web-modules/shell'>
|
|
56
|
+
Cluster registered: pass | fail — reference: <shell-<name>.md section checked>
|
|
57
|
+
Canonical nesting: pass | fail — reference: <shell-<name>.md section checked>
|
|
58
|
+
No legacy shapes: pass | fail — adia-lint: <LEGACY-SHELL output>
|
|
59
|
+
No native-primitive leak: pass | fail — adia-lint: <NATIVE-PRIMITIVE output>
|
|
60
|
+
One route owner: pass | fail — reference: <shell-<name>.md section checked>
|
|
61
|
+
Reference consulted: <shell-<name>.md>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The two mechanized gates cite `adia-lint`'s actual output; the three self-verified gates cite
|
|
65
|
+
the reference section checked against, never an assumption.
|
|
66
|
+
|
|
47
67
|
## Shared conventions (every shell; the per-shell reference carries the specifics)
|
|
48
68
|
|
|
49
69
|
- **Register by cluster barrel**, not piecemeal: `import '@adia-ai/web-modules/shell'` (or
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"name": "adia-shells routing accuracy corpus",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"purpose": "Routing-eval corpus for adia-shells (adia-ui-factory plugin). Each phrase declares whether adia-shells 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-shells routing — does this phrase activate adia-shells?",
|
|
9
|
+
|
|
10
|
+
"minimums_per_spec": {
|
|
11
|
+
"trigger_phrases": 14,
|
|
12
|
+
"adversarial_phrases": 6,
|
|
13
|
+
"task_shapes_covered": "pick-admin, pick-chat, pick-editor, pick-simple, pick-embed, shell-debugging, shell-selection-generic",
|
|
14
|
+
"adversarial_fraction": "30%"
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
"phrases": [
|
|
18
|
+
{
|
|
19
|
+
"id": "shells-admin-01",
|
|
20
|
+
"phrase": "I need a sidebar + topbar layout with a command palette for this app",
|
|
21
|
+
"should_route_to_shells": true,
|
|
22
|
+
"expected_shape": "pick-admin",
|
|
23
|
+
"rationale": "The exact 'sidebar + topbar layout' trigger phrase named in the description — this is the fence-test the audit flagged: it must land on adia-shells (picking page-chrome), not adia-compose (which builds screen content, not the frame around it)."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "shells-admin-02",
|
|
27
|
+
"phrase": "set up the full app frame — sidebar(s) plus topbar plus command palette — for the dashboard",
|
|
28
|
+
"should_route_to_shells": true,
|
|
29
|
+
"expected_shape": "pick-admin",
|
|
30
|
+
"rationale": "Restates the admin-shell decision-table signal ('full app frame — sidebar(s) + topbar + command palette + pages') in the requester's own words."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "shells-chat-01",
|
|
34
|
+
"phrase": "build an LLM conversation surface with a thread and a composer",
|
|
35
|
+
"should_route_to_shells": true,
|
|
36
|
+
"expected_shape": "pick-chat",
|
|
37
|
+
"rationale": "Matches chat-shell's decision-table signal: an LLM conversation surface (thread + composer)."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "shells-chat-02",
|
|
41
|
+
"phrase": "wire up the chat-shell's thread and composer chrome",
|
|
42
|
+
"should_route_to_shells": true,
|
|
43
|
+
"expected_shape": "pick-chat",
|
|
44
|
+
"rationale": "Names chat-shell directly and asks for its chrome, not the conversation content inside it."
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "shells-editor-01",
|
|
48
|
+
"phrase": "I need a design tool with a center canvas and resizable side panes",
|
|
49
|
+
"should_route_to_shells": true,
|
|
50
|
+
"expected_shape": "pick-editor",
|
|
51
|
+
"rationale": "Matches editor-shell's decision-table signal: a design tool — center canvas + resizable side panes."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "shells-editor-02",
|
|
55
|
+
"phrase": "add focus mode to the editor-shell's canvas + panes layout",
|
|
56
|
+
"should_route_to_shells": true,
|
|
57
|
+
"expected_shape": "pick-editor",
|
|
58
|
+
"rationale": "Focus mode is an editor-shell chrome feature named in the skill body, not screen content."
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "shells-simple-01",
|
|
62
|
+
"phrase": "scaffold a minimal centered chrome for the marketing landing page",
|
|
63
|
+
"should_route_to_shells": true,
|
|
64
|
+
"expected_shape": "pick-simple",
|
|
65
|
+
"rationale": "Matches simple-shell's decision-table signal: marketing/error/landing/auth — minimal centered chrome."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "shells-simple-02",
|
|
69
|
+
"phrase": "pick a shell for the auth error page — it just needs minimal centered chrome",
|
|
70
|
+
"should_route_to_shells": true,
|
|
71
|
+
"expected_shape": "pick-simple",
|
|
72
|
+
"rationale": "Explicit shell-selection ask against the simple-shell signal."
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "shells-embed-01",
|
|
76
|
+
"phrase": "embed this surface into a host page — size and center the light-DOM element",
|
|
77
|
+
"should_route_to_shells": true,
|
|
78
|
+
"expected_shape": "pick-embed",
|
|
79
|
+
"rationale": "The exact 'embed this surface' trigger phrase named in the description, matched to embed-shell's decision-table row."
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "shells-embed-02",
|
|
83
|
+
"phrase": "wire the embed-shell cluster for the widget we're dropping into a third-party site",
|
|
84
|
+
"should_route_to_shells": true,
|
|
85
|
+
"expected_shape": "pick-embed",
|
|
86
|
+
"rationale": "Names embed-shell directly; cluster registration is shell-selection/composition territory."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "shells-debug-01",
|
|
90
|
+
"phrase": "the sidebar's [collapsed] attribute doesn't collapse the admin-shell layout — help me debug the shell markup",
|
|
91
|
+
"should_route_to_shells": true,
|
|
92
|
+
"expected_shape": "shell-debugging",
|
|
93
|
+
"rationale": "The exact 'shell markup debugging' trigger phrase named in the description, tied to the shared state-is-an-attribute convention."
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"id": "shells-debug-02",
|
|
97
|
+
"phrase": "adia-lint flagged a legacy <aside data-sidebar> shape in our shell — fix the markup",
|
|
98
|
+
"should_route_to_shells": true,
|
|
99
|
+
"expected_shape": "shell-debugging",
|
|
100
|
+
"rationale": "Legacy data-attribute shapes are called out explicitly in the skill body as retired shell-tier vocabulary; fixing them is shell markup debugging."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"id": "shells-generic-01",
|
|
104
|
+
"phrase": "use a shell for this new app frame",
|
|
105
|
+
"should_route_to_shells": true,
|
|
106
|
+
"expected_shape": "shell-selection-generic",
|
|
107
|
+
"rationale": "The literal 'use a shell' trigger phrase from the description with no shell yet named — canonical cold-start-within-shells ask."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "shells-generic-02",
|
|
111
|
+
"phrase": "which shell fits an app that needs both a big canvas and side panes",
|
|
112
|
+
"should_route_to_shells": true,
|
|
113
|
+
"expected_shape": "shell-selection-generic",
|
|
114
|
+
"rationale": "A decision-cue question aimed at the pick-the-shell table without naming a shell — still adia-shells' job, not a specific-shell shape."
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
{
|
|
118
|
+
"id": "shells-adv-01",
|
|
119
|
+
"phrase": "compose the screens that go inside the admin-shell's page area",
|
|
120
|
+
"should_route_to_shells": false,
|
|
121
|
+
"expected_alternative": "adia-compose",
|
|
122
|
+
"rationale": "Adversarial — the audit's core fence question, resolved the other direction: screens INSIDE an already-chosen shell are adia-compose's job per the description's own NOT-fence."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "shells-adv-02",
|
|
126
|
+
"phrase": "wire the SSR host so the framework's route outlet renders inside the shell",
|
|
127
|
+
"should_route_to_shells": false,
|
|
128
|
+
"expected_alternative": "adia-host",
|
|
129
|
+
"rationale": "Adversarial — host/SSR route-outlet wiring is explicitly carved out to adia-host in both the description and the shared-conventions section (NEVER mount <router-ui> under SSR — the framework outlet owns the route)."
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"id": "shells-adv-03",
|
|
133
|
+
"phrase": "the admin-shell's sidebar-collapse behavior regressed — fix the bug in packages/web-modules source",
|
|
134
|
+
"should_route_to_shells": false,
|
|
135
|
+
"expected_alternative": "adia-author (adia-ui-forge plugin)",
|
|
136
|
+
"rationale": "Adversarial — a shell BUG in the framework monorepo itself (editing packages/web-modules source) is forge-side authoring, not factory-side shell selection/composition."
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"id": "shells-adv-04",
|
|
140
|
+
"phrase": "wire the state/data hydration for the shell's sidebar list",
|
|
141
|
+
"should_route_to_shells": false,
|
|
142
|
+
"expected_alternative": "adia-data",
|
|
143
|
+
"rationale": "Adversarial — data/state pattern choice is adia-data's territory; adia-shells only reflects state as an attribute the consumer already owns."
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"id": "shells-adv-05",
|
|
147
|
+
"phrase": "add the LLM streaming client to power the chat-shell's composer",
|
|
148
|
+
"should_route_to_shells": false,
|
|
149
|
+
"expected_alternative": "adia-llm",
|
|
150
|
+
"rationale": "Adversarial — the chat LLM client/proxy contract is explicitly deferred to adia-llm in the shell's own references section, even though it's chat-shell-adjacent."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "shells-adv-06",
|
|
154
|
+
"phrase": "scaffold a brand new app's on-disk structure before we even pick a shell",
|
|
155
|
+
"should_route_to_shells": false,
|
|
156
|
+
"expected_alternative": "adia-project",
|
|
157
|
+
"rationale": "Adversarial — app structure/scaffolding precedes shell selection and belongs to adia-project; no shell has been named or implied."
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
|
|
161
|
+
"evaluator_notes": {
|
|
162
|
+
"current_state": "20 cases (14 trigger + 6 adversarial). Each of the 7 task shapes (5 named shells + shell-debugging + shell-selection-generic) has 2 trigger cases.",
|
|
163
|
+
"promotion_criteria": "Promote to a CI gate (warn → hard-fail) when F1 >= 0.85 on this corpus across 3+ consecutive runs without description edits.",
|
|
164
|
+
"review_cadence": "Re-run on every adia-shells description edit. Add 1-2 new cases per checkpoint reflecting newly-observed routing failure modes.",
|
|
165
|
+
"known_limitations": "The audit's core open question — whether 'sidebar + topbar layout' reaches adia-shells or gets pulled toward adia-compose — is encoded as shells-admin-01/02 (positive) and shells-adv-01 (the compose-side adversarial); the heuristic TF-IDF scorer may not separate 'layout' (shell chrome) from 'screen'/'form'/'dashboard' (compose content) as cleanly as an LLM router would, since both descriptions share UI-layout vocabulary."
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -3,7 +3,7 @@ name: adia-verify
|
|
|
3
3
|
description: >-
|
|
4
4
|
Browser-QA gate for adia-ui surfaces — renders headless with zero
|
|
5
5
|
console/page errors, non-zero bounding boxes, and a screenshot actually
|
|
6
|
-
read, plus AdiaUI a11y checks. Use
|
|
6
|
+
read, plus AdiaUI a11y checks. Use when shipping a surface, on
|
|
7
7
|
"verify/QA this page", or when "tests pass" is the only evidence. NOT for
|
|
8
8
|
composing/fixing UI (adia-compose) or structural lint (adia-lint hook).
|
|
9
9
|
disable-model-invocation: false
|
|
@@ -27,7 +27,27 @@ Probe shape, the failure classes only this gate catches (0×0 host, empty-page-w
|
|
|
27
27
|
|
|
28
28
|
## Tooling boundary
|
|
29
29
|
|
|
30
|
-
The advisory `adia-lint` PostToolUse hook mechanizes the structural slice on every write (shadow DOM, raw color/px, `::slotted`, native-primitive leaks, legacy shell shapes, SSR traps) and never blocks — fix its findings rather than re-deriving its rules. The framework's `audit:shell-composition` / `audit:native-primitive-leak` run in the @adia-ai framework repo; they are not shipped in this plugin and cannot be invoked from a consumer app.
|
|
30
|
+
The advisory `adia-lint` PostToolUse hook mechanizes the structural slice on every write (shadow DOM, raw color/px, `::slotted`, native-primitive leaks, legacy shell shapes, SSR traps, and the shell-nesting/LLM-key/genui-validate rules) and never blocks — fix its findings rather than re-deriving its rules. The framework's `audit:shell-composition` / `audit:native-primitive-leak` run in the @adia-ai framework repo; they are not shipped in this plugin and cannot be invoked from a consumer app.
|
|
31
|
+
|
|
32
|
+
The render gate itself IS shipped: `node "${CLAUDE_PLUGIN_ROOT}/bin/adia-probe.mjs" <url> --selector <key-element> [--json]` runs gates 1–2 mechanically (console/page errors, bounding boxes, the `deviceScaleFactor: 2` capture — set at context creation, where it actually takes effect) and emits the VerifyProof below with verdict `pass-pending-read`. The screenshot READ and the a11y judgment slice stay yours — the probe's `imageRead` slot exists precisely so a report can't silently skip them. Requires Playwright in the consumer app (`npm i -D playwright`).
|
|
33
|
+
|
|
34
|
+
## Deliverable — the VerifyProof
|
|
35
|
+
|
|
36
|
+
The QA pass returns this record (the probe emits the mechanized half via `--json`; the reader completes it):
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
VerifyProof
|
|
40
|
+
url: <the probed page>
|
|
41
|
+
consoleErrors: pass | fail — <each error verbatim; empty = pass>
|
|
42
|
+
boundingBoxes: pass | fail — <selector: w×h per key element; any 0×0 = fail>
|
|
43
|
+
screenshot: <path> @ deviceScaleFactor 2
|
|
44
|
+
imageRead: <what the pixels actually show — REQUIRED prose, never "looks fine">
|
|
45
|
+
a11y: pass | fail — region role/label · .open-driven overlays · heading roles · keyboard path · AA contrast
|
|
46
|
+
structure: adia-lint clean on every written file | <findings>
|
|
47
|
+
verdict: ship | hold — <one line naming the blocker if hold>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
A VerifyProof with an empty `imageRead` or a bare "looks fine" is incomplete — the slot carries what was SEEN, so a later reader can challenge it.
|
|
31
51
|
|
|
32
52
|
## Verify rubric
|
|
33
53
|
|
|
@@ -39,5 +59,6 @@ A surface ships only when all pass:
|
|
|
39
59
|
| Screenshot read `[gate]` | the `deviceScaleFactor: 2` capture was looked at, after the latest structural change |
|
|
40
60
|
| Accessible `[gate]` | region role + label; `.open`-driven overlays; real heading roles; keyboard path; AA contrast |
|
|
41
61
|
| Structurally clean `[gate]` | `adia-lint` reports no smells on every file written for the surface |
|
|
62
|
+
| Data wired `[gate]` | the surface's Wiring Record (adia-data §Deliverable) exists with every round-trip row observed — a screen with unrecorded state wiring isn't done |
|
|
42
63
|
|
|
43
64
|
Neighboring work routes out: composing or fixing the surface → `adia-compose` · shell chrome → `adia-shells` · hydration/state → `adia-data` · generated-markup validation → `adia-genui`.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"name": "adia-verify routing accuracy corpus",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"purpose": "Routing-eval corpus for adia-verify (adia-ui-factory plugin). Each phrase declares whether adia-verify 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-verify routing — does this phrase activate adia-verify (the consumer-app browser-QA exit gate), and does it correctly stay OUT of adia-release's release pre-flight gates, which is the one known central-corpus misroute for any 'verify'-flavored phrase?",
|
|
9
|
+
|
|
10
|
+
"minimums_per_spec": {
|
|
11
|
+
"trigger_phrases": 14,
|
|
12
|
+
"adversarial_phrases": 6,
|
|
13
|
+
"task_shapes_covered": "browser-gate, qa-request, a11y-check, debug-symptom, anti-pattern-tests-pass",
|
|
14
|
+
"adversarial_fraction": "30%"
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
"phrases": [
|
|
18
|
+
{
|
|
19
|
+
"id": "verify-gate-01",
|
|
20
|
+
"phrase": "verify this surface renders with zero console errors before we ship it",
|
|
21
|
+
"should_route_to_verify": true,
|
|
22
|
+
"expected_shape": "browser-gate",
|
|
23
|
+
"rationale": "Canonical pre-ship browser-render gate phrasing — matches the skill's own 'before shipping a surface' trigger."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "verify-gate-02",
|
|
27
|
+
"phrase": "run the browser gate on the new settings page",
|
|
28
|
+
"should_route_to_verify": true,
|
|
29
|
+
"expected_shape": "browser-gate",
|
|
30
|
+
"rationale": "Direct 'browser gate' terminology from the skill's own name for its check."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "verify-gate-03",
|
|
34
|
+
"phrase": "check that bounding boxes are non-zero on the dashboard before merging",
|
|
35
|
+
"should_route_to_verify": true,
|
|
36
|
+
"expected_shape": "browser-gate",
|
|
37
|
+
"rationale": "Non-zero bounding box is the gate's literal pass condition."
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
"id": "verify-qa-01",
|
|
42
|
+
"phrase": "verify/QA this page before we ship it",
|
|
43
|
+
"should_route_to_verify": true,
|
|
44
|
+
"expected_shape": "qa-request",
|
|
45
|
+
"rationale": "Verbatim 'verify/QA this page' phrase from the skill description."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "verify-qa-02",
|
|
49
|
+
"phrase": "is this screen done? run the exit gate on it",
|
|
50
|
+
"should_route_to_verify": true,
|
|
51
|
+
"expected_shape": "qa-request",
|
|
52
|
+
"rationale": "'Is this screen done' — the exit-gate framing this skill owns."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": "verify-qa-03",
|
|
56
|
+
"phrase": "QA the checkout flow before it goes live for users",
|
|
57
|
+
"should_route_to_verify": true,
|
|
58
|
+
"expected_shape": "qa-request",
|
|
59
|
+
"rationale": "Consumer-app pre-launch QA request; deliberately avoids the word 'release' to not collide with adia-release."
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
{
|
|
63
|
+
"id": "verify-a11y-01",
|
|
64
|
+
"phrase": "run an accessibility pass on the profile page",
|
|
65
|
+
"should_route_to_verify": true,
|
|
66
|
+
"expected_shape": "a11y-check",
|
|
67
|
+
"rationale": "A11y check is one of the two gate halves this skill owns."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "verify-a11y-02",
|
|
71
|
+
"phrase": "check AA contrast and the keyboard path on the new modal",
|
|
72
|
+
"should_route_to_verify": true,
|
|
73
|
+
"expected_shape": "a11y-check",
|
|
74
|
+
"rationale": "AA contrast + keyboard path are named rubric rows."
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "verify-a11y-03",
|
|
78
|
+
"phrase": "does this overlay have a real heading role and an aria-label on its region?",
|
|
79
|
+
"should_route_to_verify": true,
|
|
80
|
+
"expected_shape": "a11y-check",
|
|
81
|
+
"rationale": "Region role + heading role are named a11y-gate items."
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
{
|
|
85
|
+
"id": "verify-debug-01",
|
|
86
|
+
"phrase": "the screen renders completely blank, help me figure out why",
|
|
87
|
+
"should_route_to_verify": true,
|
|
88
|
+
"expected_shape": "debug-symptom",
|
|
89
|
+
"rationale": "'Empty page' symptom — a named failure class only this gate catches."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "verify-debug-02",
|
|
93
|
+
"phrase": "this element reports a 0x0 bounding box, why isn't it sized",
|
|
94
|
+
"should_route_to_verify": true,
|
|
95
|
+
"expected_shape": "debug-symptom",
|
|
96
|
+
"rationale": "0x0 host is the skill's named failure class."
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"id": "verify-debug-03",
|
|
100
|
+
"phrase": "the page looks broken visually but the console shows no errors",
|
|
101
|
+
"should_route_to_verify": true,
|
|
102
|
+
"expected_shape": "debug-symptom",
|
|
103
|
+
"rationale": "Clean-console-but-visually-broken is the anti-pattern this gate exists to catch."
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
{
|
|
107
|
+
"id": "verify-anti-01",
|
|
108
|
+
"phrase": "our unit tests pass, but I want someone to actually look at the rendered page before we call it done",
|
|
109
|
+
"should_route_to_verify": true,
|
|
110
|
+
"expected_shape": "anti-pattern-tests-pass",
|
|
111
|
+
"rationale": "Directly invokes the skill's named anti-pattern: 'tests pass, ship it'."
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "verify-anti-02",
|
|
115
|
+
"phrase": "confirm the surface actually renders and isn't just clipped — don't take the test suite's word for it",
|
|
116
|
+
"should_route_to_verify": true,
|
|
117
|
+
"expected_shape": "anti-pattern-tests-pass",
|
|
118
|
+
"rationale": "Clipped-content-despite-passing-tests is the gate's reason to exist."
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
{
|
|
122
|
+
"id": "verify-adv-01",
|
|
123
|
+
"phrase": "run the pre-flight verification gates before we cut the v0.8 release",
|
|
124
|
+
"should_route_to_verify": false,
|
|
125
|
+
"expected_alternative": "adia-release (forge plugin)",
|
|
126
|
+
"rationale": "Adversarial — the known central-corpus misroute: 'verify' language describing release pre-flight gates (F-N1, tag/publish checkpoints), not a consumer-app browser QA pass."
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "verify-adv-02",
|
|
130
|
+
"phrase": "run a dogfood sweep across every demo page in the framework repo",
|
|
131
|
+
"should_route_to_verify": false,
|
|
132
|
+
"expected_alternative": "adia-dogfood (forge plugin)",
|
|
133
|
+
"rationale": "Adversarial — framework-side demo sweep (visual probe, attr-quote typos, shell composition) is adia-dogfood's territory, not the consumer-app exit gate."
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": "verify-adv-03",
|
|
137
|
+
"phrase": "the QA pass found the button is unstyled and misplaced — go fix the screen",
|
|
138
|
+
"should_route_to_verify": false,
|
|
139
|
+
"expected_alternative": "adia-compose (adia-ui-factory plugin)",
|
|
140
|
+
"rationale": "Adversarial — verify only reports the gap; fixing the composed screen routes to adia-compose (generator, not the gate)."
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id": "verify-adv-04",
|
|
144
|
+
"phrase": "the gate found the data isn't hydrating on load — fix the state wiring",
|
|
145
|
+
"should_route_to_verify": false,
|
|
146
|
+
"expected_alternative": "adia-data (adia-ui-factory plugin)",
|
|
147
|
+
"rationale": "Adversarial — fixing a hydration/state defect the gate surfaced belongs to adia-data, not to re-running verify."
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"id": "verify-adv-05",
|
|
151
|
+
"phrase": "run the structural lint check on the files from my last commit",
|
|
152
|
+
"should_route_to_verify": false,
|
|
153
|
+
"expected_alternative": "adia-lint hook (advisory PostToolUse hook, not a skill)",
|
|
154
|
+
"rationale": "Adversarial — structural smells (shadow DOM, raw color/px, native-primitive leaks) are the adia-lint hook's mechanized slice; verify only checks that hook reports clean, it doesn't run the lint itself."
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "verify-adv-06",
|
|
158
|
+
"phrase": "write unit tests for the new date-parsing utility function",
|
|
159
|
+
"should_route_to_verify": false,
|
|
160
|
+
"expected_alternative": null,
|
|
161
|
+
"rationale": "Adversarial — generic unit-test authoring with no browser-render or a11y surface; no AdiaUI skill should activate."
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
|
|
165
|
+
"evaluator_notes": {
|
|
166
|
+
"current_state": "20 cases (14 trigger + 6 adversarial). Each of the 5 task shapes has 2-3 trigger cases; adv-01 specifically targets the documented known misroute (verify-flavored phrase landing on adia-release).",
|
|
167
|
+
"promotion_criteria": "Promote to a CI gate (warn → hard-fail) when F1 ≥ 0.85 on this corpus across 3+ consecutive runs without description edits.",
|
|
168
|
+
"review_cadence": "Re-run on every adia-verify description edit. Add 1-2 new cases per checkpoint reflecting newly-observed routing failure modes.",
|
|
169
|
+
"known_limitations": "verify-adv-01 encodes the single highest-value adversarial for this skill: 'verify' as a bare word is release-gate-shaped in the central corpus, and the heuristic scorer may weight token overlap toward adia-release's own 'pre-flight gates' language. The description's browser/a11y-specific vocabulary (bounding boxes, console.error, aria-label) is the intended disambiguator."
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -13,9 +13,16 @@ Render the surface in a real (headless) browser and assert four things, in order
|
|
|
13
13
|
|
|
14
14
|
Gates 1 and 2 are independent, not redundant: `customElements.whenDefined(name)` never rejects, so a `Promise.all([...whenDefined]).then(bootstrap)` gate with one never-imported tag hangs forever — shell chrome still renders (tag-keyed CSS), the console stays **clean**, and the page is empty. Only the bounding-box and screenshot checks see it.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
The shipped probe runs this mechanically and emits the VerifyProof:
|
|
17
|
+
`node "${CLAUDE_PLUGIN_ROOT}/bin/adia-probe.mjs" <url> --selector <el> --json`.
|
|
18
|
+
Its logic, for when you need a bespoke variant (Playwright; works against a
|
|
19
|
+
Vite static host or an SSR dev URL):
|
|
17
20
|
|
|
18
21
|
```js
|
|
22
|
+
// deviceScaleFactor must be set at CONTEXT creation — scale:'device' on a
|
|
23
|
+
// default context captures at 1x and silently fails gate 3's 2x claim.
|
|
24
|
+
const context = await browser.newContext({ deviceScaleFactor: 2 });
|
|
25
|
+
const page = await context.newPage();
|
|
19
26
|
const errors = [];
|
|
20
27
|
page.on('console', m => m.type() === 'error' && errors.push(m.text()));
|
|
21
28
|
page.on('pageerror', e => errors.push(String(e)));
|