kushi-agents 5.0.0 → 5.0.2
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/README.md +30 -7
- package/bin/cli.mjs +73 -45
- package/package.json +51 -51
- package/plugin/instructions/agentskills-compliance.instructions.md +144 -0
- package/plugin/instructions/multi-host-install.instructions.md +125 -0
- package/plugin/instructions/plan-validate-execute.instructions.md +75 -0
- package/plugin/instructions/release-genealogy.instructions.md +52 -0
- package/plugin/skills/aggregate-project/SKILL.md +11 -2
- package/plugin/skills/apply-ado-update/SKILL.md +11 -2
- package/plugin/skills/ask-project/SKILL.md +1 -1
- package/plugin/skills/bootstrap-project/SKILL.md +39 -127
- package/plugin/skills/bootstrap-project/references/discovery-sweep.md +40 -0
- package/plugin/skills/bootstrap-project/references/pull-dispatch.md +50 -0
- package/plugin/skills/bootstrap-project/references/registry-persistence.md +55 -0
- package/plugin/skills/build-state/SKILL.md +50 -2
- package/plugin/skills/consolidate-evidence/SKILL.md +11 -2
- package/plugin/skills/dashboard/SKILL.md +20 -1
- package/plugin/skills/emit-vertex/SKILL.md +10 -1
- package/plugin/skills/fde-intake/SKILL.md +10 -1
- package/plugin/skills/fde-report/SKILL.md +10 -1
- package/plugin/skills/fde-triage/SKILL.md +10 -1
- package/plugin/skills/intro/SKILL.md +1 -1
- package/plugin/skills/link-entities/SKILL.md +43 -1
- package/plugin/skills/project-status/SKILL.md +1 -1
- package/plugin/skills/propose-ado-update/SKILL.md +11 -2
- package/plugin/skills/pull-ado/SKILL.md +26 -9
- package/plugin/skills/pull-crm/SKILL.md +39 -125
- package/plugin/skills/pull-crm/references/dataverse-doctrine.md +108 -0
- package/plugin/skills/pull-crm/references/legacy-shape.md +28 -0
- package/plugin/skills/pull-email/SKILL.md +33 -79
- package/plugin/skills/pull-email/references/retrieval-order.md +43 -0
- package/plugin/skills/pull-email/references/two-pass-pull.md +41 -0
- package/plugin/skills/pull-loop/SKILL.md +194 -177
- package/plugin/skills/pull-meetings/SKILL.md +35 -72
- package/plugin/skills/pull-meetings/references/legacy-stream.md +15 -0
- package/plugin/skills/pull-meetings/references/verbatim-capture.md +61 -0
- package/plugin/skills/pull-misc/SKILL.md +24 -7
- package/plugin/skills/pull-onenote/SKILL.md +207 -555
- package/plugin/skills/pull-onenote/references/playwright-fallback.md +111 -0
- package/plugin/skills/pull-onenote/references/preflight.md +85 -0
- package/plugin/skills/pull-onenote/references/runtime-contract.md +118 -0
- package/plugin/skills/pull-sharepoint/SKILL.md +26 -9
- package/plugin/skills/pull-teams/SKILL.md +26 -9
- package/plugin/skills/refresh-project/SKILL.md +24 -2
- package/plugin/skills/self-check/SKILL.md +9 -1
- package/plugin/skills/self-check/run.ps1 +216 -4
- package/plugin/skills/setup/SKILL.md +14 -120
- package/plugin/skills/setup/references/onedrive-pin-sync.md +60 -0
- package/plugin/skills/setup/references/recovery-prompts.md +81 -0
- package/plugin/skills/tour/SKILL.md +18 -1
- package/plugin/skills/vertex-link/SKILL.md +1 -1
- package/src/constants.mjs +39 -1
- package/src/multi-host-install.test.mjs +170 -0
- package/src/multi-host.mjs +277 -0
|
@@ -1,180 +1,197 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: "pull-loop"
|
|
3
|
-
version: "1.0.0"
|
|
4
|
-
description: "
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Skill: pull-loop
|
|
8
|
-
|
|
9
|
-
> **Doctrine contracts** — This skill operates under the standard pull-* doctrine set:
|
|
10
|
-
> - `verbatim-by-default.instructions.md` — full page bodies by default; no preview-grade pulls.
|
|
11
|
-
> - `m365-id-registry.instructions.md` — discover-once / consume-deterministically (workspaceId + pageId schema).
|
|
12
|
-
> - `loop-bootstrap-discovery.instructions.md` — workspace/page registration shape + flow.
|
|
13
|
-
> - `capture-learnings.instructions.md` — every Loop-specific fix logs to `plugin/learnings/loop.md`.
|
|
14
|
-
> - `cleanup-on-resolution.instructions.md` — when a page resolves, all stale `unresolved` / `page-body-unavailable` markers are upgraded in the same turn.
|
|
15
|
-
> - `run-reports.instructions.md` — every refresh writes a per-user report under `Evidence/<alias>/refresh-reports/`.
|
|
16
|
-
> - `evidence-thoroughness.instructions.md` — runtime detector + auto-retry; partial body = failure not "ok".
|
|
17
|
-
> - `evidence-layout-canonical.instructions.md` — all artifacts under `<project>/Evidence/<alias>/loop/{snapshot,stream}/`.
|
|
18
|
-
> - `per-source-verification-gate.instructions.md` — gate §2 loop row + §2a canonical kind.
|
|
19
|
-
> - `issue-recovery.instructions.md` — apply when discovery or capture exposes a doctrine gap.
|
|
20
|
-
|
|
21
|
-
Pulls **loop** evidence in two shapes per `snapshot-vs-stream.instructions.md`:
|
|
22
|
-
|
|
23
|
-
- **snapshot/** — full Loop page bodies — one file per registered page with `lastModified` + verbatim body
|
|
24
|
-
- **stream/** — page-edit events (who edited what, when) since last watermark — one file per ISO week in the window
|
|
25
|
-
|
|
26
|
-
Standalone Loop components embedded in Teams/OneNote/Email are NOT captured here — they are captured by their host source's pull skill to avoid double-counting. See `loop-bootstrap-discovery.instructions.md` §Surface model.
|
|
27
|
-
|
|
28
|
-
##
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
##
|
|
1
|
+
---
|
|
2
|
+
name: "pull-loop"
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "USE WHEN refresh-project / bootstrap-project dispatches Loop source OR the user says \"pull Loop for <X>\" AND the project has loop workspaces/pages registered. DO NOT USE for general Loop content discovery. Capability: pulls Microsoft Loop evidence in snapshot (full page bodies) + stream (page-edit events) shape per loop-source doctrine."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: pull-loop
|
|
8
|
+
|
|
9
|
+
> **Doctrine contracts** — This skill operates under the standard pull-* doctrine set:
|
|
10
|
+
> - `verbatim-by-default.instructions.md` — full page bodies by default; no preview-grade pulls.
|
|
11
|
+
> - `m365-id-registry.instructions.md` — discover-once / consume-deterministically (workspaceId + pageId schema).
|
|
12
|
+
> - `loop-bootstrap-discovery.instructions.md` — workspace/page registration shape + flow.
|
|
13
|
+
> - `capture-learnings.instructions.md` — every Loop-specific fix logs to `plugin/learnings/loop.md`.
|
|
14
|
+
> - `cleanup-on-resolution.instructions.md` — when a page resolves, all stale `unresolved` / `page-body-unavailable` markers are upgraded in the same turn.
|
|
15
|
+
> - `run-reports.instructions.md` — every refresh writes a per-user report under `Evidence/<alias>/refresh-reports/`.
|
|
16
|
+
> - `evidence-thoroughness.instructions.md` — runtime detector + auto-retry; partial body = failure not "ok".
|
|
17
|
+
> - `evidence-layout-canonical.instructions.md` — all artifacts under `<project>/Evidence/<alias>/loop/{snapshot,stream}/`.
|
|
18
|
+
> - `per-source-verification-gate.instructions.md` — gate §2 loop row + §2a canonical kind.
|
|
19
|
+
> - `issue-recovery.instructions.md` — apply when discovery or capture exposes a doctrine gap.
|
|
20
|
+
|
|
21
|
+
Pulls **loop** evidence in two shapes per `snapshot-vs-stream.instructions.md`:
|
|
22
|
+
|
|
23
|
+
- **snapshot/** — full Loop page bodies — one file per registered page with `lastModified` + verbatim body
|
|
24
|
+
- **stream/** — page-edit events (who edited what, when) since last watermark — one file per ISO week in the window
|
|
25
|
+
|
|
26
|
+
Standalone Loop components embedded in Teams/OneNote/Email are NOT captured here — they are captured by their host source's pull skill to avoid double-counting. See `loop-bootstrap-discovery.instructions.md` §Surface model.
|
|
27
|
+
|
|
28
|
+
## Gotchas
|
|
29
|
+
|
|
30
|
+
- **Loop workspaces are NOT discoverable via WorkIQ** — must be registered at setup time per `loop-bootstrap-discovery.instructions.md`. An empty workspaces list = the user needs to paste URLs, not a "Loop disabled" signal.
|
|
31
|
+
- **Page bodies are HTML, not Markdown** — the snapshot writer converts via Readability; if a page renders as raw HTML in evidence, the converter regressed.
|
|
32
|
+
- **Co-authoring writes can race** — Loop pages support real-time edit. The page-edit stream cites `editedAt + editor`; a single visible change can produce N stream events. De-dupe by `(editor, page, minute-bucket)`.
|
|
33
|
+
- **Component links inside Loop pages** — embedded components (tables, tasks) live in sub-URLs. Capture the parent page; do NOT recursively scrape every embedded component (out of scope for v5).
|
|
34
|
+
- **No `Loop.Read` Graph scope** — when the host backend lacks the new Loop API, pull-loop is a no-op. Surface `loop.unavailable-no-api` in `_index/entities.yml#status`.
|
|
35
|
+
|
|
36
|
+
## Tools (in order)
|
|
37
|
+
|
|
38
|
+
1. **Playwright (browser-scrape, persisted M365 profile)** — PRIMARY. Drives Loop-for-Web to render each registered page and read the verbatim body. Profile at `~/.kushi/playwright-profile/m365/` (falls back to `~/.kushi/playwright-profile/onenote/` for older installs — both are valid M365-wide profiles). Implementation: `plugin/skills/pull-loop/runner.mjs`.
|
|
39
|
+
2. **WorkIQ** — FALLBACK for body capture when Playwright profile is auth-expired (`auth-required`). PRIMARY for the **stream** shape (page-edit metadata) and for discovery during setup. Always cite `m365-id-registry` doctrine when invoking.
|
|
40
|
+
3. **Host (m365_*)** — not used. Graph Loop API is preview-only and incomplete; do not call directly.
|
|
41
|
+
|
|
42
|
+
## Canonical CLI invocations
|
|
43
|
+
|
|
44
|
+
### Bootstrap (one-time per machine)
|
|
45
|
+
|
|
46
|
+
Loop reuses the OneNote Playwright profile. Run the OneNote bootstrap if you haven't already:
|
|
47
|
+
|
|
48
|
+
```pwsh
|
|
49
|
+
cd <kushi-repo-root>
|
|
50
|
+
node plugin/skills/pull-onenote/runner.mjs --bootstrap
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The bootstrap signs you into OneNote-for-Web, then visits SharePoint surfaces. The same profile authenticates Loop-for-Web — no separate Loop bootstrap is needed.
|
|
54
|
+
|
|
55
|
+
### Pre-flight (check profile + reachability)
|
|
56
|
+
|
|
57
|
+
```pwsh
|
|
58
|
+
cd <kushi-repo-root>
|
|
59
|
+
node plugin/skills/pull-loop/runner.mjs --preflight
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Exits `0` on success, `3` on `auth-required` (re-run the OneNote bootstrap).
|
|
63
|
+
|
|
64
|
+
### Scrape a workspace (production)
|
|
65
|
+
|
|
66
|
+
Use the wrapper, not the bare runner. The wrapper writes the snapshot in the canonical layout, upserts the per-user mutable registry, and emits a run report:
|
|
67
|
+
|
|
68
|
+
```pwsh
|
|
69
|
+
cd <kushi-repo-root>
|
|
70
|
+
node plugin/skills/pull-loop/write-snapshot.mjs `
|
|
71
|
+
--project "<project>" `
|
|
72
|
+
--workspace-url "<workspace-url-from-m365-mutable.json>" `
|
|
73
|
+
--engagement-root "<engagement-root>" `
|
|
74
|
+
--alias <your-alias>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The wrapper:
|
|
78
|
+
|
|
79
|
+
1. Loads `m365-mutable.json#knownSections.<project>.loop` for the workspace.
|
|
80
|
+
2. Enumerates registered `loop_pages[]`.
|
|
81
|
+
3. Invokes `runner.mjs` once per page (or once per workspace with `--titles` filter for partial runs).
|
|
82
|
+
4. Writes snapshot files at canonical paths.
|
|
83
|
+
5. Upserts each `loop_pages[].last_status` + `last_captured_at` + `captured_via`.
|
|
84
|
+
6. Emits `refresh-reports/<timestamp>_loop.md`.
|
|
85
|
+
|
|
86
|
+
## Output structure (per `evidence-layout-canonical.instructions.md`)
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
<engagement-root>/<project>/Evidence/<alias>/loop/
|
|
90
|
+
├── snapshot/
|
|
91
|
+
│ ├── <workspace-slug>/
|
|
92
|
+
│ │ ├── _workspace.md <- workspace metadata (title, owner, page list)
|
|
93
|
+
│ │ ├── <page-slug>.md <- one per page; verbatim body
|
|
94
|
+
│ │ └── ...
|
|
95
|
+
│ └── _index.md <- workspaces enumerated this run
|
|
96
|
+
└── stream/
|
|
97
|
+
└── YYYY-MM-DD_loop-stream.md <- per-ISO-week page-edit events
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Every artifact carries the frontmatter required by `per-source-verification-gate.instructions.md` §2a:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
---
|
|
104
|
+
source: loop
|
|
105
|
+
project: <project>
|
|
106
|
+
workspace_id: <id>
|
|
107
|
+
page_id: <id>
|
|
108
|
+
captured_at: <ISO-8601>
|
|
109
|
+
captured_via: playwright | workiq
|
|
110
|
+
evidence_source_kind: page-body | page-body-unavailable | tree-only
|
|
111
|
+
---
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`evidence_source_kind` values (canonical → fallbacks):
|
|
115
|
+
|
|
116
|
+
- `page-body` — Playwright rendered the page and the full body was captured. **Canonical.**
|
|
117
|
+
- `page-body-unavailable` — Playwright reached the page but body was empty / fluid container did not render (page is a stub or component-only). Coverage notes MUST explain.
|
|
118
|
+
- `tree-only` — Only workspace metadata + page-list was captured (no page bodies). Used when WorkIQ-only path runs because Playwright auth is expired.
|
|
119
|
+
|
|
120
|
+
## Pre-flight gates (run before EVERY scrape)
|
|
121
|
+
|
|
122
|
+
Per `loop-bootstrap-discovery.instructions.md`:
|
|
123
|
+
|
|
124
|
+
| Pre-flight | Failure action |
|
|
125
|
+
|---|---|
|
|
126
|
+
| **A. Workspaces registered** for the resolved project | Refuse to run. Instruct user to run `@Kushi setup --reconfigure`. |
|
|
127
|
+
| **B. Pages registered** OR `loop_pages_status: to-be-enumerated` | Run page enumeration via WorkIQ first; on enumerate-fail, write FOLLOW-UPS.md per the gate. |
|
|
128
|
+
| **C. Playwright profile exists** at `~/.kushi/playwright-profile/m365/` or `.../onenote/` | Refuse; instruct: `node plugin/skills/pull-onenote/runner.mjs --bootstrap`. |
|
|
129
|
+
| **D. URLs are canonical** (matches Loop URL grammar; not synthesized) | Refuse + log to learnings/loop.md per `issue-recovery.instructions.md`. |
|
|
130
|
+
|
|
131
|
+
## Verification gate (per `per-source-verification-gate.instructions.md`)
|
|
132
|
+
|
|
133
|
+
After every `pull-loop` run, the gate verifies:
|
|
134
|
+
|
|
135
|
+
- Snapshot shape: at least one `snapshot/<workspace-slug>/<page-slug>.md` ≥ 200 bytes per registered page, OR a documented `page-body-unavailable` annotation in coverage notes.
|
|
136
|
+
- Stream shape: `stream/YYYY-MM-DD_loop-stream.md` covers every ISO week in the run window OR is `.empty` with reason.
|
|
137
|
+
- Registry consistency: every `loop_pages[].last_status` was updated this run (no stale `unresolved` from previous runs unless the page truly remains unresolved).
|
|
138
|
+
- `evidence_source_kind` annotation present on every written artifact.
|
|
139
|
+
- Citation: spot-check 3 random assertions per `citation-ledger.instructions.md`.
|
|
140
|
+
|
|
141
|
+
## Boundary contract
|
|
142
|
+
|
|
143
|
+
Per `loop-bootstrap-discovery.instructions.md` §Boundary:
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
# <project>/integrations.yml
|
|
147
|
+
boundaries:
|
|
148
|
+
loop:
|
|
149
|
+
workspace_ids: [] # REQUIRED — empty = source disabled (never silently widens)
|
|
150
|
+
page_ids: [] # optional — pin specific pages
|
|
151
|
+
include_components: false
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## How users invoke this
|
|
155
|
+
|
|
156
|
+
Direct invocation is uncommon — this skill is normally dispatched by:
|
|
157
|
+
|
|
158
|
+
- `@Kushi bootstrap <project>` (full per-source loop)
|
|
159
|
+
- `@Kushi refresh <project>` (per-source loop)
|
|
160
|
+
- `@Kushi aggregate <project>` (pull-only loop)
|
|
161
|
+
|
|
162
|
+
Direct:
|
|
163
|
+
|
|
164
|
+
```text
|
|
165
|
+
@Kushi pull loop <project>
|
|
166
|
+
@Kushi pull loop <project> last 14 days
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## What this skill never does
|
|
170
|
+
|
|
171
|
+
- Never captures standalone Loop components from Teams/OneNote/Email — those belong to their host source (avoids double-counting).
|
|
172
|
+
- Never falls back to Graph (Loop Graph API is preview-only and incomplete) — see `deferred-retry-on-workiq-fail.instructions.md`.
|
|
173
|
+
- Never synthesizes a `pageUrl` from `workspaceId + pageId` — only URLs observed in WorkIQ responses or registered during setup are valid. See `issue-recovery.instructions.md` for why (mirrors OneNote learnings).
|
|
174
|
+
- Never sends outbound messages.
|
|
175
|
+
- Never reads/writes outside the resolved project's folder.
|
|
176
|
+
|
|
177
|
+
## References
|
|
178
|
+
|
|
179
|
+
- `../../instructions/loop-bootstrap-discovery.instructions.md` — workspace/page registration.
|
|
180
|
+
- `../../instructions/per-source-verification-gate.instructions.md` — gate §2 + §2a.
|
|
181
|
+
- `../../instructions/fuzzy-disambiguation.instructions.md` — workspace title → ID resolution.
|
|
182
|
+
- `../../instructions/issue-recovery.instructions.md` — Issue Recovery Rule applies when discovery or capture exposes a doctrine gap; fix the smallest correct repo-owned artifact first; never use memory as a substitute.
|
|
183
|
+
- `../../learnings/loop.md` — Loop-specific fixes accumulated across runs.
|
|
184
|
+
- `docs/concepts/loop-source.md` — user-facing companion doc.
|
|
185
|
+
|
|
186
|
+
## Issue Recovery
|
|
187
|
+
|
|
188
|
+
When this skill exposes a reusable defect (auth pattern, doctrine gap, layout mismatch), apply the [Issue Recovery Rule](../../instructions/issue-recovery.instructions.md): fix the smallest correct repo-owned artifact first, prefer durable fixes over per-run workarounds, then re-run the narrowest failed check. Do NOT use memory as a substitute for correcting the workflow surface.
|
|
170
189
|
|
|
171
|
-
|
|
172
|
-
- `../../instructions/per-source-verification-gate.instructions.md` — gate §2 + §2a.
|
|
173
|
-
- `../../instructions/fuzzy-disambiguation.instructions.md` — workspace title → ID resolution.
|
|
174
|
-
- `../../instructions/issue-recovery.instructions.md` — Issue Recovery Rule applies when discovery or capture exposes a doctrine gap; fix the smallest correct repo-owned artifact first; never use memory as a substitute.
|
|
175
|
-
- `../../learnings/loop.md` — Loop-specific fixes accumulated across runs.
|
|
176
|
-
- `docs/concepts/loop-source.md` — user-facing companion doc.
|
|
190
|
+
## Validation loop
|
|
177
191
|
|
|
178
|
-
|
|
192
|
+
After writing outputs:
|
|
179
193
|
|
|
180
|
-
|
|
194
|
+
1. Run self-check targeted at this skill: `pwsh plugin/skills/self-check/run.ps1 -Targeted pull-loop`
|
|
195
|
+
2. If failures: fix and re-run the affected step (not the whole skill).
|
|
196
|
+
3. Repeat until self-check exits 0.
|
|
197
|
+
4. Only then update `run-log.yml` with success status.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "pull-meetings"
|
|
3
|
-
version: "3.0.
|
|
4
|
-
description: "
|
|
3
|
+
version: "3.0.1"
|
|
4
|
+
description: "USE WHEN refresh-project / bootstrap-project dispatches Meetings source OR the user says \"pull meetings for <X>\" AND the project boundaries.meetings window is non-empty. DO NOT USE for tenant-wide calendar queries. Capability: pulls Meetings as (A) raw immutable verbatim/<dir>/ audit folder per meeting (transcript+chat+recording-url) AND (B) CSC blocks written to weekly/YYYY-MM-DD_meetings-csc.md. WorkIQ-only."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Skill: pull-meetings
|
|
@@ -22,6 +22,14 @@ description: "v3.0.0 (kushi v4.9.0): Pull Meetings evidence as (A) raw immutable
|
|
|
22
22
|
> - ~~`verbatim-by-default.instructions.md`~~ (LEGACY — superseded by CSC for Half B; Half A still verbatim).
|
|
23
23
|
> - ~~`snapshot-vs-stream.instructions.md`~~ (LEGACY — superseded by weekly-csc).
|
|
24
24
|
|
|
25
|
+
## Gotchas
|
|
26
|
+
|
|
27
|
+
- **Meetings expire** — transcripts and chat are purged by tenant policy (~30-90 days). The verbatim/ folder is the only durable record. Always write verbatim/<YYYY-MM-DD-HHMM>_<slug>/ BEFORE writing the weekly CSC block; the CSC cites verbatim.
|
|
28
|
+
- **Join URL is the canonical ID, not subject** — the same recurring meeting has the same `meetings://joinurl=...` id across occurrences. De-dupe in _index/entities.yml by joinUrl, not by subject string.
|
|
29
|
+
- **WorkIQ returns "meeting summary" instead of transcript when scope is too wide** — ask for ONE meeting at a time by joinUrl. Bulk calendar enumeration phrasings punt to Graph; see `meetings-bootstrap-discovery.instructions.md` for the canonical forbidden list.
|
|
30
|
+
- **Recording URLs rot when the meeting host leaves the tenant** — capture the SharePoint embed URL into verbatim/recording-url.txt; if the host later leaves, the URL 404s but the verbatim transcript + chat remain.
|
|
31
|
+
- **Facilitator notes require Copilot license + organizer role** — `m365_get_facilitator_notes` returns 403 silently. If notes are missing for a meeting where you are not organizer, log `facilitator-notes: unavailable-not-organizer` in `_index/entities.yml#status`, don''t retry.
|
|
32
|
+
|
|
25
33
|
## v4.9.0 — Comprehensive Structured Capture (CSC) + weekly/ layout (HARD RULE; supersedes all snapshot/+stream/ guidance below)
|
|
26
34
|
|
|
27
35
|
Per `comprehensive-structured-capture.instructions.md` and `weekly-csc.instructions.md`:
|
|
@@ -67,8 +75,8 @@ Per `comprehensive-structured-capture.instructions.md` and `weekly-csc.instructi
|
|
|
67
75
|
|
|
68
76
|
- **Keep Half A entirely intact** (see "Half A — verbatim/ capture" section below). Half A is still mandatory and uses the v4.8 verbatim transcript WorkIQ prompts.
|
|
69
77
|
- **Half B becomes the CSC weekly block** (one CSC block per meeting in `weekly/<Monday>_meetings-csc.md`). Every assertion cites the sibling `verbatim/<dir>/` file. `Artifacts/Links` MUST include the verbatim folder path and (when present) the recording URL.
|
|
70
|
-
- Bootstrap walks the FULL boundary window — no one-meeting-per-bootstrap carve-out. Each meeting produces its own verbatim/ folder.
|
|
71
|
-
|
|
78
|
+
- Bootstrap walks the FULL boundary window — no one-meeting-per-bootstrap carve-out. Each meeting produces its own verbatim/ folder.
|
|
79
|
+
|
|
72
80
|
Pulls **meetings** evidence in three shapes per `snapshot-vs-stream.instructions.md` + `meetings-verbatim-required.instructions.md`:
|
|
73
81
|
|
|
74
82
|
- **snapshot/** — `series-index.md` listing all recurring meeting series for this project (subject, recurrence, organizer, current attendees)
|
|
@@ -122,59 +130,9 @@ plugin/instructions/scope-boundaries.instructions.md.
|
|
|
122
130
|
|
|
123
131
|
For EACH meeting in the window, the cascade has **two halves**: (A) write raw artifacts to `verbatim/<YYYY-MM-DD-HHMM>_<slug>/`, then (B) produce the curated stream block citing those verbatim files. Half A is mandatory before Half B per `meetings-verbatim-required.instructions.md`.
|
|
124
132
|
|
|
125
|
-
### Half A — verbatim/ capture (REQUIRED
|
|
126
|
-
|
|
127
|
-
For every meeting, BEFORE writing any curated text:
|
|
128
|
-
|
|
129
|
-
0. Compute slug + timestamp, create `Evidence/<alias>/meetings/verbatim/<YYYY-MM-DD-HHMM>_<slug>/`, write `captured-at.txt` (started_at, kushi_version).
|
|
130
|
-
|
|
131
|
-
1. **Transcript cascade — WorkIQ-only, EXHAUSTIVE, in order. Do NOT stop at first weak result; record each path's result in `coverage.md`.** Per `meetings-verbatim-required.instructions.md` "Transcript capture cascade":
|
|
132
|
-
- **a. WorkIQ full-transcript pull (REQUIRED first attempt)** with the canonical prompt from `workiq-only.instructions.md`:
|
|
133
|
-
> `Find the Teams meeting titled "<subject>" that occurred on <YYYY-MM-DD>. Return the full transcript verbatim with speaker labels and timestamps. Do not summarize.`
|
|
134
|
-
- If WorkIQ returns full speaker-turn text (≥ ~10 distinct `Name:` lines) → strip `request-id:` prefix, save body as `transcript.txt` with header (source, query, request-id, fidelity).
|
|
135
|
-
- If WorkIQ returns a summary (paragraphs only, no speaker turns) → run the **doubled-strict retry** from `workiq-only.instructions.md` once. If still summary-only, save as `transcript-source.md` with the `WARNING: NOT a verbatim transcript` header.
|
|
136
|
-
- **b. WorkIQ Copilot recap (SUPPLEMENTARY, always attempt)**:
|
|
137
|
-
> `Get the Copilot meeting recap (decisions, action items, key points) for the Teams meeting "<subject>" on <YYYY-MM-DD>. Return the FULL recap card verbatim. Do not summarize.`
|
|
138
|
-
- Save as `facilitator-notes.md`. Supplementary; does NOT replace the transcript.
|
|
139
|
-
- **c. WorkIQ recording-URL discovery**:
|
|
140
|
-
> `For the meeting "<subject>" on <YYYY-MM-DD>, return the SharePoint Stream recording URL if it exists, and the calendar event body.`
|
|
141
|
-
- Save URL(s) to `recording-url.txt`. If a `.mp4` URL is present, downloading the recording binary is governed by the `pull-meetings` recording-download carve-out (size < 200MB) — this is the ONLY allowed `m365_download_file` call in any kushi pull-* skill, because the recording is binary media and WorkIQ does not download binaries.
|
|
142
|
-
- **d. User-paste fallback (first-class, NOT a degradation)** — when (a) returns empty/`body-unavailable` after doubled-strict retry AND (b) returns nothing usable: prompt the user to paste verbatim transcript or notes. Save to `transcript.txt` with header `User-pasted; WorkIQ returned no transcript on <ISO timestamp>`.
|
|
143
|
-
|
|
144
|
-
**FORBIDDEN** (do NOT attempt; do NOT log as cascade steps in coverage.md): `m365_get_transcript`, `m365_get_facilitator_notes`, `m365_list_meetings`, `m365_list_events`, Graph REST `/me/onlineMeetings/.../transcripts/.../content`. These have a near-100% failure rate in this workspace and pollute the coverage trail. Use WorkIQ steps (a)/(b)/(c).
|
|
145
|
-
|
|
146
|
-
2. **Chat capture (ALWAYS, parallel with step 1 — allowed exception to workiq-only)**: `m365_list_chat_messages(chatId)` → `chat-messages.json` (raw structured-data dump) + `chat-messages.md` (rendered, one heading-block per message). Chat is **supporting evidence**; it is **NEVER** a transcript substitute. If `m365_list_chat_messages` fails, run the WorkIQ chat-thread prompt as fallback (per `workiq-only.instructions.md` Teams chat thread section).
|
|
147
|
-
|
|
148
|
-
3. Walk chat for attachments → `m365_download_file` each → `attachments/<original-name>` (binary download carve-out, same as recording.mp4).
|
|
149
|
-
|
|
150
|
-
4. Walk chat for Copilot recap card → `recap-card.md` verbatim.
|
|
151
|
-
|
|
152
|
-
5. **Classify** the verbatim folder per the doctrine:
|
|
153
|
-
- `transcript-complete` — at least one of `transcript.vtt` / `transcript.txt` / `transcript-source.md` is non-empty.
|
|
154
|
-
- `transcript-missing` — only `chat-messages.*` present; all WorkIQ cascade paths (1a–1d) returned empty.
|
|
155
|
-
|
|
156
|
-
6. Write `coverage.md` with classification + per-path attempt log (every WorkIQ path attempted, with request-id, even successful ones) + source-basis classification for stream/.
|
|
157
|
-
|
|
158
|
-
7. Update `captured-at.txt` with `completed_at` + `final_status` (one of `transcript-complete-text` / `transcript-complete-summary-only` / `transcript-missing-chat-only` / `unrecoverable`).
|
|
159
|
-
|
|
160
|
-
If 1a–1d ALL return empty AND step 2 chat is also empty AND user paste is declined → `unrecoverable`. Apply retry pattern per `auth-and-retry.instructions.md`.
|
|
133
|
+
### Half A — verbatim/ capture (REQUIRED)
|
|
161
134
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
Build the per-meeting block in `stream/<week>_meetings-stream.md` using ONLY content already persisted in verbatim/. Every assertion cites a verbatim file. Preferred citation chain:
|
|
165
|
-
- `[source: Evidence/<alias>/meetings/verbatim/<dir>/transcript.vtt · <date>]` when transcript-complete-vtt.
|
|
166
|
-
- `[source: Evidence/<alias>/meetings/verbatim/<dir>/transcript.txt · <date>]` when transcript-complete-text.
|
|
167
|
-
- `[source: Evidence/<alias>/meetings/verbatim/<dir>/transcript-source.md · <date>]` when only Copilot summary (always note the warning).
|
|
168
|
-
- `[source: Evidence/<alias>/meetings/verbatim/<dir>/chat-messages.md · <date>]` only for assertions backed by chat (not transcript content).
|
|
169
|
-
|
|
170
|
-
`Source basis` line in the curated block reflects verbatim classification:
|
|
171
|
-
- `transcript (raw VTT)` — transcript.vtt present
|
|
172
|
-
- `transcript (plain text)` — transcript.txt present, no VTT
|
|
173
|
-
- `transcript (WorkIQ Copilot summary — NOT verbatim)` — only transcript-source.md
|
|
174
|
-
- `❌ no-transcript-recovered-chat-only` — only chat-messages.*
|
|
175
|
-
- `❌ unrecoverable` — only captured-at.txt + coverage.md
|
|
176
|
-
|
|
177
|
-
A meeting with `transcript-missing-chat-only` is valid evidence in a degraded sense — actions/decisions citeable from chat are still useful — but the curated block MUST flag the gap prominently and the run-log MUST record `transcript-unrecoverable` for that meeting.
|
|
135
|
+
> **Load `references/verbatim-capture.md`** for the full transcript cascade (WorkIQ steps a–d), chat capture procedure, verbatim-folder classification rules, coverage.md format, and the Half B citation chain. Load when executing per-meeting capture.
|
|
178
136
|
|
|
179
137
|
### Ask-user fallback
|
|
180
138
|
|
|
@@ -182,17 +140,9 @@ When the entire cascade (1a–1d + chat) produces nothing usable, ask the user t
|
|
|
182
140
|
|
|
183
141
|
## Stream pass
|
|
184
142
|
|
|
185
|
-
> **LEGACY (pre-v4.9.0).** Superseded by v4.9.0 weekly/ + CSC writer (Half B) above. The Half A `verbatim/<dir>/` capture remains mandatory and unchanged.
|
|
186
|
-
|
|
187
|
-
Per `evidence-thoroughness.instructions.md`: every meeting in the window gets a full per-meeting block whose **FIRST sub-section is an AI Narrative Summary (REQUIRED, 5+ paragraphs)** covering the whole meeting end-to-end — context, what was discussed in what order, who took which position, the reasoning, the back-and-forth, soft signals, sentiment, what landed and what stayed open (cited to transcript timestamps). Then attendees → agenda → Detailed Discussion Summary (topic-organized) → chronological transcript walk-through with verbatim quotes → Decisions → Open Questions → Next Steps → Action Items → Risks → Customer Asks → Coverage Notes. **A 30-line meetings file for a week with 2 meetings is a defect — expect 300+ lines (the AI Narrative Summary alone is typically 30-50 lines per meeting).** A per-meeting block missing the AI Narrative Summary as the first sub-section is a defect even if every other section is present.
|
|
188
|
-
|
|
189
|
-
Write to: `<engagement-root>/<project>/Evidence/<alias>/Meetings/stream/<YYYY-MM-DD>_meetings-stream.md` (date = Monday of the ISO week).
|
|
190
|
-
|
|
191
|
-
Use template: `templates/weekly/meetings-stream.template.md`
|
|
192
|
-
|
|
193
|
-
If a week file already exists, MERGE (dedupe by event ID, append new events, keep existing).
|
|
143
|
+
> **LEGACY (pre-v4.9.0).** Superseded by v4.9.0 weekly/ + CSC writer (Half B) above. The Half A `verbatim/<dir>/` capture remains mandatory and unchanged.
|
|
194
144
|
|
|
195
|
-
**
|
|
145
|
+
> **Load `references/legacy-stream.md`** for the full legacy stream-file format (AI Narrative Summary, chronological transcript walk-through, attendees/agenda structure, merge rules). Load only when reading or maintaining pre-v4.9.0 stream/ files on disk.
|
|
196
146
|
|
|
197
147
|
## Mutable hints to upsert (during the run, not at the end)
|
|
198
148
|
|
|
@@ -217,11 +167,11 @@ After the pass:
|
|
|
217
167
|
- A meeting has neither transcript NOR chat messages → write `verbatim/<dir>/coverage.md` documenting every failed path + write `❌ source-expired-or-unrecoverable` block in stream/, log error, continue.
|
|
218
168
|
- All paths failed for ALL meetings in the window → mark source `failed`, write a single `❌ all paths failed` evidence file with actionable next step. Verbatim/ folders for each meeting still get created with captured-at.txt + coverage.md (the empty-folder audit trail is itself evidence).
|
|
219
169
|
- A per-meeting block lacks a sibling `verbatim/<YYYY-MM-DD-HHMM>_<slug>/` directory → **defect** per `meetings-verbatim-required.instructions.md`. Re-run Half A immediately; do NOT ship the curated block alone.
|
|
220
|
-
|
|
221
|
-
## References (v4.4.7)
|
|
222
|
-
|
|
223
|
-
- Name → ID resolution follows ..\..\instructions\fuzzy-disambiguation.instructions.md (universal fuzzy contract).
|
|
224
|
-
- After this pull completes, the per-source verification gate runs: ..\..\instructions\per-source-verification-gate.instructions.md (retry once, then write FOLLOW-UPS.md).
|
|
170
|
+
|
|
171
|
+
## References (v4.4.7)
|
|
172
|
+
|
|
173
|
+
- Name → ID resolution follows ..\..\instructions\fuzzy-disambiguation.instructions.md (universal fuzzy contract).
|
|
174
|
+
- After this pull completes, the per-source verification gate runs: ..\..\instructions\per-source-verification-gate.instructions.md (retry once, then write FOLLOW-UPS.md).
|
|
225
175
|
|
|
226
176
|
|
|
227
177
|
## Issue Recovery
|
|
@@ -240,6 +190,10 @@ WorkIQ (`workiq ask`) is the only allowed path. Use **CSC canonical prompts** fr
|
|
|
240
190
|
|
|
241
191
|
## Changelog
|
|
242
192
|
|
|
193
|
+
- **v3.0.1 (kushi v5.0.1, 2026-05-26)**: agentskills.io spec-compliance pass. Extracted Half A
|
|
194
|
+
transcript cascade (WorkIQ steps a–d, chat capture, classification, coverage.md) →
|
|
195
|
+
`references/verbatim-capture.md`; legacy stream-file format → `references/legacy-stream.md`.
|
|
196
|
+
SKILL.md trimmed from 267 to ~175 lines. Behaviour unchanged; load-on-trigger pointers added.
|
|
243
197
|
- **v3.0.0 (kushi v4.9.0, 2026-05-26)**: BREAKING. Half B is now a single weekly CSC file per ISO week
|
|
244
198
|
(`weekly/<YYYY-MM-DD>_meetings-csc.md`) + per-contributor `_index/entities.yml`. snapshot/ + stream/
|
|
245
199
|
writes removed. WorkIQ prompts for Half B switched to CSC canonical prompts. AI Narrative Summary
|
|
@@ -247,4 +201,13 @@ WorkIQ (`workiq ask`) is the only allowed path. Use **CSC canonical prompts** fr
|
|
|
247
201
|
still uses v4.8 verbatim transcript prompts. Bootstrap now walks the FULL boundary window writing
|
|
248
202
|
verbatim/ for every meeting (v4.8 one-per-source carve-out DROPPED). Legacy snapshot/+stream/
|
|
249
203
|
folders left readable; no migration.
|
|
250
|
-
- **v2.x.x**: prior snapshot/+stream/+verbatim/ shape. See git history.
|
|
204
|
+
- **v2.x.x**: prior snapshot/+stream/+verbatim/ shape. See git history.
|
|
205
|
+
|
|
206
|
+
## Validation loop
|
|
207
|
+
|
|
208
|
+
After writing outputs:
|
|
209
|
+
|
|
210
|
+
1. Run self-check targeted at this skill: `pwsh plugin/skills/self-check/run.ps1 -Targeted pull-meetings`
|
|
211
|
+
2. If failures: fix and re-run the affected step (not the whole skill).
|
|
212
|
+
3. Repeat until self-check exits 0.
|
|
213
|
+
4. Only then update `run-log.yml` with success status.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# references/legacy-stream.md (pull-meetings)
|
|
2
|
+
|
|
3
|
+
> **Load this file when** maintaining or reading pre-v4.9.0 `stream/` or `snapshot/` files — i.e., when legacy evidence exists on disk and you need to understand the prior output shape for reader fallback purposes.
|
|
4
|
+
|
|
5
|
+
## Stream pass (LEGACY — pre-v4.9.0)
|
|
6
|
+
|
|
7
|
+
Per `evidence-thoroughness.instructions.md`: every meeting in the window gets a full per-meeting block whose **FIRST sub-section is an AI Narrative Summary (REQUIRED, 5+ paragraphs)** covering the whole meeting end-to-end — context, what was discussed in what order, who took which position, the reasoning, the back-and-forth, soft signals, sentiment, what landed and what stayed open (cited to transcript timestamps). Then attendees → agenda → Detailed Discussion Summary (topic-organized) → chronological transcript walk-through with verbatim quotes → Decisions → Open Questions → Next Steps → Action Items → Risks → Customer Asks → Coverage Notes. **A 30-line meetings file for a week with 2 meetings is a defect — expect 300+ lines (the AI Narrative Summary alone is typically 30-50 lines per meeting).** A per-meeting block missing the AI Narrative Summary as the first sub-section is a defect even if every other section is present.
|
|
8
|
+
|
|
9
|
+
Write to: `<engagement-root>/<project>/Evidence/<alias>/Meetings/stream/<YYYY-MM-DD>_meetings-stream.md` (date = Monday of the ISO week).
|
|
10
|
+
|
|
11
|
+
Use template: `templates/weekly/meetings-stream.template.md`
|
|
12
|
+
|
|
13
|
+
If a week file already exists, MERGE (dedupe by event ID, append new events, keep existing).
|
|
14
|
+
|
|
15
|
+
**Verbatim sibling required.** Every per-meeting block written here MUST have a matching `Evidence/<alias>/meetings/verbatim/<YYYY-MM-DD-HHMM>_<slug>/` folder produced by Half A. The block's `Source basis` line and `Artifacts` section must cite the verbatim folder's relative path. Self-check D13 enforces this.
|