session-orchestrator 4.1.0 → 4.2.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-plan/SKILL.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.codex-plugin/skills/session-plan/SKILL.md +1 -1
- package/.cursor/skills/session-plan/SKILL.md +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/CHANGELOG.md +34 -0
- package/README.md +8 -8
- package/agents/ux-evaluator.md +1 -1
- package/commands/close.md +3 -3
- package/commands/go.md +2 -0
- package/commands/memory-cleanup.md +4 -3
- package/commands/persona-panel.md +1 -1
- package/commands/session.md +3 -2
- package/docs/README.md +4 -4
- package/docs/USER-GUIDE.md +115 -48
- package/docs/agent-authoring.md +2 -2
- package/docs/baseline.md +55 -1
- package/docs/ci-setup.md +1 -1
- package/docs/codex-setup.md +1 -0
- package/docs/components.md +2 -2
- package/docs/cursor-setup.md +1 -0
- package/docs/events-schema.md +4 -1
- package/docs/instruction-delivery.md +1 -1
- package/docs/memory-proposal-flow.md +3 -3
- package/docs/migration-v4.md +2 -2
- package/docs/owner-config-schema.md +74 -90
- package/docs/persona-panel.md +4 -4
- package/docs/pi-setup.md +1 -0
- package/docs/rule-authoring.md +13 -6
- package/docs/scope-collision-guard.md +2 -0
- package/docs/session-config-reference.md +55 -22
- package/docs/session-config-template.md +9 -5
- package/docs/vault-docs-architecture.md +4 -2
- package/hooks/_lib/hook-import-set.json +28 -3
- package/hooks/_lib/vcs-create-matcher.mjs +214 -16
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks.json +1 -1
- package/hooks/pre-bash-issue-budget.mjs +123 -26
- package/hooks/subagent-telemetry.mjs +106 -20
- package/package.json +4 -4
- package/scripts/baseline-archetypes.mjs +28 -0
- package/scripts/lib/auto-dialectic.mjs +0 -68
- package/scripts/lib/baseline-archetypes.mjs +439 -0
- package/scripts/lib/build-live-signals.mjs +5 -6
- package/scripts/lib/config/issue-budget.mjs +68 -8
- package/scripts/lib/config/private-config-dir.mjs +3 -2
- package/scripts/lib/config/remote-hosts.mjs +2 -2
- package/scripts/lib/config-schema.mjs +79 -0
- package/scripts/lib/file-lock.mjs +47 -5
- package/scripts/lib/issue-budget-reconcile.mjs +392 -0
- package/scripts/lib/issue-budget.mjs +76 -3
- package/scripts/lib/learnings/evolve-telemetry.mjs +1 -2
- package/scripts/lib/maintenance-due-banner.mjs +440 -0
- package/scripts/lib/owner-config.example.yaml +29 -46
- package/scripts/lib/owner-yaml.mjs +14 -13
- package/scripts/lib/quality-gate.mjs +13 -6
- package/scripts/lib/resource-probe/evaluate.mjs +19 -21
- package/scripts/lib/rules-sync.mjs +34 -4
- package/scripts/lib/session-close-backfill.mjs +182 -40
- package/scripts/lib/session-end/phase-skip.mjs +85 -86
- package/scripts/lib/session-end/tail-runner.mjs +178 -0
- package/scripts/lib/session-schema/constants.mjs +6 -0
- package/scripts/lib/session-schema/validator.mjs +20 -0
- package/scripts/lib/session-shape.mjs +558 -0
- package/scripts/lib/session-start-probes.mjs +10 -3
- package/scripts/lib/session-token-rollup.mjs +95 -10
- package/scripts/lib/state-md/frontmatter-mutators.mjs +22 -34
- package/scripts/lib/state-md.mjs +1 -0
- package/scripts/lib/subagents-schema.mjs +77 -9
- package/scripts/lib/telemetry/pricing.mjs +197 -0
- package/scripts/lib/telemetry/sync.mjs +50 -1
- package/scripts/lib/validate/check-skill-script-paths.mjs +33 -10
- package/scripts/lib/validate/check-unwired-features.mjs +8 -7
- package/scripts/lib/vault-mirror/process.mjs +2 -1
- package/scripts/lib/vault-status/narrative-mirror.mjs +4 -4
- package/scripts/lib/wave-resource-gate.mjs +23 -27
- package/scripts/lib/wave-sizing.mjs +10 -3
- package/scripts/materialize-wave-scope.mjs +68 -14
- package/scripts/print-applicable-rules.mjs +7 -6
- package/scripts/print-learnings-index.mjs +3 -2
- package/scripts/session-shape.mjs +266 -0
- package/skills/_shared/config-reading.md +15 -9
- package/skills/_shared/private-capability-context.md +89 -0
- package/skills/bootstrap/SKILL.md +61 -13
- package/skills/bootstrap/_shared-template.md +99 -14
- package/skills/bootstrap/deep-template.md +36 -26
- package/skills/bootstrap/fast-template.md +44 -8
- package/skills/bootstrap/intensity-heuristic.md +10 -4
- package/skills/bootstrap/private-contract.md +119 -0
- package/skills/bootstrap/public-fallback.md +30 -18
- package/skills/bootstrap/standard-template.md +39 -24
- package/skills/discovery/probes-ui.md +1 -1
- package/skills/docs-orchestrator/audience-mapping.md +1 -1
- package/skills/evolve/SKILL.md +2 -2
- package/skills/gitlab-ops/SKILL.md +3 -3
- package/skills/grill/SKILL.md +1 -1
- package/skills/memory-cleanup/SKILL.md +2 -2
- package/skills/plan/mode-new.md +9 -0
- package/skills/reconcile/SKILL.md +1 -1
- package/skills/session-end/SKILL.md +3 -2
- package/skills/session-end/phase-3-2-docs-verification.md +1 -1
- package/skills/session-end/phase-3-6-tail.md +23 -65
- package/skills/session-end/phase-3-7a-recommendations.md +2 -2
- package/skills/session-end/references/phase-3-documentation-updates.md +8 -6
- package/skills/session-end/references/phase-5-issue-cleanup.md +26 -0
- package/skills/session-end/session-metrics-write.md +31 -12
- package/skills/session-plan/SKILL.md +56 -48
- package/skills/session-plan/wave-template.md +8 -15
- package/skills/session-start/SKILL.md +18 -2
- package/skills/session-start/phase-2-5-docs-planning.md +1 -1
- package/skills/session-start/phase-8-5-express-path.md +12 -9
- package/skills/session-start/references/phase-1-5-session-continuity.md +2 -0
- package/skills/session-start/references/phase-4-ssot-environment-check.md +21 -5
- package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +3 -1
- package/skills/test-runner/rubric-v1.md +2 -2
- package/skills/wave-executor/SKILL.md +42 -12
- package/skills/wave-executor/circuit-breaker.md +3 -1
- package/skills/wave-executor/references/wave-loop-dispatch.md +4 -2
- package/skills/wave-executor/references/wave-loop-review.md +1 -1
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +6 -2
- package/templates/nextjs-minimal/package.json +1 -1
- package/templates/node-minimal/package.json +1 -1
- package/scripts/lib/multi-provider-build/providers.mjs +0 -64
- package/scripts/lib/multi-provider-build/templating.mjs +0 -130
- package/scripts/lib/owner-config/coerce.mjs +0 -29
- package/scripts/lib/owner-config/constants.mjs +0 -21
- package/scripts/lib/owner-config/defaults.mjs +0 -50
- package/scripts/lib/owner-config/error.mjs +0 -19
- package/scripts/lib/owner-config/index.mjs +0 -13
- package/scripts/lib/owner-config/merge.mjs +0 -52
- package/scripts/lib/owner-config/validate.mjs +0 -259
- package/scripts/lib/owner-config-loader.mjs +0 -170
- package/scripts/lib/owner-config.mjs +0 -28
- package/scripts/lib/soul-resolve.mjs +0 -130
- package/scripts/lib/vault-mirror/render.mjs +0 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: session-plan
|
|
3
|
-
description: Creates a structured wave execution plan with role-based assignment after user alignment. Decomposes agreed tasks into
|
|
3
|
+
description: Creates a structured wave execution plan with role-based assignment after user alignment. Decomposes agreed tasks into waves resolved from the session mode by `scripts/session-shape.mjs`, with optimal agent assignment, dependency ordering, and inter-wave checkpoints. Activated by session-start after Q&A phase completes.
|
|
4
4
|
metadata:
|
|
5
5
|
user-invocable: "false"
|
|
6
6
|
tags: orchestration, planning, waves, agents
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "Loop engineering for AI coding agents — turn ad-hoc sessions into a repeatable research → plan → wave-execute → close loop with verification gates. Runs on Claude Code, Codex CLI, Cursor, and Pi.",
|
|
10
|
-
"version": "4.
|
|
10
|
+
"version": "4.2.0"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "session-orchestrator",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.2.0",
|
|
5
5
|
"description": "Loop engineering for AI coding agents — turn ad-hoc sessions into a repeatable research → plan → wave-execute → close loop with verification gates. Runs on Claude Code, Codex CLI, Cursor, and Pi.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Bernhard Goetzendorfer",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "session-orchestrator",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0+codex.20260909111615",
|
|
4
4
|
"description": "Loop engineering for AI coding agents — turn ad-hoc sessions into a repeatable research → plan → wave-execute → close loop with verification gates. Runs on Claude Code, Codex CLI, Cursor, and Pi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"session",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: session-plan
|
|
3
|
-
description: Creates a structured wave execution plan with role-based assignment after user alignment. Decomposes agreed tasks into
|
|
3
|
+
description: Creates a structured wave execution plan with role-based assignment after user alignment. Decomposes agreed tasks into waves resolved from the session mode by `scripts/session-shape.mjs`, with optimal agent assignment, dependency ordering, and inter-wave checkpoints. Activated by session-start after Q&A phase completes.
|
|
4
4
|
metadata:
|
|
5
5
|
user-invocable: 'false'
|
|
6
6
|
tags: orchestration, planning, waves, agents
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: session-plan
|
|
3
|
-
description: "Creates a structured wave execution plan with role-based assignment after user alignment. Decomposes agreed tasks into
|
|
3
|
+
description: "Creates a structured wave execution plan with role-based assignment after user alignment. Decomposes agreed tasks into waves resolved from the session mode by `scripts/session-shape.mjs`, with optimal agent assignment, dependency ordering, and inter-wave checkpoints. Activated by session-start after Q&A phase completes."
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "session-orchestrator",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Loop engineering for AI coding agents — turn ad-hoc sessions into a repeatable research → plan → wave-execute → close loop with verification gates. Runs on Claude Code, Codex CLI, Cursor, and Pi.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bernhard Goetzendorfer"
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [4.2.0] - 2026-09-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `scripts/session-shape.mjs` (+ `scripts/lib/session-shape.mjs`) — the one place a `/session` mode + optional `--profile` resolves into an execution shape (wave count, roles, per-wave agent caps, Discovery on/off, per-wave `max-turns`). Replaces prose that answered "how many waves does a `deep` session have" in 27 places and disagreed with itself in 8 of them (measured 2026-09-09). Emits `orchestrator.session.shape_resolved`. Housekeeping is now always 1 coordinator-direct maintenance-loop wave; feature is 3 waves; deep is 5 (4 with `--known-scope true`); the `ultradeep` profile is a fixed 7 waves and ignores `waves` outright (`wavesConfigHonored: false` — PRD AC-9's "`waves < 7` is an error" is dropped). Documented in `docs/session-config-reference.md` § Session Shapes and `docs/session-config-template.md`.
|
|
15
|
+
- `scripts/lib/maintenance-due-banner.mjs` — one session-start probe (`maintenance-due`) replacing the standalone `reconcile-nudge` probe and the session-end Phase 3.6.5/3.6.7 auto-dream/auto-dialectic nudges. Six ANDed signals (evolve, sweep, reconcile, dialectic, memory-cleanup, pending-sidecar), a 7-day housekeeping cooldown, banner `⚠ maintenance due: N of 6 (…) — run /session housekeeping.`. Motivated by measurement: `orchestrator.evolve.completed` fired zero times across consumer repos while 628 learnings sat unprocessed, and the auto-dialectic nudge recorded `decided: true` while nobody ever ran it.
|
|
16
|
+
- `scripts/lib/session-end/tail-runner.mjs` (`runTailPhases`) — the mechanical APPLY half of session-end Phase 3.6.4's Expired-Learnings Sweep, closing a gap where the dry-run decision ran every close but nothing ever applied it (census: 0 sweeps applied, 628 learnings resident, across three consumer repos). Emits `orchestrator.learnings.sweep_applied`.
|
|
17
|
+
- `scripts/lib/issue-budget-reconcile.mjs` — a close-time cross-check between a session's recorded issue creations and what the issue-budget ledger actually charged, emitting `orchestrator.issue_budget.reconciled` with verdict `match` / `escaped` / `no-ledger` / `stale-record`. Motivated by a session record with 26 recorded issue creations and no ledger file under either accounting key.
|
|
18
|
+
- `issue-budget.max-per-session` now accepts the same per-session-type override syntax as `agents-per-wave` (`12 (feature: 6)`), resolved against the current session's `session-type:` (read from STATE.md) via the new `resolveMaxPerSession()` / `readSessionTypeFromStateMd()` in `scripts/lib/issue-budget.mjs`. The parser (`scripts/lib/config/issue-budget.mjs`) now returns two keys — `max-per-session` (always numeric) and `max-per-session-raw` (the unresolved value) — plus `session-type-resolved` on the loaded config.
|
|
19
|
+
- `scripts/lib/telemetry/pricing.mjs` — a per-model USD-per-million-token price table (`PRICING_TABLE_DATE: 2026-09-09`) covering uncached input, cache-read, cache-creation and output rates, used by `scripts/lib/session-token-rollup.mjs` to compute `total_cost_usd` per session (gated on `schema_version >= 2`; older records are reported as `legacy_v1_records` rather than silently summed in).
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
|
|
23
|
+
- **`js-yaml` `^4.3.1` → `^4.3.2`** (GHSA-2883-xcg3-v3hh, high) — pipeline #512 on `main` had failed in `npm-audit` on the old range; `npm audit --omit=dev --audit-level=high` now exits 0.
|
|
24
|
+
- **`vitest` + `@vitest/coverage-v8` `^4.1.5` → `^4.1.11`** (GHSA: path traversal / arbitrary file read via `@vitest/mocker` redirect mock, moderate; dev-only) — `npm audit` now reports 0 vulnerabilities at any level; the two scaffolding templates (`templates/node-minimal`, `templates/nextjs-minimal`) move from `^3.1.0` to `^4.1.11` so Dependabot stops failing on them (`dependency_file_not_supported`, no lockfile in a template).
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **CI (#1294)** — GitLab `test` job: 3 shards (was 2), inner vitest cap 840 s (was 600 s), job timeout 15 min (was 10), per-shard floor 2500 tests. Measured 2026-09-09: a degraded autoscaler VM ran every test file 3–4× slower and killed a green shard at the 600 s cap twice while its sibling shard finished in 206 s.
|
|
29
|
+
- `hooks/subagent-telemetry.mjs` schema_version 2 (#1244) — `token_input` is redefined from raw `usage.input_tokens` to BILLABLE PROMPT VOLUME (uncached + cache_read + cache_creation). Under prompt caching the old value understated real prompt volume by up to ~65,646× on one measured agent (56 vs 3,676,179 tokens). New additive fields `token_input_uncached`, `token_cache_read`, `token_cache_creation`, `model`. This is a SERIES BREAK — v1 and v2 `token_input` values are not comparable, and `scripts/lib/session-token-rollup.mjs` sums only `schema_version >= 2` records.
|
|
30
|
+
- `hooks/pre-bash-issue-budget.mjs` now charges per STATEMENT rather than per whole command; `hooks/_lib/vcs-create-matcher.mjs` additionally matches `gh|glab api … POST …/issues`.
|
|
31
|
+
- `docs/USER-GUIDE.md` § 4 Session Types and § 6 The Wave Pattern rewritten around the four resolved shapes (housekeeping/feature/deep/ultradeep) and a pointer to `scripts/session-shape.mjs --help`; the retired 3/4/5/6+ role-combination mapping table and the stale `housekeeping=2/feature=6/deep=6-10` agent-count table are replaced with the shape's actual per-type ceilings.
|
|
32
|
+
- `docs/components.md` — the Scripts exemplar list extended with `session-shape`, `maintenance-due-banner`, `tail-runner`, `issue-budget-reconcile`, `telemetry/pricing`.
|
|
33
|
+
- **Dead-code sweep (`check-unwired-features.mjs`)** — deleted `scripts/lib/soul-resolve.mjs`, `scripts/lib/owner-config-loader.mjs`, `scripts/lib/owner-config.mjs` + `scripts/lib/owner-config/` (7 files), `scripts/lib/multi-provider-build/{templating,providers}.mjs`, and the `scripts/lib/vault-mirror/render.mjs` barrel, plus their 12 test files — unreachable-library-module findings 5 → 2 (the 2 remaining are #1293). `.claude/rules/owner-persona.md`, `docs/owner-config-schema.md`, and `scripts/lib/owner-config.example.yaml` now describe the live `owner-yaml.mjs` surface instead of the removed loader.
|
|
34
|
+
- **#1288** — `decideAndRecordAutoDialectic` wrapper removed from `scripts/lib/auto-dialectic.mjs` (its only caller, session-end Phase 3.6.7, was already retired); `orchestrator.dialectic.nudge_decided` retired to a historical catalog row in `docs/events-schema.md`.
|
|
35
|
+
- **#1290 (items 1+2)** — `resolveSessionShape` now rejects out-of-set `configIsolation`/`configEnforcement` up front instead of only where `buildWave` happens to reach the resolver (previously the housekeeping shape could swallow `configIsolation: 'worktre'` unnoticed); `maintenance-due-banner.mjs` tail-scans `events.jsonl` backwards in 256 KiB chunks instead of reading the whole file (probe 31→17 ms on a 7.9 MB ledger). Item 3 deferred.
|
|
36
|
+
- **Rules** — 10 `/reconcile`-generated learnings absorbed into the 4 thematic files `toolchain-and-build.md`, `guard-design.md`, `identity-and-locks.md`, `review-and-adapter-contracts.md` per the merge contract (`docs/rule-authoring.md` § "Consolidated rules"); generated surface 128,999 → 120,906 B / 11 files (ceiling 124,000).
|
|
37
|
+
- **Peer card** — `.orchestrator/peers/AGENT.md` frontmatter restored to the top of the file (a managed block had been hand-prepended above it in `1be450a0`); the 2026-09-07 dialectic sidecar merged (9 sections replaced, 1 added).
|
|
38
|
+
- **Docs/citations** — `skills/wave-executor/SKILL.md` + `references/wave-loop-review.md` now cite `scripts/lib/workspace.mjs` for `restoreCoordinatorCwd()` (was `worktree.mjs`, which does not export it); `.claude/rules/security.md` dropped a citation to a heading that no longer exists; `.claude/rules/development.md` § Documentation gained a rule requiring an `rg` sweep for the old path whenever an exported symbol or module moves, in the SAME change (#1221 item 7).
|
|
39
|
+
|
|
40
|
+
### Notes
|
|
41
|
+
|
|
42
|
+
- **Housekeeping/VCS** — 21 stale `status:in-progress` labels cleared; #1213 closed (→ #1291); 4 merged `codex/*` branches + 2 sibling worktrees removed; 5 merged `feat/*` branches deleted on the GitHub mirror.
|
|
43
|
+
|
|
10
44
|
## [4.1.0] - 2026-09-08
|
|
11
45
|
|
|
12
46
|
### Added
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Session Orchestrator
|
|
2
2
|
|
|
3
3
|
[](LICENSE)
|
|
4
|
-
[](CHANGELOG.md)
|
|
5
5
|
[](https://www.npmjs.com/package/session-orchestrator)
|
|
6
6
|
[](docs/telemetry/telemetry-claims.md)
|
|
7
7
|
|
|
@@ -84,7 +84,7 @@ Everything else is opt-in. Full template: [`docs/session-config-template.md`](do
|
|
|
84
84
|
|
|
85
85
|
```text
|
|
86
86
|
/session feature # research + Q&A — inspect git, issues, history, then agree on scope
|
|
87
|
-
/go # execute in
|
|
87
|
+
/go # execute in typed waves sized by session type (feature: 3, deep: 5) — quality gate between each
|
|
88
88
|
/close # verify every item, commit cleanly, file carryover issues for the rest
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -184,7 +184,7 @@ Counts measured on 2026-09-07 with the command in brackets:
|
|
|
184
184
|
- **14 typed subagents** (code-implementer, test-writer, security-reviewer, session-reviewer, qa-strategist, architect-reviewer, …) (`ls agents/*.md | wc -l`)
|
|
185
185
|
- **27 hook files across 10 event types**, enforcing scope, blocking destructive commands, gating templates-first, and capturing telemetry — full on Claude Code; experimental, post-hoc, or bridged elsewhere ([Platform support](#platform-support)) (`ls hooks/*.mjs | wc -l`)
|
|
186
186
|
- **26 rule files** and **18 ADRs** carrying the reasoning behind the mechanisms (`ls .claude/rules/*.md | wc -l`, `ls docs/adr/*.md | wc -l`)
|
|
187
|
-
- **
|
|
187
|
+
- **664 vitest test files** covered by the full quality gate and CI — 13,789 static `it()`/`test()` definitions at that measurement, and the runtime total is higher because of parameterised blocks ([methodology](docs/telemetry/telemetry-claims.md)) (`find tests -name '*.test.mjs' | wc -l`); Full Gate 2026-09-09: 16847 passed / 11 skipped / 664 files
|
|
188
188
|
|
|
189
189
|
**Portable across harnesses by construction.** `scripts/generate-agents-skills.mjs` generates root `AGENTS.md` byte-identical from `CLAUDE.md` and the `.agents/skills/<name>/SKILL.md` mirrors, with spec-legal frontmatter and pointers to canonical instructions. `scripts/generate-codex-skills.mjs` generates the Codex command entrypoints. Plugin validation checks both surfaces. Separate manifests under `.claude-plugin/`, `.codex-plugin/` and `.cursor-plugin/` register each harness's components; see [Codex manifest compatibility](docs/codex-setup.md#manifest-compatibility).
|
|
190
190
|
|
|
@@ -202,13 +202,13 @@ Full component inventory: [`docs/components.md`](docs/components.md). Version hi
|
|
|
202
202
|
|
|
203
203
|
How this compares to other orchestrators — with the parts that are measured and the parts that are not: [`docs/components.md` § Comparisons](docs/components.md#comparisons).
|
|
204
204
|
|
|
205
|
-
## Recent highlights (v4.
|
|
205
|
+
## Recent highlights (v4.2.0)
|
|
206
206
|
|
|
207
|
-
Highlights of the v4.
|
|
207
|
+
Highlights of the v4.2.0 line:
|
|
208
208
|
|
|
209
|
-
- **
|
|
210
|
-
- **
|
|
211
|
-
- **
|
|
209
|
+
- **One place resolves a session into its shape.** `node scripts/session-shape.mjs` turns a mode (housekeeping/feature/deep, optional ultradeep profile) into waves, per-wave agent caps, isolation and enforcement, and records the result as an event. Housekeeping is now the maintenance loop (drift-check, sweep, evolve, reconcile, dialectic, memory-cleanup), driven by the session-start `maintenance-due` probe instead of close-time nudges.
|
|
210
|
+
- **Honest cost numbers.** Subagent telemetry schema v2 counts cache-read and cache-creation tokens (previously under-reported ~65,000×); a per-model price table rolls up USD per session. The issue-budget ledger is reconciled against the session record at close.
|
|
211
|
+
- **Leaner tree.** A dead-code sweep removed 13 unreachable library modules and their tests; `js-yaml` patched for GHSA-2883-xcg3-v3hh; ten reconciled learnings absorbed into the thematic rule files so the generated-rule surface stays under budget.
|
|
212
212
|
|
|
213
213
|
If upgrading from before 4.0, read [the v4 migration guide](docs/migration-v4.md). Full changes and verification: [CHANGELOG.md](CHANGELOG.md).
|
|
214
214
|
|
package/agents/ux-evaluator.md
CHANGED
|
@@ -51,7 +51,7 @@ Log a warning to stdout (not a finding) if an expected artifact type is absent.
|
|
|
51
51
|
|
|
52
52
|
**Step 6 — Apply Check 3: `console-errors`.** If `console.log` exists, read it. The file is NDJSON (one JSON object per line) with shape `{"ts":<epoch-ms>,"type":"error"|...,"text":"...","location":{...}}`. For each entry where `type === 'error'` OR `text` contains `UNCAUGHT`, `Unhandled`, `TypeError`, `ReferenceError`, or HTTP 4xx/5xx status strings surfaced to the UI, emit one finding. Filter lines where `text` matches developer-tooling noise patterns (e.g., Vue/React hydration hints, HMR messages, browser extension warnings). Severity HIGH for uncaught exceptions; MEDIUM for visible HTTP errors. Fingerprint inputs: `scope='console'`, `checkId='error-' + derived-msg-class`, `locator=<origin-url-or-file-line>`.
|
|
53
53
|
|
|
54
|
-
**Step 7 — Apply Check 4: `liquid-glass-conformance`.** This check is conditional: only execute it when the project's `Package.swift` declares a platform target of iOS 26+ or macOS Tahoe (26+). Read `Package.swift` (or the nearest one if multiple exist in the repo). If the platform condition is not satisfied, skip this check and note "liquid-glass-conformance: skipped (platform target < 26)" in the stdout summary. If the condition is satisfied, read each Peekaboo screenshot under `screenshots/*.png` and the accompanying AX-path metadata. Flag frames where the AX annotation indicates a translucent/blurred background that does NOT use `.glassEffect()` (look for legacy `.background(.thinMaterial)` or `.blur(radius:)` annotations in the AX dump). Severity MEDIUM; LOW when project conventions explicitly permit the legacy modifier (check for a `docs/apple-hig-exceptions.md` or similar). Fingerprint inputs: `scope='liquid-glass'`, `checkId='missing-glassEffect'`, `locator=<screen-name>.<frame-id>`.
|
|
54
|
+
**Step 7 — Apply Check 4: `liquid-glass-conformance`.** This check is conditional: only execute it when the project's `Package.swift` declares a platform target of iOS 26+ or macOS Tahoe (26+). Read `Package.swift` (or the nearest one if multiple exist in the repo). If the platform condition is not satisfied, skip this check and note "liquid-glass-conformance: skipped (platform target < 26)" in the stdout summary. If the condition is satisfied, read each Peekaboo screenshot under `screenshots/*.png` and the accompanying AX-path metadata. Flag frames where the AX annotation indicates a translucent/blurred background that does NOT use `.glassEffect()` (look for legacy `.background(.thinMaterial)` or `.blur(radius:)` annotations in the AX dump). Severity MEDIUM; LOW when project conventions explicitly permit the legacy modifier (check for a project-owned `docs/apple-hig-exceptions.md` or similar). Fingerprint inputs: `scope='liquid-glass'`, `checkId='missing-glassEffect'`, `locator=<screen-name>.<frame-id>`. <!-- path-check: example -->
|
|
55
55
|
|
|
56
56
|
**Step 8 — Write `findings.jsonl`.** Collect all emitted findings. Sort by `severity` (CRITICAL → HIGH → MEDIUM → LOW), then by `check` alphabetically, then by `fingerprint`. Write the sorted list to `<run-dir>/findings.jsonl`, one JSON object per line (NDJSON). Include a header line (a JSON comment is not valid NDJSON — do NOT add a comment line; write a metadata record instead as the first line with `"_meta": true, "rubric_version": "v1", "run_id": "<run-id>", "evaluated_at": "<ISO timestamp>"`).
|
|
57
57
|
|
package/commands/close.md
CHANGED
|
@@ -10,9 +10,9 @@ The user wants to end the current session.
|
|
|
10
10
|
**Pre-check before invoking session-end:** Determine `<state-dir>` from the current platform (`.claude/`, `.codex/`, `.cursor/`, or `.pi/`). Check if `<state-dir>/STATE.md` exists and read its `status` field. Three exit conditions:
|
|
11
11
|
|
|
12
12
|
1. **STATE.md does not exist:** Read Session Config to check `persistence`. If `persistence: false`, inform the user: "Session completed (persistence is off — STATE.md was never created). Use `/session` to start a new session." If `persistence: true` (or Session Config unavailable), inform the user: "No active session found. Use `/session` to start a session first." Either way, stop.
|
|
13
|
-
2. **STATE.md exists and `status: completed`:** `status: completed` alone is NOT proof that session-end's Phase 3.7 writer ever ran (#429) — the field can be set by hand, or by any path that stops short of that write.
|
|
14
|
-
- **A matching record exists:** Inform the user: "Previous session was already finalized by session-end. Start a new session with `/session`, or inspect `<state-dir>/STATE.md` to review the prior close. (Note: if this is unexpected after an Express Path session, `commands/go.md` should have auto-invoked /close — check that STATE.md `## Deviations` contains an `Express path:` entry.)" and stop.
|
|
15
|
-
- **No
|
|
13
|
+
2. **STATE.md exists and `status: completed`:** `status: completed` alone is NOT proof that session-end's Phase 3.7 writer ever ran (#429) — the field can be set by hand, or by any path that stops short of that write. Parse STATE.md with `parseStateMd` and parse `.orchestrator/metrics/sessions.jsonl` as JSONL. Import `findRecordedSession` from the plugin's `scripts/lib/session-close-backfill.mjs` and call it with the parsed records and `{ sessionId: frontmatter['session-id'], semanticSessionId: frontmatter.session, startedAt: frontmatter.started_at }`. This is the shared backfill identity reader: native UUIDs take precedence, conflicting native IDs never match through a label, and legacy semantic records remain readable. Do not substitute a text grep or compare the semantic label only against `session_id`. A missing ledger means no record; an unreadable or malformed ledger is inconclusive — report the read/parse failure and stop before repeating close side effects.
|
|
14
|
+
- **A matching completed record exists (including a legacy authoritative record without a `status` field):** Inform the user: "Previous session was already finalized by session-end. Start a new session with `/session`, or inspect `<state-dir>/STATE.md` to review the prior close. (Note: if this is unexpected after an Express Path session, `commands/go.md` should have auto-invoked /close — check that STATE.md `## Deviations` contains an `Express path:` entry.)" and stop.
|
|
15
|
+
- **No matching completed record exists:** Warn the user: "STATE.md completed ohne passenden Abschluss im Ledger — session-end wird zur Vervollständigung ausgeführt (#429)." An abandoned backfill stub does not prove finalization. Do NOT stop — proceed to invoke the session-end skill exactly as in exit condition 3, so the missing completion gets written this time. (The SessionEnd hook's `backfillCompletedFromStateMd` independently self-heals this same gap on a later session's teardown; this Pre-Check branch covers the case where /close is re-run before that hook has had a chance to fire.)
|
|
16
16
|
3. **STATE.md exists and `status: active` or `status: paused`:** Proceed to invoke the session-end skill.
|
|
17
17
|
|
|
18
18
|
For any other `status` value (e.g., `idle`), warn the user: "Unexpected session status `<value>`. Inspect `<state-dir>/STATE.md` and use `/session` to reset if needed." and stop.
|
package/commands/go.md
CHANGED
|
@@ -18,6 +18,8 @@ Express path activated — <N> tasks, coordinator-direct, no inter-wave checks.
|
|
|
18
18
|
|
|
19
19
|
If the banner is present (and the session-plan output emitted a 1-wave Express Path plan per `skills/session-plan/SKILL.md` § "Express Path Short-Circuit"):
|
|
20
20
|
|
|
21
|
+
**The express 1-wave plan IS the housekeeping shape.** `node scripts/session-shape.mjs --repo-root "$PWD" --session-type housekeeping --no-event` resolves to a single wave with `coordinatorDirect: true` — the express path is not a bespoke shortcut but that shape executed. Consequently, when the session type is `housekeeping`, the coordinator-direct execution runs the **maintenance loop first** (drift-check, expired sweep, `/evolve analyze`, `/reconcile`, `/evolve dialectic`, `/memory-cleanup` — ordered scope, gates and proving artefacts in `skills/wave-executor/SKILL.md` § Housekeeping Sessions — the Maintenance Loop), and **then** the selected issues in dependency order.
|
|
22
|
+
|
|
21
23
|
1. **Execute the agreed tasks directly** as coordinator actions, in dependency order. Do NOT dispatch subagents. Do NOT invoke the wave-executor skill.
|
|
22
24
|
2. **Append the Express Path deviation to STATE.md** before invoking session-end. Use `appendDeviationOnDisk()` from `scripts/lib/state-md.mjs` — the on-disk wrapper takes the STATE.md lock automatically, serialising any concurrent writers. This step ensures the audit trail exists BEFORE session-end finalizes the file. Equivalent one-liner via Bash:
|
|
23
25
|
```bash
|
|
@@ -13,12 +13,13 @@ The skill accepts two optional, mutually-exclusive flags (see PRD #502):
|
|
|
13
13
|
|
|
14
14
|
| Flag | Behavior |
|
|
15
15
|
|---|---|
|
|
16
|
-
| `--dry-run` | Run Phases 1-3 read-only. Writes a complete-replacement MEMORY.md proposal (single fenced ` ```markdown ` block; topic-file changes carried as separate `### Topic-file change:` sections after it — never git-style diff hunks, see #717) to `.orchestrator/pending-dream.md` (atomic write). Prints `pending-dream written: <N> lines proposed` (or `no consolidation needed`). Exit 0. |
|
|
17
|
-
| `--apply-pending` | Reads `.orchestrator/pending-dream.md`, refuses if older than 14 days or if MEMORY.md changed since the producing `--dry-run` (#788), applies the proposal, deletes the pending file. Prints `auto-dream applied: -<X> lines, +<Y> entries`. Exit 0 on apply; exit 1 when pending file is missing (`no pending dream to apply`), stale (`pending dream is stale (>14d), re-run --dry-run`), index-drifted (`MEMORY.md changed since the producing --dry-run; re-run --dry-run.`), or unsupported-format (`auto-dream NOT applied: pending-dream.md contains git-style diff hunks this applier cannot consume. MEMORY.md left untouched, sidecar preserved. Re-run /memory-cleanup --dry-run to regenerate a complete-body proposal.`). |
|
|
16
|
+
| `--dry-run` | Run Phases 1-3 read-only. Writes a complete-replacement MEMORY.md proposal (single fenced ` ```markdown ` block; topic-file changes carried as separate `### Topic-file change:` sections after it — never git-style diff hunks, see #717) to `.orchestrator/pending-dream.md` (atomic write). Prints `pending-dream written: <N> lines proposed` (or `no consolidation needed`). Exit 0. <!-- path-check: example --> |
|
|
17
|
+
| `--apply-pending` | Reads `.orchestrator/pending-dream.md`, refuses if older than 14 days or if MEMORY.md changed since the producing `--dry-run` (#788), applies the proposal, deletes the pending file. Prints `auto-dream applied: -<X> lines, +<Y> entries`. Exit 0 on apply; exit 1 when pending file is missing (`no pending dream to apply`), stale (`pending dream is stale (>14d), re-run --dry-run`), index-drifted (`MEMORY.md changed since the producing --dry-run; re-run --dry-run.`), or unsupported-format (`auto-dream NOT applied: pending-dream.md contains git-style diff hunks this applier cannot consume. MEMORY.md left untouched, sidecar preserved. Re-run /memory-cleanup --dry-run to regenerate a complete-body proposal.`). <!-- path-check: example --> |
|
|
18
18
|
|
|
19
19
|
Passing both flags is an error. Absence of both = legacy interactive 4-phase mode.
|
|
20
20
|
|
|
21
|
-
Session-end Phase 3.6.5 (`scripts/lib/auto-dream.mjs`) is nudge-only (#614) — it never dispatches a subagent to write the sidecar.
|
|
21
|
+
Session-end Phase 3.6.5 (`scripts/lib/auto-dream.mjs`) is nudge-only (#614) — it never dispatches a subagent to write the sidecar.
|
|
22
|
+
The only real producer of `.orchestrator/pending-dream.md` is a manual `/memory-cleanup --dry-run` run; `--apply-pending` is the operator-confirmed consumer in a later session. The sidecar file is single-writer — concurrent sessions cannot collide because the writer holds the session-lock. <!-- path-check: example -->
|
|
22
23
|
|
|
23
24
|
## Default (no flag)
|
|
24
25
|
|
|
@@ -111,7 +111,7 @@ Resolves catalog and target, prints the planned dispatch list (persona names, mo
|
|
|
111
111
|
/persona-panel docs/design-doc.md --grounding re-derive
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
Each dispatched persona is instructed to independently re-derive supporting sources via Read/Grep/Glob rather than trusting a "Sources" section already present in `docs/design-doc.md
|
|
114
|
+
Each dispatched persona is instructed to independently re-derive supporting sources via Read/Grep/Glob rather than trusting a "Sources" section already present in the input document (for example, `docs/design-doc.md`), and reports them as `derived_sources`. Advisory-only — `final_verdict` is unaffected. <!-- path-check: example -->
|
|
115
115
|
|
|
116
116
|
## Related
|
|
117
117
|
|
package/commands/session.md
CHANGED
|
@@ -9,7 +9,7 @@ You are beginning a new development session. The user has invoked `/session` wit
|
|
|
9
9
|
|
|
10
10
|
**Default rationale (measured, not assumed):** `deep` is the default because it is what operators actually run — 77.3 % of 489 recorded sessions across 5 repos, and 115 of 228 (50.4 %) in this repo's own `.orchestrator/metrics/sessions.jsonl`. The former `feature` default made the majority case the one that had to be typed out every time. A `deep` default costs a downgrade keystroke in the minority case; a `feature` default cost an upgrade keystroke in the majority case.
|
|
11
11
|
|
|
12
|
-
**Argument validation:** Valid session types are `housekeeping`, `feature`, and `deep`. An explicit `$ARGUMENTS` value ALWAYS wins over the default — `/session housekeeping` and `/session feature` behave exactly as before. `ultradeep` is additionally accepted as an ARGUMENT ALIAS (see below); it is not a fourth type. If `$ARGUMENTS` is not empty and does not match any valid type or the alias, inform the user: "Invalid session type '$ARGUMENTS'. Valid types: housekeeping, feature, deep (alias: ultradeep)." Then fall back to `deep`.
|
|
12
|
+
**Argument validation:** Valid session types are `housekeeping`, `feature`, and `deep`. An explicit `$ARGUMENTS` value ALWAYS wins over the default — `/session housekeeping` and `/session feature` behave exactly as before. `ultradeep` is additionally accepted as an ARGUMENT ALIAS (see below); it is not a fourth type. If `$ARGUMENTS` is not empty and does not match any valid type or the alias, inform the user: "Invalid session type '$ARGUMENTS'. Valid types: housekeeping, feature, deep (alias: ultradeep)." Then fall back to `deep`. Once the type (and any profile) is settled, the resolved execution shape is recorded at plan time by `node scripts/session-shape.mjs` (event `orchestrator.session.shape_resolved`), so the ledger can answer "how many waves did this session actually run".
|
|
13
13
|
|
|
14
14
|
### Argument alias: `ultradeep` (PRD `docs/prd/2026-09-06-ultradeep-session-profile.md`)
|
|
15
15
|
|
|
@@ -23,7 +23,8 @@ session-profile: ultradeep # the only place the alias survives
|
|
|
23
23
|
- **`session-type` NEVER becomes `ultradeep`.** The value is a closed set in `scripts/lib/session-schema/constants.mjs` (`VALID_SESSION_TYPES`) and in `scripts/lib/wave-sizing.mjs`; a fourth member would degrade silently in two places (`scripts/lib/telemetry/schema.mjs` maps an unknown type to `"other"`, `scripts/lib/session-close-backfill.mjs` labels it `housekeeping`). The alias exists so that no closed set has to change.
|
|
24
24
|
- **`session-profile` is optional and absent by default.** A plain `/session deep` writes NO `session-profile` key. Absent means "no profile" — never write an empty string, `none`, or `null` to mean absence. Read/write helpers: `readSessionProfile` / `setSessionProfile` in `scripts/lib/state-md.mjs`.
|
|
25
25
|
- **What the profile changes** is the WAVE SHAPE, not the session type: 7 waves with a coordinator-direct Synthesis-Gate at wave 2. See `skills/session-plan/SKILL.md` § Role-to-Wave Mapping and `skills/wave-executor/SKILL.md` § Ultradeep Profile.
|
|
26
|
-
- **
|
|
26
|
+
- **The profile OWNS its wave count.** `resolveSessionShape({ profile: 'ultradeep' })` returns 7 waves and reports `wavesConfigHonored: false` together with the ignored value; the `waves` key never applies to the profile (PRD AC-9 dropped 2026-09-09). Nothing to reconcile, nothing to ask the user about — read the count from `node scripts/session-shape.mjs --session-type deep --profile ultradeep`.
|
|
27
|
+
- **Cost — why the alias stays the exception.** Measured 2026-09-09 over 6 ultradeep runs in three repos: 362–507 min wall-clock vs 131–164 min for deep, at similar output-token volume — use only with a named research question.
|
|
27
28
|
- **Budgets are deliberately not implemented yet** (PRD § 7): no `ultradeep.max-*` key is read anywhere. Do not invent one; the PRD defers thresholds until three runs have been measured.
|
|
28
29
|
|
|
29
30
|
> **Not read from Session Config.** There is deliberately no `session-type:` (or equivalent) key in the `## Session Config` block — `scripts/lib/config.mjs` `parseSessionConfig()` does not emit one, so any such key in a repo's CLAUDE.md (or its Codex CLI equivalent AGENTS.md) is inert prose. The `session-type:` scalar that IS live lives in STATE.md frontmatter (read by `scripts/print-applicable-rules.mjs` for rule mode-gating) and is written per session, not configured per repo. Do not reintroduce a Session Config key here without wiring it into the parser first.
|
package/docs/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
This directory holds three distinct classes of document. Knowing which class a
|
|
4
4
|
file belongs to tells you whether to trust it as current, read it as history,
|
|
5
|
-
or look for it in the (private) Meta-Vault instead.
|
|
6
|
-
(Epic #774)
|
|
5
|
+
or look for it in the (private) Meta-Vault instead. The archived, private PRD `docs/prd/2026-07-08-docs-public-split.md` <!-- path-check: historical -->
|
|
6
|
+
(Epic #774) records the sanitation project that established this split; it is kept in the private Meta-Vault.
|
|
7
7
|
|
|
8
8
|
## The three classes
|
|
9
9
|
|
|
@@ -100,11 +100,11 @@ Two things worth knowing about this split:
|
|
|
100
100
|
|
|
101
101
|
### Superseded design notes
|
|
102
102
|
|
|
103
|
-
Because `docs/specs/` is gitignored, a correction written INTO a spec can never be committed — so the correction lives here instead. `docs/specs/2026-05-26-parallel-aware-sessions-design.md` (parallel-aware sessions) specifies PID-based lock liveness (`stale-pid-dead`). That is **superseded**: liveness is heartbeat-age based since #1137 (`isLockLive`; `acquire()` knows only `stale-heartbeat`), and the recorded PID is consulted nowhere since #1151 — it was the PID of the short-lived subprocess that wrote the lock, dead within a second. Read the local spec only with that correction applied.
|
|
103
|
+
Because `docs/specs/` is gitignored, a correction written INTO a spec can never be committed — so the correction lives here instead. `docs/specs/2026-05-26-parallel-aware-sessions-design.md` (parallel-aware sessions) specifies PID-based lock liveness (`stale-pid-dead`). That is **superseded**: liveness is heartbeat-age based since #1137 (`isLockLive`; `acquire()` knows only `stale-heartbeat`), and the recorded PID is consulted nowhere since #1151 — it was the PID of the short-lived subprocess that wrote the lock, dead within a second. Read the local spec only with that correction applied. <!-- path-check: historical -->
|
|
104
104
|
|
|
105
105
|
## See Also
|
|
106
106
|
|
|
107
|
-
- `docs/prd/2026-07-08-docs-public-split.md` — the epic that established this split (S1–S8, issues #775–#782).
|
|
107
|
+
- `docs/prd/2026-07-08-docs-public-split.md` — archived in the private Meta-Vault; the epic that established this split (S1–S8, issues #775–#782). <!-- path-check: historical -->
|
|
108
108
|
- `docs/session-config-reference.md` — full Session Config field reference, including the two guards named above.
|
|
109
109
|
- `docs/pm-skills-marketplace.md` — when to install `phuryn/pm-skills` alongside this plugin, and the overlap table against `/grill`, `/brainstorm`, `/plan`, `/discovery`.
|
|
110
110
|
- `README.md` — top-level project overview; links into this router for anything docs-specific.
|