@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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +25 -0
- 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-verifier.md → framework-reviewer.md} +16 -7
- package/agents/release-builder.corpus.json +39 -0
- package/agents/release-builder.md +39 -0
- package/agents/routing-corpus.json +39 -39
- package/bin/sidecar-prewrite-guard +17 -0
- package/bin/site-postwrite-derivation-gate +180 -0
- package/commands/release.md +5 -3
- package/hooks/hooks.json +4 -0
- package/package.json +1 -1
- package/references/contracts/a2ui-mcp-surface.md +1 -1
- package/skills/adia-a2ui/SKILL.md +27 -6
- package/skills/adia-a2ui/evals/routing-corpus.json +36 -29
- package/skills/adia-a2ui/references/zettel-calibration.md +5 -5
- package/skills/adia-author/SKILL.md +15 -8
- package/skills/adia-author/evals/routing-corpus.json +39 -218
- package/skills/adia-author/references/authoring-cycle.md +19 -0
- package/skills/adia-author/references/code-style.md +0 -1
- package/skills/adia-author/references/llm-bridge.md +7 -0
- package/skills/adia-author/references/worked-example.md +18 -2
- package/skills/adia-deploy/SKILL.md +33 -18
- package/skills/adia-deploy/evals/routing-corpus.json +33 -142
- package/skills/adia-dogfood/SKILL.md +11 -4
- package/skills/adia-dogfood/evals/routing-corpus.json +30 -142
- package/skills/adia-dogfood/references/admin-shell-anatomy.md +1 -1
- package/skills/adia-dogfood/references/visual-probe-triage.md +1 -5
- package/skills/adia-gen-review/SKILL.md +18 -7
- package/skills/adia-gen-review/evals/routing-corpus.json +30 -142
- 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 +33 -142
- 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 +40 -17
- package/skills/adia-release/evals/routing-corpus.json +35 -0
- package/skills/adia-release/references/changelog-discipline.md +14 -8
- package/skills/adia-release/references/cut-procedure.md +48 -28
- package/skills/adia-release/references/independent-package-release.md +1 -1
- package/skills/adia-release/scripts/insert-stub.mjs +1 -1
- package/skills/adia-release/scripts/release-pack.mjs +42 -14
- 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 +32 -14
- package/skills/adia-ssr/evals/routing-corpus.json +32 -136
- package/skills/adia-ssr/references/consumer-workarounds.md +33 -15
- package/skills/adia-ssr/references/failure-shapes.md +49 -7
- package/skills/adia-ssr/references/guard-patterns.md +41 -0
- package/skills/adia-ssr/references/status-ledger.md +5 -7
- package/skills/adia-ssr/references/test-without-linkedom.md +28 -12
- package/agents/a2ui-engineer.md +0 -26
- package/agents/release-engineer.md +0 -26
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""site-postwrite-derivation-gate — PostToolUse check: site source edits name their stale derivatives.
|
|
3
|
+
|
|
4
|
+
The docs site renders converted routes from GENERATED artifacts: site/site.js
|
|
5
|
+
probes site-a2ui/pages/<slug>.a2ui.json per route and renders it via
|
|
6
|
+
<a2ui-root>.doc — the HTML fragment under site/pages/** is only the 404
|
|
7
|
+
fallback. An editor who changes the fragment and stops there has changed
|
|
8
|
+
NOTHING users see (shipped exactly that way 2026-07, caught only by manual
|
|
9
|
+
review). site/sitemap.json likewise feeds site/llms.txt and the patterns
|
|
10
|
+
index. This hook feeds the regeneration obligation back at write-time; the
|
|
11
|
+
hard gate is the repo-wide site-a2ui verify wired in CI.
|
|
12
|
+
|
|
13
|
+
Quiet on: fragments with no sitemap route, routes the ledger has not
|
|
14
|
+
converted (the fragment IS what renders), anything under site-a2ui/ and the
|
|
15
|
+
generated pages sidecar-prewrite-guard owns, and any internal error
|
|
16
|
+
(fail-open — this hook must never block editing with a crash).
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
site-postwrite-derivation-gate --hook # PostToolUse mode: event JSON on stdin
|
|
20
|
+
site-postwrite-derivation-gate selftest # prove matcher + resolution on fixtures
|
|
21
|
+
"""
|
|
22
|
+
import json
|
|
23
|
+
import sys
|
|
24
|
+
|
|
25
|
+
SITEMAP_MARKER = "site/sitemap.json"
|
|
26
|
+
FRAGMENT_MARKER = "site/pages/"
|
|
27
|
+
|
|
28
|
+
# Generated files under site/pages/ are sidecar-prewrite-guard territory.
|
|
29
|
+
GENERATED_EXCLUDE = ("site/pages/patterns/index.html",)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def classify(path):
|
|
33
|
+
"""→ ("sitemap"|"fragment", repo-root prefix, "/"-rooted repo path) or (None, None, None)."""
|
|
34
|
+
if not path or "site-a2ui/" in path:
|
|
35
|
+
return None, None, None
|
|
36
|
+
if path.endswith(SITEMAP_MARKER):
|
|
37
|
+
return "sitemap", path[: -len(SITEMAP_MARKER)], "/" + SITEMAP_MARKER
|
|
38
|
+
idx = path.find(FRAGMENT_MARKER)
|
|
39
|
+
if idx == -1 or not path.endswith(".html") or path[idx:] in GENERATED_EXCLUDE:
|
|
40
|
+
return None, None, None
|
|
41
|
+
return "fragment", path[:idx], "/" + path[idx:]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def find_route(sitemap, rel):
|
|
45
|
+
"""Walk sections/items for the entry whose `content` equals rel; → route path or None."""
|
|
46
|
+
stack = [sitemap.get("sections") or []]
|
|
47
|
+
while stack:
|
|
48
|
+
node = stack.pop()
|
|
49
|
+
if isinstance(node, list):
|
|
50
|
+
stack.extend(node)
|
|
51
|
+
elif isinstance(node, dict):
|
|
52
|
+
if node.get("content") == rel and node.get("path"):
|
|
53
|
+
return node["path"]
|
|
54
|
+
stack.extend(v for k, v in node.items() if k in ("sections", "items", "children"))
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def resolve_fragment(root, rel):
|
|
59
|
+
"""→ feedback reason for a stale-artifact edit, or None to stay quiet.
|
|
60
|
+
|
|
61
|
+
Raises on I/O / parse trouble — the caller fail-opens.
|
|
62
|
+
"""
|
|
63
|
+
with open(root + "site/sitemap.json", encoding="utf-8") as f:
|
|
64
|
+
route = find_route(json.load(f), rel)
|
|
65
|
+
if not route:
|
|
66
|
+
return None # not a routed page
|
|
67
|
+
with open(root + "site-a2ui/ledger.json", encoding="utf-8") as f:
|
|
68
|
+
rows = json.load(f).get("pages") or []
|
|
69
|
+
row = next((r for r in rows if r.get("route") == route), None)
|
|
70
|
+
if not row or row.get("status") != "converted":
|
|
71
|
+
return None # legacy-rendered: the fragment IS what users see
|
|
72
|
+
slug = row.get("slug") or route.lstrip("/").replace("/", "__")
|
|
73
|
+
return (
|
|
74
|
+
f"site-postwrite-derivation-gate · {rel} is the SOURCE for {route}, which renders "
|
|
75
|
+
f"from GENERATED site-a2ui/pages/{slug}.a2ui.json — the artifact is now stale and "
|
|
76
|
+
f"users still see the OLD content. Regenerate: `node scripts/build/site-a2ui.mjs "
|
|
77
|
+
f"--page {route}` (repo-wide check: `npm run verify:site-a2ui`)."
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
SITEMAP_REASON = (
|
|
82
|
+
"site-postwrite-derivation-gate · site/sitemap.json feeds GENERATED surfaces that are "
|
|
83
|
+
"now stale: site/llms.txt (`npm run build:llms`) and the patterns/templates index "
|
|
84
|
+
"(`npm run build:patterns-index`). If you changed routes or content paths, also verify "
|
|
85
|
+
"site-a2ui route coverage: `node scripts/build/site-a2ui.mjs --verify`."
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def hook_mode():
|
|
90
|
+
try:
|
|
91
|
+
event = json.load(sys.stdin)
|
|
92
|
+
except Exception:
|
|
93
|
+
return 0
|
|
94
|
+
tool_input = event.get("tool_input") or {}
|
|
95
|
+
kind, root, rel = classify(tool_input.get("file_path") or "")
|
|
96
|
+
if not kind:
|
|
97
|
+
return 0
|
|
98
|
+
if kind == "sitemap":
|
|
99
|
+
print(json.dumps({"decision": "block", "reason": SITEMAP_REASON}))
|
|
100
|
+
return 0
|
|
101
|
+
try:
|
|
102
|
+
reason = resolve_fragment(root, rel)
|
|
103
|
+
except Exception:
|
|
104
|
+
return 0 # fail-open: never block editing on our own error
|
|
105
|
+
if reason:
|
|
106
|
+
print(json.dumps({"decision": "block", "reason": reason}))
|
|
107
|
+
return 0
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def selftest():
|
|
111
|
+
import os
|
|
112
|
+
import tempfile
|
|
113
|
+
|
|
114
|
+
scope_cases = [
|
|
115
|
+
("/repo/site/pages/architecture/ontology.html", "fragment"),
|
|
116
|
+
("site/pages/guides/testing.html", "fragment"),
|
|
117
|
+
("/repo/site/sitemap.json", "sitemap"),
|
|
118
|
+
("/repo/site/pages/patterns/index.html", None), # generated: prewrite guard owns it
|
|
119
|
+
("/repo/site-a2ui/pages/site__x__y.a2ui.json", None),
|
|
120
|
+
("/repo/site-a2ui/ledger.json", None),
|
|
121
|
+
("/repo/site/site.js", None),
|
|
122
|
+
("/repo/site/pages/architecture/notes.txt", None),
|
|
123
|
+
("/repo/apps/tasks/app/index.html", None),
|
|
124
|
+
]
|
|
125
|
+
for path, expected in scope_cases:
|
|
126
|
+
if classify(path)[0] != expected:
|
|
127
|
+
print(f"selftest: FAIL scope {path} → {classify(path)[0]} expected {expected}")
|
|
128
|
+
return 1
|
|
129
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
130
|
+
root = tmp + os.sep
|
|
131
|
+
os.makedirs(root + "site")
|
|
132
|
+
os.makedirs(root + "site-a2ui")
|
|
133
|
+
with open(root + "site/sitemap.json", "w", encoding="utf-8") as f:
|
|
134
|
+
json.dump(
|
|
135
|
+
{
|
|
136
|
+
"sections": [
|
|
137
|
+
{
|
|
138
|
+
"items": [
|
|
139
|
+
{"path": "/site/a/one", "content": "/site/pages/a/one.html"},
|
|
140
|
+
{"path": "/site/a/two", "content": "/site/pages/a/two.html"},
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
f,
|
|
146
|
+
)
|
|
147
|
+
with open(root + "site-a2ui/ledger.json", "w", encoding="utf-8") as f:
|
|
148
|
+
json.dump(
|
|
149
|
+
{
|
|
150
|
+
"pages": [
|
|
151
|
+
{"route": "/site/a/one", "slug": "site__a__one", "status": "converted"},
|
|
152
|
+
{"route": "/site/a/two", "slug": "site__a__two", "status": "failed"},
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
f,
|
|
156
|
+
)
|
|
157
|
+
resolve_cases = [
|
|
158
|
+
("/site/pages/a/one.html", True), # converted → nudge
|
|
159
|
+
("/site/pages/a/two.html", False), # ledger row not converted → quiet
|
|
160
|
+
("/site/pages/a/three.html", False), # no sitemap entry → quiet
|
|
161
|
+
]
|
|
162
|
+
for rel, should_fire in resolve_cases:
|
|
163
|
+
fired = resolve_fragment(root, rel) is not None
|
|
164
|
+
if fired != should_fire:
|
|
165
|
+
print(f"selftest: FAIL resolve {rel} fired={fired} expected={should_fire}")
|
|
166
|
+
return 1
|
|
167
|
+
if "site__a__one.a2ui.json" not in resolve_fragment(root, "/site/pages/a/one.html"):
|
|
168
|
+
print("selftest: FAIL reason does not name the stale artifact")
|
|
169
|
+
return 1
|
|
170
|
+
print("selftest: PASS")
|
|
171
|
+
return 0
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
if __name__ == "__main__":
|
|
175
|
+
if "selftest" in sys.argv:
|
|
176
|
+
sys.exit(selftest())
|
|
177
|
+
if "--hook" in sys.argv:
|
|
178
|
+
sys.exit(hook_mode())
|
|
179
|
+
print(__doc__)
|
|
180
|
+
sys.exit(0)
|
package/commands/release.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Cut, tag, publish, and deploy an @adia-ai release (11-package lockstep — 9 npm libraries + 2 Claude Code plugins).
|
|
2
|
+
description: Cut, tag, publish, and deploy an @adia-ai release (11-package lockstep — 9 npm libraries + 2 Claude Code plugins). This invocation IS the authorization for the whole cycle; only gate failures stop it.
|
|
3
3
|
argument-hint: "[version or package]"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Run a release. **$ARGUMENTS**
|
|
7
7
|
|
|
8
8
|
Invoke **`adia-release`** and run its cut procedure end-to-end: pre-flight
|
|
9
|
-
gates → cut → tag → publish → deploy → notes
|
|
10
|
-
|
|
9
|
+
gates → cut → tag → publish → deploy → notes. This command's invocation is
|
|
10
|
+
the operator's single authorization for the entire cycle (§Authorization,
|
|
11
|
+
operator ruling 2026-07-17) — run inline, don't re-ask per step; stop only
|
|
12
|
+
on a gate failure. The skill owns the discipline; don't restate it here.
|
package/hooks/hooks.json
CHANGED
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
{
|
|
33
33
|
"type": "command",
|
|
34
34
|
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/bin/demo-postwrite-pattern-gate\" --hook"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/bin/site-postwrite-derivation-gate\" --hook"
|
|
35
39
|
}
|
|
36
40
|
]
|
|
37
41
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/adia-ui-forge",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "Maintain the adia-ui (@adia-ai) framework itself \u2014 author primitives and shells, run the A2UI generation pipeline and its corpus, review gen-UI quality, sweep QA, cut releases, deploy. The maintainer counterpart to adia-factory (the consumer/app-author plugin).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adia-ui",
|
|
@@ -26,7 +26,7 @@ frozen-unless-versioned:
|
|
|
26
26
|
| Tool | Consumer use |
|
|
27
27
|
|---|---|
|
|
28
28
|
| `generate_ui`, `refine_ui` | gen-UI generation loop (adia-genui) |
|
|
29
|
-
| `validate_schema`, `check_anti_patterns` | the trust gate on LLM-emitted A2UI (screen-
|
|
29
|
+
| `validate_schema`, `check_anti_patterns` | the trust gate on LLM-emitted A2UI (screen-builder) |
|
|
30
30
|
| `search_chunks`, `lookup_component`, `get_component_map`, `get_traits` | catalog literacy (adia-compose — "the MCP is the live catalog, don't memorize names") |
|
|
31
31
|
| `convert_html` | migration aid (adia-migrate) |
|
|
32
32
|
| `server_status` | connectivity probe (adia-verify) |
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: adia-a2ui
|
|
3
3
|
description: >-
|
|
4
|
-
Maintains the A2UI pipeline (packages/a2ui/): chunk corpus,
|
|
5
|
-
strategies,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Maintains the A2UI pipeline (packages/a2ui/): the harvested chunk corpus,
|
|
5
|
+
compose strategies (zettel, chunk-zettel, free-form, monolithic), retrieval,
|
|
6
|
+
validator, calibration, evals, the a2ui MCP server. Use when asked to
|
|
7
|
+
author/harvest/fix chunks, tune STRONG_MATCH or zettel thresholds, validate
|
|
8
|
+
an A2UI document, diagnose an eval gap/regression or lift a semantic fail,
|
|
9
|
+
add or change MCP tools (generate_ui, compose_from_chunks,
|
|
10
|
+
check_anti_patterns, refine_composition), scan anti-patterns, run pipeline
|
|
11
|
+
ops, or when a component's A2UI contract can't express a content shape. NOT
|
|
12
|
+
for app screens (adia-compose), runtime gen-UI app features (adia-genui),
|
|
13
|
+
primitive authoring (adia-author), or gallery scoring (adia-gen-review).
|
|
9
14
|
disable-model-invocation: false
|
|
10
15
|
user-invocable: true
|
|
11
16
|
---
|
|
@@ -73,7 +78,7 @@ Unmatched work defaults to pipeline-overview and re-classifies from there.
|
|
|
73
78
|
Full structural gate after any pipeline change:
|
|
74
79
|
|
|
75
80
|
```bash
|
|
76
|
-
node scripts/build/components.mjs --verify # "clean — N files up-to-date" (
|
|
81
|
+
node scripts/build/components.mjs --verify # "clean — N files up-to-date" (the N is the gate; dir count drifts, don't pin it)
|
|
77
82
|
npm run verify:traits # 100% coverage
|
|
78
83
|
npm run smoke:engines
|
|
79
84
|
npm run smoke:register-engine # 11/11
|
|
@@ -109,3 +114,19 @@ intent → retrieval (chunk / composition search)
|
|
|
109
114
|
Every change touches exactly one stage; identify which before patching. History
|
|
110
115
|
for any constant or decision lives in git and PR descriptions
|
|
111
116
|
(`git log -S STRONG_MATCH_THRESHOLD -- packages/a2ui`).
|
|
117
|
+
|
|
118
|
+
## Pipeline Change Record — the output contract
|
|
119
|
+
|
|
120
|
+
Every change reports:
|
|
121
|
+
|
|
122
|
+
| Field | Value |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| Stage touched | retrieval \| strategy engine (zettel/chunk-zettel/free-form/monolithic) \| composer \| validator \| MCP surface |
|
|
125
|
+
| Narrowest gate run | the specific check for the touched stage, + result |
|
|
126
|
+
| Full sequence | `npm run smoke:engines` + `npm run test:a2ui` result |
|
|
127
|
+
| Floors before → after | cov/avg/MRR (zettel) or cov/avg/F1 (free-form) or cov/avg (monolithic) |
|
|
128
|
+
| Re-baseline | no / yes — if yes, the PR that ratified the new floor |
|
|
129
|
+
|
|
130
|
+
Done when every row is filled and the cited gates are green. NOT done: a
|
|
131
|
+
floor number changed with no before/after comparison, or a threshold tweak
|
|
132
|
+
with no root-cause note for why the floor moved.
|
|
@@ -1,31 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
2
|
+
"positives": [
|
|
3
|
+
"validate this A2UI document",
|
|
4
|
+
"harvest a chunk from this HTML demo",
|
|
5
|
+
"zettel coverage dropped after the last change",
|
|
6
|
+
"should this repeated subtree become its own chunk",
|
|
7
|
+
"tune the STRONG_MATCH threshold",
|
|
8
|
+
"run check_anti_patterns on this rendered HTML",
|
|
9
|
+
"refine composition with an OAuth row",
|
|
10
|
+
"MRR dropped in the chunk retrieval eval",
|
|
11
|
+
"add an MCP tool to the a2ui server",
|
|
12
|
+
"audit the training data corpus for drift",
|
|
13
|
+
"diagnose this eval gap and regression",
|
|
14
|
+
"run the MCP pipeline: generate_ui then validate_schema",
|
|
15
|
+
"lift a semantic fail under sixty",
|
|
16
|
+
"why did the composer emit composition-match instead of composition-synthesized"
|
|
17
|
+
],
|
|
18
|
+
"negatives": [
|
|
19
|
+
"build a settings page from existing primitives",
|
|
20
|
+
"add a slot to button-ui and update its yaml contract",
|
|
21
|
+
"cut a release and bump the version tag",
|
|
22
|
+
"score the generated UI quality in apps/genui",
|
|
23
|
+
"run a broad visual QA sweep across site and playgrounds",
|
|
24
|
+
"fix the @adia-ai/llm SSE adapter",
|
|
25
|
+
"explain how React state management works",
|
|
26
|
+
"compose a settings screen from catalog primitives",
|
|
27
|
+
"mount gen-root and wire data resolvers for end users at runtime",
|
|
28
|
+
"edit the getting-started docs page on the site"
|
|
29
|
+
],
|
|
30
|
+
"_measured": {
|
|
31
|
+
"as_of": "2026-07-18",
|
|
32
|
+
"scorer": "routing_eval.py (nonoun-plugins/forge)",
|
|
33
|
+
"f1": 0.783,
|
|
34
|
+
"precision": 1.0,
|
|
35
|
+
"recall": 0.643,
|
|
36
|
+
"exit_code": 0
|
|
37
|
+
}
|
|
31
38
|
}
|
|
@@ -8,7 +8,7 @@ is calibrated against the held-out intent set or production telemetry.
|
|
|
8
8
|
|
|
9
9
|
## `STRONG_MATCH_THRESHOLD = 40`
|
|
10
10
|
|
|
11
|
-
- **File**: `packages/a2ui/compose/strategies/zettel/generator-adapter.js
|
|
11
|
+
- **File**: `packages/a2ui/compose/strategies/zettel/generator-adapter.js` (`grep -n STRONG_MATCH_THRESHOLD`)
|
|
12
12
|
- **Raised**: 22 → 40 post-incident.
|
|
13
13
|
- **Reason**: at 22, login-form / signup-form played verbatim too often →
|
|
14
14
|
repetitive output. At 40, only near-perfect retrievals (chart-dashboard=48,
|
|
@@ -29,7 +29,7 @@ is calibrated against the held-out intent set or production telemetry.
|
|
|
29
29
|
|
|
30
30
|
## `STRONG_RETRIEVAL_SCORE = 8`
|
|
31
31
|
|
|
32
|
-
- **File**: `chunk-synthesizer.js
|
|
32
|
+
- **File**: `chunk-synthesizer.js` (`grep -n STRONG_RETRIEVAL_SCORE`)
|
|
33
33
|
- **Scale**: corpus-size-**independent** absolute keyword score from
|
|
34
34
|
`chunk-library.js#keywordScore()`: first name-word matches a token **+10**,
|
|
35
35
|
full-query substring **+5**, whole-word token in name **+3**, substring /
|
|
@@ -46,7 +46,7 @@ is calibrated against the held-out intent set or production telemetry.
|
|
|
46
46
|
|
|
47
47
|
## `PRE_SEARCH_LIMIT = 30`
|
|
48
48
|
|
|
49
|
-
- **Files**: `chunk-synthesizer.js
|
|
49
|
+
- **Files**: `chunk-synthesizer.js` + `chunk-refiner.js` (`grep -n PRE_SEARCH_LIMIT`)
|
|
50
50
|
- **Reason**: token-budget mitigation — pre-filter the catalog before the LLM
|
|
51
51
|
sees it; the full catalog per prompt would burn tens of thousands of tokens.
|
|
52
52
|
- **Synthesizer**: kind-aware allocation —
|
|
@@ -61,7 +61,7 @@ is calibrated against the held-out intent set or production telemetry.
|
|
|
61
61
|
|
|
62
62
|
## `SCOPE_DRIFT_RATIO = 1.5` + `SCOPE_DRIFT_MIN_ACTUAL = 20`
|
|
63
63
|
|
|
64
|
-
- **File**: `chunk-synthesizer.js
|
|
64
|
+
- **File**: `chunk-synthesizer.js` (exported; `grep -n SCOPE_DRIFT`)
|
|
65
65
|
- Composed envelope's component count > 1.5× the sum of bound chunks' counts
|
|
66
66
|
auto-fires a `scope-drift` issue — catches LLM creative expansion that
|
|
67
67
|
hallucinates components beyond the bound chunks.
|
|
@@ -70,7 +70,7 @@ is calibrated against the held-out intent set or production telemetry.
|
|
|
70
70
|
|
|
71
71
|
## `DEFAULT_MAX_ATTEMPTS = 2`
|
|
72
72
|
|
|
73
|
-
- **Files**: `chunk-refiner.js
|
|
73
|
+
- **Files**: `chunk-refiner.js` + `chunk-synthesizer.js` (`grep -n DEFAULT_MAX_ATTEMPTS`)
|
|
74
74
|
- Validator-driven retry budget. After 2 failed validations the engine emits
|
|
75
75
|
`synthesis-failed`.
|
|
76
76
|
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: adia-author
|
|
3
3
|
description: >-
|
|
4
|
-
Author or modify
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Author or modify AdiaUI framework source inside the monorepo — primitives
|
|
5
|
+
(packages/web-components), shells/composites (packages/web-modules), yaml
|
|
6
|
+
SoTs, demos. Use when asked to add a new primitive component, add or fix a prop/slot/
|
|
7
|
+
attribute/CSS variant, update a component's yaml, build or fix a shell
|
|
8
|
+
(chat-shell, admin-shell, editor-shell — sidebar/pane/bespoke-tier
|
|
9
|
+
composition), promote or extract repeated inline content into a shared
|
|
10
|
+
module, audit a component's four-axis contract/token usage/lifecycle
|
|
11
|
+
(connected/disconnected symmetry) for drift, or author/write a demo or
|
|
12
|
+
examples.html for a component or composite. NOT for composing app screens
|
|
13
|
+
from primitives (adia-compose), A2UI pipeline internals (adia-a2ui),
|
|
14
|
+
@adia-ai/llm adapter/streaming/bridge internals (adia-llm-internals), or
|
|
15
|
+
site/pages docs pages (adia-site-docs).
|
|
9
16
|
disable-model-invocation: false
|
|
10
17
|
user-invocable: true
|
|
11
18
|
---
|
|
@@ -14,7 +21,9 @@ user-invocable: true
|
|
|
14
21
|
|
|
15
22
|
Guard rails for code that lands INSIDE the adia-ui monorepo: primitives
|
|
16
23
|
(`packages/web-components/`), shells and composites (`packages/web-modules/`),
|
|
17
|
-
their `<name>.yaml` SoTs,
|
|
24
|
+
their `<name>.yaml` SoTs, and composite demos. `@adia-ai/llm` internals
|
|
25
|
+
(adapters, streaming, the bridge) are `adia-llm-internals`'s charter, not
|
|
26
|
+
this skill's — route there.
|
|
18
27
|
Light-DOM is load-bearing: `slot=` attributes are decorative metadata,
|
|
19
28
|
positioning is CSS by tag + ancestor + DOM order — never `::slotted()`,
|
|
20
29
|
`::part()`, or shadow DOM. `.claude/docs/specs/component-token-contract.md`
|
|
@@ -30,7 +39,6 @@ wins any tie with this skill. Monorepo source read while authoring (yaml, CSS,
|
|
|
30
39
|
| Shell / bespoke cluster child (`<admin-*>` `<chat-*>` `<editor-*>` `<simple-*>`) | [shell-patterns.md](references/shell-patterns.md) |
|
|
31
40
|
| Promote repeated inline UI → shared module | [module-promotion.md](references/module-promotion.md) |
|
|
32
41
|
| Contract / token / lifecycle drift audit on an existing component | [token-contract.md](references/token-contract.md) + [anti-patterns.md](references/anti-patterns.md) |
|
|
33
|
-
| Extend `@adia-ai/llm` (provider, streaming, proxy) | [llm-bridge.md](references/llm-bridge.md) |
|
|
34
42
|
| Demo for a composite/module — any `packages/web-modules/**/*.{examples,contents}.html` | [composite-demo-protocol.md](references/composite-demo-protocol.md) — NOT the primitive or promotion paths; they lack the canonical-survey discipline |
|
|
35
43
|
| Convention question ("is this idiomatic?") | [code-style.md](references/code-style.md) — cite the rule, don't expand it inline |
|
|
36
44
|
|
|
@@ -82,7 +90,6 @@ citation mechanically on every web-modules demo write; the
|
|
|
82
90
|
| Shell | render `packages/web-modules/<cluster>/<name>/<name>.html`; `node scripts/dev/audit-native-primitive-leak.mjs --include=<surface>`; `node scripts/dev/audit-shell-composition.mjs --include=<surface>` for `<admin-shell>` composites |
|
|
83
91
|
| Inline → module promotion | source page renders identically post-refactor (visual sweep + DOM diff) + native-primitive-leak audit on the touched surface |
|
|
84
92
|
| Drift audit | the findings report itself; gates run once a fix is applied |
|
|
85
|
-
| LLM-bridge extension | a real client round-trip parses + returns (`npm run check:lockstep` + `npm run smoke:engines`) |
|
|
86
93
|
| Composite demo | `npm run audit:demo-pattern-source:strict` + `npm run qa:design-coherence:strict` + (8b) `npm run qa:rendered-dom:emit -- --slug=<slug>` |
|
|
87
94
|
|
|
88
95
|
Full structural-gate sequence after any primitive / shell / promotion work:
|