session-orchestrator 4.2.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/session-start/SKILL.md +1 -1
- package/.agents/skills/ux-grill/SKILL.md +22 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +3 -2
- package/.codex-plugin/plugin.json +1 -1
- package/.codex-plugin/skills/session-start/SKILL.md +1 -1
- package/.codex-plugin/skills/ux-grill/SKILL.md +21 -0
- package/.codex-plugin/skills/ux-grill/agents/openai.yaml +5 -0
- package/.cursor/commands/ux-grill.md +14 -0
- package/.cursor/skills/session-start/SKILL.md +1 -1
- package/.cursor/skills/ux-grill/SKILL.md +13 -0
- package/.cursor-plugin/plugin.json +1 -1
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +94 -1
- package/README.md +98 -86
- package/agents/dialectic-deriver.md +11 -0
- package/commands/ux-grill.md +51 -0
- package/docs/USER-GUIDE.md +2 -2
- package/docs/codex-setup.md +8 -0
- package/docs/components.md +7 -7
- package/docs/events-schema.md +9 -5
- package/docs/github-mirror-protection.md +61 -20
- package/docs/migration-v5.md +62 -0
- package/docs/scope-collision-guard.md +14 -0
- package/hooks/_lib/hook-import-set.json +44 -2
- package/hooks/_lib/lock-bootstrap.mjs +84 -1
- package/hooks/_lib/vcs-create-matcher.mjs +190 -3
- package/hooks/enforce-scope.mjs +201 -0
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +5 -0
- package/hooks/hooks.json +7 -2
- package/hooks/on-session-start.mjs +171 -49
- package/hooks/post-bash-issue-budget-refund.mjs +375 -0
- package/hooks/pre-auq-clarity.mjs +70 -18
- package/hooks/pre-bash-issue-budget.mjs +51 -4
- package/package.json +2 -1
- package/pi/prompts/ux-grill.md +12 -0
- package/scripts/ci/assert-vitest-green.mjs +4 -2
- package/scripts/dialectic-deriver.mjs +32 -8
- package/scripts/emit-session.mjs +72 -1
- package/scripts/lib/agent-status.mjs +441 -9
- package/scripts/lib/auq/schema.mjs +10 -3
- package/scripts/lib/ci-status-banner.mjs +29 -6
- package/scripts/lib/claude-md-budget-lint.mjs +52 -2
- package/scripts/lib/config.mjs +12 -1
- package/scripts/lib/eval/engine.mjs +7 -1
- package/scripts/lib/file-lock.mjs +114 -13
- package/scripts/lib/git-porcelain.mjs +113 -0
- package/scripts/lib/instruction-budget-guard.mjs +415 -47
- package/scripts/lib/io.mjs +29 -4
- package/scripts/lib/issue-budget.mjs +336 -6
- package/scripts/lib/learnings/sizing-subject.mjs +44 -0
- package/scripts/lib/locks/staging-fence-lock.mjs +19 -38
- package/scripts/lib/locks/state-md-lock.mjs +19 -41
- package/scripts/lib/maintenance-due-banner.mjs +11 -1
- package/scripts/lib/peer-cards/merger.mjs +143 -0
- package/scripts/lib/pre-dispatch-check.mjs +20 -14
- package/scripts/lib/project-hygiene.mjs +81 -30
- package/scripts/lib/quality-gate.mjs +14 -65
- package/scripts/lib/reconcile/engine.mjs +19 -1
- package/scripts/lib/reconcile/writer.mjs +278 -11
- package/scripts/lib/scope-echo.mjs +346 -0
- package/scripts/lib/session-lock.mjs +62 -2
- package/scripts/lib/session-record-repair.mjs +91 -0
- package/scripts/lib/session-schema/filters.mjs +26 -1
- package/scripts/lib/session-start-probes.mjs +419 -53
- package/scripts/lib/test-runner/artifact-paths.mjs +30 -5
- package/scripts/lib/test-runner/issue-reconcile.mjs +45 -8
- package/scripts/lib/tmux-layout/layouts.mjs +62 -4
- package/scripts/lib/ux-grill/collect.mjs +1163 -0
- package/scripts/lib/ux-grill/compare.mjs +285 -0
- package/scripts/lib/ux-grill/manifest.mjs +618 -0
- package/scripts/lib/ux-grill/measures.mjs +431 -0
- package/scripts/lib/ux-grill/paths.mjs +224 -0
- package/scripts/lib/ux-grill/pencil-coverage.mjs +284 -0
- package/scripts/lib/ux-grill/reconcile.mjs +344 -0
- package/scripts/lib/ux-grill/run-record.mjs +316 -0
- package/scripts/lib/ux-grill/schema.mjs +321 -0
- package/scripts/lib/validate/check-untracked-test-deps.mjs +33 -19
- package/scripts/lib/validate/check-unwired-features.mjs +48 -20
- package/scripts/lib/vault-status/board-lock.mjs +18 -0
- package/scripts/lib/vault-status/board-writer.mjs +8 -0
- package/scripts/mcp-server.sh +16 -1
- package/scripts/release.mjs +7 -2
- package/skills/bootstrap/SKILL.md +12 -209
- package/skills/bootstrap/references/bootstrap-ecosystem-health-flow.md +48 -0
- package/skills/bootstrap/references/bootstrap-refresh-lock-flow.md +37 -0
- package/skills/bootstrap/references/bootstrap-retroactive-flow.md +108 -0
- package/skills/bootstrap/references/bootstrap-rules-fetch-bridge.md +64 -0
- package/skills/claude-md-drift-check/SKILL.md +9 -2
- package/skills/claude-md-drift-check/checker.mjs +213 -21
- package/skills/discovery/SKILL.md +6 -173
- package/skills/discovery/probes/vault-staleness.mjs +35 -5
- package/skills/discovery/probes-docs.md +8 -4
- package/skills/discovery/probes-supply-chain.md +4 -2
- package/skills/discovery/probes-ui.md +7 -3
- package/skills/discovery/probes-vault.md +12 -4
- package/skills/discovery/references/discovery-interactive-triage.md +139 -0
- package/skills/discovery/references/discovery-triage-state.md +54 -0
- package/skills/eval/rubric-v1.md +13 -0
- package/skills/evolve/SKILL.md +2 -458
- package/skills/evolve/references/evolve-analyze-mode.md +360 -0
- package/skills/evolve/references/evolve-dialectic-mode.md +139 -0
- package/skills/plan/mode-retro.md +4 -3
- package/skills/reconcile/SKILL.md +10 -0
- package/skills/session-end/drift-operations.md +20 -5
- package/skills/session-end/metrics-collection.md +1 -0
- package/skills/session-end/phase-3-6-tail.md +4 -2
- package/skills/session-end/references/phase-2-quality-gate.md +3 -3
- package/skills/session-end/references/phase-5-issue-cleanup.md +6 -1
- package/skills/session-end/session-metrics-write.md +2 -0
- package/skills/session-plan/SKILL.md +2 -144
- package/skills/session-plan/references/session-plan-task-classification.md +152 -0
- package/skills/session-start/SKILL.md +24 -6
- package/skills/session-start/references/operations-contract.md +114 -0
- package/skills/session-start/references/phase-4-ssot-environment-check.md +22 -20
- package/skills/session-start/soul.md +2 -2
- package/skills/test-runner/SKILL.md +1 -1
- package/skills/tmux-layout/SKILL.md +3 -1
- package/skills/ux-grill/SKILL.md +211 -0
- package/skills/ux-grill/rubric-v2.md +201 -0
- package/skills/ux-grill/soul.md +76 -0
- package/skills/wave-executor/SKILL.md +3 -128
- package/skills/wave-executor/references/wave-executor-quality-gate.md +61 -0
- package/skills/wave-executor/references/wave-executor-state-init.md +86 -0
- package/skills/wave-executor/references/wave-loop-dispatch.md +8 -0
- package/skills/wave-executor/references/wave-loop-review.md +18 -5
- package/templates/_shared/ux-manifest.template.md +149 -0
- package/templates/_shared/journey-manifest.md +0 -114
|
@@ -47,6 +47,7 @@ if [[ "$DC_ENABLED" == "true" ]]; then
|
|
|
47
47
|
DC_STATUS=$(echo "$DC_JSON" | jq -r '.status // "infra-error"')
|
|
48
48
|
DC_ERR_COUNT=$(echo "$DC_JSON" | jq -r '.errors // [] | length')
|
|
49
49
|
DC_WARN_COUNT=$(echo "$DC_JSON" | jq -r '.warnings // [] | length')
|
|
50
|
+
DC_NOTES_COUNT=$(echo "$DC_JSON" | jq -r '.notes // [] | length')
|
|
50
51
|
fi
|
|
51
52
|
```
|
|
52
53
|
|
|
@@ -55,11 +56,13 @@ fi
|
|
|
55
56
|
**Reporting rules:**
|
|
56
57
|
|
|
57
58
|
- **`mode: off`** — checker reports `status: skipped-mode-off`; include a single line "CLAUDE.md drift: skipped (mode=off)" in the quality gate report. Never blocks.
|
|
58
|
-
- **`mode: warn`** — checker always exits 0. If `.errors | length > 0`, surface the list in the report under "CLAUDE.md drift
|
|
59
|
+
- **`mode: warn`** — checker always exits 0. If `.errors | length > 0`, surface the list in the report under "CLAUDE.md drift errors (mode=warn, non-blocking)" with check + file:line + message for each entry. Never blocks close; note that `mode: strict` would have routed the same errors through the carryover path below. `.warnings[]` are rendered by their own rule below, independently of whether any error exists.
|
|
59
60
|
- **`mode: strict`** (legacy alias `hard`, normalized to `strict` at parse time — #217) — checker exits 1 on errors. On exit 1: do NOT block the close. Surface the full error list, then default to **warn + carryover + continue** (Recommended): file a carryover issue (labels `carryover`, `priority::high`) titled `[Carryover] CLAUDE.md drift (strict) — <E> errors` capturing the drift items for a follow-up session, log a Deviation entry in STATE.md `## Deviations`, then continue the close. Offer "Override and close" (continue without a carryover issue; log the Deviation) as an alternative via AskUserQuestion. The user can also (a) fix the drift directly in `CLAUDE.md` (or `AGENTS.md` on Codex CLI) / `_meta/`, or (b) temporarily set `mode: warn` while backfilling, or (c) disable a specific check via its `check-*` flag if it reports false positives on this codebase.
|
|
61
|
+
- **Warnings (`.warnings[]`, every mode that runs: `warn` and `strict`)**: whenever `DC_WARN_COUNT > 0`, also when `status: ok` and also when `DC_ERR_COUNT == 0`, render the entries under their own heading **"CLAUDE.md drift warnings (mode=<mode>, non-blocking)"**, one line per entry: `[<check>] <file>:<line> — <message>`. Warnings are the second category, separate from errors and from notes: they are NOT nested under the error branch above, so a run with `status: ok`, `errors: []` and a non-empty `warnings[]` still renders every warning (#1350 — before this rule a 36-warning run rendered nothing at all, because both the error branch and the success line excluded it). Never let a warning block the close, never let it change the exit-code dispatch below, and never file a carryover issue for a warning on its own — a warning is an operator-visible signal, not a gate. Render them from `DC_JSON` with e.g. `echo "$DC_JSON" | jq -r '.warnings[] | " [\(.check)] \(.file):\(.line) — \(.message)"'`.
|
|
62
|
+
- **Notes (`.notes[]`, every mode that runs: `warn` and `strict`)**: whenever `DC_NOTES_COUNT > 0`, also when `status: ok`, render the entries under their own heading **"CLAUDE.md drift notes (reported, not warned)"**, one line per entry: `[<check>/<probe>] <file>:<line> — <message>`. Notes are a third category, separate from errors and warnings (#1312, `.claude/rules/development.md` § Guard & Threshold Design: split the category instead of raising the threshold; source: the `notes[] human renderer (#1312)` block in `skills/claude-md-drift-check/checker.mjs`). Keeping them separate is part of the contract. Never call a note a "warning" or an "error", never let one block or change the exit-code dispatch below, and never file a carryover issue for it. It is reported, and no action follows from it. If notes are hidden, nobody reads them, and that unread state is what the split was built to end.
|
|
60
63
|
- **Exit 2** (infra error — missing `node`, unreadable `VAULT_DIR`, malformed args) — treat as a skipped gate with a loud warning ("CLAUDE.md drift: infrastructure error — <reason>"). Do NOT block the session close on infra failures.
|
|
61
64
|
|
|
62
|
-
**Exit-code dispatch:** The checker writes infra-error JSON to stderr (suppressed by `2>/dev/null` above), so `DC_JSON` is empty when `DC_EXIT == 2`. Always branch on `DC_EXIT` first, then `DC_STATUS`:
|
|
65
|
+
**Exit-code dispatch:** The checker writes infra-error JSON to stderr (suppressed by `2>/dev/null` above), so `DC_JSON` is empty when `DC_EXIT == 2`. Notes still arrive even though stderr is dropped: the checker also prints a human-readable notes block on stderr, but the same `notes[]` sits in the stdout JSON read into `DC_NOTES_COUNT` above. Do NOT remove `2>/dev/null` to show the notes. Render them from `DC_JSON`. Always branch on `DC_EXIT` first, then `DC_STATUS`:
|
|
63
66
|
|
|
64
67
|
```bash
|
|
65
68
|
if [[ "$DC_EXIT" == "2" ]]; then
|
|
@@ -76,14 +79,26 @@ fi
|
|
|
76
79
|
**Partial-skip awareness:** The checker may report `checks_skipped` in its JSON output even on successful runs. Common causes: `glab` not on PATH (Check 3 degrades gracefully), no `01-projects/` directory (Check 2 inapplicable). Surface these in the report as informational lines, not errors:
|
|
77
80
|
|
|
78
81
|
```
|
|
79
|
-
CLAUDE.md drift:
|
|
82
|
+
CLAUDE.md drift: OK (N files scanned, mode=<mode>) — E errors, W warnings, T notes
|
|
80
83
|
- Skipped: issue-reference-freshness (glab not found in PATH)
|
|
84
|
+
|
|
85
|
+
CLAUDE.md drift warnings (mode=<mode>, non-blocking)
|
|
86
|
+
[<check>] <file>:<line> — <message>
|
|
87
|
+
|
|
88
|
+
CLAUDE.md drift notes (reported, not warned)
|
|
89
|
+
[<check>/<probe>] <file>:<line> — <message>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Success line format** (when `errors: []` — a non-empty `warnings[]` or `notes[]` does NOT make the run unsuccessful; it is stated in the line and rendered under its own heading above):
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
CLAUDE.md drift: OK (N files scanned, mode=<mode>) — E errors, W warnings, T notes
|
|
81
96
|
```
|
|
82
97
|
|
|
83
|
-
|
|
98
|
+
There is exactly ONE success-line format, and it ALWAYS carries all three counts (`E` = `DC_ERR_COUNT`, `W` = `DC_WARN_COUNT`, `T` = `DC_NOTES_COUNT`) next to the files-scanned figure — so the operator can tell from the line alone whether the warning/note sections above are empty. Do not drop the counts when they are zero, and do not vary the case (`OK` here, `INVALID` below):
|
|
84
99
|
|
|
85
100
|
```
|
|
86
|
-
CLAUDE.md drift:
|
|
101
|
+
CLAUDE.md drift: OK (412 files scanned, mode=warn) — 0 errors, 36 warnings, 2 notes
|
|
87
102
|
```
|
|
88
103
|
|
|
89
104
|
**Error line format** (hard mode, carryover):
|
|
@@ -19,6 +19,7 @@ Finalize session metrics by reading the wave data accumulated during execution:
|
|
|
19
19
|
- `total_agents`: sum of agents across all waves
|
|
20
20
|
- `total_files_changed`: unique files changed across entire session (from `git diff --stat`)
|
|
21
21
|
- `agent_summary`: `{complete: N, partial: N, failed: N, spiral: N}`
|
|
22
|
+
- **Coordinator-direct fallback (#1321):** when Wave History is empty AND the session ran coordinator-direct (housekeeping — `scripts/lib/session-shape.mjs:364-376` resolves it to ONE coordinator-direct wave that `/go` never hands to wave-executor, so no wave metrics are captured — or the express path), do NOT write `waves: []` / `total_waves: 0`. Write exactly one wave entry `{wave: 1, role: "Housekeeping", agent_count: 0, coordinator_direct: true, files_changed: <N>, quality: "<pass|fail|skip — the close quality-gate result>"}` with `total_waves: 1`, `total_agents: 0`. On this path both that wave's `files_changed` and `total_files_changed` are `git diff --name-only "$SESSION_START_REF..HEAD" | wc -l` (accessor: `plan-verification.md` § SESSION_START_REF accessor). The single definition of this shape is `isCoordinatorDirectHousekeeping(record)` in `scripts/lib/session-schema/filters.mjs` (every wave `role: "Housekeeping"` AND `coordinator_direct: true`). Consumers key on it (eval gate-health, evolve effective-sizing), so write `role` and `coordinator_direct` exactly as shown. `session_type` alone never marks it.
|
|
22
23
|
3. Read `.orchestrator/metrics/events.jsonl` **once** and build both event aggregates in a single pass. If the file does not exist, treat both aggregates as zero events (omit both fields per the rules below) — do NOT fail the session close.
|
|
23
24
|
|
|
24
25
|
Filter all lines where `session == <session_id>`, then partition by `event` value:
|
|
@@ -363,17 +363,19 @@ After the Skill-Applied Judge (Phase 3.6.6 — Phase 3.6.7 is retired), and when
|
|
|
363
363
|
sessionId,
|
|
364
364
|
});
|
|
365
365
|
// writeResult = { written: number, archived: number, errors: string[] }
|
|
366
|
+
// on a budget refusal (#1316) additionally: { ok: false, reason: 'instruction-budget-exceeded', axis, current, projected, ceiling, hint }
|
|
366
367
|
```
|
|
367
368
|
|
|
368
369
|
`writeApprovedRules` is lock-serialised (via `withFileLock` on `.orchestrator/rules.lock`) and writes each approved proposal to the directory its target names — `.claude/rules/<slug>.md` for `repo-local`, `<baselineRoot>/proposals/<slug>.md` for `baseline`. Each target's write root is confined separately; the leaf comes from the renderer-minted `slug`, never from a caller-supplied path. Rejected proposals (engine-rejected + operator-rejected) are archived to `.orchestrator/reconcile.rejected.log` with reason `user-declined` for operator-rejected and the engine's own audit reason for engine-rejected.
|
|
369
370
|
|
|
370
|
-
8. Log outcome for Phase 6 Final Report: `reconcile: ${surfaced.length} surfaced → ${approved.length} approved (written: ${writeResult.written}), ${operatorRejected.length} operator-declined${writeResult.errors.length > 0 ? `, ${writeResult.errors.length} write-errors (see sweep.log)` : ''}`.
|
|
371
|
+
8. Log outcome for Phase 6 Final Report: `reconcile: ${surfaced.length} surfaced → ${approved.length} approved (written: ${writeResult.written}), ${operatorRejected.length} operator-declined${writeResult.errors.length > 0 ? `, ${writeResult.errors.length} write-errors (see sweep.log)` : ''}`. On a budget refusal (`writeResult.reason === 'instruction-budget-exceeded'`) log instead `reconcile: budget pre-flight refused the batch (${writeResult.axis} ${writeResult.projected}/${writeResult.ceiling}) — nothing written; consolidate, then re-run /reconcile` — that branch writes nothing to sweep.log.
|
|
371
372
|
|
|
372
373
|
#### Failure modes
|
|
373
374
|
|
|
374
375
|
- If `runReconcile` returns an `error` field (top-level exception caught internally): log `⚠ reconcile: engine error (${error}) — skipping`; do not block session close. No AUQ, no sidecar write.
|
|
375
376
|
- If the sidecar write (step 4) fails: log warning `⚠ reconcile: reconcile-pending.md write failed (${err})`; continue to the AUQ regardless.
|
|
376
|
-
- If `writeApprovedRules`
|
|
377
|
+
- If `writeApprovedRules` returns `ok: false` with `reason: 'instruction-budget-exceeded'` (`BUDGET_REFUSAL_REASON`, #1316): the budget pre-flight refused the WHOLE batch — nothing was written, archived or stamped (operator rejections included, so they resurface on the next run). Log `⚠ reconcile: budget pre-flight refused (${writeResult.axis} ${writeResult.projected}/${writeResult.ceiling}) — consolidate into a thematic rule file (docs/rule-authoring.md § Consolidated rules), then re-run /reconcile` and continue.
|
|
378
|
+
- Otherwise, if `writeApprovedRules` reports per-rule errors in `writeResult.errors`: log each to `.orchestrator/metrics/sweep.log` and continue. Per-rule fault isolation — one failed write does not prevent the others; the budget refusal above is the one batch-wide exception.
|
|
377
379
|
- All failures are non-fatal. Session close is never blocked by reconcile errors — same posture as Phase 3.6.7.
|
|
378
380
|
|
|
379
381
|
#### Cross-references
|
|
@@ -57,11 +57,11 @@ If `mode === 'off'`, skip Phase 2.3 entirely.
|
|
|
57
57
|
|
|
58
58
|
#### Step 2 — Invoke staleness probes
|
|
59
59
|
|
|
60
|
-
Both probes already ship in `skills/discovery/probes/`. Invoke each via Node import (no shell-out):
|
|
60
|
+
Both probes already ship in the plugin's `skills/discovery/probes/`. Invoke each via Node import (no shell-out). Import from the **plugin** root `${PLUGIN_ROOT}` (resolution chain: `skills/_shared/config-reading.md`), never from the project root — in a consumer repo the project has no `skills/` directory. `projectRoot` stays the project root the probes scan:
|
|
61
61
|
|
|
62
62
|
```js
|
|
63
|
-
import { runProbe as runStaleness } from '$
|
|
64
|
-
import { runProbe as runNarrative } from '$
|
|
63
|
+
import { runProbe as runStaleness } from '${PLUGIN_ROOT}/skills/discovery/probes/vault-staleness.mjs';
|
|
64
|
+
import { runProbe as runNarrative } from '${PLUGIN_ROOT}/skills/discovery/probes/vault-narrative-staleness.mjs';
|
|
65
65
|
|
|
66
66
|
const projectStaleness = await runStaleness(projectRoot, config);
|
|
67
67
|
const narrativeStaleness = await runNarrative(projectRoot, config);
|
|
@@ -74,7 +74,12 @@
|
|
|
74
74
|
- **`issue-budget.overflow: collect-issue` (default)** — create exactly ONE issue:
|
|
75
75
|
- Title: `[Backlog-Sammel] <accountingSessionId>, <N> zurückgestellte Punkte`
|
|
76
76
|
- Labels: `type::backlog`, `priority::low`
|
|
77
|
-
- Body: a Markdown checklist with one `- [ ]` line per `overflow[]` entry (`title` when present, otherwise the truncated `command`, plus its `at` timestamp).
|
|
77
|
+
- Body: a Markdown checklist with one `- [ ]` line per `overflow[]` entry (`title` when present, otherwise the truncated `command`, plus its `at` timestamp). Since #1314 an entry may also carry `description`, `repo` and `truncated`; older entries have only `title`/`command`/`at` and render exactly as before.
|
|
78
|
+
- `description` present → put it under the line as a collapsed `<details><summary>Beschreibung</summary>` block, verbatim. If `truncated: true`, append `(gekürzt)` to the summary.
|
|
79
|
+
- `truncated: true` and NO `description` (the body file was over 1 MiB and was not read) → add an indented line `Beschreibung zu groß, nicht übernommen`.
|
|
80
|
+
- `descriptionUnresolved: 'cwd-changed'` → add an indented line `Beschreibung nicht aufgelöst (cd in der Kette)`; the raw `command` still names the file.
|
|
81
|
+
- `repo` present and NOT this repo → render ONLY the title line, `Ziel: <repo>`, and `Beschreibung zurückgehalten (Ziel-Repo abweichend) — liegt im Budget-Zustand`. Never put that entry's `description` into this repo's collector: it would silently change the content's visibility. The counter file keeps it until the overflow reset.
|
|
82
|
+
- `repo` present → add an indented line `Ziel: <repo>` under the entry. All entries stay in the ONE collector in this repo (no second collector per foreign repo): the cap is per session, and a second create would itself need an exemption; the `Ziel:` line is what the operator re-files against.
|
|
78
83
|
- This collector issue is itself EXEMPT from the cap (`[Backlog-Sammel]` is in the exemption list in `scripts/lib/issue-budget.mjs`), so it always lands even at count == max.
|
|
79
84
|
- **`issue-budget.overflow: vault-note`** — create NO issue. Write one Markdown file `vault/00-inbox/<accountingSessionId>-backlog-sammel.md` (path relative to `vault-integration.vault-dir`) with valid vault frontmatter and the same checklist body.
|
|
80
85
|
- After the artefact exists, reset `overflow` to `[]` in the counter file and record the collector issue ID / note path in the Phase 6 Final Report under `### Zurückgestellt (issue-budget)`.
|
|
@@ -104,6 +104,8 @@
|
|
|
104
104
|
```
|
|
105
105
|
`scripts/emit-session.mjs` calls `validateSession` from `scripts/lib/session-schema.mjs` before appending, stamps `schema_version: 1` if absent, and uses `appendJsonl` (atomic for lines < PIPE_BUF). Exit 1 on validation error, exit 2 on I/O error — block session close in both cases so malformed metrics can never reach disk.
|
|
106
106
|
|
|
107
|
+
**`session_profile` (#1247):** when `$METRICS_ENTRY` omits the `session_profile` key, `emit-session.mjs` fills it itself from this repo's own `<state-dir>/STATE.md` `session-profile` frontmatter (e.g. `ultradeep`) — no coordinator-side plumbing needed; an explicit value on the entry always wins and is never overwritten.
|
|
108
|
+
|
|
107
109
|
**`autopilot_run_id` (additive, optional, #300):** when this session was launched by `/autopilot`, the wave-executor `sessionRunner` callback passes `args.autopilotRunId` from `runLoop`. session-end MUST persist that value as a top-level field on the JSONL record:
|
|
108
110
|
|
|
109
111
|
```json
|
|
@@ -185,150 +185,7 @@ Before assigning tasks to waves, discover available agents for this session:
|
|
|
185
185
|
|
|
186
186
|
## Step 1.8: Task-to-Role Classification
|
|
187
187
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
| Signal in task | Role | Examples |
|
|
191
|
-
|---|---|---|
|
|
192
|
-
| Needs codebase understanding before changes; audit, explore, verify assumptions, check existing coverage | **Discovery** | "Audit auth flow", "Check test coverage for module X", "Identify affected modules" |
|
|
193
|
-
| New feature code, new API endpoints, DB schema changes, primary UI components, new modules | **Impl-Core** | "Add /api/users endpoint", "Create migration for invoices table", "Implement auth middleware" |
|
|
194
|
-
| Bug fixes from prior waves, secondary features, integration work, edge cases, polish of existing code | **Impl-Polish** | "Fix pagination edge case", "Integrate payment with billing", "Handle error states in form" |
|
|
195
|
-
| Documentation updates — new/changed README sections, CLAUDE.md (or AGENTS.md on Codex CLI) updates, vault context.md/decisions.md narratives, ADR edits. Audience-aware (User/Dev/Vault). Gated on `docs-orchestrator.enabled` | **Docs** | "Update README for new --no-vault flag", "Write CLAUDE.md section for new hook (or AGENTS.md on Codex CLI)", "Append vault decisions.md entry for architecture change" |
|
|
196
|
-
| Write/update tests, lint fixes, security review, code simplification, type errors | **Quality** | "Add tests for auth module", "Fix TypeScript errors", "Security audit of new API" |
|
|
197
|
-
| Documentation updates, issue cleanup, commit preparation, SSOT refresh, changelog | **Finalization** | "Update README", "Close resolved issues", "Write session handover notes" |
|
|
198
|
-
|
|
199
|
-
**Disambiguation rules:**
|
|
200
|
-
- If a task involves BOTH exploration AND implementation → split it: Discovery agent reads/validates, Impl-Core agent implements. Create two separate task entries.
|
|
201
|
-
- If a task is "fix something from a previous session" (not from this session's Impl-Core) → classify as **Impl-Core** (it is new work for this session).
|
|
202
|
-
- A "write tests for new feature code being built this session" task is created ONLY when Discovery or a qa-strategist run reported a **named gap** — a concrete bug or regression the current suite would let through, stated as such. When that gap exists, classify the task as **Quality** (not Impl-Core); tests run after implementation. "Feature X was built" is NOT by itself evidence of test demand: with no named gap, no Quality task is created — do not synthesize one to give the role something to do. A dispatched `test-writer` may correspondingly report `no-tests-needed` as a SUCCESS status, not a failure.
|
|
203
|
-
- If unsure between Impl-Core and Impl-Polish → if the task is on the critical path (other tasks depend on it), it is **Impl-Core**. If independent polish, it is **Impl-Polish**.
|
|
204
|
-
- **Docs role** is only active when `docs-orchestrator.enabled: true` in Session Config. When disabled (default), documentation-update tasks fall into **Impl-Polish** (inline doc changes alongside code) or **Finalization** (standalone doc/SSOT updates) as today.
|
|
205
|
-
|
|
206
|
-
#### Step 1.8 Docs-role: Consuming the Phase 2.5 Emission Block
|
|
207
|
-
|
|
208
|
-
When `docs-orchestrator.enabled: true`, session-start Phase 2.5 emits a delimited block in the conversation context. Read and parse it before synthesizing Docs-role tasks:
|
|
209
|
-
|
|
210
|
-
**Locating the block:** Search the conversation context for the header `### Docs Planning Result (Phase 2.5)`. If the header is absent, Phase 2.5 was skipped — emit **0 Docs tasks** and do not fabricate any.
|
|
211
|
-
|
|
212
|
-
**Parsing rules (apply in document order):**
|
|
213
|
-
- `Audiences:` — comma-separated list of active audience identifiers (e.g., `user, dev`). Trim whitespace around each value.
|
|
214
|
-
- `Mode:` — single enum value: `warn`, `strict`, or `off`. Store as `$docs_mode`.
|
|
215
|
-
- `Docs-tasks-seed:` — multi-entry bullet list. Each top-level `- audience:` bullet is **one seed task**. Parse in document order; do not merge entries. Each seed task has:
|
|
216
|
-
- `audience:` — target audience (`user`, `dev`, or `vault`)
|
|
217
|
-
- `rationale:` — free-text description of what needs documenting
|
|
218
|
-
|
|
219
|
-
**Synthesizing Docs-role tasks:** For each seed task entry (in document order):
|
|
220
|
-
1. Set `role: Docs`.
|
|
221
|
-
2. Set `description` derived from the `rationale` field (paraphrase as an actionable imperative, e.g., "Document the new `--no-vault` flag in user-facing README").
|
|
222
|
-
3. Set `audience` from the `audience` field.
|
|
223
|
-
4. Set `target-pattern` by looking up the audience in the `Audiences & File Patterns` table in `skills/docs-orchestrator/audience-mapping.md`. Use the glob pattern listed there for the matched audience row.
|
|
224
|
-
5. Resolve `subagent_type` per the Docs-role fast path in Step 1.5 point 4 above.
|
|
225
|
-
|
|
226
|
-
**If the block is absent:** Do not fabricate Docs tasks. The Docs role remains empty; apply the empty-role rule from Step 2.
|
|
227
|
-
|
|
228
|
-
- Housekeeping sessions: skip Steps 1.8, 2, and 3 — housekeeping is the **maintenance loop**, one coordinator-direct wave. `total-waves: 1` and the wave's `coordinatorDirect: true` come from the shape (`scripts/session-shape.mjs --session-type housekeeping`), not from this prose.
|
|
229
|
-
- No role classification — no wave-executor dispatch, no per-role agent sizing.
|
|
230
|
-
- **Default scope, in this order:**
|
|
231
|
-
1. drift-check — `node skills/claude-md-drift-check/checker.mjs --mode warn`
|
|
232
|
-
2. expired-learnings sweep — `node scripts/sweep-expired-learnings.mjs --json`, then `--apply --json` when the dry run reports `archived > 0`
|
|
233
|
-
3. `/evolve analyze`
|
|
234
|
-
4. `/reconcile`
|
|
235
|
-
5. `/evolve dialectic` — dry-run first, then `--apply`
|
|
236
|
-
6. `/memory-cleanup`
|
|
237
|
-
- Operator-selected housekeeping issues are appended AFTER the six maintenance items, in the order the operator picked them.
|
|
238
|
-
- **Why coordinator-direct:** four of the six are AUQ-gated, and `AskUserQuestion` does not exist inside a dispatched agent (`.claude/rules/ask-via-tool.md` AUQ-004) — a wave-executor dispatch would strand the decision. "Coordinator-direct" means no wave-executor, NOT zero subagents: item 5 dispatches the read-only `dialectic-deriver` subagent directly.
|
|
239
|
-
- Wave plan output uses: `### Wave 1: Housekeeping (coordinator-direct, 0 agents)`
|
|
240
|
-
|
|
241
|
-
Record the assigned role next to each task before proceeding to Step 2.
|
|
242
|
-
|
|
243
|
-
### Docs-tasks persistence (for session-end Phase 3.2)
|
|
244
|
-
|
|
245
|
-
When `docs-orchestrator.enabled: true` AND the plan contains 1+ Docs tasks, session-plan MUST emit a machine-readable block **at the end of its plan output** (after the wave plan, before `Ready to execute?`). This block is the single source of truth (SSOT) consumed downstream:
|
|
246
|
-
|
|
247
|
-
- **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `docs-tasks: [...]` into STATE.md frontmatter.
|
|
248
|
-
- **session-end Phase 3.2 (docs verification):** reads `docs-tasks` back from STATE.md to verify each task produced a diff.
|
|
249
|
-
|
|
250
|
-
**Emit format:**
|
|
251
|
-
|
|
252
|
-
```yaml
|
|
253
|
-
### Docs Tasks (machine-readable)
|
|
254
|
-
docs-tasks:
|
|
255
|
-
- id: docs-1
|
|
256
|
-
audience: <user|dev|vault>
|
|
257
|
-
target-pattern: <glob from skills/docs-orchestrator/audience-mapping.md>
|
|
258
|
-
rationale: <verbatim rationale from Phase 2.5 seed>
|
|
259
|
-
wave: <wave number where this docs-writer agent is dispatched>
|
|
260
|
-
status: planned
|
|
261
|
-
- id: docs-2
|
|
262
|
-
...
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
**Field rules:**
|
|
266
|
-
- `id`: sequential index-based identifier (`docs-1`, `docs-2`, …). No UUID generation required.
|
|
267
|
-
- `audience`: one of `user`, `dev`, `vault`.
|
|
268
|
-
- `target-pattern`: the glob from `skills/docs-orchestrator/audience-mapping.md` for this audience row — do not invent patterns.
|
|
269
|
-
- `rationale`: copy the `rationale` text from the Phase 2.5 seed entry verbatim (do not paraphrase here).
|
|
270
|
-
- `wave`: the actual wave number assigned in Step 2 where the `docs-writer` agent for this task is dispatched.
|
|
271
|
-
- `status`: always `planned` at plan time. Terminal values are set by session-end Phase 3.2 per-task verification loop: `ok` (diff substantive), `partial` (diff has `<!-- REVIEW: source needed -->` markers), or `gap` (no matching diff). wave-executor does NOT perform intermediate status updates — `status: planned` remains until session-end writes the terminal value.
|
|
272
|
-
|
|
273
|
-
**Omission rule:** When `docs-orchestrator.enabled: false` OR there are 0 Docs tasks, do NOT emit the `### Docs Tasks (machine-readable)` block. Absence of the block signals to wave-executor and session-end that no docs verification is needed for this session.
|
|
274
|
-
|
|
275
|
-
### Wave-Plan Mission Status (machine-readable)
|
|
276
|
-
|
|
277
|
-
When the wave plan contains 1 or more wave-plan items (i.e., for all non-empty plans), session-plan MUST emit a machine-readable mission-status block **at the end of its plan output** (after the Docs Tasks block if present, before `Ready to execute?`). This block is the SSOT consumed by wave-executor (for STATE.md persistence) and session-end Phase 1.9 (for enum-based classification).
|
|
278
|
-
|
|
279
|
-
- **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `mission-status: [...]` into STATE.md frontmatter via `writeMissionStatus` from `scripts/lib/state-md.mjs`.
|
|
280
|
-
- **session-end Phase 1.9:** reads `mission-status` back from STATE.md frontmatter via `parseMissionStatus` to classify items into the 1.1–1.4 buckets using enum values.
|
|
281
|
-
|
|
282
|
-
**Emit format:**
|
|
283
|
-
|
|
284
|
-
```yaml
|
|
285
|
-
### Wave-Plan Mission Status (machine-readable)
|
|
286
|
-
mission-status:
|
|
287
|
-
- id: m-1
|
|
288
|
-
task: <task description from wave-plan item>
|
|
289
|
-
wave: <N>
|
|
290
|
-
status: brainstormed
|
|
291
|
-
- id: m-2
|
|
292
|
-
task: <task description from wave-plan item>
|
|
293
|
-
wave: <N>
|
|
294
|
-
status: brainstormed
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
**Field rules:**
|
|
298
|
-
- `id`: sequential `m-N` identifier. No UUID generation required.
|
|
299
|
-
- `task`: verbatim task description from the wave-plan item (do not paraphrase).
|
|
300
|
-
- `wave`: the wave number where this task is dispatched.
|
|
301
|
-
- `status`: always `brainstormed` at plan emission. Terminal values are updated at gate transitions by wave-executor: `brainstormed` → `validated` (user confirms via `/go`) → `in-dev` (agent dispatched) → `testing` (Quality wave) → `completed` (Quality gate green). session-end Phase 1.9 reads the current value to classify the item.
|
|
302
|
-
|
|
303
|
-
**Transition gates (summary):**
|
|
304
|
-
At plan time, all items start at `brainstormed`. When the user runs `/go` to approve the plan, wave-executor updates each item to `validated`. When an agent for a wave-plan item is dispatched, wave-executor updates that item to `in-dev`. When the Quality wave begins, items from prior waves move to `testing`. When the Quality gate passes, items finalize at `completed`. Rollback to `brainstormed` is permitted from any state. This ordering is **coordinator convention, not a mechanical gate** — nothing validates a transition before it is written (see "Default and transitions" below).
|
|
305
|
-
|
|
306
|
-
**Omission rule:** When the plan has 0 wave-plan items (e.g., pure express-path coord-direct with no sub-agent tasks), do NOT emit the `### Wave-Plan Mission Status (machine-readable)` block.
|
|
307
|
-
|
|
308
|
-
### Mission-Status Enum (#340)
|
|
309
|
-
|
|
310
|
-
Every wave-plan item carries a `status` field drawn from a 5-value enum. The field is always present on items emitted in the `### Wave-Plan Mission Status (machine-readable)` block (see below). It is also the value persisted in STATE.md frontmatter and read back by session-end Phase 1.9 for enum-based classification.
|
|
311
|
-
|
|
312
|
-
#### Enum values
|
|
313
|
-
|
|
314
|
-
| Status | Meaning | Set when |
|
|
315
|
-
|---|---|---|
|
|
316
|
-
| `brainstormed` | Draft item from `/plan`, not yet user-confirmed | Plan emitted by session-plan (all items start here) |
|
|
317
|
-
| `validated` | User confirmed via AUQ in session-plan (`/go` approval) | wave-executor: user runs `/go` to approve the wave plan |
|
|
318
|
-
| `in-dev` | Agent picked up the task this wave | wave-executor: agent dispatched for this item |
|
|
319
|
-
| `testing` | Implementation done, tests passing for this task | wave-executor: Quality wave begins for this item's work |
|
|
320
|
-
| `completed` | Quality-Lite green for this task's wave | wave-executor: Quality gate passes for this item |
|
|
321
|
-
|
|
322
|
-
#### Default and transitions
|
|
323
|
-
|
|
324
|
-
- **Default at plan creation:** `brainstormed` — all items start here.
|
|
325
|
-
- **Transitions are coordinator-level orchestration** (not inside individual agent prompts). See `skills/wave-executor/SKILL.md` "Mission-Status Updates (#340)" for when each transition fires.
|
|
326
|
-
- **Rollback:** any item may return to `brainstormed` from any state (e.g. if work is discarded or re-planned).
|
|
327
|
-
- **No mechanical validation — by design.** The `status` values come from the 5-value enum in the table above, but nothing checks a transition before it is written. `setMissionStatus` (`scripts/lib/state-md/mission-status.mjs`) mirrors whatever string it is handed onto BOTH the body section and the frontmatter array, deliberately without an enum gate: gating it would reintroduce the exact body-says-X/frontmatter-says-Y divergence that sync exists to remove. An out-of-enum value therefore lands visibly on both surfaces instead of being silently rejected on one. Keeping the enum honest is the coordinator's job.
|
|
328
|
-
|
|
329
|
-
#### Status field in wave-plan items
|
|
330
|
-
|
|
331
|
-
Every item in the wave plan output carries an implicit `status: brainstormed` at plan time. The `### Wave-Plan Mission Status (machine-readable)` block below (emitted at the end of the plan output) is the machine-readable form that wave-executor and session-end Phase 1.9 consume. session-plan does NOT write STATUS transitions — it only emits the initial `brainstormed` values.
|
|
188
|
+
Assigns exactly one role (Discovery/Impl-Core/Impl-Polish/Docs/Quality/Finalization) to each Step 1 task via the signal-to-role mapping table, the disambiguation rules, the Docs-role Phase 2.5 emission-block parsing, and the housekeeping short-circuit. Also emits the Docs Tasks and Wave-Plan Mission Status machine-readable blocks (SSOT for wave-executor + session-end) and the Mission-Status Enum (#340). See [references/session-plan-task-classification.md](references/session-plan-task-classification.md). **Read WHEN:** after Step 1.5, before Step 2.
|
|
332
189
|
|
|
333
190
|
## Step 2: Wave Assignment
|
|
334
191
|
|
|
@@ -601,6 +458,7 @@ If the user requests changes:
|
|
|
601
458
|
| File | Purpose |
|
|
602
459
|
|------|---------|
|
|
603
460
|
| `wave-template.md` | Step 4 agent specification format and count tables |
|
|
461
|
+
| `references/session-plan-task-classification.md` | Step 1.8: task-to-role classification, Docs-tasks + Wave-Plan Mission Status emission blocks, Mission-Status Enum (#340) |
|
|
604
462
|
|
|
605
463
|
## Anti-Patterns
|
|
606
464
|
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Session Plan — Step 1.8: Task-to-Role Classification
|
|
2
|
+
|
|
3
|
+
> Reference of the session-plan skill, split out of `SKILL.md` (#1246). Body moved **byte-identical**; only this header is new.
|
|
4
|
+
> **Sibling-file paths inside this body are relative to the parent directory, not to `references/`** — none needed rewriting: the moved body carries no relative markdown links, only backticked file mentions, which were deliberately left untouched so the bytes stay verifiable against the pre-split file.
|
|
5
|
+
> **Read after Step 1.5 (Agent Discovery) and before Step 2 (Wave Assignment) in `../SKILL.md`.** Covers the signal-to-role mapping table, disambiguation rules, the Docs-role Phase 2.5 emission block, the housekeeping short-circuit, the Docs-tasks and Wave-Plan Mission Status machine-readable emission blocks, and the Mission-Status Enum (#340).
|
|
6
|
+
|
|
7
|
+
## Step 1.8: Task-to-Role Classification
|
|
8
|
+
|
|
9
|
+
For each task from Step 1, assign exactly one role. Use these signal-to-role mappings:
|
|
10
|
+
|
|
11
|
+
| Signal in task | Role | Examples |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| Needs codebase understanding before changes; audit, explore, verify assumptions, check existing coverage | **Discovery** | "Audit auth flow", "Check test coverage for module X", "Identify affected modules" |
|
|
14
|
+
| New feature code, new API endpoints, DB schema changes, primary UI components, new modules | **Impl-Core** | "Add /api/users endpoint", "Create migration for invoices table", "Implement auth middleware" |
|
|
15
|
+
| Bug fixes from prior waves, secondary features, integration work, edge cases, polish of existing code | **Impl-Polish** | "Fix pagination edge case", "Integrate payment with billing", "Handle error states in form" |
|
|
16
|
+
| Documentation updates — new/changed README sections, CLAUDE.md (or AGENTS.md on Codex CLI) updates, vault context.md/decisions.md narratives, ADR edits. Audience-aware (User/Dev/Vault). Gated on `docs-orchestrator.enabled` | **Docs** | "Update README for new --no-vault flag", "Write CLAUDE.md section for new hook (or AGENTS.md on Codex CLI)", "Append vault decisions.md entry for architecture change" |
|
|
17
|
+
| Write/update tests, lint fixes, security review, code simplification, type errors | **Quality** | "Add tests for auth module", "Fix TypeScript errors", "Security audit of new API" |
|
|
18
|
+
| Documentation updates, issue cleanup, commit preparation, SSOT refresh, changelog | **Finalization** | "Update README", "Close resolved issues", "Write session handover notes" |
|
|
19
|
+
|
|
20
|
+
**Disambiguation rules:**
|
|
21
|
+
- If a task involves BOTH exploration AND implementation → split it: Discovery agent reads/validates, Impl-Core agent implements. Create two separate task entries.
|
|
22
|
+
- If a task is "fix something from a previous session" (not from this session's Impl-Core) → classify as **Impl-Core** (it is new work for this session).
|
|
23
|
+
- A "write tests for new feature code being built this session" task is created ONLY when Discovery or a qa-strategist run reported a **named gap** — a concrete bug or regression the current suite would let through, stated as such. When that gap exists, classify the task as **Quality** (not Impl-Core); tests run after implementation. "Feature X was built" is NOT by itself evidence of test demand: with no named gap, no Quality task is created — do not synthesize one to give the role something to do. A dispatched `test-writer` may correspondingly report `no-tests-needed` as a SUCCESS status, not a failure.
|
|
24
|
+
- If unsure between Impl-Core and Impl-Polish → if the task is on the critical path (other tasks depend on it), it is **Impl-Core**. If independent polish, it is **Impl-Polish**.
|
|
25
|
+
- **Docs role** is only active when `docs-orchestrator.enabled: true` in Session Config. When disabled (default), documentation-update tasks fall into **Impl-Polish** (inline doc changes alongside code) or **Finalization** (standalone doc/SSOT updates) as today.
|
|
26
|
+
|
|
27
|
+
#### Step 1.8 Docs-role: Consuming the Phase 2.5 Emission Block
|
|
28
|
+
|
|
29
|
+
When `docs-orchestrator.enabled: true`, session-start Phase 2.5 emits a delimited block in the conversation context. Read and parse it before synthesizing Docs-role tasks:
|
|
30
|
+
|
|
31
|
+
**Locating the block:** Search the conversation context for the header `### Docs Planning Result (Phase 2.5)`. If the header is absent, Phase 2.5 was skipped — emit **0 Docs tasks** and do not fabricate any.
|
|
32
|
+
|
|
33
|
+
**Parsing rules (apply in document order):**
|
|
34
|
+
- `Audiences:` — comma-separated list of active audience identifiers (e.g., `user, dev`). Trim whitespace around each value.
|
|
35
|
+
- `Mode:` — single enum value: `warn`, `strict`, or `off`. Store as `$docs_mode`.
|
|
36
|
+
- `Docs-tasks-seed:` — multi-entry bullet list. Each top-level `- audience:` bullet is **one seed task**. Parse in document order; do not merge entries. Each seed task has:
|
|
37
|
+
- `audience:` — target audience (`user`, `dev`, or `vault`)
|
|
38
|
+
- `rationale:` — free-text description of what needs documenting
|
|
39
|
+
|
|
40
|
+
**Synthesizing Docs-role tasks:** For each seed task entry (in document order):
|
|
41
|
+
1. Set `role: Docs`.
|
|
42
|
+
2. Set `description` derived from the `rationale` field (paraphrase as an actionable imperative, e.g., "Document the new `--no-vault` flag in user-facing README").
|
|
43
|
+
3. Set `audience` from the `audience` field.
|
|
44
|
+
4. Set `target-pattern` by looking up the audience in the `Audiences & File Patterns` table in `skills/docs-orchestrator/audience-mapping.md`. Use the glob pattern listed there for the matched audience row.
|
|
45
|
+
5. Resolve `subagent_type` per the Docs-role fast path in Step 1.5 point 4 above.
|
|
46
|
+
|
|
47
|
+
**If the block is absent:** Do not fabricate Docs tasks. The Docs role remains empty; apply the empty-role rule from Step 2.
|
|
48
|
+
|
|
49
|
+
- Housekeeping sessions: skip Steps 1.8, 2, and 3 — housekeeping is the **maintenance loop**, one coordinator-direct wave. `total-waves: 1` and the wave's `coordinatorDirect: true` come from the shape (`scripts/session-shape.mjs --session-type housekeeping`), not from this prose.
|
|
50
|
+
- No role classification — no wave-executor dispatch, no per-role agent sizing.
|
|
51
|
+
- **Default scope, in this order:**
|
|
52
|
+
1. drift-check — `node skills/claude-md-drift-check/checker.mjs --mode warn`
|
|
53
|
+
2. expired-learnings sweep — `node scripts/sweep-expired-learnings.mjs --json`, then `--apply --json` when the dry run reports `archived > 0`
|
|
54
|
+
3. `/evolve analyze`
|
|
55
|
+
4. `/reconcile`
|
|
56
|
+
5. `/evolve dialectic` — dry-run first, then `--apply`
|
|
57
|
+
6. `/memory-cleanup`
|
|
58
|
+
- Operator-selected housekeeping issues are appended AFTER the six maintenance items, in the order the operator picked them.
|
|
59
|
+
- **Why coordinator-direct:** four of the six are AUQ-gated, and `AskUserQuestion` does not exist inside a dispatched agent (`.claude/rules/ask-via-tool.md` AUQ-004) — a wave-executor dispatch would strand the decision. "Coordinator-direct" means no wave-executor, NOT zero subagents: item 5 dispatches the read-only `dialectic-deriver` subagent directly.
|
|
60
|
+
- Wave plan output uses: `### Wave 1: Housekeeping (coordinator-direct, 0 agents)`
|
|
61
|
+
|
|
62
|
+
Record the assigned role next to each task before proceeding to Step 2.
|
|
63
|
+
|
|
64
|
+
### Docs-tasks persistence (for session-end Phase 3.2)
|
|
65
|
+
|
|
66
|
+
When `docs-orchestrator.enabled: true` AND the plan contains 1+ Docs tasks, session-plan MUST emit a machine-readable block **at the end of its plan output** (after the wave plan, before `Ready to execute?`). This block is the single source of truth (SSOT) consumed downstream:
|
|
67
|
+
|
|
68
|
+
- **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `docs-tasks: [...]` into STATE.md frontmatter.
|
|
69
|
+
- **session-end Phase 3.2 (docs verification):** reads `docs-tasks` back from STATE.md to verify each task produced a diff.
|
|
70
|
+
|
|
71
|
+
**Emit format:**
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
### Docs Tasks (machine-readable)
|
|
75
|
+
docs-tasks:
|
|
76
|
+
- id: docs-1
|
|
77
|
+
audience: <user|dev|vault>
|
|
78
|
+
target-pattern: <glob from skills/docs-orchestrator/audience-mapping.md>
|
|
79
|
+
rationale: <verbatim rationale from Phase 2.5 seed>
|
|
80
|
+
wave: <wave number where this docs-writer agent is dispatched>
|
|
81
|
+
status: planned
|
|
82
|
+
- id: docs-2
|
|
83
|
+
...
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Field rules:**
|
|
87
|
+
- `id`: sequential index-based identifier (`docs-1`, `docs-2`, …). No UUID generation required.
|
|
88
|
+
- `audience`: one of `user`, `dev`, `vault`.
|
|
89
|
+
- `target-pattern`: the glob from `skills/docs-orchestrator/audience-mapping.md` for this audience row — do not invent patterns.
|
|
90
|
+
- `rationale`: copy the `rationale` text from the Phase 2.5 seed entry verbatim (do not paraphrase here).
|
|
91
|
+
- `wave`: the actual wave number assigned in Step 2 where the `docs-writer` agent for this task is dispatched.
|
|
92
|
+
- `status`: always `planned` at plan time. Terminal values are set by session-end Phase 3.2 per-task verification loop: `ok` (diff substantive), `partial` (diff has `<!-- REVIEW: source needed -->` markers), or `gap` (no matching diff). wave-executor does NOT perform intermediate status updates — `status: planned` remains until session-end writes the terminal value.
|
|
93
|
+
|
|
94
|
+
**Omission rule:** When `docs-orchestrator.enabled: false` OR there are 0 Docs tasks, do NOT emit the `### Docs Tasks (machine-readable)` block. Absence of the block signals to wave-executor and session-end that no docs verification is needed for this session.
|
|
95
|
+
|
|
96
|
+
### Wave-Plan Mission Status (machine-readable)
|
|
97
|
+
|
|
98
|
+
When the wave plan contains 1 or more wave-plan items (i.e., for all non-empty plans), session-plan MUST emit a machine-readable mission-status block **at the end of its plan output** (after the Docs Tasks block if present, before `Ready to execute?`). This block is the SSOT consumed by wave-executor (for STATE.md persistence) and session-end Phase 1.9 (for enum-based classification).
|
|
99
|
+
|
|
100
|
+
- **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `mission-status: [...]` into STATE.md frontmatter via `writeMissionStatus` from `scripts/lib/state-md.mjs`.
|
|
101
|
+
- **session-end Phase 1.9:** reads `mission-status` back from STATE.md frontmatter via `parseMissionStatus` to classify items into the 1.1–1.4 buckets using enum values.
|
|
102
|
+
|
|
103
|
+
**Emit format:**
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
### Wave-Plan Mission Status (machine-readable)
|
|
107
|
+
mission-status:
|
|
108
|
+
- id: m-1
|
|
109
|
+
task: <task description from wave-plan item>
|
|
110
|
+
wave: <N>
|
|
111
|
+
status: brainstormed
|
|
112
|
+
- id: m-2
|
|
113
|
+
task: <task description from wave-plan item>
|
|
114
|
+
wave: <N>
|
|
115
|
+
status: brainstormed
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Field rules:**
|
|
119
|
+
- `id`: sequential `m-N` identifier. No UUID generation required.
|
|
120
|
+
- `task`: verbatim task description from the wave-plan item (do not paraphrase).
|
|
121
|
+
- `wave`: the wave number where this task is dispatched.
|
|
122
|
+
- `status`: always `brainstormed` at plan emission. Terminal values are updated at gate transitions by wave-executor: `brainstormed` → `validated` (user confirms via `/go`) → `in-dev` (agent dispatched) → `testing` (Quality wave) → `completed` (Quality gate green). session-end Phase 1.9 reads the current value to classify the item.
|
|
123
|
+
|
|
124
|
+
**Transition gates (summary):**
|
|
125
|
+
At plan time, all items start at `brainstormed`. When the user runs `/go` to approve the plan, wave-executor updates each item to `validated`. When an agent for a wave-plan item is dispatched, wave-executor updates that item to `in-dev`. When the Quality wave begins, items from prior waves move to `testing`. When the Quality gate passes, items finalize at `completed`. Rollback to `brainstormed` is permitted from any state. This ordering is **coordinator convention, not a mechanical gate** — nothing validates a transition before it is written (see "Default and transitions" below).
|
|
126
|
+
|
|
127
|
+
**Omission rule:** When the plan has 0 wave-plan items (e.g., pure express-path coord-direct with no sub-agent tasks), do NOT emit the `### Wave-Plan Mission Status (machine-readable)` block.
|
|
128
|
+
|
|
129
|
+
### Mission-Status Enum (#340)
|
|
130
|
+
|
|
131
|
+
Every wave-plan item carries a `status` field drawn from a 5-value enum. The field is always present on items emitted in the `### Wave-Plan Mission Status (machine-readable)` block (see below). It is also the value persisted in STATE.md frontmatter and read back by session-end Phase 1.9 for enum-based classification.
|
|
132
|
+
|
|
133
|
+
#### Enum values
|
|
134
|
+
|
|
135
|
+
| Status | Meaning | Set when |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| `brainstormed` | Draft item from `/plan`, not yet user-confirmed | Plan emitted by session-plan (all items start here) |
|
|
138
|
+
| `validated` | User confirmed via AUQ in session-plan (`/go` approval) | wave-executor: user runs `/go` to approve the wave plan |
|
|
139
|
+
| `in-dev` | Agent picked up the task this wave | wave-executor: agent dispatched for this item |
|
|
140
|
+
| `testing` | Implementation done, tests passing for this task | wave-executor: Quality wave begins for this item's work |
|
|
141
|
+
| `completed` | Quality-Lite green for this task's wave | wave-executor: Quality gate passes for this item |
|
|
142
|
+
|
|
143
|
+
#### Default and transitions
|
|
144
|
+
|
|
145
|
+
- **Default at plan creation:** `brainstormed` — all items start here.
|
|
146
|
+
- **Transitions are coordinator-level orchestration** (not inside individual agent prompts). See `skills/wave-executor/SKILL.md` "Mission-Status Updates (#340)" for when each transition fires.
|
|
147
|
+
- **Rollback:** any item may return to `brainstormed` from any state (e.g. if work is discarded or re-planned).
|
|
148
|
+
- **No mechanical validation — by design.** The `status` values come from the 5-value enum in the table above, but nothing checks a transition before it is written. `setMissionStatus` (`scripts/lib/state-md/mission-status.mjs`) mirrors whatever string it is handed onto BOTH the body section and the frontmatter array, deliberately without an enum gate: gating it would reintroduce the exact body-says-X/frontmatter-says-Y divergence that sync exists to remove. An out-of-enum value therefore lands visibly on both surfaces instead of being silently rejected on one. Keeping the enum honest is the coordinator's job.
|
|
149
|
+
|
|
150
|
+
#### Status field in wave-plan items
|
|
151
|
+
|
|
152
|
+
Every item in the wave plan output carries an implicit `status: brainstormed` at plan time. The `### Wave-Plan Mission Status (machine-readable)` block below (emitted at the end of the plan output) is the machine-readable form that wave-executor and session-end Phase 1.9 consume. session-plan does NOT write STATUS transitions — it only emits the initial `brainstormed` values.
|
|
@@ -9,8 +9,9 @@ model-preference-cursor: claude-opus-4-6
|
|
|
9
9
|
description: >
|
|
10
10
|
Use this skill when initializing a session for any project repo. Autonomously analyzes git state,
|
|
11
11
|
VCS issues, SSOT files, branches, environment, and cross-repo status. Then presents
|
|
12
|
-
structured findings with recommendations
|
|
13
|
-
Triggered by /session
|
|
12
|
+
structured findings with recommendations before development wave planning, or an operations
|
|
13
|
+
contract for explicitly requested time-bounded operational work. Triggered by /session
|
|
14
|
+
[housekeeping|feature|deep] or a direct session-start request.
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
# Session Start Skill
|
|
@@ -25,12 +26,28 @@ Before anything else, read and internalize `soul.md` in this skill directory. It
|
|
|
25
26
|
|
|
26
27
|
## Phase 0: Bootstrap Gate
|
|
27
28
|
|
|
28
|
-
Read `skills/_shared/bootstrap-gate.md` and execute the gate check. If the gate is CLOSED, invoke `skills/bootstrap/SKILL.md` and wait for completion before proceeding. If the gate is OPEN, continue to Phase 1.
|
|
29
|
+
Read `skills/_shared/bootstrap-gate.md` and execute the gate check. If the gate is CLOSED, invoke `skills/bootstrap/SKILL.md` and wait for completion before proceeding. If the gate is OPEN, evaluate the Operations route below. When that route does not apply, continue to Phase 0.5 and then Phase 1.
|
|
29
30
|
|
|
30
31
|
<HARD-GATE>
|
|
31
32
|
Do NOT proceed past Phase 0 if GATE_CLOSED. There is no bypass. Refer to `skills/_shared/bootstrap-gate.md` for the full HARD-GATE constraints.
|
|
32
33
|
</HARD-GATE>
|
|
33
34
|
|
|
35
|
+
## Operations route — before Phase 0.5
|
|
36
|
+
|
|
37
|
+
After the bootstrap gate, select this route ONLY when the user's current request explicitly
|
|
38
|
+
asks for time-bounded operational work (for example launch preparation, research, distribution,
|
|
39
|
+
or community work) and supplies a duration or deadline. A document mentioning such work is
|
|
40
|
+
not a request. An explicit development session type retains the development path; mixed
|
|
41
|
+
requests use operations as coordinator only when the user asks for ongoing operational work,
|
|
42
|
+
with individual code changes handled through the development workflow.
|
|
43
|
+
|
|
44
|
+
Read [the operations contract](references/operations-contract.md) in full and follow it
|
|
45
|
+
instead of Phases 0.5–9 below. It retains read-only config, peer, repository, issue and
|
|
46
|
+
profile preflight, then uses the current harness's native execution and completion tools.
|
|
47
|
+
Do not fabricate a development session type, wave plan, STATE.md entry, or autopilot run.
|
|
48
|
+
This is a prose-invoked route, not a new `/session operations` argument or background runner.
|
|
49
|
+
When its conditions are absent, continue to Phase 0.5 unchanged.
|
|
50
|
+
|
|
34
51
|
## Phase 0.5: Parallel-Aware Preamble
|
|
35
52
|
|
|
36
53
|
> Skip silently when `persistence: false` in Session Config.
|
|
@@ -205,7 +222,7 @@ Group issues by:
|
|
|
205
222
|
|
|
206
223
|
## Phase 4: SSOT & Environment Check
|
|
207
224
|
|
|
208
|
-
> Always runs; every finding is a NON-BLOCKING banner in the Session Overview (never a gate — the Full Gate is the Quality wave's job). Covers SSOT freshness, the Baseline quality commands (resolved `.orchestrator/policy/quality-gates.json` → Session Config → defaults, each availability-checked with `command -v`), Pencil design status, plugin
|
|
225
|
+
> Always runs; every finding is a NON-BLOCKING banner in the Session Overview (never a gate — the Full Gate is the Quality wave's job). Covers SSOT freshness, the Baseline quality commands (resolved `.orchestrator/policy/quality-gates.json` → Session Config → defaults, each availability-checked with `command -v`), Pencil design status, plugin freshness, and the banner-probe family registered in `scripts/lib/session-start-probes.mjs` (bootstrap-lock-freshness, vault-staleness, telemetry-flush-health, ci-status, qg-command-drift, peer-cards, loop-readiness, instruction-budget, maintenance-due, sessions-staleness, sessions-integrity, owner-config, moc-staleness, context-coverage, claude-md-budget-lint, tests:src-ratio, project-hygiene, mirror-issues, git-config-drift — 19 total). Per-probe module path, return contract and exact banner wording: [`references/phase-4-ssot-environment-check.md`](references/phase-4-ssot-environment-check.md).
|
|
209
226
|
|
|
210
227
|
## Phase 4.5: Resource Health (v3.1.0)
|
|
211
228
|
|
|
@@ -371,7 +388,7 @@ After user alignment:
|
|
|
371
388
|
## Critical Rules
|
|
372
389
|
|
|
373
390
|
- **NEVER make assumptions** about code state based on memory or docs — always verify in actual files
|
|
374
|
-
- **NEVER skip the Q&A phase** — the user MUST confirm direction before wave planning
|
|
391
|
+
- **On the development route, NEVER skip the Q&A phase** — the user MUST confirm direction before wave planning. The operations route uses its own authorization contract and does not create a wave plan.
|
|
375
392
|
- **ALWAYS verify parallel subagent work against the started set**, never against the launch ack — `run_in_background: true` is allowed and recommended for wave dispatch (`skills/wave-executor/wave-loop.md § Started-Set Verification`); skills that need every result before their next phase (persona-panel, discovery, test-runner, session-end) keep `false` and say why
|
|
376
393
|
- **ALWAYS check `.env` or `.env.local`** for VCS host, API keys, and service URLs
|
|
377
394
|
- **ALWAYS present options with pros/cons and a clear recommendation** — never just list facts
|
|
@@ -384,6 +401,7 @@ After user alignment:
|
|
|
384
401
|
| File | Purpose |
|
|
385
402
|
|------|---------|
|
|
386
403
|
| `soul.md` | Identity and communication principles |
|
|
404
|
+
| `references/operations-contract.md` | Explicit time-bounded operations route: preflight, authorization, native execution, evidence and close-out |
|
|
387
405
|
| (inline) Phase 1.05 | Skill-Invocation Self-Report (#1199) — mirrors session-end Phase 0.6 |
|
|
388
406
|
| `references/phase-1-1-dispatcher-autonomy-capture.md` | Phase 1.1 full procedural body — one-time-per-repo dispatcher-autonomy capture; committed-block presence guard (`isDispatcherAutonomyBlockPresent`), the AUQ definition from `scripts/lib/config/dispatcher-autonomy-capture.mjs`, and the `writeDispatcherAutonomyBlock` write |
|
|
389
407
|
| `references/phase-1-2-session-lock.md` | Phases 1.2 + 1.2.1 full procedural bodies — Session Lock Acquire: `acquire()` call, active/stale/cross-host AUQ flows, `forceAcquire()` on user consent, deviation note wiring; plus Phase 1.2.1 Peer-Guard (`findPeers` STATE.md surface, Worktree-Promotion AUQ, SOFT-GATE + fail-open) |
|
|
@@ -393,7 +411,7 @@ After user alignment:
|
|
|
393
411
|
| `phase-2-5-docs-planning.md` | Phase 2.5 full procedural body — docs-orchestrator config, audience detection, AUQ confirmation, result block emission, non-overlap rules |
|
|
394
412
|
| (inline) Phase 2.6 | Steering docs gate + load — reads `.orchestrator/steering/{product,tech,structure}.md`; silent no-op when directory absent |
|
|
395
413
|
| `references/phase-2-7-portfolio-snapshot.md` | Phase 2.7 full procedural body — GitLab Portfolio Snapshot: dry-run aggregation banner; gated on `gitlab-portfolio.enabled: true` + `vault-integration.enabled: true`; dispatches `scripts/lib/gitlab-portfolio/cli.mjs --dry-run`; 8s timeout; never blocks session-start |
|
|
396
|
-
| `references/phase-4-ssot-environment-check.md` | Phase 4 full procedural body — SSOT freshness, Baseline quality-command resolution + `command -v` availability check, Pencil status, plugin/`bootstrap.lock` freshness, and the
|
|
414
|
+
| `references/phase-4-ssot-environment-check.md` | Phase 4 full procedural body — SSOT freshness, Baseline quality-command resolution + `command -v` availability check, Pencil status, plugin/`bootstrap.lock` freshness, and the 19-probe banner family (module path, return contract and exact wording per probe) |
|
|
397
415
|
| `phase-4-5-resource-health.md` | Phase 4.5 full procedural body — resource probe, adaptive thresholds table, AUQ presentation, session-plan cap handoff |
|
|
398
416
|
| `references/phase-6-5-forced-reads.md` | Phases 6.5.1 + 6.5.2 full procedural bodies — the two forced-read STATE.md continuity slots: `## What Not To Retry` (`readWhatNotToRetry`, #623) and `## Open Questions` (`readOpenQuestions`, #772), both rendered unconditionally and wrapped via `wrapHistorical` from `scripts/lib/historical-guard.mjs` |
|
|
399
417
|
| `references/phase-6-6-project-intelligence.md` | Phase 6.6 full procedural body — active-learnings surface from `.orchestrator/metrics/learnings.jsonl`, cap+rank via `learnings-surface-top-n`, grouping by type, and the Surface health block |
|