kushi-agents 6.1.2 → 6.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 (86) hide show
  1. package/package.json +1 -1
  2. package/plugin/instructions/agentskills-compliance.instructions.md +144 -0
  3. package/plugin/instructions/dashboard-artifact.instructions.md +132 -0
  4. package/plugin/instructions/guided-tour.instructions.md +100 -0
  5. package/plugin/instructions/karpathy-state-layout.instructions.md +124 -0
  6. package/plugin/instructions/schema-evolve.instructions.md +73 -0
  7. package/plugin/instructions/skill-authoring.instructions.md +147 -0
  8. package/plugin/instructions/skill-evals.instructions.md +130 -0
  9. package/plugin/runners/bootstrap.mjs +55 -22
  10. package/plugin/runners/lib/runlog.mjs +153 -6
  11. package/plugin/runners/migrate-to-v550.mjs +192 -0
  12. package/plugin/runners/pull-email.mjs +194 -3
  13. package/plugin/runners/pull-meetings.mjs +207 -4
  14. package/plugin/runners/pull-onenote.mjs +239 -3
  15. package/plugin/runners/pull-sharepoint.mjs +284 -3
  16. package/plugin/runners/pull-state.mjs +297 -0
  17. package/plugin/runners/pull-teams.mjs +170 -3
  18. package/plugin/runners/refresh.mjs +9 -1
  19. package/plugin/runners/test/fixtures/email-abn-amro.json +13 -0
  20. package/plugin/runners/test/fixtures/email-novel-error.json +9 -0
  21. package/plugin/runners/test/fixtures/meetings-abn-amro.json +10 -0
  22. package/plugin/runners/test/fixtures/meetings-body-unavailable.json +10 -0
  23. package/plugin/runners/test/fixtures/onenote-abn-amro.json +30 -0
  24. package/plugin/runners/test/fixtures/onenote-partial.json +21 -0
  25. package/plugin/runners/test/fixtures/refresh-dir/email.json +7 -4
  26. package/plugin/runners/test/fixtures/refresh-dir/teams.json +6 -4
  27. package/plugin/runners/test/fixtures/sharepoint-abn-amro.json +12 -0
  28. package/plugin/runners/test/fixtures/teams-abn-amro.json +11 -0
  29. package/plugin/runners/test/integration/migrate-to-v550.integration.test.mjs +138 -0
  30. package/plugin/runners/test/integration/pull-email.integration.test.mjs +149 -0
  31. package/plugin/runners/test/integration/pull-meetings.integration.test.mjs +92 -0
  32. package/plugin/runners/test/integration/pull-onenote.integration.test.mjs +86 -0
  33. package/plugin/runners/test/integration/pull-sharepoint.integration.test.mjs +93 -0
  34. package/plugin/runners/test/integration/pull-teams.integration.test.mjs +91 -0
  35. package/plugin/runners/test/unit/runlog.test.mjs +1 -1
  36. package/plugin/skills/build-state/SKILL.md +195 -0
  37. package/plugin/skills/build-state/evals/evals.json +31 -0
  38. package/plugin/skills/dashboard/SKILL.md +132 -0
  39. package/plugin/skills/dashboard/evals/evals.json +33 -0
  40. package/plugin/skills/lint-state/.created-by-skill-creator +0 -0
  41. package/plugin/skills/lint-state/SKILL.md +98 -0
  42. package/plugin/skills/lint-state/evals/evals.json +34 -0
  43. package/plugin/skills/lint-state/lint.ps1 +218 -0
  44. package/plugin/skills/promote/.created-by-skill-creator +1 -0
  45. package/plugin/skills/promote/SKILL.md +125 -0
  46. package/plugin/skills/promote/evals/evals.json +35 -0
  47. package/plugin/skills/schema-evolve/.created-by-skill-creator +0 -0
  48. package/plugin/skills/schema-evolve/SKILL.md +106 -0
  49. package/plugin/skills/schema-evolve/evals/evals.json +37 -0
  50. package/plugin/skills/skill-checker/SKILL.md +136 -0
  51. package/plugin/skills/skill-checker/check-skill.ps1 +416 -0
  52. package/plugin/skills/skill-checker/evals/evals.json +41 -0
  53. package/plugin/skills/skill-creator/SKILL.md +134 -0
  54. package/plugin/skills/skill-creator/evals/evals.json +40 -0
  55. package/plugin/skills/skill-creator/generate-eval-review.ps1 +101 -0
  56. package/plugin/skills/skill-creator/optimize-description.ps1 +87 -0
  57. package/plugin/skills/skill-creator/scaffold.ps1 +180 -0
  58. package/plugin/skills/skill-creator/templates/evals-starter.template.json +27 -0
  59. package/plugin/skills/skill-creator/templates/gotchas-stub.template.md +9 -0
  60. package/plugin/skills/skill-creator/templates/skill-skeleton.template.md +28 -0
  61. package/plugin/skills/teach/.created-by-skill-creator +0 -0
  62. package/plugin/skills/teach/SKILL.md +79 -0
  63. package/plugin/skills/teach/evals/evals.json +59 -0
  64. package/plugin/skills/tour/SKILL.md +85 -0
  65. package/plugin/skills/tour/build-tour.ps1 +185 -0
  66. package/plugin/skills/tour/evals/evals.json +33 -0
  67. package/plugin/templates/state/00_overview.template.md +44 -0
  68. package/plugin/templates/state/01_decisions.template.md +41 -0
  69. package/plugin/templates/state/02_stakeholders.template.md +48 -0
  70. package/plugin/templates/state/03_architecture-and-solution.template.md +56 -0
  71. package/plugin/templates/state/04_workshops-and-key-meetings.template.md +43 -0
  72. package/plugin/templates/state/05_action-items.template.md +29 -0
  73. package/plugin/templates/state/06_risks-and-issues.template.md +43 -0
  74. package/plugin/templates/state/07_timeline-and-milestones.template.md +45 -0
  75. package/plugin/templates/state/08_artifacts-and-deliverables.template.md +55 -0
  76. package/plugin/templates/state/09_open-questions.template.md +62 -0
  77. package/plugin/templates/state/AGENTS.template.md +33 -0
  78. package/plugin/templates/state/CLAUDE.template.md +33 -0
  79. package/plugin/templates/state/README.md +41 -0
  80. package/plugin/templates/state/answers.README.md +7 -0
  81. package/plugin/templates/state/hot.template.md +12 -0
  82. package/plugin/templates/state/index.template.md +41 -0
  83. package/plugin/templates/state/log.template.md +14 -0
  84. package/plugin/templates/state/page.template.md +22 -0
  85. package/plugin/templates/state/review-queue.template.md +10 -0
  86. package/plugin/runners/test/integration/csc-pull.integration.test.mjs +0 -160
@@ -0,0 +1,195 @@
1
+ ---
2
+ name: "build-state"
3
+ version: "5.0.0"
4
+ description: "USE WHEN the user says \"regenerate State for <X>\", \"rebuild State\", or \"@Kushi state <X>\" AND the project already has Evidence/ populated. DO NOT USE to pull new evidence (use refresh-project or pull-*). Capability: pure re-render — reads Evidence/_index/entities.yml + weekly CSC + legacy fallback, writes <project>/State/ in BOTH legacy 00–09 synthesis (full profile) AND Karpathy layout (index.md + log.md + per-entity pages + CLAUDE.md/AGENTS.md). Plan-validate-execute writer."
5
+ ---
6
+
7
+ # Skill: build-state
8
+
9
+ ## v4.9.0 — Reader fallback chain (HARD RULE; per `weekly-csc.instructions.md`)
10
+
11
+ For every `<alias>/<source>/` accessed:
12
+
13
+ 1. **Primary**: read `Evidence/<alias>/<source>/_index/entities.yml`. For each entity needed, pull `latest_csc_file` + `latest_csc_block_offset`; open the weekly file and read the CSC block by entity anchor.
14
+ 2. **Secondary (no _index/, but weekly/ exists)**: walk `Evidence/<alias>/<source>/weekly/*.md` newest-first; parse `## <name> {#<anchor>}` headings; build an in-memory entity index for this query.
15
+ 3. **Legacy fallback (pre-v4.9.0)**: if `weekly/` is empty BUT `snapshot/` or `stream/` exist, read those. Cite as legacy.
16
+
17
+ Citation form in this skill's output:
18
+ - **New (v4.9.0)**: `[source: <alias>/<source>/weekly/<YYYY-MM-DD>_<source>-csc.md#<entity-anchor> · <iso-ts>]`
19
+ - **Legacy (reading from snapshot/+stream/)**: append ` (legacy pre-v4.9.0 layout)` after the citation.
20
+
21
+ Mark the answer / output footer with `Source-layout: weekly-csc | weekly-csc-plus-legacy | legacy-only` so the user knows whether a refresh would update the layout.
22
+
23
+ Readers MUST NOT delete or modify legacy folders. Migration is out of scope for v4.9.0.
24
+
25
+ Run this when the user says: "regenerate state for `<X>`", "rebuild State", "@Kushi state `<X>`". This skill makes NO source calls — it only reads Evidence and writes State.
26
+
27
+ ## Inputs
28
+
29
+ - `<project>` — already-bootstrapped project.
30
+
31
+ ## Plan / Validate / Execute
32
+
33
+ Per `plan-validate-execute.instructions.md`:
34
+
35
+ 1. **Plan** — before Step 2 (regenerate State files), serialize the proposed
36
+ state shape to `<project>/Evidence/_plan/build-state-plan.json`:
37
+ - `inputs[]` — every `_index/entities.yml` row, `weekly/*.md` file, and
38
+ legacy `snapshot/`/`stream/` fallback file the run intends to read.
39
+ Each entry: `{ source, alias, path, last_modified, included_in: [<state_file>, ...] }`.
40
+ - `proposed_state_files[]` — `{ id: "00..08", title, sections: [...],
41
+ citation_count, evidence_window: [from_iso, to_iso] }`.
42
+ - `proposed_open_questions[]` — `{ text, source_refs[] }` (the OQ list
43
+ Step 5 plans to write).
44
+ - `proposed_karpathy_emit[]` — the v5 Karpathy block paths planned for Step 6.
45
+ 2. **Validate** — for every `evidence_ref` in the plan, re-confirm the source
46
+ file exists and its `last_modified` matches the plan. Drop any reference
47
+ whose anchor no longer resolves (the underlying weekly file may have been
48
+ re-written between plan and execute). If validate drops > 20% of references
49
+ in any single State file, abort that file's write and surface the plan for
50
+ review.
51
+ 3. **Execute** — write `State/00..08_*.md` and the Karpathy outputs. Stamp each
52
+ State file's banner with the plan ID + validate-pass timestamp.
53
+
54
+ The `_plan/` file is overwritten on every run and is safe to delete between
55
+ runs — transient working artifact, not authoritative truth.
56
+
57
+ ## Steps
58
+
59
+
60
+ ## v5.1.0 — Incremental mode (HARD RULE; per `living-wiki.instructions.md`)
61
+
62
+ Build-state is now incremental by default:
63
+
64
+ 1. **Read existing State/ pages.** Before regenerating, load every existing `State/**/*.md`.
65
+ 2. **Preserve human edits.** Content OUTSIDE `<!-- kushi:auto:start -->` / `<!-- kushi:auto:end -->` fences is NEVER modified.
66
+ 3. **Re-derive fenced regions only.** For each `<!-- kushi:auto:start section="<id>" -->` block, re-derive content from current evidence and replace the block contents.
67
+ 4. **Contradiction detection.** When a re-derived fact contradicts an existing fact (different value for same entity property):
68
+ - Wrap both in `> [!warning] Contradicted` / `> [!info] New value` callouts per `living-wiki.instructions.md`.
69
+ - Add entity to `_review-queue.md`.
70
+ 5. **Auto-resolve.** Apply the auto-resolve threshold from `living-wiki.instructions.md` (≥3 sources + ≥30 days old + no human override).
71
+ 6. **Log + index.** Append `build-state` entry to `State/log.md` via `Append-StateLog.ps1`. Update `State/index.md` via `Update-StateIndex.ps1`.
72
+
73
+ When creating NEW pages (entity not previously in State/), wrap all auto-derived content in `<!-- kushi:auto -->` fences.
74
+
75
+
76
+ ## Step checklist
77
+
78
+ Progress-trackable view of the steps below. Each `### Step` block expands the corresponding checkbox.
79
+
80
+ - [ ] Step 1 — Read all Evidence
81
+ - [ ] Step 2 — For each State file (00–08), regenerate
82
+ - [ ] Step 3 — Conflict resolution
83
+ - [ ] Step 4 — Citation density
84
+ - [ ] Step 5 — Open Questions (mandatory every run)
85
+ - [ ] Step 6 — v5 Karpathy emission (ADDITIVE; per `karpathy-state-layout.instructions.md`)
86
+ - [ ] Step 7 — Banner
87
+
88
+ ### Step 1 — Read all Evidence
89
+
90
+ For the resolved `<project>`, apply the v4.9.0 fallback chain for each `<alias>/<source>/`:
91
+ - **Primary**: read `Evidence/<alias>/<source>/_index/entities.yml`; load entities via `latest_csc_file` + offset.
92
+ - **Secondary**: if no `_index/`, walk `Evidence/<alias>/<source>/weekly/*.md` newest-first.
93
+ - **Legacy fallback**: if `weekly/` is empty, read `Evidence/<alias>/<source>/snapshot/**/*.md` (current truth per entity) and `Evidence/<alias>/<source>/stream/**/*.md` (chronological events). Cite as `(legacy pre-v4.9.0 layout)`.
94
+ - Walk `Evidence/_Consolidated/**/*.md` (multi-user merged where present).
95
+
96
+ ### Step 2 — For each State file (00–08), regenerate
97
+
98
+ | State file | Pulls primarily from |
99
+ |---|---|
100
+ | 00_overview.md | snapshot/CRM/<id>.md, snapshot/sharepoint/files/*overview*.md, snapshot/onenote/pages/*overview*.md |
101
+ | 01_decisions.md | stream/meetings/* (decision lines), stream/teams/* (decision lines), stream/email/* (decision lines), snapshot/ado/items/* (state changes) |
102
+ | 02_stakeholders.md | snapshot/teams/chat-roster.md, snapshot/crm/<id>.md (engagement contacts), stream/email/* (sender/recipient analysis) |
103
+ | 03_architecture-and-solution.md | snapshot/onenote/pages/*architecture*.md, snapshot/sharepoint/files/*arch*.md, stream/meetings/* (arch discussions) |
104
+ | 04_workshops-and-key-meetings.md | snapshot/meetings/series-index.md, stream/meetings/* (per-meeting blocks) |
105
+ | 05_action-items.md | stream/meetings/* (action lines), stream/teams/* (action lines), snapshot/ado/items/* |
106
+ | 06_risks-and-issues.md | stream/meetings/* (risk lines), stream/email/* (escalations), snapshot/ado/items/* (risk-tagged) |
107
+ | 07_timeline-and-milestones.md | snapshot/crm/<id>.md (milestones), snapshot/ado/items/* (iterations), stream/meetings/* (date commits) |
108
+ | 08_artifacts-and-deliverables.md | snapshot/sharepoint/tree.md + files/*, snapshot/onenote/pages/* |
109
+
110
+ ### Step 3 — Conflict resolution
111
+
112
+ - Latest fact wins on conflicts (compare `as of YYYY-MM-DD` snapshots and stream event timestamps).
113
+ - Preserve superseded values via `Supersedes:` line under the new entry.
114
+ - Each State file ends with a `## Conflicts` section listing every superseded value with both citations.
115
+
116
+ ### Step 4 — Citation density
117
+
118
+ Per `citation-ledger.instructions.md`: every assertion in every State file MUST have an inline citation. Snapshot citations use `as of YYYY-MM-DD`; stream citations use `· YYYY-MM-DD`. Where a fact is BOTH "currently true" AND "decided on date X", cite both.
119
+
120
+ ### Step 5 — Open Questions (mandatory every run)
121
+
122
+ Update `<project>/State/09_open-questions.md`:
123
+ - Scan new evidence for items that are conflicting, second-hand, low-fidelity, or that prompt a follow-up question → add as new `Q-NNN` rows under 🔴 Open / 🟡 Partial. Set Fidelity (Low/Medium/High), Category, Source, Asked Of, Needed By.
124
+ - For every existing 🔴/🟡 row, check if new evidence answers it. If yes: flip to 🟢 Resolved, fill Answer + Source of Answer + Resolved On, fold the answer into the appropriate State file (00–08), record path in **Folded Into**. Never delete rows.
125
+ - If a question is no longer relevant (scope cut, decision overtaken), flip to ⚫ Stale with reason.
126
+ - Bump the file's `As of:` line. Briefly mention in run-log how many opened / partial / resolved / staled.
127
+
128
+ ### Step 6 — v5 Karpathy emission (ADDITIVE; per `karpathy-state-layout.instructions.md`)
129
+
130
+ After Steps 1–5 produce the legacy 00–09 files, ALSO emit the v5 layout:
131
+
132
+ 1. Ensure category folders exist under `<project>/State/`:
133
+ `people/`, `opportunities/`, `adoworkitems/`, `decisions/`, `risks/`,
134
+ `customerasks/`, `meetings/`, `artifacts/`.
135
+ 2. For each entity surfaced via the reader-fallback chain, write one
136
+ markdown file using `..\..\templates\state\page.template.md`. Filename
137
+ slug = lowercase ascii of the entity title (alphanumeric + hyphen, ≤80
138
+ chars), with `.md` suffix. Place it in the matching category folder.
139
+ The front-matter MUST include `kushi_state_page: true`, the canonical
140
+ `entity_ids: [...]` (graph node ids), and a `related: [...]` array of
141
+ other state-page paths (relative, slash-separated) discovered via graph
142
+ edges (`decides`, `discusses`, `action-item-tracks`, `references`,
143
+ `produced-by`, `follow-up-of`, `same-thread`, `participant-of`).
144
+ 3. Regenerate `<project>/State/index.md` from
145
+ `..\..\templates\state\index.template.md` by enumerating every file
146
+ under `State/**/*.md` whose front-matter has `kushi_state_page: true`,
147
+ grouped by category, sorted by filename. The index MUST be fully
148
+ overwritten each run.
149
+ 4. Append a new dated entry to `<project>/State/log.md`
150
+ (from `..\..\templates\state\log.template.md`):
151
+ `## YYYY-MM-DD HH:mm UTC — build-state run by <alias>` plus a short
152
+ summary (`pages_written: N`, `categories_touched: …`,
153
+ `legacy_files_rewritten: 00..09`).
154
+ 5. Ensure `<project>/State/CLAUDE.md` and `<project>/State/AGENTS.md` exist
155
+ and are byte-identical copies of
156
+ `..\..\templates\state\CLAUDE.template.md` (per the doctrine — Windows
157
+ does not honor symlinks reliably, so we copy).
158
+ 6. `[[wikilink]]` rendering: page bodies SHOULD use the
159
+ `[[category/slug]]` form for cross-references; the build does not need
160
+ to resolve these — they are render-time hints for human + agent
161
+ readers.
162
+
163
+ v5 emission is gated on `m365Mutable.state.layout: "karpathy"` (default
164
+ true). If set to `"legacy"`, skip Step 6.
165
+
166
+ ### Step 7 — Banner
167
+
168
+ Top of every State file:
169
+
170
+ ```markdown
171
+ > _As of: YYYY-MM-DD HH:mm. Regenerated by @Kushi build-state. Source: Evidence/ weekly CSC + legacy snapshots + streams._
172
+ ```
173
+
174
+ `Source-layout: weekly-csc | weekly-csc-plus-legacy | legacy-only` (append to banner to reflect which layout was actually read).
175
+
176
+ ## Triggers
177
+
178
+ - "regenerate state for `<X>`"
179
+ - "rebuild state"
180
+ - "@Kushi state `<X>`"
181
+ - "re-render State after I fixed `<file>`"
182
+
183
+ ## Changelog
184
+
185
+ - **v4.0.0 (kushi v5.0.0, 2026-05-26)**: ADDITIVE Karpathy-style emission — per-entity pages under `State/<category>/`, `State/index.md`, `State/log.md`, `State/CLAUDE.md`, `State/AGENTS.md`. Distinguished by `kushi_state_page: true`. Legacy 00–09 synthesis is retained for `full` profile parity. Gated on `m365Mutable.state.layout` (default `karpathy`). See `..\..\instructions\karpathy-state-layout.instructions.md`.
186
+ - **v3.0.0 (kushi v4.9.0, 2026-05-26)**: 3-step reader fallback chain (`_index/entities.yml` → `weekly/*.md` → legacy `snapshot/` + `stream/`). New citation form `weekly/<YYYY-MM-DD>_<source>-csc.md#<anchor>`. Legacy citations suffixed `(legacy pre-v4.9.0 layout)`. Output marked with `Source-layout:` footer.
187
+
188
+ ## Validation loop
189
+
190
+ After writing outputs:
191
+
192
+ 1. Run self-check targeted at this skill: `pwsh plugin/skills/self-check/run.ps1 -Targeted state`
193
+ 2. If failures: fix and re-run the affected step (not the whole skill).
194
+ 3. Repeat until self-check exits 0.
195
+ 4. Only then update `run-log.yml` with success status.
@@ -0,0 +1,31 @@
1
+ {
2
+ "skill": "build-state",
3
+ "version": "1.0.0",
4
+ "description": "Karpathy State layout — index.md + log.md + per-category folders.",
5
+ "cases": [
6
+ {
7
+ "id": "bs-state-index",
8
+ "name": "fixture State/index.md has kushi_state_page front-matter",
9
+ "input": "validate state fixture",
10
+ "fixture": "evals/fixtures/fixture-acme",
11
+ "canary": true,
12
+ "grader_type": "script",
13
+ "args": { "read_fixture": "State/index.md" },
14
+ "expected_assertions": [
15
+ { "type": "regex-match", "pattern": "kushi_state_page:\\s*true" }
16
+ ]
17
+ },
18
+ {
19
+ "id": "bs-state-log-exists",
20
+ "name": "fixture State/log.md exists",
21
+ "input": "verify log",
22
+ "fixture": "evals/fixtures/fixture-acme",
23
+ "canary": false,
24
+ "grader_type": "script",
25
+ "expected_assertions": [
26
+ { "type": "file-exists", "path": "State/log.md" },
27
+ { "type": "file-exists", "path": "State/index.md" }
28
+ ]
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: "dashboard"
3
+ version: "1.0.0"
4
+ description: "USE WHEN the user says \"@Kushi dashboard <X>\" OR after refresh-project/bootstrap-project completes AND <project>/Evidence/_graph/project-graph.json exists. DO NOT USE before link-entities has produced a graph (no-op without it). Capability: renders single self-contained <project>/dashboard.html via Cytoscape.js v3 + cose-bilkent, Clawpilot theme variables, two-view tabs (Graph + Timeline), source/alias/date filters, fuzzy search, side panel with cited CSC blocks."
5
+ ---
6
+
7
+ # Skill: dashboard
8
+
9
+ > **v5.0.0 — Single-file HTML dashboard producer.** See
10
+ > `..\..\instructions\dashboard-artifact.instructions.md` for the full
11
+ > contract: inputs, outputs, theming, views, filters, search, side panel.
12
+ >
13
+ > **Theming uses the Clawpilot `web-artifacts-builder` skill.** All CSS
14
+ > variables (`--bg`, `--fg`, `--accent`, `--surface`, `--border`, …) come from
15
+ > that skill's theme contract so the dashboard adopts the user's Clawpilot
16
+ > palette when opened inside Clawpilot, and falls back to a default
17
+ > light/dark scheme in a vanilla browser.
18
+
19
+ ## When to run
20
+
21
+ - Automatically as part of `refresh-project` (after `link-entities` +
22
+ `build-state`) and `bootstrap-project` (same chain).
23
+ - Manually: `@Kushi dashboard <project>`.
24
+
25
+ ## Inputs
26
+
27
+ - `<project>` — already-bootstrapped project root.
28
+ - `<project>/Evidence/_graph/project-graph.json` — REQUIRED. Missing graph →
29
+ skill is a no-op (dashboard is not produced).
30
+ - `<project>/Evidence/<alias>/<source>/_index/entities.yml` — OPTIONAL per
31
+ contributor / source.
32
+ - `<project>/State/index.md` — OPTIONAL. Used to populate the side panel's
33
+ "State pages" list.
34
+
35
+ ## Output
36
+
37
+ - `<project>/dashboard.html` — single self-contained HTML file.
38
+
39
+ ## Steps
40
+
41
+
42
+ ## Step checklist
43
+
44
+ Progress-trackable view of the steps below. Each `### Step` block expands the corresponding checkbox.
45
+
46
+ - [ ] Step 1 — Verify inputs
47
+ - [ ] Step 2 — Collect data
48
+ - [ ] Step 3 — Render
49
+ - [ ] Step 4 — Verify
50
+
51
+ ### Step 1 — Verify inputs
52
+
53
+ If `<project>/Evidence/_graph/project-graph.json` does not exist, exit
54
+ cleanly with a one-line message ("no graph — run `link-entities` first").
55
+ Do NOT produce a dashboard.
56
+
57
+ ### Step 2 — Collect data
58
+
59
+ 1. Read the graph JSON.
60
+ 2. Walk all `Evidence/<alias>/<source>/_index/entities.yml` files and merge
61
+ their entries into a single index map keyed by entity id (used by the
62
+ side panel to surface `latest_csc_file` quickly).
63
+ 3. Read `State/index.md` if present; parse the v5 state pages it lists.
64
+
65
+ ### Step 3 — Render
66
+
67
+ Invoke the embedder:
68
+
69
+ ```pwsh
70
+ pwsh plugin/templates/dashboard/embedder.ps1 `
71
+ -TemplatePath plugin/templates/dashboard/dashboard.template.html `
72
+ -OutPath <project>/dashboard.html `
73
+ -GraphJsonPath <project>/Evidence/_graph/project-graph.json `
74
+ -IndexJsonPath <intermediate> `
75
+ -StateJsonPath <intermediate>
76
+ ```
77
+
78
+ The embedder substitutes the `__GRAPH_JSON__`, `__INDEX_JSON__`, and
79
+ `__STATE_JSON__` placeholders in the template with the stringified JSON of
80
+ the collected data, and writes the result to `<project>/dashboard.html`.
81
+
82
+ ### Step 4 — Verify
83
+
84
+ Confirm `<project>/dashboard.html` exists and is non-empty. Open the file
85
+ in a browser (manual verification step — not automated here) to confirm:
86
+ the graph view renders, the side panel opens on node click, filters work.
87
+
88
+ ## Hard rules
89
+
90
+ - The output is a **single self-contained HTML file**. No external CDN
91
+ fetches at view time.
92
+ - Theming uses the Clawpilot `web-artifacts-builder` skill's CSS variables.
93
+ - Idempotent — the file is fully regenerated on every run.
94
+ - NEVER write outside `<project>/dashboard.html`.
95
+
96
+ ## Triggers
97
+
98
+ - "dashboard `<X>`"
99
+ - "build dashboard for `<X>`"
100
+ - "@Kushi dashboard `<X>`"
101
+ - (auto) end of `refresh-project` / `bootstrap-project`
102
+
103
+ ## References
104
+
105
+ - `..\..\instructions\dashboard-artifact.instructions.md`
106
+ - `..\..\instructions\entity-graph.instructions.md`
107
+ - `..\..\instructions\karpathy-state-layout.instructions.md`
108
+ - `..\..\instructions\issue-recovery.instructions.md`
109
+ - Clawpilot user skill: `web-artifacts-builder` (theme variables, single-HTML
110
+ packaging contract).
111
+
112
+ ## Issue Recovery
113
+
114
+ When this skill exposes a reusable defect (template placeholder mismatch,
115
+ data shape drift, theming regression), apply the [Issue Recovery Rule](../../instructions/issue-recovery.instructions.md):
116
+ fix the template or embedder first, re-render, verify in browser, then
117
+ re-run self-check D22.dashboard.
118
+
119
+ ## Changelog
120
+
121
+ - **v1.0.0 (kushi v5.0.0, 2026-05-26)**: initial release. Cytoscape.js v3 +
122
+ cose-bilkent + Clawpilot theme variables; two-view tabs; side panel;
123
+ filters; fuzzy search.
124
+
125
+ ## Validation loop
126
+
127
+ After writing outputs:
128
+
129
+ 1. Run self-check targeted at this skill: `pwsh plugin/skills/self-check/run.ps1 -Targeted dashboard`
130
+ 2. If failures: fix and re-run the affected step (not the whole skill).
131
+ 3. Repeat until self-check exits 0.
132
+ 4. Only then update `run-log.yml` with success status.
@@ -0,0 +1,33 @@
1
+ {
2
+ "skill": "dashboard",
3
+ "version": "1.0.0",
4
+ "description": "Auto-seeded evals for dashboard. Replace with real cases as the skill matures.",
5
+ "cases": [
6
+ {
7
+ "id": "dashboard-smoke-1",
8
+ "name": "dashboard produces a non-empty response",
9
+ "input": "synthetic dashboard probe — canary smoke",
10
+ "canary": false,
11
+ "grader_type": "script",
12
+ "expected_assertions": [
13
+ {
14
+ "type": "regex-match",
15
+ "pattern": ".+"
16
+ }
17
+ ]
18
+ },
19
+ {
20
+ "id": "dashboard-smoke-2",
21
+ "name": "dashboard echoes case id",
22
+ "input": "case-id dashboard-smoke-2",
23
+ "canary": false,
24
+ "grader_type": "script",
25
+ "expected_assertions": [
26
+ {
27
+ "type": "regex-match",
28
+ "pattern": "dashboard-smoke-2"
29
+ }
30
+ ]
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: "lint-state"
3
+ version: "1.0.0"
4
+ description: "USE WHEN the user says 'lint state', 'check state health', 'wiki lint', 'kushi lint <project>', or 'find stale/orphan/contradictions in State'. DO NOT USE for evidence-level validation (use self-check) or for rebuilding State (use build-state). Capability: runs wiki-lint finding classes against Evidence/<alias>/State/, writes dated lint report, updates log.md + index.md."
5
+ ---
6
+
7
+ # Skill: lint-state
8
+
9
+ Run wiki-lint checks against a project's `State/` directory per `wiki-lint.instructions.md`. Reports contradictions, stale claims, orphan pages, missing cross-refs, and data gaps — each with a ready-to-paste fix snippet.
10
+
11
+ ## Triggers
12
+
13
+ - "lint state for `<project>`"
14
+ - "check state health"
15
+ - "wiki lint `<project>`"
16
+ - `kushi lint <project>` (CLI verb)
17
+ - "find contradictions in State"
18
+ - "any stale claims in `<project>`?"
19
+
20
+ ## Inputs
21
+
22
+ - `<project>` — engagement name (fuzzy-matched per `engagement-root-resolution.instructions.md`).
23
+
24
+ ## Step checklist
25
+
26
+ - [ ] Step 1 — Resolve project root + State/ path
27
+ - [ ] Step 2 — Run finding-class checks
28
+ - [ ] Step 3 — Generate lint report
29
+ - [ ] Step 4 — Update log.md + index.md
30
+ - [ ] Step 5 — Print summary
31
+
32
+ ### Step 1 — Resolve project root
33
+
34
+ Resolve `<engagement-root>/<project>/Evidence/<alias>/State/` using standard engagement-root resolution. Verify `State/` exists; if not, advise running `build-state` first.
35
+
36
+ ### Step 2 — Run finding-class checks
37
+
38
+ Per `wiki-lint.instructions.md`, execute each finding class:
39
+
40
+ 1. **contradiction-flagged**: scan `State/**/*.md` for `> [!warning] Contradicted` callouts.
41
+ 2. **stale-claim**: parse citations, flag entities with newest citation > 60 days old.
42
+ 3. **orphan-page**: find pages with `kushi_state_page: true` not linked from index.md or siblings.
43
+ 4. **missing-cross-ref**: cross-reference entity mentions against frontmatter `entity_ids`/`related`.
44
+ 5. **data-gap**: find section headers with empty/placeholder bodies.
45
+
46
+ ### Step 3 — Generate lint report
47
+
48
+ Write `Evidence/<alias>/State/reports/lint-YYYY-MM-DD.md`:
49
+
50
+ ```markdown
51
+ ---
52
+ generated_at: "YYYY-MM-DDTHH:MM:SSZ"
53
+ generated_by: "lint-state v1.0.0"
54
+ findings_count: N
55
+ ---
56
+
57
+ # Lint Report — YYYY-MM-DD
58
+
59
+ ## Summary
60
+
61
+ | Class | Count | Severity |
62
+ |---|---|---|
63
+ | contradiction-flagged | N | warning |
64
+ | stale-claim | N | warning |
65
+ | orphan-page | N | warning |
66
+ | missing-cross-ref | N | info |
67
+ | data-gap | N | info |
68
+
69
+ **Total findings: N**
70
+
71
+ ## Findings
72
+
73
+ ### contradiction-flagged: <entity> — <description>
74
+ ...per wiki-lint.instructions.md format...
75
+ ```
76
+
77
+ ### Step 4 — Update log.md + index.md
78
+
79
+ Call shared helpers:
80
+ - `Append-StateLog.ps1 -Op lint-state -Title "Lint pass (<N> findings)"`
81
+ - `Update-StateIndex.ps1 -Op lint-state`
82
+
83
+ ### Step 5 — Print summary
84
+
85
+ One-line console output: `lint-state: <N> findings (<breakdown by class>). Report: State/reports/lint-YYYY-MM-DD.md`
86
+
87
+ ## Validation loop
88
+
89
+ After writing outputs:
90
+ 1. Verify `State/reports/lint-YYYY-MM-DD.md` exists and has valid frontmatter.
91
+ 2. Verify `State/log.md` has the new entry at top.
92
+ 3. Verify `State/index.md` "Last touched" pointer is updated.
93
+
94
+ ## References
95
+
96
+ - `../../instructions/wiki-lint.instructions.md`
97
+ - `../../instructions/log-format.instructions.md`
98
+ - `../../instructions/living-wiki.instructions.md`
@@ -0,0 +1,34 @@
1
+ {
2
+ "skill": "lint-state",
3
+ "version": "1.0.0",
4
+ "description": "Wiki-lint checks against State/ — contradictions, stale claims, orphans, cross-refs, data gaps.",
5
+ "cases": [
6
+ {
7
+ "id": "lint-state-clean",
8
+ "name": "Lint a clean State/ with no findings",
9
+ "input": "Run lint against a well-maintained State/ directory with no contradictions, stale claims, or orphans.",
10
+ "expected_assertions": [
11
+ { "type": "regex-match", "target": "stdout", "pattern": "lint-state: 0 findings" }
12
+ ],
13
+ "grader_type": "script"
14
+ },
15
+ {
16
+ "id": "lint-state-contradiction",
17
+ "name": "Lint detects contradiction callouts",
18
+ "input": "Run lint against a State/ directory with one unresolved > [!warning] Contradicted callout.",
19
+ "expected_assertions": [
20
+ { "type": "regex-match", "target": "stdout", "pattern": "contradiction-flagged=1" }
21
+ ],
22
+ "grader_type": "script"
23
+ },
24
+ {
25
+ "id": "lint-state-orphan",
26
+ "name": "Lint detects orphan pages",
27
+ "input": "Run lint against a State/ directory with a page that has kushi_state_page: true but is not linked from index.md.",
28
+ "expected_assertions": [
29
+ { "type": "regex-match", "target": "stdout", "pattern": "orphan-page=1" }
30
+ ],
31
+ "grader_type": "script"
32
+ }
33
+ ]
34
+ }