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.
- package/.github/copilot-instructions.kushi.md +38 -0
- package/README.md +33 -0
- package/bin/cli.mjs +2 -0
- package/package.json +17 -4
- package/plugin/agents/kushi.agent.md +155 -147
- package/plugin/instructions/ado-bootstrap-discovery.instructions.md +111 -0
- package/plugin/instructions/ado-engagement-tree.instructions.md +73 -0
- package/plugin/instructions/answer-from-evidence.instructions.md +1 -1
- package/plugin/instructions/auth-and-retry.instructions.md +51 -16
- package/plugin/instructions/azure-auth-patterns.instructions.md +13 -6
- package/plugin/instructions/bootstrap-status-format.instructions.md +113 -0
- package/plugin/instructions/capture-learnings.instructions.md +95 -0
- package/plugin/instructions/cleanup-on-resolution.instructions.md +69 -0
- package/plugin/instructions/crm-bootstrap-discovery.instructions.md +79 -0
- package/plugin/instructions/crm-internal-vs-confirmed.instructions.md +79 -0
- package/plugin/instructions/evidence-confidence-ladder.instructions.md +66 -0
- package/plugin/instructions/evidence-layout-canonical.instructions.md +115 -0
- package/plugin/instructions/evidence-thoroughness.instructions.md +82 -12
- package/plugin/instructions/full-view-gate.instructions.md +91 -0
- package/plugin/instructions/m365-id-registry.instructions.md +134 -0
- package/plugin/instructions/meetings-verbatim-required.instructions.md +176 -0
- package/plugin/instructions/run-reports.instructions.md +129 -0
- package/plugin/instructions/scope-boundaries.instructions.md +218 -0
- package/plugin/instructions/snapshot-vs-stream.instructions.md +2 -0
- package/plugin/instructions/update-ledger.instructions.md +132 -0
- package/plugin/instructions/verbatim-by-default.instructions.md +73 -0
- package/plugin/instructions/workiq-first.instructions.md +15 -31
- package/plugin/instructions/workiq-only.instructions.md +193 -0
- package/plugin/learnings/README.md +50 -0
- package/plugin/learnings/ado.md +45 -0
- package/plugin/learnings/crm.md +96 -0
- package/plugin/learnings/cross-cutting.md +36 -0
- package/plugin/learnings/email.md +33 -0
- package/plugin/learnings/meetings.md +30 -0
- package/plugin/learnings/misc.md +46 -0
- package/plugin/learnings/onenote.md +215 -0
- package/plugin/learnings/sharepoint.md +5 -0
- package/plugin/learnings/teams.md +5 -0
- package/plugin/plugin.json +22 -2
- package/plugin/prompts/apply-ado.prompt.md +14 -0
- package/plugin/prompts/propose-ado.prompt.md +12 -0
- package/plugin/reference-packs/fde/crm-field-manifest.md +165 -0
- package/plugin/skills/apply-ado-update/SKILL.md +125 -0
- package/plugin/skills/ask-project/SKILL.md +2 -0
- package/plugin/skills/bootstrap-project/SKILL.md +81 -3
- package/plugin/skills/propose-ado-update/SKILL.md +108 -0
- package/plugin/skills/pull-ado/SKILL.md +173 -23
- package/plugin/skills/pull-crm/SKILL.md +168 -15
- package/plugin/skills/pull-email/SKILL.md +139 -22
- package/plugin/skills/pull-meetings/SKILL.md +109 -25
- package/plugin/skills/pull-misc/README.md +84 -0
- package/plugin/skills/pull-misc/SKILL.md +257 -0
- package/plugin/skills/pull-misc/runner.mjs +280 -0
- package/plugin/skills/pull-onenote/README.md +90 -0
- package/plugin/skills/pull-onenote/SKILL.md +400 -51
- package/plugin/skills/pull-onenote/runner.mjs +356 -0
- package/plugin/skills/pull-onenote/scripts/recapture-section-url.mjs +295 -0
- package/plugin/skills/pull-onenote/write-snapshot.mjs +271 -0
- package/plugin/skills/pull-sharepoint/SKILL.md +44 -12
- package/plugin/skills/pull-teams/SKILL.md +40 -11
- package/plugin/skills/refresh-project/SKILL.md +33 -2
- package/plugin/skills/self-check/run.ps1 +186 -4
- package/plugin/templates/ado-update/discussion-comment.template.md +26 -0
- package/plugin/templates/ado-update/integrations-ado-writes.example.yml +49 -0
- package/plugin/templates/ado-update/proposed.template.md +78 -0
- package/plugin/templates/init/external-links.template.txt +30 -0
- package/plugin/templates/init/project-integrations.template.yml +57 -2
- package/plugin/templates/snapshot/meeting-verbatim.template.md +110 -0
- package/plugin/templates/snapshot/meetings-series-index.template.md +3 -1
- package/plugin/templates/snapshot/onenote-page.template.md +92 -23
- package/plugin/templates/weekly/meetings-stream.template.md +11 -6
- package/src/copilot-instructions.mjs +80 -0
- package/src/main.mjs +18 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**"
|
|
3
|
+
description: "Scope & Boundaries — every WorkIQ ask MUST cite a configured boundary; CRM/ADO require config.yml. Discovery is bounded, not free-form. No improvisation, no figure-it-out."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Scope & Boundaries (HARD RULE — partial-determinism contract)
|
|
7
|
+
|
|
8
|
+
Kushi's credibility depends on **knowing where it is allowed to look** and refusing
|
|
9
|
+
to improvise outside that perimeter. WorkIQ is powerful but fuzzy; Microsoft Graph
|
|
10
|
+
is broad and easy to mis-scope; CRM and ADO are tenant-specific. Without explicit
|
|
11
|
+
boundaries, the same question can return different evidence on different runs — and
|
|
12
|
+
every cited assertion becomes "trust me, I asked WorkIQ".
|
|
13
|
+
|
|
14
|
+
This file defines the contract that every `pull-*` skill, every WorkIQ ask, every
|
|
15
|
+
host-fallback Graph call, and every CRM/ADO probe MUST honor.
|
|
16
|
+
|
|
17
|
+
## The contract — three rules, no exceptions
|
|
18
|
+
|
|
19
|
+
### Rule 1 — Every ask cites a configured boundary
|
|
20
|
+
|
|
21
|
+
Before issuing **any** WorkIQ query, `m365_*` host call, Graph REST call, or CRM/ADO
|
|
22
|
+
REST call, the skill MUST resolve the boundary it is operating inside from
|
|
23
|
+
`<engagement-root>/<project>/integrations.yml boundaries:` (per-source) or the
|
|
24
|
+
global `<engagement-root>/.project-evidence/{crm,ado}/config.yml` (auth +
|
|
25
|
+
tenant + org). The resolved boundary MUST be recorded in the evidence file's
|
|
26
|
+
`## Source Basis` block, e.g.:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
## Source Basis
|
|
30
|
+
- path: workiq
|
|
31
|
+
- boundary: integrations.yml#boundaries.email.mailboxes=["Inbox","FDE-Intake"]
|
|
32
|
+
- boundary: integrations.yml#boundaries.email.sender_domains=["microsoft.com","hcahealthcare.com"]
|
|
33
|
+
- boundary: integrations.yml#boundaries.date_window_days=30
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
A query issued without a citable boundary is a **defect** — the skill must refuse
|
|
37
|
+
and ask the user to update `integrations.yml boundaries:` (or the relevant
|
|
38
|
+
config.yml) instead of guessing.
|
|
39
|
+
|
|
40
|
+
### Rule 2 — No source is queried outside its boundary
|
|
41
|
+
|
|
42
|
+
A boundary is **inclusive only**: only sources / mailboxes / channels / sections /
|
|
43
|
+
folders / domains explicitly listed are queried. There is no "and also widen if I
|
|
44
|
+
don't find enough" fallback. If the boundary is too narrow and a refresh comes
|
|
45
|
+
back light, the skill writes a Coverage Notes entry pointing at the boundary that
|
|
46
|
+
limited the scope and asks the user to widen it next run — it does NOT widen on
|
|
47
|
+
its own.
|
|
48
|
+
|
|
49
|
+
This is the partial-determinism contract: **the user controls scope; Kushi controls
|
|
50
|
+
depth.** Once the user has set the boundary, every refresh under that boundary
|
|
51
|
+
returns evidence over the same surface — no run-to-run drift.
|
|
52
|
+
|
|
53
|
+
### Rule 3 — CRM & ADO require explicit config.yml; no inference, no narration-from-email
|
|
54
|
+
|
|
55
|
+
`pull-crm` and `pull-ado` (and the downstream `propose-ado-update` /
|
|
56
|
+
`apply-ado-update`) are **HARD-fail** without their global config.yml:
|
|
57
|
+
|
|
58
|
+
| Skill | Hard prerequisite | Failure message (verbatim) |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `pull-crm` | `<engagement-root>/.project-evidence/crm/config.yml` exists with non-placeholder `environmentUrl` | `crm-config-missing — drop a filled config.yml at <engagement-root>/.project-evidence/crm/config.yml. See plugin/templates/init/crm-config.template.yml.` |
|
|
61
|
+
| `pull-ado` | `<engagement-root>/.project-evidence/ado/config.yml` exists with non-placeholder `organization` AND `defaultProject` | `ado-config-missing — drop a filled config.yml at <engagement-root>/.project-evidence/ado/config.yml. See plugin/templates/init/ado-config.template.yml.` |
|
|
62
|
+
| `propose-ado-update` | both above + `integrations.yml ado.engagement_id > 0` | per `propose-ado-update/SKILL.md` Prerequisites table |
|
|
63
|
+
|
|
64
|
+
Pre-v3.7.0 behavior allowed `pull-crm` to "narrate from email" when the live
|
|
65
|
+
config was missing — that is **explicitly forbidden as of v3.7.0**. CRM evidence
|
|
66
|
+
must come from CRM. Email evidence stays in the email source. Cross-source
|
|
67
|
+
synthesis happens at the consolidation step, not at the pull step.
|
|
68
|
+
|
|
69
|
+
## The boundaries schema
|
|
70
|
+
|
|
71
|
+
Lives in `<engagement-root>/<project>/integrations.yml` under a top-level
|
|
72
|
+
`boundaries:` key. Every per-source key is **optional** — but if a source's
|
|
73
|
+
boundary is omitted, that source is **disabled** for the project (not silently
|
|
74
|
+
queried with defaults).
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
boundaries:
|
|
78
|
+
date_window_days: 30 # default lookback window for streams (snapshot ignores)
|
|
79
|
+
|
|
80
|
+
email:
|
|
81
|
+
mailboxes: # required if email enabled
|
|
82
|
+
- "Inbox"
|
|
83
|
+
- "Inbox/FDE Intake" # well-known names OR folder IDs
|
|
84
|
+
sender_domains: # optional — narrows by sender
|
|
85
|
+
- "microsoft.com"
|
|
86
|
+
- "hcahealthcare.com"
|
|
87
|
+
subject_keywords: # optional — additional narrowing
|
|
88
|
+
- "HCA"
|
|
89
|
+
- "FE-2026-001458"
|
|
90
|
+
|
|
91
|
+
teams:
|
|
92
|
+
chat_ids: # required if teams enabled — pinned, not fuzzy-discovered
|
|
93
|
+
- "19:meeting_…@thread.v2"
|
|
94
|
+
channel_ids: [] # required for channel evidence (empty = no channels)
|
|
95
|
+
|
|
96
|
+
meetings:
|
|
97
|
+
series_join_urls: # required if meetings enabled — pinned, not subject-keyword-fuzzy
|
|
98
|
+
- "https://teams.microsoft.com/l/meetup-join/…"
|
|
99
|
+
organizer_emails: [] # optional — additional filter
|
|
100
|
+
|
|
101
|
+
onenote:
|
|
102
|
+
section_file_ids: # required if onenote enabled — drive-item IDs (narrowest)
|
|
103
|
+
- "3d0ad388-fd6b-45a8-8619-60dd709b7ade"
|
|
104
|
+
notebooks: [] # optional — broaden if needed; section_file_ids preferred
|
|
105
|
+
|
|
106
|
+
sharepoint:
|
|
107
|
+
local_folders: # required if sharepoint enabled
|
|
108
|
+
- "C:\\…\\HCA"
|
|
109
|
+
site_urls: [] # optional — for online-only docs
|
|
110
|
+
drive_ids: [] # optional — Graph-direct access
|
|
111
|
+
|
|
112
|
+
crm:
|
|
113
|
+
entity_sets: # optional — overrides global defaultEntitySet
|
|
114
|
+
- "msdyn_engagements"
|
|
115
|
+
record_ids: # required if crm enabled — pinned record GUIDs
|
|
116
|
+
- "<guid>"
|
|
117
|
+
request_ids: # OR pinned FE-XXXXX IDs
|
|
118
|
+
- "FE-2026-001458"
|
|
119
|
+
|
|
120
|
+
ado:
|
|
121
|
+
area_paths: # required if ado enabled
|
|
122
|
+
- "ISE-Engagements\\HCA"
|
|
123
|
+
iteration_paths: [] # optional — for sprint-scoped queries
|
|
124
|
+
initiative_query: "" # optional — saved WIQL query ID
|
|
125
|
+
work_item_ids: [] # optional — pin specific work items
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Why this shape
|
|
129
|
+
|
|
130
|
+
- **Per-source, not per-skill** — one place to read; every `pull-*` consumes from
|
|
131
|
+
`boundaries.<source>`.
|
|
132
|
+
- **IDs preferred over names** — `chat_ids` over `chat_topics`, `section_file_ids`
|
|
133
|
+
over `section_names`, `record_ids` over `title_contains`. IDs survive renames;
|
|
134
|
+
names drift.
|
|
135
|
+
- **Required vs optional is explicit** — the schema doc above marks each.
|
|
136
|
+
Bootstrap scaffolds the required keys; missing required keys = source disabled.
|
|
137
|
+
- **No global default boundaries** — each project declares its own; the only
|
|
138
|
+
cross-project default is `date_window_days`. Engagements differ; boundaries
|
|
139
|
+
must too.
|
|
140
|
+
|
|
141
|
+
## How `pull-*` skills MUST consume the boundary
|
|
142
|
+
|
|
143
|
+
Each per-source skill follows this template (already enforced in v3.7.0 SKILL.md
|
|
144
|
+
rewrites):
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
1. Resolve boundary:
|
|
148
|
+
- read integrations.yml#boundaries.<source>
|
|
149
|
+
- if missing or empty for a required key → REFUSE with explicit message:
|
|
150
|
+
"<source>-boundary-missing — add boundaries.<source>.<key> to
|
|
151
|
+
<engagement-root>/<project>/integrations.yml. See doctrine in
|
|
152
|
+
plugin/instructions/scope-boundaries.instructions.md."
|
|
153
|
+
2. Issue every query scoped to the resolved boundary:
|
|
154
|
+
- WorkIQ ask: include boundary keys in the prompt
|
|
155
|
+
("…in mailbox 'Inbox/FDE Intake' from senders @microsoft.com,@hcahealthcare.com…")
|
|
156
|
+
- m365_* host call: pass folder/chat/section/site IDs as filter args
|
|
157
|
+
- Graph REST: use exact resource paths, not /search?
|
|
158
|
+
3. Record the boundary in `## Source Basis` of every evidence file written.
|
|
159
|
+
4. If the boundary is too narrow (zero hits): write a Coverage Notes entry
|
|
160
|
+
citing the limiting boundary key. Do NOT widen the query.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Bootstrap behavior (per `bootstrap-project/SKILL.md`)
|
|
164
|
+
|
|
165
|
+
On first run for a new project, bootstrap MUST:
|
|
166
|
+
|
|
167
|
+
1. Create `<engagement-root>/<project>/integrations.yml` with the `boundaries:`
|
|
168
|
+
block scaffolded (every source as `_required: true` with empty value list).
|
|
169
|
+
2. Detect which sources have enough hints in `m365-mutable.json` to auto-populate
|
|
170
|
+
the boundary (e.g. a previously discovered `section_file_id` populates
|
|
171
|
+
`boundaries.onenote.section_file_ids` automatically).
|
|
172
|
+
3. For sources where bootstrap cannot auto-populate, write the source as
|
|
173
|
+
**disabled** (`enabled: false`) with a one-liner in `OPEN-QUESTIONS-DRAFT.md`
|
|
174
|
+
asking the user to fill the boundary and re-enable.
|
|
175
|
+
4. For CRM and ADO, ALSO check that the global `<engagement-root>/.project-evidence/{crm,ado}/config.yml`
|
|
176
|
+
exists and has non-placeholder values; if not, scaffold from
|
|
177
|
+
`plugin/templates/init/{crm,ado}-config.template.yml` and park in
|
|
178
|
+
`OPEN-QUESTIONS-DRAFT.md` with the path the user needs to fill.
|
|
179
|
+
|
|
180
|
+
Bootstrap **never silently widens** an empty boundary by inferring from the rest
|
|
181
|
+
of the corpus. Empty boundary = source disabled = explicit user action required.
|
|
182
|
+
|
|
183
|
+
## Coverage Notes — boundary-aware
|
|
184
|
+
|
|
185
|
+
Every per-entity Coverage Notes block (per `evidence-thoroughness.instructions.md`)
|
|
186
|
+
MUST now also enumerate which boundaries were hit and which were exhausted /
|
|
187
|
+
empty. Example:
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
## Coverage Notes
|
|
191
|
+
- Boundary: integrations.yml#boundaries.email.mailboxes=["Inbox","Inbox/FDE Intake"] — HIT (12 threads)
|
|
192
|
+
- Boundary: integrations.yml#boundaries.email.sender_domains=["microsoft.com","hcahealthcare.com"] — HIT (all 12 in-scope)
|
|
193
|
+
- Boundary: integrations.yml#boundaries.date_window_days=30 — HIT (full window)
|
|
194
|
+
- Source not queried: any mailbox outside boundary (by design — see scope-boundaries.instructions.md)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## What this rule replaces
|
|
198
|
+
|
|
199
|
+
- The pre-v3.7.0 "WorkIQ-first, fall back to Graph, then ask user" cascade is
|
|
200
|
+
REPLACED by "WorkIQ-only within boundary, ask user when WorkIQ fails after
|
|
201
|
+
doubled-strict retry." Per `workiq-only.instructions.md` (v3.11.0+), Graph /
|
|
202
|
+
`m365_*` are FORBIDDEN as fallbacks for in-scope M365 sources. There is no
|
|
203
|
+
scope expansion at any tier.
|
|
204
|
+
- The pre-v3.7.0 `pull-crm` "narrate from email" fallback is REMOVED. CRM
|
|
205
|
+
evidence requires CRM source.
|
|
206
|
+
- The pre-v3.7.0 fuzzy-discovery loops in `pull-ado` (title_contains, tags_contains)
|
|
207
|
+
are PRESERVED but only run inside `boundaries.ado.area_paths`.
|
|
208
|
+
|
|
209
|
+
## Cross-references
|
|
210
|
+
|
|
211
|
+
- `evidence-thoroughness.instructions.md` — depth bar (orthogonal: depth applies
|
|
212
|
+
inside the boundary; this rule defines the boundary).
|
|
213
|
+
- `workiq-only.instructions.md` — query strategy (now scoped per Rule 1; Graph /
|
|
214
|
+
`m365_*` fallbacks FORBIDDEN for in-scope M365 sources).
|
|
215
|
+
- `bootstrap-project/SKILL.md` — scaffolding the boundaries block.
|
|
216
|
+
- `pull-*/SKILL.md` (all 7) — Boundaries (REQUIRED) sub-section enforces Rule 1+2.
|
|
217
|
+
- `pull-crm/SKILL.md` + `pull-ado/SKILL.md` — Hard prerequisites enforce Rule 3.
|
|
218
|
+
- `propose-ado-update/SKILL.md` — Prerequisites table (already enforces ADO config + engagement_id).
|
|
@@ -29,6 +29,8 @@ Every source produces evidence in TWO distinct shapes. Mixing them is a defect.
|
|
|
29
29
|
|
|
30
30
|
## Storage layout
|
|
31
31
|
|
|
32
|
+
> **Path is canonical** — every per-source artifact lives under `Evidence/<alias>/<source>/` and **nowhere else** under `<project>/`. Sibling folders like `<project>/email-context/`, `<project>/notes/`, `<project>/_Weekly Summaries/` are FORBIDDEN per `evidence-layout-canonical.instructions.md`. Bootstrap and refresh auto-migrate any legacy folders into `Evidence/<alias>/<source>/_legacy_*_pre-bootstrap/`.
|
|
33
|
+
|
|
32
34
|
```
|
|
33
35
|
<engagement-root>/<project>/Evidence/<alias>/
|
|
34
36
|
email/
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**"
|
|
3
|
+
description: "Write-path doctrine for Kushi. Any skill that writes outside the engagement folder (currently: ADO Initiative field + Discussion comment) MUST flow through propose → review/approve → apply → append-to-ledger, with citation, confidence, fingerprint, and a reverse op recorded for every applied item. Read-only refresh and aggregation are NOT subject to this gate."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Update Ledger — Write-Path Doctrine
|
|
7
|
+
|
|
8
|
+
Kushi is read-first. Aggregation, refresh, ask, and report skills produce no external side effects — they only write inside the engagement folder under `Evidence/`, `State/`, `Reports/`, etc.
|
|
9
|
+
|
|
10
|
+
The **write path** — currently `apply-ado-update`, future possibly CRM / OneNote / SharePoint — is governed by this file. Any new write skill must follow these rules and pass self-check rule **C13** (write-path safety).
|
|
11
|
+
|
|
12
|
+
## The 4 stages, every time
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
propose → review (or auto-allowlist) → apply → append to ledger
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
No write skill skips a stage. No write skill writes without a corresponding ledger entry in the same operation.
|
|
19
|
+
|
|
20
|
+
## Where the ledger lives
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
<engagement-root>/<project>/ado-updates/<YYYY-MM-DD>/
|
|
24
|
+
proposed.md ← from propose-ado-update (Markdown, human-reviewable)
|
|
25
|
+
ledger.jsonl ← from apply-ado-update (one line per applied write)
|
|
26
|
+
planned.jsonl ← preview-stub only: writes that would have happened
|
|
27
|
+
attachments/ ← optional: payloads sent to ADO (raw HTML for comments)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
One subfolder per run date, **inside the project folder** (sibling to `Evidence/`, `State/`, `Reports/`). Files are append-only — never edit a past ledger entry. Mistakes are corrected by appending a `revert` entry (see "Reversal").
|
|
31
|
+
|
|
32
|
+
## Ledger entry schema
|
|
33
|
+
|
|
34
|
+
One JSON object per line (JSONL), one entry per applied write. Required fields:
|
|
35
|
+
|
|
36
|
+
| Field | Type | Notes |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `timestamp` | ISO-8601 UTC | When the write was sent. |
|
|
39
|
+
| `initiativeId` | int | ADO work item ID written to. (Same value as `integrations.yml ado.engagement_id`.) |
|
|
40
|
+
| `org`, `project` | string | ADO org + project (so a ledger entry is unambiguous standalone). |
|
|
41
|
+
| `kind` | `"field"` \| `"comment"` | What was written. |
|
|
42
|
+
| `fieldRefName` | string \| null | For `kind: "field"` — the ADO reference name. Null for `comment`. |
|
|
43
|
+
| `currentValue` | string | Value just before the write (from the optimistic-lock pre-fetch). |
|
|
44
|
+
| `proposedValue` | string | Value sent in the write. |
|
|
45
|
+
| `appliedValue` | string | Value confirmed in the write response. May differ from proposed if ADO normalized it. |
|
|
46
|
+
| `revBefore`, `revAfter` | int | ADO `/rev` values before/after — together with `currentValue` they form the reversal anchor. |
|
|
47
|
+
| `approver` | string | `<alias>` for human, `auto:<rule-name>` for allowlisted auto-apply, never empty. |
|
|
48
|
+
| `confidence` | `"high" \| "medium" \| "low"` | Carried forward from `proposed.md`. |
|
|
49
|
+
| `evidenceCitations` | string[] | Each entry is `<source-path> · <YYYY-MM-DD>`. Min 1; entries with 0 citations MUST NOT be approved. |
|
|
50
|
+
| `fingerprint` | string | Deterministic, derived from project + week + initiativeId + kind. Used by duplicate detection on the next run. Format: `kushi-weekly-<YYYY-WW>-<initiativeId>-<kind>`. |
|
|
51
|
+
| `reverseOp` | object | What to do to undo this write. See "Reversal". |
|
|
52
|
+
| `result` | `"ok" \| "rev-mismatch" \| "duplicate-skipped" \| "error"` | Final disposition. |
|
|
53
|
+
| `errorMessage` | string \| null | Populated only when `result: "error"`. |
|
|
54
|
+
| `kushiVersion` | semver | The version of `kushi-agents` that wrote this entry. |
|
|
55
|
+
|
|
56
|
+
Anything else (correlation IDs, request payload hashes) is allowed but optional.
|
|
57
|
+
|
|
58
|
+
## Reversal
|
|
59
|
+
|
|
60
|
+
Every ledger entry includes a `reverseOp` that, applied alone, restores the prior state:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
"reverseOp": {
|
|
64
|
+
"kind": "field",
|
|
65
|
+
"fieldRefName": "Custom.FDEStatusSummary",
|
|
66
|
+
"patch": [
|
|
67
|
+
{ "op": "test", "path": "/rev", "value": <revAfter> },
|
|
68
|
+
{ "op": "add", "path": "/fields/Custom.FDEStatusSummary", "value": "<currentValue>" }
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
For comments, the reverse op is a `DELETE` of the comment ID returned by the POST:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
"reverseOp": {
|
|
77
|
+
"kind": "comment",
|
|
78
|
+
"commentId": 9871,
|
|
79
|
+
"method": "DELETE",
|
|
80
|
+
"url": "https://dev.azure.com/{org}/{project}/_apis/wit/workItems/{id}/comments/9871?api-version=7.1-preview.4"
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
A future `revert-ado-update` skill (not in v0.1.0-preview) will read the latest ledger and apply reverse ops in reverse chronological order, again gated by user approval.
|
|
85
|
+
|
|
86
|
+
## Approval rules (HARD)
|
|
87
|
+
|
|
88
|
+
1. **No write without an entry in `proposed.md`.** Apply skills MUST refuse to write items that aren't in the proposal, even if asked.
|
|
89
|
+
2. **No write without ≥ 1 citation.** Items with empty `evidenceCitations` are rejected at the gate.
|
|
90
|
+
3. **No silent overwrite of drift.** If the live ADO value differs from the `currentValue` recorded in `proposed.md`, the apply step MUST stop and require explicit re-approval (showing both values).
|
|
91
|
+
4. **Auto-apply is opt-in, narrow, and per-field.** Allowed only when:
|
|
92
|
+
- `writes.<kind>.autoApply: true` in `<engagement-root>/.kushi/ado-update.yml`, AND
|
|
93
|
+
- `confidence == "high"`, AND
|
|
94
|
+
- The proposed value matches a configured pattern (e.g., `<MMM YYYY>: <text>` for `statusSummary` with `strategy: append-month`).
|
|
95
|
+
Items failing any of these auto-apply criteria fall back to interactive approval.
|
|
96
|
+
5. **No bulk apply across projects.** One project per invocation. (Iterating projects is the orchestrator's job; the apply skill itself is single-project.)
|
|
97
|
+
6. **No write outside the allowlist.** The apply skill must reject any field reference name or work-item ID not declared in the project's `integrations.yml ado.writes.allowlist.fields` (and the work-item ID must equal `ado.engagement_id`).
|
|
98
|
+
|
|
99
|
+
## Duplicate detection
|
|
100
|
+
|
|
101
|
+
Before writing a comment, fetch the latest N comments on the work item and look for the Kushi fingerprint line:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
— Generated by Kushi v<version> · proposed <YYYY-MM-DD> · ledger:ado-updates/<YYYY-MM-DD>/ledger.jsonl
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
If a comment with the same `kushi-weekly-<YYYY-WW>-<initiativeId>-comment` fingerprint exists for the current ISO week → record `result: "duplicate-skipped"` in the ledger and do NOT write again. Field updates use idempotency on the value itself (same `<MMM YYYY>: ...` line not duplicated).
|
|
108
|
+
|
|
109
|
+
## What is NOT subject to this doctrine
|
|
110
|
+
|
|
111
|
+
- `aggregate`, `bootstrap`, `refresh`, `consolidate`, `pull-*` — pure reads from M365 + CRM + ADO. They write to the engagement folder only.
|
|
112
|
+
- `ask`, `fde-*`, `state`, `project-status` — pure local file operations.
|
|
113
|
+
- `self-check`, `intro` — never write outside the kushi install.
|
|
114
|
+
|
|
115
|
+
The gate exists because **writing into someone else's system of record demands an audit trail and a path back**. Reads inside the engagement folder do not.
|
|
116
|
+
|
|
117
|
+
## Self-check coverage
|
|
118
|
+
|
|
119
|
+
A future self-check rule **C13: write-path safety** will verify:
|
|
120
|
+
|
|
121
|
+
- Every skill folder whose `SKILL.md` contains the word `PATCH` or `POST` (HTTP write verbs) outside a fenced quote → must reference this instruction file in its `## References` section.
|
|
122
|
+
- Every such skill must declare its allowlist source (config file path) explicitly in the SKILL.md.
|
|
123
|
+
- The repo MUST NOT contain a skill that issues an ADO write call without a corresponding `ledger.jsonl` append in the same code path.
|
|
124
|
+
|
|
125
|
+
C13 is not yet implemented in `self-check/run.ps1` — added when `apply-ado-update` graduates from preview-stub to write-enabled.
|
|
126
|
+
|
|
127
|
+
## References
|
|
128
|
+
|
|
129
|
+
- `propose-ado-update` SKILL.md — produces the `proposed.md` this doctrine governs.
|
|
130
|
+
- `apply-ado-update` SKILL.md — the only code path authorized to write to ADO; consumes `proposed.md`, appends to `ledger.jsonl`.
|
|
131
|
+
- `azure-auth-patterns.instructions.md` — pre-flight + token + tenant guards that protect every write.
|
|
132
|
+
- `side-by-side-config.instructions.md` — `integrations.yml ado.writes:` follows the same template-vs-live pattern.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**"
|
|
3
|
+
description: "Verbatim-by-default rule — every pull-* skill captures full bodies and full content as the default mode. Headlines / one-line summaries / 'preview only' are defects. The user does NOT have to ask for detail; detail is the contract."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Verbatim-by-default (HARD RULE)
|
|
7
|
+
|
|
8
|
+
Every `pull-<source>` skill captures **full content verbatim** as its default mode. The user does NOT have to say "more detail" or "give me the full body" — that's the contract, every time.
|
|
9
|
+
|
|
10
|
+
This restates and hardens the existing thoroughness contract in `evidence-thoroughness.instructions.md` with one additional rule: **the user asking for detail is a defect signal, not a feature request**.
|
|
11
|
+
|
|
12
|
+
## What "verbatim" means per source
|
|
13
|
+
|
|
14
|
+
| Source | Default capture |
|
|
15
|
+
|---|---|
|
|
16
|
+
| Email | Full body of every message in scope, every header, every attachment metadata. NOT just subject + sender + 200-char preview. |
|
|
17
|
+
| Teams chats | Every message in every in-scope thread, full text, sender, timestamp, reactions, attachments, replies. NOT just an outcome line. |
|
|
18
|
+
| Meetings | Full transcript walk-through with verbatim quotes + timestamps, every attendee, every artifact link. NOT a 3-bullet "what happened". |
|
|
19
|
+
| OneNote | Full page bodies, every page in scope, last-modified + author. NOT page titles only. |
|
|
20
|
+
| SharePoint | Full extracted body of every key file + every recently-modified file (top-N) + every user-pinned file. NOT a folder tree alone. |
|
|
21
|
+
| CRM | Every field the API returns, all long-text fields verbatim, every annotation/note verbatim, every related activity. NOT a 5-field summary. |
|
|
22
|
+
| ADO | Engagement + every child WI; per-item all fields verbatim, every comment verbatim, every revision verbatim. NOT parent-only. |
|
|
23
|
+
|
|
24
|
+
## Anti-patterns (defects to refuse, not negotiate)
|
|
25
|
+
|
|
26
|
+
The following are defects in any `pull-*` output. If the runtime detects one, it MUST auto-retry with stricter prompting per `thoroughness-detector.instructions.md` rather than ship the thin output.
|
|
27
|
+
|
|
28
|
+
1. **Email preview-only** — capturing only `bodyPreview` (200 chars) instead of `body`. Defect.
|
|
29
|
+
2. **"And N more"** — any phrase like "...and 12 more emails", "10 of 47 shown", "see source for rest". Defect.
|
|
30
|
+
3. **Single-message-per-thread** — collapsing a 30-message thread into one "summary" line. Defect.
|
|
31
|
+
4. **Speaker-name only transcripts** — listing meeting attendees and decisions without the chronological verbatim quotes. Defect.
|
|
32
|
+
5. **Folder tree without bodies** — SharePoint snapshot that lists files but extracts no key-file bodies. Defect.
|
|
33
|
+
6. **CRM "key fields"-only** — pulling only title + status + customer instead of every populated field + all long-text + all annotations. Defect.
|
|
34
|
+
7. **ADO parent-only** — pulling the engagement WI without expanding the tree to every child + per-item comments + per-item revisions. Defect.
|
|
35
|
+
8. **Inferred narrative as substitute for body** (NEW v3.7.6.1) — when a source returns no body / `page-body-unavailable` / `body-not-extractable`, writing an "AI Narrative Summary" that infers what the artifact "likely contains" from adjacent evidence (other emails, chat traffic, page titles, file names). This is fabrication, not capture, and it pollutes the citation chain. The correct behavior is to write the header + the unavailable marker + a `next_step` asking the user to paste — and STOP. Empty is the correct state until the body is actually retrieved.
|
|
36
|
+
9. **Meeting summary without sibling verbatim/ folder** (NEW v3.10.0) — meetings are the one EXPIRING evidence class. A per-meeting curated block in `Evidence/<alias>/meetings/stream/*.md` without a matching `Evidence/<alias>/meetings/verbatim/<YYYY-MM-DD-HHMM>_<slug>/` directory is a defect even if the curated block is rich. See `meetings-verbatim-required.instructions.md` for the full contract and self-check rule D13. Rationale: Teams recordings and VTT transcripts are purged by tenant retention (often within 60 days). If the only artifact captured is the curated summary, the underlying evidence is unrecoverable once the source expires.
|
|
37
|
+
|
|
38
|
+
## The "you should do better" defect
|
|
39
|
+
|
|
40
|
+
When a user reads evidence and says any of:
|
|
41
|
+
|
|
42
|
+
- "you should do better and get details better"
|
|
43
|
+
- "this is too light"
|
|
44
|
+
- "where's the detail from `<source>`?"
|
|
45
|
+
- "i want detail by default"
|
|
46
|
+
- "why is nothing captured?"
|
|
47
|
+
|
|
48
|
+
— that is the **highest-severity** thoroughness defect. Treat it as a hard rule violation, not a preference. Specifically:
|
|
49
|
+
|
|
50
|
+
1. The skill that produced the thin output is at fault. Identify which `pull-*` skill underdelivered.
|
|
51
|
+
2. Re-pull from source at full depth in the same turn (no asking for confirmation).
|
|
52
|
+
3. Append a `learnings/<source>.md` entry per `capture-learnings.instructions.md` describing the miss + the fix.
|
|
53
|
+
4. If the miss was a doctrinal gap (skill spec didn't require the thing), update the SKILL.md or this instruction in the same commit.
|
|
54
|
+
|
|
55
|
+
## Orchestrator contract
|
|
56
|
+
|
|
57
|
+
`bootstrap-project` and `refresh-project` MUST dispatch every enabled `pull-<source>` skill that has its boundary satisfied. **Skipping a source silently is a defect** — if a source is not pulled, the orchestrator must:
|
|
58
|
+
|
|
59
|
+
1. Log the skip with reason (`boundary-missing`, `auth-blocked`, `user-disabled`) in the per-user refresh report (per `run-reports.instructions.md`).
|
|
60
|
+
2. Mark the source `not-pulled-this-run` in `bootstrap-status.md`'s Context Artifact Status table.
|
|
61
|
+
3. Suggest the fix in the report's "Skips & gaps" section.
|
|
62
|
+
|
|
63
|
+
A run that pulled CRM + ADO but silently omitted email is a defect of the orchestrator, even if every individual `pull-*` it did invoke was perfect.
|
|
64
|
+
|
|
65
|
+
## Self-check enforcement
|
|
66
|
+
|
|
67
|
+
`plugin/skills/self-check/run.ps1` deep-mode rule **D11** (added v3.7.6):
|
|
68
|
+
- For each per-user refresh report, warn if any source listed in `<project>/integrations.yml#boundaries.<source>` (with non-empty boundary) is absent from the report's "What was done" table.
|
|
69
|
+
- Warn on per-source evidence files smaller than the per-source minimum byte threshold (defaults: email-stream 5KB / week, teams-stream 5KB / week, meetings-stream 8KB / week, onenote-snapshot 3KB / page, sharepoint key file 2KB / file, crm-snapshot 4KB / record, ado-snapshot 3KB / WI). Below threshold suggests headlines-only.
|
|
70
|
+
|
|
71
|
+
## Apply
|
|
72
|
+
|
|
73
|
+
Every `pull-*` SKILL.md MUST reference this instruction file in its frontmatter or first paragraph alongside `evidence-thoroughness.instructions.md`. The two are co-equal.
|
|
@@ -1,47 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
applyTo: "**"
|
|
3
|
-
description: "
|
|
3
|
+
description: "DEPRECATED as of kushi v3.11.0. The canonical M365 doctrine is workiq-only.instructions.md. This file is preserved as a stub redirect — do NOT use any of the old Graph-REST-fallback language; it is OVERRIDDEN by workiq-only."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# DEPRECATED — see `workiq-only.instructions.md`
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This file is a **deprecation stub** as of kushi **v3.11.0** (formalised in **v3.12.0**).
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The previous "WorkIQ-first, Graph REST as last-resort fallback" cascade is **REMOVED**. It produced thin metadata-only evidence, silent fall-throughs, and a defect-looking trail in coverage.md because the Graph / `m365_*` host tools fail nearly every call in this workspace.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## The new canonical rule
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
2. **Ask user to paste** — if WorkIQ is missing, unauthenticated, or returns insufficient content, ask the user to paste the data **verbatim** (NOT summarized). This is a first-class path, not an error.
|
|
16
|
-
3. **Graph REST / `m365_*` host tools** — **last resort only**, used non-blocking with an explicit `➖ partial via Graph REST` marker in the evidence file. Skills MUST NOT silently fall through to Graph when WorkIQ fails; the user must be informed and given a chance to paste.
|
|
14
|
+
All M365 evidence retrieval (Email, Teams, OneNote, SharePoint, Meetings, Calendar discovery) is governed by:
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
**`plugin/instructions/workiq-only.instructions.md`** — WorkIQ is the ONLY path. Graph REST and `m365_*` host tools are **FORBIDDEN** as fallbacks for in-scope M365 sources. The single allowed exception is `m365_list_chat_messages` as a parallel structured-data dump (`chat-messages.json`) alongside the WorkIQ pull — NEVER as a substitute.
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
When WorkIQ fails after a doubled-strict retry → ask the user to paste verbatim. User-paste is a **first-class evidence path**, not a degradation.
|
|
21
19
|
|
|
22
|
-
##
|
|
20
|
+
## Out of WorkIQ scope (unchanged)
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|---|---|
|
|
26
|
-
| Email | `Find emails about <project> in folder <folder> between <start> and <end>, give me sender, recipients, full body, and reply chain` |
|
|
27
|
-
| Teams Chats | `Show full message-by-message reproduction of <project> Teams threads between <start> and <end>` |
|
|
28
|
-
| OneNote | `Get full page bodies from OneNote section <section> notebook <notebook> modified between <start> and <end>` |
|
|
29
|
-
| SharePoint | `List SharePoint files for <project> modified between <start> and <end> with author and brief content summary` |
|
|
30
|
-
| Meetings | `Get full transcript and Copilot recap for meeting <subject> on <date>` |
|
|
31
|
-
| CRM | `Get CRM engagement record FE-<id> with all field values, comments, and audit history` |
|
|
32
|
-
| ADO | `Get ADO work items for <project> updated between <start> and <end> with full discussion thread` |
|
|
22
|
+
These remain on their direct paths and are NOT governed by `workiq-only`:
|
|
33
23
|
|
|
34
|
-
|
|
24
|
+
- **CRM (Dataverse)** — REST via `az account get-access-token --resource https://<env>.crm.dynamics.com` per `crm-bootstrap-discovery.instructions.md` + `pull-crm/SKILL.md`.
|
|
25
|
+
- **ADO** — REST via `az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798` per `ado-bootstrap-discovery.instructions.md` + `pull-ado/SKILL.md`.
|
|
35
26
|
|
|
36
|
-
|
|
27
|
+
## Migration
|
|
37
28
|
|
|
38
|
-
|
|
39
|
-
2. Probe `workiq ask -q "ping"`. If EULA prompt → run `workiq accept-eula` once, retry. If auth-failed → log `workiq-auth-failed` and ask user to re-authenticate.
|
|
40
|
-
3. Only after a successful probe, proceed to per-source queries.
|
|
29
|
+
Every reference to `workiq-first.instructions.md` in skills / agents / docs should be updated to `workiq-only.instructions.md`. References to the old "Graph REST as last-resort" paragraph are invalid and MUST be removed.
|
|
41
30
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
Graph is allowed only as a non-blocking last resort, and only with:
|
|
45
|
-
- An explicit `➖ partial via Graph REST` marker in the evidence file.
|
|
46
|
-
- A `next_step` line telling the user to install/repair WorkIQ for full-fidelity capture next run.
|
|
47
|
-
- Never as a silent default.
|
|
31
|
+
See `workiq-only.instructions.md` for: the canonical per-source WorkIQ prompts, the doubled-strict retry pattern, the user-paste fallback, the forbidden-paths list, and the coverage.md requirements.
|