@event4u/agent-config 7.0.2 → 7.2.0

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 (140) hide show
  1. package/.claude-plugin/marketplace.json +9 -1
  2. package/CHANGELOG.md +117 -0
  3. package/README.md +4 -2
  4. package/dist/agent-src/commands/council/default.md +28 -20
  5. package/dist/agent-src/commands/evals/fix.json +5 -1
  6. package/dist/agent-src/commands/fix/comments.md +101 -0
  7. package/dist/agent-src/commands/fix.md +5 -2
  8. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +65 -0
  9. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +68 -0
  10. package/dist/agent-src/contexts/execution/host-capability-manifest.md +68 -0
  11. package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +62 -0
  12. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +59 -0
  13. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +8 -3
  14. package/dist/agent-src/contexts/execution/subagent-response-contract.md +56 -0
  15. package/dist/agent-src/contexts/execution/subagent-routing.md +57 -0
  16. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +54 -0
  17. package/dist/agent-src/contexts/execution/subagent-steering.md +71 -0
  18. package/dist/agent-src/contexts/execution/verify-budget.md +50 -0
  19. package/dist/agent-src/rules/brand-source-of-truth.md +10 -0
  20. package/dist/agent-src/rules/delegation-policy.md +85 -0
  21. package/dist/agent-src/rules/design-fidelity.md +98 -0
  22. package/dist/agent-src/rules/domain-safety-pii.md +22 -0
  23. package/dist/agent-src/rules/legal-safety-floor.md +182 -0
  24. package/dist/agent-src/rules/lethal-trifecta-guard.md +25 -22
  25. package/dist/agent-src/rules/output-discipline.md +85 -0
  26. package/dist/agent-src/rules/telegraph-speak.md +4 -1
  27. package/dist/agent-src/rules/token-budget-discipline.md +94 -0
  28. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +102 -15
  29. package/dist/agent-src/scripts/update_roadmap_progress.ts +30 -3
  30. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +20 -5
  31. package/dist/agent-src/skills/ai-council/SKILL.md +28 -1
  32. package/dist/agent-src/skills/blade-ui/SKILL.md +9 -0
  33. package/dist/agent-src/skills/contract-review/SKILL.md +125 -0
  34. package/dist/agent-src/skills/contract-review/evals/triggers.json +17 -0
  35. package/dist/agent-src/skills/dashboard-design/SKILL.md +21 -5
  36. package/dist/agent-src/skills/design-intelligence/SKILL.md +96 -0
  37. package/dist/agent-src/skills/design-review/SKILL.md +83 -0
  38. package/dist/agent-src/skills/design-system-capture/SKILL.md +234 -0
  39. package/dist/agent-src/skills/design-tokens/SKILL.md +1 -0
  40. package/dist/agent-src/skills/dpa-review/SKILL.md +130 -0
  41. package/dist/agent-src/skills/dpa-review/evals/triggers.json +17 -0
  42. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +15 -4
  43. package/dist/agent-src/skills/fe-design/SKILL.md +98 -16
  44. package/dist/agent-src/skills/flux/SKILL.md +8 -0
  45. package/dist/agent-src/skills/iconography/SKILL.md +1 -0
  46. package/dist/agent-src/skills/laravel/SKILL.md +1 -0
  47. package/dist/agent-src/skills/legal-intake-triage/SKILL.md +128 -0
  48. package/dist/agent-src/skills/legal-intake-triage/evals/triggers.json +17 -0
  49. package/dist/agent-src/skills/legal-practice-profile/SKILL.md +101 -0
  50. package/dist/agent-src/skills/legal-practice-profile/evals/triggers.json +17 -0
  51. package/dist/agent-src/skills/livewire/SKILL.md +8 -0
  52. package/dist/agent-src/skills/nda-triage/SKILL.md +114 -0
  53. package/dist/agent-src/skills/nda-triage/evals/triggers.json +17 -0
  54. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +21 -9
  55. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +3 -1
  56. package/dist/agent-src/skills/recursive-verification/SKILL.md +186 -0
  57. package/dist/agent-src/skills/roadmap-management/SKILL.md +17 -0
  58. package/dist/agent-src/skills/skill-writing/SKILL.md +18 -0
  59. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +11 -0
  60. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +17 -7
  61. package/dist/agent-src/skills/typography-system/SKILL.md +14 -0
  62. package/dist/agent-src/skills/ui-component-architect/SKILL.md +9 -0
  63. package/dist/agent-src/templates/agent-settings.md +64 -19
  64. package/dist/discovery/deprecation-report.md +1 -1
  65. package/dist/discovery/discovery-manifest.json +362 -43
  66. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  67. package/dist/discovery/discovery-manifest.summary.md +13 -5
  68. package/dist/discovery/orphan-report.md +1 -1
  69. package/dist/discovery/packs.json +56 -11
  70. package/dist/discovery/trust-report.md +7 -5
  71. package/dist/discovery/workspaces.json +38 -7
  72. package/dist/mcp/registry-manifest.json +3 -3
  73. package/dist/router.json +1 -1
  74. package/dist/server/routes/wizard.js +4 -3
  75. package/dist/server/routes/wizard.js.map +1 -1
  76. package/dist/server/schemas/settings.js +23 -0
  77. package/dist/server/schemas/settings.js.map +1 -1
  78. package/dist/ui/assets/{index-CoQo90sz.js → index-UjcTG_9O.js} +2 -2
  79. package/dist/ui/assets/index-UjcTG_9O.js.map +1 -0
  80. package/dist/ui/index.html +1 -1
  81. package/docs/RELEASE_STORY_TEMPLATE.md +37 -0
  82. package/docs/architecture.md +4 -4
  83. package/docs/benchmark.md +46 -0
  84. package/docs/catalog.md +18 -6
  85. package/docs/command-flows.md +7 -1
  86. package/docs/contracts/ai-council-config.md +17 -10
  87. package/docs/contracts/audit-log-v1.md +7 -0
  88. package/docs/contracts/auto-orchestration-v1.md +70 -0
  89. package/docs/contracts/capability-boundary.md +64 -0
  90. package/docs/contracts/command-clusters.md +1 -1
  91. package/docs/contracts/discovery-manifest.schema.json +2 -2
  92. package/docs/contracts/package-self-orientation.md +3 -0
  93. package/docs/contracts/subagent-boundary.md +54 -0
  94. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +32 -0
  95. package/docs/decisions/ADR-020-global-only-consumer-scope.md +13 -6
  96. package/docs/decisions/ADR-049-configuration-trust-boundary.md +11 -1
  97. package/docs/decisions/ADR-093-ai-council-config-user-global.md +10 -4
  98. package/docs/decisions/ADR-104-ai-council-config-global-only.md +119 -0
  99. package/docs/decisions/ADR-105-automatic-subagent-orchestration.md +102 -0
  100. package/docs/decisions/ADR-106-recursive-verification-benchmark-gate.md +126 -0
  101. package/docs/decisions/ADR-107-legal-domain-pack-adoption.md +70 -0
  102. package/docs/decisions/ADR-108-open-source-forever-no-commercial-tier.md +46 -0
  103. package/docs/decisions/INDEX.md +5 -0
  104. package/docs/getting-started.md +2 -2
  105. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +53 -0
  106. package/docs/guidelines/agent-infra/domain-pack-architecture.md +56 -0
  107. package/docs/guidelines/design-antipatterns-triggers.json +17 -0
  108. package/docs/guidelines/design-antipatterns.md +170 -0
  109. package/docs/guidelines/design-modes.md +97 -0
  110. package/package.json +1 -1
  111. package/src/config/agent-settings.template.yml +103 -3
  112. package/src/config/discovery/packs.yml +24 -0
  113. package/src/config/discovery/workspaces.yml +7 -0
  114. package/src/scripts/_lib/auto_dispatch.ts +95 -0
  115. package/src/scripts/_lib/host_capability.ts +59 -0
  116. package/src/scripts/_lib/orchestration_gate.ts +98 -0
  117. package/src/scripts/_lib/subagent_bundle.ts +154 -0
  118. package/src/scripts/_lib/subagent_response.ts +82 -0
  119. package/src/scripts/_lib/subagent_routing.ts +81 -0
  120. package/src/scripts/_lib/subagent_spawn.ts +97 -0
  121. package/src/scripts/_lib/subagent_steering.ts +64 -0
  122. package/src/scripts/_lib/verify_budget.ts +54 -0
  123. package/src/scripts/ai_council/advisors.ts +4 -2
  124. package/src/scripts/ai_council/clients.ts +7 -1
  125. package/src/scripts/ai_council/config.ts +22 -17
  126. package/src/scripts/bench_ab_v2_run.ts +127 -0
  127. package/src/scripts/bench_ab_v2_stats.ts +39 -0
  128. package/src/scripts/check_council_config_location.ts +6 -5
  129. package/src/scripts/check_trunk_drift.ts +67 -0
  130. package/src/scripts/lint_design_quality.ts +321 -0
  131. package/src/scripts/lint_discovery_vocabulary.ts +6 -0
  132. package/src/scripts/lint_framework_leakage_allowlist.json +21 -0
  133. package/src/scripts/lint_legal_pack.ts +197 -0
  134. package/src/scripts/lint_output_slop.ts +223 -0
  135. package/src/scripts/lint_pack_risk_class.ts +79 -0
  136. package/src/scripts/probe_projection_fidelity.ts +7 -1
  137. package/src/scripts/schemas/agent-settings.schema.json +23 -0
  138. package/src/scripts/schemas/skill.schema.json +5 -0
  139. package/src/scripts/skill_linter.ts +3 -0
  140. package/dist/ui/assets/index-CoQo90sz.js.map +0 -1
@@ -140,14 +140,26 @@ function _inbound_ref_rewrite(
140
140
  old_rel: string,
141
141
  new_rel: string,
142
142
  dry_run: boolean,
143
+ tracked = true,
143
144
  ): string[] {
144
- const grep = _run(['git', 'grep', '-l', '--', old_rel], root);
145
145
  const changed: string[] = [];
146
- if (grep.returncode !== 0) {
147
- // 1 = no matches, fine
148
- return changed;
146
+ // Tracked repo → `git grep` (fast, index-aware). Untracked fallback (gap A)
147
+ // → walk the filesystem, since `git grep` only sees committed content and
148
+ // would miss every inbound ref in a pre-first-commit consumer.
149
+ let candidates: string[];
150
+ if (tracked) {
151
+ const grep = _run(['git', 'grep', '-l', '--', old_rel], root);
152
+ if (grep.returncode === 1) {
153
+ return changed; // no matches
154
+ }
155
+ candidates =
156
+ grep.returncode === 0
157
+ ? _splitlines(grep.stdout).map((l) => l.trim())
158
+ : _fs_grep_files(root, old_rel); // git grep unusable → fs walk
159
+ } else {
160
+ candidates = _fs_grep_files(root, old_rel);
149
161
  }
150
- for (const line of _splitlines(grep.stdout)) {
162
+ for (const line of candidates) {
151
163
  const rel = line.trim();
152
164
  if (!rel || rel === old_rel) {
153
165
  // skip the roadmap file itself
@@ -176,14 +188,86 @@ function _replaceAll(text: string, oldStr: string, newStr: string): string {
176
188
  return text.split(oldStr).join(newStr);
177
189
  }
178
190
 
179
- function _git_mv(root: string, src_rel: string, dst_rel: string, dry_run: boolean): boolean {
191
+ interface MoveResult {
192
+ /** the move (or dry-run no-op) succeeded */
193
+ ok: boolean;
194
+ /** the move went through `git mv` (tracked); false → plain filesystem
195
+ * rename was used because the repo has no commits / the file is untracked.
196
+ * The caller rewrites inbound refs on the filesystem (not via `git add`)
197
+ * when this is false. */
198
+ tracked: boolean;
199
+ }
200
+
201
+ /**
202
+ * Move `src_rel` → `dst_rel`, preferring `git mv`.
203
+ *
204
+ * Untracked-safe (road-to-roadmap-archival-robustness, gap A): a consumer that
205
+ * closed a roadmap in a pre-first-commit / untracked working tree cannot use
206
+ * `git mv` (it errors). Instead of printing `git mv failed` and leaving the
207
+ * completed roadmap to rot in the active tree, fall back to a plain
208
+ * `fs.renameSync`. The TS-only enhancement post-dates the deleted Python twin
209
+ * (ADR-200), so there is no byte-parity obligation on this failure path.
210
+ */
211
+ function _git_mv(root: string, src_rel: string, dst_rel: string, dry_run: boolean): MoveResult {
180
212
  const dst = path.join(root, dst_rel);
181
- if (!dry_run) {
182
- fs.mkdirSync(path.dirname(dst), { recursive: true });
183
- const cp = _run(['git', 'mv', src_rel, dst_rel], root);
184
- return cp.returncode === 0;
213
+ if (dry_run) {
214
+ return { ok: true, tracked: true };
215
+ }
216
+ fs.mkdirSync(path.dirname(dst), { recursive: true });
217
+ const cp = _run(['git', 'mv', src_rel, dst_rel], root);
218
+ if (cp.returncode === 0) {
219
+ return { ok: true, tracked: true };
220
+ }
221
+ // Fallback: untracked file or a repo with no commits — plain rename.
222
+ try {
223
+ fs.renameSync(path.join(root, src_rel), dst);
224
+ return { ok: true, tracked: false };
225
+ } catch {
226
+ return { ok: false, tracked: false };
185
227
  }
186
- return true;
228
+ }
229
+
230
+ /**
231
+ * Repo-relative paths of files containing `needle`, by walking the filesystem.
232
+ *
233
+ * The untracked fallback for `_inbound_ref_rewrite`: `git grep` only sees
234
+ * tracked content, so in a pre-first-commit consumer it misses every inbound
235
+ * reference. Walk the tree (skipping `.git` / `node_modules` and obvious binary
236
+ * trees), read text files, and match the literal path. Bounded by skipping the
237
+ * heavy dirs; an untracked consumer's tree is small.
238
+ */
239
+ function _fs_grep_files(root: string, needle: string): string[] {
240
+ const SKIP = new Set(['.git', 'node_modules', '.augment', 'dist']);
241
+ const hits: string[] = [];
242
+ const walk = (dirAbs: string): void => {
243
+ let entries: fs.Dirent[];
244
+ try {
245
+ entries = fs.readdirSync(dirAbs, { withFileTypes: true });
246
+ } catch {
247
+ return;
248
+ }
249
+ for (const e of entries) {
250
+ if (e.name.startsWith('.git') || SKIP.has(e.name)) {
251
+ continue;
252
+ }
253
+ const abs = path.join(dirAbs, e.name);
254
+ if (e.isDirectory()) {
255
+ walk(abs);
256
+ } else if (e.isFile() && /\.(md|json|ya?ml|ts|js|txt)$/.test(e.name)) {
257
+ let text: string;
258
+ try {
259
+ text = fs.readFileSync(abs, { encoding: 'utf-8' });
260
+ } catch {
261
+ continue;
262
+ }
263
+ if (text.includes(needle)) {
264
+ hits.push(path.relative(root, abs).split(path.sep).join('/'));
265
+ }
266
+ }
267
+ }
268
+ };
269
+ walk(root);
270
+ return hits;
187
271
  }
188
272
 
189
273
  interface ArchiveRecord {
@@ -222,12 +306,15 @@ function archive_completed(
222
306
  continue; // complete, but not this branch's work
223
307
  }
224
308
  const new_rel = `agents/roadmaps/archive/${stats.rel}`;
225
- if (!_git_mv(root, old_rel, new_rel, dry_run)) {
226
- process.stderr.write(` ⚠️ git mv failed for ${old_rel}\n`);
309
+ const mv = _git_mv(root, old_rel, new_rel, dry_run);
310
+ if (!mv.ok) {
311
+ process.stderr.write(` ⚠️ could not archive ${old_rel} (mv failed)\n`);
227
312
  continue;
228
313
  }
229
- const refs = _inbound_ref_rewrite(root, old_rel, new_rel, dry_run);
230
- if (!dry_run && refs.length) {
314
+ const refs = _inbound_ref_rewrite(root, old_rel, new_rel, dry_run, mv.tracked);
315
+ // Stage rewritten refs only in a tracked repo; an untracked consumer's
316
+ // files are not in the index, so the filesystem rewrite is the whole job.
317
+ if (!dry_run && refs.length && mv.tracked) {
231
318
  _run(['git', 'add', '--', ...refs], root);
232
319
  }
233
320
  archived.push({ roadmap: old_rel, archived_to: new_rel, refs_migrated: refs });
@@ -520,9 +520,15 @@ function render(roadmaps: RoadmapStats[], bundles: Bundle[] | null = null): stri
520
520
  ' · [roadmaps/](roadmaps/) · [archive/](roadmaps/archive/) · ' +
521
521
  '[skipped/](roadmaps/skipped/) · [later/](roadmaps/later/)\n';
522
522
  lines.push(
523
- '> Auto-generated by `.augment/scripts/update_roadmap_progress.ts`. ' +
524
- 'Do not edit — regenerated on every roadmap-create, -execute, or ' +
525
- 'completion change (last-modified timestamp lives in git history).\n>\n' +
523
+ // Honest provenance (road-to-roadmap-archival-robustness, gap C): name a
524
+ // regen path that exists in EVERY install, not a hardcoded
525
+ // `.augment/scripts/...` that a script-less / non-Augment consumer does
526
+ // not have. `task roadmap-progress` covers Taskfile projects; the bare
527
+ // script name covers the rest.
528
+ '> Auto-generated — do not edit. Regenerate with `task roadmap-progress` ' +
529
+ 'or by running the `update_roadmap_progress` script for your install; ' +
530
+ 'rewritten on every roadmap create / execute / completion change ' +
531
+ '(timestamp lives in git history).\n>\n' +
526
532
  header_meta,
527
533
  );
528
534
  lines.push('## Overall\n');
@@ -568,6 +574,27 @@ function render(roadmaps: RoadmapStats[], bundles: Bundle[] | null = null): stri
568
574
  }
569
575
  lines.push('');
570
576
  }
577
+ const unarchived = unarchived_complete(roadmaps);
578
+ if (unarchived.length) {
579
+ // Non-CI backstop (road-to-roadmap-archival-robustness, gap C): a
580
+ // persistent dashboard banner makes "completed but unarchived" visible
581
+ // without the CI `--check` gate — the consumer sees it on every regen.
582
+ lines.push('## ✅ Completed — pending archival\n');
583
+ lines.push(
584
+ 'These roadmaps are **complete** (`count_open == 0`, ' +
585
+ '`count_deferred == 0`) but still sit in the active tree. They ' +
586
+ 'should be in `agents/roadmaps/archive/`. Run the archival sweep ' +
587
+ '`archive_completed_roadmaps --all` (untracked-safe), or follow the ' +
588
+ 'manual fallback documented in the `roadmap-management` skill, then ' +
589
+ 'regenerate this dashboard.\n',
590
+ );
591
+ lines.push('| Roadmap | Done | Total |');
592
+ lines.push('|---|---:|---:|');
593
+ for (const r of unarchived) {
594
+ lines.push(`| [${r.rel}](roadmaps/${r.rel}) | ${r.done} | ${r.total_active} |`);
595
+ }
596
+ lines.push('');
597
+ }
571
598
  if (roadmaps.length === 0) {
572
599
  lines.push('_No open roadmaps._\n');
573
600
  return lines.join('\n') + '\n';
@@ -9,6 +9,7 @@ workspaces:
9
9
  - engineering
10
10
  packs:
11
11
  - engineering-base
12
+ token_budget_class: rich
12
13
  ---
13
14
 
14
15
  # accessibility-auditor
@@ -53,11 +54,12 @@ gets a verdict in step 5; missing one is a coverage failure.
53
54
  **Perceivable** — text alternatives for non-text (`alt`, `aria-label`),
54
55
  contrast ≥ 4.5:1 for body / 3:1 for large or UI components, no
55
56
  colour-only state ("error in red" must also be iconic or text).
56
- Grounded reference for palette + chart verdicts: corpus WCAG-adjusted
57
- token sets (`--domain color`), chart a11y grades + colorblind fallbacks
58
- (`--domain chart`), mobile touch/a11y rules (`--domain web`, 44pt) via
59
- [`design-intelligence`](../design-intelligence/SKILL.md) — cite the corpus
60
- row; WCAG 2.2 AA *method* stays this skill's checklists.
57
+ Grounded reference for palette + chart verdicts: the adopted corpus's
58
+ WCAG-adjusted token sets (`--domain color`), chart a11y grades +
59
+ colorblind fallbacks (`--domain chart`), and mobile touch/a11y rules
60
+ (`--domain web`, 44pt targets) via
61
+ [`design-intelligence`](../design-intelligence/SKILL.md) — cite the
62
+ corpus row; the WCAG 2.2 AA *method* stays this skill's own checklists.
61
63
  Widget-pattern selection (dialog, combobox, tabs, toast, table, form
62
64
  errors, drag-reorder …) grounds in the ARIA-APG corpus:
63
65
  `ground.py search --manifest
@@ -145,3 +147,16 @@ Top 3 fixes: <ordered by user impact>
145
147
  jurisdictions.
146
148
  - Do NOT close a finding by adjusting the test instead of the UI;
147
149
  the user's experience is the ground truth, not the test report.
150
+
151
+ ## Why this skill is rich
152
+
153
+ WCAG 2.2 AA compliance is non-negotiable detail — each success criterion
154
+ has a specific testable condition, failure mode, and remediation path.
155
+ The skill carries the full WCAG criterion matrix with concrete test
156
+ procedures (not just "check contrast"), keyboard-navigation patterns
157
+ (roving tabindex, trap management, escape-key handling), ARIA role/
158
+ property/state tables, and screen-reader-specific edge cases per
159
+ assistive technology. Condensing to "check contrast and add aria-labels"
160
+ loses the test procedures that turn a vague finding into a reproducible
161
+ failure with a specific remedy. Accessibility bugs that are described
162
+ vaguely cannot be verified as fixed.
@@ -35,7 +35,34 @@ Do NOT use when:
35
35
  * The artefact contains secrets that cannot be redacted with the
36
36
  bundler's pattern set → ask the user before sending.
37
37
  * The user has not configured any council member → state that and stop;
38
- do not silently fall back to anything.
38
+ do not silently fall back to anything. **But "not configured" is
39
+ decided by the CLI, never by the project tree** — see the rule below.
40
+
41
+ ## Configuration is ALWAYS user-global
42
+
43
+ ```
44
+ THE COUNCIL CONFIG IS ALWAYS USER-GLOBAL. NEVER SEARCH THE PROJECT FOR IT.
45
+ THE ABSENCE OF A COUNCIL FILE IN A PROJECT SAYS NOTHING ABOUT WHETHER
46
+ THE COUNCIL IS CONFIGURED. ONLY THE CLI / RESOLVER DECIDES THAT.
47
+ ```
48
+
49
+ Council config lives at one place only:
50
+ `~/.event4u/agent-config/settings/.ai-council.yml` (per
51
+ [ADR-104](../../../docs/decisions/ADR-104-ai-council-config-global-only.md),
52
+ superseding ADR-093). Configured **once per developer**; works in **every**
53
+ project, worktree, and CWD — including consumer repos carrying none of this
54
+ package's internals.
55
+
56
+ Before claiming the council unavailable, run the CLI (`council:estimate`) and
57
+ read its exit code + message. **Never** conclude "council not configured in
58
+ this project" from missing project files: `scripts/ai_council` (package-internal,
59
+ absent from every consumer repo), `.agent-settings.yml` (legacy block removed in
60
+ ADR-093), or a project-local `.ai-council.yml` (never read — ADR-104). Eyeballing
61
+ the project for these, then deciding solo instead of running the resolver, is the
62
+ canonical failure ADR-104 stops.
63
+
64
+ Only escape from user-global: `$AI_COUNCIL_CONFIG`, an explicit absolute path
65
+ for tests / power users — still not a project search.
39
66
 
40
67
  ## When NOT to invoke — necessity self-check
41
68
 
@@ -133,6 +133,15 @@ current state on the next polish round.
133
133
  - Do NOT put business logic in Blade templates — use Livewire or view composers.
134
134
  - Do NOT use inline styles — use Tailwind utility classes.
135
135
 
136
+ ## Anti-slop
137
+
138
+ Before shipping a Blade view, pull
139
+ [`docs/guidelines/design-antipatterns.md`](../../../docs/guidelines/design-antipatterns.md)
140
+ and scan Visual / Typography / Layout — the Blade markup is where side-stripe
141
+ accents (V1), icon-tile feature cards (T3), and the centered-hero + 3-column
142
+ template (L1/L2) concretely land. Stack-specific Tailwind class/hex bans live in
143
+ [`tailwind-engineer`](../tailwind-engineer/SKILL.md).
144
+
136
145
  ## Auto-trigger keywords
137
146
 
138
147
  - Blade template
@@ -0,0 +1,125 @@
1
+ ---
2
+ model_tier: inherit
3
+ name: contract-review
4
+ description: "Use when reviewing a contract clause-by-clause from your party's side — buyer/seller/vendor/licensee. Triggers on 'review this contract', 'redline this MSA', 'is this clause a problem'."
5
+ status: active
6
+ tier: senior
7
+ council_depth: deep
8
+ domain: process
9
+ recommended_for_user_types: [legal]
10
+ workspaces:
11
+ - legal-review-prep
12
+ packs:
13
+ - legal-review-prep
14
+ trust:
15
+ level: advisory
16
+ install:
17
+ removable: true
18
+ ---
19
+
20
+ # contract-review
21
+
22
+ ## When to use
23
+
24
+ - A contract draft (MSA / SOW / vendor / licence / partner agreement) needs a **position-aware, clause-by-clause** review — the user states their party role and the review adjusts to what *their* side should fear.
25
+ - An existing contract is being negotiated and each load-bearing clause needs a GREEN / YELLOW / RED severity call plus a specific redline *suggestion* (not an edit).
26
+ - A non-lawyer needs the analysis that prepares the attorney conversation: what each clause binds, where the risk concentrates, what to ask for.
27
+
28
+ Do NOT use to **issue a legal opinion** (the licensed attorney decides — see `legal-safety-floor`), for the non-lawyer cognition layer that precedes a structured review (route to [`contracts-cognition`](../contracts-cognition/SKILL.md)), or for DPA / data-processing review (route to [`dpa-review`](../dpa-review/SKILL.md)).
29
+
30
+ ## Procedure
31
+
32
+ ### Step 0: Fix the party role and the jurisdiction
33
+
34
+ 1. The user states their **party role**: `buyer` / `seller` / `vendor` / `licensee` / `licensor` (or the contract's own term). The review is asymmetric — a cap that protects the seller exposes the buyer. If the role is missing, STOP and ask once. Do not infer from prose.
35
+ 2. Read the governing-law clause. If the contract is governed by a jurisdiction **outside EU/DE scope**, REFUSE the review: *"This is governed by &lt;jurisdiction&gt; — outside this pack's EU/DE scope. Consult licensed local counsel."* Never a stale guess for an out-of-scope jurisdiction.
36
+ 3. Tag the output with `Jurisdiction: EU` or `Jurisdiction: DE` — the one you reasoned under.
37
+
38
+ ### Step 1: Establish the position profile
39
+
40
+ Read thresholds and acceptable positions from the `legal-practice-profile` (sibling skill). The skill ships **no default legal positions** — caps, notice windows, indemnity shapes, and acceptable-risk bands are the profile's, not the agent's.
41
+
42
+ Until the profile is configured, emit explicit `[configure]` placeholders (e.g. *"indemnity cap acceptable band: [configure]"*) and say plainly that no position is being asserted.
43
+
44
+ ### Step 2: Map clauses to the risk taxonomy
45
+
46
+ Walk the contract clause by clause. Classify each against a public clause-risk reference (a CUAD-style 41-category taxonomy — named as a reference; **no dataset is vendored**): liability/indemnity, term/renewal/termination, IP/licence grant, confidentiality, data, governing law, audit, exclusivity/MFN, change-of-control, payment, warranty, assignment, and the rest.
47
+
48
+ For each clause, read it **from the user's party role**: *"under what scenario does this fire, and who pays when it does?"*
49
+
50
+ ### Step 3: Assign GREEN / YELLOW / RED per clause
51
+
52
+ - **GREEN** — standard, symmetric, within (or absent-of) the profile band. A triage signal, not a clearance.
53
+ - **YELLOW** — acceptable only with a named change, or carries role-specific risk worth surfacing.
54
+ - **RED** — unbounded, one-way against the user's role, or contradicts a `[configure]`/profile band. Leads the redline list.
55
+
56
+ ### Step 4: Produce redline SUGGESTIONS (never edits)
57
+
58
+ For each YELLOW/RED clause, write a specific *suggested* ask — the cap to add, the carve-out to remove, the notice window to extend — phrased as a proposal for counsel and the negotiation lead, **not** an applied edit to the document.
59
+
60
+ ### Step 5: Surface the open questions, refuse the final call
61
+
62
+ List what the licensed attorney must decide (which clauses are counsel-led vs commercial) and the open questions the review could not resolve. Do **not** issue a sign / don't-sign verdict.
63
+
64
+ ### Step 6: Emit the review artifacts
65
+
66
+ Produce `review-frame.md` and `redline-suggestions.md` (see Output). Every artifact carries the `Jurisdiction:` tag and the work-product line below.
67
+
68
+ > ⚠️ Attorney review required on material use. This is a draft for a licensed attorney, not legal advice and not a legal conclusion.
69
+
70
+ ## Related Skills
71
+
72
+ **WHEN to use this**
73
+
74
+ - Position-aware clause-by-clause review of a contract within EU/DE scope.
75
+ - The user knows their party role and wants per-clause severity + redline suggestions.
76
+
77
+ **WHEN NOT to use this**
78
+
79
+ - Mutual / one-way NDA quick read — route to [`nda-triage`](../nda-triage/SKILL.md).
80
+ - DPA / Art. 28 / data-processing review — route to [`dpa-review`](../dpa-review/SKILL.md).
81
+ - "Is this even a legal problem / what is this document" — route to [`legal-intake-triage`](../legal-intake-triage/SKILL.md).
82
+ - Non-lawyer cognition that precedes a structured review — route to [`contracts-cognition`](../contracts-cognition/SKILL.md).
83
+
84
+ Obeys `legal-safety-floor` (rule): no final legal call, mandatory work-product line, EU/DE-only hard refusal, machine-checkable `Jurisdiction:` tag.
85
+
86
+ ## When the agent should load this
87
+
88
+ - "Review this contract from the buyer's side."
89
+ - "Redline this MSA — we're the vendor."
90
+ - "Is this indemnity clause a problem for us?"
91
+ - "Prüf diesen Vertrag aus unserer Sicht durch."
92
+ - "Worauf müssen wir als Lizenznehmer achten?"
93
+
94
+ ## Output
95
+
96
+ 1. **`review-frame.md`** — party role, `Jurisdiction:` tag, position profile read (or `[configure]` placeholders), per-clause table with GREEN/YELLOW/RED severity + risk-taxonomy category + the firing scenario from the user's side. Carries the work-product line.
97
+ 2. **`redline-suggestions.md`** — per YELLOW/RED clause, the specific suggested ask (cap / carve-out / notice window), phrased as a proposal for counsel — never an applied edit; plus the open questions and counsel-led vs commercial-led split. Carries the work-product line.
98
+
99
+ ## Gotcha
100
+
101
+ - The review is **asymmetric**: a GREEN for the seller can be a RED for the buyer. Re-run severity against the stated party role, never against "the contract" in the abstract.
102
+ - Severity is a triage signal, never a clearance — a GREEN clause is not a sign-off, and the agent never issues the sign / don't-sign call.
103
+ - The skill ships **no default positions**. A severity asserted without a profile band or a `[configure]` placeholder is a fabricated legal position — surface the gap, don't fill it.
104
+ - Out-of-scope governing law is a hard refusal, not a best-effort guess — a stale read of a jurisdiction the pack doesn't cover is worse than no read.
105
+ - Suggested redlines are proposals, not edits. Applying changes to the document silently strips the attorney's review gate.
106
+
107
+ ## Do NOT
108
+
109
+ - Do NOT issue a final legal call (sign / don't-sign / safe / unsafe) — surface analysis + open questions; the licensed attorney decides.
110
+ - Do NOT invent thresholds or acceptable positions — read them from `legal-practice-profile` or emit `[configure]`.
111
+ - Do NOT review a contract governed by an out-of-scope jurisdiction — refuse and route to licensed local counsel.
112
+ - Do NOT emit any artifact without the `Jurisdiction:` tag and the verbatim attorney work-product line in the body.
113
+ - Do NOT apply redlines as edits — emit them as suggestions only.
114
+
115
+ ## Runnable example
116
+
117
+ Vendor-side review of a customer-drafted MSA, governed by German law.
118
+
119
+ - Step 0 — party role = `vendor`; governing law = Germany → in scope. `Jurisdiction: DE`.
120
+ - Step 1 — `legal-practice-profile` not yet configured → indemnity-cap band, notice-window floor, and acceptable-liability shape all emitted as `[configure]`; output states no position is asserted.
121
+ - Step 2 — clauses mapped: uncapped IP indemnity (liability/indemnity), 3-year auto-renewal / 90-day notice (term/renewal), MFN buried in pricing schedule (exclusivity/MFN), unilateral audit right (audit).
122
+ - Step 3 — severity from vendor's side: uncapped IP indemnity → **RED**; auto-renewal + short notice → **YELLOW**; MFN → **RED** (forecloses portfolio pricing); audit right → YELLOW.
123
+ - Step 4 — redline suggestions: cap IP indemnity at `[configure]`× ACV with carve-outs; extend notice to `[configure]` days, reduce renewal to 1 year; strike MFN or limit to identical SKU; bound audit frequency + notice.
124
+ - Step 5 — open questions: is the IP-indemnity carve-out scope counsel-led (yes); auto-renewal window is commercial-led. No sign / don't-sign verdict.
125
+ - Step 6 — emit `review-frame.md` + `redline-suggestions.md`, each tagged `Jurisdiction: DE` and carrying the attorney work-product line.
@@ -0,0 +1,17 @@
1
+ {
2
+ "skill": "contract-review",
3
+ "last_eval": "2026-06-24",
4
+ "description": "5 should-trigger + 5 should-not-trigger. Should-trigger covers DE+EN phrasings for position-aware clause-by-clause review of a contract (EU/DE). Should-not-trigger covers near-miss neighbours: NDA triage (nda-triage), DPA review (dpa-review), 'is this a legal problem' triage (legal-intake-triage), and non-legal contract-of-work.",
5
+ "queries": [
6
+ { "q": "review this vendor MSA against our position as the buyer", "trigger": true },
7
+ { "q": "clause-by-clause review of this SaaS subscription agreement with redline suggestions", "trigger": true },
8
+ { "q": "prüfe diesen Vertrag klauselweise aus unserer Sicht als Lizenznehmer", "trigger": true },
9
+ { "q": "GREEN/YELLOW/RED review of this services agreement, we're the seller", "trigger": true },
10
+ { "q": "welche Klauseln in diesem Liefervertrag sind für uns riskant?", "trigger": true },
11
+ { "q": "is this NDA standard enough to just sign?", "trigger": false },
12
+ { "q": "review this data processing agreement against GDPR Art. 28", "trigger": false },
13
+ { "q": "is this even a legal problem or can we proceed?", "trigger": false },
14
+ { "q": "set up our legal playbook and jurisdiction", "trigger": false },
15
+ { "q": "review my pull request for code quality", "trigger": false }
16
+ ]
17
+ }
@@ -23,11 +23,17 @@ Do NOT use when:
23
23
 
24
24
  ## Procedure: Design a dashboard
25
25
 
26
- Ground chart-type choice in the adopted data-viz corpus, not memory:
27
- `ground.py search --manifest <skills-root>/design-intelligence/data/manifest.json
28
- --domain chart "<data shape>"` → best chart type, when-NOT-to-use, volume
29
- threshold, a11y grade + colorblind fallback, library recommendation
30
- ([`design-intelligence`](../design-intelligence/SKILL.md)).
26
+ 1. **Inspect the data sources** — Identify which signals already exist (logs, metrics, app queries) and where they live (Grafana / Loki / app DB) before designing a new panel.
27
+ 2. **Pick the surface** — Use the decision tables below to choose Grafana, app dashboard, or embed; document audience and refresh cadence.
28
+ 3. **Draft the layout** — Sketch panels, choose visualization per signal (RED / USE / Golden Signals), define filters and thresholds.
29
+ **Ground the chart-type choice** in the adopted data-viz corpus instead
30
+ of memory: `ground.py search --manifest
31
+ <skills-root>/design-intelligence/data/manifest.json --domain chart
32
+ "<data shape>"` returns the best chart type, when-NOT-to-use, data-volume
33
+ threshold, a11y grade + colorblind fallback, and a library
34
+ recommendation per row (see
35
+ [`design-intelligence`](../design-intelligence/SKILL.md)).
36
+ 4. **Implement and verify** — Build the dashboard, load realistic data, and confirm every panel answers a named question for the named audience.
31
37
 
32
38
  | Domain | Technology | Purpose |
33
39
  |---|---|---|
@@ -120,6 +126,16 @@ Config required: `allow_embedding = true`, `cookie_samesite = none` (cross-origi
120
126
  - Do NOT mix ops metrics with business KPIs on the same dashboard.
121
127
  - Do NOT show admin data without tenant scoping.
122
128
 
129
+ ## Anti-slop
130
+
131
+ Dashboards have their own signature tell: the **hero-metric template** (giant
132
+ number + small label + a row of stats + gradient) is L1 in
133
+ [`docs/guidelines/design-antipatterns.md`](../../../docs/guidelines/design-antipatterns.md).
134
+ Pull the catalog and check L1–L3 (hero-metric, identical-card grids, monotonous
135
+ spacing) before finalizing the layout — a dashboard is product-mode
136
+ (`docs/guidelines/design-modes.md`): design serves the task, so favour data
137
+ density and earned familiarity over decorative variance.
138
+
123
139
  ## Auto-trigger keywords
124
140
 
125
141
  - dashboard
@@ -9,6 +9,7 @@ workspaces:
9
9
  - engineering
10
10
  packs:
11
11
  - frontend-design
12
+ token_budget_class: rich
12
13
  trust:
13
14
  level: professional
14
15
  install:
@@ -48,6 +49,80 @@ Provenance + licenses: [`ATTRIBUTION.md`](ATTRIBUTION.md); manifest:
48
49
  layout pattern / chart type / icon system fits this product.
49
50
  - Stack-idiom lookup before writing UI code (`--stack` axis).
50
51
 
52
+ ## Cross-task design memory — read DESIGN.md / PRODUCT.md first
53
+
54
+ Before running the corpus grounding or producing any design brief, check
55
+ the project root for `DESIGN.md` and/or `PRODUCT.md` (written by
56
+ `design-system-capture`). If they exist:
57
+
58
+ 1. Read `DESIGN.md` — apply its captured visual decisions (radius, shadows,
59
+ motion, spacing) as **project constraints** that take precedence over
60
+ corpus suggestions. The corpus fills gaps; DESIGN.md overrides.
61
+ 2. Read `PRODUCT.md` — note interaction patterns that affect the design
62
+ (e.g., destructive-action policy, empty-state approach) so the brief
63
+ is consistent with existing product conventions.
64
+ 3. After generating the design brief: if a decision was made that isn't yet
65
+ in DESIGN.md (e.g., chose a specific shadow for a new elevated surface),
66
+ flag it for capture: *"Suggest adding to DESIGN.md: elevated surface shadow = …"*
67
+
68
+ Boundary vs `brand-to-tokens`/`.tokens.json`:
69
+ - `.tokens.json` = primitive definitions (gray-700 = #374151)
70
+ - `DESIGN.md` = usage decisions (elevated surfaces use the gray-700 shadow, 8px radius)
71
+ Both are consumed; DESIGN.md takes precedence for usage questions.
72
+
73
+ ## Register — brand vs product
74
+
75
+ Determine the design register before grounding (see
76
+ [`docs/guidelines/design-modes.md`](../../../docs/guidelines/design-modes.md)):
77
+ **brand mode** ("the impression IS the product" — marketing, landing, consumer
78
+ first-impression) prioritizes distinctive selection; **product mode** ("design
79
+ serves the task" — dashboard, admin, workflow) prioritizes earned familiarity
80
+ and accessibility. The register changes which corpus selections are appropriate
81
+ (distinctive palette/typography in brand mode; predictable, semantic in product
82
+ mode). State the register in the Design Read line below.
83
+
84
+ ## Design Read — articulate intent before generating
85
+
86
+ Before producing any design brief or making any style selection, emit one
87
+ line that declares the design read:
88
+
89
+ ```
90
+ Reading this as: <page-kind> for <audience>, <vibe> language, leaning <design-system>.
91
+ ```
92
+
93
+ Examples:
94
+ - `Reading this as: SaaS dashboard for internal ops teams, functional language, leaning Radix/shadcn.`
95
+ - `Reading this as: marketing landing for B2C consumer product, playful editorial, leaning custom tokens.`
96
+ - `Reading this as: admin panel for technical users, dense/utilitarian language, leaning data-grid primitives.`
97
+
98
+ **If context is incomplete:** state so and proceed exploratory — *"Design context incomplete: no audience defined; proposing exploratory direction, expect revision after audience is clarified."* Do NOT block on missing context; do NOT prompt the user with a gate; state the gap and continue.
99
+
100
+ **Anti-Default Discipline — first-impulse check:** Before committing to any design direction, verify you are NOT defaulting to:
101
+ - Purple/violet + cyan-on-dark gradient palette (AI color cliché)
102
+ - Centered hero over a dark gradient mesh with a single CTA
103
+ - Three equal-weight feature cards in a grid
104
+ - Inter or Space Grotesk as the uncritical body font choice
105
+ - "Premium consumer" cream/sand background + brass/clay accents
106
+
107
+ If any of these was the first impulse, name a different direction or explicitly justify why this brief genuinely calls for it.
108
+
109
+ ## Honesty / real-system grounding
110
+
111
+ When the brief maps to an official design system (Material Design, Fluent,
112
+ Carbon, Polaris, GOV.UK, shadcn, Tailwind UI, Radix, etc.):
113
+
114
+ 1. **Install the real package** — do not hand-recreate its CSS or components.
115
+ Surface the install command for the project's package manager (the
116
+ system's official package, e.g. the shadcn CLI or the `@mui/material`
117
+ distribution) and link the canonical documentation URL.
118
+ 2. **Never label an approximation as the official system.** If generating
119
+ approximate CSS for a system the project does not yet depend on, label it
120
+ explicitly: *"Approximation of Material Design elevation — not the official
121
+ `@mui/material` package; install the package for production use."*
122
+ 3. **If no official system is relevant:** pick a deliberate creative direction
123
+ (see Design Read above); never fall back to an unnamed generic aesthetic
124
+ (per `source-discovery-gate`: real source before guessing).
125
+
51
126
  ## Procedure: Produce a grounded design brief (`ui-design-brief` rebound)
52
127
 
53
128
  1. **Ground** (one call — engine runs the manifest's plan
@@ -170,6 +245,27 @@ guidance + docs URLs from here instead of memory.
170
245
  - Keep queries product-shaped ("fintech dashboard", "luxury e-commerce
171
246
  mobile") — the detect map routes generic words to `style`.
172
247
 
248
+ ## Anti-slop discipline
249
+
250
+ Before finalizing any design brief, cross-check against
251
+ [`docs/guidelines/design-antipatterns.md`](../../../docs/guidelines/design-antipatterns.md)
252
+ — especially the Color (C1–C5), Typography (T7–T8), and Layout (L1–L2) sections.
253
+ If the grounded corpus selection lands on a pattern in the catalog, either invoke
254
+ the override condition or adjust the selection. Run the AI-slop originality
255
+ self-test (catalog § "The AI-slop originality self-test") on the chosen aesthetic
256
+ direction before emitting `design_confirmed`.
257
+
258
+ ## Why this skill is rich
259
+
260
+ This skill carries 11 tabular CSVs (161-row UI-reasoning decision map,
261
+ WCAG-adjusted color token sets, 84 styles, 73 font pairings, 25 chart rules, UX/
262
+ react/mobile guidelines) plus 16 prose design-language specs and a 10-category
263
+ pre-delivery checklist. Agents need to see the full corpus to make grounded
264
+ selections — condensing to a summary destroys the evidence trail ("corpus
265
+ row 47 justifies the palette choice") that the skill's output contract requires.
266
+ Compressing the 16 design-language specs into fragments makes the style
267
+ selection unreproducible and audit-unfriendly.
268
+
173
269
  ## Policies
174
270
 
175
271
  - Upstream MIT + Apache-2.0 obligations: [`ATTRIBUTION.md`](ATTRIBUTION.md).