session-orchestrator 5.12.0 → 5.13.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +4 -1
- package/.codex-plugin/agents/explorer.toml +1 -1
- package/.codex-plugin/agents/session-reviewer.toml +2 -2
- package/.codex-plugin/agents/wave-worker.toml +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/.orchestrator/policy/blocked-commands.json +8 -0
- package/.orchestrator/policy/public-export.json +30 -0
- package/CHANGELOG.md +162 -4
- package/README.md +126 -127
- package/agents/analyst.md +7 -2
- package/agents/architect-reviewer.md +7 -2
- package/agents/code-implementer.md +4 -2
- package/agents/db-specialist.md +9 -2
- package/agents/dialectic-deriver.md +9 -3
- package/agents/docs-writer.md +7 -2
- package/agents/eval-judge.md +7 -1
- package/agents/qa-strategist.md +7 -2
- package/agents/security-reviewer.md +9 -2
- package/agents/session-reviewer.md +18 -2
- package/agents/skill-applied-judge.md +7 -1
- package/agents/test-writer.md +9 -2
- package/agents/ui-developer.md +9 -2
- package/agents/ux-evaluator.md +6 -1
- package/commands/session.md +1 -1
- package/commands/templates-ack.md +89 -18
- package/docs/agent-authoring.md +30 -11
- package/docs/ci-setup.md +38 -2
- package/docs/codex-setup.md +33 -9
- package/docs/components.md +13 -2
- package/docs/cursor-setup.md +3 -3
- package/docs/events-schema.md +5 -4
- package/docs/evidence-candidates.md +63 -0
- package/docs/fleet-checkin-audit.md +7 -4
- package/docs/github-mirror-protection.md +150 -3
- package/docs/install.md +90 -17
- package/docs/instruction-delivery.md +1 -1
- package/docs/migration-v4.md +2 -2
- package/docs/mods.md +118 -0
- package/docs/owner-config-schema.md +1 -0
- package/docs/plugin-architecture-v3.md +1 -1
- package/docs/pm-skills-marketplace.md +4 -3
- package/docs/rule-authoring.md +24 -13
- package/docs/scope-collision-guard.md +2 -1
- package/docs/session-config-reference.md +49 -15
- package/docs/session-config-template.md +30 -22
- package/docs/sessions-ledger-repair.md +137 -0
- package/docs/vault-docs-architecture.md +1 -1
- package/hooks/_lib/hook-import-set.json +406 -73
- package/hooks/_lib/hook-root.mjs +301 -0
- package/hooks/_lib/lock-bootstrap.mjs +434 -4
- package/hooks/_lib/orchestrator-ignore.mjs +3 -0
- package/hooks/_lib/subagent-transcript.mjs +2 -2
- package/hooks/_lib/vcs-create-matcher.mjs +13 -17
- package/hooks/cwd-change-restore.mjs +5 -1
- package/hooks/enforce-commands.mjs +4 -3
- package/hooks/enforce-scope.mjs +11 -1
- package/hooks/hooks-codex.json +48 -2
- package/hooks/hooks.json +31 -31
- package/hooks/on-session-end.mjs +38 -15
- package/hooks/on-session-start.mjs +139 -49
- package/hooks/on-stop.mjs +11 -6
- package/hooks/post-bash-issue-budget-refund.mjs +6 -1
- package/hooks/post-bash-write-verify.mjs +8 -4
- package/hooks/post-edit-validate.mjs +45 -52
- package/hooks/post-subagent-discovery-validator.mjs +2 -2
- package/hooks/post-tool-batch-wave-signal.mjs +8 -4
- package/hooks/post-tool-failure-corrective-context.mjs +5 -1
- package/hooks/pre-bash-destructive-guard.mjs +220 -8
- package/hooks/pre-bash-issue-budget.mjs +6 -1
- package/hooks/pre-bash-sessions-ledger-guard.mjs +691 -123
- package/hooks/pre-bash-staging-fence.mjs +258 -14
- package/hooks/pre-bash-templates-first.mjs +28 -27
- package/hooks/run-node.sh +1 -1
- package/hooks/skill-invocation-telemetry.mjs +15 -8
- package/hooks/subagent-telemetry.mjs +77 -14
- package/hooks/wave-scope-commit-guard.mjs +143 -14
- package/mods/so-hud/.claude-plugin/plugin.json +11 -0
- package/mods/so-hud/README.md +57 -0
- package/mods/so-hud/hooks/beacon-io.mjs +101 -0
- package/mods/so-hud/hooks/heredoc-scan.ts +394 -0
- package/mods/so-hud/hooks/hooks.json +1 -0
- package/mods/so-hud/hooks/logic.ts +182 -0
- package/mods/so-hud/hooks/register.tsx +670 -0
- package/mods/so-hud/hooks/rules.ts +2998 -0
- package/mods/so-hud/tsconfig.json +8 -0
- package/mods/so-hud/types/index.d.ts +36 -0
- package/package.json +4 -2
- package/rules/_index.md +1 -1
- package/rules/always-on/ask-via-tool.md +1 -1
- package/rules/always-on/loop-and-monitor.md +17 -194
- package/rules/always-on/parallel-sessions.md +3 -1
- package/rules/opt-in-stack/backend-data.md +1 -1
- package/rules/opt-in-stack/backend.md +1 -1
- package/rules/opt-in-stack/security-web.md +5 -1
- package/scripts/agent-usage-census.mjs +79 -0
- package/scripts/apply-session-learnings.mjs +34 -6
- package/scripts/archive-closed-prds.mjs +21 -5
- package/scripts/autopilot.mjs +11 -5
- package/scripts/backfill-abandoned-sessions.mjs +13 -3
- package/scripts/backfill-evidence-digest.mjs +2 -1
- package/scripts/backfill-learnings-from-vault.mjs +61 -6
- package/scripts/backfill-sessions.mjs +16 -2
- package/scripts/check-package-manager.mjs +26 -8
- package/scripts/check-sessions-integrity.mjs +4 -1
- package/scripts/ci/assert-vitest-green.mjs +3 -0
- package/scripts/ci/windows-smoke.mjs +201 -0
- package/scripts/close-precheck.mjs +55 -0
- package/scripts/dialectic-deriver.mjs +20 -12
- package/scripts/emit-event.mjs +2 -2
- package/scripts/emit-session.mjs +239 -20
- package/scripts/eval-session.mjs +17 -3
- package/scripts/export-hw-learnings.mjs +29 -2
- package/scripts/fleet-checkin-audit.mjs +8 -4
- package/scripts/fleet-checkin.mjs +39 -27
- package/scripts/gc-stale-worktrees.mjs +6 -1
- package/scripts/github-export.mjs +128 -0
- package/scripts/github-protection-audit.mjs +3 -1
- package/scripts/handover-queue-check.mjs +209 -0
- package/scripts/harness-audit.mjs +6 -4
- package/scripts/lib/agent-frontmatter.mjs +57 -10
- package/scripts/lib/agent-status.mjs +125 -7
- package/scripts/lib/agent-usage-census.mjs +394 -0
- package/scripts/lib/auto-dialectic.mjs +17 -10
- package/scripts/lib/auto-dream.mjs +22 -14
- package/scripts/lib/autopilot/loop.mjs +3 -1
- package/scripts/lib/autopilot/recent-runs.mjs +4 -2
- package/scripts/lib/autopilot/stall-sampler.mjs +2 -1
- package/scripts/lib/autopilot/telemetry.mjs +5 -1
- package/scripts/lib/autopilot/worktree-pipeline.mjs +5 -5
- package/scripts/lib/baseline-archetypes.mjs +10 -2
- package/scripts/lib/blocked-commands-policy.mjs +4 -3
- package/scripts/lib/build-live-signals.mjs +13 -9
- package/scripts/lib/ci-status-banner.mjs +329 -24
- package/scripts/lib/codex/plugin-contract.mjs +8 -0
- package/scripts/lib/cold-start-detector.mjs +5 -2
- package/scripts/lib/command-blocker.mjs +603 -43
- package/scripts/lib/common.mjs +3 -2
- package/scripts/lib/config/cross-repo.mjs +74 -7
- package/scripts/lib/config/host-paths.mjs +6 -2
- package/scripts/lib/config/section-extractor.mjs +65 -11
- package/scripts/lib/config/template-keys.mjs +153 -0
- package/scripts/lib/config/vault-integration.mjs +1 -0
- package/scripts/lib/config.mjs +2 -2
- package/scripts/lib/coordinator-snapshot.mjs +1 -1
- package/scripts/lib/discovery/triage-state.mjs +2 -1
- package/scripts/lib/dispatcher/rank.mjs +5 -7
- package/scripts/lib/ecosystem-health.mjs +2 -2
- package/scripts/lib/eval/engine.mjs +3 -2
- package/scripts/lib/eval/session-resolve.mjs +6 -2
- package/scripts/lib/eval/sink.mjs +4 -3
- package/scripts/lib/events-retention-banner.mjs +3 -2
- package/scripts/lib/events-schema.mjs +10 -0
- package/scripts/lib/events.mjs +23 -12
- package/scripts/lib/evolve/autonomy-verdict.mjs +4 -9
- package/scripts/lib/evolve/autopilot-effectiveness.mjs +8 -18
- package/scripts/lib/fleet-protocol.mjs +4 -0
- package/scripts/lib/gates/gate-full.mjs +172 -11
- package/scripts/lib/gates/gate-helpers.mjs +236 -23
- package/scripts/lib/git-config-drift.mjs +141 -7
- package/scripts/lib/github-export.mjs +447 -0
- package/scripts/lib/gitlab-portfolio/cli.mjs +16 -5
- package/scripts/lib/handover-queue-marks.mjs +159 -0
- package/scripts/lib/hardware-pattern-detector.mjs +103 -13
- package/scripts/lib/harness-audit/categories/category1.mjs +16 -4
- package/scripts/lib/harness-audit/categories/category4.mjs +11 -8
- package/scripts/lib/harness-audit/categories/category6.mjs +25 -5
- package/scripts/lib/harness-audit/categories/category9.mjs +10 -4
- package/scripts/lib/host-identity.mjs +9 -5
- package/scripts/lib/http-request.mjs +64 -0
- package/scripts/lib/instruction-budget-guard.mjs +30 -22
- package/scripts/lib/io.mjs +6 -3
- package/scripts/lib/issue-budget-reconcile.mjs +3 -2
- package/scripts/lib/issue-budget.mjs +36 -7
- package/scripts/lib/learnings/evidence-candidates.mjs +154 -0
- package/scripts/lib/learnings/expiry-sweep.mjs +99 -7
- package/scripts/lib/learnings/io.mjs +289 -15
- package/scripts/lib/learnings/select.mjs +53 -4
- package/scripts/lib/learnings/store-role.mjs +209 -0
- package/scripts/lib/learnings/surface.mjs +46 -7
- package/scripts/lib/ledger-path.mjs +113 -0
- package/scripts/lib/maintenance-due-banner.mjs +63 -12
- package/scripts/lib/memory-banner.mjs +5 -6
- package/scripts/lib/memory-proposals/collector.mjs +5 -2
- package/scripts/lib/memory-proposals/sink.mjs +7 -4
- package/scripts/lib/memory-proposals/store.mjs +22 -5
- package/scripts/lib/mode-selector-accuracy.mjs +2 -1
- package/scripts/lib/no-follow-open.mjs +57 -0
- package/scripts/lib/orphan-reaper/reaper-audit.mjs +4 -2
- package/scripts/lib/own-lock-root.mjs +95 -0
- package/scripts/lib/owner-interview.mjs +2 -1
- package/scripts/lib/owner-yaml.mjs +70 -7
- package/scripts/lib/platform.mjs +161 -9
- package/scripts/lib/plugin-update-banner.mjs +15 -11
- package/scripts/lib/pre-push-local-partial.mjs +117 -0
- package/scripts/lib/pre-push-remote-gate.mjs +151 -25
- package/scripts/lib/process-group.mjs +270 -34
- package/scripts/lib/project-hygiene.mjs +28 -0
- package/scripts/lib/quality-gate.mjs +33 -9
- package/scripts/lib/reconcile/backlog.mjs +29 -15
- package/scripts/lib/reconcile/engine.mjs +26 -2
- package/scripts/lib/reconcile/idempotency.mjs +65 -3
- package/scripts/lib/reconcile/rule-expiry-sweep.mjs +53 -12
- package/scripts/lib/reconcile/verdict-ledger.mjs +224 -0
- package/scripts/lib/reconcile-nudge-banner.mjs +40 -6
- package/scripts/lib/resource-probe/evaluate.mjs +32 -9
- package/scripts/lib/resource-probe/probe-platform.mjs +3 -1
- package/scripts/lib/rule-loader.mjs +20 -10
- package/scripts/lib/scope-baseline.mjs +123 -8
- package/scripts/lib/scope-echo.mjs +5 -2
- package/scripts/lib/scope-gate.mjs +55 -20
- package/scripts/lib/session-close-backfill.mjs +75 -7
- package/scripts/lib/session-end/close-precheck.mjs +151 -0
- package/scripts/lib/session-end/phase-skip.mjs +8 -7
- package/scripts/lib/session-end/tail-runner.mjs +7 -2
- package/scripts/lib/session-id.mjs +9 -1
- package/scripts/lib/session-identity/own-session.mjs +63 -0
- package/scripts/lib/session-lock.mjs +114 -0
- package/scripts/lib/session-record-repair.mjs +245 -35
- package/scripts/lib/session-registry.mjs +72 -9
- package/scripts/lib/session-schema/constants.mjs +9 -0
- package/scripts/lib/session-schema/filters.mjs +56 -1
- package/scripts/lib/session-schema/validator.mjs +15 -5
- package/scripts/lib/session-start-probes.mjs +149 -22
- package/scripts/lib/session-token-rollup.mjs +2 -1
- package/scripts/lib/session-work-trees.mjs +166 -0
- package/scripts/lib/sessions-canonical.mjs +61 -3
- package/scripts/lib/sessions-integrity-banner.mjs +17 -39
- package/scripts/lib/sessions-staleness-banner.mjs +8 -5
- package/scripts/lib/sh-quote.mjs +1 -0
- package/scripts/lib/skill-evidence-window.mjs +5 -1
- package/scripts/lib/skill-health/join.mjs +10 -9
- package/scripts/lib/skill-invocations-schema.mjs +13 -0
- package/scripts/lib/skill-judgments-schema.mjs +6 -2
- package/scripts/lib/snapshot-probe.mjs +414 -0
- package/scripts/lib/so-hud/collect.mjs +49 -5
- package/scripts/lib/so-hud/runtime.mjs +15 -4
- package/scripts/lib/spiral-carryover.mjs +8 -1
- package/scripts/lib/state-md/frontmatter-mutators.mjs +266 -8
- package/scripts/lib/state-md/idle-reset.mjs +14 -5
- package/scripts/lib/state-md/mission-status.mjs +5 -1
- package/scripts/lib/state-md-peer-guard.mjs +2 -0
- package/scripts/lib/state-md.mjs +31 -8
- package/scripts/lib/sunset/walker.mjs +4 -3
- package/scripts/lib/telemetry/consent.mjs +4 -2
- package/scripts/lib/telemetry/queue.mjs +3 -3
- package/scripts/lib/telemetry/sync.mjs +45 -9
- package/scripts/lib/test-runner/artifact-paths.mjs +10 -2
- package/scripts/lib/tmux-layout/layouts.mjs +20 -3
- package/scripts/lib/ux-grill/paths.mjs +5 -1
- package/scripts/lib/validate/check-agents.mjs +37 -6
- package/scripts/lib/validate/check-component-paths.mjs +25 -1
- package/scripts/lib/validate/check-guard-requires-parity.mjs +3 -3
- package/scripts/lib/validate/check-hooks-symmetry.mjs +53 -32
- package/scripts/lib/validate/check-json-files.mjs +3 -1
- package/scripts/lib/validate/check-learning-provenance.mjs +3 -2
- package/scripts/lib/validate/check-learnings-shell-writes.mjs +10 -4
- package/scripts/lib/validate/check-metrics-ledger-root.mjs +234 -0
- package/scripts/lib/validate/check-owner-leakage.mjs +159 -11
- package/scripts/lib/validate/check-test-posix-shell.mjs +246 -0
- package/scripts/lib/validate/check-unwired-features.mjs +4 -2
- package/scripts/lib/validate/check-vcs-repo-flag-positional.mjs +58 -0
- package/scripts/lib/validate/check-vcs-repo-flag.mjs +259 -73
- package/scripts/lib/validate/check-workflow-continue-on-error.mjs +63 -0
- package/scripts/lib/validate/confidential-names.mjs +3 -1
- package/scripts/lib/vault-mirror/migrate-ids.mjs +321 -0
- package/scripts/lib/vault-mirror/namespace.mjs +19 -7
- package/scripts/lib/vault-mirror/process.mjs +56 -27
- package/scripts/lib/vault-mirror/prune.mjs +5 -2
- package/scripts/lib/vault-mirror/render-learnings.mjs +3 -3
- package/scripts/lib/vault-mirror/render-sessions.mjs +36 -53
- package/scripts/lib/vault-mirror/retention.mjs +2 -2
- package/scripts/lib/vault-mirror/utils.mjs +79 -0
- package/scripts/lib/vault-staleness-banner.mjs +4 -7
- package/scripts/lib/vault-status/board-writer.mjs +2 -1
- package/scripts/lib/vault-status/narrative-mirror.mjs +66 -7
- package/scripts/lib/wave-executor/foreign-dispatch.mjs +20 -0
- package/scripts/lib/win-process-tree.mjs +137 -0
- package/scripts/lib/workspace.mjs +1 -1
- package/scripts/lib/worktree/constants.mjs +1 -1
- package/scripts/lib/worktree/lifecycle.mjs +1 -1
- package/scripts/lib/worktree/listing.mjs +1 -1
- package/scripts/lib/zx.mjs +50 -0
- package/scripts/mcp-server.mjs +16 -7
- package/scripts/mcp-server.sh +13 -83
- package/scripts/measure-policy-cache-effectiveness.mjs +7 -5
- package/scripts/memory-propose.mjs +10 -3
- package/scripts/migrate-cold-start-seed.mjs +7 -0
- package/scripts/migrate-legacy-learnings.sh +22 -0
- package/scripts/migrate-sessions-jsonl.mjs +16 -2
- package/scripts/migrate-vault-paths.mjs +29 -13
- package/scripts/parse-config.mjs +71 -14
- package/scripts/print-learnings-index.mjs +25 -2
- package/scripts/release-session-lock.mjs +94 -7
- package/scripts/release.mjs +451 -24
- package/scripts/relocate-vault-corpus.mjs +11 -7
- package/scripts/repair-invalid-sessions.mjs +68 -3
- package/scripts/resolve-session-invocation.mjs +10 -17
- package/scripts/run-migrate-v2-cross-repo.mjs +56 -1
- package/scripts/run-quality-gate.mjs +33 -7
- package/scripts/self-update.mjs +56 -7
- package/scripts/session-commit-files.mjs +133 -0
- package/scripts/site-numbers.mjs +52 -9
- package/scripts/snapshot-probe.mjs +156 -0
- package/scripts/so-hud.mjs +29 -6
- package/scripts/state-md-idle-reset.mjs +2 -1
- package/scripts/sweep-expired-learnings.mjs +54 -6
- package/scripts/sweep-expired-rules.mjs +4 -1
- package/scripts/validate-plugin.mjs +22 -0
- package/scripts/vault-integration-watcher.mjs +54 -6
- package/scripts/vault-mirror.mjs +9 -0
- package/skills/_shared/fleet-protocol.md +142 -1
- package/skills/_shared/instruction-file-resolution.md +1 -1
- package/skills/_shared/monitor-patterns.md +44 -25
- package/skills/_shared/platform-tools.md +7 -0
- package/skills/_shared/state-ownership.md +3 -2
- package/skills/architecture/references/domain-model.md +1 -1
- package/skills/bootstrap/SKILL.md +3 -1
- package/skills/bootstrap/_shared-template.md +4 -4
- package/skills/bootstrap/fast-template.md +1 -1
- package/skills/bootstrap/private-contract.md +1 -1
- package/skills/bootstrap/references/bootstrap-retroactive-flow.md +17 -9
- package/skills/bootstrap/templates/agents/project-code-review.md +5 -1
- package/skills/bootstrap/templates/agents/project-discovery.md +5 -1
- package/skills/bootstrap/templates/agents/project-quality-gate.md +5 -1
- package/skills/claude-md-drift-check/SKILL.md +3 -3
- package/skills/claude-md-drift-check/checker.mjs +61 -101
- package/skills/close/SKILL.md +20 -7
- package/skills/discovery/probes/docs-staleness.mjs +7 -5
- package/skills/discovery/probes/frontend-slop.mjs +7 -3
- package/skills/discovery/probes/ssot-code-diff.mjs +5 -3
- package/skills/discovery/probes/supply-chain-slopcheck.mjs +10 -8
- package/skills/discovery/probes/vault-narrative-staleness.mjs +30 -10
- package/skills/discovery/probes/vault-staleness.mjs +5 -3
- package/skills/discovery/probes-session.md +3 -0
- package/skills/discovery/probes-vault.md +2 -0
- package/skills/dispatcher/SKILL.md +1 -1
- package/skills/eval/SKILL.md +3 -1
- package/skills/evolve/SKILL.md +2 -0
- package/skills/evolve/references/evolve-analyze-mode.md +3 -3
- package/skills/evolve/references/evolve-dialectic-mode.md +1 -1
- package/skills/gitlab-ops/SKILL.md +7 -6
- package/skills/gitlab-portfolio/SKILL.md +2 -2
- package/skills/go/SKILL.md +13 -1
- package/skills/npm-publish/SKILL.md +5 -2
- package/skills/plan/SKILL.md +23 -10
- package/skills/plan/mode-feature.md +13 -8
- package/skills/plan/mode-new.md +6 -14
- package/skills/plan/prd-feature-template.md +19 -0
- package/skills/plan/prd-full-template.md +12 -5
- package/skills/plan/prd-premortem-panel.md +48 -0
- package/skills/plan/prd-reviewer-prompt.md +11 -3
- package/skills/plan/soul.md +1 -1
- package/skills/portfolio/SKILL.md +5 -6
- package/skills/quality-gates/SKILL.md +2 -4
- package/skills/reconcile/SKILL.md +27 -4
- package/skills/release/SKILL.md +16 -8
- package/skills/session-end/SKILL.md +94 -11
- package/skills/session-end/phase-3-2-docs-verification.md +1 -0
- package/skills/session-end/phase-3-6-tail.md +11 -7
- package/skills/session-end/phase-3-7a-recommendations.md +9 -2
- package/skills/session-end/plan-verification.md +16 -1
- package/skills/session-end/references/phase-3-documentation-updates.md +14 -12
- package/skills/session-end/references/phase-5-issue-cleanup.md +1 -1
- package/skills/session-end/references/session-summary-template.md +4 -0
- package/skills/session-end/session-metrics-write.md +7 -4
- package/skills/session-plan/SKILL.md +5 -3
- package/skills/session-start/SKILL.md +9 -3
- package/skills/session-start/phase-4-5-resource-health.md +11 -5
- package/skills/session-start/phase-8-5-express-path.md +4 -3
- package/skills/session-start/references/phase-1-2-session-lock.md +7 -5
- package/skills/session-start/references/phase-1-5-session-continuity.md +2 -2
- 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 +3 -2
- package/skills/tmux-layout/SKILL.md +2 -2
- package/skills/vault-sync/validator.mjs +3 -2
- package/skills/wave-executor/SKILL.md +5 -4
- package/skills/wave-executor/references/wave-executor-state-init.md +3 -3
- package/skills/wave-executor/references/wave-loop-dispatch.md +11 -5
- package/skills/wave-executor/references/wave-loop-review.md +13 -5
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +1 -1
- package/assets/og-card.png +0 -0
- package/assets/og-card.svg +0 -47
- package/assets/wave-lifecycle.svg +0 -98
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: session-reviewer
|
|
3
|
-
description: 'Use this agent between waves or at session end to verify work quality against the session plan
|
|
4
|
-
model:
|
|
3
|
+
description: 'Use this agent between waves or at session end to verify work quality against the session plan, or ad hoc to review a named diff, branch or MR without any plan (verdict ship / ship nach Fix / FIX_REQUIRED). Checks implementation correctness, test coverage, TypeScript health, security basics, and issue tracking accuracy.'
|
|
4
|
+
model: opus
|
|
5
|
+
effort: medium
|
|
5
6
|
color: pink
|
|
6
7
|
tools: Read, Grep, Glob, Bash, SendMessage
|
|
7
8
|
sandbox-tier: read-only
|
|
@@ -12,6 +13,15 @@ output-schema: schemas/session-reviewer.schema.json
|
|
|
12
13
|
|
|
13
14
|
You are a quality gate agent. Your job is to verify work quality — NOT to implement or fix anything.
|
|
14
15
|
|
|
16
|
+
## Ad-hoc Mode (no wave plan)
|
|
17
|
+
|
|
18
|
+
When your prompt names a diff, branch, commit range or MR but no wave plan or session plan, review that change on its own. Do NOT look for, create or ask for a plan, STATE.md or wave artefacts; their absence is not a finding and not an obstacle.
|
|
19
|
+
|
|
20
|
+
- **Scope:** the named change only (`git diff <base>...<branch>`, `git show <sha>`, `glab mr diff <n>` / `gh pr diff <n>`), judged against the repo's CLAUDE.md/AGENTS.md and `.claude/rules/`. Read-only: you never check out, commit or push.
|
|
21
|
+
- **Findings:** only those you can back with a concrete scenario (input or state → wrong result) and a `file:line`. Rank them **HOCH / MITTEL / NIEDRIG**, at most ~12, each with its RCR-007 class. Keep CONFIRMED / REFUTED (§ Depth and Escalation Authority) — they apply in both modes.
|
|
22
|
+
- **Verdict**, exactly one: `ship` (no finding needs a fix before merge) · `ship nach Fix` (only MITTEL/NIEDRIG findings with a local, named fix; no second review needed) · `FIX_REQUIRED` (any HOCH, or a fix that needs another review).
|
|
23
|
+
- **Output:** the findings list, CONFIRMED, REFUTED and the verdict replace the wave-shaped report below. Still append the JSON summary as the last fenced block, with `verdict` mapped `ship`→`PROCEED`, `ship nach Fix`→`FIX_REQUIRED`, `FIX_REQUIRED`→`FIX_REQUIRED`, `fix_required` listing the items to fix before merge (empty only for `ship`, as the schema requires for `PROCEED`), and `categories` filled from what you checked. The prose verdict still tells `ship nach Fix` (no second review) apart from `FIX_REQUIRED`.
|
|
24
|
+
|
|
15
25
|
## Review Checklist
|
|
16
26
|
|
|
17
27
|
> **Verification standard**: When verifying inter-wave checkpoint completion, apply `.claude/rules/verification-before-completion.md` Gate Function — never accept agent `STATUS: done` claims that lack quoted verification evidence.
|
|
@@ -246,3 +256,9 @@ Verdict variants (concrete examples per scenario):
|
|
|
246
256
|
- `fix_required`: array of strings describing items that must be addressed before proceeding
|
|
247
257
|
- Wrap in a fenced code block tagged `json` so consuming skills can extract via regex
|
|
248
258
|
- The coordinator's `validateAgentOutput()` parses the LAST fenced ```json block; place it at the end of your response
|
|
259
|
+
|
|
260
|
+
## Examples
|
|
261
|
+
|
|
262
|
+
<example>Context: Impl-Core wave is complete, coordinator needs quality check before Impl-Polish. user: "Impl-Core wave done, review before continuing" assistant: "I'll dispatch the session-reviewer to verify Impl-Core outputs." <commentary>Inter-wave quality gate ensures issues are caught early, not at session end.</commentary></example>
|
|
263
|
+
|
|
264
|
+
<example>Context: Session end, verifying all work before committing. user: "/close" assistant: "Running session-reviewer to verify all session work before committing." <commentary>Final quality gate before any code is committed.</commentary></example>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: skill-applied-judge
|
|
3
|
-
description: 'Use this agent at session-end Phase 3.6.6 (#645 L3) to judge — from the session transcript evidence (excerpts) — whether each selected skill was actually APPLIED and whether its work COMPLETED. Dispatched read-only by scripts/lib/skill-judge.mjs::runSkillJudge as Haiku with a bounded per-call budget. RETURNS one fenced json block of advisory per-skill judgments; the coordinator writes them. Read-only by contract — never writes files. Advisory-only — output never gates any action.
|
|
3
|
+
description: 'Use this agent at session-end Phase 3.6.6 (#645 L3) to judge — from the session transcript evidence (excerpts) — whether each selected skill was actually APPLIED and whether its work COMPLETED. Dispatched read-only by scripts/lib/skill-judge.mjs::runSkillJudge as Haiku with a bounded per-call budget. RETURNS one fenced json block of advisory per-skill judgments; the coordinator writes them. Read-only by contract — never writes files. Advisory-only — output never gates any action.'
|
|
4
4
|
model: haiku
|
|
5
|
+
effort: medium
|
|
6
|
+
omitClaudeMd: true
|
|
5
7
|
color: cyan
|
|
6
8
|
tools: Read, Grep, Glob
|
|
7
9
|
sandbox-tier: read-only
|
|
@@ -135,3 +137,7 @@ Rules:
|
|
|
135
137
|
- `scripts/lib/skill-judgments-schema.mjs` — the schema the coordinator validates against
|
|
136
138
|
- `skills/session-end/SKILL.md` § Phase 3.6.6 — the dispatch + write site
|
|
137
139
|
- Issue #645 (OpenSpace A, epic #643) — original spec and L3 acceptance criteria
|
|
140
|
+
|
|
141
|
+
## Examples
|
|
142
|
+
|
|
143
|
+
<example>Context: session-end Phase 3.6.6 with skill-evolution.judge: true. user "Judge whether the skills this session selected were actually applied." assistant "Dispatching skill-applied-judge to read the transcript evidence and emit advisory applied/completed judgments for each selected skill." <commentary>The judge produces a cheap advisory signal feeding the L3 skill-judgments sidecar — never an auto-action gate.</commentary></example>
|
package/agents/test-writer.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: test-writer
|
|
3
|
-
description: 'Use this agent to close NAMED test gaps and to consolidate redundant tests. It writes the specific missing test, and it deletes, merges, or parameterises tests that do not earn their keep.
|
|
4
|
-
model:
|
|
3
|
+
description: 'Use this agent to close NAMED test gaps and to consolidate redundant tests. It writes the specific missing test, and it deletes, merges, or parameterises tests that do not earn their keep.'
|
|
4
|
+
model: sonnet
|
|
5
|
+
effort: medium
|
|
5
6
|
color: orange
|
|
6
7
|
tools: Read, Edit, Write, Glob, Grep, Bash, Skill(session-orchestrator:*), SendMessage
|
|
7
8
|
sandbox-tier: repo-write
|
|
@@ -141,3 +142,9 @@ Required: `status`, `task_id`, `files_changed`, `blockers`. Optional: `verdict`,
|
|
|
141
142
|
- **Coverage threshold conflict**: Adding tests for a low-priority module pushes coverage down (because new lines exposed). → That's expected; do not skip writing tests just to game the coverage metric. Coverage measures untested code, not test quality.
|
|
142
143
|
- **Property-based vs example-based**: Function has clear invariants (e.g., parser inverts serializer). → Consider property-based tests (`fast-check`, `Hypothesis`) alongside examples. Use sparingly — only when invariants are stronger than examples.
|
|
143
144
|
- **Snapshot tests**: Output is large structured data (rendered HTML, AST). → Snapshots are acceptable when the project uses them, but always pair with at least one explicit assertion on key fields — pure snapshot tests rot quickly.
|
|
145
|
+
|
|
146
|
+
## Examples
|
|
147
|
+
|
|
148
|
+
<example>Context: Quality wave named one concrete gap — the invoice service never exercises the declined-payment branch. user: "The invoice service has no test for a declined payment" assistant: "I'll dispatch the test-writer to add that one error-path test and run the falsification check on it." <commentary>A named gap states a bug that would ship undetected; 'improve coverage' names nothing and is not a dispatchable task.</commentary></example>
|
|
149
|
+
|
|
150
|
+
<example>Context: The auth test file has 14 tests — 6 assert the same validation branch and 3 only pin prose strings. user: "Clean up the auth test file" assistant: "I'll use the test-writer to merge the 6 duplicates into one parameterised test and delete the 3 prose-pinning tests — net test count falls 14 to 6 while catch-power rises, reported as test_delta.removed plus test_delta.consolidated." <commentary>Consolidation is a success outcome: fewer tests that each catch a distinct bug beat many that catch none, and a scope with no real gap legitimately ends with status no-tests-needed.</commentary></example>
|
package/agents/ui-developer.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ui-developer
|
|
3
|
-
description: 'Use this agent for frontend implementation — UI components, pages, styling, accessibility, and responsive design. Handles React/Next.js components, CSS, and design system work.
|
|
4
|
-
model:
|
|
3
|
+
description: 'Use this agent for frontend implementation — UI components, pages, styling, accessibility, and responsive design. Handles React/Next.js components, CSS, and design system work.'
|
|
4
|
+
model: opus
|
|
5
|
+
effort: medium
|
|
5
6
|
color: magenta
|
|
6
7
|
tools: Read, Edit, Write, Glob, Grep, Bash, Skill(session-orchestrator:*), SendMessage
|
|
7
8
|
sandbox-tier: repo-write
|
|
@@ -108,3 +109,9 @@ Required: `status`, `task_id`, `files_changed`, `blockers`. Optional: `verdict`.
|
|
|
108
109
|
- **Mobile-first conflict**: Design mockup is desktop-only with no mobile spec. → Implement mobile-first with reasonable defaults (single column, stacked filters), flag the desktop-only spec in Notes for design clarification.
|
|
109
110
|
- **Animation request**: Task asks for "smooth transitions" without specifics. → Use the project's existing motion tokens (typically `transition: 200ms ease`) and flag for design review if heavier animation is needed.
|
|
110
111
|
- **JS-disabled fallback**: Server-rendered page must work without JS. → Confirm with the wave plan; if unspecified, use progressive enhancement (form posts work, JS adds client-side validation on top).
|
|
112
|
+
|
|
113
|
+
## Examples
|
|
114
|
+
|
|
115
|
+
<example>Context: Implementation wave includes UI component work. user: "Build the invoice list page with filters and pagination" assistant: "I'll dispatch the ui-developer agent to implement the invoice list UI." <commentary>Frontend page implementation with interactive components is the ui-developer's specialty.</commentary></example>
|
|
116
|
+
|
|
117
|
+
<example>Context: Accessibility improvements needed. user: "Fix WCAG violations in the dashboard components" assistant: "I'll use the ui-developer to audit and fix the accessibility issues." <commentary>WCAG compliance requires understanding semantic HTML, ARIA attributes, and keyboard navigation.</commentary></example>
|
package/agents/ux-evaluator.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ux-evaluator
|
|
3
|
-
description: 'Use this agent for read-only UX evaluation of test-runner driver artifacts (Playwright AX-tree snapshots, screenshots, console output). Applies the 4-check UX rubric (onboarding-step-count ≤7, axe-violations critical/serious, console-errors visible to user, Apple-Liquid-Glass .glassEffect() conformance on SwiftUI 26+) and emits structured findings JSON with stable fingerprints.
|
|
3
|
+
description: 'Use this agent for read-only UX evaluation of test-runner driver artifacts (Playwright AX-tree snapshots, screenshots, console output). Applies the 4-check UX rubric (onboarding-step-count ≤7, axe-violations critical/serious, console-errors visible to user, Apple-Liquid-Glass .glassEffect() conformance on SwiftUI 26+) and emits structured findings JSON with stable fingerprints.'
|
|
4
4
|
model: opus
|
|
5
|
+
effort: medium
|
|
5
6
|
color: blue
|
|
6
7
|
tools: Read, Grep, Glob, Bash
|
|
7
8
|
sandbox-tier: read-only
|
|
@@ -159,3 +160,7 @@ After the human-readable stdout summary, append a fenced ```json block matching
|
|
|
159
160
|
```
|
|
160
161
|
|
|
161
162
|
Required: `verdict` (enum PROCEED|PROCEED_WITH_FOLLOWUPS|FIX_REQUIRED|BLOCKED), `run_id`, `rubric_version`, `checks_applied`, `findings_count`, `findings_path`. Optional: `severity_counts`. The coordinator's `validateAgentOutput()` parses the LAST fenced ```json block; place it at the end of your response.
|
|
163
|
+
|
|
164
|
+
## Examples
|
|
165
|
+
|
|
166
|
+
<example>Context: test-runner has just produced .orchestrator/metrics/test-runs/12345-1715688000123/ax-snapshots/. user: "Evaluate UX of the dashboard flow against rubric-v1." assistant: "I'll dispatch ux-evaluator to read the AX-tree snapshots and emit findings.json per skills/test-runner/rubric-v1.md." <commentary>ux-evaluator is the only agent that translates driver-captured artifacts into reconcilable findings; it never invokes drivers itself.</commentary></example>
|
package/commands/session.md
CHANGED
|
@@ -17,7 +17,7 @@ You are beginning a new development session. The complete text following `/sessi
|
|
|
17
17
|
|
|
18
18
|
**Explicit execution requests:** Ordinary housekeeping uses the coordinator-direct maintenance shape returned by `scripts/session-shape.mjs`. If the user explicitly requests parallel subagents or waves in the context, carry that request into the session plan as an override for this run, following [User-authorized housekeeping execution deviation](../skills/session-plan/SKILL.md#user-authorized-housekeeping-execution-deviation). Retain `session-type: housekeeping`, keep the resolver's default shape distinct from the actual plan, and preserve global Session Config and the user's model settings. The planning and execution skills apply this exception before their housekeeping shortcuts; the request does not implicitly authorize unrelated external actions.
|
|
19
19
|
|
|
20
|
-
### Argument alias: `ultradeep` (PRD
|
|
20
|
+
### Argument alias: `ultradeep` (spec: internal session-profile PRD, 2026-09-06)
|
|
21
21
|
|
|
22
22
|
`/session ultradeep` is an alias, NOT a fourth `session_type`. Resolve it to TWO STATE.md frontmatter values and then continue exactly as a `deep` session would:
|
|
23
23
|
|
|
@@ -5,7 +5,7 @@ argument-hint: "[optional-reason]"
|
|
|
5
5
|
|
|
6
6
|
# Templates Acknowledgement
|
|
7
7
|
|
|
8
|
-
Write a session-scoped acknowledgement entry to `.orchestrator/runtime/templates-acknowledged.json`. Once written, the `pre-bash-templates-first` hook (G6) will allow `gh`/`glab` create operations for the rest of the current session without requiring a prior template Read.
|
|
8
|
+
Write a session-scoped acknowledgement entry to `.orchestrator/runtime/templates-acknowledged.json` (inside a linked git worktree: the main checkout's `.orchestrator/runtime/`, where the hook reads it). Once written, the `pre-bash-templates-first` hook (G6) will allow `gh`/`glab` create operations for the rest of the current session without requiring a prior template Read.
|
|
9
9
|
|
|
10
10
|
**Use this only when:**
|
|
11
11
|
- You have already reviewed the relevant template externally (e.g. copy-paste workflow), OR
|
|
@@ -15,28 +15,76 @@ Write a session-scoped acknowledgement entry to `.orchestrator/runtime/templates
|
|
|
15
15
|
|
|
16
16
|
Run the following node snippet to write the acknowledgement:
|
|
17
17
|
|
|
18
|
+
The acknowledgement requires proof from the nearest ancestor whose process name
|
|
19
|
+
(basename of `comm`) is `claude`: its `~/.claude/sessions/<pid>.json` must supply a valid `sessionId`.
|
|
20
|
+
Only parent PID and process name are measured, with at most 64 processes and no
|
|
21
|
+
cycles. Nonempty native environment IDs must agree with that invocation.
|
|
22
|
+
Missing process/session evidence refuses the acknowledgement, including on
|
|
23
|
+
harnesses without a Claude ancestor. Shared
|
|
24
|
+
`.orchestrator/current-session.json` state is never used as identity. This guards against accidental acknowledgement
|
|
25
|
+
for a parent session from a nested harness; it is not a security boundary against
|
|
26
|
+
a hostile child (which could write the file directly). A Claude started as a
|
|
27
|
+
plain `node` script has no `claude` ancestor and is refused. Run this
|
|
28
|
+
from the target project with the harness's plugin-root environment set (or from
|
|
29
|
+
the session-orchestrator repository itself).
|
|
30
|
+
The hook accepts this acknowledgement only when its invocation supplies a valid,
|
|
31
|
+
unambiguous `session_id` or `sessionId`; inherited environment IDs cannot grant
|
|
32
|
+
an acknowledgement bypass when that invocation ID is missing.
|
|
33
|
+
|
|
18
34
|
```bash
|
|
19
35
|
node --input-type=module -e "
|
|
20
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync } from 'node:fs';
|
|
36
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync, statSync } from 'node:fs';
|
|
21
37
|
import { join, dirname } from 'node:path';
|
|
22
38
|
import { randomBytes } from 'node:crypto';
|
|
39
|
+
import { pathToFileURL } from 'node:url';
|
|
23
40
|
|
|
24
41
|
const cwd = process.cwd();
|
|
25
|
-
const sessionFile = join(cwd, '.orchestrator', 'current-session.json');
|
|
26
|
-
const ackFile = join(cwd, '.orchestrator', 'runtime', 'templates-acknowledged.json');
|
|
27
42
|
const reason = process.argv[1] ?? '';
|
|
28
43
|
const userId = process.env.USER ?? process.env.USERNAME ?? '';
|
|
29
44
|
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
// Bootstrap from the same root precedence as the plugin resolver. The cwd
|
|
46
|
+
// fallback is restricted to the plugin repository, never an arbitrary project.
|
|
47
|
+
const roots = [
|
|
48
|
+
['claude', 'CLAUDE_PLUGIN_ROOT'], ['codex', 'CODEX_PLUGIN_ROOT'],
|
|
49
|
+
['cursor', 'CURSOR_RULES_DIR'], ['pi', 'PI_PLUGIN_ROOT'],
|
|
50
|
+
];
|
|
51
|
+
const platform = (process.env.SO_PLATFORM ?? '').trim();
|
|
52
|
+
const ordered = [...roots.filter(([p]) => p === platform), ...roots.filter(([p]) => p !== platform)];
|
|
53
|
+
let pluginRoot = null;
|
|
54
|
+
for (const name of ['PLUGIN_ROOT', ...ordered.map(([, name]) => name)]) {
|
|
55
|
+
const candidate = (process.env[name] ?? '').trim();
|
|
56
|
+
if (!candidate) continue;
|
|
57
|
+
try { if (statSync(candidate).isDirectory()) { pluginRoot = candidate; break; } } catch { /* try next root */ }
|
|
58
|
+
}
|
|
59
|
+
if (!pluginRoot) {
|
|
33
60
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
61
|
+
if (JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8')).name === 'session-orchestrator') pluginRoot = cwd;
|
|
62
|
+
} catch { /* no plugin-root evidence */ }
|
|
63
|
+
}
|
|
64
|
+
if (!pluginRoot) {
|
|
65
|
+
process.stderr.write('⚠ templates-ack: plugin root unavailable — ack not written\n');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
// The ack file is runtime state: in a linked worktree it lives in the MAIN
|
|
69
|
+
// checkout, the same root the pre-bash-templates-first hook reads (#1729).
|
|
70
|
+
let ackFile = null;
|
|
71
|
+
try {
|
|
72
|
+
const { resolveEventsLedgerRoot } = await import(pathToFileURL(join(pluginRoot, 'scripts/lib/platform.mjs')).href);
|
|
73
|
+
ackFile = join(resolveEventsLedgerRoot(cwd), '.orchestrator', 'runtime', 'templates-acknowledged.json');
|
|
74
|
+
} catch {
|
|
75
|
+
process.stderr.write('⚠ templates-ack: root resolver unavailable — ack not written\n');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
let sessionId = null;
|
|
79
|
+
try {
|
|
80
|
+
const { readInvocationSessionId } = await import(pathToFileURL(join(pluginRoot, 'scripts/lib/session-identity/own-session.mjs')).href);
|
|
81
|
+
sessionId = readInvocationSessionId();
|
|
82
|
+
} catch {
|
|
83
|
+
process.stderr.write('⚠ templates-ack: process-local identity helper unavailable — ack not written\n');
|
|
84
|
+
process.exit(1);
|
|
37
85
|
}
|
|
38
86
|
if (!sessionId) {
|
|
39
|
-
process.stderr.write('⚠ templates-ack:
|
|
87
|
+
process.stderr.write('⚠ templates-ack: session id does not come from this invocation — ack not written\n');
|
|
40
88
|
process.exit(1);
|
|
41
89
|
}
|
|
42
90
|
|
|
@@ -67,15 +115,38 @@ if (reason) process.stdout.write(' Reason: ' + reason + '\n');
|
|
|
67
115
|
|
|
68
116
|
## Verification
|
|
69
117
|
|
|
70
|
-
After writing, confirm the entry exists
|
|
118
|
+
After writing, confirm the entry exists. The check resolves the same root as
|
|
119
|
+
the writer (main checkout for a linked worktree); the `Written:` line above
|
|
120
|
+
names the same file.
|
|
71
121
|
|
|
72
122
|
```bash
|
|
73
|
-
node -e "
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
123
|
+
node --input-type=module -e "
|
|
124
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
125
|
+
import { join } from 'node:path';
|
|
126
|
+
import { pathToFileURL } from 'node:url';
|
|
127
|
+
const cwd = process.cwd();
|
|
128
|
+
// Same plugin-root lookup as the writer: an env root first, the cwd only
|
|
129
|
+
// when it IS the plugin repository, never an arbitrary project.
|
|
130
|
+
let pluginRoot = null;
|
|
131
|
+
for (const name of ['PLUGIN_ROOT', 'CLAUDE_PLUGIN_ROOT', 'CODEX_PLUGIN_ROOT', 'CURSOR_RULES_DIR', 'PI_PLUGIN_ROOT']) {
|
|
132
|
+
const candidate = (process.env[name] ?? '').trim();
|
|
133
|
+
if (!candidate) continue;
|
|
134
|
+
try { if (statSync(candidate).isDirectory()) { pluginRoot = candidate; break; } } catch { /* try next root */ }
|
|
135
|
+
}
|
|
136
|
+
if (!pluginRoot) {
|
|
137
|
+
try {
|
|
138
|
+
if (JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8')).name === 'session-orchestrator') pluginRoot = cwd;
|
|
139
|
+
} catch { /* no plugin-root evidence */ }
|
|
140
|
+
}
|
|
141
|
+
if (!pluginRoot) { console.log('plugin root unavailable'); process.exit(1); }
|
|
142
|
+
let root;
|
|
143
|
+
try {
|
|
144
|
+
const { resolveEventsLedgerRoot } = await import(pathToFileURL(join(pluginRoot, 'scripts/lib/platform.mjs')).href);
|
|
145
|
+
root = resolveEventsLedgerRoot(cwd);
|
|
146
|
+
} catch { console.log('root resolver unavailable'); process.exit(1); }
|
|
147
|
+
const p = join(root, '.orchestrator', 'runtime', 'templates-acknowledged.json');
|
|
148
|
+
if (!existsSync(p)) { console.log('NOT FOUND: ' + p); process.exit(1); }
|
|
149
|
+
console.log(JSON.stringify(JSON.parse(readFileSync(p, 'utf8')), null, 2));
|
|
79
150
|
"
|
|
80
151
|
```
|
|
81
152
|
|
package/docs/agent-authoring.md
CHANGED
|
@@ -48,8 +48,9 @@ Agent files live in `agents/` as Markdown with YAML frontmatter. Required fields
|
|
|
48
48
|
```yaml
|
|
49
49
|
---
|
|
50
50
|
name: kebab-case-name # 3-50 chars, lowercase + hyphens only
|
|
51
|
-
description: Use this agent when [conditions]. <example>
|
|
52
|
-
model:
|
|
51
|
+
description: Use this agent when [conditions]. # single-line routing sentence; <example> blocks go in the body § Examples
|
|
52
|
+
model: opus # inherit | sonnet | opus | haiku | fable — OR full ID like claude-opus-5-5, claude-sonnet-4-6, claude-haiku-4-5-20251001, claude-sonnet-5, claude-fable-5
|
|
53
|
+
effort: medium # low | medium | high | xhigh | max — REQUIRED whenever model is not inherit (#1614)
|
|
53
54
|
color: blue # blue | cyan | green | yellow | purple | orange | pink | red | magenta
|
|
54
55
|
tools: Read, Grep, Glob, Bash # comma-separated string OR JSON array (both accepted; we prefer comma-string for consistency)
|
|
55
56
|
---
|
|
@@ -59,8 +60,9 @@ tools: Read, Grep, Glob, Bash # comma-separated string OR JSON array (bo
|
|
|
59
60
|
|
|
60
61
|
**Required vs optional:**
|
|
61
62
|
- Runtime canonical doc: only `name` + `description` are required.
|
|
62
|
-
- Our validator (defensive for plugin-distribution): all four of `name + description + model + color` required; `tools` optional.
|
|
63
|
-
- `
|
|
63
|
+
- Our validator (defensive for plugin-distribution): all four of `name + description + model + color` required; `effort` required as soon as `model` is not `inherit`; `tools` optional.
|
|
64
|
+
- `omitClaudeMd: true|false` (optional, #1616) drops CLAUDE.md from the agent's start context. Set only on narrow judges that read nothing but the records they are handed (`eval-judge`, `skill-applied-judge`, `dialectic-deriver`); reviewers and implementers keep it because they check against the rules.
|
|
65
|
+
- `description` MUST be a single-line inline string, NOT a YAML block scalar (`>` or `|`). It carries only the routing sentence(s) — the text the dispatcher matches on. `<example>…</example>` blocks (with `<commentary>`) do NOT go inline in the description: they live in a `## Examples` section at the end of the body, one block per paragraph (#887, #1157).
|
|
64
66
|
- `tools` accepts BOTH comma-separated string (`Read, Edit, Write`) and JSON array (`["Read", "Edit", "Write"]`). Anthropic's own reference agents use array form; we use string form for consistency.
|
|
65
67
|
|
|
66
68
|
**Body conventions** (from Anthropic's `plugins/plugin-dev/agents/*` reference set):
|
|
@@ -68,15 +70,25 @@ tools: Read, Grep, Glob, Bash # comma-separated string OR JSON array (bo
|
|
|
68
70
|
- Length: 500–3000 words is the recommended range. Below 500 reads as under-specified; above 3000 reads as bloated.
|
|
69
71
|
- Read-only reviewer agents: tools `Read, Grep, Glob, Bash` (no Edit/Write). Implementer agents: `Read, Edit, Write, Glob, Grep, Bash`. Agents on the escalation allowlist append `SendMessage` to either baseline — see § Escalation Channel (#1051) for the six that do and why the rest do not.
|
|
70
72
|
|
|
71
|
-
## Model Selection & Cost Routing (#768)
|
|
73
|
+
## Model Selection & Cost Routing (#768, #1614)
|
|
72
74
|
|
|
73
|
-
`model:`
|
|
75
|
+
Every agent pins `model:` AND `effort:` explicitly. `inherit` was the default until 2026-10-14 and cost the catalog its users: under a Fable lead, an inheriting agent ran on the most expensive model at the session's effort, and the fleet moved to private opus/medium agents (census in #1614: plugin share of dispatches fell from 61 % in the week of 15 September to 6 % in the week of 8 October).
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
| Role | model | effort | Agents |
|
|
78
|
+
|---|---|---|---|
|
|
79
|
+
| Implementation and review | `opus` | `medium` | `code-implementer`, `db-specialist`, `ui-developer`, `session-reviewer`, `security-reviewer`, `architect-reviewer` |
|
|
80
|
+
| Tests, docs, analysis | `sonnet` | `medium` | `test-writer`, `docs-writer`, `qa-strategist`, `analyst` |
|
|
81
|
+
| Narrow judges | `haiku` | `medium` | `eval-judge`, `skill-applied-judge`, `dialectic-deriver` |
|
|
82
|
+
| Rare solo evaluator | `opus` | `medium` | `ux-evaluator` (judges screenshots and AX trees against a rubric, dispatched alone, not fanned out) |
|
|
83
|
+
|
|
84
|
+
- **`effort` is required whenever `model` is not `inherit`** (validated by `checkAgentEffort` in `scripts/lib/agent-frontmatter.mjs`). The per-model default differs: Sonnet 5.5 defaults to `high`, Opus 5.5 to `medium`, so a Sonnet agent without `effort` thinks longer than an Opus one. `medium` follows the owner's standing instruction (2026-09-30); raise it only for a named reason in the agent.
|
|
85
|
+
- **`haiku`** — narrow classification or a single structured verdict over a short input. Whether read-only analysis roles move to Haiku is an open owner decision (#1614); do not switch them until it is made.
|
|
86
|
+
- **`sonnet`** — work that needs judgment but not the strongest reasoning: test gaps, docs, PRD and coverage analysis.
|
|
87
|
+
- **`opus`** — code changes and reviews, where a missed defect costs more than the tokens.
|
|
88
|
+
- **`inherit`** — only with a reason written into the agent (e.g. the agent must follow whatever model the operator chose). It also inherits the session's effort.
|
|
89
|
+
- **Full model-ID pinning** (`claude-opus-5-5`, `claude-sonnet-5`, `claude-fable-5-20260101`, …) — only for a demonstrated dependency on one model version (a reproducibility snapshot, a known regression on newer models). Document the reason inline as a frontmatter comment.
|
|
90
|
+
|
|
91
|
+
Whether `effort` from a **plugin** agent's frontmatter takes effect is not stated in the upstream docs; the #1614 acceptance smoke checks it per role. If it does not, the dispatcher passes `effort` as a dispatch parameter (Claude Code v2.1.292+).
|
|
80
92
|
|
|
81
93
|
**Resolution order** (highest precedence first): `CLAUDE_CODE_SUBAGENT_MODEL` environment variable → the invocation-time model parameter (if the dispatcher passes one explicitly) → the agent's own frontmatter `model:` value. An agent's `model:` is therefore a default, not a guarantee — a session or environment override can supersede it.
|
|
82
94
|
|
|
@@ -90,6 +102,13 @@ Every agent definition with `repo-write` sandbox-tier (i.e. `Edit`/`Write` prese
|
|
|
90
102
|
|
|
91
103
|
This is deliberately more explicit than a bare "Do NOT commit" — the git index and stash are SHARED resources across concurrently-dispatched sibling agents in the same wave, and `git stash`/`git add`/`git mv`/`git rm` are index-mutating even when scoped to the agent's own files. `docs-writer.md` had NO git-write restriction at all until #724 closed the gap (its `repo-write` siblings at least carried a bare "Do NOT commit" line) — when adding a new repo-write agent, copy the ban line verbatim rather than re-deriving a weaker phrasing so this gap does not recur. See `.claude/rules/parallel-sessions.md` § PSA-007 for the full rationale and fleet evidence.
|
|
92
104
|
|
|
105
|
+
**Sole exception — worktree mode (#1614).** Only `code-implementer` may stage its own files one by one and commit, and only when its prompt carries a line `WORKTREE-MODE: <absolute path> <branch>` that matches `git rev-parse --show-toplevel` and `git branch --show-current`; otherwise the ban applies unchanged. Coordinator duty: never grant the coordinator's own worktree, never put two agents in one worktree. The wave-executor never sets the line. A linked worktree has its own index, so the index race this ban prevents does not exist there. The commit hook briefly adds an entry to the shared stash via lint-staged; the agent itself never runs `git stash`. Push, merge, `git reset`, `git stash` and `git clean` stay banned. The exception lives in the agent's own Rules section, next to the unchanged ban line, so Check 10 still finds the ban. The detector `psa007-git-write` (`scripts/lib/wave-transcript-tail.mjs`) still reports every commit inside a wave; that is correct, because wave prompts never carry `WORKTREE-MODE`.
|
|
106
|
+
|
|
107
|
+
## Waiting, Forks and Start Cost (#1615, #1616)
|
|
108
|
+
|
|
109
|
+
- **Waiting longer than 5 minutes does not belong in a subagent.** A subagent's prompt cache lives 5 minutes, so every longer wait (pipeline, remote run, rerun) rebuilds its whole context on the next turn (#1615 measured 250 M rewritten tokens in 14 days). The agent reports its intermediate state and ends; the coordinator waits with Monitor and then continues it with `SendMessage` (or dispatches a fresh one).
|
|
110
|
+
- **Fork or subagent.** A short task that needs the current conversation goes to a fork: it inherits system prompt, tools and history and reads the parent session's cache, so it does not pay the 60–80k token start context again. A task with its own file scope, worktree or model goes to a subagent. The wave-executor stays on subagents, because it needs scope boundaries.
|
|
111
|
+
|
|
93
112
|
## Escalation Channel (#1051)
|
|
94
113
|
|
|
95
114
|
Six agents opt into `SendMessage` so a wave-blocking obstacle can reach the coordinator **while the wave is still running**, instead of surfacing only in the final report after the wave has ended. The allowlist is exactly:
|
package/docs/ci-setup.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
> **Maintainer-internal.** This document describes the maintainer's private CI mirror setup. It is not required for using the plugin.
|
|
4
4
|
|
|
5
|
+
GitHub's Linux/macOS test matrix is supplemented by two non-blocking Windows jobs on `windows-latest` (#1612): `test-windows-smoke` runs lint, typecheck and `scripts/ci/windows-smoke.mjs` (the product contract for Claude Code on Windows; it moves into `gate` after 10 green main runs), and `test-windows-suite` runs the full suite for information while the test-portability backlog is open. The fresh SessionStart smoke needs npm-registry access and reports unavailable network as unmeasurable.
|
|
6
|
+
|
|
5
7
|
## schema-drift-check job
|
|
6
8
|
|
|
7
9
|
The `schema-drift-check` job compares the vendored `vault-frontmatter` schema
|
|
@@ -633,8 +635,42 @@ The router tries eligible aliases in configuration order, checking each with
|
|
|
633
635
|
`offload doctor -H <alias> --brief --no-probe`. The alias selects a gate execution
|
|
634
636
|
host; it is independent of the Git remote being pushed to. With no eligible
|
|
635
637
|
host, no `offload` executable, or unavailable remote readiness/transport, the
|
|
636
|
-
hook
|
|
637
|
-
|
|
638
|
+
hook falls back locally. A classified transport failure can first try the next
|
|
639
|
+
configured host.
|
|
640
|
+
|
|
641
|
+
The local fallback depends on the push target (#1642):
|
|
642
|
+
|
|
643
|
+
- **A branch other than `main` on `origin`** (by remote name or its exact push
|
|
644
|
+
URL) takes the local **partial** gate, `scripts/lib/pre-push-local-partial.mjs`.
|
|
645
|
+
It computes the files changed since the merge-base with origin's default
|
|
646
|
+
branch and runs `node --check` and ESLint on the changed source files, plus
|
|
647
|
+
`vitest related --run` for all changed files. A red check blocks the push. The
|
|
648
|
+
full suite then runs in the MR pipeline on the pushed head SHA.
|
|
649
|
+
- **Everything else** (any push that includes `main` or a tag — every pushed ref counts, not only the first — the GitHub mirror, a push
|
|
650
|
+
by URL to another host, a hand invocation without a remote) runs the full
|
|
651
|
+
gate locally. No MR pipeline stands between those pushes and their result.
|
|
652
|
+
- The partial gate exits 10 and hands over to the full local gate when there is
|
|
653
|
+
no merge-base, when a source file was deleted or renamed, when `package.json`, `package-lock.json`, `vitest.config.*` or
|
|
654
|
+
`eslint.config.*` changed, or when `eslint`/`vitest` is missing from
|
|
655
|
+
`node_modules` (fail-closed). Its ledger event is
|
|
656
|
+
`orchestrator.quality_gate.{passed,failed}` with `variant: 'local-partial'`.
|
|
657
|
+
- Ceiling: `vitest related` follows the import graph. A test that reaches a
|
|
658
|
+
changed file only by spawning it (hooks, `.husky/`, CLIs) or by reading it
|
|
659
|
+
from disk (policy JSON, Markdown, fixtures; edited or deleted) is not
|
|
660
|
+
selected locally, and the MR pipeline catches that class. Only a deleted or
|
|
661
|
+
renamed source file (`.mjs`/`.cjs`/`.js`) falls back to the full gate (#1643).
|
|
662
|
+
|
|
663
|
+
`SO_GATE_HOSTS` overrides the host order for one push without a config commit:
|
|
664
|
+
`SO_GATE_HOSTS=hostA,hostB git push` tries exactly those aliases, in that order,
|
|
665
|
+
instead of the configured `remote-hosts` list (whitespace-only counts as unset).
|
|
666
|
+
Every alias must have a regular file `<alias>.env` in offload's host registry
|
|
667
|
+
(`${OFFLOAD_CONFIG_DIR:-$HOME/.config/remote-offload}/hosts/`, the same rule
|
|
668
|
+
`offload -H` uses) and match `^[A-Za-z0-9._-]+$`. An unknown or invalid alias,
|
|
669
|
+
or an override none of whose hosts can run the gate (not ready, transport
|
|
670
|
+
failure, no `offload`), blocks the push with exit 2 and does **not** fall back
|
|
671
|
+
to the local gate. The router logs the chosen host and its source (`config`,
|
|
672
|
+
`override`, or `fallback` to local) on stderr, and the remote gate's ledger
|
|
673
|
+
event carries `host` and `host_source`.
|
|
638
674
|
|
|
639
675
|
On the remote checkout, the command checks out the pushed SHA again, verifies
|
|
640
676
|
`HEAD` and a clean source tree, and runs `npm run --silent quality-gate`.
|
package/docs/codex-setup.md
CHANGED
|
@@ -11,7 +11,7 @@ Guide for using Session Orchestrator with OpenAI Codex through Codex's public pl
|
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Two paths. The clone below is the complete install: it puts the runtime dependencies next to the plugin. The short remote form (`codex plugin marketplace add <owner>/<repo>`) needs no clone and takes two commands, but the installed plugin has no `node_modules`, so part of the plugin falls back or stops until you run `npm install` there — see "Short-Form Marketplace Add" below.
|
|
15
15
|
|
|
16
16
|
Clone the repository, install its runtime dependencies, and run the installer from the plugin root:
|
|
17
17
|
|
|
@@ -34,7 +34,7 @@ A marketplace on the working checkout copies all of it into the Codex plugin cac
|
|
|
34
34
|
|
|
35
35
|
It operates only through public Codex plugin commands; hook trust remains untouched.
|
|
36
36
|
|
|
37
|
-
### Short-Form Marketplace Add (
|
|
37
|
+
### Short-Form Marketplace Add (Verified 2026-09-04, codex-cli 0.144.4; dependencies measured 2026-10-21, codex-cli 0.160.1)
|
|
38
38
|
|
|
39
39
|
`codex plugin marketplace add --help` documents a short remote form:
|
|
40
40
|
|
|
@@ -42,7 +42,7 @@ It operates only through public Codex plugin commands; hook trust remains untouc
|
|
|
42
42
|
codex plugin marketplace add owner/repo --ref main
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
This is the
|
|
45
|
+
This is the shortest install path — no local clone needed. Confirmed end-to-end on codex-cli **0.144.4** (2026-09-04), against this repo's unchanged flat layout (`.codex-plugin/plugin.json` + `.claude-plugin/marketplace.json` at repo root, no `plugins/<name>/`):
|
|
46
46
|
|
|
47
47
|
```
|
|
48
48
|
$ codex plugin add session-orchestrator@kanevry --json
|
|
@@ -53,6 +53,13 @@ $ echo $?
|
|
|
53
53
|
|
|
54
54
|
`codex plugin list --available --json --marketplace kanevry` confirms `installed: true, enabled: true` for the same layout — no `plugins/<name>/` restructuring was needed.
|
|
55
55
|
|
|
56
|
+
**No runtime dependencies on this path (measured 2026-10-21, codex-cli 0.160.1, isolated `CODEX_HOME`).** `marketplace add` and `plugin add` both exit 0, but the installed path (`~/.codex/plugins/cache/kanevry/session-orchestrator/<version>`) has no `node_modules`. The SessionStart hook, the Bash guards and `scripts/parse-config.mjs` still run (the destructive-command guard's `git stash` check falls back to a warning, because it needs `zx`). Everything else that needs a runtime dependency (`zx`, `zod`, `js-yaml`, `ajv`, `remark`, …) either falls back or stops:
|
|
57
|
+
|
|
58
|
+
- `owner.yaml` loads `js-yaml` lazily: when the file exists, owner preferences fall back to defaults and the process prints `WARN owner-yaml: 'js-yaml' is not installed … Run 'npm install' in the plugin directory`.
|
|
59
|
+
- Scripts that import a dependency at the top stop with `ERR_MODULE_NOT_FOUND` and no warning: the worktree helpers (`zx`), the learnings index (`zod`), the persona panel and the PRD archive (`js-yaml`), among others (18 files import `js-yaml` that way).
|
|
60
|
+
|
|
61
|
+
To restore them, run `npm install --omit=dev --ignore-scripts` in the `installedPath` that `codex plugin add --json` prints, and again after every update, because each version gets a new cache directory. The clone path above avoids this.
|
|
62
|
+
|
|
56
63
|
**Historical note:** on codex-cli 0.141.0 (2026-08-28), the identical `plugin add` command failed against this same layout with `Error: plugin session-orchestrator was not found in marketplace kanevry`; upgrading to 0.144.4+ resolves it.
|
|
57
64
|
|
|
58
65
|
### Switching Marketplace Sources
|
|
@@ -160,9 +167,10 @@ $ strings -a "$(npm root -g)/@openai/codex/node_modules/@openai/codex-darwin-arm
|
|
|
160
167
|
| Event | 0.144.4 | Wired here |
|
|
161
168
|
|---|---|---|
|
|
162
169
|
| `SessionStart` | yes | yes — banner + `on-session-start.mjs` |
|
|
163
|
-
| `PostToolUse` | yes | yes — `loop-guard.mjs` |
|
|
170
|
+
| `PostToolUse` | yes | yes — `loop-guard.mjs`; `Bash`: `post-bash-write-verify.mjs` (warn-only, #1691) |
|
|
164
171
|
| `SubagentStop`, `Stop` | yes | yes — `on-stop.mjs` |
|
|
165
|
-
| `PreToolUse
|
|
172
|
+
| `PreToolUse` | yes | yes — `Bash`: destructive guard, staging fence, memory-propose audit, sessions-ledger guard, issue budget, `enforce-commands.mjs` (#1691); `pre-bash-templates-first.mjs` and the Edit/Write guards stay unwired (see below) |
|
|
173
|
+
| `SubagentStart` | yes | declared, **empty** |
|
|
166
174
|
| `UserPromptSubmit`, `PermissionRequest`, `PreCompact`, `PostCompact` | yes | no — this repo has no handler for them |
|
|
167
175
|
| `SessionEnd`, `Interrupt` | **no — event does not exist** | n/a |
|
|
168
176
|
| `PostToolUseFailure`, `PostToolBatch`, `CwdChanged` | no — Claude-only | n/a |
|
|
@@ -171,26 +179,42 @@ $ strings -a "$(npm root -g)/@openai/codex/node_modules/@openai/codex-darwin-arm
|
|
|
171
179
|
|
|
172
180
|
For the day `SessionEnd` does land: upstream caps it (and `Interrupt`) at a **1 s default / 3 s maximum** timeout, where every other event gets 600 s. `hooks/on-session-end.mjs` measures ~221 ms median, so it fits — but only just, and only while it stays that fast.
|
|
173
181
|
|
|
174
|
-
###
|
|
182
|
+
### Which PreToolUse guards run on Codex — the reason, corrected
|
|
175
183
|
|
|
176
184
|
Earlier revisions of this page said the handlers were unwired because "no Codex bridge delivers `tool_name`". **That was measuring the wrong thing** — it grepped our own adapter code rather than the Codex payload contract. There is no bridge because none is needed:
|
|
177
185
|
|
|
178
186
|
- `pre-tool-use.command.input` REQUIRES `tool_name` and `tool_input`, alongside `cwd`, `hook_event_name`, `model`, `permission_mode`, `session_id`, `tool_use_id`, `transcript_path`, `turn_id`.
|
|
179
187
|
- The deny envelope is `hookSpecificOutput.{hookEventName, permissionDecision, permissionDecisionReason}` — byte-identical to what `emitDeny()` already writes, and Codex enforces exactly that shape (its own error text: *"PreToolUse hook returned permissionDecision:deny without a non-empty permissionDecisionReason"*). Codex additionally rejects `permissionDecision: "allow"` and `"ask"`; our allow path is a bare `exit 0` with no stdout, so it is compatible.
|
|
180
188
|
|
|
181
|
-
|
|
189
|
+
Until 2026-10-20 this page named the **tool-name vocabulary** as the real blocker: Codex's model-facing tools are `shell`, `exec_command`, `unified_exec`, `apply_patch`, `update_plan`, `view_image`, and `strings -a <codex> | grep -c '"Bash"'` returned `0` (codex-cli 0.144.4). **For the shell tool that is refuted** (#1669, measured 2026-10-20 on codex-cli 0.160.1 with a logging PreToolUse hook under `codex exec`): a shell call reaches the hook as `"tool_name":"Bash"` with `"tool_input":{"command":"<string>"}`, and `matcher: "Bash"` fires. Codex maps its shell tool to the Claude name at the hook boundary, so the Bash guards need no tool-name map. The allow-only `pre-bash-staging-fence.mjs` is wired on that basis. For the Edit/Write matchers (`apply_patch`) the vocabulary question is still unmeasured.
|
|
190
|
+
|
|
191
|
+
**Codex honours a deny** (#1691, measured 2026-10-20 on codex-cli 0.160.1). `codex exec` with `pre-bash-destructive-guard.mjs` as the only PreToolUse hook and the prompt `printf x > CLAUDE.md` logged `Command blocked by PreToolUse hook: Destructive command blocked: '> CLAUDE.md' (rule: redirect-truncate-protected)`, and `CLAUDE.md` stayed unchanged. The control run with `hooks.PreToolUse=[]` ran the command and the file became `x`. The measured payload carries `session_id`, `turn_id`, `cwd` (the session workdir, which is also the hook's process cwd), `tool_name: "Bash"`, `tool_input.command` and `transcript_path: null`; PostToolUse adds `tool_response: ""`. A real Codex session exports no `CLAUDE_*` variables.
|
|
192
|
+
|
|
193
|
+
Each Bash hook was then fed that payload and wired only where it enforces on it:
|
|
194
|
+
|
|
195
|
+
| Hook | On Codex | Why |
|
|
196
|
+
|---|---|---|
|
|
197
|
+
| `pre-bash-destructive-guard.mjs` | wired | denies `> CLAUDE.md` |
|
|
198
|
+
| `pre-bash-sessions-ledger-guard.mjs` | wired | denies a direct write to `.orchestrator/metrics/sessions.jsonl` |
|
|
199
|
+
| `pre-bash-issue-budget.mjs` | wired | with a cap of 1 the second `glab issue create` is denied and parked |
|
|
200
|
+
| `enforce-commands.mjs` | wired | applies `blockedCommands` from `.codex/wave-scope.json` |
|
|
201
|
+
| `pre-bash-memory-propose-audit.mjs` | wired | appends its audit event (observe-only by design) |
|
|
202
|
+
| `post-bash-write-verify.mjs` (PostToolUse) | wired | reports a write outside `allowedPaths` (warn-only by design) |
|
|
203
|
+
| `pre-bash-templates-first.mjs` | **not wired** | it can only deny there: the template-Read proof needs `transcript_path`, which Codex sends as `null`, and `/templates-ack` needs a `claude` parent process |
|
|
204
|
+
| `post-bash-issue-budget-refund.mjs` | n/a | runs on `PostToolUseFailure`, which Codex does not have; a failed create keeps its budget slot |
|
|
182
205
|
|
|
183
|
-
|
|
206
|
+
What this still leaves open: **the file-scope guard is behavioural only on Codex today**, because the Edit/Write guards need an `apply_patch` payload adapter. `tests/hooks/codex-bash-guards-wiring.test.mjs` runs every registered Bash command on the measured payload.
|
|
184
207
|
|
|
185
208
|
These per-event gaps are tracked as documented asymmetries in `scripts/lib/validate/check-hooks-symmetry.mjs` (Check 6, `handlerAsymmetries`) — an UNDOCUMENTED one-platform-only handler fails validation.
|
|
186
209
|
|
|
187
|
-
An empty `
|
|
210
|
+
An empty `SubagentStart` array means the event belongs to the validated Codex surface but currently has no payload-compatible handler. It does not mean installation or hook trust failed.
|
|
188
211
|
|
|
189
212
|
## Usage
|
|
190
213
|
|
|
191
214
|
After installation or refresh, start a fresh task. In the desktop composer, open the skill picker, search for `go` or `close`, and select the matching **Session Orchestrator** entry. In Codex CLI or the IDE extension, use `/skills` or mention the namespaced skill directly in your prompt. [OpenAI skill invocation](https://learn.chatgpt.com/docs/build-skills)
|
|
192
215
|
|
|
193
216
|
```text
|
|
217
|
+
$session-orchestrator:bootstrap # once per repository, before the first session
|
|
194
218
|
$session-orchestrator:session # start with the deep default
|
|
195
219
|
$session-orchestrator:session housekeeping # maintenance session
|
|
196
220
|
$session-orchestrator:session deep # explicit deep session
|
package/docs/components.md
CHANGED
|
@@ -57,7 +57,7 @@ Codex uses the curated six-event project subset `SessionStart`, `PreToolUse`, `P
|
|
|
57
57
|
|
|
58
58
|
- **Output Styles (3):** `session-report`, `wave-summary`, `finding-report`.
|
|
59
59
|
- **Policy & rules:** `.orchestrator/policy/blocked-commands.json` (destructive-command rules); `.claude/rules/parallel-sessions.md` (PSA-001..PSA-004).
|
|
60
|
-
- **Destructive-command guard.** On Claude Code, the active `hooks/pre-bash-destructive-guard.mjs` applies `.orchestrator/policy/blocked-commands.json` in the main session and in subagent waves. The policy has
|
|
60
|
+
- **Destructive-command guard.** On Claude Code, the active `hooks/pre-bash-destructive-guard.mjs` applies `.orchestrator/policy/blocked-commands.json` in the main session and in subagent waves. The policy has 13 blocking rules (`git reset --hard`, `rm -rf`, `git push --force`, deletion of `.orchestrator/metrics/**`, and more) and 4 warning rules. Cursor and Pi use event bridges with documented limits; On Codex the same hook runs as a `PreToolUse` Bash hook, and Codex honours its deny (measured 2026-10-20, codex-cli 0.160.1, #1691). Scope `enforcement: warn` or `off` does not change the separate destructive-command policy — see [Platform support](../README.md#platform-support). Where the hook is active, bypass it per session only for intentional maintenance by setting `allow-destructive-ops: true` in Session Config. The rule source of truth is [`.claude/rules/parallel-sessions.md`](https://github.com/Kanevry/session-orchestrator/blob/main/.claude/rules/parallel-sessions.md) (PSA-003), vendored to consumer repos via `/bootstrap`.
|
|
61
61
|
- **Import probe.** `hooks/post-edit-import-probe.mjs` (PostToolUse on `Edit`/`Write`/`MultiEdit`) guards the other direction: a hook-reachable helper saved in a broken intermediate state makes *every* Bash/Edit/Write call fail with an internal hook error, host-wide, for every session sharing the working copy. Right after such a file is saved the probe runs ESLint `no-undef` on it (plus a child-process `import()` for `scripts/lib/**`) and reports the blast radius; it never blocks and always exits 0. It only fires for files listed in the committed allowlist [`hooks/_lib/hook-import-set.json`](../hooks/_lib/hook-import-set.json), regenerated by `node scripts/generate-hook-import-set.mjs`. Kill switch: `SO_DISABLED_HOOKS=post-edit-import-probe`.
|
|
62
62
|
- **Process-group kill + orphan reaper.** Both quality-gate paths spawn their commands `detached: true`, so the whole process GROUP is killed on timeout (SIGTERM → grace → SIGKILL, exit 124) instead of only the shell — the shell's own children used to be reparented to PID 1 and keep running. Every gate process this repo starts is recorded in `.orchestrator/runtime/gate-processes.jsonl`; `hooks/post-tool-batch-wave-signal.mjs` and `hooks/on-stop.mjs` trigger a throttled, detached orphan scan that reaps only what that register claims. Ships inert (`reaper.enabled: false`, `reaper.mode: report`) until its firing rate is measured — rule [`.claude/rules/host-resources.md`](../.claude/rules/host-resources.md) § HR-107, rationale [ADR-0015](adr/0015-process-group-kill-and-orphan-reaper.md), audit trail `.orchestrator/metrics/reaper-audit.jsonl`.
|
|
63
63
|
- **ADR-0016 Cross-session messaging.** Adopt for the live cross-session axis (CSM-001..005), Spike for Remote Control (#1056, closed negative); anchors "entries vs messages" — files hold state, messages are hints — rationale [ADR-0016](adr/0016-cross-session-messaging.md).
|
|
@@ -72,13 +72,24 @@ Codex uses the curated six-event project subset `SessionStart`, `PreToolUse`, `P
|
|
|
72
72
|
|
|
73
73
|
`scripts/harness-audit.mjs` runs **9 deterministic categories / 38 checks** over a repo and emits `.orchestrator/metrics/audit.jsonl`. Category 8 ("Large-Codebase Readiness") operationalises Anthropic's [Claude Code large-codebase best-practices](https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start) checklist — layered `CLAUDE.md` (or `AGENTS.md`), codebase-map presence, LSP/code-intelligence wiring, scoped test/lint commands, `permissions.deny`, and root-file leanness — as scored signals you can run on yourself and on consumer repos. Category 9 ("Skill-Health Surfacing") surfaces the #648 per-skill health pipeline — telemetry hygiene, scorer wiring, and an advisory-only verdict tally that never affects points; non-adoption always scores full points. These checks are intentionally orthogonal to repo-audit's baseline-compliance pass/fail; both surfaces ship.
|
|
74
74
|
|
|
75
|
+
## Design choices
|
|
76
|
+
|
|
77
|
+
- **The wave order is deliberate.** Discovery runs first so every implementer starts from the same picture of the code. Impl-Core runs before Impl-Polish so the structure exists before anything integrates against it. The Quality wave simplifies generated code *before* tests are written; write the tests first and they assert whatever the model produced, so changing it later means rewriting the tests too.
|
|
78
|
+
- **Checks run after each implementation wave, not only at the end.** A mistake caught after wave 2 costs one wave. The same mistake found at `/close` has already been copied into every wave after it. Findings below the configured confidence threshold are not shown to you.
|
|
79
|
+
- **A crash does not lose the session.** `STATE.md` records which wave finished and what deviated from the plan. The next `/session` offers to continue from the last completed wave.
|
|
80
|
+
- **Two sessions in one working copy is treated as a real risk.** Two people, or two of your own sessions, in the same checkout share one git index, one filesystem and one `STATE.md`, and neither can see the other's uncommitted work. A heartbeat session lock, per-agent file-scope manifests, and the rules in [`.claude/rules/parallel-sessions.md`](../.claude/rules/parallel-sessions.md) exist for exactly that case.
|
|
81
|
+
- **Guards run where the harness supports them, and the [platform table](../README.md#platform-support) says where they do not.** The destructive-command policy (13 rules block, 4 warn) runs as a real hook on Claude Code and Codex and as a bridge on Cursor and Pi; file-scope enforcement is a hook on Claude Code, a bridge on Cursor and Pi, and instructions only on Codex (see [Other surfaces](#other-surfaces)).
|
|
82
|
+
- **What it learns is opt-in and readable.** Every session appends a record. After 5 or more sessions, `/evolve analyze` proposes patterns with a confidence score; you read them and delete the ones you disagree with. Nothing is applied without you.
|
|
83
|
+
- **GitLab and GitHub, both fully.** It detects which one your remote points at and drives issues and merge or pull requests for either.
|
|
84
|
+
- **No build step.** Skills, commands and agents are Markdown with YAML frontmatter; the code that dispatches, validates and records runs in `scripts/lib/*.mjs` and `hooks/*.mjs`. When a session does something you did not expect, you can open the file that decided it.
|
|
85
|
+
|
|
75
86
|
## Comparisons
|
|
76
87
|
|
|
77
88
|
Moved here from the README so that a claim about another project can carry its measurement next to it. Every row below names when and how it was measured; rows that could not be measured were **removed rather than softened** — an unverifiable comparison row is worse than none.
|
|
78
89
|
|
|
79
90
|
### vs. `open-gsd/gsd-core`
|
|
80
91
|
|
|
81
|
-
Surface counts measured 2026-09-06 by this repo's 360° ecosystem probe (
|
|
92
|
+
Surface counts measured 2026-09-06 by this repo's 360° ecosystem probe (GitHub-overlap report of the 2026-09-06 360° audit; audit reports stay in the private GitLab repository and are not part of the public mirror); session-orchestrator's own counts measured the same day with the commands listed in the [README](../README.md#what-you-get).
|
|
82
93
|
|
|
83
94
|
| Axis | session-orchestrator | `open-gsd/gsd-core` |
|
|
84
95
|
|---|---|---|
|