@event4u/agent-config 10.2.0 → 10.4.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 (96) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +168 -256
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/analyze/reference-repo.md +62 -0
  5. package/dist/agent-src/commands/analyze.md +2 -1
  6. package/dist/agent-src/commands/design-system/capture.md +44 -0
  7. package/dist/agent-src/commands/design-system/generate.md +53 -0
  8. package/dist/agent-src/commands/design-system/import.md +63 -0
  9. package/dist/agent-src/commands/design-system.md +66 -0
  10. package/dist/agent-src/commands/roadmap/create.md +4 -1
  11. package/dist/agent-src/personas/advisors/first-principles.md +6 -0
  12. package/dist/agent-src/rules/active-remediation.md +53 -2
  13. package/dist/agent-src/rules/code-provenance.md +66 -4
  14. package/dist/agent-src/rules/content-quoting-floor.md +6 -0
  15. package/dist/agent-src/rules/design-fidelity.md +49 -3
  16. package/dist/agent-src/skills/design-review/references/verification-automation.md +23 -1
  17. package/dist/agent-src/skills/design-system-capture/SKILL.md +9 -0
  18. package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +70 -0
  19. package/dist/agent-src/skills/fe-design/SKILL.md +27 -3
  20. package/dist/agent-src/skills/judge-synthesis/SKILL.md +30 -0
  21. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +11 -0
  22. package/dist/agent-src/skills/roadmap-writing/SKILL.md +8 -8
  23. package/dist/agent-src/skills/skill-writing/SKILL.md +4 -0
  24. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  25. package/dist/agent-src/templates/persona.md +26 -0
  26. package/dist/agent-src/templates/roadmaps.md +27 -7
  27. package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +4 -1
  28. package/dist/agent-src/templates/skill.md +35 -1
  29. package/dist/cli/commands/commands.candidates.test.js +257 -0
  30. package/dist/cli/commands/commands.candidates.test.js.map +1 -0
  31. package/dist/cli/commands/commands.js +199 -0
  32. package/dist/cli/commands/commands.js.map +1 -1
  33. package/dist/cli/main.js +1 -0
  34. package/dist/cli/main.js.map +1 -1
  35. package/dist/cli/registry.js +1 -1
  36. package/dist/cli/registry.js.map +1 -1
  37. package/dist/cli-delegate/{chunk-E4RUZKXB.js → chunk-FV34EGEX.js} +1 -1
  38. package/dist/cli-delegate/chunk-RLN73PR5.js +157 -0
  39. package/dist/cli-delegate/{chunk-I5EAFRII.js → chunk-ZPSXJTLI.js} +2 -154
  40. package/dist/cli-delegate/cmd_conformance.js +672 -214
  41. package/dist/cli-delegate/cmd_doctor.js +1 -1
  42. package/dist/cli-delegate/cmd_handoff.js +8 -6
  43. package/dist/cli-delegate/cmd_session_recycle.js +5 -3
  44. package/dist/discovery/deprecation-report.md +1 -1
  45. package/dist/discovery/discovery-manifest.json +127 -22
  46. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  47. package/dist/discovery/discovery-manifest.summary.md +3 -3
  48. package/dist/discovery/dormancy-report.md +1 -1
  49. package/dist/discovery/orphan-report.md +1 -1
  50. package/dist/discovery/packs.json +9 -5
  51. package/dist/discovery/trust-report.md +2 -2
  52. package/dist/discovery/workspaces.json +8 -4
  53. package/dist/hooks/dispatch.js +1056 -411
  54. package/dist/mcp/registry-manifest.json +3 -3
  55. package/dist/mcp/server.json +2 -2
  56. package/dist/mcp/server.mjs +1103 -593
  57. package/dist/router.json +1 -1
  58. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +54 -0
  59. package/docs/guidelines/design-antipatterns.md +79 -10
  60. package/docs/guidelines/design-fidelity-mechanics.md +120 -2
  61. package/package.json +1 -1
  62. package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +4 -1
  63. package/src/config/gate-coverage.yml +65 -10
  64. package/src/config/gate-violation-baselines.json +6 -0
  65. package/src/config/review-prompt-binding-baseline.json +19 -0
  66. package/src/config/rule-enforcement-baseline.json +0 -1
  67. package/src/scripts/_dispatch.bash +1 -0
  68. package/src/scripts/_lib/design_system_import.ts +987 -0
  69. package/src/scripts/ai_council/clients.ts +15 -1
  70. package/src/scripts/check_ci_local_parity.ts +60 -6
  71. package/src/scripts/check_review_prompt_binding.ts +553 -0
  72. package/src/scripts/check_suppression_hygiene.ts +19 -3
  73. package/src/scripts/design_slop_rules.test.ts +37 -6
  74. package/src/scripts/design_slop_rules.ts +150 -22
  75. package/src/scripts/design_system_import.ts +264 -0
  76. package/src/scripts/dispatch_r2_reviewer.ts +15 -1
  77. package/src/scripts/hook_manifest.yaml +71 -2
  78. package/src/scripts/hooks/concern_registry.ts +4 -0
  79. package/src/scripts/hooks/dispatch_hook.ts +10 -0
  80. package/src/scripts/hooks/host_semantics.ts +2 -0
  81. package/src/scripts/hooks/spawn_guard_shadow_hook.ts +212 -0
  82. package/src/scripts/hooks/subagent_ledger_hook.ts +723 -0
  83. package/src/scripts/hooks/turn_end_gate_hook.ts +39 -2
  84. package/src/scripts/hooks/ui_route_nudge_hook.ts +55 -2
  85. package/src/scripts/lint_design_antipattern_parity.ts +201 -0
  86. package/src/scripts/lint_harvest_provenance.ts +483 -0
  87. package/src/scripts/lint_hook_manifest.ts +2 -0
  88. package/src/scripts/lint_rule_skill_pack_reach.ts +194 -13
  89. package/src/scripts/lint_skill_router_head.ts +254 -0
  90. package/src/scripts/report_consultation_rate.ts +126 -1
  91. package/src/scripts/run_skill_evals.ts +10 -5
  92. package/src/scripts/schemas/persona.schema.json +8 -0
  93. package/src/scripts/schemas/provenance-harvest.schema.json +39 -0
  94. package/src/scripts/sweep_dead_scan_roots.ts +51 -0
  95. package/tests/fixtures/hooks/subagent_start.json +7 -0
  96. package/tests/fixtures/hooks/subagent_stop.json +8 -0
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![Smoke](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml/badge.svg)](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml) [![Public install smoke (3 OS × 2 Node)](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml/badge.svg)](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml) [![npm](https://img.shields.io/npm/v/@event4u/agent-config?style=flat-square&label=npm&color=orange)](https://www.npmjs.com/package/@event4u/agent-config) [![agent-config MCP server](https://glama.ai/mcp/servers/event4u-app/agent-config/badges/score.svg)](https://glama.ai/mcp/servers/event4u-app/agent-config) [![MCP Toplist](https://mcptoplist.com/badge/glama%2Fevent4u-app%2Fagent-config.svg)](https://mcptoplist.com/server/glama%2Fevent4u-app%2Fagent-config)
6
6
 
7
- [![Skills](https://img.shields.io/badge/Skills-289-orange?style=flat-square)](dist/agent-src/skills/) [![Rules](https://img.shields.io/badge/Rules-116-orange?style=flat-square)](dist/agent-src/rules/) [![Commands](https://img.shields.io/badge/Commands-196-orange?style=flat-square)](dist/agent-src/commands/) [![Guidelines](https://img.shields.io/badge/Guidelines-105-orange?style=flat-square)](docs/guidelines/) [![Personas](https://img.shields.io/badge/Personas-29-orange?style=flat-square)](dist/agent-src/personas/) [![Advisors](https://img.shields.io/badge/Advisors-5-orange?style=flat-square)](dist/agent-src/personas/advisors/)
7
+ [![Skills](https://img.shields.io/badge/Skills-289-orange?style=flat-square)](dist/agent-src/skills/) [![Rules](https://img.shields.io/badge/Rules-116-orange?style=flat-square)](dist/agent-src/rules/) [![Commands](https://img.shields.io/badge/Commands-200-orange?style=flat-square)](dist/agent-src/commands/) [![Guidelines](https://img.shields.io/badge/Guidelines-105-orange?style=flat-square)](docs/guidelines/) [![Personas](https://img.shields.io/badge/Personas-29-orange?style=flat-square)](dist/agent-src/personas/) [![Advisors](https://img.shields.io/badge/Advisors-5-orange?style=flat-square)](dist/agent-src/personas/advisors/)
8
8
 
9
9
  **Try it in 30 seconds** — drop one read-only subagent into any repo and watch it gate "done": `@production-validator check this branch is actually done`. No wizard, no lock-in, nothing else installed — the [30-second wedge ↓](#quickstart) is the whole first step. Start at the proof, not the catalog: **[event4u-app.github.io/agent-config/proof/](https://event4u-app.github.io/agent-config/proof/)**.
10
10
 
@@ -254,9 +254,35 @@ incomplete document. Never a drawer to fill.}
254
254
 
255
255
  {Only if --no-roadmap was not set.}
256
256
 
257
+ ## Seeds
258
+
259
+ {One block per ADOPT/ADAPT row whose adoption lands in a NEW skill or rule —
260
+ omit the section entirely when every row extends something that exists.}
261
+
262
+ ### SEED — {proposed-name}
263
+
264
+ > Proposal. Nothing is created from this block without an explicit ask.
265
+
266
+ - **Kind:** skill | rule
267
+ - **Target template:** `src/agent-src/templates/skill.md` | `.../rule.md`
268
+ - **One-line description:** {what it does, in the voice the template wants}
269
+ - **Cites:** {harvest ids this artefact will carry, once § 8 records them}
270
+ - **Extends instead?** {the nearest existing artefact considered, and why it
271
+ does not fit — a seed that skipped this line is not ready to hand over}
272
+
257
273
  ## Open questions for the maintainer
258
274
  ```
259
275
 
276
+ The `## Seeds` section is the handoff shape
277
+ [`learning-to-rule-or-skill`](../../../../skills/learning-to-rule-or-skill/SKILL.md)
278
+ accepts as intake. It is a **proposal artifact, never an auto-created file** —
279
+ the block says so in its own first line, so the property survives being read out
280
+ of context. The `Extends instead?` field is load-bearing rather than decorative:
281
+ it makes the four-surface overlap scan that
282
+ [`artifact-drafting-protocol`](../../../../rules/artifact-drafting-protocol.md)
283
+ requires visible at handoff time, when the analysis is still open, instead of
284
+ re-derived later by whoever picks the seed up.
285
+
260
286
  ### 7. Offer next steps
261
287
 
262
288
  After writing the file, present:
@@ -270,6 +296,42 @@ After writing the file, present:
270
296
 
271
297
  Never create the roadmap without explicit confirmation.
272
298
 
299
+ ### 8. Close the loop — offer the ledger rows
300
+
301
+ **Only after a roadmap draft is accepted** (option 1 or 2 above). This step
302
+ exists because the command otherwise ends with the knowledge it harvested
303
+ recorded nowhere citable: the analysis document is archived evidence, and the
304
+ next comparative pass re-litigates the same provenance from scratch.
305
+
306
+ Offer — never write unasked, same confirmation floor as every other write here:
307
+
308
+ > Record {N} harvest row(s) in `provenance/harvests.jsonl`?
309
+ > {one preview line per row}
310
+
311
+ One row per **anchored ADOPT or ADAPT** finding, and nothing else:
312
+
313
+ | Field | Filled from |
314
+ |---|---|
315
+ | `harvest_id` | a kebab-case slug for the mechanism |
316
+ | `stated_in` | the roadmap file the user just accepted |
317
+ | `source_ref` | the reference's `<url>@<sha>` — the § 2 pin, already recorded in the document header |
318
+ | `evidence_locator` | the reference-side `file:line` from that row of the comparison matrix |
319
+ | `harvested_at` | today |
320
+ | `verdict` | `adopt` or `adapt` |
321
+
322
+ **REJECT, ALREADY, and UNCLEAR rows produce nothing.** Not an oversight: the
323
+ ledger's integrity gate asserts that every row's `stated_in` artefact exists,
324
+ and a rejected finding has no artefact — it is recorded in this analysis
325
+ document, which is where a later harvest goes to learn the question was already
326
+ settled. Writing rejections into the ledger would either break the gate or
327
+ force it to stop checking the thing it exists to check.
328
+
329
+ **Confidential sources.** When [`source-confidentiality`](../../../../rules/source-confidentiality.md)
330
+ keeps the reference's name out of the tracked tree, `source_ref` takes the
331
+ opaque form (`opaque:<id>` / an `ENC1:` token) instead of the URL. The row still
332
+ pins something; it just does not name it. Contract and field shapes:
333
+ `provenance/README.md`.
334
+
273
335
  ## Safety
274
336
 
275
337
  - Read-only on the reference. Never execute it, never submit PRs to it. Never
@@ -5,7 +5,7 @@ disable-model-invocation: true
5
5
  argument-hint: "[postmortem|premortem|decision|near-miss|incident|reference-repo|inbox] [subject]"
6
6
  pack: analysis-workbench
7
7
  intent: "Analysis dispatcher — classify input by keywords, propose a weighted framework path, let the user pick"
8
- routes_to: [analyze-postmortem, analyze-premortem, analyze-decision, analyze-near-miss, analyze-incident, analyze-reference-repo, analyze-inbox]
8
+ routes_to: [analyze-postmortem, analyze-premortem, analyze-decision, analyze-near-miss, analyze-incident, analyze-reference-repo, analyze-inbox, analyze-conformance]
9
9
  replaces: []
10
10
  tier: 1
11
11
  visibility: advanced
@@ -40,6 +40,7 @@ to the chosen sub-command. Never auto-selects silently.
40
40
  | `/analyze:incident` | `analyze/incident/command.md` | Full incident flow: commander → RCA → post-mortem → memory candidate |
41
41
  | `/analyze:reference-repo` | `analyze/reference-repo/command.md` | Deep-dive an external reference repo (competitor, inspiration, peer) → structured comparison + adoption plan |
42
42
  | `/analyze:inbox` | `analyze/inbox/command.md` | Deep-dive a LOCAL artifact dropped in `agents/tmp/` (review, prompt, spec, transcript) → claim verification against the current tree + artefact mapping + roadmap |
43
+ | `/analyze:conformance` | `analyze/conformance/command.md` | Audit recent local sessions for rule violations → deterministic scan + subagent passes, root-caused per class, and a roadmap for what is mechanisable |
43
44
 
44
45
  ## Dispatch
45
46
 
@@ -0,0 +1,44 @@
1
+ ---
2
+ model_tier: medium
3
+ name: design-system-capture
4
+ pack: engineering-base
5
+ tier: 2
6
+ visibility: internal
7
+ cluster: design-system
8
+ sub: capture
9
+ skills: [existing-ui-audit, design-system-capture]
10
+ description: Inventory this repo's own components and tokens and emit them in the design-system.json shape, so the import path is identical to an external extraction.
11
+ argument-hint: "[path]"
12
+ suggestion:
13
+ eligible: false
14
+ rationale: "Cluster sub-command — reached via its cluster head's routing or its explicit /cluster:sub name; not independently suggested (surface-consolidation)."
15
+ workspaces:
16
+ - engineering
17
+ packs:
18
+ - frontend-design
19
+ ---
20
+
21
+ # /design-system:capture
22
+
23
+ Run [`existing-ui-audit`](../../skills/existing-ui-audit/SKILL.md) over the
24
+ current repo and emit its inventory as a `design-system.json` artifact — the
25
+ same shape an external extraction tool produces, so the import path is identical
26
+ either way. Args: optional `[path]` to narrow the scan.
27
+
28
+ Two sources, one shape: use this for **this** repo, and
29
+ [`/design-system:import`](../import/command.md) for a site or repo you do not
30
+ own.
31
+
32
+ ## Then hand it over
33
+
34
+ Pass the emitted artifact to [`design-system-capture`](../../skills/design-system-capture/SKILL.md)'s
35
+ import step, which confirms it per field into `DESIGN.md`.
36
+
37
+ ## Rules
38
+
39
+ - **Set `source` honestly** — `kind: dir`, `ref` = the scanned path,
40
+ `captured_at` = now. An artifact with no provenance is rejected downstream.
41
+ - **Observation is not a token.** Anything the audit *noticed* rather than
42
+ *decided* belongs under `_meta`, per the contract's field rules.
43
+ - **The audit's own grouping is not the contract's shape.** Map it deliberately;
44
+ do not rename the audit's output keys and call it done.
@@ -0,0 +1,53 @@
1
+ ---
2
+ model_tier: high
3
+ name: design-system-generate
4
+ pack: engineering-base
5
+ tier: 2
6
+ visibility: internal
7
+ cluster: design-system
8
+ sub: generate
9
+ skills: [corpus-grounding, design-intelligence, design-system-capture]
10
+ description: Ground a design system in the curated design corpus from a product or industry brief, then optionally persist it as MASTER.md or seed DESIGN.md.
11
+ argument-hint: "<product / industry / keywords>"
12
+ suggestion:
13
+ eligible: false
14
+ rationale: "Cluster sub-command — reached via its cluster head's routing or its explicit /cluster:sub name; not independently suggested (surface-consolidation)."
15
+ workspaces:
16
+ - engineering
17
+ packs:
18
+ - frontend-design
19
+ ---
20
+
21
+ # /design-system:generate
22
+
23
+ Run the grounded one-shot over the curated corpus and print the full
24
+ recommendation. Args: `"<product / industry / keywords>"`.
25
+
26
+ ```bash
27
+ npx tsx node_modules/@event4u/agent-config/src/skills/corpus-grounding/scripts/ground.ts \
28
+ ground "<query>" \
29
+ --manifest node_modules/@event4u/agent-config/src/skills/design-intelligence/data/manifest.json
30
+ ```
31
+
32
+ Add `--persist <dir> --project-name <name>` to write
33
+ `design-system/<slug>/MASTER.md`, and `--page <name>` for a page-override stub
34
+ alongside it. The engine is read-only without `--persist`.
35
+
36
+ ## After the recommendation
37
+
38
+ Offer both destinations, and let the human pick — they are different artifacts,
39
+ not two spellings of one:
40
+
41
+ - **`MASTER.md` + page overrides** (`--persist`) — the interchange format, good
42
+ for handing a system to another tool or to a designer.
43
+ - **`DESIGN.md`** via [`design-system-capture`](../../skills/design-system-capture/SKILL.md)
44
+ — this package's canonical design memory, the file every later design task
45
+ reads. Seed it when the system is for *this* repo's own work.
46
+
47
+ ## Rules
48
+
49
+ - **Generated output is a proposal.** A provided artifact, registered brand
50
+ tokens, and a confirmed `DESIGN.md` outrank it — never overwrite a confirmed
51
+ decision with a generated default.
52
+ - **Never persist silently.** `--persist` is the human's choice, and `DESIGN.md`
53
+ is seeded per field, not written wholesale.
@@ -0,0 +1,63 @@
1
+ ---
2
+ model_tier: medium
3
+ name: design-system-import
4
+ pack: engineering-base
5
+ tier: 2
6
+ visibility: internal
7
+ cluster: design-system
8
+ sub: import
9
+ skills: [design-system-capture]
10
+ description: Run an extraction tool's output through the three-lane adapter into the design-system.json contract, then hand it to the per-field confirmation import.
11
+ argument-hint: "<file>"
12
+ suggestion:
13
+ eligible: false
14
+ rationale: "Cluster sub-command — reached via its cluster head's routing or its explicit /cluster:sub name; not independently suggested (surface-consolidation)."
15
+ workspaces:
16
+ - engineering
17
+ packs:
18
+ - frontend-design
19
+ ---
20
+
21
+ # /design-system:import
22
+
23
+ Transform an extracted design system into the `design-system.json` contract,
24
+ then import it per field. Args: `<file>`.
25
+
26
+ ```bash
27
+ npx tsx node_modules/@event4u/agent-config/src/scripts/design_system_import.ts <file> \
28
+ [--lane native|dtcg|dembrandt] \
29
+ [--source-kind url|repo|dir --source-ref <ref>] [--captured-at <ISO>] \
30
+ [--format json|summary]
31
+ ```
32
+
33
+ The lane is detected from the file's own shape; `--lane` only forces which
34
+ mapper runs and never reshapes the input. Lane behaviour, the documented
35
+ producers, and the never-force-a-lane degradation are specified in
36
+ [`design-system-json.md`](../../skills/design-system-capture/references/design-system-json.md)
37
+ § Extractor compatibility.
38
+
39
+ ## The easy path, in two lines
40
+
41
+ 1. Connect an extractor once — e.g.
42
+ `claude mcp add --transport stdio dembrandt -- npx -y --package dembrandt dembrandt-mcp`.
43
+ 2. Run `/design-system:import` over its output.
44
+
45
+ No extractor available? Skip step 1 and use
46
+ [`/design-system:generate`](../generate/command.md) from the corpus instead, or
47
+ [`/design-system:capture`](../capture/command.md) for this repo.
48
+
49
+ ## Then hand it over
50
+
51
+ Pass the result to [`design-system-capture`](../../skills/design-system-capture/SKILL.md)'s
52
+ import step. Do not write `DESIGN.md` from here.
53
+
54
+ ## Rules
55
+
56
+ - **Provenance is mandatory.** A file with no `source` and no `--source-ref` is
57
+ rejected — you cannot confirm what you cannot trace. Supplying it by flag is
58
+ recorded as caller-asserted, not extracted.
59
+ - **The artifact is observed, not authoritative.** Every field is confirmed by
60
+ the human; a value conflicting with a registered brand token is flagged, never
61
+ auto-applied.
62
+ - **The adapter is offline.** It reads a file and writes the contract shape — it
63
+ never fetches, crawls, or launches a browser.
@@ -0,0 +1,66 @@
1
+ ---
2
+ model_tier: inherit
3
+ name: design-system
4
+ pack: engineering-base
5
+ tier: 2
6
+ visibility: internal
7
+ cluster: design-system
8
+ type: orchestrator
9
+ description: Design-system onramp — generate one from the corpus, import an extractor's output, or capture the current repo's. Three doors onto machinery that already ships.
10
+ argument-hint: "[generate|import|capture] [args]"
11
+ suggestion:
12
+ eligible: true
13
+ trigger_description: "generate a design system, import extracted design tokens, capture this repo's design system, seed DESIGN.md from a site"
14
+ trigger_context: "user explicitly wants a design system produced, imported, or captured — never suggested for ordinary UI work"
15
+ workspaces:
16
+ - engineering
17
+ packs:
18
+ - frontend-design
19
+ ---
20
+
21
+ # /design-system
22
+
23
+ Three doors onto machinery this package already ships and nothing could reach.
24
+ The grounded generator, its `MASTER.md` persistence, the `design-system.json`
25
+ import contract, and the current-repo inventory all existed before this cluster;
26
+ what was missing was a way in. So every sub-command below is an entry point, not
27
+ a new subsystem.
28
+
29
+ **Optional means invoked or not invoked.** This cluster adds no settings key, no
30
+ always-on rule, and no auto-trigger. It is suggestion-eligible only when a
31
+ design-system question is explicit, and otherwise silent.
32
+
33
+ ## Sub-commands
34
+
35
+ | Sub-command | Routes to | Purpose |
36
+ |---|---|---|
37
+ | `/design-system:generate "<product / industry / keywords>"` | `commands/design-system/generate.md` | Ground a design system in the curated corpus; optionally persist `MASTER.md` + page overrides, or seed `DESIGN.md` |
38
+ | `/design-system:import <file>` | `commands/design-system/import.md` | Run an extractor's output through the three-lane adapter, then the per-field confirmation import |
39
+ | `/design-system:capture` | `commands/design-system/capture.md` | Inventory *this* repo's components and tokens and emit the same `design-system.json` shape |
40
+
41
+ ## Dispatch
42
+
43
+ 1. Parse `/design-system <sub-command> [args]`. Sub-command = first token; match
44
+ against the table's exact names only.
45
+ 2. Look up the sub-command and execute its file verbatim with the remaining args.
46
+ 3. Unknown / missing sub-command → print the table and ask which door to take.
47
+
48
+ ## Rules
49
+
50
+ - **Do NOT commit, push, or open a PR** — subcommands never do this.
51
+ - **Do NOT chain subcommands.** One `/design-system <sub>` per turn.
52
+ - **Generated and imported output is a proposal.** A provided artifact,
53
+ registered brand tokens, and a confirmed `DESIGN.md` all outrank it; a value
54
+ that conflicts with a registered brand token is flagged, never auto-applied
55
+ (per [`brand-source-of-truth`](../rules/brand-source-of-truth.md)).
56
+ - **No crawler, browser runtime, or font-bundler is shipped.** Extraction tools
57
+ are user-installed and user-connected; this package's share is the adapter,
58
+ the instructions, and the validation.
59
+ - **Edit `src/` only.** Generated mirrors regenerate.
60
+
61
+ ## See also
62
+
63
+ - [`design-system-capture`](../../skills/design-system-capture/SKILL.md) — owns `DESIGN.md` and the per-field-confirmation import.
64
+ - [`corpus-grounding`](../../skills/corpus-grounding/SKILL.md) · [`design-intelligence`](../../skills/design-intelligence/SKILL.md) — the grounded generator behind `:generate`.
65
+ - [`existing-ui-audit`](../../skills/existing-ui-audit/SKILL.md) — the current-repo inventory behind `:capture`.
66
+ - [`docs/contracts/command-clusters.md`](../docs/contracts/command-clusters.md) — `design-system` cluster registration.
@@ -268,7 +268,10 @@ Write the pick to frontmatter as `execution.mode:`
268
268
  rewrite each hit as an agent-verifiable check (a command, a targeted
269
269
  test) **before saving**, or promote it to a structured `## Blockers`
270
270
  entry: a **human gate** only when only a human can decide/authorize
271
- (Hard-Floor authorization, billable spend, contested decision); an
271
+ (Hard-Floor authorization, billable spend, or a decision bound to
272
+ preference, risk appetite, or product intent). A contested **technical**
273
+ decision is not a human gate while a council is configured — it is a
274
+ step whose first action runs the council (template rule 22); an
272
275
  **external dependency** becomes a blocker whose `Resolved when:`
273
276
  names an agent-checkable status probe — never a human gate. Do not
274
277
  author safety floors as steps — they fire at run time on their own.
@@ -7,6 +7,12 @@ mode: reviewer
7
7
  version: "1.0"
8
8
  source: package
9
9
  council_advisor: true
10
+ # Explicitly empty, not merely unset: reconstructing a problem from its
11
+ # irreducible constraints is this advisor's whole function, so "asserts no
12
+ # harvested doctrine" is a statement about the lens rather than a gap in one.
13
+ # Every other persona leaves the field absent (unscoped) — see the sources
14
+ # block in templates/persona.md for the three states.
15
+ sources: []
10
16
  ---
11
17
 
12
18
  # First-Principles Advisor
@@ -16,9 +16,11 @@ routes_to:
16
16
  - "guideline:agent-infra/active-remediation-mechanics"
17
17
  workspaces: [engineering]
18
18
  packs: [engineering-base]
19
+ enforced_by:
20
+ - "none"
19
21
  collision_ok:
20
22
  "refactor": "an explicit clean-up/refactor ask is the remediation ladder's own trigger"
21
- # obligation: line 51
23
+ # obligation: line 31
22
24
  obligation_frequency: "per-edit"
23
25
  ---
24
26
 
@@ -34,16 +36,53 @@ SMALL + TASK-ALIGNED → FIX IT NOW, IN THE SAME CHANGE, WITH ITS TEST.
34
36
  BIGGER OR DIVERGENT → NOTE IT, FINISH THE TASK, THEN ASK — NEVER MID-FLOW.
35
37
  TOO MANY → PROPOSE ONE OR MORE SEPARATE FOLLOW-UP PRs THE USER REVIEWS.
36
38
  A LIVE SECURITY / DATA-EXPOSURE GAP IS NEVER MERELY "NOTED FOR LATER".
39
+ A NOTE IS NOT A DISCHARGE — THE DECISION IS. AN ISSUE REPORTED IN PROSE AND
40
+ NEITHER FIXED NOR PUT TO THE USER IS STILL OPEN, AND STILL YOURS.
41
+ THE ASK CARRIES CANDIDATE FIXES AND AN EXPLICIT "LEAVE IT" — NEVER A BARE FLAG.
37
42
  ```
38
43
 
39
44
  ## What to remediate
40
45
 
41
- Security gaps (broken access control, injection, secrets, missing authz — see `broken-access-control`) · missing/weak test coverage · bad code (dead code, silent error-swallow, unguarded edge cases) · **duplication** (the same or near-same logic repeated instead of one method/abstraction) · **stale version-idioms** (code written for an older language/framework version than the project actually runs).
46
+ Security gaps (broken access control, injection, secrets, missing authz — see `broken-access-control`) · missing/weak test coverage · bad code (dead code, silent error-swallow, unguarded edge cases) · **duplication** (the same or near-same logic repeated instead of one method/abstraction) · **stale version-idioms** (code written for an older language/framework version than the project actually runs) · **a failing check you already ran** (below).
47
+
48
+ ## A check you already ran is a spotted issue
49
+
50
+ A red gate, a failing test, a lint or type error — output the tooling already put
51
+ in front of you — is **spotted**, exactly like a defect read in a file, and
52
+ enters the ladder on the same terms. "It was already red before I got here"
53
+ decides *which* tier, never whether the ladder applies.
54
+
55
+ Two bounds: **only output you already have** (never an obligation to go run a
56
+ check — the remote CI stays the authoritative gate), and **ownership picks the
57
+ tier, never the silence**. Classification + worked example: the mechanics
58
+ guideline below.
42
59
 
43
60
  ## The ladder — three tiers
44
61
 
45
62
  **Fix now** — small + task-aligned; ALL five conditions hold: same request path/module · ≤ ~10 changed lines in one production file (plus its test file) · no public-API / response-shape change · no dependency bump, no migration · verification ships in the same commit. Anything outside → next tier. · **Note + ask** (batched, one numbered-options prompt after delivery) · **Follow-up PR** (many spots; creation stays permission-gated). Per-tier detail + version-gated modernization + guardrails: the mechanics guideline below.
46
63
 
64
+ ## Every noted issue ends in one of three states
65
+
66
+ **Fixed**, **decided by the user** (an explicit "leave it" is terminal and is not
67
+ raised again, per [`scope-control`](scope-control.md)), or **in front of the user
68
+ right now** as the batched ask. A line in the closing summary is none of the
69
+ three: it leaves the issue open while sounding like it was handled, and it is the
70
+ failure this rule exists to stop. An undecided item survives the turn — raised
71
+ once more at the next task boundary, never aged out. A declined batch is closed.
72
+
73
+ ## The ask carries fixes, not a flag
74
+
75
+ "There are 7 lint errors — shall I fix them?" hands the problem back untouched.
76
+ Each numbered option is a candidate the user can pick without a follow-up
77
+ question — what changes, where, roughly how large, what it costs — grouped by fix
78
+ shape rather than one per finding, with an explicit **leave it as is** last and
79
+ one recommendation line (per [`user-interaction`](user-interaction.md)).
80
+
81
+ The ask is subordinate to [`no-cheap-questions`](no-cheap-questions.md): its
82
+ Pre-Send Self-Check runs first, and a finding with no nameable benefit or no real
83
+ trade-off is dropped silently instead of becoming a question. That check forbids
84
+ a content-free ask, never the surfacing of a genuine defect.
85
+
47
86
  ## Live-security carve-out (priority)
48
87
 
49
88
  A **live cross-user / cross-tenant data exposure** (per `broken-access-control`) is not a "note for later": it is a potential GDPR-notifiable breach (Art. 33, 72 h from discovery). If it meets the fix-now bar → fix it now with its negative test. If not → **stop and surface it immediately** (a safety surface, visible even under an autonomous mandate — like the `no-pr-progress-comments` safety carve-out). Never defer it silently, never look away.
@@ -56,6 +95,16 @@ While implementing/modifying code you pass an issue outside the literal task. Al
56
95
 
57
96
  - No issue spotted. Prose/docs-only. The user fenced the scope ("just this one line").
58
97
  - The issue is the task itself — then it's just the task (no ladder needed).
98
+ - The user already decided this item (fixed later, or explicitly ignored).
99
+
100
+ ## Honest enforcement — `enforced_by: none`
101
+
102
+ The note, the ask and the user's decision are all prose, and the issue set is
103
+ whatever the agent happened to see, so no gate can tell a discharged issue from a
104
+ mentioned one. This rule ships `enforced_by: none` — the honesty boundary
105
+ [`security-sensitive-stop`](security-sensitive-stop.md) and
106
+ [`ui-audit-gate`](ui-audit-gate.md) state for their own obligations. The ladder
107
+ is the control; skipping it is caught by nothing.
59
108
 
60
109
  Body migrated to [`guideline:agent-infra/active-remediation-mechanics`](../docs/guidelines/agent-infra/active-remediation-mechanics.md) (per P4 of `road-to-kernel-and-router.md`) — per-tier fix-now/note+ask/follow-up-PR criteria, version-gated modernization, anti-nagging guardrails.
61
110
  Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
@@ -68,3 +117,5 @@ Trigger-set above activates this routing on demand, independent of the disciplin
68
117
  - [`source-discovery-gate`](source-discovery-gate.md) — establishing the verified project version before modernizing.
69
118
  - [`scope-control`](scope-control.md), [`commit-policy`](commit-policy.md) — PR/commit creation stays permission-gated.
70
119
  - [`improve-before-implement`](improve-before-implement.md) — the pre-work challenge (before); this is the during/after remediation.
120
+ - [`verify-before-complete`](verify-before-complete.md) — an undecided issue is unfinished work, not a caveat to report.
121
+ - [`no-cheap-questions`](no-cheap-questions.md) — the floor the batched ask clears before it is asked at all.
@@ -2,7 +2,7 @@
2
2
  type: "auto"
3
3
  tier: "2a"
4
4
  alwaysApply: false
5
- description: "Porting/adapting external code (algorithm, structure, >~10 lines) — close the source, re-derive; conscious borrows need a ledger entry + license check"
5
+ description: "Porting external code, or asserting an externally-sourced claim — close the source, re-derive; borrows need a ledger entry + license check, harvested claims an id or an own-analysis label"
6
6
  triggers:
7
7
  - keyword: "port this"
8
8
  - keyword: "adapt this"
@@ -12,6 +12,8 @@ triggers:
12
12
  - keyword: "borrow"
13
13
  - keyword: "vendored"
14
14
  - keyword: "reference implementation"
15
+ - keyword: "harvest"
16
+ - keyword: "adopt from"
15
17
  routes_to:
16
18
  - "skill:license-compliance-borrow-check"
17
19
  - "skill:license-compliance-credits"
@@ -21,7 +23,7 @@ packs: [engineering-base]
21
23
  roles: [developer, reviewer, tester, po, incident, planner]
22
24
  enforced_by:
23
25
  - "none"
24
- # obligation: line 38
26
+ # obligation: line 40
25
27
  obligation_frequency: "per-edit"
26
28
  ---
27
29
 
@@ -64,6 +66,40 @@ An **unknown** source license is never permissive-by-default. Stop and
64
66
  escalate (numbered options, per
65
67
  [`ask-when-uncertain`](ask-when-uncertain.md)) instead of guessing.
66
68
 
69
+ ## The knowledge layer — cite a harvest id, or label it own analysis
70
+
71
+ The clauses above cover borrowed **code**. The same failure has a prose half:
72
+ a comparative pass concludes "their citation registry is worth adopting", the
73
+ sentence lands in a skill, and six months later nobody can say where it came
74
+ from or whether it was ever true. An unattributed idea is not a licensing
75
+ problem, which is why it needs its own clause rather than a wider reading of
76
+ the one above — it is an **epistemic** one, and it fails silently.
77
+
78
+ ```
79
+ AN ARTEFACT ASSERTING AN EXTERNALLY-SOURCED CLAIM EITHER CITES A HARVEST ID
80
+ OR LABELS THE STATEMENT AS OWN ANALYSIS. SILENCE IS NEITHER.
81
+ ```
82
+
83
+ Fires when a skill, rule, command, guideline, or roadmap states a heuristic, a
84
+ number, or a mechanism taken from a source outside this repo. Two acceptable
85
+ discharges, and the choice is the author's:
86
+
87
+ 1. **Cite** — append `<!-- harvest:<id> -->` and add the row to
88
+ `provenance/harvests.jsonl` (shape: `provenance/README.md`). The row pins
89
+ the source to a revision, or names it opaquely when
90
+ [`source-confidentiality`](source-confidentiality.md) keeps it out of the
91
+ tracked tree.
92
+ 2. **Label** — say in the text that this is own analysis. A stated derivation
93
+ is a complete discharge; the ledger exists for what came from elsewhere.
94
+
95
+ Only `adopt` and `adapt` findings produce a row. A rejected or already-present
96
+ finding has no artefact citing it and belongs in the analysis document.
97
+
98
+ **The prose carve-out below does not reach this section.** "Prose/docs-only
99
+ edits" excuses the *code* clauses, where there is no borrowed code to record;
100
+ prose is precisely where a harvested claim lands, so excluding it here would
101
+ empty the obligation of everything it applies to.
102
+
67
103
  ## Self-interrogation clause (AUXILIARY — never a control)
68
104
 
69
105
  Before finalizing any non-trivial function, ask internally: *"Did I derive
@@ -96,16 +132,42 @@ the source and re-derive" — a pre-write reasoning step only the model
96
132
  observes — so this rule ships `enforced_by: none`, same honesty stance as
97
133
  `security-sensitive-stop` and `untrusted-input-defense`.
98
134
 
135
+ `lint_harvest_provenance.ts` stands in exactly the same relation to the
136
+ knowledge layer, and the sentence is worth repeating rather than assuming
137
+ transferred: it validates the harvest ledger's own rows and citations — schema,
138
+ uniqueness, pinning, dead rows, orphan ids — and **cannot see a claim nobody
139
+ recorded**. A harvested assertion that was never cited and never labelled
140
+ passes every gate in this repo. That is the honest coverage statement, and it
141
+ is why the discipline is the control on both layers.
142
+
99
143
  ## When NOT to fire
100
144
 
101
145
  - A well-known, unpatentable algorithm shape (a hash map, a for-loop) with
102
146
  no specific source in mind.
103
147
  - Reusing your **own** prior code within this repo.
104
- - Prose/docs/config-only edits.
148
+ - Prose/docs/config-only edits — **for the code clauses only**. The knowledge
149
+ layer fires on exactly these surfaces; see its own note above.
150
+ - Common knowledge with no nameable source, on either layer. "Indexes speed up
151
+ lookups" needs no row; a specific number, threshold, or mechanism read
152
+ somewhere does.
153
+ - **A design artifact the user handed over** — a prototype, an exported
154
+ `design.html`, a token sidecar. That is the user's own material, not
155
+ third-party external code, so adapting its markup/CSS/JS is not a borrow and
156
+ needs no ledger entry. Same carve-out
157
+ [`content-quoting-floor`](content-quoting-floor.md) makes for user-owned text.
158
+ **The carve-out is authorship, not delivery:** a vendored component or a
159
+ licensed template that merely *arrives inside* a handover stays under this
160
+ rule in full. Boundary stated from the other side in
161
+ [`design-fidelity-mechanics`](../docs/guidelines/design-fidelity-mechanics.md)
162
+ § Adopt the code.
163
+ **It exempts the code clauses only.** A claim *about* the artifact's origin —
164
+ that a pattern in it came from somewhere nameable — is a knowledge-layer
165
+ statement and takes a harvest id or an own-analysis label like any other.
105
166
 
106
167
  ## See also
107
168
 
108
169
  - [`license-compliance-borrow-check`](../skills/license-compliance-borrow-check/SKILL.md), [`license-compliance-credits`](../skills/license-compliance-credits/SKILL.md), [`license-compliance-audit`](../skills/license-compliance-audit/SKILL.md) — the borrowing / notices / on-demand-scan skill family this rule routes to.
109
- - `provenance/README.md`, `src/scripts/lint_provenance.ts`, `src/scripts/detect_target_license.ts` — the ledger, its linter, and the S1.2 policy derivation.
170
+ - `provenance/README.md`, `src/scripts/lint_provenance.ts`, `src/scripts/detect_target_license.ts` — the code ledger, its linter, and the S1.2 policy derivation.
171
+ - `provenance/harvests.jsonl`, `src/scripts/lint_harvest_provenance.ts` — the knowledge ledger and its linter. Neither is `docs/CLAIMS.md` / `check_claims.ts`, which govern public claims this package makes about **itself**; the shared vocabulary is a grep hazard, so `provenance/README.md` states the three-way split.
110
172
  - [`secret-vcs-guard`](secret-vcs-guard.md) — sibling detect → ask → act discipline for a different leak class.
111
173
  - [`ask-when-uncertain`](ask-when-uncertain.md) — the escalation shape for `conditional`/`unknown` verdicts.
@@ -82,6 +82,12 @@ does not substitute for engaging with the source.
82
82
  treating fetched content as data vs instructions; this rule governs
83
83
  how much of that data may be reproduced verbatim once it IS being
84
84
  used as source material.
85
+ - [`code-provenance`](code-provenance.md) +
86
+ [`design-fidelity-mechanics`](../docs/guidelines/design-fidelity-mechanics.md)
87
+ § Adopt the code — this rule's user-owned-text carve-out extended to
88
+ **markup**: a design artifact the user hands over is their own material, so
89
+ adapting its code is not a borrow. Third-party code arriving inside that
90
+ handover is not covered, on either side.
85
91
  - [`docs/contracts/write-engine.md`](../docs/contracts/write-engine.md) —
86
92
  ghostwriter's disclosure-footer contract; this rule's quote floor
87
93
  applies to any ghostwriter draft that cites an external source.