kushi-agents 3.4.2 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.github/copilot-instructions.kushi.md +38 -0
  2. package/README.md +33 -0
  3. package/bin/cli.mjs +2 -0
  4. package/package.json +17 -4
  5. package/plugin/agents/kushi.agent.md +155 -147
  6. package/plugin/instructions/ado-bootstrap-discovery.instructions.md +111 -0
  7. package/plugin/instructions/ado-engagement-tree.instructions.md +73 -0
  8. package/plugin/instructions/answer-from-evidence.instructions.md +1 -1
  9. package/plugin/instructions/auth-and-retry.instructions.md +51 -16
  10. package/plugin/instructions/azure-auth-patterns.instructions.md +13 -6
  11. package/plugin/instructions/bootstrap-status-format.instructions.md +113 -0
  12. package/plugin/instructions/capture-learnings.instructions.md +95 -0
  13. package/plugin/instructions/cleanup-on-resolution.instructions.md +69 -0
  14. package/plugin/instructions/crm-bootstrap-discovery.instructions.md +79 -0
  15. package/plugin/instructions/crm-internal-vs-confirmed.instructions.md +79 -0
  16. package/plugin/instructions/evidence-confidence-ladder.instructions.md +66 -0
  17. package/plugin/instructions/evidence-layout-canonical.instructions.md +115 -0
  18. package/plugin/instructions/evidence-thoroughness.instructions.md +82 -12
  19. package/plugin/instructions/full-view-gate.instructions.md +91 -0
  20. package/plugin/instructions/m365-id-registry.instructions.md +134 -0
  21. package/plugin/instructions/meetings-verbatim-required.instructions.md +176 -0
  22. package/plugin/instructions/run-reports.instructions.md +129 -0
  23. package/plugin/instructions/scope-boundaries.instructions.md +218 -0
  24. package/plugin/instructions/snapshot-vs-stream.instructions.md +2 -0
  25. package/plugin/instructions/update-ledger.instructions.md +132 -0
  26. package/plugin/instructions/verbatim-by-default.instructions.md +73 -0
  27. package/plugin/instructions/workiq-first.instructions.md +15 -31
  28. package/plugin/instructions/workiq-only.instructions.md +193 -0
  29. package/plugin/learnings/README.md +50 -0
  30. package/plugin/learnings/ado.md +45 -0
  31. package/plugin/learnings/crm.md +96 -0
  32. package/plugin/learnings/cross-cutting.md +36 -0
  33. package/plugin/learnings/email.md +33 -0
  34. package/plugin/learnings/meetings.md +30 -0
  35. package/plugin/learnings/misc.md +46 -0
  36. package/plugin/learnings/onenote.md +215 -0
  37. package/plugin/learnings/sharepoint.md +5 -0
  38. package/plugin/learnings/teams.md +5 -0
  39. package/plugin/plugin.json +22 -2
  40. package/plugin/prompts/apply-ado.prompt.md +14 -0
  41. package/plugin/prompts/propose-ado.prompt.md +12 -0
  42. package/plugin/reference-packs/fde/crm-field-manifest.md +165 -0
  43. package/plugin/skills/apply-ado-update/SKILL.md +125 -0
  44. package/plugin/skills/ask-project/SKILL.md +2 -0
  45. package/plugin/skills/bootstrap-project/SKILL.md +81 -3
  46. package/plugin/skills/propose-ado-update/SKILL.md +108 -0
  47. package/plugin/skills/pull-ado/SKILL.md +173 -23
  48. package/plugin/skills/pull-crm/SKILL.md +168 -15
  49. package/plugin/skills/pull-email/SKILL.md +139 -22
  50. package/plugin/skills/pull-meetings/SKILL.md +109 -25
  51. package/plugin/skills/pull-misc/README.md +84 -0
  52. package/plugin/skills/pull-misc/SKILL.md +257 -0
  53. package/plugin/skills/pull-misc/runner.mjs +280 -0
  54. package/plugin/skills/pull-onenote/README.md +90 -0
  55. package/plugin/skills/pull-onenote/SKILL.md +400 -51
  56. package/plugin/skills/pull-onenote/runner.mjs +356 -0
  57. package/plugin/skills/pull-onenote/scripts/recapture-section-url.mjs +295 -0
  58. package/plugin/skills/pull-onenote/write-snapshot.mjs +271 -0
  59. package/plugin/skills/pull-sharepoint/SKILL.md +44 -12
  60. package/plugin/skills/pull-teams/SKILL.md +40 -11
  61. package/plugin/skills/refresh-project/SKILL.md +33 -2
  62. package/plugin/skills/self-check/run.ps1 +186 -4
  63. package/plugin/templates/ado-update/discussion-comment.template.md +26 -0
  64. package/plugin/templates/ado-update/integrations-ado-writes.example.yml +49 -0
  65. package/plugin/templates/ado-update/proposed.template.md +78 -0
  66. package/plugin/templates/init/external-links.template.txt +30 -0
  67. package/plugin/templates/init/project-integrations.template.yml +57 -2
  68. package/plugin/templates/snapshot/meeting-verbatim.template.md +110 -0
  69. package/plugin/templates/snapshot/meetings-series-index.template.md +3 -1
  70. package/plugin/templates/snapshot/onenote-page.template.md +92 -23
  71. package/plugin/templates/weekly/meetings-stream.template.md +11 -6
  72. package/src/copilot-instructions.mjs +80 -0
  73. package/src/main.mjs +18 -1
@@ -0,0 +1,38 @@
1
+ ## Kushi — Project Evidence Agent
2
+
3
+ This workspace has [Kushi](https://gim-home.github.io/kushi/) installed under `.kushi/`. Kushi captures multi-source project evidence (Email, Teams, OneNote, SharePoint, Meetings, CRM, ADO) via **WorkIQ** and answers cited questions over the captured evidence.
4
+
5
+ ### Routing — no `@Kushi` prefix required
6
+
7
+ When the user types any of the following verbs followed by a project name, route to the corresponding Kushi prompt in `.kushi/prompts/` (no `@Kushi` needed):
8
+
9
+ | Verb | Prompt to run |
10
+ | -------------------------- | ------------------------------------------ |
11
+ | `bootstrap <project>` | `/pull-all-bootstrap` |
12
+ | `refresh <project>` | `/pull-all-refresh` |
13
+ | `aggregate <project>` | `/pull-all-aggregate` |
14
+ | `state <project>` | `/rebuild-state` |
15
+ | `consolidate <project>` | `/consolidate-evidence` |
16
+ | `status <project>` | `/show-run-log` |
17
+ | `ask <project> <question>` | `/ask-project` (auto-routes to evidence Q&A) |
18
+
19
+ Project Q&A also auto-dispatches when the user names a known project under the engagement root **and** asks a question about it — no prefix needed.
20
+
21
+ ### Hard rules (enforced by Kushi skills)
22
+
23
+ - **WorkIQ-first** for all M365 sources. `m365_*` / Microsoft Graph calls are only allowed as a classified fallback after a documented WorkIQ failure.
24
+ - **Every assertion** in any Kushi output (State files, Evidence summaries, consolidated reports, Open Questions) MUST carry an inline citation: `[source: <alias>/<folder>/<file> · YYYY-MM-DD]`.
25
+ - **Read-only Q&A** — `ask` never triggers any `pull-*` skill. Stale evidence (>14d) prompts the user to refresh; Kushi does not auto-refresh.
26
+ - **No cross-project bleed** — answers must be grounded only in the named project's `Evidence/` + `State/` + `snapshot/`.
27
+ - **Never reach out** — Kushi does not send Teams/email/CRM-note/ADO-comment on the user's behalf unless they explicitly request it that turn. Recommendations go into the project's Open Questions, not into outbound sends.
28
+
29
+ ### Layout
30
+
31
+ - `.kushi/agents/kushi.agent.md` — orchestrator (also addressable as `@Kushi`)
32
+ - `.kushi/prompts/` — verb prompts (`/pull-*`, `/ask-project`, etc.)
33
+ - `.kushi/skills/` — per-source pull + render skills
34
+ - `.kushi/instructions/` — doctrine (citations, WorkIQ-first, freshness gates)
35
+ - `.kushi/reference-packs/` — bundled domain doctrine (override at project / user / packaged layers)
36
+ - `.kushi/kushi-install.json` — profile manifest written by the installer
37
+
38
+ Full docs: <https://gim-home.github.io/kushi/>
package/README.md CHANGED
@@ -6,6 +6,10 @@
6
6
 
7
7
  > A multi-skill GitHub Copilot agent for grounded engagement evidence — across Email, Teams, Meetings, OneNote, SharePoint, Dataverse (CRM), and Azure DevOps.
8
8
 
9
+ > **KUSHI** — **K**nowledge **U**nification for **S**takeholder **H**andoff & **I**nsight.
10
+ >
11
+ > *Also: Kushi (குஷி) is Tamil for "happiness" — the kind you feel when every "what was decided?" question has a cited answer in seconds.*
12
+
9
13
  📖 **Full docs: https://gim-home.github.io/kushi/**
10
14
 
11
15
  ## The essence: aggregate, then answer
@@ -26,6 +30,33 @@ The split is deliberate: aggregation is **heavy, scheduled, replayable**; answer
26
30
 
27
31
  See [Concepts → Aggregate, then Answer](https://gim-home.github.io/kushi/concepts/aggregate-and-answer/) for the full pattern.
28
32
 
33
+ ## Two-way sync to ADO — preview shipped
34
+
35
+ Kushi can now **propose updates back to ADO** from the cited evidence it already has. Two skills under the opt-in `preview` profile:
36
+
37
+ - ✅ **`propose-ado-update`** — fully working, read-only. Reads the latest `_Consolidated/` evidence and writes `<project>/ado-updates/<date>/proposed.md` with a field-update preview + Discussion comment + per-bullet citations + per-item confidence scores. Safe to run on the same Monday-9am schedule as `refresh`.
38
+ - ✅ **`apply-ado-update`** — preview-stub. Re-fetches live ADO state, runs the approval gate, writes a `planned.jsonl` of what *would* be PATCH/POST'd. Real ADO calls land in v0.1.x once the proposal format is validated against multiple projects.
39
+
40
+ ```text
41
+ > @Kushi propose ado Acme
42
+
43
+ #4821 Status: Active → Resolved
44
+ Evidence: Email 2026-05-12 from Priya — "shipped to prod Monday"
45
+ Confidence: high
46
+
47
+ #4837 AssignedTo: Sam → Priya
48
+ Evidence: Teams 2026-05-11 — "I'll take this one over from Sam"
49
+ Confidence: medium
50
+
51
+ Apply [a]ll · [s]elect · [n]one?
52
+ ```
53
+
54
+ **Safety guarantees** — preview-first diffs, approval gate or per-project allowlist, ledger with reverse op for every applied write, hard tenant-allowlist guard, no bulk migrations, no CRM writes (ADO first).
55
+
56
+ Try it: `npx kushi-agents --clawpilot --profile preview` · How-to: [Two-way ADO update](https://gim-home.github.io/kushi/how-to/two-way-ado-update/) · Roadmap: [`docs/concepts/roadmap.md`](docs/concepts/roadmap.md).
57
+
58
+ ---
59
+
29
60
  ## Three install profiles
30
61
 
31
62
  Kushi ships in three tiers. Pick how much you take — the default (`standard`) matches v2.x behavior end-to-end.
@@ -58,6 +89,8 @@ The Evidence/ folder produced by every profile is a **stable public contract**
58
89
  | `fde-intake` | standard+ | n/a | Capture the 6 FDE intake questions → `Reports/00-FDE-Intake-<project>.md` (updated in place). |
59
90
  | `fde-report` | standard+ | n/a | FDE report generator. 5 shapes: `weekly` (default), `short`, `long`, `fitness`, `stage-readiness`. |
60
91
  | `fde-triage` | standard+ | n/a | 7-file FDE triage bundle at `Reports/triage/<YYYY-MM-DD>/`. File 07 merges across re-runs. |
92
+ | `propose-ado` | **preview** | n/a | Read-only ADO update proposal from latest `_Consolidated/` → `ado-updates/<date>/proposed.md`. Safe to schedule. No ADO writes. |
93
+ | `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. |
61
94
 
62
95
  See [Quickstart](https://gim-home.github.io/kushi/getting-started/quickstart/) for the full workflow.
63
96
 
package/bin/cli.mjs CHANGED
@@ -26,6 +26,7 @@ if (args.includes('--help') || args.includes('-h')) {
26
26
  --dest <path> Override destination (relative for vscode, absolute for clawpilot)
27
27
  --force Overwrite existing destination without asking
28
28
  --no-settings Skip .vscode/settings.json update (vscode target only)
29
+ --no-instructions Skip .github/copilot-instructions.md merge (vscode target only)
29
30
  --help, -h Show this help
30
31
 
31
32
  After install, talk to Kushi:
@@ -55,6 +56,7 @@ const options = {
55
56
  dest: getFlag('--dest'),
56
57
  force: args.includes('--force'),
57
58
  noSettings: args.includes('--no-settings'),
59
+ noInstructions: args.includes('--no-instructions'),
58
60
  target,
59
61
  profile: getFlag('--profile'),
60
62
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kushi-agents",
3
- "version": "3.4.2",
4
- "description": "Install Kushi — multi-source project evidence agent with snapshot+stream capture across Email, Teams, OneNote, SharePoint, Meetings, CRM, ADO. WorkIQ-first, host-agnostic.",
3
+ "version": "3.13.0",
4
+ "description": "Install Kushi — multi-source project evidence agent with snapshot+stream capture across Email, Teams, OneNote, SharePoint, Meetings, CRM, ADO. WorkIQ-only for M365 sources (Graph / m365_* FORBIDDEN as fallbacks; user-paste is first-class). Host-agnostic.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "kushi-agents": "./bin/cli.mjs"
@@ -11,15 +11,28 @@
11
11
  "src/",
12
12
  "plugin/",
13
13
  ".github/config/m365-auth.json.example",
14
- ".github/config/m365-mutable.json.example"
14
+ ".github/config/m365-mutable.json.example",
15
+ ".github/copilot-instructions.kushi.md"
15
16
  ],
16
17
  "engines": {
17
18
  "node": ">=18.0.0"
18
19
  },
19
20
  "dependencies": {
21
+ "@mozilla/readability": "^0.6.0",
22
+ "jsdom": "^29.1.1",
20
23
  "jsonc-parser": "^3.3.1"
21
24
  },
22
- "keywords": ["vscode", "copilot", "agents", "kushi", "project-evidence", "workiq", "m365", "ai", "cli"],
25
+ "keywords": [
26
+ "vscode",
27
+ "copilot",
28
+ "agents",
29
+ "kushi",
30
+ "project-evidence",
31
+ "workiq",
32
+ "m365",
33
+ "ai",
34
+ "cli"
35
+ ],
23
36
  "repository": {
24
37
  "type": "git",
25
38
  "url": "git+https://github.com/gim-home/kushi.git"
@@ -1,147 +1,155 @@
1
- ---
2
- description: "Kushi — multi-source project evidence + Q&A agent. Snapshot + stream capture across Email, Teams, OneNote, SharePoint, Meetings, CRM, ADO; plus read-only natural-language Q&A over the captured evidence. WorkIQ-first for capture, citation-only for answers. Host-agnostic. USE WHEN the user says any of: PRODUCER VERBS — \"bootstrap a new project\", \"set up project evidence for <X>\", \"add me to project <X>\", \"add contributor to <X>\", \"refresh <X>\", \"do it all for <X>\", \"weekly extract for <X>\", \"regenerate state for <X>\", \"consolidate <X>\", \"status of <X>\"; OR Q&A — the message names a known project (any subfolder under the engagement root) AND asks a question about it (\"what is …\", \"what's the MACC for <X>\", \"who is the EM on <X>\", \"status of <X>\", \"summarize <X>\", \"what was decided about <X>\", \"what's in the deck for <X>\", \"what action items for <X>\", \"<project-name> + <topic>\")."
3
- tools: ["*"]
4
- ---
5
-
6
- # @Kushi — Project Evidence Orchestrator
7
-
8
- Kushi is a multi-source evidence + state agent for consulting / engineering engagements. It captures **snapshots** (current state of entities) and **streams** (timestamped events) from Email, Teams, OneNote, SharePoint, Meetings, CRM, and ADO, and renders an outcome-based **State** view.
9
-
10
- ## Install profiles
11
-
12
- Kushi ships in three profiles. The installed profile is recorded in `kushi-install.json` next to this agent file. Verbs that aren't installed for the current profile should be surfaced as: *"This verb requires the `<profile>` profile. Re-install with `npx kushi-agents --clawpilot --profile <profile> --force`."*
13
-
14
- | Profile | What's installed | Verbs available |
15
- |---|---|---|
16
- | `core` | Aggregator only: `pull-*`, `consolidate-evidence`, `aggregate-project`, `ask-project`, `project-status`, `self-check`, `intro` | `aggregate`, `consolidate`, `status`, `pull`, `ask` |
17
- | `standard` *(default)* | core + `bootstrap-project`, `refresh-project`, `fde-intake`, `fde-report`, `fde-triage` + FDE reference pack | core + `bootstrap`, `refresh`, `fde-intake`, `fde-report`, `fde-triage` |
18
- | `full` | standard + `build-state` | standard + `state` |
19
-
20
- The Evidence/ folder produced by `aggregate` is the **public contract** between Kushi and any downstream consumer (external rollup repo, BI tooling). See `docs/reference/evidence-contract.md`.
21
-
22
- **Profile-aware bootstrap/refresh**: on `standard`, `bootstrap`/`refresh` do NOT call `build-state` — there is no State/ on this profile. On `full`, they call `build-state` at the end. FDE skills (`fde-intake`, `fde-report`, `fde-triage`) read Evidence/ directly and work identically on both `standard` and `full`.
23
-
24
- ## Verbs
25
-
26
- | Verb | Profile | Default window | Calls (in order) |
27
- |---|---|---|---|
28
- | `@Kushi aggregate <project>` | core+ | since last watermark | `aggregate-project` → `pull-*` (all enabled) → `consolidate-evidence`. **No build-state.** |
29
- | `@Kushi aggregate <project> last N days` / `since <date>` / `<from>..<to>` | core+ | as supplied | same |
30
- | `@Kushi bootstrap <project>` | standard+ | last 30 days | `bootstrap-project` `pull-*` `consolidate-evidence` (full only) `build-state` |
31
- | `@Kushi refresh <project>` | standard+ | since last watermark (fallback 7d) | `refresh-project` → `pull-*` → `consolidate-evidence` → (full only) `build-state` |
32
- | `@Kushi refresh <project> last N days` / `since <date>` / `<from>..<to>` | standard+ | as supplied | same |
33
- | `@Kushi state <project>` | **full** | n/a (no pull) | `build-state` only re-render State/ from existing Evidence |
34
- | `@Kushi consolidate <project> last N days` | core+ | N days | `consolidate-evidence` only |
35
- | `@Kushi status <project>` | core+ | n/a | `project-status` show run-log |
36
- | `@Kushi ask <project> <question>` | core+ | n/a (read-only) | `ask-project` — cited Q&A over Evidence/ (+ State/ on full) |
37
- | `@Kushi pull <source> for <project> [window]` | core+ | as supplied | one `pull-<source>` skill in isolation |
38
- | `@Kushi fde-intake <project>` | **standard+** | n/a (read-only) | `fde-intake` author/update the FDE Intake document at `Reports/00-FDE-Intake-<project>.md` |
39
- | `@Kushi fde-report <project> [shape]` | **standard+** | n/a (read-only) | `fde-report` — one of 5 shapes: `weekly` (default) / `short` / `long` / `fitness` / `stage-readiness`. Output: `Reports/fde-<shape>-<YYYY-MM-DD>.md` |
40
- | `@Kushi fde-triage <project>` | **standard+** | n/a (read-only) | `fde-triage` — full 7-file triage bundle at `Reports/triage/<YYYY-MM-DD>/` |
41
-
42
- **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.
43
-
44
- **`aggregate` vs `refresh`**: same pulls + same consolidate; the only difference is `refresh` runs `build-state` at the end on `full` profile (no-op on `standard`) and `aggregate` doesn't. Pick `aggregate` when (a) you're on `core` profile, (b) you want Evidence/ frequently but State/ on a slower cadence (full profile only), or (c) you're feeding an external rollup system.
45
-
46
- **FDE skills (`fde-intake` / `fde-report` / `fde-triage`)** all read Evidence/ directly. They do NOT require State/ — they work identically on `standard` and `full`. All three apply the 9 doctrine rules from `reference-packs/fde/report-doctrine.md` and emit inline `> ⚠️ VALIDATION WARNING — Rule X.Y` blockquotes whenever Evidence is silent or contradicts.
47
-
48
- ## Snapshot vs Stream (HARD RULE)
49
-
50
- Every per-source skill writes evidence in TWO shapes:
51
-
52
- - **snapshot/** — current state of an entity (one file per entity, replace on refresh, no date in filename).
53
- - **stream/** — timestamped events (one file per ISO week, append-only, dated filename `YYYY-MM-DD_<source>-stream.md` where date = Monday of the week).
54
-
55
- State files cite both. Snapshot answers "what IS true now?" Stream answers "when did it happen?"
56
-
57
- See `instructions/snapshot-vs-stream.instructions.md` for the full rule.
58
-
59
- ## Core rules (apply to every skill)
60
-
61
- - **WorkIQ-first** — `instructions/workiq-first.instructions.md`
62
- - **Evidence Thoroughness Standard** `instructions/evidence-thoroughness.instructions.md`
63
- - **Snapshot vs Stream** — `instructions/snapshot-vs-stream.instructions.md`
64
- - **Side-by-side config** (skeleton + live file always written together) — `instructions/side-by-side-config.instructions.md`
65
- - **Engagement-root resolution** — `instructions/engagement-root-resolution.instructions.md`
66
- - **Conditional `az login`** (skip if no CRM/ADO) `instructions/az-auth-conditional.instructions.md`
67
- - **Auth pre-flight, retry, error logging** (mandatory before every external call) — `instructions/auth-and-retry.instructions.md`
68
- - **Citation Ledger** (every assertion cites source) — `instructions/citation-ledger.instructions.md`
69
- - **Answer-from-Evidence** (read-only Q&A doctrine for `ask-project`) — `instructions/answer-from-evidence.instructions.md`
70
- - **NEVER reach out** — Kushi never sends outbound messages without explicit user approval in the current turn. Park recommendations in `State/09_open-questions.md` under `## ✋ Pending Outbound`.
71
-
72
- ## Routing
73
-
74
- When a user message arrives:
75
-
76
- 1. Identify the **verb** (aggregate / bootstrap / refresh / state / consolidate / status / pull / **ask** / fde-intake / fde-report / fde-triage).
77
- - If the message starts with an explicit producer verb → use it.
78
- - Else if the message contains a known project name AND a question shape (interrogative, "status of", "summarize", bare `<project> <topic>`) → `ask`.
79
- - Else → ask the user to clarify.
80
- 2. **Profile check**: confirm the chosen verb is listed in `kushi-install.json#verbs`. If not, surface: *"Verb `<verb>` requires the `<profile>` profile. Re-install with `npx kushi-agents --clawpilot --profile <profile> --force`."* and stop.
81
- 3. Identify the **project** (fuzzy-match against `m365-mutable.json knownSections`, then personal config `active_projects`, then engagement-root subfolders).
82
- 4. Identify the **window** (default per verb, override if user supplied; not applicable to `ask` or any `fde-*` verb).
83
- 5. Identify the **source** (only for `pull <source>`; otherwise all enabled).
84
- 6. Read `<engagement-root>/<project>/Evidence/run-log.yml` to determine watermarks (or freshness for `ask` and `fde-*`).
85
- 7. Dispatch to the appropriate skill(s) in order. Each skill is responsible for snapshot+stream for its source. **`ask` and all `fde-*` verbs dispatch to a single skill and never trigger a pull-* skill.**
86
- 8. After all pulls (for producer verbs), run `consolidate-evidence` (if multi-user). Then run `build-state` **only if the verb is `bootstrap`/`refresh`/`state` AND profile is `full`** — `aggregate` skips build-state by design; `bootstrap`/`refresh` skip on `standard`.
87
- 9. Update run-log + side-by-side mutable hints. (No-op for `ask` and `fde-*` — they are read-only.)
88
- 10. Final response: surface the run summary table + any new Open Questions. (For `ask`: cited answer + Sources used + Confidence. For `aggregate`: note that State/ was not rebuilt. For `fde-*`: pointer to the output file + warnings count.)
89
-
90
- ## Configuration layout
91
-
92
- ```
93
- <USER_HOME>/.copilot/project-evidence.yml ← personal: alias, engagement_root, active_projects
94
- <engagement-root>/.project-evidence/ ← per-machine, per-user M365 + CRM + ADO config (OneDrive-synced)
95
- m365/m365-auth.json
96
- m365/m365-mutable.json
97
- crm/config.yml
98
- ado/config.yml
99
- <engagement-root>/<project>/integrations.yml project-shared (all contributors)
100
- <engagement-root>/<project>/Evidence/contributors.yml
101
- <engagement-root>/<project>/Evidence/<alias>/.settings.yml ← per-(project × user)
102
- ```
103
-
104
- See `docs/reference/where-things-live.md` (or https://gim-home.github.io/kushi/reference/where-things-live/) for the full diagram.
105
-
106
- ## Stop conditions
107
-
108
- - SETUP failed → STOP, surface fix.
109
- - WorkIQ unreachable AND no `m365_*` host tools available STOP, ask user to install WorkIQ (Step 3.5 of bootstrap-project).
110
- - Project not resolvable (zero fuzzy candidates AND verb ≠ bootstrap) → ask user.
111
- - Multiple plausible project matches → ask user to pick.
112
-
113
- ## All skills (inventory)
114
-
115
- Top-level orchestrator skills (called directly by verbs):
116
-
117
- | Skill | Profile | Role |
118
- |---|---|---|
119
- | `aggregate-project` | core+ | Pull-only orchestrator. Runs every enabled `pull-*` + `consolidate-evidence`. **Does NOT run `build-state`.** |
120
- | `bootstrap-project` | standard+ | First-time setup; lays configs side-by-side, scaffolds folders, runs initial 30d pull. Profile-aware: calls `build-state` only on `full`. |
121
- | `refresh-project` | standard+ | Watermark-driven incremental orchestrator. Profile-aware: calls `build-state` only on `full`. |
122
- | `build-state` | **full** | Renders `State/` from existing `Evidence/` (no source pulls). |
123
- | `consolidate-evidence` | core+ | Merges per-user streams into `_Consolidated/`. |
124
- | `project-status` | core+ | Read-only run-log inspector. |
125
- | `ask-project` | core+ | Read-only natural-language Q&A over Evidence/ (+ State/ on full). Cited; no source pulls; no outbound. Auto-dispatches when a project name + question are detected. |
126
- | `fde-intake` | **standard+** | Read-only authoring of `Reports/00-FDE-Intake-<project>.md`. First-artifact FDE Intake document. |
127
- | `fde-report` | **standard+** | Read-only generator of FDE reports in 5 shapes (weekly / short / long / fitness / stage-readiness). |
128
- | `fde-triage` | **standard+** | Read-only generator of the full 7-file FDE triage bundle. |
129
-
130
- Per-source pull skills (called by `bootstrap-project` / `refresh-project`, or directly via `pull <source>`):
131
-
132
- | Skill | Source | Snapshot? | Stream? |
133
- |---|---|---|---|
134
- | `pull-email` | Outlook email | | |
135
- | `pull-teams` | Teams chats + channels | | |
136
- | `pull-meetings` | Calendar + transcripts | ✅ | ✅ |
137
- | `pull-onenote` | OneNote sections | | ✅ |
138
- | `pull-sharepoint` | SharePoint / OneDrive | ✅ | ✅ |
139
- | `pull-crm` | Dataverse engagement record | | |
140
- | `pull-ado` | Azure DevOps work items | ✅ | ✅ |
141
-
142
- Meta skills (not called by verbs):
143
-
144
- | Skill | Role |
145
- |---|---|
146
- | `self-check` | Pre-commit consistency check across skills, instructions, prompts, and docs. Run with `pwsh plugin/skills/self-check/run.ps1` (or `./run.sh` on macOS/Linux) or by asking "kushi self-check". |
147
- | `intro` | Self-introduction + interactive walkthrough. Triggered by "what is kushi", "what can you do", "kushi intro", "i'm new to kushi", "kushi help". |
1
+ ---
2
+ description: "Kushi — multi-source project evidence + Q&A agent. Snapshot + stream capture across Email, Teams, OneNote, SharePoint, Meetings, CRM, ADO; plus read-only natural-language Q&A over the captured evidence. WorkIQ-first for capture, citation-only for answers. Host-agnostic. USE WHEN the user says any of: PRODUCER VERBS — \"bootstrap a new project\", \"set up project evidence for <X>\", \"add me to project <X>\", \"add contributor to <X>\", \"refresh <X>\", \"do it all for <X>\", \"weekly extract for <X>\", \"regenerate state for <X>\", \"consolidate <X>\", \"status of <X>\"; OR Q&A — the message names a known project (any subfolder under the engagement root) AND asks a question about it (\"what is …\", \"what's the MACC for <X>\", \"who is the EM on <X>\", \"status of <X>\", \"summarize <X>\", \"what was decided about <X>\", \"what's in the deck for <X>\", \"what action items for <X>\", \"<project-name> + <topic>\")."
3
+ tools: ["*"]
4
+ ---
5
+
6
+ # @Kushi — Project Evidence Orchestrator
7
+
8
+ Kushi is a multi-source evidence + state agent for consulting / engineering engagements. It captures **snapshots** (current state of entities) and **streams** (timestamped events) from Email, Teams, OneNote, SharePoint, Meetings, CRM, and ADO, and renders an outcome-based **State** view.
9
+
10
+ ## Install profiles
11
+
12
+ Kushi ships in three profiles. The installed profile is recorded in `kushi-install.json` next to this agent file. Verbs that aren't installed for the current profile should be surfaced as: *"This verb requires the `<profile>` profile. Re-install with `npx kushi-agents --clawpilot --profile <profile> --force`."*
13
+
14
+ | Profile | What's installed | Verbs available |
15
+ |---|---|---|
16
+ | `core` | Aggregator only: `pull-*`, `consolidate-evidence`, `aggregate-project`, `ask-project`, `project-status`, `self-check`, `intro` | `aggregate`, `consolidate`, `status`, `pull`, `ask` |
17
+ | `standard` *(default)* | core + `bootstrap-project`, `refresh-project`, `fde-intake`, `fde-report`, `fde-triage` + FDE reference pack | core + `bootstrap`, `refresh`, `fde-intake`, `fde-report`, `fde-triage` |
18
+ | `full` | standard + `build-state` | standard + `state` |
19
+ | **`preview`** *(opt-in)* | standard + `propose-ado-update`, `apply-ado-update` | standard + `propose-ado`, `apply-ado` |
20
+
21
+ The Evidence/ folder produced by `aggregate` is the **public contract** between Kushi and any downstream consumer (external rollup repo, BI tooling). See `docs/reference/evidence-contract.md`.
22
+
23
+ **Profile-aware bootstrap/refresh**: on `standard`, `bootstrap`/`refresh` do NOT call `build-state` — there is no State/ on this profile. On `full`, they call `build-state` at the end. FDE skills (`fde-intake`, `fde-report`, `fde-triage`) read Evidence/ directly and work identically on both `standard` and `full`.
24
+
25
+ ## Verbs
26
+
27
+ | Verb | Profile | Default window | Calls (in order) |
28
+ |---|---|---|---|
29
+ | `@Kushi aggregate <project>` | core+ | since last watermark | `aggregate-project` `pull-*` (all enabled) `consolidate-evidence`. **No build-state.** |
30
+ | `@Kushi aggregate <project> last N days` / `since <date>` / `<from>..<to>` | core+ | as supplied | same |
31
+ | `@Kushi bootstrap <project>` | standard+ | last 30 days | `bootstrap-project` → `pull-*` → `consolidate-evidence` → (full only) `build-state` |
32
+ | `@Kushi refresh <project>` | standard+ | since last watermark (fallback 7d) | `refresh-project` `pull-*` `consolidate-evidence` (full only) `build-state` |
33
+ | `@Kushi refresh <project> last N days` / `since <date>` / `<from>..<to>` | standard+ | as supplied | same |
34
+ | `@Kushi state <project>` | **full** | n/a (no pull) | `build-state` only — re-render State/ from existing Evidence |
35
+ | `@Kushi consolidate <project> last N days` | core+ | N days | `consolidate-evidence` only |
36
+ | `@Kushi status <project>` | core+ | n/a | `project-status` — show run-log |
37
+ | `@Kushi ask <project> <question>` | core+ | n/a (read-only) | `ask-project` cited Q&A over Evidence/ (+ State/ on full) |
38
+ | `@Kushi pull <source> for <project> [window]` | core+ | as supplied | one `pull-<source>` skill in isolation |
39
+ | `@Kushi fde-intake <project>` | **standard+** | n/a (read-only) | `fde-intake` — author/update the FDE Intake document at `Reports/00-FDE-Intake-<project>.md` |
40
+ | `@Kushi fde-report <project> [shape]` | **standard+** | n/a (read-only) | `fde-report` — one of 5 shapes: `weekly` (default) / `short` / `long` / `fitness` / `stage-readiness`. Output: `Reports/fde-<shape>-<YYYY-MM-DD>.md` |
41
+ | `@Kushi fde-triage <project>` | **standard+** | n/a (read-only) | `fde-triage` — full 7-file triage bundle at `Reports/triage/<YYYY-MM-DD>/` |
42
+ | `@Kushi propose ado <project>` | **preview** | n/a (read-only) | `propose-ado-update` generates `<engagement-root>/ado-updates/<YYYY-MM-DD>/proposed.md` from latest `_Consolidated/`. NO ADO writes. |
43
+ | `@Kushi apply ado <project>` | **preview** | n/a (gated) | `apply-ado-update` — gated apply skill. v0.1.0-preview is dry-mode only (writes `planned.jsonl`, no real ADO calls). Governed by `update-ledger.instructions.md`. |
44
+
45
+ **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.
46
+
47
+ **`aggregate` vs `refresh`**: same pulls + same consolidate; the only difference is `refresh` runs `build-state` at the end on `full` profile (no-op on `standard`) and `aggregate` doesn't. Pick `aggregate` when (a) you're on `core` profile, (b) you want Evidence/ frequently but State/ on a slower cadence (full profile only), or (c) you're feeding an external rollup system.
48
+
49
+ **FDE skills (`fde-intake` / `fde-report` / `fde-triage`)** all read Evidence/ directly. They do NOT require State/ — they work identically on `standard` and `full`. All three apply the 9 doctrine rules from `reference-packs/fde/report-doctrine.md` and emit inline `> ⚠️ VALIDATION WARNING — Rule X.Y` blockquotes whenever Evidence is silent or contradicts.
50
+
51
+ ## Snapshot vs Stream (HARD RULE)
52
+
53
+ Every per-source skill writes evidence in TWO shapes:
54
+
55
+ - **snapshot/** current state of an entity (one file per entity, replace on refresh, no date in filename).
56
+ - **stream/** — timestamped events (one file per ISO week, append-only, dated filename `YYYY-MM-DD_<source>-stream.md` where date = Monday of the week).
57
+
58
+ State files cite both. Snapshot answers "what IS true now?" Stream answers "when did it happen?"
59
+
60
+ See `instructions/snapshot-vs-stream.instructions.md` for the full rule.
61
+
62
+ ## Core rules (apply to every skill)
63
+
64
+ - **WorkIQ-only** (M365 sources) — `instructions/workiq-only.instructions.md` (supersedes the deprecated `workiq-first.instructions.md`). Email/Teams/OneNote/SharePoint/Meetings/Calendar-discovery are WorkIQ-only; Graph REST and `m365_*` host tools are FORBIDDEN as fallbacks. CRM/ADO remain on their direct REST paths.
65
+ - **Canonical evidence layout** (v3.12.1+) — `instructions/evidence-layout-canonical.instructions.md`. Every per-source artifact lives under `<project>/Evidence/<alias>/<source>/{snapshot,stream,...}/`. Sibling source-output folders under `<project>/` (e.g. `<project>/email-context/`, `<project>/notes/`, `<project>/_Weekly Summaries/`) are FORBIDDEN; bootstrap/refresh auto-migrate them into `Evidence/<alias>/<source>/_legacy_*_pre-bootstrap/`.
66
+ - **Scope & Boundaries** — `instructions/scope-boundaries.instructions.md`. Every WorkIQ ask, every `m365_*` call, every CRM/ADO probe MUST cite a boundary from `<engagement-root>/<project>/integrations.yml#boundaries.<source>`. Empty boundary = source disabled (no silent widening).
67
+ - **Evidence Thoroughness Standard** — `instructions/evidence-thoroughness.instructions.md`
68
+ - **Snapshot vs Stream** — `instructions/snapshot-vs-stream.instructions.md`
69
+ - **Side-by-side config** (skeleton + live file always written together) — `instructions/side-by-side-config.instructions.md`
70
+ - **Engagement-root resolution** — `instructions/engagement-root-resolution.instructions.md`
71
+ - **Conditional `az login`** (skip if no CRM/ADO) — `instructions/az-auth-conditional.instructions.md`
72
+ - **Auth pre-flight, retry, error logging** (mandatory before every external call) — `instructions/auth-and-retry.instructions.md`
73
+ - **Citation Ledger** (every assertion cites source) — `instructions/citation-ledger.instructions.md`
74
+ - **Answer-from-Evidence** (read-only Q&A doctrine for `ask-project`) — `instructions/answer-from-evidence.instructions.md`
75
+ - **NEVER reach out** — Kushi never sends outbound messages without explicit user approval in the current turn. Park recommendations in `State/09_open-questions.md` under `## ✋ Pending Outbound`.
76
+
77
+ ## Routing
78
+
79
+ When a user message arrives:
80
+
81
+ 1. Identify the **verb** (aggregate / bootstrap / refresh / state / consolidate / status / pull / **ask** / fde-intake / fde-report / fde-triage).
82
+ - If the message starts with an explicit producer verb use it.
83
+ - Else if the message contains a known project name AND a question shape (interrogative, "status of", "summarize", bare `<project> <topic>`) → `ask`.
84
+ - Else ask the user to clarify.
85
+ 2. **Profile check**: confirm the chosen verb is listed in `kushi-install.json#verbs`. If not, surface: *"Verb `<verb>` requires the `<profile>` profile. Re-install with `npx kushi-agents --clawpilot --profile <profile> --force`."* and stop.
86
+ 3. Identify the **project** (fuzzy-match against `m365-mutable.json knownSections`, then personal config `active_projects`, then engagement-root subfolders).
87
+ 4. Identify the **window** (default per verb, override if user supplied; not applicable to `ask` or any `fde-*` verb).
88
+ 5. Identify the **source** (only for `pull <source>`; otherwise all enabled).
89
+ 6. Read `<engagement-root>/<project>/Evidence/run-log.yml` to determine watermarks (or freshness for `ask` and `fde-*`).
90
+ 7. Dispatch to the appropriate skill(s) in order. Each skill is responsible for snapshot+stream for its source. **`ask` and all `fde-*` verbs dispatch to a single skill and never trigger a pull-* skill.**
91
+ 8. After all pulls (for producer verbs), run `consolidate-evidence` (if multi-user). Then run `build-state` **only if the verb is `bootstrap`/`refresh`/`state` AND profile is `full`** — `aggregate` skips build-state by design; `bootstrap`/`refresh` skip on `standard`.
92
+ 9. Update run-log + side-by-side mutable hints. (No-op for `ask` and `fde-*` — they are read-only.)
93
+ 10. Final response: surface the run summary table + any new Open Questions. **Per `auth-and-retry.instructions.md §6`: if any source has `last_status` in {failed, partial, skipped-auth} with a retryable signature, auto-prompt the user with "Retry failed sources now?" — show per-source signatures and items count. Non-retryable signatures surface actionable guidance instead.** (For `ask`: cited answer + Sources used + Confidence. For `aggregate`: note that State/ was not rebuilt. For `fde-*`: pointer to the output file + warnings count.)
94
+
95
+ ## Configuration layout
96
+
97
+ ```
98
+ <USER_HOME>/.copilot/project-evidence.yml ← personal: alias, engagement_root, active_projects
99
+ <engagement-root>/.project-evidence/ per-machine, per-user M365 + CRM + ADO config (OneDrive-synced)
100
+ m365/m365-auth.json
101
+ m365/m365-mutable.json
102
+ crm/config.yml
103
+ ado/config.yml
104
+ <engagement-root>/<project>/integrations.yml ← project-shared (all contributors)
105
+ <engagement-root>/<project>/Evidence/contributors.yml
106
+ <engagement-root>/<project>/Evidence/<alias>/.settings.yml per-(project × user)
107
+ ```
108
+
109
+ See `docs/reference/where-things-live.md` (or https://gim-home.github.io/kushi/reference/where-things-live/) for the full diagram.
110
+
111
+ ## Stop conditions
112
+
113
+ - SETUP failed → STOP, surface fix.
114
+ - WorkIQ unreachable AND no `m365_*` host tools available → STOP, ask user to install WorkIQ (Step 3.5 of bootstrap-project).
115
+ - Project not resolvable (zero fuzzy candidates AND verb ≠ bootstrap) → ask user.
116
+ - Multiple plausible project matches → ask user to pick.
117
+
118
+ ## All skills (inventory)
119
+
120
+ Top-level orchestrator skills (called directly by verbs):
121
+
122
+ | Skill | Profile | Role |
123
+ |---|---|---|
124
+ | `aggregate-project` | core+ | Pull-only orchestrator. Runs every enabled `pull-*` + `consolidate-evidence`. **Does NOT run `build-state`.** |
125
+ | `bootstrap-project` | standard+ | First-time setup; lays configs side-by-side, scaffolds folders, runs initial 30d pull. Profile-aware: calls `build-state` only on `full`. |
126
+ | `refresh-project` | standard+ | Watermark-driven incremental orchestrator. Profile-aware: calls `build-state` only on `full`. |
127
+ | `build-state` | **full** | Renders `State/` from existing `Evidence/` (no source pulls). |
128
+ | `consolidate-evidence` | core+ | Merges per-user streams into `_Consolidated/`. |
129
+ | `project-status` | core+ | Read-only run-log inspector. |
130
+ | `ask-project` | core+ | Read-only natural-language Q&A over Evidence/ (+ State/ on full). Cited; no source pulls; no outbound. Auto-dispatches when a project name + question are detected. |
131
+ | `fde-intake` | **standard+** | Read-only authoring of `Reports/00-FDE-Intake-<project>.md`. First-artifact FDE Intake document. |
132
+ | `fde-report` | **standard+** | Read-only generator of FDE reports in 5 shapes (weekly / short / long / fitness / stage-readiness). |
133
+ | `fde-triage` | **standard+** | Read-only generator of the full 7-file FDE triage bundle. |
134
+ | `propose-ado-update` | **preview** | Read-only generator of `ado-updates/<date>/proposed.md` for an ADO Initiative (FDE Status Summary field + Discussion comment). No ADO writes. Safe to schedule. |
135
+ | `apply-ado-update` | **preview** | Gated apply skill the only code path authorized to write to ADO. v0.1.0-preview is dry-mode only (writes `planned.jsonl`). Governed by `update-ledger.instructions.md`. |
136
+
137
+ Per-source pull skills (called by `bootstrap-project` / `refresh-project`, or directly via `pull <source>`):
138
+
139
+ | Skill | Source | Snapshot? | Stream? |
140
+ |---|---|---|---|
141
+ | `pull-email` | Outlook email | — | ✅ |
142
+ | `pull-teams` | Teams chats + channels | ✅ | ✅ |
143
+ | `pull-meetings` | Calendar + transcripts | ✅ | ✅ |
144
+ | `pull-onenote` | OneNote sections | ✅ | ✅ |
145
+ | `pull-sharepoint` | SharePoint / OneDrive | ✅ | ✅ |
146
+ | `pull-misc` | User-curated `external-links.txt` (Loop, web, files, PDFs, GitHub) | | |
147
+ | `pull-crm` | Dataverse engagement record | | |
148
+ | `pull-ado` | Azure DevOps work items | ✅ | ✅ |
149
+
150
+ Meta skills (not called by verbs):
151
+
152
+ | Skill | Role |
153
+ |---|---|
154
+ | `self-check` | Pre-commit consistency check across skills, instructions, prompts, and docs. Run with `pwsh plugin/skills/self-check/run.ps1` (or `./run.sh` on macOS/Linux) or by asking "kushi self-check". |
155
+ | `intro` | Self-introduction + interactive walkthrough. Triggered by "what is kushi", "what can you do", "kushi intro", "i'm new to kushi", "kushi help". |
@@ -0,0 +1,111 @@
1
+ ---
2
+ applyTo: "**/skills/bootstrap-project/**, **/skills/pull-ado/**, **/skills/refresh-project/**"
3
+ ---
4
+
5
+ # ADO bootstrap discovery — HARD rule (kushi v3.11.0+)
6
+
7
+ ## The defect this rule exists to prevent
8
+
9
+ Bootstrap runs that wrote `boundaries.ado.disabled: true` after a single shallow probe (or no probe at all) — declaring "no ADO engagement discovered" without ever issuing a live WIQL query against `dev.azure.com/IndustrySolutions`. Result: pull-ado is never dispatched, the project Evidence/ado/ stays empty, and when an Engagement work item later appears nothing notices. Mirror of the CRM defect documented in `crm-bootstrap-discovery.instructions.md` (JD bootstrap 2026-05-18).
10
+
11
+ ## The rule
12
+
13
+ `boundaries.ado.disabled: true` is **forbidden at bootstrap** — even when zero records exist for the project. The correct disposition when ADO has no engagement yet is:
14
+
15
+ ```yaml
16
+ boundaries:
17
+ ado:
18
+ # No engagement work item exists yet — keep the boundary EMPTY and retryable.
19
+ # Discovery will re-run on every refresh until something matches.
20
+ area_paths: []
21
+ work_item_ids: []
22
+ last_discovery_attempt: 'YYYY-MM-DD'
23
+ last_discovery_result: 'no-match'
24
+ last_discovery_queries:
25
+ - 'WIQL: Engagement title CONTAINS <token>'
26
+ - 'WIQL: title CONTAINS <token> across all WI types'
27
+ - 'WIQL: tags CONTAINS <slug>'
28
+ - 'WIQL: Custom.ISCRMRequestId = <fe-id>'
29
+ next_retry_on: 'next refresh'
30
+ ```
31
+
32
+ `disabled: true` is reserved for the explicit case "user confirmed this project will NEVER have an ADO engagement" — and even then prefer leaving the boundary empty with `reason: 'user-opted-out-<date>'` so the discovery probe still runs (cheap) and surfaces if reality changes.
33
+
34
+ ## Why ADO is different from CRM
35
+
36
+ | Aspect | CRM | ADO |
37
+ |---|---|---|
38
+ | Record existence at bootstrap | Usually exists (FDE Intake creates it before kickoff) | Often does NOT exist yet (work item is created when active delivery starts, sometimes weeks after intake) |
39
+ | Bootstrap failure mode | Defect (record IS there; shallow probe missed it) | Expected (record genuinely not there yet) |
40
+ | Correct disposition | Resolve via 4-step REST sequence | Run discovery, record `no-match`, KEEP RETRYING on every refresh |
41
+ | `disabled: true` legitimate? | Only after exhaustive 5-step sequence + user-ask | Only after user explicit opt-out |
42
+
43
+ For John Deere on 2026-05-18: the CRM record (FE-2026-001791) exists and was missed (defect). The ADO engagement work item does NOT exist yet (expected; intake just happened 2026-05-13). Both currently land as `disabled: true` because bootstrap treats them the same — that's the defect this rule fixes.
44
+
45
+ ## Required execution at bootstrap time
46
+
47
+ After ADO config presence + auth probe succeed:
48
+
49
+ 1. **WIQL probe 1 — Engagement-type by title**:
50
+ ```sql
51
+ SELECT [System.Id],[System.Title],[System.State],[System.AreaPath],[System.Tags],[System.CreatedDate],[System.ChangedDate]
52
+ FROM workitems
53
+ WHERE [System.TeamProject] = '<defaultProject>'
54
+ AND [System.WorkItemType] = 'Engagement'
55
+ AND ([System.Title] CONTAINS '<token1>' OR [System.Title] CONTAINS '<token2>')
56
+ AND [System.State] <> 'Removed'
57
+ ORDER BY [System.ChangedDate] DESC
58
+ ```
59
+ Tokens = each word/phrase from the project name (e.g. for "John Deere": tokens `John Deere`, `Deere`, `JDDO`, `JDIS`).
60
+
61
+ 2. **WIQL probe 2 — Any WI type by title (catches Activity-only patterns or wrong-typed engagements)**:
62
+ ```sql
63
+ SELECT [System.Id],[System.Title],[System.WorkItemType],[System.State],[System.AreaPath]
64
+ FROM workitems
65
+ WHERE [System.TeamProject] = '<defaultProject>'
66
+ AND [System.Title] CONTAINS '<token>'
67
+ AND [System.State] <> 'Removed'
68
+ AND [System.CreatedDate] > '<2-years-ago>'
69
+ ```
70
+
71
+ 3. **WIQL probe 3 — Tag fallback**:
72
+ ```sql
73
+ WHERE [System.Tags] CONTAINS '<slug>'
74
+ ```
75
+ Slug = lowercased token, hyphenated (`john-deere`, `deere`, `jddo`).
76
+
77
+ 4. **WIQL probe 4 — CRM cross-link (if CRM record_id was resolved)**:
78
+ ```sql
79
+ WHERE [Custom.ISCRMRequestId] = '<request_id>'
80
+ ```
81
+ E.g. `Custom.ISCRMRequestId = 'FE-2026-001791'`. Single most reliable probe when CRM is linked.
82
+
83
+ 5. **Disposition**:
84
+ - **1 unique match**: persist `work_item_ids: [<id>]` + `engagement_id: <id>` + the resolved area path into `area_paths`. Run pull-ado in step 4b.
85
+ - **N matches**: present top 5 candidates (id, title, state, areaPath, createdDate, link); ask user to pick. Never auto-pick.
86
+ - **0 matches across all 4 probes**: write the empty-boundary block above with `last_discovery_result: 'no-match'` and the queries attempted. **DO NOT** write `disabled: true`. Add a one-liner to OPEN-QUESTIONS-DRAFT.md noting that ADO will keep retrying on each refresh.
87
+
88
+ ## Required logging
89
+
90
+ Every bootstrap (and first-refresh) ADO-discovery run MUST write the attempt trail to `<project>/Evidence/<alias>/refresh-reports/<ts>_bootstrap.md` under a `## ADO resolution attempts` section, including the exact WIQL bodies, response counts, and final disposition. Same structure as CRM in `crm-bootstrap-discovery.instructions.md`.
91
+
92
+ ## Retry behavior on subsequent refreshes
93
+
94
+ `refresh-project` MUST re-run the discovery sequence when `boundaries.ado.work_item_ids` is empty AND `last_discovery_result == 'no-match'` AND `last_discovery_attempt` is older than the current run. If a record now matches → resolve, persist, run pull-ado. If still no match → update `last_discovery_attempt` and continue. Refresh-project NEVER writes `disabled: true` autonomously; only a user opt-out (via integrations.yml#boundaries.ado.user_opted_out: true) prevents the retry.
95
+
96
+ ## Anti-patterns
97
+
98
+ 1. **Writing `boundaries.ado.disabled: true` at bootstrap when no ADO record exists yet.** FORBIDDEN. The correct disposition is empty-boundary + `last_discovery_result: 'no-match'`. Use `disabled: true` only on explicit user opt-out (and even then prefer empty-with-reason).
99
+ 2. **Stopping after WIQL probe 1.** All 4 probes (Engagement-typed, any-typed, tag, CRM-cross-link) must run before disposition.
100
+ 3. **Auto-picking from multi-match.** Never. Always present top 5 to user.
101
+ 4. **Skipping the retry on refresh.** When boundary is empty + last_result=no-match, refresh MUST re-probe — that's the whole point of using empty over disabled.
102
+ 5. **Hiding the attempt trail.** The exact WIQL bodies and counts MUST land in the bootstrap refresh-report; "couldn't find anything" without queries is unauditable.
103
+ 6. **Skipping discovery because CRM is empty too.** ADO and CRM are independent registries. JD's ADO work item could be created before its CRM record was even known to bootstrap, or vice versa.
104
+
105
+ ## Cross-references
106
+
107
+ - `plugin/skills/pull-ado/SKILL.md` — Step 1 resolution order; this instruction wraps the bootstrap-time version.
108
+ - `plugin/skills/bootstrap-project/SKILL.md` Step 4 — must dispatch this discovery before any disposition.
109
+ - `plugin/skills/refresh-project/SKILL.md` — must re-run when boundary is empty + no-match.
110
+ - `plugin/instructions/crm-bootstrap-discovery.instructions.md` — sibling rule for CRM (different failure-mode, same pattern).
111
+ - `plugin/instructions/cleanup-on-resolution.instructions.md` — when discovery resolves a previously empty boundary, prune the stale `no-match` notes in the same turn.