kushi-agents 4.4.3 → 4.7.4
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 +4 -0
- package/package.json +4 -4
- package/plugin/agents/kushi.agent.md +30 -14
- package/plugin/config/studios.json +37 -0
- package/plugin/config/studios.schema.json +45 -0
- package/plugin/instructions/auth-and-retry.instructions.md +268 -1
- package/plugin/instructions/engagement-root-resolution.instructions.md +5 -1
- package/plugin/instructions/evidence-thoroughness.instructions.md +103 -1
- package/plugin/instructions/fuzzy-disambiguation.instructions.md +97 -0
- package/plugin/instructions/identity-resolution.instructions.md +76 -0
- package/plugin/instructions/issue-recovery.instructions.md +58 -0
- package/plugin/instructions/kushi-config-root.instructions.md +66 -0
- package/plugin/instructions/loop-bootstrap-discovery.instructions.md +105 -0
- package/plugin/instructions/m365-id-registry.instructions.md +1 -1
- package/plugin/instructions/onedrive-pin-policy.instructions.md +132 -0
- package/plugin/instructions/per-source-verification-gate.instructions.md +193 -0
- package/plugin/instructions/sharepoint-to-onedrive-sync.instructions.md +116 -0
- package/plugin/instructions/status-color-rule.instructions.md +62 -0
- package/plugin/instructions/studio-registry.instructions.md +48 -0
- package/plugin/instructions/update-ledger.instructions.md +1 -1
- package/plugin/instructions/verbatim-by-default.instructions.md +1 -1
- package/plugin/instructions/vertex-emit.instructions.md +120 -0
- package/plugin/instructions/workiq-input-sanitization.instructions.md +43 -0
- package/plugin/instructions/workiq-onenote-query-shape.instructions.md +79 -0
- package/plugin/instructions/workiq-only.instructions.md +15 -9
- package/plugin/learnings/loop.md +11 -0
- package/plugin/learnings/onenote.md +27 -1
- package/plugin/lib/Get-KushiConfig.ps1 +22 -9
- package/plugin/lib/detect-vertex-repo.mjs +96 -0
- package/plugin/lib/render-vertex.mjs +249 -0
- package/plugin/lib/sanitize-workiq-input.mjs +72 -0
- package/plugin/lib/studio-registry.mjs +39 -0
- package/plugin/lib/vertex-validate.mjs +121 -0
- package/plugin/plugin.json +16 -6
- package/plugin/prompts/bootstrap.prompt.md +9 -7
- package/plugin/prompts/emit-vertex.prompt.md +33 -0
- package/plugin/prompts/setup.prompt.md +29 -0
- package/plugin/prompts/vertex-link.prompt.md +27 -0
- package/plugin/skills/aggregate-project/SKILL.md +24 -2
- package/plugin/skills/apply-ado-update/SKILL.md +9 -4
- package/plugin/skills/ask-project/SKILL.md +4 -0
- package/plugin/skills/bootstrap-project/SKILL.md +67 -41
- package/plugin/skills/consolidate-evidence/SKILL.md +5 -1
- package/plugin/skills/emit-vertex/README.md +37 -0
- package/plugin/skills/emit-vertex/SKILL.md +173 -0
- package/plugin/skills/intro/SKILL.md +2 -0
- package/plugin/skills/propose-ado-update/SKILL.md +8 -3
- package/plugin/skills/pull-ado/SKILL.md +11 -1
- package/plugin/skills/pull-crm/SKILL.md +12 -2
- package/plugin/skills/pull-email/SKILL.md +11 -1
- package/plugin/skills/pull-loop/README.md +64 -0
- package/plugin/skills/pull-loop/SKILL.md +180 -0
- package/plugin/skills/pull-loop/runner.mjs +261 -0
- package/plugin/skills/pull-loop/write-snapshot.mjs +181 -0
- package/plugin/skills/pull-meetings/SKILL.md +11 -1
- package/plugin/skills/pull-misc/README.md +4 -4
- package/plugin/skills/pull-misc/SKILL.md +18 -12
- package/plugin/skills/pull-onenote/SKILL.md +71 -19
- package/plugin/skills/pull-sharepoint/SKILL.md +11 -2
- package/plugin/skills/pull-teams/SKILL.md +11 -2
- package/plugin/skills/refresh-project/SKILL.md +38 -7
- package/plugin/skills/self-check/SKILL.md +14 -1
- package/plugin/skills/self-check/run.ps1 +442 -20
- package/plugin/skills/setup/SKILL.md +377 -0
- package/plugin/skills/vertex-link/SKILL.md +143 -0
- package/plugin/templates/init/m365-auth.template.json +10 -4
- package/plugin/templates/init/project-evidence.template.yml +10 -3
- package/plugin/templates/init/project-integrations.template.yml +5 -0
- package/plugin/templates/snapshot/ado-item.template.md +1 -1
- package/plugin/templates/snapshot/crm-record.template.md +1 -1
- package/plugin/templates/snapshot/meetings-series-index.template.md +1 -1
- package/plugin/templates/snapshot/onenote-page.template.md +1 -1
- package/plugin/templates/snapshot/sharepoint-file.template.md +1 -1
- package/plugin/templates/snapshot/sharepoint-tree.template.md +1 -1
- package/plugin/templates/snapshot/teams-roster.template.md +1 -1
- package/plugin/templates/weekly/ado-stream.template.md +1 -1
- package/plugin/templates/weekly/crm-stream.template.md +1 -1
- package/plugin/templates/weekly/email-stream.template.md +1 -1
- package/plugin/templates/weekly/meetings-stream.template.md +1 -1
- package/plugin/templates/weekly/onenote-stream.template.md +1 -1
- package/plugin/templates/weekly/sharepoint-stream.template.md +1 -1
- package/plugin/templates/weekly/teams-stream.template.md +1 -1
- package/src/check-workiq.mjs +109 -15
- package/src/config-loader.mjs +71 -13
- package/src/config-root-resolve.test.mjs +137 -0
- package/src/detect-vertex-repo.test.mjs +128 -0
- package/src/emit-vertex.e2e.test.mjs +308 -0
- package/src/forbidden-workiq-phrasings.test.mjs +111 -0
- package/src/main.mjs +11 -2
- package/src/sanitize-workiq-input.test.mjs +45 -0
- package/src/vertex-validate.test.mjs +142 -0
- package/plugin/instructions/az-auth-conditional.instructions.md +0 -39
- package/plugin/instructions/azure-auth-patterns.instructions.md +0 -233
- package/plugin/instructions/thoroughness-detector.instructions.md +0 -105
- package/plugin/instructions/workiq-first.instructions.md +0 -31
|
@@ -20,7 +20,7 @@ This skill **never** writes to `State/`. It only writes to `Evidence/`.
|
|
|
20
20
|
|
|
21
21
|
1. **Resolve project** — fuzzy-match against `m365-mutable.json knownSections` -> `active_projects` -> `<engagement-root>` subfolders.
|
|
22
22
|
2. **Resolve window** — default = since last `aggregate`/`refresh`/`bootstrap` watermark in `Evidence/run-log.yml`; fallback 7 days if no watermark.
|
|
23
|
-
3. **Pull each enabled source in turn** (`pull-email`, `pull-teams`, `pull-meetings`, `pull-onenote`, `pull-sharepoint`, `pull-crm`, `pull-ado`) — each writes its own snapshot/ + stream/ files under `Evidence/<alias>/<source>/`.
|
|
23
|
+
3. **Pull each enabled source in turn** (`pull-email`, `pull-teams`, `pull-meetings`, `pull-onenote`, `pull-loop`, `pull-sharepoint`, `pull-crm`, `pull-ado`) — each writes its own snapshot/ + stream/ files under `Evidence/<alias>/<source>/`. **After each pull, run the verification gate** per `..\..\instructions\per-source-verification-gate.instructions.md`: on first failure retry once with the same window; on second failure append a 5-field entry to `<project>/FOLLOW-UPS.md`, log `status: failed-gate` to `Evidence/run-log.yml`, and continue to the next source (never abort the whole aggregate).
|
|
24
24
|
4. **Run `consolidate-evidence`** — merges all aliases' streams into `Evidence/_Consolidated/<YYYY-MM-DD>_consolidated.md`. Skip silently if only one alias exists.
|
|
25
25
|
5. **Update `Evidence/run-log.yml`** — record this aggregate run, its watermark, the sources pulled, the alias that produced it.
|
|
26
26
|
6. **DO NOT run `build-state`.** State/ is not the concern of this skill.
|
|
@@ -37,13 +37,25 @@ Evidence/
|
|
|
37
37
|
│ ├── teams/{snapshot,stream}/... <- snapshot + stream
|
|
38
38
|
│ ├── meetings/{snapshot,stream}/...
|
|
39
39
|
│ ├── onenote/{snapshot,stream}/...
|
|
40
|
+
│ ├── loop/{snapshot,stream}/... <- if enabled (v4.6.0+)
|
|
40
41
|
│ ├── sharepoint/{snapshot,stream}/...
|
|
41
42
|
│ ├── crm/{snapshot,stream}/... <- if enabled
|
|
42
43
|
│ └── ado/{snapshot,stream}/... <- if enabled
|
|
43
44
|
└── _Consolidated/
|
|
44
|
-
|
|
45
|
+
├── YYYY-MM-DD_consolidated.md <- if multi-user
|
|
46
|
+
└── ado/current-state.md <- v4.5.1+ if ADO enabled
|
|
45
47
|
```
|
|
46
48
|
|
|
49
|
+
### ADO consolidated current-state (v4.5.1+)
|
|
50
|
+
|
|
51
|
+
When ADO is enabled for the project, after the per-user ADO snapshots/streams are written, `aggregate-project` writes a single canonical roll-up at `Evidence/_Consolidated/ado/current-state.md` containing:
|
|
52
|
+
|
|
53
|
+
- **Current best discussion source per work item** — for each ADO item touched in the window, the path to the artifact whose `evidence_source_kind` (per `per-source-verification-gate.instructions.md` §2a) ranks highest in the canonical order (`comments` > `history` > `attachment-fallback` > `description-only`).
|
|
54
|
+
- **Supersession log** — when a newer artifact supersedes an earlier one (e.g. comments became available after an initial attachment-fallback snapshot), the prior path is logged with a `superseded-by:` pointer.
|
|
55
|
+
- **Attachment-fallback annotation** — items whose best source is `attachment-fallback` are listed in a dedicated section with the attachment path so consumers (`ask-project`, `fde-report`) can warn that discussion lives in a doc, not in comments.
|
|
56
|
+
|
|
57
|
+
This roll-up lives under `_Consolidated/` per `evidence-layout-canonical.instructions.md` (HARD: no source siblings under `<project>/`). It is regenerated on every aggregate/refresh run; prior versions are not preserved.
|
|
58
|
+
|
|
47
59
|
`State/` is **NOT** touched. Existing `State/*.md` files (from earlier `refresh`/`state` runs) remain unchanged.
|
|
48
60
|
|
|
49
61
|
See `docs/reference/evidence-contract.md` for the full schema (filename rules, frontmatter, citation format).
|
|
@@ -70,3 +82,13 @@ See `docs/reference/evidence-contract.md` for the full schema (filename rules, f
|
|
|
70
82
|
| Rebuild State/ only, no new pulls | `state` |
|
|
71
83
|
| Capture from one source only | `pull <source>` |
|
|
72
84
|
| Merge per-user streams without pulling | `consolidate` |
|
|
85
|
+
|
|
86
|
+
## References (v4.4.7)
|
|
87
|
+
|
|
88
|
+
- Name → ID resolution (any source) follows `..\..\instructions\fuzzy-disambiguation.instructions.md`.
|
|
89
|
+
- After each per-source pull, run the gate per `..\..\instructions\per-source-verification-gate.instructions.md` (retry once → FOLLOW-UPS.md on failure).
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
## Issue Recovery
|
|
93
|
+
|
|
94
|
+
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.
|
|
@@ -37,7 +37,7 @@ Same as `propose-ado-update`. Reads ADO connection from `<workspace>/.kushi/conf
|
|
|
37
37
|
1. **Resolve engagement root + project** per `engagement-root-resolution.instructions.md`.
|
|
38
38
|
2. Confirm `<project>/integrations.yml ado.engagement_id > 0`. If 0 → abort with the same message `propose-ado-update` uses ("ADO Initiative not yet linked").
|
|
39
39
|
3. Confirm `<project>/ado-updates/<YYYY-MM-DD>/proposed.md` exists. If not → tell user to run `@Kushi propose ado <project>` first. Never fabricate a proposal.
|
|
40
|
-
4. Per `
|
|
40
|
+
4. Per `auth-and-retry.instructions.md` — Section 1 (session pre-check) + Section 3 (ADO tenant validation, using `<workspace>/.kushi/config/shared/integrations.yml`) **must** complete green before any further step.
|
|
41
41
|
|
|
42
42
|
## Steps (current preview-stub behavior)
|
|
43
43
|
|
|
@@ -102,8 +102,8 @@ After step 5 (approval), instead of step 6:
|
|
|
102
102
|
| `proposed.md` missing | Stop. Tell user to run `@Kushi propose ado <project>` first. |
|
|
103
103
|
| `integrations.yml` missing or `ado.engagement_id == 0` | Stop with same message `propose-ado-update` uses; do not prompt for an ID. |
|
|
104
104
|
| `ado.writes:` block missing | Stop. Tell user to run `@Kushi propose ado <project>` first (it scaffolds the block). |
|
|
105
|
-
| ADO 401 on the read-only re-fetch in step 2 | Re-acquire token once per `
|
|
106
|
-
| Tenant mismatch | Per `
|
|
105
|
+
| ADO 401 on the read-only re-fetch in step 2 | Re-acquire token once per `auth-and-retry.instructions.md` §4; if still 401, abort `auth-failed`. |
|
|
106
|
+
| Tenant mismatch | Per `auth-and-retry.instructions.md` §3 — abort with the exact `az login --tenant <id>` command. |
|
|
107
107
|
| `proposal-drift` (current ADO value differs from `proposed.md` snapshot) | Show diff between live and proposed; require user to re-confirm or re-run `propose-ado-update`. |
|
|
108
108
|
| `duplicate-detected` (comment fingerprint already on the work item) | Skip comment portion; continue with field if not also duplicate. |
|
|
109
109
|
| Allowlist rejection | Refuse the item before approval. Tell user the field reference name is not in `integrations.yml ado.writes.allowlist.fields`. |
|
|
@@ -120,6 +120,11 @@ After step 5 (approval), instead of step 6:
|
|
|
120
120
|
## References
|
|
121
121
|
|
|
122
122
|
- `update-ledger.instructions.md` — ledger schema, reverse-op format, write-path safety doctrine.
|
|
123
|
-
- `
|
|
123
|
+
- `auth-and-retry.instructions.md` — pre-flight, tenant validation, token reuse, 401 recovery.
|
|
124
124
|
- `propose-ado-update` SKILL.md — produces the `proposed.md` consumed by this skill.
|
|
125
125
|
- `engagement-root-resolution.instructions.md` — resolving `<engagement-root>` and `<project>`.
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
## Issue Recovery
|
|
129
|
+
|
|
130
|
+
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.
|
|
@@ -162,3 +162,7 @@ Explicit triggers also accepted:
|
|
|
162
162
|
### Example 6 — Missing evidence
|
|
163
163
|
> User: "what did Mark say in last week's call about pricing?"
|
|
164
164
|
> → If no Meetings file for that week: "I don't have a meetings transcript for week of YYYY-MM-DD. Want me to pull meetings for AGCO since YYYY-MM-DD?"
|
|
165
|
+
|
|
166
|
+
## References (v4.4.7)
|
|
167
|
+
|
|
168
|
+
- Name → ID resolution (any source) follows `..\..\instructions\fuzzy-disambiguation.instructions.md`.
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "bootstrap-project"
|
|
3
|
-
version: "2.3.
|
|
3
|
+
version: "2.3.3"
|
|
4
4
|
description: "First-time setup for a project: machine preflight, side-by-side config, engagement-root + project resolution, initial 30d snapshot+stream pull across all enabled sources. Verbatim-by-default per `verbatim-by-default.instructions.md` — every enabled source dispatched, no silent skips. CRM bootstrap discovery REQUIRED to run live Dataverse 4-step resolution before declaring disabled per `crm-bootstrap-discovery.instructions.md` (v2.3.0). Writes per-user refresh report per `run-reports.instructions.md`. Cleans stale no-match notes on resolution per `cleanup-on-resolution.instructions.md`. Builds State/ only on `full` profile. Idempotent."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Skill: bootstrap-project
|
|
8
8
|
|
|
9
|
+
> **Config-root resolution (v4.7.2+)**: NEVER conclude "Kushi isn't installed" from a missing `<workspace>/.kushi/` directory. Configs may live at `<workspace>/.kushi/config/` (vscode install) OR `~/.copilot/m-skills/kushi/config/` (Clawpilot install). Always probe via `Get-KushiConfig` / `loadKushiConfig`, which walks both. See `instructions/kushi-config-root.instructions.md`. If `Get-KushiConfig -Name 'project-evidence' -Path` returns a real path, the install is fine — proceed. Do NOT prompt the user to install/overwrite `.kushi/`.
|
|
10
|
+
>
|
|
9
11
|
> **Verbatim-by-default**: every `pull-<source>` whose boundary is satisfied MUST be dispatched. Silent skips are defects. See `verbatim-by-default.instructions.md`.
|
|
10
12
|
>
|
|
11
13
|
> **Per-user bootstrap report REQUIRED**: at end of run, write `<project>/Evidence/<alias>/refresh-reports/<YYYY-MM-DD-HHmm>_bootstrap.md` per `run-reports.instructions.md`. Distinct from `<project>/bootstrap-status.md` (durable state) — this is per-user run narrative.
|
|
@@ -41,33 +43,26 @@ After every run (success or coverage-gaps), write `<project>/bootstrap-status.md
|
|
|
41
43
|
|
|
42
44
|
## Steps
|
|
43
45
|
|
|
44
|
-
### Step 0 —
|
|
46
|
+
### Step 0 — Delegate ALL onboarding questions to the `setup` skill (REQUIRED, never asks here)
|
|
45
47
|
|
|
46
|
-
Per `identity-resolution.instructions.md`.
|
|
48
|
+
Per `identity-resolution.instructions.md` (v4.4.5 extension). The bootstrap orchestrator **MUST NOT** itself prompt for identity, OneNote, mailbox folders, or `projects_root`. The `setup` skill owns those questions.
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
* Persist resolved values back to the YAML (preserve comments).
|
|
54
|
-
* Echo one line: `✓ Identity: <displayName> <<UPN>> (alias=<alias>). Edit .kushi/config/user/project-evidence.yml to override.`
|
|
55
|
-
* If all three are already explicit non-placeholder values → skip silently.
|
|
50
|
+
1. Read `<workspace>/.kushi/config/user/project-evidence.yml#identity_status`.
|
|
51
|
+
2. If it is missing, empty, `<auto>`, or any `skipped-*` value → **dispatch the `setup` skill with `--from-bootstrap <project>`** and WAIT for completion.
|
|
52
|
+
- `setup` will auto-accept the EULA, functionally verify WorkIQ via `workiq ask -q "Who am I?"`, capture identity, ask the optional OneNote / mailbox questions, mirror `projects_root`, append `<project>` to `active_projects`, and print the file-pointer footer.
|
|
53
|
+
- On `setup` completion, re-read `identity_status`. If still `skipped-*` → STOP. Print: *"Bootstrap blocked — WorkIQ unreachable. Run `@Kushi setup` once WorkIQ is up. Or manually set `identity_status: verified` in `.kushi/config/user/project-evidence.yml` to override."* Exit cleanly.
|
|
54
|
+
3. If `identity_status: verified` → no-op. Bootstrap proceeds to Step 1.
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
Bootstrap NEVER calls `workiq ask -q "Who am I?"` itself. It NEVER asks the user about OneNote, mailbox folders, or `projects_root`. Those questions live in `setup` so the user is asked at most once.
|
|
58
57
|
|
|
59
58
|
### Step 1 — Machine preflight (SETUP)
|
|
60
59
|
|
|
61
60
|
Verify in order. Stop on hard failures.
|
|
62
61
|
|
|
63
62
|
1. **OS + host runtime** — display OS + Node/PowerShell version. Informational.
|
|
64
|
-
2. **WorkIQ install (REQUIRED, hard stop)** —
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- `$env:ProgramFiles\WorkIQ\workiq.cmd`
|
|
68
|
-
If found, persist path. If not found, ask user for path (or to install). Test with `<workiq.cli_path> --help`. Without WorkIQ, M365 sources will all fail — STOP.
|
|
69
|
-
3. **Conditional az login** — only if `<workspace>/.kushi/config/shared/integrations.yml` OR `<workspace>/.kushi/config/shared/integrations.yml` exists. Per `az-auth-conditional.instructions.md`. Soft warning on failure, never blocking.
|
|
70
|
-
4. **Engagement-root resolution** — per `engagement-root-resolution.instructions.md`. Persist to `<workspace>/.kushi/config/user/project-evidence.yml engagement_root` if newly resolved.
|
|
63
|
+
2. **WorkIQ install (REQUIRED, hard stop)** — already verified in Step 0 via the `setup` dispatch. Re-confirm only that `workiq.cli_path` resolves; do NOT re-prompt or re-probe the filesystem. **Do NOT probe `$HOME\.kushi\bin\` — removed in v4.4.4** because it triggered VS Code's "Allow reading external directory?" prompt even on machines where workiq was already on PATH.
|
|
64
|
+
3. **Conditional az login** — only if `<workspace>/.kushi/config/shared/integrations.yml` exists with CRM/ADO blocks populated. Per `auth-and-retry.instructions.md`. Soft warning on failure, never blocking.
|
|
65
|
+
4. **Engagement-root resolution** — per `engagement-root-resolution.instructions.md`. `projects_root` was already captured by `setup` in Step 0; this step only validates it points at a real directory. **Sync-pending gate (v4.5.0):** if `<workspace>/.kushi/config/user/project-evidence.yml#projects_root_status` is `syncing` or `manual-sync-pending`, refuse to continue with: *"Engagement root sync still pending. Run `@Kushi setup --resume-sync` once OneDrive finishes syncing the library."* Exit cleanly.
|
|
71
66
|
|
|
72
67
|
Display SETUP summary table with ✅ / ⚙️ / ❌ / ⚠️ / ➖ markers.
|
|
73
68
|
|
|
@@ -117,6 +112,8 @@ Create the project folder structure (per `engagement-root-resolution.instruction
|
|
|
117
112
|
|
|
118
113
|
The `State/` subtree is created **only on `full` profile**. On `standard`, only `Evidence/` is scaffolded. State files (when scaffolded) come from `templates/state/*.template.md`.
|
|
119
114
|
|
|
115
|
+
**Pin hook (v4.5.0):** immediately after scaffold, per `onedrive-pin-policy.instructions.md`, extend the OneDrive pin set to cover the new folders — `<project>/integrations.yml`, `<project>/bootstrap-status.md` (after Step 7 writes it), `<project>/Evidence/<alias>/`, `<project>/Evidence/_Consolidated/` (when created), and `<project>/State/` (when scaffolded). Idempotent + additive — never unpins. Skips silently on Linux or when OneDrive isn't running. This keeps every contributor's own slice always-on-device while leaving other contributors' evidence cloud-only.
|
|
116
|
+
|
|
120
117
|
### Step 4 — Initial pull (last 30 days)
|
|
121
118
|
|
|
122
119
|
**Boundaries gate** (kushi v3.7.0+, per `scope-boundaries.instructions.md`): before dispatching any `pull-*`, read `<engagement-root>/<project>/integrations.yml#boundaries` and verify each enabled source has its required boundary key populated. For sources where bootstrap can auto-populate from existing `m365-mutable.json` discovery hints (e.g. a previously-discovered `section_file_id` lands in `boundaries.onenote.section_file_ids`), do so and continue. For sources where the boundary cannot be auto-populated, write the source as **disabled** in `integrations.yml` and add a one-liner to `<project>/OPEN-QUESTIONS-DRAFT.md` (or `State/09_open-questions.md` on `full` profile) asking the user to fill the boundary and re-enable.
|
|
@@ -136,7 +133,7 @@ For each enabled source, resolve and persist the canonical lookup keys into `<wo
|
|
|
136
133
|
"<projectKey>": {
|
|
137
134
|
// OneNote (pull-onenote uses these as Step A inputs)
|
|
138
135
|
"one_sectionName": "<displayName>.one",
|
|
139
|
-
"one_sectionFileId": "<wdsectionfileid GUID>", // PRIMARY — verbatim
|
|
136
|
+
"one_sectionFileId": "<wdsectionfileid GUID>", // PRIMARY — consumed verbatim by pull-onenote
|
|
140
137
|
"one_sectionGroupId": "<wdsectiongroupid GUID>", // when boundary is a section group
|
|
141
138
|
"one_sectionOneNoteGuid": "<wdsectiononenoteguid GUID>", // alternate identifier (older notebooks)
|
|
142
139
|
"one_sectionPath": "/<group>/<section>.one", // human-readable path for run-reports
|
|
@@ -158,38 +155,57 @@ For each enabled source, resolve and persist the canonical lookup keys into `<wo
|
|
|
158
155
|
}
|
|
159
156
|
```
|
|
160
157
|
|
|
161
|
-
**OneNote discovery procedure (deterministic, follow exactly)
|
|
158
|
+
**OneNote discovery procedure (deterministic, follow exactly).**
|
|
162
159
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
160
|
+
Per `workiq-onenote-query-shape.instructions.md` — the **only** WorkIQ query shape that returns OneNote data is **natural-language naming by display name**, scoped to one section in one notebook. The doctrine file lists every empirically-broken phrasing (enumeration verbs, structured-field requests, filter-syntax expressions, ID-lookup questions) in its "Forbidden phrasings" table — see that file for the canonical anti-pattern list. Drivers MUST NOT emit any of those phrasings; they fail empirically (WorkIQ punts to Graph or routes to summary mode).
|
|
161
|
+
|
|
162
|
+
1. For each entry in `boundaries.onenote.section_names[]` (or the user-provided section name, e.g. `HCA`), run **one** narrow WorkIQ query per section using display names only:
|
|
166
163
|
```
|
|
167
|
-
|
|
168
|
-
3. Validate by re-issuing the Step A.1 enumerate query from `pull-onenote/SKILL.md` against the discovered `wdsectionfileid`. If the table has ≥ 1 page row, persist the IDs. If empty, try `wdsectiongroupid`, then `wdsectiononenoteguid`. If all three fail, write the section as `disabled` with `next_step: ask user for sourceDoc URL` and continue.
|
|
169
|
-
4. Persist to `m365-mutable.json#knownSections.<projectKey>` and mirror the resolved IDs into `boundaries.onenote.section_file_ids[]` / `section_group_ids[]` in `integrations.yml`.
|
|
170
|
-
5. Record one line in `bootstrap-status.md`: `OneNote: resolved wdsectionfileid=<id> via name "<name>" (N pages enumerated)`.
|
|
171
|
-
6. **Browser-URL completeness gate (kushi v3.10.0+).** After persisting `one_sectionFileId`, the browser-required fields (`one_notebookSourceDoc`, `one_notebookSpoBaseUrl`, `one_sectionWebUrl`, `one_sectionName`) MUST also be present and valid. Run:
|
|
172
|
-
```pwsh
|
|
173
|
-
node plugin/skills/pull-onenote/scripts/recapture-section-url.mjs --project <name> --engagement-root <engagement-root> --check
|
|
164
|
+
workiq ask -q "In the OneNote notebook '<NOTEBOOK DISPLAY NAME>', show me the pages in the section named '<SECTION DISPLAY NAME>'. Return a flat table with: page title, last modified, web URL. No commentary. Do not truncate."
|
|
174
165
|
```
|
|
175
|
-
|
|
166
|
+
The notebook display name comes from `m365Auth.oneNote.defaultNotebookName` in `m365-auth.json` (persisted during `setup`). The section display name comes from `boundaries.onenote.section_names[]` in `integrations.yml`.
|
|
167
|
+
2. **Parse GUIDs out of the URL fragments** in the response — the `web URL` column contains `Doc.aspx` URLs of the form `...?...&wd=target(<section>|<wdsectionfileid>/...)&...&wdpartid={GUID}{1}&wdsectionfileid={GUID}`. Extract `wdsectionfileid`, `wdpartid`, and `sourcedoc` GUIDs. Do NOT interpret prose summaries.
|
|
168
|
+
3. If the table is empty or the query returns a Graph-Explorer-style punt (classified per `fallback-status-reporting.instructions.md`), mark the section `disabled = true, reason = "workiq-discovery-failed"` in `integrations.yml`, write a one-line entry in `bootstrap-status.md`, and continue. Do NOT escalate to Playwright at bootstrap time — escalation is per `workiq-onenote-query-shape.instructions.md` "When (and only when) to use Playwright" (refresh-time, opted-in, threshold-driven).
|
|
169
|
+
4. Persist resolved IDs to `m365-mutable.json#knownSections.<projectKey>` per `m365-id-registry.instructions.md` and mirror into `boundaries.onenote.section_file_ids[]` / `section_group_ids[]` in `integrations.yml`.
|
|
170
|
+
5. Record one line in `bootstrap-status.md`: `OneNote: resolved wdsectionfileid=<id> via natural-language query for section "<name>" in notebook "<notebook>" (N pages enumerated)`.
|
|
171
|
+
6. **Browser-URL fields are OPTIONAL at bootstrap (kushi v4.7.3+).** The Playwright-required fields (`one_notebookSourceDoc`, `one_notebookSpoBaseUrl`, `one_sectionWebUrl`, `one_sectionName`) are only needed if the user has opted into the Playwright recovery fallback (`m365Auth.oneNote.playwrightFallback: true`). When opted in, run `recapture-section-url.mjs --check`; if exit 1, prompt for the address-bar URL paste. When NOT opted in, skip this gate entirely — WorkIQ-only operation does not need these fields.
|
|
176
172
|
|
|
177
173
|
**SharePoint, Teams, Email, CRM, ADO** follow the same shape: bootstrap discovers and persists; refresh consumes. Per-source discovery procedures live in each `pull-*/SKILL.md`'s "Bootstrap discovery" section. Bootstrap MUST invoke each pull-*'s discovery probe with the user-supplied seed (folder name, channel name, request id, work item id), persist the resolved IDs, and only then dispatch the pull.
|
|
178
174
|
|
|
179
|
-
#### Step 4b — Dispatch
|
|
175
|
+
#### Step 4b — Dispatch (with verification gate after each pull)
|
|
180
176
|
|
|
181
|
-
Then dispatch to each enabled per-source skill with `--window last 30 days` (each skill self-refuses if its boundary is still empty)
|
|
177
|
+
Then dispatch to each enabled per-source skill with `--window last 30 days` (each skill self-refuses if its boundary is still empty). **After every dispatch**, run the per-source verification gate per `..\..\instructions\per-source-verification-gate.instructions.md`:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
for source in [pull-email, pull-teams, pull-meetings, pull-onenote, pull-loop,
|
|
181
|
+
pull-sharepoint, pull-crm, pull-ado, pull-misc]:
|
|
182
|
+
if not enabled(source): continue
|
|
183
|
+
result = dispatch(source, --window "last 30 days")
|
|
184
|
+
gate = run_verification_gate(source, result)
|
|
185
|
+
if gate.status == "fail":
|
|
186
|
+
retry = dispatch(source, --window "last 30 days", --retry)
|
|
187
|
+
gate2 = run_verification_gate(source, retry)
|
|
188
|
+
if gate2.status == "fail":
|
|
189
|
+
append_to_followups(<project>/FOLLOW-UPS.md, gate2)
|
|
190
|
+
append_to_runlog(<project>/Evidence/run-log.yml, source, "failed-gate")
|
|
191
|
+
append_to_tracking(gate2.process_audit_failures)
|
|
192
|
+
# do NOT abort the whole bootstrap — continue to next source
|
|
193
|
+
# next source
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Source order (deterministic, do not reshuffle):
|
|
182
197
|
|
|
183
198
|
1. `pull-email`
|
|
184
199
|
2. `pull-teams`
|
|
185
200
|
3. `pull-meetings`
|
|
186
201
|
4. `pull-onenote`
|
|
187
|
-
5. `pull-
|
|
188
|
-
6. `pull-
|
|
189
|
-
7. `pull-
|
|
190
|
-
8. `pull-
|
|
202
|
+
5. `pull-loop` (if enabled — boundary `boundaries.loop.workspace_ids[]` populated)
|
|
203
|
+
6. `pull-sharepoint`
|
|
204
|
+
7. `pull-crm` (if enabled)
|
|
205
|
+
8. `pull-ado` (if enabled)
|
|
206
|
+
9. `pull-misc` (if `<project>/external-links.txt` exists with ≥ 1 non-placeholder, non-delegated link)
|
|
191
207
|
|
|
192
|
-
Each produces snapshot/ + stream/ output per `snapshot-vs-stream.instructions.md`.
|
|
208
|
+
Each produces snapshot/ + stream/ output per `snapshot-vs-stream.instructions.md`. The gate enforces: shape (snapshot/ + stream/ + verbatim/ where applicable) → per-source extras (transcript-class file for meetings, sectionId for onenote, siteId for sharepoint, chatId for teams, folders for email, engagementRecordId for crm, areaPath for ado) → process-compliance (workiq-first / verbatim-by-default / capture-learnings / run-report mention / fuzzy-disambiguation cited / cleanup-on-resolution / citation-ledger).
|
|
193
209
|
|
|
194
210
|
**pull-misc bootstrap note:** if `<project>/external-links.txt` does NOT exist, scaffold it from `templates/init/external-links.template.txt` so the user has a place to paste links. Mark the source as `enabled: true, links: 0` in `integrations.yml#boundaries.misc` and skip the dispatch (nothing to fetch yet).
|
|
195
211
|
|
|
@@ -208,8 +224,9 @@ If `standard` (or `core`) → **skip this step**. Note in the run summary: *"Sta
|
|
|
208
224
|
Per `side-by-side-config.instructions.md` "Verification" rule, list all live config files (path + size + last-write time). Show:
|
|
209
225
|
- SETUP summary table
|
|
210
226
|
- Side-by-side config table (templates ↔ live files)
|
|
211
|
-
- Per-source pull table (snapshot count + stream weeks covered)
|
|
227
|
+
- Per-source pull table (snapshot count + stream weeks covered + **gate status** [pass / retried-pass / failed-followups-written])
|
|
212
228
|
- New Open Questions count
|
|
229
|
+
- **Open follow-ups count** — if `<project>/FOLLOW-UPS.md` was appended to, surface the count and link to the file
|
|
213
230
|
|
|
214
231
|
End with a one-liner pointing at Q&A:
|
|
215
232
|
|
|
@@ -222,4 +239,13 @@ End with a one-liner pointing at Q&A:
|
|
|
222
239
|
- "add me to project `<name>`"
|
|
223
240
|
- "I'm new to `<name>`, set me up"
|
|
224
241
|
- "do it all for `<name>`" (when project has no Evidence/ folder yet)
|
|
225
|
-
- "redo onboarding for `<name>`" (forces re-prompt of all config questions)
|
|
242
|
+
- "redo onboarding for `<name>`" (forces re-prompt of all config questions)
|
|
243
|
+
## References (v4.4.7)
|
|
244
|
+
|
|
245
|
+
- Name → ID resolution (any source) follows `..\..\instructions\fuzzy-disambiguation.instructions.md`.
|
|
246
|
+
- After each per-source pull, run the gate per `..\..\instructions\per-source-verification-gate.instructions.md` (retry once → FOLLOW-UPS.md on failure).
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
## Issue Recovery
|
|
250
|
+
|
|
251
|
+
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.
|
|
@@ -44,4 +44,8 @@ Append a `consolidation_runs:` entry: `{ window, contributors, files_written }`.
|
|
|
44
44
|
|
|
45
45
|
- "consolidate `<X>` last `<N>` days"
|
|
46
46
|
- "merge contributors for `<X>` week of `<date>`"
|
|
47
|
-
- (auto) called by refresh-project when contributors.yml lists >1 alias
|
|
47
|
+
- (auto) called by refresh-project when contributors.yml lists >1 alias
|
|
48
|
+
|
|
49
|
+
## Issue Recovery
|
|
50
|
+
|
|
51
|
+
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.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# emit-vertex / vertex-link
|
|
2
|
+
|
|
3
|
+
Two sister skills that integrate kushi with the [vertex](https://github.com/commercial-software-engineering/vertex) shared note-taking platform.
|
|
4
|
+
|
|
5
|
+
| Skill | What |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `vertex-link` | One-time mapping: kushi project → vertex repo + customer + initiative. Populates `kushi.yaml#vertex`. |
|
|
8
|
+
| `emit-vertex` | Render vertex-shaped artifacts (weekly status, decisions, workshops, comms, living-doc PR proposals) from kushi Evidence/+State/. |
|
|
9
|
+
|
|
10
|
+
See:
|
|
11
|
+
|
|
12
|
+
- [`SKILL.md`](./SKILL.md) for the full emit contract
|
|
13
|
+
- [`../vertex-link/SKILL.md`](../vertex-link/SKILL.md) for the link contract
|
|
14
|
+
- [`../../instructions/vertex-emit.instructions.md`](../../instructions/vertex-emit.instructions.md) for hard doctrine
|
|
15
|
+
- [`../../../docs/concepts/kushi-with-vertex.md`](../../../docs/concepts/kushi-with-vertex.md) for the user-facing concept guide
|
|
16
|
+
|
|
17
|
+
## CLI quick reference
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
# One-time
|
|
21
|
+
kushi vertex-link --project <p> --vertex-repo <path>
|
|
22
|
+
|
|
23
|
+
# Then any time
|
|
24
|
+
kushi emit-vertex --project <p> --weekly # this week's status
|
|
25
|
+
kushi emit-vertex --project <p> --decisions # ADRs from State/01_decisions.md
|
|
26
|
+
kushi emit-vertex --project <p> --workshops # workshop write-ups
|
|
27
|
+
kushi emit-vertex --project <p> --comms # call transcripts + chats + significant emails
|
|
28
|
+
kushi emit-vertex --project <p> --living # PR-style diffs against living docs
|
|
29
|
+
kushi emit-vertex --project <p> --all # everything
|
|
30
|
+
|
|
31
|
+
# Add --apply to copy staged files into the vertex repo
|
|
32
|
+
# Add --dry-run to skip validation + apply
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## No vertex schema vendoring
|
|
36
|
+
|
|
37
|
+
Schemas live in the vertex repo at `.vertex/scripts/validation/schemas/`. The validator is `.vertex/scripts/validation/validate_frontmatter.py`. emit-vertex detects the vertex repo via `vertex.json` and uses both in place. Kushi ships no copies.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "emit-vertex"
|
|
3
|
+
description: "Render vertex-shaped artifacts from kushi Evidence/+State/ — weekly status, decisions, workshops, comms, living-doc PR proposals. Stages first, validates against vertex's own schemas, applies on demand."
|
|
4
|
+
applyTo: ["emit-vertex"]
|
|
5
|
+
version: "1.1.0"
|
|
6
|
+
maturity: "preview"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# emit-vertex
|
|
10
|
+
|
|
11
|
+
Render the artifacts that the [vertex](https://github.com/commercial-software-engineering/vertex) shared note-taking platform publishes (`<customer-slug>/<initiative-slug>/…`) from kushi's captured Evidence/ + State/ for a single kushi project.
|
|
12
|
+
|
|
13
|
+
## Implementation status (as of v4.7.1)
|
|
14
|
+
|
|
15
|
+
End-to-end verified against the real vertex validator + schemas (43 tests passing):
|
|
16
|
+
|
|
17
|
+
- ✅ **Detect** — `plugin/lib/detect-vertex-repo.mjs` reads `vertex.json`, locates `validate_frontmatter.py`, returns repo info or named errors (`vertex-repo-not-found`, `vertex-json-missing`, `vertex-json-malformed`, `vertex-validator-missing`)
|
|
18
|
+
- ✅ **Validate** — `plugin/lib/vertex-validate.mjs` invokes the real Python validator with `--base-dir` so staged files OUTSIDE the vertex repo still match the schema-mapping globs. Probes for a Python with `pyyaml` (some Windows shims advertise `python3 --version` ok but lack the module).
|
|
19
|
+
- ✅ **Render** — `plugin/lib/render-vertex.mjs` produces schema-clean markdown for:
|
|
20
|
+
- `status-updates/YYYY-MM-DD.md` (type=status-update; green/yellow/red enum; required fields)
|
|
21
|
+
- `decisions/NNN-<slug>.md` (zero-padded ADR number; type=decision)
|
|
22
|
+
- `comms/call-transcripts/YYYY-MM-DD-<slug>.md` (type=call-transcript; participants list)
|
|
23
|
+
- `comms/chats/YYYY-MM-DD-<slug>.md` (type=chat)
|
|
24
|
+
- `comms/emails/YYYY-MM-DD-<slug>.md` (type=email)
|
|
25
|
+
- ✅ **Multi-binding mapping** — `kushi.yaml#vertex.bindings[]` with vertex-parity targeting precedence (CLI flag > path inference > default > single > prompt)
|
|
26
|
+
|
|
27
|
+
Still doctrine-only (agent follows SKILL.md, no JS helper yet):
|
|
28
|
+
- Workshops, living-doc diff proposals, indicator rollups from State/ ledgers
|
|
29
|
+
|
|
30
|
+
## Doctrine
|
|
31
|
+
|
|
32
|
+
This skill is governed by:
|
|
33
|
+
|
|
34
|
+
1. **HARD** [`vertex-emit.instructions.md`](../../instructions/vertex-emit.instructions.md) — full doctrine: hard rules, source→artifact mapping, CLI surface, failure modes
|
|
35
|
+
2. **HARD** [`citation-ledger.instructions.md`](../../instructions/citation-ledger.instructions.md) — every bullet/row carries `[source: …]`
|
|
36
|
+
3. **HARD** [`workiq-input-sanitization.instructions.md`](../../instructions/workiq-input-sanitization.instructions.md) — any WorkIQ touch is sanitized
|
|
37
|
+
4. **HARD** [`status-color-rule.instructions.md`](../../instructions/status-color-rule.instructions.md) — 🟢🟡🔴 first-match-wins
|
|
38
|
+
5. **HARD** [`studio-registry.instructions.md`](../../instructions/studio-registry.instructions.md) — distros from `plugin/config/studios.json`
|
|
39
|
+
6. **HARD** [`tracking.instructions.md`](../../instructions/tracking.instructions.md) — emit writes a tracking entry
|
|
40
|
+
7. **HARD** [`run-reports.instructions.md`](../../instructions/run-reports.instructions.md) — per-run report under `Evidence/<alias>/refresh-reports/`
|
|
41
|
+
|
|
42
|
+
## Tools
|
|
43
|
+
|
|
44
|
+
- **Vertex repo** (PRIMARY, detected via `vertex.json`) — schemas + validator used in place; no vendoring
|
|
45
|
+
- **kushi Evidence/+State/** (PRIMARY) — input
|
|
46
|
+
- **kushi.yaml#vertex** (PRIMARY) — mapping (`repo_path`, `customer_slug`, `initiative_slug`, `studio`)
|
|
47
|
+
- **WorkIQ** (FALLBACK, only if evidence is stale and user opts in via `--refresh-first`)
|
|
48
|
+
- **Playwright / Host / Graph** (NOT USED)
|
|
49
|
+
|
|
50
|
+
## Pre-flight gates (must all pass before staging)
|
|
51
|
+
|
|
52
|
+
| Gate | Check |
|
|
53
|
+
|---|---|
|
|
54
|
+
| A | `kushi.yaml#vertex.repo_path` resolves to a directory containing `vertex.json` |
|
|
55
|
+
| B | `<repo>/.vertex/scripts/validation/validate_frontmatter.py` exists |
|
|
56
|
+
| C | `<repo>/<customer-slug>/<initiative-slug>/` either exists OR vertex bootstrap is needed (skill surfaces with vertex's own `/bootstrap` recommendation) |
|
|
57
|
+
| D | `kushi.yaml#vertex.{customer_slug, initiative_slug}` are non-empty and pass `sanitize-workiq-input` |
|
|
58
|
+
| E | At least one mode flag (`--weekly`, `--decisions`, `--workshops`, `--comms`, `--living`, `--all`) |
|
|
59
|
+
| F | Python 3 is on PATH (required to invoke `validate_frontmatter.py`) |
|
|
60
|
+
|
|
61
|
+
Failures: see "Failure modes" table in `vertex-emit.instructions.md`. Each failure is a named, actionable code — never silent.
|
|
62
|
+
|
|
63
|
+
## Phases
|
|
64
|
+
|
|
65
|
+
### Phase 1 — Resolve
|
|
66
|
+
|
|
67
|
+
1. Read `kushi.yaml#vertex`. If missing, exit with `vertex-mapping-incomplete` and recommend `kushi vertex-link`.
|
|
68
|
+
2. Resolve `repo_path`, verify `vertex.json` exists. Read `vertex.json#version` and log it.
|
|
69
|
+
3. Resolve `<repo>/<customer-slug>/<initiative-slug>/` — confirm or recommend vertex bootstrap.
|
|
70
|
+
4. Determine reporting window:
|
|
71
|
+
- `--weekly` without `--week-ending` → candidate week per vertex's rule (Mon-Fri; Fri after 17:00 = current; Sat/Sun = current; else = prior). Always confirm with user.
|
|
72
|
+
- Other modes → no window (operate on all evidence).
|
|
73
|
+
|
|
74
|
+
### Phase 2 — Collect
|
|
75
|
+
|
|
76
|
+
1. Load `Evidence/<all-aliases>/` for the project, filtered by window if applicable.
|
|
77
|
+
2. Load `State/*.md` for living docs and decisions.
|
|
78
|
+
3. Load `Evidence/_Consolidated/<week>_consolidated.md` for cross-contributor view (`consolidate-evidence` is a prerequisite for `--weekly`; if missing, run it first).
|
|
79
|
+
4. Run `status-color-rule` evaluator on the evidence; record `rule_id`, `triggers` with citations, `color`, `reason`.
|
|
80
|
+
5. For each requested artifact mode, build the in-memory render plan.
|
|
81
|
+
|
|
82
|
+
### Phase 3 — Stage
|
|
83
|
+
|
|
84
|
+
For each artifact in the render plan, write to:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
<engagement-root>/<project>/.kushi-staging/vertex/<run-ts>/<customer-slug>/<initiative-slug>/<vertex-relative-path>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Living-doc proposals are written as:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
<staging-root>/proposals/<vertex-relative-path>.diff
|
|
94
|
+
<staging-root>/proposals/<vertex-relative-path>.proposal.md
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Every emitted file has:
|
|
98
|
+
- Schema-valid frontmatter (per vertex schema for that path)
|
|
99
|
+
- Body content from kushi evidence, with inline citations on every claim
|
|
100
|
+
- A `Sources` section at the end (point-in-time artifacts) listing the evidence files consulted
|
|
101
|
+
|
|
102
|
+
### Phase 4 — Validate
|
|
103
|
+
|
|
104
|
+
For each staged file (not for `.diff`/`.proposal.md` companions):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
python3 <vertex-repo>/.vertex/scripts/validation/validate_frontmatter.py <staged-file>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If any file fails, surface the validator output, attempt one automatic fix-up pass (re-render with stricter frontmatter from the schema), revalidate. If still failing, exit with `vertex-schema-fail` and the path + error.
|
|
111
|
+
|
|
112
|
+
### Phase 5 — Apply (only with `--apply`)
|
|
113
|
+
|
|
114
|
+
1. For each staged point-in-time file:
|
|
115
|
+
- If target doesn't exist → copy in.
|
|
116
|
+
- If target exists → present diff, prompt overwrite / abort / sibling-suffix. Default abort.
|
|
117
|
+
2. For each staged living-doc proposal:
|
|
118
|
+
- Do NOT copy into vertex repo.
|
|
119
|
+
- Print path to the staged `.diff` + `.proposal.md` and a one-line summary.
|
|
120
|
+
3. GitDoc inside the vertex repo will auto-commit any actually-copied files when the user next saves the editor (or immediately if GitDoc debounce has fired).
|
|
121
|
+
|
|
122
|
+
### Phase 6 — Report
|
|
123
|
+
|
|
124
|
+
Write `<engagement-root>/<project>/Evidence/<alias>/refresh-reports/<ts>_emit-vertex.md` per `run-reports.instructions.md`. Write a tracking entry per `tracking.instructions.md`. Append per-source learnings (if any) per `capture-learnings.instructions.md`.
|
|
125
|
+
|
|
126
|
+
## Boundary contract
|
|
127
|
+
|
|
128
|
+
- emit-vertex MUST NOT `git commit` / `git push` — GitDoc inside the vertex repo handles all version control.
|
|
129
|
+
- emit-vertex MUST NOT edit living docs in place — only PR-style proposals.
|
|
130
|
+
- emit-vertex MUST NOT vendor or modify vertex schemas — read them in place from the vertex repo.
|
|
131
|
+
- emit-vertex MUST run `validate_frontmatter.py` before any `--apply`.
|
|
132
|
+
- emit-vertex MUST NOT call WorkIQ unless the user passes `--refresh-first` (and even then, only via `pull-*` skills with full sanitization).
|
|
133
|
+
|
|
134
|
+
## Outputs (canonical paths)
|
|
135
|
+
|
|
136
|
+
### Point-in-time (copied to vertex repo on `--apply`)
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
<vertex-repo>/<customer-slug>/<initiative-slug>/status-updates/<week-ending>.md
|
|
140
|
+
<vertex-repo>/<customer-slug>/<initiative-slug>/comms/emails/status/<week-ending>-weekly-status.md
|
|
141
|
+
<vertex-repo>/<customer-slug>/<initiative-slug>/decisions/<NNN>-<slug>.md
|
|
142
|
+
<vertex-repo>/<customer-slug>/<initiative-slug>/workshops/<topic>.md
|
|
143
|
+
<vertex-repo>/<customer-slug>/<initiative-slug>/comms/call-transcripts/<YYYY-MM-DD>-<slug>.md
|
|
144
|
+
<vertex-repo>/<customer-slug>/<initiative-slug>/comms/chats/<YYYY-MM-DD>-<topic>.md
|
|
145
|
+
<vertex-repo>/<customer-slug>/<initiative-slug>/comms/emails/<YYYY-MM-DD>-<subject>.md
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Living-doc proposals (NEVER copied; staged only)
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
<staging-root>/proposals/customer-details.md.diff
|
|
152
|
+
<staging-root>/proposals/customer-details.md.proposal.md
|
|
153
|
+
<staging-root>/proposals/msft-stakeholders.md.diff
|
|
154
|
+
<staging-root>/proposals/risk-register.md.diff
|
|
155
|
+
<staging-root>/proposals/architecture-overview.md.diff
|
|
156
|
+
<staging-root>/proposals/tech-stack.md.diff
|
|
157
|
+
<staging-root>/proposals/initiative-overview.md.diff
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Tracking + reporting
|
|
161
|
+
|
|
162
|
+
Per `tracking.instructions.md`, every run writes one row to `<project>/Evidence/<alias>/tracking.md` with run-ts, mode flags, files staged, files validated, files applied, files skipped, and the validator exit summary. Per-run report at `refresh-reports/<ts>_emit-vertex.md` carries the human-readable detail.
|
|
163
|
+
|
|
164
|
+
## Issue recovery
|
|
165
|
+
|
|
166
|
+
Per `issue-recovery.instructions.md`. emit-vertex's pre-flight failures, schema failures, and overwrite-blocked events are all named codes — recovery is mechanical.
|
|
167
|
+
|
|
168
|
+
## See also
|
|
169
|
+
|
|
170
|
+
- [`vertex-emit.instructions.md`](../../instructions/vertex-emit.instructions.md) — full doctrine
|
|
171
|
+
- [`vertex-link/SKILL.md`](../vertex-link/SKILL.md) — sister skill that populates `kushi.yaml#vertex` mapping
|
|
172
|
+
- [`docs/concepts/kushi-with-vertex.md`](../../../docs/concepts/kushi-with-vertex.md) — outcome-based user-facing guide
|
|
173
|
+
- [vertex repo](https://github.com/commercial-software-engineering/vertex)
|
|
@@ -110,6 +110,8 @@ Present this verbatim:
|
|
|
110
110
|
> | | `pull-crm` | core+ | ✅ | ✅ |
|
|
111
111
|
> | | `pull-ado` | core+ | ✅ | ✅ |
|
|
112
112
|
> | **Consumer (Q&A)** | `ask-project` | core+ | reads both | — |
|
|
113
|
+
> | **Vertex integration** | `vertex-link` | core+ | — | — |
|
|
114
|
+
> | | `emit-vertex` | core+ | reads both | — |
|
|
113
115
|
> | **FDE authoring** | `fde-intake` | standard+ | reads both | — |
|
|
114
116
|
> | | `fde-report` | standard+ | reads both | — |
|
|
115
117
|
> | | `fde-triage` | standard+ | reads both | — |
|
|
@@ -50,7 +50,7 @@ Refuse to produce `proposed.md` and tell the user exactly what's missing if any
|
|
|
50
50
|
1. **Resolve config (deterministic)** — load global ADO config (tenant/org/apiVersion) + per-project `integrations.yml` (engagement_id + writes block). All from known paths above. No prompts unless `writes:` is missing.
|
|
51
51
|
2. **First-run scaffold of `ado.writes:`** — if missing, append the template block to `integrations.yml ado:` (preserving every existing key). Stop. Tell user to confirm `fieldRefName` matches their tenant's process template. (Honors `side-by-side-config.instructions.md`: template stays generic, live filled file holds the real value.)
|
|
52
52
|
3. **Pick the consolidated file** — most recent `<project>/Evidence/_Consolidated/<YYYY-MM-DD>_consolidated.md`. Optionally chase referenced per-source files for citations.
|
|
53
|
-
4. **Read current ADO field value** (read-only GET, per `
|
|
53
|
+
4. **Read current ADO field value** (read-only GET, per `auth-and-retry.instructions.md` — pre-flight + tenant validation + token reuse + 401 retry):
|
|
54
54
|
```
|
|
55
55
|
GET https://dev.azure.com/{org}/{project}/_apis/wit/workitems/{engagement_id}?api-version=7.1&fields={ado.writes.statusSummary.fieldRefName},System.Rev
|
|
56
56
|
```
|
|
@@ -93,7 +93,7 @@ Refuse to produce `proposed.md` and tell the user exactly what's missing if any
|
|
|
93
93
|
| `integrations.yml` missing | Refuse. Tell user to run `@Kushi bootstrap <project>` first. |
|
|
94
94
|
| `ado.engagement_id == 0` (Initiative not linked yet) | Refuse with the message in Prerequisites table. Do NOT prompt for an ID. |
|
|
95
95
|
| `ado.writes:` block missing | Scaffold from template, stop, ask user to confirm `fieldRefName`. |
|
|
96
|
-
| ADO 401 on fetch | Per `
|
|
96
|
+
| ADO 401 on fetch | Per `auth-and-retry.instructions.md` §4 — re-acquire token once, retry. If still 401, abort and report `auth-failed`. |
|
|
97
97
|
| ADO 404 on Initiative ID | Abort, report `initiative-not-found`. The `engagement_id` in integrations.yml is wrong; tell user to re-run pull-ado discovery or fix manually. |
|
|
98
98
|
| Field reference name not present on work item type | Skip the field portion of `proposed.md`; still produce the comment portion. |
|
|
99
99
|
| Latest consolidated > 8 days old | Continue but flag `stale-evidence` at top of `proposed.md`. |
|
|
@@ -102,7 +102,12 @@ Refuse to produce `proposed.md` and tell the user exactly what's missing if any
|
|
|
102
102
|
## References
|
|
103
103
|
|
|
104
104
|
- `update-ledger.instructions.md` — write-path doctrine and ledger schema (used by `apply-ado-update`; this skill produces the `proposed.md` shape `apply-ado-update` consumes).
|
|
105
|
-
- `
|
|
105
|
+
- `auth-and-retry.instructions.md` — token acquisition, tenant validation, retry-on-401.
|
|
106
106
|
- `side-by-side-config.instructions.md` — config template vs live filled file (here: `integrations.yml ado.writes:` block).
|
|
107
107
|
- `engagement-root-resolution.instructions.md` — resolving `<engagement-root>` and `<project>`.
|
|
108
108
|
- `evidence-thoroughness.instructions.md` — what counts as a citable bullet.
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
## Issue Recovery
|
|
112
|
+
|
|
113
|
+
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.
|
|
@@ -20,7 +20,7 @@ Pulls **ado** evidence in two shapes per `snapshot-vs-stream.instructions.md`:
|
|
|
20
20
|
- **snapshot/** — engagement TREE: parent Engagement + every child WI; each item gets full fields + every discussion comment verbatim + full revision history
|
|
21
21
|
- **stream/** — new comments + state changes + field changes + attachments across the entire tree, weekly bucket
|
|
22
22
|
|
|
23
|
-
WorkIQ-first per `workiq-
|
|
23
|
+
WorkIQ-first per `workiq-only.instructions.md` — but **for ADO, REST is preferred for snapshot** because WorkIQ summarizes discussion threads. Thoroughness per `evidence-thoroughness.instructions.md`; runtime detector + auto-retry + paste-prompt per `evidence-thoroughness.instructions.md`. Citations per `citation-ledger.instructions.md`. Side-by-side mutable hints written immediately on discovery per `side-by-side-config.instructions.md`. Tree expansion + per-item discussion + revision pulls per `ado-engagement-tree.instructions.md`.
|
|
24
24
|
|
|
25
25
|
## Inputs
|
|
26
26
|
|
|
@@ -239,3 +239,13 @@ After successful pass:
|
|
|
239
239
|
- Step 1 returns zero candidates → record `no-match` + WIQL + `next_step`, stop.
|
|
240
240
|
- A child WI fetch fails → mark `❌ item-fetch-failed` in `tree.md`, continue tree.
|
|
241
241
|
- Discussion paging fails mid-stream → record `❌ comments-partial — N/M fetched` and continue.
|
|
242
|
+
|
|
243
|
+
## References (v4.4.7)
|
|
244
|
+
|
|
245
|
+
- Name → ID resolution follows ..\..\instructions\fuzzy-disambiguation.instructions.md (universal fuzzy contract).
|
|
246
|
+
- After this pull completes, the per-source verification gate runs: ..\..\instructions\per-source-verification-gate.instructions.md (retry once, then write FOLLOW-UPS.md).
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
## Issue Recovery
|
|
250
|
+
|
|
251
|
+
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.
|
|
@@ -20,7 +20,7 @@ Pulls **crm** evidence in two shapes per `snapshot-vs-stream.instructions.md`:
|
|
|
20
20
|
- **snapshot/** — engagement record with EVERY field the API returns (owner, status, account, dates, custom fields), all long-text fields VERBATIM, plus every related annotation (note) verbatim
|
|
21
21
|
- **stream/** — notes added, activities logged, field-level changes (old → new + actor + timestamp)
|
|
22
22
|
|
|
23
|
-
WorkIQ-first per `workiq-
|
|
23
|
+
WorkIQ-first per `workiq-only.instructions.md`. Thoroughness per `evidence-thoroughness.instructions.md`; runtime detector + auto-retry + paste-prompt per `evidence-thoroughness.instructions.md`. Citations per `citation-ledger.instructions.md`. Side-by-side mutable hints written immediately on discovery per `side-by-side-config.instructions.md`.
|
|
24
24
|
|
|
25
25
|
## Inputs
|
|
26
26
|
|
|
@@ -208,7 +208,7 @@ If a week file already exists, MERGE (dedupe by event ID, append new events, kee
|
|
|
208
208
|
|
|
209
209
|
1. **Dataverse REST Web API** (preferred for snapshot — gives explicit `$select` + `$expand` control) via `az account get-access-token` against the configured tenant. Read connection from `<workspace>/.kushi/config/shared/integrations.yml`.
|
|
210
210
|
2. **WorkIQ** — only when REST is unavailable; phrase queries to demand verbatim long-text + every annotation (see Step B template above). WorkIQ summarizes by default, so use this path only as fallback.
|
|
211
|
-
3. **Graph REST** — last resort, soft-fail per `
|
|
211
|
+
3. **Graph REST** — last resort, soft-fail per `auth-and-retry.instructions.md`.
|
|
212
212
|
4. **Ask user** — paste verbatim source content if all above fail.
|
|
213
213
|
|
|
214
214
|
Document which path succeeded under `## Source Basis` in each output file.
|
|
@@ -237,3 +237,13 @@ After successful pass:
|
|
|
237
237
|
- Hint missing AND fuzzy resolution returns 0 candidates → ask user once, persist answer to mutable, continue.
|
|
238
238
|
- Multiple plausible candidates → ask user to pick, persist answer.
|
|
239
239
|
- All paths failed for a given record → write evidence file with `❌ all paths failed` marker, log to run-log errors, continue with rest of run.
|
|
240
|
+
|
|
241
|
+
## References (v4.4.7)
|
|
242
|
+
|
|
243
|
+
- Name → ID resolution follows ..\..\instructions\fuzzy-disambiguation.instructions.md (universal fuzzy contract).
|
|
244
|
+
- After this pull completes, the per-source verification gate runs: ..\..\instructions\per-source-verification-gate.instructions.md (retry once, then write FOLLOW-UPS.md).
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
## Issue Recovery
|
|
248
|
+
|
|
249
|
+
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.
|