kushi-agents 5.4.2 → 5.4.4

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 (37) hide show
  1. package/README.md +9 -0
  2. package/package.json +2 -2
  3. package/plugin/agents/kushi.agent.md +1 -0
  4. package/plugin/instructions/bootstrap-status-format.instructions.md +14 -13
  5. package/plugin/instructions/multi-user-shared-files.instructions.md +117 -87
  6. package/plugin/plugin.json +32 -9
  7. package/plugin/prompts/bootstrap.prompt.md +2 -1
  8. package/plugin/prompts/consolidate.prompt.md +4 -1
  9. package/plugin/prompts/create-skill.prompt.md +26 -0
  10. package/plugin/prompts/doctor.prompt.md +31 -0
  11. package/plugin/prompts/explain.prompt.md +22 -0
  12. package/plugin/prompts/global.prompt.md +28 -0
  13. package/plugin/prompts/lint.prompt.md +28 -0
  14. package/plugin/prompts/migrate-files.prompt.md +29 -0
  15. package/plugin/prompts/promote.prompt.md +26 -0
  16. package/plugin/prompts/schema-evolve.prompt.md +27 -0
  17. package/plugin/prompts/teach.prompt.md +25 -0
  18. package/plugin/skills/aggregate-project/SKILL.md +3 -3
  19. package/plugin/skills/bootstrap-project/SKILL.md +6 -6
  20. package/plugin/skills/consolidate-evidence/SKILL.md +94 -1
  21. package/plugin/skills/migrate-per-user-files/SKILL.md +47 -0
  22. package/plugin/skills/migrate-per-user-files/evals/evals.json +41 -0
  23. package/plugin/skills/migrate-per-user-files/migrate.ps1 +136 -0
  24. package/plugin/skills/migrate-per-user-files/references/migration-strategy.md +23 -0
  25. package/plugin/skills/pull-ado/SKILL.md +1 -1
  26. package/plugin/skills/pull-crm/SKILL.md +1 -1
  27. package/plugin/skills/pull-email/SKILL.md +1 -1
  28. package/plugin/skills/pull-loop/SKILL.md +1 -1
  29. package/plugin/skills/pull-meetings/SKILL.md +1 -1
  30. package/plugin/skills/pull-misc/SKILL.md +3 -3
  31. package/plugin/skills/pull-onenote/SKILL.md +1 -1
  32. package/plugin/skills/pull-sharepoint/SKILL.md +1 -1
  33. package/plugin/skills/pull-teams/SKILL.md +1 -1
  34. package/plugin/skills/refresh-project/SKILL.md +5 -5
  35. package/plugin/skills/self-check/SKILL.md +1 -0
  36. package/plugin/skills/self-check/run.ps1 +34 -0
  37. package/src/per-user-files.test.mjs +137 -0
package/README.md CHANGED
@@ -218,6 +218,15 @@ The Evidence/ folder produced by every profile is a **stable public contract**
218
218
  | `apply-ado` | **preview** | n/a | Gated apply skill. v0.1.0-preview is dry-mode only (writes `planned.jsonl`); real ADO PATCH/POST lands in v0.1.x. |
219
219
  | `vertex-link` | **preview** | n/a | One-time link of a kushi project to a vertex repo `<customer>/<initiative>` (multi-binding supported). Populates `kushi.yaml#vertex`. Re-run with `--reconfigure` to change. |
220
220
  | `emit-vertex` | **preview** | n/a | Render vertex-shaped artifacts from kushi Evidence/+State/ — weekly status, decisions, workshops, comms, living-doc diff proposals. Stages first, validates against vertex's own schemas, applies on demand. |
221
+ | `doctor` | core+ | n/a | v5.4.0 — Aggregated health check (env, self-check, evals, skill-checker, live-install drift, global wiki). `--json` for CI; `--strict` to fail on yellow. |
222
+ | `lint` | standard+ | n/a | v5.1.0 — Run wiki-lint checks against `State/` (contradictions, stale claims, orphans, missing cross-refs, data gaps). Writes `State/reports/lint-YYYY-MM-DD.md`. |
223
+ | `teach` | standard+ | n/a | v5.2.0 — Persist a reusable fact/preference/pattern under `.kushi/learnings/`. |
224
+ | `explain` | standard+ | n/a | v5.2.0 — Retrieve a previously taught fact/preference/pattern from `.kushi/learnings/`. |
225
+ | `promote` | standard+ | n/a | v5.3.0 — Copy a project State page into the global wiki at `~/.kushi-global/` with identifier redaction + back-link + dual log. Refuses without `--force` when identifiers detected. |
226
+ | `migrate-files` | standard+ | n/a | v5.4.4 — One-time migration of root-level `bootstrap-status.md` / `FOLLOW-UPS.md` / `OPEN-QUESTIONS-DRAFT.md` to per-user `Evidence/<alias>/`. Dry-run by default; `--apply` to commit. Refuses to overwrite on content conflict. |
227
+ | `global` (init/status/ask/lint) | standard+ | n/a | v5.3.0 — Manage the per-user cross-engagement wiki at `~/.kushi-global/State/`. |
228
+ | `schema-evolve` | standard+ | n/a | v5.2.0 — Migrate `kushi.yaml` and Evidence/ layouts across schema versions; idempotent + dry-run by default. |
229
+ | `create-skill` / `check-skill` | full | n/a | v5.0.4 — Skill-authoring harness (scaffold a new skill; lint/retrofit every SKILL.md against `skill-authoring.instructions.md`). |
221
230
 
222
231
  See [Quickstart](https://gim-home.github.io/kushi/getting-started/quickstart/) for the full workflow.
223
232
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kushi-agents",
3
- "version": "5.4.2",
3
+ "version": "5.4.4",
4
4
  "description": "Install Kushi — multi-source project evidence agent with Comprehensive Structured Capture (CSC) into weekly-only files across Email, Teams, OneNote, Loop, SharePoint, Meetings, CRM, ADO. Meetings retain a sibling verbatim/ audit folder. WorkIQ-only for M365 sources (Graph / m365_* FORBIDDEN as fallbacks; user-paste is first-class). Host-agnostic.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "license": "MIT",
43
43
  "scripts": {
44
- "test": "node --test src/check-workiq.test.mjs src/seed-config.test.mjs src/sanitize-workiq-input.test.mjs src/detect-vertex-repo.test.mjs src/vertex-validate.test.mjs src/emit-vertex.e2e.test.mjs src/config-root-resolve.test.mjs src/forbidden-workiq-phrasings.test.mjs src/multi-host-install.test.mjs src/eval-aggregator.test.mjs src/eval-runner.test.mjs src/skill-creator.test.mjs src/skill-checker.test.mjs src/hooks-dispatcher.test.mjs src/parallel-refresh.test.mjs src/otel-emit.test.mjs src/teach.test.mjs src/schema-evolve.test.mjs src/global-wiki.test.mjs src/promote.test.mjs src/doctor.test.mjs src/setup-wizard.test.mjs src/cli-no-args.test.mjs src/cli-no-args-tty.test.mjs",
44
+ "test": "node --test src/check-workiq.test.mjs src/seed-config.test.mjs src/sanitize-workiq-input.test.mjs src/detect-vertex-repo.test.mjs src/vertex-validate.test.mjs src/emit-vertex.e2e.test.mjs src/config-root-resolve.test.mjs src/forbidden-workiq-phrasings.test.mjs src/multi-host-install.test.mjs src/eval-aggregator.test.mjs src/eval-runner.test.mjs src/skill-creator.test.mjs src/skill-checker.test.mjs src/hooks-dispatcher.test.mjs src/parallel-refresh.test.mjs src/otel-emit.test.mjs src/teach.test.mjs src/schema-evolve.test.mjs src/global-wiki.test.mjs src/promote.test.mjs src/doctor.test.mjs src/setup-wizard.test.mjs src/cli-no-args.test.mjs src/cli-no-args-tty.test.mjs src/per-user-files.test.mjs",
45
45
  "test:integration:bootstrap": "node src/bootstrap-dryrun.integration.test.mjs",
46
46
  "smoke": "node scripts/smoke.mjs",
47
47
  "eval": "pwsh plugin/skills/eval/run-evals.ps1 -Skill",
@@ -57,6 +57,7 @@ The Evidence/ folder produced by `aggregate` is the **public contract** between
57
57
  | `@Kushi global init` / `status` / `ask <q>` / `lint` | standard+ | n/a | v5.3.0 — `global-wiki` — manage the per-user cross-engagement wiki at `~/.kushi-global/State/` (env `KUSHI_GLOBAL_ROOT` for tests). |
58
58
  | `@Kushi promote <project> <page>` | standard+ | n/a | v5.3.0 — `promote` — copy a project State page into the global wiki with identifier redaction + back-link + dual log. Refuses without `--force` when identifiers detected. |
59
59
  | `@Kushi doctor` | core+ | n/a (read-only) | v5.4.0 — `doctor` — aggregated health check (env, self-check, evals, skill-checker, live-install drift, global wiki). `--json` for CI; `--strict` to fail on yellow. |
60
+ | `@Kushi migrate-files <project>` | standard+ | n/a | v5.4.4 — `migrate-per-user-files` — one-time migration of root-level `bootstrap-status.md` / `FOLLOW-UPS.md` / `OPEN-QUESTIONS-DRAFT.md` to per-user `Evidence/<alias>/`. Dry-run by default; `--apply` to commit. Refuses to overwrite on content conflict (`[needs-merge]`). |
60
61
 
61
62
  **Note on auto-routing**: `ask` does NOT require the `@Kushi ask` prefix. Any message that names a known project AND asks a question (what / who / when / status / summarize / etc.) auto-dispatches to `ask-project`. Producer verbs win in the unambiguous case.
62
63
 
@@ -5,7 +5,9 @@ excludeAgent: "code-review"
5
5
 
6
6
  # Bootstrap Status Artifact — Format Contract
7
7
 
8
- When `bootstrap-project` (or any full refresh / retry workflow) finishes a project run, it MUST write `<project>/bootstrap-status.md` using the format below. This file is the **fast orientation artifact** for the project — what was bootstrapped, what durable context now exists, what stage the engagement is in, what gaps remain. It is NOT a transcript of the run.
8
+ When `bootstrap-project` (or any full refresh / retry workflow) finishes a project run, it MUST write `<project>/Evidence/<alias>/bootstrap-status.md` using the format below. This file is the **per-user fast orientation artifact** for the project — what was bootstrapped, what durable context now exists, what stage the engagement is in, what gaps remain. It is NOT a transcript of the run.
9
+
10
+ > **v5.4.4+ — per-user path.** The bootstrap-status artifact is **per-user authored** under `Evidence/<alias>/bootstrap-status.md` per `multi-user-shared-files.instructions.md` § "Per-user authored files". A cross-contributor rollup lives at `<project>/_Consolidated/bootstrap-status.md`, written deterministically by `consolidate-evidence` (Step 5). The pre-v5.4.4 root-level `<project>/bootstrap-status.md` is owned by `consolidate-evidence` only; writers MUST NOT touch it. Legacy projects are auto-migrated by `migrate-per-user-files`.
9
11
 
10
12
  > **v4.4.2 contracts** — every `Status` cell in this artifact MUST come from the closed taxonomy in `status-taxonomy.instructions.md`. Direct-path failures that were recovered by a documented fallback MUST be rendered as `completed-via-fallback` per `fallback-status-reporting.instructions.md`, not `failed` / `blocked`. The pre-v4.4.2 ad-hoc strings (`populated`, `unsynced`, `degraded`, `partial-cap`, etc.) are mapped onto the taxonomy in `status-taxonomy.instructions.md §1`.
11
13
 
@@ -92,29 +94,28 @@ Use these exact strings everywhere (table cells, run-log, narrative):
92
94
  - `ado-not-complete` — engagement record not found yet OR ADO linkage missing
93
95
  - `completed-with-coverage-gaps` — final outcome with explicit gaps recorded
94
96
 
95
- ## Multi-contributor safety (kushi v4.4.0+)
97
+ ## Multi-contributor safety (kushi v5.4.4+)
96
98
 
97
- `<project>/bootstrap-status.md` is shared across all contributors via OneDrive. Per `multi-user-shared-files.instructions.md`:
99
+ Per `multi-user-shared-files.instructions.md`, this file is **per-user authored** at `<project>/Evidence/<alias>/bootstrap-status.md` and the consolidated cross-contributor view lives at `<project>/_Consolidated/bootstrap-status.md` (written by `consolidate-evidence` Step 5):
98
100
 
99
- 1. **Before writing**, scan `<project>/` for sibling conflict copies (e.g. `bootstrap-status-conflict-<alias>-<host>.md` or OneDrive's `bootstrap-status (Stan's conflicted copy *)`). If any exist, merge their content into the canonical file (taking the most recent per-source row) and delete the conflict copies. Log this in the per-user bootstrap report under `## Conflict copies merged`.
100
- 2. **Preserve other contributors' attribution.** Read the existing file; the `## Contributors who have bootstrapped this project` section MUST keep one row per alias that has ever written it. Update only the row matching the current alias.
101
- 3. **Per-source rows** in `## Context Artifact Status` reflect the most recent discovery across all contributors. Add a trailing `Discovered by` column showing which alias performed the latest discovery (cross-referenced from each alias's `m365-mutable.json` via `Get-KushiConfig`).
102
- 4. **The final one-line status** is for the most recent run only and may be overwritten by any contributor.
101
+ 1. **Writers target the per-user path only.** Every `bootstrap-project` / `refresh-project` run writes its own `Evidence/<alias>/bootstrap-status.md`. There is no read-modify-write contention each alias owns its file.
102
+ 2. **No `Contributors who have bootstrapped this project` section on the per-user file.** That section is reconstructed in the `_Consolidated/bootstrap-status.md` rollup, which lists every contributor with their per-user file's `Last Run` / `Mode` / `Outcome`.
103
+ 3. **Conflict-copies on the per-user file are extremely rare** (only the owning alias writes it). If they do appear, the alias's next bootstrap absorbs them and deletes them per the universal merge rules.
104
+ 4. **The final one-line status** on the per-user file is for the most recent run by that alias only.
103
105
 
104
- ### Required `## Contributors who have bootstrapped this project` section
106
+ ### Required `## Run summary` section on the per-user file
105
107
 
106
- Append this section immediately after `## Bootstrap Status`:
108
+ Append immediately after `## Bootstrap Status`:
107
109
 
108
110
  ```
109
- ## Contributors who have bootstrapped this project
111
+ ## Run summary
110
112
 
111
113
  | Alias | Display Name | Last Run | Mode | Outcome |
112
114
  |---|---|---|---|---|
113
- | ushak | Usha Kandregula | 2026-05-20 07:42 EDT | bootstrap | bootstrap-complete-with-coverage-gaps |
114
- | stand | Stan Doe | 2026-05-18 16:01 EDT | refresh | refresh-complete |
115
+ | ushak | Usha Kandregula | 2026-05-27 09:42 EDT | bootstrap | bootstrap-complete-with-coverage-gaps |
115
116
  ```
116
117
 
117
- Preserve every existing row except the one matching your alias.
118
+ `consolidate-evidence` Step 5 reads every `Evidence/<alias>/bootstrap-status.md`, harvests its `## Run summary` row, and emits a merged `## Contributors who have bootstrapped this project` table into `_Consolidated/bootstrap-status.md`.
118
119
 
119
120
  ## Sections to AVOID in bootstrap-status
120
121
 
@@ -1,87 +1,117 @@
1
- ---
2
- applyTo: "**/SKILL.md,**/*.prompt.md,**/Evidence/run-log.yml,**/integrations.yml,**/bootstrap-status.md,**/OPEN-QUESTIONS-DRAFT.md,**/State/09_open-questions.md,**/Evidence/contributors.yml"
3
- ---
4
-
5
- # Multi-user shared-file safety
6
-
7
- ## Why this exists
8
-
9
- A Kushi engagement folder (`<engagement-root>/<project>/`) is shared across all contributors via OneDrive. Several artifacts inside it are **logically shared** — every contributor reads and writes the same path:
10
-
11
- | Shared artifact | Path | Writers |
12
- |---|---|---|
13
- | Per-project integrations | `<project>/integrations.yml` | `bootstrap-project`, `propose-ado-update`, `apply-ado-update`, every `pull-*` that discovers an ID |
14
- | Bootstrap status snapshot | `<project>/bootstrap-status.md` | `bootstrap-project` (every run, any contributor) |
15
- | Open questions draft | `<project>/OPEN-QUESTIONS-DRAFT.md` (or `State/09_open-questions.md` on full profile) | `bootstrap-project`, `consolidate-evidence`, `build-state`, `propose-ado-update` |
16
- | Run log | `<project>/Evidence/run-log.yml` | every `pull-*`, `bootstrap-project`, `refresh-project`, `fde-*` |
17
- | Contributors list | `<project>/Evidence/contributors.yml` | every `pull-*` (first time an alias touches the project) |
18
-
19
- Without rules, two contributors running concurrently produce one of:
20
- - OneDrive conflict-copy (`*-conflict-<alias>-<host>.yml`) — silent loss until manually merged.
21
- - Last-writer-wins overwrite — silent loss of the other contributor's data.
22
-
23
- This doctrine codifies the contract every writer must honor. It is **not** a substitute for proper locking, but it makes concurrent runs eventually consistent and recoverable.
24
-
25
- ## Universal rules (apply to every shared artifact)
26
-
27
- 1. **Read-modify-write, never blind-write.** Before writing any shared artifact, the skill MUST read the current file, merge its new contribution, and write the merged result. Blind overwrite is forbidden.
28
- 2. **Detect and absorb conflict-copies.** Before reading the canonical file, glob for sibling files matching `<basename>-conflict-*` or `<basename> (<host>'s conflicted copy *)`. If any exist, merge their contents into the canonical file, then delete the conflict copies. Log the merge in the run report.
29
- 3. **Stamp every contribution.** Every line / block / list-entry that a skill adds must carry its alias (from `project-evidence.yml`) and an ISO timestamp so future readers (and the merge logic above) can deterministically reconcile.
30
- 4. **Idempotent appends.** Re-running the same skill in the same window MUST NOT duplicate prior entries. Use a `(alias, source, window_key)` tuple as the dedupe key.
31
- 5. **Never delete another contributor's contribution.** A skill may only modify or remove entries it created (matched by alias). Cleanup of other aliases' entries is reserved for `consolidate-evidence`.
32
-
33
- ## Per-artifact contracts
34
-
35
- ### `<project>/integrations.yml`
36
-
37
- - **Pattern**: read-modify-write with alias stamp on changed fields.
38
- - Whenever a skill discovers a new ID (CRM `record_id`, ADO `engagement_id`, OneNote `section_file_id`, etc.), it MUST:
39
- 1. Read the current file.
40
- 2. If the target field is non-empty AND differs from the discovered value, write the discovered value into a sibling key `<field>_proposed_<alias>` and add a Q-row to `OPEN-QUESTIONS-DRAFT.md` for human reconciliation. Do not overwrite.
41
- 3. If the target field is empty (or matches), write the value and append a comment line: `# resolved by <alias> on <YYYY-MM-DD>` immediately above the changed key.
42
- - The `last_discovery_attempt` / `last_discovery_result` keys MAY be overwritten by any alias (they are intentionally last-writer-wins; the value is "the most recent attempt by anyone").
43
-
44
- ### `<project>/bootstrap-status.md`
45
-
46
- - **Pattern**: full rewrite is permitted, but the file MUST carry a `## Contributors who have bootstrapped this project` section listing every alias that has ever written it, with their last-run timestamp.
47
- - Before rewriting, the skill MUST read the existing Contributors section and preserve every entry whose alias differs from the current alias. Update only its own alias row.
48
- - The per-source status tables (`OneNote`, `Email`, `Teams`, etc.) reflect the **most recent** discovery across all contributors. Skills MUST cross-reference `m365-mutable.json` (which is per-user) when a row shows discovered IDs, also note which alias performed the discovery in a trailing `(by <alias>)` cell.
49
-
50
- ### `<project>/OPEN-QUESTIONS-DRAFT.md` and `<project>/State/09_open-questions.md`
51
-
52
- - **Pattern**: append-only with dedup.
53
- - Every question row carries `[asked by <alias> on <YYYY-MM-DD>]` as the trailing column.
54
- - Before appending a new question, the skill MUST scan existing rows for a question whose normalized text (lowercased, whitespace-collapsed) matches. If a match exists, do not append a duplicate; instead, append `, <alias> on <date>` to the existing row's attribution.
55
- - Rows are removed only by an explicit `resolve-open-question` action (out of scope here) — never by another `bootstrap` / `refresh` run.
56
-
57
- ### `<project>/Evidence/run-log.yml`
58
-
59
- - **Pattern**: structured append + max() merge.
60
- - Run history (`runs:` list) is append-only. Every entry carries `alias:` and `run_at:`.
61
- - Per-source watermarks (`sources.<source>.watermark`) use **max()** merge: when writing, the skill reads the current value and writes `max(current, new)`. Never overwrite with an older watermark.
62
- - Per-source errors (`sources.<source>.errors[]`) are append-only with `alias` + `at` on every entry; dedup on `(alias, code, at)`.
63
-
64
- ### `<project>/Evidence/contributors.yml`
65
-
66
- - **Pattern**: append-only, alias-keyed.
67
- - The first time an alias runs against the project, append `{ alias, display_name, email, first_seen: <YYYY-MM-DD> }`. Subsequent runs MUST NOT modify the entry.
68
- - `last_seen` MAY be updated by any run, max()-merged.
69
-
70
- ## Implementation guidance for skill authors
71
-
72
- - Read `<workspace>/.kushi/config/user/project-evidence.yml` to get your alias via `Get-KushiConfig -Name 'project-evidence'`. Never hardcode aliases.
73
- - For YAML merges, use `Get-Content -Raw | ConvertFrom-Yaml`, mutate, then `ConvertTo-Yaml`. Preserve comments where possible by line-based merging when structure permits.
74
- - For Markdown table merges in `OPEN-QUESTIONS-DRAFT.md`, parse the body to a list of rows, dedup by normalized question text, re-emit.
75
- - On any merge conflict the skill cannot resolve deterministically, write the alternative as a sibling-key `<field>_proposed_<alias>` (for YAML) or a `> Disagreement: <alias-A> says ..., <alias-B> says ...` callout (for Markdown) and add a Q-row to `OPEN-QUESTIONS-DRAFT.md`.
76
-
77
- ## Out of scope
78
-
79
- - True file locking (filesystem advisory locks, OneDrive's checkout API) — relies on platform support Kushi can't assume.
80
- - Server-side merge service Kushi is local-only by design.
81
-
82
- ## Related doctrine
83
-
84
- - `evidence-layout-canonical.instructions.md` — what lives where under `Evidence/`.
85
- - `run-reports.instructions.md` — per-user run narrative (always under `Evidence/<alias>/`, no concurrency risk).
86
- - `bootstrap-status-format.instructions.md` format contract for the shared status artifact.
87
- - `citation-ledger.instructions.md` every assertion in shared artifacts must carry a citation; alias attribution is the citation for shared-file entries.
1
+ ---
2
+ applyTo: "**/SKILL.md,**/*.prompt.md,**/Evidence/run-log.yml,**/integrations.yml,**/bootstrap-status.md,**/FOLLOW-UPS.md,**/OPEN-QUESTIONS-DRAFT.md,**/Evidence/*/bootstrap-status.md,**/Evidence/*/FOLLOW-UPS.md,**/Evidence/*/OPEN-QUESTIONS-DRAFT.md,**/_Consolidated/bootstrap-status.md,**/_Consolidated/FOLLOW-UPS.md,**/_Consolidated/OPEN-QUESTIONS-DRAFT.md,**/State/09_open-questions.md,**/Evidence/contributors.yml"
3
+ ---
4
+
5
+ # Multi-user shared-file safety
6
+
7
+ ## Why this exists
8
+
9
+ A Kushi engagement folder (`<engagement-root>/<project>/`) is shared across all contributors via OneDrive. Some artifacts inside it are **logically shared** — every contributor reads and writes the same path. Others are **per-user authored** — every contributor writes their own copy under `Evidence/<alias>/` and `consolidate-evidence` later merges them into `_Consolidated/`.
10
+
11
+ | Shared artifact | Path | Writers |
12
+ |---|---|---|
13
+ | Per-project integrations | `<project>/integrations.yml` | `bootstrap-project`, `propose-ado-update`, `apply-ado-update`, every `pull-*` that discovers an ID |
14
+ | Run log | `<project>/Evidence/run-log.yml` | every `pull-*`, `bootstrap-project`, `refresh-project`, `fde-*` |
15
+ | Contributors list | `<project>/Evidence/contributors.yml` | every `pull-*` (first time an alias touches the project) |
16
+ | Project config | `<project>/kushi.yaml`, `<project>/.settings.yml` | `setup`, `bootstrap-project` |
17
+
18
+ Without rules, two contributors running concurrently produce one of:
19
+ - OneDrive conflict-copy (`*-conflict-<alias>-<host>.yml`) silent loss until manually merged.
20
+ - Last-writer-wins overwrite — silent loss of the other contributor''s data.
21
+
22
+ This doctrine codifies the contract every writer must honor. It is **not** a substitute for proper locking, but it makes concurrent runs eventually consistent and recoverable.
23
+
24
+ ## Per-user authored files (v5.4.4+)
25
+
26
+ Three artifacts that historically lived at the project root are now **per-user authored** with an auto-generated consolidated view. v5.4.3 soak finding #5: every contributor''s `bootstrap-project` run was overwriting the previous contributor''s `<project>/bootstrap-status.md`, silently losing truth.
27
+
28
+ | File | Per-user path (truth) | Consolidated path (auto-generated by `consolidate-evidence`) |
29
+ |---|---|---|
30
+ | `bootstrap-status.md` | `<project>/Evidence/<alias>/bootstrap-status.md` | `<project>/_Consolidated/bootstrap-status.md` |
31
+ | `FOLLOW-UPS.md` | `<project>/Evidence/<alias>/FOLLOW-UPS.md` | `<project>/_Consolidated/FOLLOW-UPS.md` |
32
+ | `OPEN-QUESTIONS-DRAFT.md` | `<project>/Evidence/<alias>/OPEN-QUESTIONS-DRAFT.md` | `<project>/_Consolidated/OPEN-QUESTIONS-DRAFT.md` |
33
+
34
+ **Rules:**
35
+
36
+ 1. **Writers target the per-user path only.** `bootstrap-project`, `refresh-project`, `aggregate-project`, every `pull-*` (for `OPEN-QUESTIONS-DRAFT.md` rows they append), `propose-ado-update`, and the per-source verification gate (for `FOLLOW-UPS.md` rows) all write to `<project>/Evidence/<alias>/<file>`. The alias is resolved from `.kushi/config/user/project-evidence.yml` via `Get-KushiConfig -Name ''project-evidence''`. Writers MUST NOT touch the project-root copies — those are owned by `consolidate-evidence`, which writes to `_Consolidated/`.
37
+ 2. **`consolidate-evidence` owns the `_Consolidated/` copies.** After per-user files are written, `consolidate-evidence` (called either directly, or transitively from `aggregate-project` / `refresh-project`) emits `<project>/_Consolidated/<file>` from every contributor''s `Evidence/<alias>/<file>`. Deterministic merge no LLM. Idempotent.
38
+ 3. **The root-level copies are NEVER written by hand or by skills going forward.** Legacy projects may still carry root-level `bootstrap-status.md` / `FOLLOW-UPS.md` / `OPEN-QUESTIONS-DRAFT.md` from pre-v5.4.4 runs; the `migrate-per-user-files` skill moves them to `Evidence/<alias>/` on first opportunity. See `plugin/skills/migrate-per-user-files/SKILL.md`.
39
+ 4. **Readers MAY read both.** Q&A / dashboard / FDE-report skills SHOULD prefer `_Consolidated/<file>` when present; fall back to merging every `Evidence/<alias>/<file>` themselves if the consolidated copy is stale.
40
+
41
+ ### Per-user `bootstrap-status.md`
42
+
43
+ - Full rewrite by its owning alias only. Other aliases'' files are untouched.
44
+ - The `## Contributors who have bootstrapped this project` section is no longer required on the per-user file — each alias''s file represents only that alias''s bootstrap state. The consolidated copy at `_Consolidated/bootstrap-status.md` reconstructs the cross-contributor section.
45
+
46
+ ### Per-user `FOLLOW-UPS.md`
47
+
48
+ - Append-only by its owning alias under `Evidence/<alias>/FOLLOW-UPS.md`. Open / Resolved sections per `per-source-verification-gate.instructions.md` §B (5-field shape). Auto-resolution flips `Status: open` `resolved-<YYYY-MM-DD>` on the alias''s next run when the gate passes. Consolidated rollup at `_Consolidated/FOLLOW-UPS.md`.
49
+
50
+ ### Per-user `OPEN-QUESTIONS-DRAFT.md`
51
+
52
+ - Append-only at `Evidence/<alias>/OPEN-QUESTIONS-DRAFT.md`, dedup by normalized question text within the alias''s own file. Every row carries `[asked by <alias> on <YYYY-MM-DD>]`.
53
+ - Rows are removed only by an explicit `resolve-open-question` action never by another `bootstrap` / `refresh` run. Cross-contributor rollup at `_Consolidated/OPEN-QUESTIONS-DRAFT.md`.
54
+
55
+ ### Auto-consolidation merge contract
56
+
57
+ `consolidate-evidence` emits three deterministic files under `_Consolidated/` (see `plugin/skills/consolidate-evidence/SKILL.md` Step 5):
58
+
59
+ - **`_Consolidated/bootstrap-status.md`** header + per-contributor sub-section (verbatim copy of each `Evidence/<alias>/bootstrap-status.md`) + a merged "Latest discovery sweep results" table preferring most-recent-resolved per source.
60
+ - **`_Consolidated/FOLLOW-UPS.md`** dedup-merged rows tagged with originating `(alias)`. Dedup key is the source + first line of "Next-time-do".
61
+ - **`_Consolidated/OPEN-QUESTIONS-DRAFT.md`** questions deduped by normalized text, with an attribution column listing every alias that asked it and the earliest date.
62
+
63
+ Re-running `consolidate-evidence` is idempotent. Output is byte-stable for the same input set.
64
+
65
+ ## Universal rules (apply to every shared artifact)
66
+
67
+ 1. **Read-modify-write, never blind-write.** Before writing any shared artifact, the skill MUST read the current file, merge its new contribution, and write the merged result. Blind overwrite is forbidden.
68
+ 2. **Detect and absorb conflict-copies.** Before reading the canonical file, glob for sibling files matching `<basename>-conflict-*` or `<basename> (<host>''s conflicted copy *)`. If any exist, merge their contents into the canonical file, then delete the conflict copies. Log the merge in the run report.
69
+ 3. **Stamp every contribution.** Every line / block / list-entry that a skill adds must carry its alias (from `project-evidence.yml`) and an ISO timestamp so future readers (and the merge logic above) can deterministically reconcile.
70
+ 4. **Idempotent appends.** Re-running the same skill in the same window MUST NOT duplicate prior entries. Use a `(alias, source, window_key)` tuple as the dedupe key.
71
+ 5. **Never delete another contributor''s contribution.** A skill may only modify or remove entries it created (matched by alias). Cleanup of other aliases'' entries is reserved for `consolidate-evidence`.
72
+
73
+ ## Per-artifact contracts (truly shared root files)
74
+
75
+ ### `<project>/integrations.yml`
76
+
77
+ - **Pattern**: read-modify-write with alias stamp on changed fields.
78
+ - Whenever a skill discovers a new ID (CRM `record_id`, ADO `engagement_id`, OneNote `section_file_id`, etc.), it MUST:
79
+ 1. Read the current file.
80
+ 2. If the target field is non-empty AND differs from the discovered value, write the discovered value into a sibling key `<field>_proposed_<alias>` and add a Q-row to the alias''s `Evidence/<alias>/OPEN-QUESTIONS-DRAFT.md` for human reconciliation. Do not overwrite.
81
+ 3. If the target field is empty (or matches), write the value and append a comment line: `# resolved by <alias> on <YYYY-MM-DD>` immediately above the changed key.
82
+ - The `last_discovery_attempt` / `last_discovery_result` keys MAY be overwritten by any alias (they are intentionally last-writer-wins; the value is "the most recent attempt by anyone").
83
+
84
+ ### `<project>/Evidence/run-log.yml`
85
+
86
+ - **Pattern**: structured append + max() merge.
87
+ - Run history (`runs:` list) is append-only. Every entry carries `alias:` and `run_at:`.
88
+ - Per-source watermarks (`sources.<source>.watermark`) use **max()** merge: when writing, the skill reads the current value and writes `max(current, new)`. Never overwrite with an older watermark.
89
+ - Per-source errors (`sources.<source>.errors[]`) are append-only with `alias` + `at` on every entry; dedup on `(alias, code, at)`.
90
+
91
+ ### `<project>/Evidence/contributors.yml`
92
+
93
+ - **Pattern**: append-only, alias-keyed.
94
+ - The first time an alias runs against the project, append `{ alias, display_name, email, first_seen: <YYYY-MM-DD> }`. Subsequent runs MUST NOT modify the entry.
95
+ - `last_seen` MAY be updated by any run, max()-merged.
96
+
97
+ ## Implementation guidance for skill authors
98
+
99
+ - Read `<workspace>/.kushi/config/user/project-evidence.yml` to get your alias via `Get-KushiConfig -Name ''project-evidence''`. Never hardcode aliases.
100
+ - For per-user files (`bootstrap-status.md`, `FOLLOW-UPS.md`, `OPEN-QUESTIONS-DRAFT.md`), write under `<project>/Evidence/<alias>/<file>`. Path-scope hint near every literal mention: `Evidence/<alias>/` or `_Consolidated/`.
101
+ - For YAML merges of shared root files, use `Get-Content -Raw | ConvertFrom-Yaml`, mutate, then `ConvertTo-Yaml`. Preserve comments where possible by line-based merging when structure permits.
102
+ - For Markdown table merges in per-user `OPEN-QUESTIONS-DRAFT.md`, parse the body to a list of rows, dedup by normalized question text, re-emit.
103
+ - On any merge conflict the skill cannot resolve deterministically, write the alternative as a sibling-key `<field>_proposed_<alias>` (for YAML) or a `> Disagreement: <alias-A> says ..., <alias-B> says ...` callout (for Markdown) and add a Q-row to `<project>/Evidence/<alias>/OPEN-QUESTIONS-DRAFT.md`.
104
+
105
+ ## Out of scope
106
+
107
+ - True file locking (filesystem advisory locks, OneDrive''s checkout API) — relies on platform support Kushi can''t assume.
108
+ - Server-side merge service — Kushi is local-only by design.
109
+
110
+ ## Related doctrine
111
+
112
+ - `evidence-layout-canonical.instructions.md` — what lives where under `Evidence/`.
113
+ - `run-reports.instructions.md` — per-user run narrative (always under `Evidence/<alias>/`, no concurrency risk).
114
+ - `bootstrap-status-format.instructions.md` — format contract for the per-user bootstrap-status artifact.
115
+ - `citation-ledger.instructions.md` — every assertion in shared artifacts must carry a citation; alias attribution is the citation for shared-file entries.
116
+ - `plugin/skills/consolidate-evidence/SKILL.md` — Step 5 (v5.4.4+) emits the `_Consolidated/` copies of the per-user authored files.
117
+ - `plugin/skills/migrate-per-user-files/SKILL.md` — one-time migration from root-level legacy paths to `Evidence/<alias>/`.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kushi",
3
3
  "description": "Multi-source project evidence + Q&A agent. Snapshot + stream capture across Email, Teams, OneNote, Loop, SharePoint, Meetings, CRM, ADO; plus read-only natural-language Q&A over the captured evidence. WorkIQ-only for M365 sources (Graph / m365_* FORBIDDEN as fallbacks; user-paste is first-class). Host-agnostic. Three install profiles: core (aggregator only), standard (default — adds bootstrap/refresh + FDE authoring), full (adds State/ rollup).",
4
- "version": "3.15.0",
4
+ "version": "3.16.0",
5
5
  "author": "ushakrishnan",
6
6
  "repository": "https://github.com/gim-home/kushi",
7
7
  "default_profile": "standard",
@@ -11,6 +11,8 @@
11
11
  "skills": [
12
12
  "intro",
13
13
  "self-check",
14
+ "doctor",
15
+ "eval",
14
16
  "setup",
15
17
  "pull-email",
16
18
  "pull-teams",
@@ -18,6 +20,7 @@
18
20
  "pull-onenote",
19
21
  "pull-loop",
20
22
  "pull-sharepoint",
23
+ "pull-misc",
21
24
  "pull-crm",
22
25
  "pull-ado",
23
26
  "aggregate-project",
@@ -34,7 +37,8 @@
34
37
  "status",
35
38
  "ask",
36
39
  "vertex-link",
37
- "emit-vertex"
40
+ "emit-vertex",
41
+ "doctor"
38
42
  ],
39
43
  "instructions": "*",
40
44
  "templates": [
@@ -50,7 +54,8 @@
50
54
  "pull",
51
55
  "ask",
52
56
  "vertex-link",
53
- "emit-vertex"
57
+ "emit-vertex",
58
+ "doctor"
54
59
  ]
55
60
  },
56
61
  "standard": {
@@ -64,7 +69,12 @@
64
69
  "fde-triage",
65
70
  "link-entities",
66
71
  "dashboard",
67
- "tour"
72
+ "tour",
73
+ "lint-state",
74
+ "teach",
75
+ "promote",
76
+ "schema-evolve",
77
+ "migrate-per-user-files"
68
78
  ],
69
79
  "prompts": [
70
80
  "bootstrap",
@@ -74,7 +84,8 @@
74
84
  "fde-triage",
75
85
  "link-entities",
76
86
  "dashboard",
77
- "tour"
87
+ "tour",
88
+ "migrate-files"
78
89
  ],
79
90
  "templates": [
80
91
  "init",
@@ -92,15 +103,24 @@
92
103
  "fde-triage",
93
104
  "link-entities",
94
105
  "dashboard",
95
- "tour"
106
+ "tour",
107
+ "lint",
108
+ "teach",
109
+ "explain",
110
+ "promote",
111
+ "schema-evolve",
112
+ "migrate-files"
96
113
  ],
97
114
  "_": null
98
115
  },
99
116
  "full": {
100
117
  "extends": "standard",
101
- "description": "Standard + State/ rollup. Adds the opinionated outcome-based State/ files (decisions, stakeholders, architecture, action items, risks, timeline, artifacts, open questions) built on top of Evidence/. On this profile, bootstrap/refresh call build-state at the end.",
118
+ "description": "Standard + State/ rollup + global cross-engagement wiki + skill-authoring harness. Adds the opinionated outcome-based State/ files (decisions, stakeholders, architecture, action items, risks, timeline, artifacts, open questions) built on top of Evidence/, plus ~/.kushi-global/ wiki tooling and skill-creator/skill-checker for contributors. On this profile, bootstrap/refresh call build-state at the end.",
102
119
  "skills": [
103
- "build-state"
120
+ "build-state",
121
+ "global-wiki",
122
+ "skill-creator",
123
+ "skill-checker"
104
124
  ],
105
125
  "prompts": [
106
126
  "state"
@@ -110,7 +130,10 @@
110
130
  ],
111
131
  "reference_packs": [],
112
132
  "verbs": [
113
- "state"
133
+ "state",
134
+ "global",
135
+ "create-skill",
136
+ "check-skill"
114
137
  ]
115
138
  },
116
139
  "preview": {
@@ -59,7 +59,8 @@ Produces:
59
59
  - `<engagement-root>/<project>/integrations.yml` (per-project boundaries + enabled-sources, shared via OneDrive)
60
60
  - `<engagement-root>/<project>/Evidence/{contributors.yml, run-log.yml, <alias>/.settings.yml, <alias>/{email,teams,meetings,onenote,sharepoint,crm,ado}/{snapshot,stream}/, <alias>/_deferred-retries/}`
61
61
  - `<engagement-root>/<project>/State/{00..09}_*.md` (full profile only)
62
- - `<engagement-root>/<project>/bootstrap-status.md` (shared, multi-user safe)
62
+ - `<engagement-root>/<project>/Evidence/<alias>/bootstrap-status.md` (per-user authored, v5.4.4+ — auto-consolidated to `<project>/_Consolidated/bootstrap-status.md` by `consolidate-evidence`)
63
+ - `<engagement-root>/<project>/Evidence/<alias>/FOLLOW-UPS.md` and `<engagement-root>/<project>/Evidence/<alias>/OPEN-QUESTIONS-DRAFT.md` (per-user authored, v5.4.4+ — auto-consolidated under `_Consolidated/`)
63
64
 
64
65
  Delegates to `bootstrap-project` skill. After scaffolding, calls each `pull-<source>` skill, then `build-state` (full profile only).
65
66
 
@@ -24,7 +24,10 @@ Reads:
24
24
  - `<engagement-root>/<project>/Evidence/contributors.yml`
25
25
 
26
26
  Writes:
27
- - `<engagement-root>/<project>/Evidence/_Consolidated/<YYYY-MM-DD>_consolidated.md` (Monday of the week)
27
+ - `<engagement-root>/<project>/Evidence/_Consolidated/<YYYY-MM-DD>_consolidated.md` (Monday of the week — per-source CSC rollups)
28
+ - `<engagement-root>/<project>/_Consolidated/bootstrap-status.md` (v5.4.4+ — rollup of every `Evidence/<alias>/bootstrap-status.md`)
29
+ - `<engagement-root>/<project>/_Consolidated/FOLLOW-UPS.md` (v5.4.4+ — rollup of every `Evidence/<alias>/FOLLOW-UPS.md`)
30
+ - `<engagement-root>/<project>/_Consolidated/OPEN-QUESTIONS-DRAFT.md` (v5.4.4+ — rollup of every `Evidence/<alias>/OPEN-QUESTIONS-DRAFT.md`)
28
31
 
29
32
  Provenance tags retained (source: <alias>/<source>/<file>) per `citation-ledger.instructions.md`.
30
33
 
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: create-skill
3
+ description: "Scaffold a new kushi skill from the skill-creator harness."
4
+ argument-hint: "Skill name + optional --description '...'. Example: 'create-skill pull-confluence'."
5
+ agent: kushi
6
+ tools: [search, read/readFile, edit, 'execute/runInTerminal', agent]
7
+ ---
8
+
9
+ ## User Input
10
+
11
+ ```text
12
+ ${input:name_and_flags:Skill name + optional flags, e.g. 'pull-confluence --description "Pull from Confluence"'}
13
+ ```
14
+
15
+ # /create-skill
16
+
17
+ Route to `@Kushi create-skill <name>`.
18
+
19
+ Scaffolds a new skill under `plugin/skills/<name>/` with SKILL.md frontmatter,
20
+ description placeholder, references/ folder, and example test stub. Output
21
+ conforms to `skill-authoring.instructions.md` so `check-skill` passes on first
22
+ run.
23
+
24
+ Companion verb: `/check-skill <name>` lints + retrofits an existing skill.
25
+
26
+ Delegates to `skill-creator` skill.
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: doctor
3
+ description: "Aggregated health check — env, self-check, evals, skill-checker, install drift, global wiki."
4
+ argument-hint: "No project needed; runs system-wide diagnostics. Flags: --json (CI), --strict (fail on yellow)."
5
+ agent: kushi
6
+ tools: [search, read/readFile, 'execute/runInTerminal', agent]
7
+ ---
8
+
9
+ ## User Input
10
+
11
+ ```text
12
+ ${input:flags:Optional flags (--json, --strict). Empty for human-readable run.}
13
+ ```
14
+
15
+ # /doctor
16
+
17
+ Route to `@Kushi doctor` — aggregated health check covering:
18
+
19
+ - **env** — node, pwsh, kushi version, install layout
20
+ - **self-check** `-Deep` — D1..D41 doctrine checks
21
+ - **evals** `:canary` — golden-set regression check
22
+ - **skill-checker** `-All` — every SKILL.md against `skill-authoring.instructions.md`
23
+ - **live-install drift** — repo source vs installed `~/.copilot/m-skills/kushi/` and `~/.vscode/chat/skills/kushi/`
24
+ - **global wiki** — `~/.kushi-global/State/` shape + run-log
25
+
26
+ Output: colored ribbon (GREEN / YELLOW / RED) + per-finding fix.
27
+
28
+ Read-only by default. No pulls, no writes.
29
+
30
+ Delegates to the `doctor` skill (`skills/doctor/doctor.ps1`). For CI:
31
+ `pwsh -File skills/doctor/doctor.ps1 --json --strict`.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: explain
3
+ description: "Retrieve a previously taught fact / preference / pattern from .kushi/learnings/."
4
+ argument-hint: "Topic. Example: 'explain HCA naming-convention'."
5
+ agent: kushi
6
+ tools: [search, read/readFile, agent]
7
+ ---
8
+
9
+ ## User Input
10
+
11
+ ```text
12
+ ${input:topic:Topic, e.g. 'HCA naming-convention'}
13
+ ```
14
+
15
+ # /explain
16
+
17
+ Route to `@Kushi explain <topic>`.
18
+
19
+ Looks up `.kushi/learnings/<slug>.md` (or fuzzy-match by topic substring) and renders
20
+ the body + history. Read-only — never mutates the learning. Companion to `/teach`.
21
+
22
+ Delegates to `teach` skill (explain mode).
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: global
3
+ description: "Manage the per-user cross-engagement wiki at ~/.kushi-global/State/."
4
+ argument-hint: "Sub-verb: init | status | ask <question> | lint. Example: 'global ask what's our default pull window?'"
5
+ agent: kushi
6
+ tools: [search, read/readFile, edit, agent]
7
+ ---
8
+
9
+ ## User Input
10
+
11
+ ```text
12
+ ${input:subverb_and_args:Sub-verb + args, e.g. 'init', 'status', 'ask what's our default pull window?', 'lint'}
13
+ ```
14
+
15
+ # /global
16
+
17
+ Route to `@Kushi global <sub-verb>`.
18
+
19
+ Manages the cross-engagement wiki at `~/.kushi-global/State/` (override with
20
+ `KUSHI_GLOBAL_ROOT` for tests). Sub-verbs:
21
+
22
+ - `init` — scaffold the global wiki layout (decisions/, patterns/, glossary/, run-log).
23
+ - `status` — show last-promoted pages + recent activity from the dual log.
24
+ - `ask <q>` — citation-only Q&A over the global wiki (mirrors `kushi ask <project>` shape).
25
+ - `lint` — wiki-lint over the global wiki (same checks as project lint).
26
+
27
+ Delegates to `global-wiki` skill. Companion verb: `/promote` copies a project
28
+ page up into the global wiki with identifier redaction.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: lint
3
+ description: "Run wiki-lint checks against State/ — contradictions, stale claims, orphans, gaps."
4
+ argument-hint: "Project name; runs against <project>/State/ and writes State/reports/lint-YYYY-MM-DD.md"
5
+ agent: kushi
6
+ tools: [search, read/readFile, edit, agent]
7
+ ---
8
+
9
+ ## User Input
10
+
11
+ ```text
12
+ ${input:project:Project name, e.g. HCA}
13
+ ```
14
+
15
+ # /lint
16
+
17
+ Route to `@Kushi lint <project>`.
18
+
19
+ Runs the v5.1.0 `lint-state` skill against `<engagement-root>/<project>/State/`:
20
+ - contradiction detection (claim A vs claim B with same subject)
21
+ - stale claims (>14d without source-evidence freshness)
22
+ - orphan pages (no inbound cross-refs)
23
+ - missing required cross-refs per page type
24
+ - data gaps (entities referenced but not pulled)
25
+
26
+ Writes `<project>/State/reports/lint-YYYY-MM-DD.md`. Read-only against Evidence/.
27
+
28
+ Delegates to `lint-state` skill.