kushi-agents 5.4.3 → 5.4.5

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 (33) hide show
  1. package/README.md +10 -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 +7 -4
  7. package/plugin/prompts/bootstrap.prompt.md +2 -1
  8. package/plugin/prompts/consolidate.prompt.md +4 -1
  9. package/plugin/prompts/migrate-files.prompt.md +29 -0
  10. package/plugin/skills/aggregate-project/SKILL.md +3 -3
  11. package/plugin/skills/bootstrap-project/SKILL.md +6 -6
  12. package/plugin/skills/consolidate-evidence/SKILL.md +94 -1
  13. package/plugin/skills/doctor/doctor.ps1 +101 -11
  14. package/plugin/skills/migrate-per-user-files/SKILL.md +47 -0
  15. package/plugin/skills/migrate-per-user-files/evals/evals.json +41 -0
  16. package/plugin/skills/migrate-per-user-files/migrate.ps1 +136 -0
  17. package/plugin/skills/migrate-per-user-files/references/migration-strategy.md +23 -0
  18. package/plugin/skills/pull-ado/SKILL.md +1 -1
  19. package/plugin/skills/pull-crm/SKILL.md +1 -1
  20. package/plugin/skills/pull-email/SKILL.md +1 -1
  21. package/plugin/skills/pull-loop/SKILL.md +1 -1
  22. package/plugin/skills/pull-meetings/SKILL.md +1 -1
  23. package/plugin/skills/pull-misc/SKILL.md +3 -3
  24. package/plugin/skills/pull-onenote/SKILL.md +1 -1
  25. package/plugin/skills/pull-sharepoint/SKILL.md +1 -1
  26. package/plugin/skills/pull-teams/SKILL.md +1 -1
  27. package/plugin/skills/refresh-project/SKILL.md +5 -5
  28. package/plugin/skills/self-check/SKILL.md +4 -2
  29. package/plugin/skills/self-check/run.ps1 +235 -1
  30. package/src/hooks-dispatcher.test.mjs +2 -2
  31. package/src/layout-portable.test.mjs +89 -0
  32. package/src/per-user-files.test.mjs +137 -0
  33. package/src/profile-coverage.test.mjs +84 -0
package/README.md CHANGED
@@ -223,12 +223,22 @@ The Evidence/ folder produced by every profile is a **stable public contract**
223
223
  | `teach` | standard+ | n/a | v5.2.0 — Persist a reusable fact/preference/pattern under `.kushi/learnings/`. |
224
224
  | `explain` | standard+ | n/a | v5.2.0 — Retrieve a previously taught fact/preference/pattern from `.kushi/learnings/`. |
225
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. |
226
227
  | `global` (init/status/ask/lint) | standard+ | n/a | v5.3.0 — Manage the per-user cross-engagement wiki at `~/.kushi-global/State/`. |
227
228
  | `schema-evolve` | standard+ | n/a | v5.2.0 — Migrate `kushi.yaml` and Evidence/ layouts across schema versions; idempotent + dry-run by default. |
228
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`). |
229
230
 
230
231
  See [Quickstart](https://gim-home.github.io/kushi/getting-started/quickstart/) for the full workflow.
231
232
 
233
+ ### Doctor works from both layouts (v5.4.5+)
234
+
235
+ `doctor` and `self-check` are **layout-portable**: they run cleanly from either the **source tree** (this repo: `plugin/skills/...`) or an **installed host directory** (e.g. `~/.vscode/chat/skills/kushi/skills/...` — FLAT, no `plugin/` prefix). A banner like `[layout=source]` or `[layout=install (host=clawpilot)]` prints at the top of every run so you know which personality is active.
236
+
237
+ - **Source mode** (default in this repo): runs the full source-author surface (C1..C12, D1..D43).
238
+ - **Install mode**: runs a focused install-integrity probe set (manifest validity, every enumerated skill present, agent file, skills-metadata sibling, npm-latest drift if `npm` is on PATH, optional global wiki shape). Fix hints become `Re-install: npx kushi-agents@latest --<host> --force` instead of "restore from git".
239
+
240
+ Force a mode with `-LayoutMode source|install` on either script; default is `auto`.
241
+
232
242
  ## Install
233
243
 
234
244
  Kushi supports **two host surfaces** as first-class peers (v5.0.2+):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kushi-agents",
3
- "version": "5.4.3",
3
+ "version": "5.4.5",
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 src/layout-portable.test.mjs src/profile-coverage.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",
@@ -73,7 +73,8 @@
73
73
  "lint-state",
74
74
  "teach",
75
75
  "promote",
76
- "schema-evolve"
76
+ "schema-evolve",
77
+ "migrate-per-user-files"
77
78
  ],
78
79
  "prompts": [
79
80
  "bootstrap",
@@ -83,7 +84,8 @@
83
84
  "fde-triage",
84
85
  "link-entities",
85
86
  "dashboard",
86
- "tour"
87
+ "tour",
88
+ "migrate-files"
87
89
  ],
88
90
  "templates": [
89
91
  "init",
@@ -106,7 +108,8 @@
106
108
  "teach",
107
109
  "explain",
108
110
  "promote",
109
- "schema-evolve"
111
+ "schema-evolve",
112
+ "migrate-files"
110
113
  ],
111
114
  "_": null
112
115
  },
@@ -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,29 @@
1
+ ---
2
+ mode: agent
3
+ description: "Migrate root-level bootstrap-status.md / FOLLOW-UPS.md / OPEN-QUESTIONS-DRAFT.md to per-user Evidence/<alias>/ paths (kushi v5.4.4+ doctrine)."
4
+ ---
5
+
6
+ # /kushi.migrate-files
7
+
8
+ One-time migration for projects bootstrapped under kushi ≤ v5.4.3.
9
+
10
+ Dispatch the `migrate-per-user-files` skill at `plugin/skills/migrate-per-user-files/` for the current project. Default to **dry-run**. Show the plan and ask the user to re-run with `--apply` to commit. If they explicitly request "apply now" / "do it" / "go" in the same turn, invoke with `-Apply`.
11
+
12
+ ## Resolves
13
+
14
+ - ProjectRoot = the project folder under the current engagement root (resolve via the standard `Get-ProjectRoot` helper).
15
+
16
+ ## Writes
17
+
18
+ - `<project>/Evidence/<alias>/bootstrap-status.md` (moved from root)
19
+ - `<project>/Evidence/<alias>/FOLLOW-UPS.md` (moved from root)
20
+ - `<project>/Evidence/<alias>/OPEN-QUESTIONS-DRAFT.md` (moved from root)
21
+ - `<project>/Evidence/run-log.yml` (appended `migrations:` entry on `--apply`)
22
+
23
+ ## Defensive behavior
24
+
25
+ If both root and per-user copies exist with different content, the skill emits `[needs-merge]` and exits 1 in `--apply` mode — it will NEVER overwrite a per-user file. Hand-merge, then re-run.
26
+
27
+ ## After migration
28
+
29
+ Run `/kushi.consolidate` to generate the `_Consolidated/` rollups for cross-contributor visibility, then `/kushi.status` to verify the bootstrap status reads from the new per-user path.
@@ -20,8 +20,8 @@ This skill **never** writes to `State/`. It only writes to `Evidence/`.
20
20
 
21
21
  1. **Resolve project** — fuzzy-match against `m365-mutable.json knownSections` -> `active_projects` -> `<engagement-root>` subfolders.
22
22
  2. **Resolve window** — default = since last `aggregate`/`refresh`/`bootstrap` watermark in `Evidence/run-log.yml`; fallback 7 days if no watermark.
23
- 3. **Pull each enabled source in turn** (`pull-email`, `pull-teams`, `pull-meetings`, `pull-onenote`, `pull-loop`, `pull-sharepoint`, `pull-crm`, `pull-ado`) — each writes its own snapshot/ + stream/ files under `Evidence/<alias>/<source>/`. **After each pull, run the verification gate** per `..\..\instructions\per-source-verification-gate.instructions.md`: on first failure retry once with the same window; on second failure append a 5-field entry to `<project>/FOLLOW-UPS.md`, log `status: failed-gate` to `Evidence/run-log.yml`, and continue to the next source (never abort the whole aggregate).
24
- 4. **Run `consolidate-evidence`** — merges all aliases' streams into `Evidence/_Consolidated/<YYYY-MM-DD>_consolidated.md`. Skip silently if only one alias exists.
23
+ 3. **Pull each enabled source in turn** (`pull-email`, `pull-teams`, `pull-meetings`, `pull-onenote`, `pull-loop`, `pull-sharepoint`, `pull-crm`, `pull-ado`) — each writes its own snapshot/ + stream/ files under `Evidence/<alias>/<source>/`. **After each pull, run the verification gate** per `..\..\instructions\per-source-verification-gate.instructions.md`: on first failure retry once with the same window; on second failure append a 5-field entry to `<project>/Evidence/<alias>/FOLLOW-UPS.md` (per-user, v5.4.4+; cross-contributor view at `_Consolidated/FOLLOW-UPS.md`), log `status: failed-gate` to `Evidence/run-log.yml`, and continue to the next source (never abort the whole aggregate).
24
+ 4. **Run `consolidate-evidence`** — merges all aliases' streams into `Evidence/_Consolidated/<YYYY-MM-DD>_consolidated.md`, AND emits the three per-user-files rollups: `_Consolidated/bootstrap-status.md`, `_Consolidated/FOLLOW-UPS.md`, `_Consolidated/OPEN-QUESTIONS-DRAFT.md` (Step 5 of consolidate-evidence). Skip the per-source weekly consolidation silently if only one alias exists; the per-user-files rollup ALWAYS runs (single-alias rollup is a verbatim copy with an attribution header).
25
25
  5. **Update `Evidence/run-log.yml`** — record this aggregate run, its watermark, the sources pulled, the alias that produced it.
26
26
  6. **DO NOT run `build-state`.** State/ is not the concern of this skill.
27
27
 
@@ -86,7 +86,7 @@ See `docs/reference/evidence-contract.md` for the full schema (filename rules, f
86
86
  ## References (v4.4.7)
87
87
 
88
88
  - Name → ID resolution (any source) follows `..\..\instructions\fuzzy-disambiguation.instructions.md`.
89
- - After each per-source pull, run the gate per `..\..\instructions\per-source-verification-gate.instructions.md` (retry once → FOLLOW-UPS.md on failure).
89
+ - After each per-source pull, run the gate per `..\..\instructions\per-source-verification-gate.instructions.md` (retry once → `Evidence/<alias>/FOLLOW-UPS.md` on failure; consolidated at `_Consolidated/FOLLOW-UPS.md`).
90
90
 
91
91
 
92
92
  ## Issue Recovery
@@ -10,7 +10,7 @@ description: "USE WHEN the user says \"bootstrap <X>\", \"set up project evidenc
10
10
  >
11
11
  > **Verbatim-by-default**: every `pull-<source>` whose boundary is satisfied MUST be dispatched. Silent skips are defects. See `verbatim-by-default.instructions.md`.
12
12
  >
13
- > **Per-user bootstrap report REQUIRED**: at end of run, write `<project>/Evidence/<alias>/refresh-reports/<YYYY-MM-DD-HHmm>_bootstrap.md` per `run-reports.instructions.md`. Distinct from `<project>/bootstrap-status.md` (durable state) — this is per-user run narrative.
13
+ > **Per-user bootstrap report REQUIRED**: at end of run, write `<project>/Evidence/<alias>/refresh-reports/<YYYY-MM-DD-HHmm>_bootstrap.md` per `run-reports.instructions.md`. Distinct from `<project>/Evidence/<alias>/bootstrap-status.md` (per-user durable state, v5.4.4+) — this is per-user run narrative.
14
14
  >
15
15
  > **Cleanup on resolution**: when this run resolves an ID/folder/section, prune stale `no-match` / probe-trail notes per `cleanup-on-resolution.instructions.md`.
16
16
  >
@@ -37,9 +37,9 @@ The active profile is read from `kushi-install.json#profile` next to this agent
37
37
 
38
38
  ## Bootstrap-status artifact
39
39
 
40
- After every run (success or coverage-gaps), write `<project>/bootstrap-status.md` per the format contract in `instructions/bootstrap-status-format.instructions.md`. This is the project's fast-orientation artifact — required tables, normalized status vocabulary (`resolved`, `populated`, `unsynced`, `degraded-list-only`, `throttled-tooManyRequests`, `ado-not-complete`, `completed-with-coverage-gaps`), one-line final status. Do NOT inline run history here; that goes in `update-status.md`.
40
+ After every run (success or coverage-gaps), write `<project>/Evidence/<alias>/bootstrap-status.md` per the format contract in `instructions/bootstrap-status-format.instructions.md`. This is the **per-user** fast-orientation artifact for the project (v5.4.4+) — required tables, normalized status vocabulary (`resolved`, `populated`, `unsynced`, `degraded-list-only`, `throttled-tooManyRequests`, `ado-not-complete`, `completed-with-coverage-gaps`), one-line final status. Do NOT inline run history here; that goes in the per-user refresh report. The cross-contributor rollup at `<project>/_Consolidated/bootstrap-status.md` is owned by `consolidate-evidence` Step 5 — bootstrap MUST NOT write to it directly.
41
41
 
42
- > **Multi-contributor safety (kushi v4.4.0+)**: this file is shared via OneDrive. Per `multi-user-shared-files.instructions.md`, every write MUST: (a) absorb sibling conflict copies, (b) preserve other aliases' rows in `## Contributors who have bootstrapped this project`, (c) cite the discovering alias in per-source rows. Same rules apply to `<project>/integrations.yml`, `<project>/OPEN-QUESTIONS-DRAFT.md`, `<project>/Evidence/run-log.yml`, `<project>/Evidence/contributors.yml`.
42
+ > **Per-user authored files (v5.4.4+)**: per `multi-user-shared-files.instructions.md`, three artifacts that used to live at the project root are now per-user: `bootstrap-status.md`, `FOLLOW-UPS.md`, and `OPEN-QUESTIONS-DRAFT.md`. Bootstrap MUST write all three under `<project>/Evidence/<alias>/<file>` (alias from `Get-KushiConfig -Name 'project-evidence'`). `consolidate-evidence` later emits the merged copies under `<project>/_Consolidated/`. Truly shared root files (`integrations.yml`, `Evidence/run-log.yml`, `Evidence/contributors.yml`) still follow the read-modify-write contract in `multi-user-shared-files.instructions.md`.
43
43
 
44
44
  ## Inputs
45
45
 
@@ -134,7 +134,7 @@ Create the project folder structure (per `engagement-root-resolution.instruction
134
134
 
135
135
  The `State/` subtree is created **only on `full` profile**. On `standard`, only `Evidence/` is scaffolded. State files (when scaffolded) come from `templates/state/*.template.md`.
136
136
 
137
- **Pin hook (v4.5.0):** immediately after scaffold, per `onedrive-pin-policy.instructions.md`, extend the OneDrive pin set to cover the new folders — `<project>/integrations.yml`, `<project>/bootstrap-status.md` (after Step 7 writes it), `<project>/Evidence/<alias>/`, `<project>/Evidence/_Consolidated/` (when created), and `<project>/State/` (when scaffolded). Idempotent + additive — never unpins. Skips silently on Linux or when OneDrive isn't running. This keeps every contributor's own slice always-on-device while leaving other contributors' evidence cloud-only.
137
+ **Pin hook (v4.5.0, updated v5.4.4):** immediately after scaffold, per `onedrive-pin-policy.instructions.md`, extend the OneDrive pin set to cover the new folders — `<project>/integrations.yml`, `<project>/Evidence/<alias>/bootstrap-status.md` (after Step 7 writes it), `<project>/Evidence/<alias>/`, `<project>/Evidence/_Consolidated/` (when created), and `<project>/State/` (when scaffolded). Idempotent + additive — never unpins. Skips silently on Linux or when OneDrive isn't running. This keeps every contributor's own slice always-on-device while leaving other contributors' evidence cloud-only.
138
138
 
139
139
  ### Step 3.5 — Customer-hint discovery sweep (REQUIRED, kushi v4.8.0+)
140
140
 
@@ -183,7 +183,7 @@ Per `side-by-side-config.instructions.md` "Verification" rule, list all live con
183
183
  - Side-by-side config table (templates ↔ live files)
184
184
  - Per-source pull table (snapshot count + stream weeks covered + **gate status** [pass / retried-pass / failed-followups-written])
185
185
  - New Open Questions count
186
- - **Open follow-ups count** — if `<project>/FOLLOW-UPS.md` was appended to, surface the count and link to the file
186
+ - **Open follow-ups count** — if `<project>/Evidence/<alias>/FOLLOW-UPS.md` was appended to, surface the count and link to the file (the cross-contributor rollup lives at `<project>/_Consolidated/FOLLOW-UPS.md` after `consolidate-evidence` runs)
187
187
 
188
188
  End with a one-liner pointing at Q&A:
189
189
 
@@ -200,7 +200,7 @@ End with a one-liner pointing at Q&A:
200
200
  ## References (v4.4.7)
201
201
 
202
202
  - Name → ID resolution (any source) follows `..\..\instructions\fuzzy-disambiguation.instructions.md`.
203
- - After each per-source pull, run the gate per `..\..\instructions\per-source-verification-gate.instructions.md` (retry once → FOLLOW-UPS.md on failure).
203
+ - After each per-source pull, run the gate per `..\..\instructions\per-source-verification-gate.instructions.md` (retry once → `Evidence/<alias>/FOLLOW-UPS.md` on failure; consolidated to `_Consolidated/FOLLOW-UPS.md`).
204
204
 
205
205
 
206
206
  ## Issue Recovery