session-orchestrator 5.3.0 → 5.5.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/claude-md-drift-check/SKILL.md +1 -1
- package/.agents/skills/test-audit/SKILL.md +21 -0
- package/.agents/skills/test-audit/agents/openai.yaml +5 -0
- 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/claude-md-drift-check/SKILL.md +1 -1
- package/.codex-plugin/skills/test-audit/SKILL.md +21 -0
- package/.codex-plugin/skills/test-audit/agents/openai.yaml +5 -0
- package/.cursor/commands/test-audit.md +14 -0
- package/.cursor/rules/060-evolve.mdc +28 -13
- package/.cursor/skills/claude-md-drift-check/SKILL.md +1 -1
- package/.cursor/skills/test-audit/SKILL.md +12 -0
- package/.cursor-plugin/plugin.json +1 -1
- package/.orchestrator/policy/blocked-commands.json +1 -1
- package/AGENTS.md +9 -31
- package/CHANGELOG.md +162 -0
- package/README.md +14 -10
- package/docs/agent-authoring.md +2 -2
- package/docs/baseline.md +10 -1
- package/docs/ci-setup.md +154 -4
- package/docs/components.md +11 -11
- package/docs/events-schema.md +25 -19
- package/docs/install.md +14 -2
- package/docs/migration-v4.md +24 -17
- package/docs/persona-panel.md +5 -4
- package/docs/plugin-architecture-v3.md +1 -1
- package/docs/rule-authoring.md +27 -12
- package/docs/scope-collision-guard.md +40 -16
- package/docs/session-config-reference.md +61 -12
- package/docs/session-config-template.md +11 -2
- package/docs/vault-docs-architecture.md +8 -4
- package/hooks/_lib/hook-import-set.json +42 -29
- package/hooks/_lib/lock-bootstrap.mjs +118 -26
- package/hooks/config-protection.mjs +1 -1
- package/hooks/enforce-commands.mjs +28 -13
- package/hooks/enforce-scope.mjs +201 -23
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +5 -0
- package/hooks/hooks-pi.json +5 -0
- package/hooks/hooks.json +6 -1
- package/hooks/on-session-start.mjs +57 -2
- package/hooks/on-stop.mjs +70 -168
- package/hooks/post-bash-write-verify.mjs +98 -17
- package/hooks/post-edit-validate.mjs +15 -5
- package/hooks/post-tool-batch-wave-signal.mjs +32 -152
- package/hooks/pre-bash-memory-propose-audit.mjs +71 -10
- package/hooks/pre-bash-sessions-ledger-guard.mjs +28 -2
- package/hooks/pre-bash-staging-fence.mjs +29 -8
- package/hooks/pre-edit-sessions-ledger-guard.mjs +162 -0
- package/hooks/pre-task-scope-disjoint.mjs +1143 -279
- package/hooks/subagent-telemetry.mjs +96 -19
- package/hooks/wave-scope-commit-guard.mjs +168 -72
- package/package.json +2 -6
- package/pi/prompts/test-audit.md +12 -0
- package/rules/README.md +6 -1
- package/rules/_index.md +3 -3
- package/rules/always-on/bash-harness-pitfalls.md +7 -1
- package/rules/opt-in-domain/prompt-caching.md +5 -1
- package/rules/opt-in-stack/backend-data.md +9 -1
- package/rules/opt-in-stack/backend.md +7 -1
- package/rules/opt-in-stack/frontend.md +6 -1
- package/rules/opt-in-stack/security-web.md +7 -1
- package/rules/opt-in-stack/swift.md +5 -1
- package/scripts/apply-session-learnings.mjs +513 -0
- package/scripts/archive-closed-prds.mjs +40 -12
- package/scripts/autopilot.mjs +57 -54
- package/scripts/backfill-abandoned-sessions.mjs +81 -6
- package/scripts/backfill-learnings-from-vault.mjs +49 -22
- package/scripts/baseline-archetypes.mjs +1 -1
- package/scripts/check-package-manager.mjs +62 -5
- package/scripts/codex-install.mjs +3 -0
- package/scripts/cursor-install.mjs +47 -6
- package/scripts/emit-session.mjs +298 -2
- package/scripts/export-hw-learnings.mjs +40 -10
- package/scripts/fleet-checkin.mjs +170 -0
- package/scripts/lib/agent-frontmatter.mjs +3 -3
- package/scripts/lib/auto-dream.mjs +7 -6
- package/scripts/lib/autopilot/flags.mjs +6 -1
- package/scripts/lib/autopilot/loop.mjs +32 -13
- package/scripts/lib/autopilot/stall-sampler.mjs +13 -9
- package/scripts/lib/baseline-archetypes.mjs +41 -22
- package/scripts/lib/blocked-commands-policy.mjs +40 -0
- package/scripts/lib/common.mjs +41 -0
- package/scripts/lib/config/host-paths.mjs +79 -0
- package/scripts/lib/config/persona-gate-wave.mjs +3 -3
- package/scripts/lib/config/reaper.mjs +7 -6
- package/scripts/lib/config/vault-integration.mjs +151 -16
- package/scripts/lib/config-schema.mjs +13 -0
- package/scripts/lib/config.mjs +75 -10
- package/scripts/lib/eval/engine.mjs +13 -0
- package/scripts/lib/events-retention-banner.mjs +393 -0
- package/scripts/lib/events-rotation.mjs +21 -6
- package/scripts/lib/events.mjs +72 -5
- package/scripts/lib/fleet-protocol.mjs +288 -0
- package/scripts/lib/gates/gate-baseline.mjs +13 -3
- package/scripts/lib/gates/gate-full.mjs +7 -2
- package/scripts/lib/gates/gate-helpers.mjs +93 -2
- package/scripts/lib/gates/gate-incremental.mjs +23 -22
- package/scripts/lib/gates/gate-per-file.mjs +16 -7
- package/scripts/lib/hardening.mjs +1 -0
- package/scripts/lib/harness-audit/categories/category4.mjs +8 -6
- package/scripts/lib/instruction-budget-guard.mjs +77 -11
- package/scripts/lib/learnings/expiry-sweep.mjs +420 -22
- package/scripts/lib/learnings/io.mjs +274 -37
- package/scripts/lib/learnings/schema.mjs +163 -15
- package/scripts/lib/learnings/sizing-subject.mjs +2 -2
- package/scripts/lib/lock-reaper.mjs +38 -14
- package/scripts/lib/maintenance-due-banner.mjs +23 -8
- package/scripts/lib/memory-proposals/schema.mjs +11 -5
- package/scripts/lib/named-baseline-resolver.mjs +53 -28
- package/scripts/lib/named-vault-resolver.mjs +147 -5
- package/scripts/lib/orphan-reaper/defaults.mjs +41 -0
- package/scripts/lib/orphan-reaper/no-follow-append.mjs +87 -0
- package/scripts/lib/orphan-reaper/ps-snapshot.mjs +181 -0
- package/scripts/lib/orphan-reaper/reaper-audit.mjs +323 -0
- package/scripts/lib/orphan-reaper/reaper-decide.mjs +395 -0
- package/scripts/lib/orphan-reaper/scan-throttle.mjs +144 -0
- package/scripts/lib/orphan-reaper/scan.mjs +510 -0
- package/scripts/lib/orphan-reaper/trigger.mjs +173 -0
- package/scripts/lib/orphan-reaper.mjs +47 -1315
- package/scripts/lib/owner-yaml.mjs +104 -6
- package/scripts/lib/persona-panel/catalog-loader.mjs +1 -1
- package/scripts/lib/platform.mjs +206 -2
- package/scripts/lib/plugin-update-banner.mjs +3 -1
- package/scripts/lib/process-group.mjs +134 -22
- package/scripts/lib/project-hygiene.mjs +21 -1
- package/scripts/lib/quality-gate.mjs +45 -5
- package/scripts/lib/resource-probe.mjs +1 -1
- package/scripts/lib/rule-loader.mjs +100 -62
- package/scripts/lib/rules-sync.mjs +27 -12
- package/scripts/lib/scope-baseline.mjs +119 -29
- package/scripts/lib/scope-echo.mjs +7 -0
- package/scripts/lib/scope-gate.mjs +194 -27
- package/scripts/lib/session-close-backfill.mjs +129 -4
- package/scripts/lib/session-end/tail-runner.mjs +10 -5
- package/scripts/lib/session-lock-shape.mjs +6 -3
- package/scripts/lib/session-lock.mjs +320 -67
- package/scripts/lib/session-record-repair.mjs +183 -26
- package/scripts/lib/session-registry.mjs +67 -17
- package/scripts/lib/session-schema/constants.mjs +30 -4
- package/scripts/lib/session-schema/validator.mjs +28 -1
- package/scripts/lib/session-start-probes.mjs +242 -68
- package/scripts/lib/session-token-rollup.mjs +252 -54
- package/scripts/lib/sessions-canonical.mjs +100 -9
- package/scripts/lib/sessions-staleness-banner.mjs +3 -1
- package/scripts/lib/sh-quote.mjs +29 -0
- package/scripts/lib/subagents-schema.mjs +30 -3
- package/scripts/lib/tail-window.mjs +27 -3
- package/scripts/lib/telemetry/pricing.mjs +121 -71
- package/scripts/lib/telemetry/sync.mjs +17 -0
- package/scripts/lib/tests-src-ratio.mjs +215 -23
- package/scripts/lib/tmux-layout/layouts.mjs +1 -11
- package/scripts/lib/tmux-layout/telemetry-stats.mjs +12 -0
- package/scripts/lib/tmux-layout/tmux-shell.mjs +2 -11
- package/scripts/lib/ux-grill/reconcile.mjs +1 -1
- package/scripts/lib/validate/check-agents.mjs +1 -1
- package/scripts/lib/validate/check-hooks-symmetry.mjs +5 -0
- package/scripts/lib/validate/check-learnings-shell-writes.mjs +214 -0
- package/scripts/lib/validate/check-test-value-bans.mjs +388 -27
- package/scripts/lib/validate/check-unicode-safety.mjs +1 -0
- package/scripts/lib/validate/check-unwired-features.mjs +1 -1
- package/scripts/lib/validate/check-vcs-repo-flag.mjs +1 -1
- package/scripts/lib/validate-vendored-rules.mjs +206 -81
- package/scripts/lib/vault-mirror/auto-commit.mjs +5 -3
- package/scripts/lib/vault-mirror/namespace.mjs +47 -26
- package/scripts/lib/vault-mirror/process.mjs +350 -62
- package/scripts/lib/vault-mirror/pseudonym-map.mjs +14 -5
- package/scripts/lib/vault-mirror/render-learnings.mjs +66 -3
- package/scripts/lib/vault-mirror/render-sessions.mjs +28 -4
- package/scripts/lib/vault-mirror/telemetry.mjs +25 -11
- package/scripts/lib/vault-status/board-writer.mjs +53 -12
- package/scripts/lib/vault-status/narrative-mirror.mjs +40 -9
- package/scripts/lib/vcs-repo-spec.mjs +8 -0
- package/scripts/lib/wave-executor/dispatch-common.mjs +10 -18
- package/scripts/lib/wave-executor/foreign-dispatch.mjs +1 -1
- package/scripts/lib/wave-executor/remote-dispatch.mjs +1 -1
- package/scripts/lib/wave-resource-gate.mjs +34 -8
- package/scripts/materialize-wave-scope.mjs +7 -4
- package/scripts/memory-propose.mjs +18 -5
- package/scripts/release-session-lock.mjs +2 -1
- package/scripts/release.mjs +11 -3
- package/scripts/repair-invalid-sessions.mjs +37 -4
- package/scripts/run-migrate-v2-cross-repo.mjs +171 -31
- package/scripts/run-quality-gate.mjs +331 -307
- package/scripts/self-update.mjs +229 -0
- package/scripts/site-numbers.mjs +163 -5
- package/scripts/sweep-expired-learnings.mjs +603 -20
- package/scripts/sweep-expired-rules.mjs +2 -1
- package/scripts/validate-plugin.mjs +7 -0
- package/scripts/validate-wave-scope.mjs +21 -2
- package/scripts/vault-backfill.mjs +50 -37
- package/scripts/vault-integration-watcher.mjs +2 -1
- package/scripts/vault-mirror.mjs +238 -75
- package/scripts/wave-scope-binding.mjs +2 -1
- package/skills/_shared/config-reading.md +3 -3
- package/skills/_shared/fleet-protocol.md +134 -0
- package/skills/_shared/state-ownership.md +41 -12
- package/skills/autopilot/SKILL.md +25 -11
- package/skills/bootstrap/SKILL.md +6 -4
- package/skills/bootstrap/_shared-template.md +97 -2
- package/skills/bootstrap/fast-template.md +4 -1
- package/skills/bootstrap/private-contract.md +2 -1
- package/skills/bootstrap/public-fallback.md +6 -3
- package/skills/bootstrap/references/bootstrap-refresh-lock-flow.md +5 -3
- package/skills/bootstrap/references/bootstrap-retroactive-flow.md +2 -1
- package/skills/bootstrap/standard-template.md +2 -0
- package/skills/claude-md-drift-check/SKILL.md +10 -10
- package/skills/claude-md-drift-check/checker.mjs +26 -18
- package/skills/discovery/probes/ssot-code-diff.mjs +12 -6
- package/skills/discovery/probes/vault-narrative-staleness.mjs +6 -2
- package/skills/discovery/probes/vault-staleness.mjs +9 -3
- package/skills/docs-orchestrator/SKILL.md +12 -5
- package/skills/docs-orchestrator/audience-mapping.md +5 -3
- package/skills/evolve/SKILL.md +13 -4
- package/skills/evolve/references/evolve-analyze-mode.md +42 -18
- package/skills/memory-cleanup/SKILL.md +1 -1
- package/skills/persona-panel/SKILL.md +2 -2
- package/skills/persona-panel/persona-format.md +2 -2
- package/skills/persona-panel/presets/designer-lens.md +1 -1
- package/skills/persona-panel/presets/engineer-lens.md +1 -1
- package/skills/persona-panel/presets/pm-lens.md +1 -1
- package/skills/plan/mode-retro.md +19 -4
- package/skills/quality-gates/SKILL.md +6 -4
- package/skills/remote-offload/SKILL.md +4 -2
- package/skills/session-end/learning-patterns.md +23 -13
- package/skills/session-end/metrics-collection.md +6 -7
- package/skills/session-end/phase-3-2-docs-verification.md +7 -6
- package/skills/session-end/plan-verification.md +25 -9
- package/skills/session-end/references/phase-3-documentation-updates.md +13 -3
- package/skills/session-end/references/phase-4a-worktree-cleanup.md +2 -0
- package/skills/session-end/references/session-summary-template.md +1 -1
- package/skills/session-end/session-metrics-write.md +65 -68
- package/skills/session-plan/SKILL.md +0 -3
- package/skills/session-start/SKILL.md +8 -2
- package/skills/session-start/references/operations-contract.md +6 -0
- package/skills/session-start/references/phase-1-2-session-lock.md +32 -7
- package/skills/session-start/references/phase-1-7-vault-status-board.md +1 -1
- package/skills/session-start/references/phase-4-ssot-environment-check.md +10 -3
- package/skills/test-audit/SKILL.md +152 -0
- package/skills/test-audit/references/campaign.md +111 -0
- package/skills/test-audit/references/mutate.sh +50 -0
- package/skills/vault-mirror/SKILL.md +21 -11
- package/skills/wave-executor/SKILL.md +2 -2
- package/skills/wave-executor/circuit-breaker.md +1 -1
- package/skills/wave-executor/references/wave-executor-state-init.md +3 -0
- package/skills/wave-executor/references/wave-loop-dispatch.md +11 -1
- package/skills/wave-executor/references/wave-loop-review.md +4 -6
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +13 -5
- package/templates/personas/README.md +5 -5
- package/templates/personas/accounting-compliance.v1.md +1 -1
- package/templates/personas/accounting-tax-advisor.v1.md +1 -1
- package/templates/personas/buyer-p1-cto.v1.md +1 -1
- package/templates/personas/buyer-p2-kanzlei.v1.md +1 -1
- package/templates/personas/buyer-p3-build.v1.md +1 -1
- package/templates/personas/buyer-p4-tech-veto.v1.md +1 -1
- package/templates/personas/buyer-p5-solo.v1.md +1 -1
- package/templates/personas/buyer-p6-ld.v1.md +1 -1
- package/templates/personas/klima-ai-expert.v1.md +1 -1
- package/templates/personas/klima-physicist.v1.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claude-md-drift-check
|
|
3
|
-
description: "Use when detecting drift between CLAUDE.md (or AGENTS.md, the Codex CLI alias) / _meta narrative and live repository state. Ten checks: absolute-path resolution, 01-projects/ count claims, issue-reference freshness, session-file existence, command-count sync, session-config-parity (mandatory template keys = error, opt-in gaps = warning), vault-dir-parity (CLAUDE.md vs AGENTS.md), generated-rule-staleness (WARN-only), rule-scoping (paths:/globs: frontmatter defects, dangling rule citations, zero-match globs), and docs-parity (docs/components.md count-claims vs on-disk counts, template-vs-reference config-key parity, stale .claude/metrics/ paths). Full per-check spec in the body table. Invoked as an opt-in session-end phase; mirrors vault-sync's lean JSON+exit-code contract."
|
|
3
|
+
description: "Use when detecting drift between CLAUDE.md (or AGENTS.md, the Codex CLI alias) / _meta narrative and live repository state. Ten checks: absolute-path resolution, 01-projects/ count claims, issue-reference freshness, session-file existence, command-count sync, session-config-parity (mandatory template keys = error, opt-in gaps = note, unknown local keys = warning), vault-dir-parity (CLAUDE.md vs AGENTS.md), generated-rule-staleness (WARN-only), rule-scoping (paths:/globs: frontmatter defects, dangling rule citations, zero-match globs), and docs-parity (docs/components.md count-claims vs on-disk counts, template-vs-reference config-key parity, stale .claude/metrics/ paths). Full per-check spec in the body table. Invoked as an opt-in session-end phase; mirrors vault-sync's lean JSON+exit-code contract."
|
|
4
4
|
metadata:
|
|
5
5
|
model: haiku
|
|
6
6
|
---
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-audit
|
|
3
|
+
description: "Use when writing, reviewing, or pruning tests. Three modes, one value bar: a four-question gate before any new test is written, a focused audit of one scope, and a campaign over a whole repo or subsystem that removes the least useful tests under a coverage guard. Every delete, merge, or repair carries written evidence and a caught mutation. Triggered by \"audit the tests\", \"prune the test suite\", \"remove low-value tests\", \"test diet\", \"is this test worth adding\", /test-audit."
|
|
4
|
+
metadata:
|
|
5
|
+
user-invocable: "true"
|
|
6
|
+
argument-hint: "[gate|audit|campaign] [scope] [--goal \"<goal>\"]"
|
|
7
|
+
model: inherit
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# test-audit
|
|
11
|
+
|
|
12
|
+
> **Portable mirror — generated, do not edit.** The canonical workflow lives at
|
|
13
|
+
> [`skills/test-audit/SKILL.md`](../../../skills/test-audit/SKILL.md); read that file for the full instructions.
|
|
14
|
+
> This mirror carries only agentskills.io-spec-legal frontmatter so harnesses that
|
|
15
|
+
> discover skills under `.agents/skills/` can find and route to the skill.
|
|
16
|
+
>
|
|
17
|
+
> Regenerate with `node scripts/generate-agents-skills.mjs`.
|
|
18
|
+
|
|
19
|
+
Read the linked document in full and follow its complete workflow, including prechecks and stop conditions. Resolve its link relative to this SKILL.md, not the project working directory. The plugin root is three directories above this file. Resolve package paths such as `skills/` and `scripts/` from that root and relative links in the canonical document from its own directory. Keep the user’s project as the target of project operations.
|
|
20
|
+
|
|
21
|
+
`$ARGUMENTS` means the trailing user input after the selected command skill, or an empty string when absent. Preserve flags, quoted text, and Unicode as data. Do not perform global substitution in the command document, shell expansion on the argument string, or execution of that string as shell code. Pass command arguments through structured tool parameters or safely quoted individual arguments.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "A repeatable Plan, Go, Close workflow for AI coding sessions: /session reads your repo and agrees the scope, /go runs the work in waves with a quality gate between each, /close verifies and commits. Runs on Claude Code, Codex CLI, Cursor and Pi.",
|
|
10
|
-
"version": "5.
|
|
10
|
+
"version": "5.5.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": "5.
|
|
4
|
+
"version": "5.5.0",
|
|
5
5
|
"description": "A repeatable Plan, Go, Close workflow for AI coding sessions: /session reads your repo and agrees the scope, /go runs the work in waves with a quality gate between each, /close verifies and commits. 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": "5.
|
|
3
|
+
"version": "5.5.0+codex.20261003080809",
|
|
4
4
|
"description": "A repeatable Plan, Go, Close workflow for AI coding sessions: /session reads your repo and agrees the scope, /go runs the work in waves with a quality gate between each, /close verifies and commits. Runs on Claude Code, Codex CLI, Cursor and Pi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"session",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claude-md-drift-check
|
|
3
|
-
description: 'Use when detecting drift between CLAUDE.md (or AGENTS.md, the Codex CLI alias) / _meta narrative and live repository state. Ten checks: absolute-path resolution, 01-projects/ count claims, issue-reference freshness, session-file existence, command-count sync, session-config-parity (mandatory template keys = error, opt-in gaps = warning), vault-dir-parity (CLAUDE.md vs AGENTS.md), generated-rule-staleness (WARN-only), rule-scoping (paths:/globs: frontmatter defects, dangling rule citations, zero-match globs), and docs-parity (docs/components.md count-claims vs on-disk counts, template-vs-reference config-key parity, stale .claude/metrics/ paths). Full per-check spec in the body table. Invoked as an opt-in session-end phase; mirrors vault-sync''s lean JSON+exit-code contract.'
|
|
3
|
+
description: 'Use when detecting drift between CLAUDE.md (or AGENTS.md, the Codex CLI alias) / _meta narrative and live repository state. Ten checks: absolute-path resolution, 01-projects/ count claims, issue-reference freshness, session-file existence, command-count sync, session-config-parity (mandatory template keys = error, opt-in gaps = note, unknown local keys = warning), vault-dir-parity (CLAUDE.md vs AGENTS.md), generated-rule-staleness (WARN-only), rule-scoping (paths:/globs: frontmatter defects, dangling rule citations, zero-match globs), and docs-parity (docs/components.md count-claims vs on-disk counts, template-vs-reference config-key parity, stale .claude/metrics/ paths). Full per-check spec in the body table. Invoked as an opt-in session-end phase; mirrors vault-sync''s lean JSON+exit-code contract.'
|
|
4
4
|
metadata:
|
|
5
5
|
model: haiku
|
|
6
6
|
---
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-audit
|
|
3
|
+
description: 'Use when writing, reviewing, or pruning tests. Three modes, one value bar: a four-question gate before any new test is written, a focused audit of one scope, and a campaign over a whole repo or subsystem that removes the least useful tests under a coverage guard. Every delete, merge, or repair carries written evidence and a caught mutation. Triggered by "audit the tests", "prune the test suite", "remove low-value tests", "test diet", "is this test worth adding", /test-audit.'
|
|
4
|
+
metadata:
|
|
5
|
+
user-invocable: 'true'
|
|
6
|
+
argument-hint: '[gate|audit|campaign] [scope] [--goal "<goal>"]'
|
|
7
|
+
model: inherit
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<!-- Generated by scripts/generate-codex-skills.mjs; do not edit. -->
|
|
11
|
+
|
|
12
|
+
# test-audit
|
|
13
|
+
|
|
14
|
+
Read [`skills/test-audit/SKILL.md`](../../../skills/test-audit/SKILL.md) in full before taking any action, then follow its complete workflow.
|
|
15
|
+
The linked document is authoritative, including its prechecks, argument rules, and stop conditions.
|
|
16
|
+
|
|
17
|
+
Resolve this link relative to this SKILL.md, not the project working directory. The plugin root is three directories above this file. Resolve package paths such as `skills/` and `scripts/` from that root; resolve relative links inside the canonical document from its own directory. Keep the user’s project as the target of project operations.
|
|
18
|
+
|
|
19
|
+
`$ARGUMENTS` means the trailing user input after the selected command skill, or an empty string when absent. Preserve flags, quoted text, and Unicode as data. Do not perform global substitution in the command document, shell expansion on the argument string, or execution of that string as shell code. When the workflow needs a command, pass its arguments through structured tool parameters or safely quoted individual arguments.
|
|
20
|
+
|
|
21
|
+
Regenerate with `node scripts/generate-codex-skills.mjs`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Use when writing, reviewing, or pruning tests. Three modes, one value bar: a four-question gate before any new test is written, a focused audit of one scope, and a campaign over a whole repo or subsystem that removes the least useful tests under a coverage guard. Every delete, merge, or repair carries written evidence and a caught mutation. Triggered by \"audit the tests\", \"prune the test suite\", \"remove low-value tests\", \"test diet\", \"is this test worth adding\", /test-audit."
|
|
3
|
+
argument-hint: "[gate|audit|campaign] [scope] [--goal \\\"<goal>\\\"]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /test-audit
|
|
7
|
+
|
|
8
|
+
Use the Session Orchestrator skill definition at `skills/test-audit/SKILL.md`.
|
|
9
|
+
|
|
10
|
+
Arguments: $ARGUMENTS
|
|
11
|
+
|
|
12
|
+
Read that skill file and follow it exactly. When it references `$ARGUMENTS`, substitute the arguments above. Keep all Session Orchestrator platform fallbacks intact.
|
|
13
|
+
|
|
14
|
+
Cursor has no Skill tool. When the skill says to invoke another skill, Read `skills/<skill-name>/SKILL.md` and follow it. Supporting files (`soul.md`, phase docs) live in that same `skills/<skill-name>/` directory.
|
|
@@ -13,7 +13,7 @@ Extract patterns from session history into reusable learnings. Three modes of op
|
|
|
13
13
|
- **Persistence gate**: `persistence: true` must be set in Session Config. If not, abort: "Learnings require persistence to be enabled in Session Config."
|
|
14
14
|
- Session history must exist at `.orchestrator/metrics/sessions.jsonl`
|
|
15
15
|
- Learnings are stored at `.orchestrator/metrics/learnings.jsonl`
|
|
16
|
-
- Config field: `learning-expiry-days` (default: 30) —
|
|
16
|
+
- Config field: `learning-expiry-days` (default: 30) — legacy window used only by the Review-mode *Extend expiry* action; new and confirmed learnings derive `expires_at` per `type` via `deriveExpiresAt()` (`LEARNING_TTL_DAYS`)
|
|
17
17
|
|
|
18
18
|
## Cursor Adaptation
|
|
19
19
|
|
|
@@ -96,14 +96,22 @@ If zero patterns were extracted, report: "No patterns found in session history."
|
|
|
96
96
|
|
|
97
97
|
### Step 5: Write Confirmed Learnings
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
1.
|
|
101
|
-
2. Apply confidence updates for confirmed existing learnings (+0.15, cap at 1.0)
|
|
102
|
-
3. Apply confidence decrements for contradicted learnings (-0.2)
|
|
103
|
-
4.
|
|
104
|
-
5.
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
Write through the archive-safe pipeline — never a shell redirect (#1017, #1446):
|
|
100
|
+
1. Snapshot the store into the sidecar: `node scripts/sweep-expired-learnings.mjs --prune --snapshot .orchestrator/tmp/learnings-next.jsonl`. It writes every record of `learnings.jsonl` behind a line-1 `{"_store_generation": "sha256:…", "_store_path": "…"}` header naming the exact store state and the store they came from (#1486). Work on the SIDECAR, never on a separate read of `learnings.jsonl`. On a non-default store pass the same `--file` / `--archive` here as to the apply below. Exit `1` here (a PATH that would replace a ledger) wrote nothing: report it and stop. A malformed (unparseable) store line does not stop the snapshot: it prints a stderr WARN with the line numbers and a `malformed` count, and the apply below keeps those lines verbatim — report the count, never hand-edit the store; the one sanctioned repair is `node scripts/sweep-expired-learnings.mjs --drop-malformed --line N` (dry run by default: previews plus the store generation), then `--drop-malformed --line N --apply --generation <TOKEN> --repo-root "$(pwd)"` once the operator confirmed the previews (`--accept-embedded` for a line still holding a readable record; a changed store exits `3`)
|
|
101
|
+
2. Apply confidence updates for confirmed existing learnings (+0.15, cap at 1.0; reset `expires_at` via `deriveExpiresAt(now, type)`)
|
|
102
|
+
3. Apply confidence decrements for contradicted learnings (-0.2; `expires_at` unchanged)
|
|
103
|
+
4. Add new learnings with confidence 0.5 in the canonical shape (see Learning JSONL Format below)
|
|
104
|
+
5. Edit the sidecar `.orchestrator/tmp/learnings-next.jsonl` into that full next generation via the file-write or edit tool, **keeping line 1 — the `_store_generation` header — unchanged and first** (under `tmp/`, never `metrics/`: a metrics-dir sidecar makes the cleanup `rm` a blocked command, #1453). A peer session may append to the store while you edit; the helper compares the store with the header under its lock and refuses on any difference, because such a record is absent from your sidecar and would otherwise be archived `pruned`. Then let the `/evolve` helper prune (`expires_at` < now OR `confidence` <= 0.0), consolidate duplicates (same `type` + `subject`, highest confidence wins), archive every removed record and rewrite the store with a `.bak-<ISO>` snapshot. The `--apply` call is also `/evolve`'s only `orchestrator.evolve.completed` emit (#1206): export `N` (new learnings from item 4), `M` (existing learnings confirmed in item 2) and `DURATION_MS` (elapsed ms since this `/evolve` run started) first — without them the event records zero counters. Preview first, then apply:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
NEXT=".orchestrator/tmp/learnings-next.jsonl"
|
|
108
|
+
node scripts/sweep-expired-learnings.mjs --prune --dry-run --json --entries "$NEXT" --repo-root "$(pwd)"
|
|
109
|
+
node scripts/sweep-expired-learnings.mjs --prune --apply --json --entries "$NEXT" \
|
|
110
|
+
--appended "${N:-0}" --boosted "${M:-0}" --duration-ms "${DURATION_MS:-0}" \
|
|
111
|
+
--repo-root "$(pwd)" && rm -f "$NEXT"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Exit `1` = the sidecar is absent, malformed, empty, lacks its line-1 header, or was snapshotted from another store than `--file`; `2` = the prune failed inside the helper. On `1` and `2`, report the error and stop — store and archive untouched. Exit `3` = the store changed after step 1, nothing written. Retry once: snapshot into a FRESH path (`--prune --snapshot .orchestrator/tmp/learnings-next-retry.jsonl`, same `--file` / `--archive` as the apply), re-apply this run's decisions to the records in that file, and run the block above with `NEXT` set to it; a second consecutive `3`: stop and report. Never move the fresh header onto the old sidecar's records — they lack the peer change the header protects. Never delete `$NEXT` by hand: the `&&` keeps it on failure as the record of this run's decisions.
|
|
107
115
|
|
|
108
116
|
Report: "Saved N new learnings, updated M existing. Total active: K."
|
|
109
117
|
|
|
@@ -140,7 +148,7 @@ Present as a numbered Markdown list (see Cursor Adaptation above):
|
|
|
140
148
|
|
|
141
149
|
### Step 3: Apply Changes
|
|
142
150
|
|
|
143
|
-
Same
|
|
151
|
+
Same pipeline as analyze mode Step 5, exit codes included: snapshot the store into the sidecar with `--prune --snapshot "$NEXT"`, modify the selected entries in the sidecar keeping its line-1 header (a deleted entry is simply left out of the sidecar — the helper archives it), then run `node scripts/sweep-expired-learnings.mjs --prune --dry-run --json --entries "$NEXT" --repo-root "$(pwd)"` followed by `--prune --apply --json --entries "$NEXT" --repo-root "$(pwd)"`.
|
|
144
152
|
|
|
145
153
|
Report: "Updated N learnings. Total active: K."
|
|
146
154
|
|
|
@@ -185,6 +193,7 @@ Each line in `.orchestrator/metrics/learnings.jsonl` is a JSON object:
|
|
|
185
193
|
|
|
186
194
|
```json
|
|
187
195
|
{
|
|
196
|
+
"schema_version": 1,
|
|
188
197
|
"id": "uuid-v4",
|
|
189
198
|
"type": "fragile-file|effective-sizing|recurring-issue|scope-guidance|deviation-pattern",
|
|
190
199
|
"subject": "identifier for the pattern",
|
|
@@ -192,11 +201,17 @@ Each line in `.orchestrator/metrics/learnings.jsonl` is a JSON object:
|
|
|
192
201
|
"evidence": "specific data points supporting the pattern",
|
|
193
202
|
"confidence": 0.5,
|
|
194
203
|
"source_session": "session-id",
|
|
204
|
+
"scope": "local",
|
|
205
|
+
"host_class": null,
|
|
206
|
+
"anonymized": false,
|
|
207
|
+
"file_paths": ["src/lib/auth.ts"],
|
|
195
208
|
"created_at": "2026-04-07T00:00:00Z",
|
|
196
209
|
"expires_at": "2026-05-07T00:00:00Z"
|
|
197
210
|
}
|
|
198
211
|
```
|
|
199
212
|
|
|
213
|
+
`schema_version` is the integer `1`. `scope` MUST be `local|private|public` — a file path belongs in `file_paths`, never in `scope` (GH#69). `expires_at` is derived per `type` via `deriveExpiresAt()` (`LEARNING_TTL_DAYS`).
|
|
214
|
+
|
|
200
215
|
### Confidence Lifecycle
|
|
201
216
|
|
|
202
217
|
| Event | Change |
|
|
@@ -225,8 +240,8 @@ Each line in `.orchestrator/metrics/learnings.jsonl` is a JSON object:
|
|
|
225
240
|
- NEVER skip deduplication (check `type` + `subject` match)
|
|
226
241
|
- NEVER write learnings without user confirmation
|
|
227
242
|
- ALWAYS use uuid-v4 for new learning IDs (generate via `uuidgen`)
|
|
228
|
-
- ALWAYS
|
|
229
|
-
- ALWAYS
|
|
243
|
+
- ALWAYS derive `expires_at` per type via `deriveExpiresAt()` unless the candidate supplies one
|
|
244
|
+
- ALWAYS write through `scripts/sweep-expired-learnings.mjs --prune` (snapshot, modify the sidecar keeping its header line, prune) — NEVER a shell rewrite of the store
|
|
230
245
|
- ALWAYS cap confidence at 1.0
|
|
231
246
|
- NEVER fabricate patterns -- only extract from actual session data with verifiable evidence
|
|
232
|
-
- NEVER append to `learnings.jsonl` with `>>` --
|
|
247
|
+
- NEVER append to `learnings.jsonl` with `>>` -- the only write is the prune helper's atomic tmp-file + rename, which keeps a `.bak-<ISO>` snapshot
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claude-md-drift-check
|
|
3
|
-
description: "Use when detecting drift between CLAUDE.md (or AGENTS.md, the Codex CLI alias) / _meta narrative and live repository state. Ten checks: absolute-path resolution, 01-projects/ count claims, issue-reference freshness, session-file existence, command-count sync, session-config-parity (mandatory template keys = error, opt-in gaps = warning), vault-dir-parity (CLAUDE.md vs AGENTS.md), generated-rule-staleness (WARN-only), rule-scoping (paths:/globs: frontmatter defects, dangling rule citations, zero-match globs), and docs-parity (docs/components.md count-claims vs on-disk counts, template-vs-reference config-key parity, stale .claude/metrics/ paths). Full per-check spec in the body table. Invoked as an opt-in session-end phase; mirrors vault-sync's lean JSON+exit-code contract."
|
|
3
|
+
description: "Use when detecting drift between CLAUDE.md (or AGENTS.md, the Codex CLI alias) / _meta narrative and live repository state. Ten checks: absolute-path resolution, 01-projects/ count claims, issue-reference freshness, session-file existence, command-count sync, session-config-parity (mandatory template keys = error, opt-in gaps = note, unknown local keys = warning), vault-dir-parity (CLAUDE.md vs AGENTS.md), generated-rule-staleness (WARN-only), rule-scoping (paths:/globs: frontmatter defects, dangling rule citations, zero-match globs), and docs-parity (docs/components.md count-claims vs on-disk counts, template-vs-reference config-key parity, stale .claude/metrics/ paths). Full per-check spec in the body table. Invoked as an opt-in session-end phase; mirrors vault-sync's lean JSON+exit-code contract."
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-audit
|
|
3
|
+
description: "Use when writing, reviewing, or pruning tests. Three modes, one value bar: a four-question gate before any new test is written, a focused audit of one scope, and a campaign over a whole repo or subsystem that removes the least useful tests under a coverage guard. Every delete, merge, or repair carries written evidence and a caught mutation. Triggered by \"audit the tests\", \"prune the test suite\", \"remove low-value tests\", \"test diet\", \"is this test worth adding\", /test-audit."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# test-audit
|
|
7
|
+
|
|
8
|
+
Canonical skill: `skills/test-audit/SKILL.md`
|
|
9
|
+
|
|
10
|
+
Read that file and follow it exactly. Resolve relative links against `skills/test-audit/`, not this wrapper.
|
|
11
|
+
|
|
12
|
+
Cursor has no Skill tool. Treat "invoke the test-audit skill" as: Read `skills/test-audit/SKILL.md`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "session-orchestrator",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "A repeatable Plan, Go, Close workflow for AI coding sessions: /session reads your repo and agrees the scope, /go runs the work in waves with a quality gate between each, /close verifies and commits. Runs on Claude Code, Codex CLI, Cursor and Pi.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bernhard Goetzendorfer"
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"pattern": "rm|mv|unlink .orchestrator (state dir) or .orchestrator/metrics/**",
|
|
134
134
|
"severity": "block",
|
|
135
135
|
"target-denylist": [".orchestrator", ".orchestrator/metrics", ".orchestrator/metrics/**"],
|
|
136
|
-
"rationale": "Deleting or renaming anything under .orchestrator/metrics/ destroys append-only session telemetry with no recovery path — the ledger IS the history, and nothing re-derives it. Measured 2026-09-19 (#1401): a wave subagent ran `touch .orchestrator/metrics/events.jsonl.1` (which ADOPTED the existing rotated ledger instead of creating a probe file), then `rm -f` on the same path — 53,896 lines / 10 MB covering 2026-04-12 to 2026-09-18 were gone, and the guard said nothing, because `rm` was only ever matched as the literal pattern `rm -rf`. Severity is `block`, not `warn`, on a measured absence of legitimate callers: rotation and ledger repair run through Node fs, never through Bash (`renameSync`/`unlinkSync` at scripts/lib/events-rotation.mjs:16,61,69,74), and a census of every shell rm/mv/unlink in scripts/, hooks/, .husky/, .gitlab-ci.yml and the guard's own 60-command test corpus found ZERO targeting this directory. Intentional maintenance has two named bypasses: `allow-destructive-ops: true` in Session Config (per session), or SO_DISABLED_HOOKS=pre-bash-destructive-guard (
|
|
136
|
+
"rationale": "Deleting or renaming anything under .orchestrator/metrics/ destroys append-only session telemetry with no recovery path — the ledger IS the history, and nothing re-derives it. Measured 2026-09-19 (#1401): a wave subagent ran `touch .orchestrator/metrics/events.jsonl.1` (which ADOPTED the existing rotated ledger instead of creating a probe file), then `rm -f` on the same path — 53,896 lines / 10 MB covering 2026-04-12 to 2026-09-18 were gone, and the guard said nothing, because `rm` was only ever matched as the literal pattern `rm -rf`. Severity is `block`, not `warn`, on a measured absence of legitimate callers: rotation and ledger repair run through Node fs, never through Bash (`renameSync`/`unlinkSync` at scripts/lib/events-rotation.mjs:16,61,69,74), and a census of every shell rm/mv/unlink in scripts/, hooks/, .husky/, .gitlab-ci.yml and the guard's own 60-command test corpus found ZERO targeting this directory. Intentional maintenance has two named bypasses: `allow-destructive-ops: true` in Session Config (per session), or SO_DISABLED_HOOKS=pre-bash-destructive-guard in the environment of the whole session (session-level: the hook reads it from its own process env, so a `SO_DISABLED_HOOKS=… rm …` prefix inside the command has no effect). Covers `rm`, `mv` (both operand roles — the source vanishes, an existing destination is overwritten) and `unlink`, through transparent wrappers (sudo/env/timeout/nohup/nice/…), every chain position, and literal `bash -c` / `env -S` / `eval` payloads. NAMED CEILING (BV-004), each measured: `find … -delete`, `find … -exec rm`, `… | xargs rm`, `git rm <path>` and in-process `node -e fs.unlinkSync(…)` are NOT covered — in each the path is not lexically an operand of a resolvable destructive verb (see PATH_DESTRUCTIVE_VERBS in scripts/lib/command-blocker.mjs). REVISIT TRIGGER: any of those five shapes appearing in a real deletion incident or a transcript census. `.orchestrator/tmp/**` is outside this denylist by construction, not by an exemption clause, and the match is judged PER TARGET — a sibling tmp operand can never lift the verdict for a metrics operand. SPELLING CEILING (measured 2026-09-19 against this hook, one payload per row): the #1401 incident was an agent re-spelling a blocked command, so the four re-spellings were run back through the guard. Two were closed HERE by adding the exact entry `.orchestrator` to the denylist above — `rm -r .orchestrator` (ALLOW before: only the literal `rm -rf` pattern of `rm-rf-destructive` caught the -rf form, and `rm -r` is one character shorter) and `mv .orchestrator /tmp/x` (ALLOW before). That entry is EXACT, not a prefix: `.orchestrator/tmp/**` deletes stay ALLOW, re-measured after the change (`rm -rf .orchestrator/tmp/*`, `rm -rf .orchestrator/tmp`, `rm -f .orchestrator/tmp/scratch.json` → all ALLOW), so the widening adds no exemption clause that could be lifted. Three remain OPEN and are DECLARED, not papered over: (0) a TRAILING SLASH on the state dir — `rm -r .orchestrator/` → ALLOW (measured 2026-09-19, found while re-measuring this change): the operand keeps its slash and the exact entry `.orchestrator` does not match it, while a `.orchestrator/` entry would be read as a DIRECTORY-PREFIX glob (measured: `pathMatchesPattern('.orchestrator/tmp/x', '.orchestrator/') === true`) and would swallow the tmp exemption — so the fix belongs in operand normalisation in scripts/lib/command-blocker.mjs, never in this list; (1) a wildcard in a DIRECTORY segment — `rm -f .orchestrator/*/events.jsonl` — because the guard is lexical and never expands globs, so the operand it sees is the literal string `.orchestrator/*/events.jsonl`, which no concrete-path glob in this denylist matches; (2) a cwd-changing chain — `cd .orchestrator/metrics && rm -f events.jsonl` — because the guard does not track cwd across chain segments and the operand it sees is the bare `events.jsonl`. Closing either needs glob expansion or cwd tracking in scripts/lib/command-blocker.mjs, i.e. a matcher change, not a policy change. REVISIT TRIGGER for these two: either form appearing in a real deletion incident or a transcript census — or any widening of this denylist beyond exact paths, which would need a per-verb exemption for `.orchestrator/tmp/**` bound to the statement the matcher hit (widening without narrowing the bypass opens a hole the narrow form did not have, `.claude/rules/guard-design.md`).",
|
|
137
137
|
"sources": ["#1401", "PSA-003"]
|
|
138
138
|
}
|
|
139
139
|
]
|
package/AGENTS.md
CHANGED
|
@@ -12,13 +12,11 @@
|
|
|
12
12
|
> - **Session narrative** (machine-written by session-end Phase 3.7 via `scripts/lib/vault-status/narrative-mirror.mjs`) → `01-projects/session-orchestrator/_session-narrative.md`
|
|
13
13
|
> - **Operator tmux side-channel** → `/tmux-layout` (4-pane: STATE.md/CI-watch/events; [ADR-0007](docs/adr/0007-tmux-visualization-substrate.md))
|
|
14
14
|
>
|
|
15
|
-
> Additive instruction-file layering: this root for the big picture, nested files (`.claude/rules/*.md`) for local conventions; the authoring spec lives in `docs/agent-authoring.md`.
|
|
16
|
-
>
|
|
17
15
|
> **Root `AGENTS.md` is GENERATED byte-identical from this file** (`node scripts/generate-agents-skills.mjs`) for harnesses that read only `AGENTS.md` (Codex CLI, OpenCode, Kiro, Cursor's AGENTS path). Never edit it; edit here and regenerate. `validate-plugin` fails on drift.
|
|
18
16
|
|
|
19
17
|
## Current State <!-- consistency:exempt:lean-root-pointer-section -->
|
|
20
18
|
|
|
21
|
-
State-free by design (see the **Live state is not in this file** gotcha below)
|
|
19
|
+
State-free by design (see the **Live state is not in this file** gotcha below) — SSOTs:
|
|
22
20
|
- **Version + test/coverage** → README badges
|
|
23
21
|
- **Per-session metrics & history** → [`.orchestrator/metrics/sessions.jsonl`](./.orchestrator/metrics/sessions.jsonl)
|
|
24
22
|
- **Decisions** (hand-authored) → [[01-projects/session-orchestrator/decisions]] (Meta-Vault) · **Session narrative** (generated) → `_session-narrative.md` beside it
|
|
@@ -27,36 +25,16 @@ State-free by design (see the **Live state is not in this file** gotcha below).
|
|
|
27
25
|
|
|
28
26
|
These are the non-obvious, mistake-causing facts that must load every session. Everything else is delegated above.
|
|
29
27
|
|
|
30
|
-
- **CI status is the source of truth at session-start
|
|
31
|
-
|
|
32
|
-
Never claim CI green from `npm test` alone — the 8-pipeline silent regression (2026-05-09 → 2026-05-10, fixed in deep-2) is the cautionary tale. <!-- consistency:exempt:runtime-only -->
|
|
33
|
-
- **Destructive-Command Guard is active in main + subagent waves on harnesses with a compatible command hook.** On Claude Code, and through the supported Cursor and Pi bridges, `hooks/pre-bash-destructive-guard.mjs` applies `.orchestrator/policy/blocked-commands.json`:
|
|
34
|
-
**12 of its 16 rules are `severity: block`, the other 4 only warn** (measured 2026-09-19: `jq '[.rules[].severity]|group_by(.)|map({(.[0]):length})|add' .orchestrator/policy/blocked-commands.json`).
|
|
35
|
-
The 16th is `ledger-delete-protected` (#1401): `rm`/`mv`/`unlink` on `.orchestrator/metrics/**` — added after a wave agent deleted a rotated 53.896-line ledger archive that no rule covered, because `rm` existed only as the pattern `rm -rf` and the redirect denylist's `*.jsonl` did not match `events.jsonl.1`.
|
|
36
|
-
On Codex, the destructive-command rules are instructions only because no compatible `PreToolUse` command handler is wired. Rule source of truth: [`.claude/rules/parallel-sessions.md`](.claude/rules/parallel-sessions.md) (PSA-003). Per-session bypass via Session Config: `allow-destructive-ops: true` (intentional maintenance only).
|
|
28
|
+
- **CI status is the source of truth at session-start** — never claim CI green from `npm test` alone (8-pipeline silent regression 2026-05-09 → 2026-05-10, fixed in deep-2); Phase 4 🚨 banner `checkCiStatus({ repoRoot })` in `scripts/lib/ci-status-banner.mjs`; see `skills/session-start/references/phase-4-ssot-environment-check.md` (incident: ADR-0006). <!-- consistency:exempt:runtime-only -->
|
|
29
|
+
- **Destructive-Command Guard** (`hooks/pre-bash-destructive-guard.mjs`, `.orchestrator/policy/blocked-commands.json`: 12 block / 4 warn of 16 rules) is live on Claude Code + Cursor/Pi bridges, instruction-only on Codex. PSA-003 (`parallel-sessions.md`); bypass `allow-destructive-ops: true`; long form incl. #1401: `docs/session-config-reference.md`. <!-- consistency:exempt:runtime-only -->
|
|
37
30
|
- **Session Config below is runtime-critical.** `scripts/parse-config.mjs` parses the `## Session Config` block; `claude-md-drift-check` Check 6 enforces top-level-key parity against `docs/session-config-template.md`. Edit it like code, not prose — a dropped key changes runtime behaviour.
|
|
38
31
|
- **Live state is not in this file.** Stack: Node 24+, vitest, ESLint 10 (`npm ci` after clone). Test counts, backlog, version, component inventory drift fast — the SSOT is README badges + `.orchestrator/metrics/sessions.jsonl`. Per-session detail lives in the Meta-Vault decisions log (linked above), not here.
|
|
39
|
-
- **`memory.propose` requires `SO_WAVE_AGENT=1
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
Detection therefore tries the `.orchestrator/promoted-from.json` marker `enterWorktree()` writes at creation time FIRST (`source: 'marker'` — carries the source session id + branch, survives the process boundary), falling back to the legacy `path.basename(repoRoot) === <repo-name>-<sessionId>` basename match (`source: 'basename'`) only for worktrees created before the marker existed.
|
|
46
|
-
Clean worktree → auto-remove with WARN. Dirty (uncommitted/untracked/unpushed) → AUQ `[Behalten/Löschen/Manuell]` (`isWorktreeClean()` discounts exactly the marker's own untracked line, never operator work).
|
|
47
|
-
The Phase 4a cleanup runs AFTER Phase 4 commit+push, not before — this respects #490 durableCommit ordering so sessions.jsonl + STATE.md are persisted to origin BEFORE worktree-removal.
|
|
48
|
-
PSA-003 compliance enforced. Implementation: `skills/session-end/references/phase-4a-worktree-cleanup.md`; process-boundary rationale: `docs/adr/0013-worktree-promotion-process-boundary.md`. <!-- consistency:exempt:runtime-only -->
|
|
49
|
-
- **`allowedPaths` is COMPUTED, and the scope declaration has TWO shapes — writing only one is the silent failure (#1020).**
|
|
50
|
-
(a) **Per agent**, `<state-dir>/filescopes/wave-<N>/<agent-id>.json`, a JSON array of path STRINGS. This is `$AGENT_FILESCOPE_JSON` — what the `FILE-SCOPE` prompt injection, the Learnings-Index and `--assert-subset` read.
|
|
51
|
-
(b) **Per wave**, ONE aggregate sidecar holding an array of `{id, files}` RECORDS, built from every file in (a) plus the coordinator's own. This is the only thing `--assert-disjoint` and `--union` accept: pass them the wave directory and you get `Cannot read --union file`; pass them a single (a)-file and you get `must be a JSON array of {id, files} records`.
|
|
52
|
-
`node scripts/materialize-wave-scope.mjs --state-dir <state-dir> --wave <N>` is the canonical writer: it receives that one record array on stdin, writes every (a) file first, then (b) last. Neither is a `$TMPDIR` copy, and neither substitutes for the other.
|
|
53
|
-
Skipping (a) degrades the chain to signal-free ALLOW: no `FILE-SCOPE` block reaches the prompt, so `hooks/pre-task-scope-disjoint.mjs` extracts nothing, permits the dispatch, and writes no ledger entry — the absence looks identical to a clean run.
|
|
54
|
-
**Measured 2026-08-19:** a coordinator that wrote only (b) ran SIX waves and ~27 dispatches with zero injection; `.orchestrator/wave-dispatch-scopes.json` still carried a `|w2|` entry from two days earlier. Only `wave-scope.json` `allowedPaths` (global Gate 7) was live, which is why blocks still fired and the gap stayed invisible.
|
|
55
|
-
The coordinator's OWN direct edits go in a `coordinator.json` under (a) **and must be folded into (b)** — a `coordinator.json` that is never folded in is read by nothing. 2 of the 5 recorded divergences were coordinator-direct edits, which no agent scope file covers by construction.
|
|
56
|
-
Mechanism, error-class matrix and named limits: [`docs/scope-collision-guard.md`](docs/scope-collision-guard.md); the authoritative two-stage procedure is `skills/wave-executor/references/wave-loop-scope-manifest.md` § 3.1/3.2. <!-- consistency:exempt:runtime-only -->
|
|
57
|
-
- **`vault-dir` resolves HOST-LOCALLY — a hand-run vault probe writes into the operator's REAL vault.** Precedence is `SO_VAULT_DIR` > `owner.yaml` `paths.vault-dir` > the committed `vault-integration.vault-dir` below (`scripts/lib/config/host-paths.mjs`); the literal value in this file LOSES against both.
|
|
58
|
-
So a throwaway invocation of a vault writer (`mirrorNarrative()`, `vault-mirror.mjs`, the board writer) with a synthetic `repoRoot` does **not** land in a sandbox — the fake repo path only fakes the SOURCE, never the DESTINATION. A reviewer in this repo walked into exactly that.
|
|
59
|
-
Export `SO_VAULT_DIR=<tmpdir>` before ANY manual invocation of vault-writing code. <!-- consistency:exempt:runtime-only -->
|
|
32
|
+
- **`memory.propose` requires `SO_WAVE_AGENT=1`** — `scripts/memory-propose.mjs` exits 3 from the coordinator thread (use `/evolve`); wave-executor sets it per dispatched agent. Statuses: queued 0 · dry-run-ok 0 · quota-exceeded 1 · rejected-low-confidence 2 · rejected-wrong-context 3 · error 4 — `docs/session-config-reference.md` § Memory Proposals. <!-- consistency:exempt:runtime-only -->
|
|
33
|
+
- **Auto-promoted worktree cleanup keys on the `.orchestrator/promoted-from.json` marker, not on session-id coincidence (#1069)** — promotion is a process boundary (ADR-0013), so `detectAutoPromotedWorktree()` tries the marker first (`source: 'marker'`) and falls back to the `<repo>-<sessionId>` basename only for pre-marker worktrees.
|
|
34
|
+
`/close` Phase 4a runs AFTER Phase 4 commit+push (#490): clean → auto-remove with WARN, dirty → AUQ `[Behalten/Löschen/Manuell]`; Hybrid Pattern (Anthropic-style, ADR-0008), PSA-003. Long form: `skills/session-end/references/phase-4a-worktree-cleanup.md`. <!-- consistency:exempt:runtime-only -->
|
|
35
|
+
- **`allowedPaths` is COMPUTED, and the scope declaration has TWO shapes — writing only one is the silent failure (#1020).** (a) per-agent `<state-dir>/filescopes/wave-<N>/<agent-id>.json` (path strings = `$AGENT_FILESCOPE_JSON`: FILE-SCOPE injection, Learnings-Index, `--assert-subset`); (b) per-wave `{id, files}` records, the only input of `--assert-disjoint`/`--union`.
|
|
36
|
+
`node scripts/materialize-wave-scope.mjs --state-dir <state-dir> --wave <N>` writes both; fold `coordinator.json` into (b). Skipping (a) = signal-free ALLOW (2026-08-19: six waves, ~27 dispatches, zero injection). Long form: `docs/scope-collision-guard.md` § The two-shape trap; `skills/wave-executor/references/wave-loop-scope-manifest.md` § 3.1/3.2. <!-- consistency:exempt:runtime-only -->
|
|
37
|
+
- **`vault-dir` resolves HOST-LOCALLY** (`SO_VAULT_DIR` > `owner.yaml` > committed `vault-integration.vault-dir`, `scripts/lib/config/host-paths.mjs`) — a hand-run vault writer with a synthetic `repoRoot` still writes into the REAL vault; export `SO_VAULT_DIR=<tmpdir>` before any manual invocation. Detail: `docs/session-config-reference.md` (#1448). <!-- consistency:exempt:runtime-only -->
|
|
60
38
|
|
|
61
39
|
## Session Config
|
|
62
40
|
|