kushi-agents 5.6.5 → 5.7.1
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.
- package/bin/cli.mjs +7 -0
- package/package.json +1 -1
- package/plugin/instructions/bootstrap-status-format.instructions.md +151 -151
- package/plugin/instructions/customer-hint-discovery.instructions.md +131 -131
- package/plugin/instructions/deferred-retry-on-workiq-fail.instructions.md +155 -155
- package/plugin/instructions/evidence-layout-canonical.instructions.md +123 -123
- package/plugin/instructions/karpathy-state-layout.instructions.md +124 -124
- package/plugin/instructions/living-wiki.instructions.md +88 -88
- package/plugin/instructions/log-format.instructions.md +78 -78
- package/plugin/instructions/no-hallucinated-success.instructions.md +45 -45
- package/plugin/instructions/onedrive-pin-policy.instructions.md +132 -132
- package/plugin/instructions/tracking.instructions.md +165 -165
- package/plugin/instructions/weekly-csc.instructions.md +335 -335
- package/plugin/learnings/crm.md +96 -96
- package/plugin/learnings/cross-cutting.md +127 -110
- package/plugin/learnings/meetings.md +30 -30
- package/plugin/learnings/onenote.md +200 -200
- package/plugin/plugin.json +1 -0
- package/plugin/reference-packs/fde/report-doctrine.md +189 -189
- package/plugin/runners/discover.mjs +286 -0
- package/plugin/runners/lib/workiq.mjs +53 -3
- package/plugin/runners/package.json +11 -11
- package/plugin/runners/test/unit/discover.test.mjs +130 -0
- package/plugin/skills/apply-ado-update/SKILL.md +135 -135
- package/plugin/skills/ask-project/evals/evals.json +34 -34
- package/plugin/skills/bootstrap-project/SKILL.md +3 -2
- package/plugin/skills/consolidate-evidence/SKILL.md +10 -10
- package/plugin/skills/discover-project/SKILL.md +56 -0
- package/plugin/skills/discover-project/evals/evals.json +46 -0
- package/plugin/skills/pull-onenote/write-snapshot.mjs +272 -272
- package/plugin/skills/setup/references/onedrive-pin-sync.md +60 -60
- package/plugin/templates/init/external-links.template.txt +30 -30
- package/plugin/templates/snapshot/meeting-verbatim.template.md +104 -104
- package/plugin/templates/state/00_overview.template.md +44 -44
- package/plugin/templates/state/01_decisions.template.md +41 -41
- package/plugin/templates/state/02_stakeholders.template.md +48 -48
- package/plugin/templates/state/03_architecture-and-solution.template.md +56 -56
- package/plugin/templates/state/04_workshops-and-key-meetings.template.md +43 -43
- package/plugin/templates/state/05_action-items.template.md +29 -29
- package/plugin/templates/state/06_risks-and-issues.template.md +43 -43
- package/plugin/templates/state/07_timeline-and-milestones.template.md +45 -45
- package/plugin/templates/state/08_artifacts-and-deliverables.template.md +55 -55
- package/plugin/templates/state/09_open-questions.template.md +62 -62
- package/plugin/templates/weekly/run-log.template.md +88 -88
- package/src/bootstrap-dryrun.integration.test.mjs +235 -235
- package/src/detect-vertex-repo.test.mjs +128 -128
- package/src/emit-vertex.e2e.test.mjs +308 -308
- package/src/install-runner-deps.mjs +57 -57
- package/src/main.mjs +1 -1
- package/src/multi-host.mjs +35 -0
- package/src/vertex-validate.test.mjs +142 -142
package/bin/cli.mjs
CHANGED
|
@@ -182,10 +182,16 @@ if (args.includes('--help') || args.includes('-h')) {
|
|
|
182
182
|
--clawpilot Install to ~/.copilot/m-skills/kushi/
|
|
183
183
|
--vscode Install to ~/.vscode/chat/skills/kushi/ (a.k.a. GitHub Copilot Chat)
|
|
184
184
|
--all-hosts Install to BOTH hosts
|
|
185
|
+
--no-workspace Skip the auto workspace install (host install only)
|
|
185
186
|
--uninstall [--clawpilot|--vscode|--all]
|
|
186
187
|
Cleanly remove the kushi install + skills-metadata.json entry
|
|
187
188
|
from the chosen host(s). Default = all detected hosts.
|
|
188
189
|
|
|
190
|
+
Note: when run from inside a project directory (any of: package.json, .git,
|
|
191
|
+
.kushi/, Evidence/, etc.), host installs ALSO refresh the workspace
|
|
192
|
+
.kushi/ install in cwd. One command covers both. Pass --no-workspace to
|
|
193
|
+
suppress, or run from a non-project directory.
|
|
194
|
+
|
|
189
195
|
Workspace install (legacy / default when no host flag is given):
|
|
190
196
|
--target vscode Install to <cwd>/.kushi/ + update .vscode/settings.json [default]
|
|
191
197
|
--target clawpilot Alias for --clawpilot (kept for back-compat)
|
|
@@ -274,6 +280,7 @@ if (wantsVscode || wantsAllHosts || wantsUninstall) {
|
|
|
274
280
|
all,
|
|
275
281
|
uninstall: wantsUninstall,
|
|
276
282
|
profile: getFlag('--profile'),
|
|
283
|
+
includeWorkspace: !args.includes('--no-workspace'),
|
|
277
284
|
}).catch((err) => {
|
|
278
285
|
console.error(`\n ${err.message}\n`);
|
|
279
286
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kushi-agents",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.7.1",
|
|
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": {
|
|
@@ -1,151 +1,151 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "**"
|
|
3
|
-
excludeAgent: "code-review"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Bootstrap Status Artifact — Format Contract
|
|
7
|
-
|
|
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`.
|
|
11
|
-
|
|
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`.
|
|
13
|
-
|
|
14
|
-
## Required section order
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
# Bootstrap Status
|
|
18
|
-
|
|
19
|
-
- Bootstrap Date: YYYY-MM-DD HH:MM TZ
|
|
20
|
-
- Project: <name>
|
|
21
|
-
- Customer Hint: <token used to resolve>
|
|
22
|
-
- Mode: bootstrap | refresh | retry | force
|
|
23
|
-
- Lookback Window: <days>
|
|
24
|
-
|
|
25
|
-
## Preflight Checks
|
|
26
|
-
|
|
27
|
-
| Check | Status | Notes |
|
|
28
|
-
|---|---|---|
|
|
29
|
-
| `.kushi/config/shared/integrations.yml` filled | resolved \| blocked-auth \| missing | ... |
|
|
30
|
-
| `.kushi/config/shared/integrations.yml` filled | ... | ... |
|
|
31
|
-
| `<project>/integrations.yml` boundaries present | ... | ... |
|
|
32
|
-
| `az` CLI tenant matches | cli-available \| blocked-auth | ... |
|
|
33
|
-
|
|
34
|
-
## Context Artifact Status
|
|
35
|
-
|
|
36
|
-
| Artifact | Status | Notes |
|
|
37
|
-
|---|---|---|
|
|
38
|
-
| `crm/snapshot/<entity>/<id>.md` | populated \| unsynced \| degraded \| partial-template | <annotation count> |
|
|
39
|
-
| `ado/snapshot/engagement-<id>.md` | populated \| ado-not-complete | <tree size> |
|
|
40
|
-
| `ado/snapshot/items/*.md` | populated \| skipped \| ado-not-complete | <N items> |
|
|
41
|
-
| `onenote/snapshot/<section>/*.md` | populated \| degraded | <pages enumerated/failed> |
|
|
42
|
-
| `email/_index/<week>_message-index.md` | populated \| degraded-list-only \| throttled-tooManyRequests | <N enumerated> |
|
|
43
|
-
| `email/stream/<week>_email-stream.md` | populated \| degraded-list-only | <N threads> |
|
|
44
|
-
| `teams/...` | ... | ... |
|
|
45
|
-
|
|
46
|
-
## Current Bootstrap Outcome
|
|
47
|
-
|
|
48
|
-
- One-line current state per source.
|
|
49
|
-
- CRM stage: <plain-language interpretation of statuscode> (`internal-only` per `evidence-confidence-ladder`).
|
|
50
|
-
- ADO linkage: pinned engagement <id> | pending pick from N candidates | `ado-not-complete`.
|
|
51
|
-
- Notable gaps: ...
|
|
52
|
-
|
|
53
|
-
## Access Limitations
|
|
54
|
-
|
|
55
|
-
| System | Status | Reason | Workaround |
|
|
56
|
-
|---|---|---|---|
|
|
57
|
-
| ADO | resolved | — | — |
|
|
58
|
-
| CRM | blocked-auth | tenant mismatch | `az login --tenant <id>` |
|
|
59
|
-
| Email | throttled-tooManyRequests | WorkIQ rate-limited | retry next refresh |
|
|
60
|
-
|
|
61
|
-
## Deferred Retries (kushi v4.4.1+, per `deferred-retry-on-workiq-fail.instructions.md`)
|
|
62
|
-
|
|
63
|
-
Omit this section entirely if `<project>/Evidence/<alias>/_deferred-retries/` is empty across all contributors.
|
|
64
|
-
|
|
65
|
-
| Source | Target | Attempts | Marker | First seen | Discovered by |
|
|
66
|
-
|---|---|---|---|---|---|
|
|
67
|
-
| meetings | "JD FDE Intake" 2026-05-13 | 1 | `Evidence/ushak/_deferred-retries/2026-05-20-1230_meetings_empty.yml` | 2026-05-20 | ushak |
|
|
68
|
-
| onenote | "Architecture overview" | 2 | `Evidence/ushak/_deferred-retries/2026-05-19-0810_onenote_throttled.yml` | 2026-05-19 | ushak |
|
|
69
|
-
|
|
70
|
-
Markers older than 5 attempts auto-promote to `OPEN-QUESTIONS-DRAFT.md`. The next `refresh` drains the queue (Step 2a in `refresh-project/SKILL.md`) — do NOT manually retry by calling `m365_get_*` / Graph; those are forbidden per `workiq-only.instructions.md`.
|
|
71
|
-
|
|
72
|
-
## Bootstrap Status
|
|
73
|
-
|
|
74
|
-
ONE final line, normalized:
|
|
75
|
-
- `bootstrap-complete`
|
|
76
|
-
- `bootstrap-complete-with-coverage-gaps`
|
|
77
|
-
- `bootstrap-blocked — <primary reason>`
|
|
78
|
-
- `refresh-complete`
|
|
79
|
-
- `refresh-complete-with-coverage-gaps`
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Normalized status vocabulary
|
|
83
|
-
|
|
84
|
-
Use these exact strings everywhere (table cells, run-log, narrative):
|
|
85
|
-
|
|
86
|
-
- `resolved` — check passed
|
|
87
|
-
- `cli-available` — required CLI is installed and authenticated
|
|
88
|
-
- `blocked-auth` — auth missing/failed
|
|
89
|
-
- `partial-template` — file exists but only template scaffolding written
|
|
90
|
-
- `unsynced` — file does not contain real data yet
|
|
91
|
-
- `populated` — file contains real fetched data
|
|
92
|
-
- `degraded` / `degraded-list-only` — partial fetch (e.g. email body-unavailable for some messages)
|
|
93
|
-
- `throttled-tooManyRequests` — source rate-limited
|
|
94
|
-
- `ado-not-complete` — engagement record not found yet OR ADO linkage missing
|
|
95
|
-
- `completed-with-coverage-gaps` — final outcome with explicit gaps recorded
|
|
96
|
-
|
|
97
|
-
## Multi-contributor safety (kushi v5.4.4+)
|
|
98
|
-
|
|
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):
|
|
100
|
-
|
|
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.
|
|
105
|
-
|
|
106
|
-
### Required `## Run summary` section on the per-user file
|
|
107
|
-
|
|
108
|
-
Append immediately after `## Bootstrap Status`:
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
## Run summary
|
|
112
|
-
|
|
113
|
-
| Alias | Display Name | Last Run | Mode | Outcome |
|
|
114
|
-
|---|---|---|---|---|
|
|
115
|
-
| ushak | Usha Kandregula | 2026-05-27 09:42 EDT | bootstrap | bootstrap-complete-with-coverage-gaps |
|
|
116
|
-
```
|
|
117
|
-
|
|
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`.
|
|
119
|
-
|
|
120
|
-
## Sections to AVOID in bootstrap-status
|
|
121
|
-
|
|
122
|
-
Do NOT keep these in `bootstrap-status.md` (they belong elsewhere or become stale):
|
|
123
|
-
|
|
124
|
-
- `Fallback Inputs Used` → run-log only
|
|
125
|
-
- `Evidence & Current Context` → State files
|
|
126
|
-
- `FDE Fitness Assessment` → State/00_overview.md
|
|
127
|
-
- `Source Coverage` → already covered by Access Limitations
|
|
128
|
-
- `Recommended Actions` → State/05_action-items.md or Open Questions/
|
|
129
|
-
- long historical retry logs → run-log only
|
|
130
|
-
|
|
131
|
-
## Stable-summary test
|
|
132
|
-
|
|
133
|
-
When deciding whether a detail belongs in `bootstrap-status.md`, ask: **"Does this help a future reader understand the current durable project state?"** If it's mainly describing how this one run unfolded, push it to `update-status.md` (per-run history) or the run-log instead.
|
|
134
|
-
|
|
135
|
-
## ADO-not-complete note
|
|
136
|
-
|
|
137
|
-
When a bootstrap cannot resolve the ADO Engagement WI, include in `## Current Bootstrap Outcome`:
|
|
138
|
-
|
|
139
|
-
> ADO context sync pending: engagement record not found yet; bootstrap is usable with CRM/transcript context and should be revisited after ADO engagement creation or when the candidate WI is pinned to `integrations.yml#ado.engagement_id`.
|
|
140
|
-
|
|
141
|
-
And reflect `ado-not-complete` in the relevant Context Artifact Status rows.
|
|
142
|
-
|
|
143
|
-
## Relationship to other artifacts
|
|
144
|
-
|
|
145
|
-
- Detailed CRM content → `crm-context/record-profile.md` + `crm/snapshot/`
|
|
146
|
-
- Detailed ADO tree → `ado/snapshot/tree.md` + per-item files
|
|
147
|
-
- Detailed transcripts → `meeting-transcripts/index.md`
|
|
148
|
-
- Per-run history → `update-status.md` (project-local)
|
|
149
|
-
- Cross-source synthesis → `State/`
|
|
150
|
-
|
|
151
|
-
`bootstrap-status.md` summarizes; it never duplicates these artifacts.
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**"
|
|
3
|
+
excludeAgent: "code-review"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Bootstrap Status Artifact — Format Contract
|
|
7
|
+
|
|
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`.
|
|
11
|
+
|
|
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`.
|
|
13
|
+
|
|
14
|
+
## Required section order
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
# Bootstrap Status
|
|
18
|
+
|
|
19
|
+
- Bootstrap Date: YYYY-MM-DD HH:MM TZ
|
|
20
|
+
- Project: <name>
|
|
21
|
+
- Customer Hint: <token used to resolve>
|
|
22
|
+
- Mode: bootstrap | refresh | retry | force
|
|
23
|
+
- Lookback Window: <days>
|
|
24
|
+
|
|
25
|
+
## Preflight Checks
|
|
26
|
+
|
|
27
|
+
| Check | Status | Notes |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `.kushi/config/shared/integrations.yml` filled | resolved \| blocked-auth \| missing | ... |
|
|
30
|
+
| `.kushi/config/shared/integrations.yml` filled | ... | ... |
|
|
31
|
+
| `<project>/integrations.yml` boundaries present | ... | ... |
|
|
32
|
+
| `az` CLI tenant matches | cli-available \| blocked-auth | ... |
|
|
33
|
+
|
|
34
|
+
## Context Artifact Status
|
|
35
|
+
|
|
36
|
+
| Artifact | Status | Notes |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `crm/snapshot/<entity>/<id>.md` | populated \| unsynced \| degraded \| partial-template | <annotation count> |
|
|
39
|
+
| `ado/snapshot/engagement-<id>.md` | populated \| ado-not-complete | <tree size> |
|
|
40
|
+
| `ado/snapshot/items/*.md` | populated \| skipped \| ado-not-complete | <N items> |
|
|
41
|
+
| `onenote/snapshot/<section>/*.md` | populated \| degraded | <pages enumerated/failed> |
|
|
42
|
+
| `email/_index/<week>_message-index.md` | populated \| degraded-list-only \| throttled-tooManyRequests | <N enumerated> |
|
|
43
|
+
| `email/stream/<week>_email-stream.md` | populated \| degraded-list-only | <N threads> |
|
|
44
|
+
| `teams/...` | ... | ... |
|
|
45
|
+
|
|
46
|
+
## Current Bootstrap Outcome
|
|
47
|
+
|
|
48
|
+
- One-line current state per source.
|
|
49
|
+
- CRM stage: <plain-language interpretation of statuscode> (`internal-only` per `evidence-confidence-ladder`).
|
|
50
|
+
- ADO linkage: pinned engagement <id> | pending pick from N candidates | `ado-not-complete`.
|
|
51
|
+
- Notable gaps: ...
|
|
52
|
+
|
|
53
|
+
## Access Limitations
|
|
54
|
+
|
|
55
|
+
| System | Status | Reason | Workaround |
|
|
56
|
+
|---|---|---|---|
|
|
57
|
+
| ADO | resolved | — | — |
|
|
58
|
+
| CRM | blocked-auth | tenant mismatch | `az login --tenant <id>` |
|
|
59
|
+
| Email | throttled-tooManyRequests | WorkIQ rate-limited | retry next refresh |
|
|
60
|
+
|
|
61
|
+
## Deferred Retries (kushi v4.4.1+, per `deferred-retry-on-workiq-fail.instructions.md`)
|
|
62
|
+
|
|
63
|
+
Omit this section entirely if `<project>/Evidence/<alias>/_deferred-retries/` is empty across all contributors.
|
|
64
|
+
|
|
65
|
+
| Source | Target | Attempts | Marker | First seen | Discovered by |
|
|
66
|
+
|---|---|---|---|---|---|
|
|
67
|
+
| meetings | "JD FDE Intake" 2026-05-13 | 1 | `Evidence/ushak/_deferred-retries/2026-05-20-1230_meetings_empty.yml` | 2026-05-20 | ushak |
|
|
68
|
+
| onenote | "Architecture overview" | 2 | `Evidence/ushak/_deferred-retries/2026-05-19-0810_onenote_throttled.yml` | 2026-05-19 | ushak |
|
|
69
|
+
|
|
70
|
+
Markers older than 5 attempts auto-promote to `OPEN-QUESTIONS-DRAFT.md`. The next `refresh` drains the queue (Step 2a in `refresh-project/SKILL.md`) — do NOT manually retry by calling `m365_get_*` / Graph; those are forbidden per `workiq-only.instructions.md`.
|
|
71
|
+
|
|
72
|
+
## Bootstrap Status
|
|
73
|
+
|
|
74
|
+
ONE final line, normalized:
|
|
75
|
+
- `bootstrap-complete`
|
|
76
|
+
- `bootstrap-complete-with-coverage-gaps`
|
|
77
|
+
- `bootstrap-blocked — <primary reason>`
|
|
78
|
+
- `refresh-complete`
|
|
79
|
+
- `refresh-complete-with-coverage-gaps`
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Normalized status vocabulary
|
|
83
|
+
|
|
84
|
+
Use these exact strings everywhere (table cells, run-log, narrative):
|
|
85
|
+
|
|
86
|
+
- `resolved` — check passed
|
|
87
|
+
- `cli-available` — required CLI is installed and authenticated
|
|
88
|
+
- `blocked-auth` — auth missing/failed
|
|
89
|
+
- `partial-template` — file exists but only template scaffolding written
|
|
90
|
+
- `unsynced` — file does not contain real data yet
|
|
91
|
+
- `populated` — file contains real fetched data
|
|
92
|
+
- `degraded` / `degraded-list-only` — partial fetch (e.g. email body-unavailable for some messages)
|
|
93
|
+
- `throttled-tooManyRequests` — source rate-limited
|
|
94
|
+
- `ado-not-complete` — engagement record not found yet OR ADO linkage missing
|
|
95
|
+
- `completed-with-coverage-gaps` — final outcome with explicit gaps recorded
|
|
96
|
+
|
|
97
|
+
## Multi-contributor safety (kushi v5.4.4+)
|
|
98
|
+
|
|
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):
|
|
100
|
+
|
|
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.
|
|
105
|
+
|
|
106
|
+
### Required `## Run summary` section on the per-user file
|
|
107
|
+
|
|
108
|
+
Append immediately after `## Bootstrap Status`:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
## Run summary
|
|
112
|
+
|
|
113
|
+
| Alias | Display Name | Last Run | Mode | Outcome |
|
|
114
|
+
|---|---|---|---|---|
|
|
115
|
+
| ushak | Usha Kandregula | 2026-05-27 09:42 EDT | bootstrap | bootstrap-complete-with-coverage-gaps |
|
|
116
|
+
```
|
|
117
|
+
|
|
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`.
|
|
119
|
+
|
|
120
|
+
## Sections to AVOID in bootstrap-status
|
|
121
|
+
|
|
122
|
+
Do NOT keep these in `bootstrap-status.md` (they belong elsewhere or become stale):
|
|
123
|
+
|
|
124
|
+
- `Fallback Inputs Used` → run-log only
|
|
125
|
+
- `Evidence & Current Context` → State files
|
|
126
|
+
- `FDE Fitness Assessment` → State/00_overview.md
|
|
127
|
+
- `Source Coverage` → already covered by Access Limitations
|
|
128
|
+
- `Recommended Actions` → State/05_action-items.md or Open Questions/
|
|
129
|
+
- long historical retry logs → run-log only
|
|
130
|
+
|
|
131
|
+
## Stable-summary test
|
|
132
|
+
|
|
133
|
+
When deciding whether a detail belongs in `bootstrap-status.md`, ask: **"Does this help a future reader understand the current durable project state?"** If it's mainly describing how this one run unfolded, push it to `update-status.md` (per-run history) or the run-log instead.
|
|
134
|
+
|
|
135
|
+
## ADO-not-complete note
|
|
136
|
+
|
|
137
|
+
When a bootstrap cannot resolve the ADO Engagement WI, include in `## Current Bootstrap Outcome`:
|
|
138
|
+
|
|
139
|
+
> ADO context sync pending: engagement record not found yet; bootstrap is usable with CRM/transcript context and should be revisited after ADO engagement creation or when the candidate WI is pinned to `integrations.yml#ado.engagement_id`.
|
|
140
|
+
|
|
141
|
+
And reflect `ado-not-complete` in the relevant Context Artifact Status rows.
|
|
142
|
+
|
|
143
|
+
## Relationship to other artifacts
|
|
144
|
+
|
|
145
|
+
- Detailed CRM content → `crm-context/record-profile.md` + `crm/snapshot/`
|
|
146
|
+
- Detailed ADO tree → `ado/snapshot/tree.md` + per-item files
|
|
147
|
+
- Detailed transcripts → `meeting-transcripts/index.md`
|
|
148
|
+
- Per-run history → `update-status.md` (project-local)
|
|
149
|
+
- Cross-source synthesis → `State/`
|
|
150
|
+
|
|
151
|
+
`bootstrap-status.md` summarizes; it never duplicates these artifacts.
|
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "**/skills/bootstrap-project/**, **/skills/pull-email/**, **/skills/pull-teams/**, **/skills/pull-meetings/**, **/skills/pull-sharepoint/**, **/skills/refresh-project/**"
|
|
3
|
-
description: "Customer-hint discovery sweep — bootstrap MUST attempt WorkIQ-driven discovery for every source whose boundary is empty before declaring blocked-config. Mirrors crm-bootstrap-discovery + loop-bootstrap-discovery pattern. Kushi v4.8.0+."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Customer-hint discovery sweep (HARD RULE — kushi v4.8.0+)
|
|
7
|
-
|
|
8
|
-
## The defect this rule exists to prevent
|
|
9
|
-
|
|
10
|
-
Bootstrap runs that scaffold an empty `<project>/integrations.yml#boundaries.*` and immediately declare every source `blocked-config` — without ever asking WorkIQ "who/what mentions this customer?". The result: a fresh project bootstrap finishes with 0 evidence pulled, the user is told to hand-populate mailboxes / chat IDs / channel IDs / meeting join URLs / SharePoint sites, and the entire value proposition of "bootstrap a project from a customer hint" collapses to a config form. Discovered 2026-05-26 on the Northwind bootstrap — every source row read `blocked-config` despite extensive Northwind email / Teams / meeting history in the tenant.
|
|
11
|
-
|
|
12
|
-
## The rule
|
|
13
|
-
|
|
14
|
-
Before `bootstrap-project` (or `refresh-project` on a first pull) is allowed to write `last_status: blocked-config` for **email, teams, meetings, or sharepoint**, the per-source customer-hint discovery sweep defined in the matching doctrine MUST be attempted with the customer hint + lookback window:
|
|
15
|
-
|
|
16
|
-
| Source | Doctrine file (mandatory) |
|
|
17
|
-
|---|---|
|
|
18
|
-
| email | `email-bootstrap-discovery.instructions.md` |
|
|
19
|
-
| teams | `teams-bootstrap-discovery.instructions.md` |
|
|
20
|
-
| meetings | `meetings-bootstrap-discovery.instructions.md` |
|
|
21
|
-
| sharepoint | `sharepoint-bootstrap-discovery.instructions.md` |
|
|
22
|
-
| onenote | `bootstrap-project/SKILL.md#step-4a` (already shipped v4.7.x — display-name driven) |
|
|
23
|
-
| loop | `loop-bootstrap-discovery.instructions.md` (already shipped v4.6.0) |
|
|
24
|
-
| crm | `crm-bootstrap-discovery.instructions.md` (already shipped v3.11.0) |
|
|
25
|
-
| ado | `ado-bootstrap-discovery.instructions.md` |
|
|
26
|
-
|
|
27
|
-
`blocked-config` is ONLY legitimate when:
|
|
28
|
-
|
|
29
|
-
1. **The sweep ran** and returned 0 candidates → status is `unresolved` (sweep succeeded but no hits), not `blocked-config`. Use `discovery-empty` annotation in the per-source notes.
|
|
30
|
-
2. **The sweep COULD not run** because a prerequisite is genuinely missing (e.g. CRM/ADO need `<workspace>/.kushi/config/shared/integrations.yml` populated, SharePoint local-folder enumeration needs a local OneDrive sync path the customer hint cannot infer). In that case, `blocked-config` is correct, and the per-source `next_step` MUST cite the specific missing config field.
|
|
31
|
-
|
|
32
|
-
Any other path that writes `blocked-config` without attempting the sweep is a **defect**.
|
|
33
|
-
|
|
34
|
-
## Required inputs
|
|
35
|
-
|
|
36
|
-
- `<customer-hint>` — verbatim string the user provided at bootstrap invocation (e.g. `Northwind`). Captured by `bootstrap-project` Step 0/1 and persisted to `<project>/bootstrap-status.md` under `Customer Hint:`. Used VERBATIM in v4.8.0 — no fuzzy expansion (deferred to v4.9.0).
|
|
37
|
-
- `<lookback-days>` — defaults to **90** for discovery (longer than the 30-day pull window so historical chats / series still surface). Configurable via `<workspace>/.kushi/config/user/m365-mutable.json#bootstrap.discoveryLookbackDays`.
|
|
38
|
-
- `<project>` — engagement name (already resolved).
|
|
39
|
-
- `<alias>` — current contributor.
|
|
40
|
-
|
|
41
|
-
## Required outputs
|
|
42
|
-
|
|
43
|
-
For each source whose sweep runs:
|
|
44
|
-
|
|
45
|
-
1. **Append discovered IDs / URLs / paths to `<engagement-root>/<project>/integrations.yml#boundaries.<source>.<key>`** as plain strings (existing pull-* skills consume strings — do NOT change the array element type). Idempotent: deduplicate by exact-string equality.
|
|
46
|
-
|
|
47
|
-
2. **Write a sidecar discovery record to `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_<source>_discovery.yml`** with the per-row metadata (`discovered_by`, `discovered_at`, `needs_review`, `query`, `request_id`, `confidence`). The sidecar lives **inside the contributor's alias folder** because discovery results are inherently per-identity (each contributor sees a different mailbox / chat / meeting set). Schema:
|
|
48
|
-
|
|
49
|
-
```yaml
|
|
50
|
-
source: email | teams | meetings | sharepoint
|
|
51
|
-
project: <project>
|
|
52
|
-
customer_hint: '<hint>'
|
|
53
|
-
lookback_days: 90
|
|
54
|
-
discovered_at: '<ISO-8601>'
|
|
55
|
-
discovered_by: <alias>
|
|
56
|
-
query: '<exact WorkIQ prompt>'
|
|
57
|
-
workiq_request_id: '<request-id from response>'
|
|
58
|
-
total_candidates_found: <N>
|
|
59
|
-
candidates_persisted: <M> # ≤ 10 after cap
|
|
60
|
-
candidates_deferred: <N - M> # written to OPEN-QUESTIONS-DRAFT.md
|
|
61
|
-
results:
|
|
62
|
-
- value: '<string written to boundary>'
|
|
63
|
-
label: '<human-readable label>'
|
|
64
|
-
confidence: high | medium | low
|
|
65
|
-
needs_review: true
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
3. **If `total_candidates_found > 10`**, persist the top 10 by recency to the boundary and append the remaining N–10 to `<project>/OPEN-QUESTIONS-DRAFT.md` under `## Discovery sweep — candidates over cap` with one row per candidate.
|
|
69
|
-
|
|
70
|
-
4. **Add a `## Discovery Sweep Results` section to `<project>/bootstrap-status.md`** after `## Context Artifact Status`. Table shape:
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
## Discovery Sweep Results
|
|
74
|
-
|
|
75
|
-
| Source | Hint | Query attempted | Candidates found | Persisted | Deferred | Discovered by |
|
|
76
|
-
|---|---|---|---|---|---|---|
|
|
77
|
-
| email | Northwind | "In my Inbox..." | 7 | 7 | 0 | ushak |
|
|
78
|
-
| teams | Northwind | "In my Teams chats..." | 14 | 10 | 4 | ushak |
|
|
79
|
-
| meetings | Northwind | "In my calendar..." | 3 | 3 | 0 | ushak |
|
|
80
|
-
| sharepoint | Northwind | "In my SharePoint sites..." | 0 | 0 | 0 | ushak |
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Behavior matrix (per source)
|
|
84
|
-
|
|
85
|
-
| Sweep result | `boundaries.<source>.<key>` written? | `last_status` | `retry_signal` | Open Questions written? |
|
|
86
|
-
|---|---|---|---|---|
|
|
87
|
-
| 0 candidates | no | `unresolved` (annotated `discovery-empty`) | `user-action` | yes — "Discovery sweep for `<source>` returned 0 hits for `<hint>`; widen hint or seed `boundaries.<source>.<key>` manually" |
|
|
88
|
-
| 1–10 candidates | yes (all) | `completed-with-coverage-gaps` (because rows are `needs_review`) | `watch` | only if any row low-confidence |
|
|
89
|
-
| > 10 candidates | yes (top 10 by recency) | `completed-with-coverage-gaps` | `watch` | yes — "Discovery sweep returned >10 candidates; review the deferred list" |
|
|
90
|
-
| **WorkIQ punted — no surface for this source** (sharepoint sites, teams channels — v4.8.1 empirical) | no | `unresolved` (annotated `discovery-empty-no-workiq-surface`) | `user-action` | yes — cite that this source has no known WorkIQ discovery surface and direct the user to manual configuration (the per-source doctrine has the exact wording) |
|
|
91
|
-
| Sweep query failed (WorkIQ error / classified per `fallback-status-reporting.instructions.md`) | no | `deferred` (write marker per `deferred-retry-on-workiq-fail.instructions.md`) | `retry` | no — next refresh will drain |
|
|
92
|
-
| Prerequisite genuinely missing (e.g. CRM shared config empty) | no | `blocked-config` | `user-action` | yes — cite specific missing field |
|
|
93
|
-
|
|
94
|
-
## Multi-contributor safety
|
|
95
|
-
|
|
96
|
-
When the boundary already has rows from another alias (or sibling `Evidence/<other-alias>/_discovery/` folders already have entries):
|
|
97
|
-
|
|
98
|
-
1. **Append-only** — the new alias's sweep adds rows that are not already present (dedupe by exact-string equality on the boundary value). Never remove or rewrite another alias's row.
|
|
99
|
-
2. **Sidecar files are per-contributor-folder-per-source-per-date** — each contributor writes only into their own `Evidence/<alias>/_discovery/` folder. Filenames are NOT suffixed with `-<alias>` (folder already namespaces the owner). On the same day, contributors `ushak` and `stand` produce `Evidence/ushak/_discovery/2026-05-26_email_discovery.yml` and `Evidence/stand/_discovery/2026-05-26_email_discovery.yml` respectively — no collision possible. Bootstrap-status's Discovery Sweep Results table shows one row per source × alias.
|
|
100
|
-
3. **`Discovered by` column in bootstrap-status's per-source Context Artifact Status row** cites the most recent discovering alias. Preserve other aliases' rows in `## Contributors who have bootstrapped this project` per `multi-user-shared-files.instructions.md`.
|
|
101
|
-
4. **NEVER write to another contributor's `Evidence/<other-alias>/_discovery/` folder.** Reading other aliases' discovery sidecars (e.g. to merge already-confirmed candidates into the shared boundary) is allowed and expected; writing into them is forbidden.
|
|
102
|
-
|
|
103
|
-
## Rerun behavior
|
|
104
|
-
|
|
105
|
-
When the user re-runs bootstrap on a project that already has populated boundaries:
|
|
106
|
-
|
|
107
|
-
| Boundary state | Sweep behavior |
|
|
108
|
-
|---|---|
|
|
109
|
-
| Empty | Run sweep (full discovery). |
|
|
110
|
-
| Has rows, none `needs_review: true` (all confirmed) | **Skip sweep.** Boundary is gospel — do not re-discover. |
|
|
111
|
-
| Has rows, some `needs_review: true` (sidecar shows confidence < high) | Run sweep. Merge new candidates by ID. Promote previously-discovered candidates from `needs_review: true` → `false` only if user has manually confirmed (i.e. removed the `needs_review` flag from the sidecar). |
|
|
112
|
-
| User passes `--force-rediscover` | Run sweep regardless of state. Merge new candidates; never delete user-confirmed rows. |
|
|
113
|
-
|
|
114
|
-
## Forbidden behaviors
|
|
115
|
-
|
|
116
|
-
1. **Declaring `blocked-config` without running the sweep first** for email/teams/meetings/sharepoint — see "The defect" above. CRM/ADO have their own mandates in `crm-bootstrap-discovery` / `ado-bootstrap-discovery`.
|
|
117
|
-
2. **Auto-narrowing the customer hint** ("Northwind" → "Northwind Healthcare Inc"). Use the hint verbatim. Smart-expansion is v4.9.0.
|
|
118
|
-
3. **Discovering across all sources in one mega-query.** Each source has its own narrow WorkIQ prompt (see per-source doctrines). Mega-queries punt to Graph and return empty.
|
|
119
|
-
4. **Inferring local OneDrive sync paths from the hint** for SharePoint `local_folders[]`. Discovery populates `site_urls[]` only.
|
|
120
|
-
5. **Calling Graph / `m365_*` directly for discovery.** Per `workiq-only.instructions.md` the four sources covered here use WorkIQ exclusively. The only allowed `m365_*` exceptions remain `m365_list_chat_messages` (parallel structured dump per pull-teams) and the per-source carve-outs already named in their pull-* SKILLs.
|
|
121
|
-
|
|
122
|
-
## References
|
|
123
|
-
|
|
124
|
-
- `crm-bootstrap-discovery.instructions.md` — the original "must-attempt-before-declaring-disabled" doctrine; this file mirrors its pattern for the WorkIQ-driven sources.
|
|
125
|
-
- `loop-bootstrap-discovery.instructions.md` — Loop-specific discovery + registry shape.
|
|
126
|
-
- `scope-boundaries.instructions.md` — the broader partial-determinism contract; this doctrine is the discovery-time enabler that makes boundaries achievable.
|
|
127
|
-
- `workiq-only.instructions.md` — what discovery is NOT allowed to call (Graph, m365_* for content).
|
|
128
|
-
- `status-taxonomy.instructions.md` — the closed-set status vocabulary; `unresolved` + `discovery-empty` annotation vs. `blocked-config`.
|
|
129
|
-
- `fallback-status-reporting.instructions.md` — how to classify WorkIQ punts during the sweep.
|
|
130
|
-
- `multi-user-shared-files.instructions.md` — append-only rules for the boundary file.
|
|
131
|
-
- `bootstrap-status-format.instructions.md` — where `## Discovery Sweep Results` slots in the report.
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/skills/bootstrap-project/**, **/skills/pull-email/**, **/skills/pull-teams/**, **/skills/pull-meetings/**, **/skills/pull-sharepoint/**, **/skills/refresh-project/**"
|
|
3
|
+
description: "Customer-hint discovery sweep — bootstrap MUST attempt WorkIQ-driven discovery for every source whose boundary is empty before declaring blocked-config. Mirrors crm-bootstrap-discovery + loop-bootstrap-discovery pattern. Kushi v4.8.0+."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Customer-hint discovery sweep (HARD RULE — kushi v4.8.0+)
|
|
7
|
+
|
|
8
|
+
## The defect this rule exists to prevent
|
|
9
|
+
|
|
10
|
+
Bootstrap runs that scaffold an empty `<project>/integrations.yml#boundaries.*` and immediately declare every source `blocked-config` — without ever asking WorkIQ "who/what mentions this customer?". The result: a fresh project bootstrap finishes with 0 evidence pulled, the user is told to hand-populate mailboxes / chat IDs / channel IDs / meeting join URLs / SharePoint sites, and the entire value proposition of "bootstrap a project from a customer hint" collapses to a config form. Discovered 2026-05-26 on the Northwind bootstrap — every source row read `blocked-config` despite extensive Northwind email / Teams / meeting history in the tenant.
|
|
11
|
+
|
|
12
|
+
## The rule
|
|
13
|
+
|
|
14
|
+
Before `bootstrap-project` (or `refresh-project` on a first pull) is allowed to write `last_status: blocked-config` for **email, teams, meetings, or sharepoint**, the per-source customer-hint discovery sweep defined in the matching doctrine MUST be attempted with the customer hint + lookback window:
|
|
15
|
+
|
|
16
|
+
| Source | Doctrine file (mandatory) |
|
|
17
|
+
|---|---|
|
|
18
|
+
| email | `email-bootstrap-discovery.instructions.md` |
|
|
19
|
+
| teams | `teams-bootstrap-discovery.instructions.md` |
|
|
20
|
+
| meetings | `meetings-bootstrap-discovery.instructions.md` |
|
|
21
|
+
| sharepoint | `sharepoint-bootstrap-discovery.instructions.md` |
|
|
22
|
+
| onenote | `bootstrap-project/SKILL.md#step-4a` (already shipped v4.7.x — display-name driven) |
|
|
23
|
+
| loop | `loop-bootstrap-discovery.instructions.md` (already shipped v4.6.0) |
|
|
24
|
+
| crm | `crm-bootstrap-discovery.instructions.md` (already shipped v3.11.0) |
|
|
25
|
+
| ado | `ado-bootstrap-discovery.instructions.md` |
|
|
26
|
+
|
|
27
|
+
`blocked-config` is ONLY legitimate when:
|
|
28
|
+
|
|
29
|
+
1. **The sweep ran** and returned 0 candidates → status is `unresolved` (sweep succeeded but no hits), not `blocked-config`. Use `discovery-empty` annotation in the per-source notes.
|
|
30
|
+
2. **The sweep COULD not run** because a prerequisite is genuinely missing (e.g. CRM/ADO need `<workspace>/.kushi/config/shared/integrations.yml` populated, SharePoint local-folder enumeration needs a local OneDrive sync path the customer hint cannot infer). In that case, `blocked-config` is correct, and the per-source `next_step` MUST cite the specific missing config field.
|
|
31
|
+
|
|
32
|
+
Any other path that writes `blocked-config` without attempting the sweep is a **defect**.
|
|
33
|
+
|
|
34
|
+
## Required inputs
|
|
35
|
+
|
|
36
|
+
- `<customer-hint>` — verbatim string the user provided at bootstrap invocation (e.g. `Northwind`). Captured by `bootstrap-project` Step 0/1 and persisted to `<project>/bootstrap-status.md` under `Customer Hint:`. Used VERBATIM in v4.8.0 — no fuzzy expansion (deferred to v4.9.0).
|
|
37
|
+
- `<lookback-days>` — defaults to **90** for discovery (longer than the 30-day pull window so historical chats / series still surface). Configurable via `<workspace>/.kushi/config/user/m365-mutable.json#bootstrap.discoveryLookbackDays`.
|
|
38
|
+
- `<project>` — engagement name (already resolved).
|
|
39
|
+
- `<alias>` — current contributor.
|
|
40
|
+
|
|
41
|
+
## Required outputs
|
|
42
|
+
|
|
43
|
+
For each source whose sweep runs:
|
|
44
|
+
|
|
45
|
+
1. **Append discovered IDs / URLs / paths to `<engagement-root>/<project>/integrations.yml#boundaries.<source>.<key>`** as plain strings (existing pull-* skills consume strings — do NOT change the array element type). Idempotent: deduplicate by exact-string equality.
|
|
46
|
+
|
|
47
|
+
2. **Write a sidecar discovery record to `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_<source>_discovery.yml`** with the per-row metadata (`discovered_by`, `discovered_at`, `needs_review`, `query`, `request_id`, `confidence`). The sidecar lives **inside the contributor's alias folder** because discovery results are inherently per-identity (each contributor sees a different mailbox / chat / meeting set). Schema:
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
source: email | teams | meetings | sharepoint
|
|
51
|
+
project: <project>
|
|
52
|
+
customer_hint: '<hint>'
|
|
53
|
+
lookback_days: 90
|
|
54
|
+
discovered_at: '<ISO-8601>'
|
|
55
|
+
discovered_by: <alias>
|
|
56
|
+
query: '<exact WorkIQ prompt>'
|
|
57
|
+
workiq_request_id: '<request-id from response>'
|
|
58
|
+
total_candidates_found: <N>
|
|
59
|
+
candidates_persisted: <M> # ≤ 10 after cap
|
|
60
|
+
candidates_deferred: <N - M> # written to OPEN-QUESTIONS-DRAFT.md
|
|
61
|
+
results:
|
|
62
|
+
- value: '<string written to boundary>'
|
|
63
|
+
label: '<human-readable label>'
|
|
64
|
+
confidence: high | medium | low
|
|
65
|
+
needs_review: true
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
3. **If `total_candidates_found > 10`**, persist the top 10 by recency to the boundary and append the remaining N–10 to `<project>/OPEN-QUESTIONS-DRAFT.md` under `## Discovery sweep — candidates over cap` with one row per candidate.
|
|
69
|
+
|
|
70
|
+
4. **Add a `## Discovery Sweep Results` section to `<project>/bootstrap-status.md`** after `## Context Artifact Status`. Table shape:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
## Discovery Sweep Results
|
|
74
|
+
|
|
75
|
+
| Source | Hint | Query attempted | Candidates found | Persisted | Deferred | Discovered by |
|
|
76
|
+
|---|---|---|---|---|---|---|
|
|
77
|
+
| email | Northwind | "In my Inbox..." | 7 | 7 | 0 | ushak |
|
|
78
|
+
| teams | Northwind | "In my Teams chats..." | 14 | 10 | 4 | ushak |
|
|
79
|
+
| meetings | Northwind | "In my calendar..." | 3 | 3 | 0 | ushak |
|
|
80
|
+
| sharepoint | Northwind | "In my SharePoint sites..." | 0 | 0 | 0 | ushak |
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Behavior matrix (per source)
|
|
84
|
+
|
|
85
|
+
| Sweep result | `boundaries.<source>.<key>` written? | `last_status` | `retry_signal` | Open Questions written? |
|
|
86
|
+
|---|---|---|---|---|
|
|
87
|
+
| 0 candidates | no | `unresolved` (annotated `discovery-empty`) | `user-action` | yes — "Discovery sweep for `<source>` returned 0 hits for `<hint>`; widen hint or seed `boundaries.<source>.<key>` manually" |
|
|
88
|
+
| 1–10 candidates | yes (all) | `completed-with-coverage-gaps` (because rows are `needs_review`) | `watch` | only if any row low-confidence |
|
|
89
|
+
| > 10 candidates | yes (top 10 by recency) | `completed-with-coverage-gaps` | `watch` | yes — "Discovery sweep returned >10 candidates; review the deferred list" |
|
|
90
|
+
| **WorkIQ punted — no surface for this source** (sharepoint sites, teams channels — v4.8.1 empirical) | no | `unresolved` (annotated `discovery-empty-no-workiq-surface`) | `user-action` | yes — cite that this source has no known WorkIQ discovery surface and direct the user to manual configuration (the per-source doctrine has the exact wording) |
|
|
91
|
+
| Sweep query failed (WorkIQ error / classified per `fallback-status-reporting.instructions.md`) | no | `deferred` (write marker per `deferred-retry-on-workiq-fail.instructions.md`) | `retry` | no — next refresh will drain |
|
|
92
|
+
| Prerequisite genuinely missing (e.g. CRM shared config empty) | no | `blocked-config` | `user-action` | yes — cite specific missing field |
|
|
93
|
+
|
|
94
|
+
## Multi-contributor safety
|
|
95
|
+
|
|
96
|
+
When the boundary already has rows from another alias (or sibling `Evidence/<other-alias>/_discovery/` folders already have entries):
|
|
97
|
+
|
|
98
|
+
1. **Append-only** — the new alias's sweep adds rows that are not already present (dedupe by exact-string equality on the boundary value). Never remove or rewrite another alias's row.
|
|
99
|
+
2. **Sidecar files are per-contributor-folder-per-source-per-date** — each contributor writes only into their own `Evidence/<alias>/_discovery/` folder. Filenames are NOT suffixed with `-<alias>` (folder already namespaces the owner). On the same day, contributors `ushak` and `stand` produce `Evidence/ushak/_discovery/2026-05-26_email_discovery.yml` and `Evidence/stand/_discovery/2026-05-26_email_discovery.yml` respectively — no collision possible. Bootstrap-status's Discovery Sweep Results table shows one row per source × alias.
|
|
100
|
+
3. **`Discovered by` column in bootstrap-status's per-source Context Artifact Status row** cites the most recent discovering alias. Preserve other aliases' rows in `## Contributors who have bootstrapped this project` per `multi-user-shared-files.instructions.md`.
|
|
101
|
+
4. **NEVER write to another contributor's `Evidence/<other-alias>/_discovery/` folder.** Reading other aliases' discovery sidecars (e.g. to merge already-confirmed candidates into the shared boundary) is allowed and expected; writing into them is forbidden.
|
|
102
|
+
|
|
103
|
+
## Rerun behavior
|
|
104
|
+
|
|
105
|
+
When the user re-runs bootstrap on a project that already has populated boundaries:
|
|
106
|
+
|
|
107
|
+
| Boundary state | Sweep behavior |
|
|
108
|
+
|---|---|
|
|
109
|
+
| Empty | Run sweep (full discovery). |
|
|
110
|
+
| Has rows, none `needs_review: true` (all confirmed) | **Skip sweep.** Boundary is gospel — do not re-discover. |
|
|
111
|
+
| Has rows, some `needs_review: true` (sidecar shows confidence < high) | Run sweep. Merge new candidates by ID. Promote previously-discovered candidates from `needs_review: true` → `false` only if user has manually confirmed (i.e. removed the `needs_review` flag from the sidecar). |
|
|
112
|
+
| User passes `--force-rediscover` | Run sweep regardless of state. Merge new candidates; never delete user-confirmed rows. |
|
|
113
|
+
|
|
114
|
+
## Forbidden behaviors
|
|
115
|
+
|
|
116
|
+
1. **Declaring `blocked-config` without running the sweep first** for email/teams/meetings/sharepoint — see "The defect" above. CRM/ADO have their own mandates in `crm-bootstrap-discovery` / `ado-bootstrap-discovery`.
|
|
117
|
+
2. **Auto-narrowing the customer hint** ("Northwind" → "Northwind Healthcare Inc"). Use the hint verbatim. Smart-expansion is v4.9.0.
|
|
118
|
+
3. **Discovering across all sources in one mega-query.** Each source has its own narrow WorkIQ prompt (see per-source doctrines). Mega-queries punt to Graph and return empty.
|
|
119
|
+
4. **Inferring local OneDrive sync paths from the hint** for SharePoint `local_folders[]`. Discovery populates `site_urls[]` only.
|
|
120
|
+
5. **Calling Graph / `m365_*` directly for discovery.** Per `workiq-only.instructions.md` the four sources covered here use WorkIQ exclusively. The only allowed `m365_*` exceptions remain `m365_list_chat_messages` (parallel structured dump per pull-teams) and the per-source carve-outs already named in their pull-* SKILLs.
|
|
121
|
+
|
|
122
|
+
## References
|
|
123
|
+
|
|
124
|
+
- `crm-bootstrap-discovery.instructions.md` — the original "must-attempt-before-declaring-disabled" doctrine; this file mirrors its pattern for the WorkIQ-driven sources.
|
|
125
|
+
- `loop-bootstrap-discovery.instructions.md` — Loop-specific discovery + registry shape.
|
|
126
|
+
- `scope-boundaries.instructions.md` — the broader partial-determinism contract; this doctrine is the discovery-time enabler that makes boundaries achievable.
|
|
127
|
+
- `workiq-only.instructions.md` — what discovery is NOT allowed to call (Graph, m365_* for content).
|
|
128
|
+
- `status-taxonomy.instructions.md` — the closed-set status vocabulary; `unresolved` + `discovery-empty` annotation vs. `blocked-config`.
|
|
129
|
+
- `fallback-status-reporting.instructions.md` — how to classify WorkIQ punts during the sweep.
|
|
130
|
+
- `multi-user-shared-files.instructions.md` — append-only rules for the boundary file.
|
|
131
|
+
- `bootstrap-status-format.instructions.md` — where `## Discovery Sweep Results` slots in the report.
|