From session-orchestrator
Initializes project sessions by autonomously analyzing git state, VCS issues, SSOT files, branches, environment, and cross-repo status; presents structured findings, recommendations, and wave plan. Triggered by /session [housekeeping|feature|deep].
npx claudepluginhub kanevry/session-orchestrator --plugin session-orchestratorThis skill uses the workspace's default tool permissions.
Before anything else, read and internalize `soul.md` in this skill directory. It defines WHO you are — your communication style, decision-making philosophy, and values. Every interaction in this session should reflect this identity. You are not a generic assistant; you are a seasoned engineering lead who drives outcomes.
Guides strict Test-Driven Development (TDD): write failing tests first for features, bugfixes, refactors before any production code. Enforces red-green-refactor cycle.
Guides systematic root cause investigation for bugs, test failures, unexpected behavior, performance issues, and build failures before proposing fixes.
Guides A/B test setup with mandatory gates for hypothesis validation, metrics definition, sample size calculation, and execution readiness checks.
Before anything else, read and internalize soul.md in this skill directory. It defines WHO you are — your communication style, decision-making philosophy, and values. Every interaction in this session should reflect this identity. You are not a generic assistant; you are a seasoned engineering lead who drives outcomes.
Read skills/_shared/bootstrap-gate.md and execute the gate check. If the gate is CLOSED, invoke skills/bootstrap/SKILL.md and wait for completion before proceeding. If the gate is OPEN, continue to Phase 1.
Read and parse Session Config per skills/_shared/config-reading.md. Store result as $CONFIG.
Skip this phase if
persistenceconfig isfalse.
Check for <state-dir>/STATE.md in the project root:
Where
<state-dir>is.claude/under Claude Code or.codex/under Codex CLI. Seeskills/_shared/platform-tools.mdfor details.
Ownership Reference: See
skills/_shared/state-ownership.mdfor the STATE.md ownership contract, schema, and guards.
Before reading STATE.md contents, validate the branch field:
branch does not match git rev-parse --abbrev-ref HEAD, log: "⚠ STATE.md from branch [X], current branch is [Y] — treating as stale." Skip to step 2 (treat as if STATE.md does not exist).status field:
status: active — previous session crashed or was interrupted. Use the AskUserQuestion tool to present: "Found unfinished session from [started_at]. [N] waves completed. Resume or start fresh?" with options to resume the previous plan or start a new session. After a resume choice, proceed to Snapshot Recovery subsection below.status: paused — session was intentionally paused. Use AskUserQuestion to offer resuming from the pause point or starting fresh. After a resume choice, proceed to Snapshot Recovery subsection below.status: completed — previous session ended cleanly. Note the summary for context (what was done, what was deferred), then reset STATE.md to idle before any new session state is written (see "Idle Reset" below). Continue with normal initialization.When (and only when) the prior status is completed, rewrite STATE.md to a clean idle state before Phase 1b (Initialize STATE.md) runs. This prevents the next agent from reading a stale "completed" banner at session-start, while preserving the prior session's record in a demoted archive block.
Reset rules — applies ONLY on the completed branch. Do NOT perform this reset on active or paused; those paths stay user-interactive via AskUserQuestion.
status: idle.current-wave (set to 0).## Wave History body into a new ## Previous Session archive section (retain the record, but demote it below the new session's live state). Remove the original ## Wave History section — wave-executor will recreate it on the next wave.## Deviations (leave the heading with an empty body so the schema is preserved).schema-version, session-type, branch, issues, started_at, total-waves) intact until Phase 1b overwrites them with the new session's values.Rationale: /close intentionally keeps STATE.md as a record so the next session-start can read it. This reset completes that contract by demoting the record before new session state is written, so a fresh session never appears "already completed".
Applies ONLY after the user chose to resume from the active/paused branch above. Skip entirely on the completed branch (snapshots for completed sessions are GC'd by session-end, not offered for recovery) and on the "start fresh" path of an active/paused prompt (starting fresh implies abandoning any snapshot).
import { listSnapshots, deleteSnapshot } from '$PLUGIN_ROOT/scripts/lib/coordinator-snapshot.mjs';
const snaps = await listSnapshots({ sessionId: '<sessionId from STATE.md>' });
If snaps.length === 0 → no snapshots to recover; continue to the Current-Task Banner.
If snaps.length >= 1 → present the following choice:
Claude Code (AskUserQuestion):
AskUserQuestion({
questions: [{
question: `Found ${snaps.length} coordinator snapshot(s) from the resumed session (latest from ${humanAgeOf(snaps[0].createdAt)}). Recover, keep as backup, or discard?`,
header: "Snapshot",
multiSelect: false,
options: [
{ label: "Recover (diff vs current tree) (Recommended)", description: "Apply the latest snapshot back onto the working tree. You will see a diff and can unstage unwanted changes before committing." },
{ label: "Keep as backup", description: "Leave refs/so-snapshots/* in place untouched. You can recover manually later via `git stash apply $(git rev-parse <ref>)`." },
{ label: "Discard all", description: "Delete all refs/so-snapshots/<sessionId>/* immediately via deleteSnapshot." },
],
}],
});
Codex CLI / Cursor IDE fallback (numbered Markdown list):
Snapshot recovery options:
1. **Recover (Recommended)** — Apply the latest snapshot back onto the working tree. You will see a diff and can unstage unwanted changes before committing.
2. **Keep as backup** — Leave the refs in place untouched. You can recover manually later.
3. **Discard all** — Delete all refs/so-snapshots/<sessionId>/* immediately.
Reply with the number of your choice.
On user choice:
git stash apply <snaps[0].sha> (use apply, not pop — leaves the ref intact in case the user changes their mind). Then show the resulting git diff --stat so the user sees what landed.Snapshot(s) retained: <N>. Recover manually with \git stash apply `.`snaps, call deleteSnapshot({refName: snap.ref}). Log count.Snapshot age (humanAgeOf) is derived from snap.createdAt (ISO 8601 from git for-each-ref --format='%(committerdate:iso8601)'). A simple inline helper:
function humanAgeOf(iso) {
const mins = Math.floor((Date.now() - new Date(iso).getTime()) / 60000);
if (mins < 60) return `${mins}m ago`;
const hrs = Math.floor(mins / 60);
if (hrs < 24) return `${hrs}h ago`;
return `${Math.floor(hrs / 24)}d ago`;
}
After the continuity checks above, render a one-line banner showing the current task from STATE.md. This gives the user an immediate "where am I" signal before the rest of the session overview loads.
node --input-type=module -e "
import {readFileSync} from 'node:fs';
import {readCurrentTask} from '${PLUGIN_ROOT}/scripts/lib/state-md.mjs';
try {
const t = readCurrentTask(readFileSync('<state-dir>/STATE.md', 'utf8'));
if (t) console.log('Current task: ' + t.description);
} catch {}
"
Skip silently when STATE.md is absent or unreadable. The banner is informational, not load-bearing.
Also read <state-dir>/STATUS.md if it exists for additional project-level context.
Skip if
persistenceconfig isfalse.
<state-dir>/metrics/ where <state-dir> is .claude/, .codex/, or .cursor/ per platform).<state-dir>/metrics/sessions.jsonl as a platform-specific legacy fallback.Run these checks in parallel using Bash:
git branch -a, current branch, ahead/behind origingit log --oneline -N where N is read from recent-commits config (default: 20) — identify last session's work by commit patternsgit status --short + git log origin/main..HEAD --onelinestale-branch-days (default: 7) daysSkip this phase if
docs-orchestrator.enabledconfig is nottrue(default:false).
Read the three controlling fields from $CONFIG using the canonical jq accessor pattern:
DOCS_ENABLED=$(echo "$CONFIG" | jq -r '."docs-orchestrator".enabled // false')
DOCS_AUDIENCES=$(echo "$CONFIG" | jq -r '."docs-orchestrator".audiences // ["user","dev","vault"] | join(",")')
DOCS_MODE=$(echo "$CONFIG" | jq -r '."docs-orchestrator".mode // "warn"')
Valid values for mode: warn | strict | off. Never use hard.
If DOCS_ENABLED is not true, skip all remaining steps in this phase and proceed directly to Phase 3.
Using signals already gathered in Phases 2–5 (git analysis, VCS issues, branch state, SSOT checks), apply the following heuristic to determine which audiences are likely affected. Record each match with its triggering signal for inclusion in the output block.
User audience — flag as likely when any of the following are true:
README.md, docs/user/**/*.md, docs/getting-started.md, or examples/**/*.mdcommands/ directory)Dev audience — flag as likely when any of the following are true:
CLAUDE.md, docs/dev/**/*.md, or docs/adr/**/*.md.mjs scripts, skill files (skills/**), hook files (hooks/**), or agent definitions (agents/**) are added or substantially changedVault audience — flag as likely when ALL of the following are true:
vault-integration.enabled: true is present in $CONFIGAfter detection, intersect the detected set with the audiences listed in DOCS_AUDIENCES (the user may have narrowed the allowed set in config). If the intersection is empty, proceed to Step 3 without pre-selecting any option as "Recommended" and add a note that no audiences were auto-detected.
See skills/docs-orchestrator/audience-mapping.md for the authoritative audience → file-pattern and trigger table.
Present the audience confirmation using the platform-appropriate interaction pattern.
Claude Code (AskUserQuestion):
Mark the auto-detected primary audience (or audiences, if multiple) with (Recommended). multiSelect: true because a single change commonly touches more than one audience.
AskUserQuestion({
questions: [{
question: "Welche Audiences berührt dieser Scope? (Mehrfachauswahl möglich)",
header: "Audiences",
multiSelect: true,
options: [
{
label: "Dev (Recommended)", // add "(Recommended)" to each detected audience
description: "Architektur-, Modul- oder Refactoring-Änderungen — aktualisiert CLAUDE.md, docs/dev/**, docs/adr/**."
},
{
label: "User",
description: "Öffentlich sichtbare Änderungen — aktualisiert README.md, docs/user/**, examples/**."
},
{
label: "Vault",
description: "Strategische oder Status-Änderungen — aktualisiert <vault>/01-projects/<slug>/context.md, decisions.md, people.md."
}
]
}]
})
Codex CLI / Cursor IDE fallback (numbered Markdown list):
Welche Audiences berührt dieser Scope? (Mehrfachauswahl möglich)
Auto-detected: [dev] ← list detected audiences here, or "none" if empty intersection
1. **Dev (Recommended)** — Architektur-, Modul- oder Refactoring-Änderungen. Targets: CLAUDE.md, docs/dev/**, docs/adr/**.
2. **User** — Öffentlich sichtbare Änderungen. Targets: README.md, docs/user/**, examples/**.
3. **Vault** — Strategische oder Status-Änderungen. Targets: <vault>/01-projects/<slug>/context.md, decisions.md, people.md.
Enter one or more numbers (comma-separated), or press Enter to accept the recommended default.
Store the confirmed audience list as CONFIRMED_AUDIENCES.
After the user confirms (or defaults are accepted), emit the following delimited block verbatim into the conversation context. This block is the contract between Phase 2.5 and session-plan Step 1.8 — session-plan MUST parse it to classify tasks as Docs role and route them to the docs-writer agent.
### Docs Planning Result (Phase 2.5)
Audiences: [<comma-separated confirmed audiences, e.g. dev, user>]
Detected-from: [<comma-separated detection signals, e.g. affected-files, issue-labels>]
Mode: <warn|strict|off>
Docs-tasks-seed:
- audience: "dev"
rationale: "<one-line reason derived from detection signal, e.g. 'new skill scaffolded in skills/docs-orchestrator'>"
- audience: "user"
rationale: "<one-line reason, or omit entry if audience not confirmed>"
Session-plan Step 1.8 identifies this block by the exact heading ### Docs Planning Result (Phase 2.5) and reads Audiences: and Docs-tasks-seed: to seed the Docs role task list. Parse rule for Docs-tasks-seed:: each top-level - audience: bullet is exactly one seed task; parse all entries in document order; the following indented rationale: key binds to the most recent - audience:. If this block is absent (phase was skipped), session-plan MUST NOT create any Docs role tasks.
docs-orchestrator MUST NOT write to the following paths — they are owned by sibling skills:
<vault>/01-projects/*/_overview.md — owned by vault-mirror (regenerated from JSONL on every session-end)<vault>/03-daily/* — owned by daily (idempotent day-level notes; a second writer would corrupt the file)See skills/docs-orchestrator/audience-mapping.md (Non-Overlap with Sibling Skills table) for the complete ownership list and source-citation rules.
Proceed to Phase 3.
VCS Reference: Detect the VCS platform per the "VCS Auto-Detection" section of the gitlab-ops skill. Use CLI commands per the "Common CLI Commands" section. For cross-project queries, see "Dynamic Project Resolution."
Using the detected VCS CLI, query (reading issue-limit from Session Config, default: 50):
Group issues by:
priority:critical / priority:high — must-addressstatus:ready — ready to work onSSOT freshness: for each file in ssot-files config, check last modified date. Flag if older than ssot-freshness-days (default: 5) days.
Quality baseline: Run Baseline quality checks per the quality-gates skill. Commands are resolved in this order (issue #183):
a. .orchestrator/policy/quality-gates.json — preferred source when present.
b. Session Config test-command / typecheck-command / lint-command — fallback.
c. Hardcoded defaults: pnpm test --run, tsgo --noEmit, pnpm lint.
Before running, perform a command-availability check: for each resolved command, extract the binary (first token) and run command -v <binary>. If absent, skip that check and log ⚠ Quality baseline: <binary> not found — skipping <variant>. Report results but do not block the session.
Pencil design status: if pencil is configured, verify the .pen file exists at the configured path. Report: "Pencil design configured at [path] — design-code alignment reviews will run after Impl-Core and Impl-Polish waves." If file not found, warn: "Pencil path configured but file not found at [path]."
Plugin freshness: Determine the session-orchestrator plugin directory (navigate up from this skill's base directory to the plugin root). Run git -C <plugin-dir> log -1 --format="%ci" to get the last commit date. If older than plugin-freshness-days (default: 30) days, flag a warning in the Session Overview: "⚠ Session Orchestrator plugin last updated [N] days ago — consider pulling the latest version." Non-blocking — present in overview, don't halt.
Additionally, if .orchestrator/bootstrap.lock exists in the current repo, invoke the bootstrap-lock-freshness probe (scripts/lib/bootstrap-lock-freshness.mjs) to check lock age and plugin-version drift. When severity is warn or alert, render an additional banner alongside the plugin-freshness warning:
"⚠ bootstrap.lock: age=<N>d, plugin-version=<lock-ver> (current=<plugin-ver>) — consider re-running /bootstrap --retroactive to refresh.""⚠ bootstrap.lock: <message> — re-run /bootstrap --retroactive is strongly recommended."Both banners are non-blocking — display in the Session Overview, do not halt the session. If bootstrap-lock-freshness.mjs is absent (pre-#186 plugin install), skip silently.
For each repo in cross-repos:
cd ~/Projects/<repo> && git log --oneline -5 && git status --shortLook across the gathered data for:
stale-issue-days (default: 30) days without progress → flag for triageSkip this phase if
persistenceconfig isfalse.
Platform Note: Session memory files at
~/.claude/projects/are a Claude Code feature. On Codex CLI and Cursor IDE, skip this phase — per-project memory persistence is not available on those platforms.
Surface context from previous sessions:
~/.claude/projects/<project>/memory/session-*.mdmemory-cleanup-threshold has been reached (number of session-*.md files >= threshold), include a note in the Session Overview: "Consider running /memory-cleanup — [N] session memory files accumulated."Skip if
persistenceconfig isfalseor.orchestrator/metrics/learnings.jsonldoes not exist. If the canonical file is absent and a legacy<state-dir>/metrics/learnings.jsonlstill exists, do not read it — direct the user to runscripts/migrate-legacy-learnings.shonce to migrate.
Read .orchestrator/metrics/learnings.jsonl and surface active learnings (confidence > 0.3, not expired):
confidence DESC, then created_at DESC as tiebreaker. Slice to the first learnings-surface-top-n entries (default 15). Only the surfaced subset is used for the grouping below. Record the full pre-cap active count M (confidence > 0.3, not expired) and the surfaced count N for the Surface Health section.Present a Surface Health block immediately after the per-type grouping, before the Project Intelligence section. Use the values computed in step 1 (M = active count pre-cap, N = surfaced count = learnings-surface-top-n):
Compute confidence buckets across the full active set (M entries, confidence > 0.3, not expired):
confidence >= 0.7confidence >= 0.5 and < 0.7confidence > 0.3 and < 0.5Present the block using this template (substitute {M}, {N}, {M - N}, bucket counts, oldest values, and paths):
**Project Intelligence — Surface Health**
Active learnings: {M} (high: {high-count} / medium: {med-count} / low: {low-count})
Surfaced this session: {N} | Suppressed: {M - N}
Oldest surfaced: {oldest-created_at ISO 8601} ({relative-age} days ago)
Source file: .orchestrator/metrics/learnings.jsonl
Vault mirror: {vault-dir value from Session Config, or "not enabled" if absent/empty}
Oldest surfaced entry: find the entry among the top-N surfaced learnings with the smallest created_at value. Display the raw ISO 8601 timestamp and compute relative age as floor((current_date - created_at) / 86400) days.
Vault mirror: read vault-integration.vault-dir from Session Config (echo "$CONFIG" | jq -r '."vault-integration"."vault-dir" // empty'). If the value is absent or empty, print "not enabled".
Conditional advisory — print the following line only when {M - N} > {N} (i.e., suppressed count exceeds surfaced count):
⚠ More learnings are suppressed ({M - N}) than surfaced ({N}). Consider raising
learnings-surface-top-nin Session Config or running/evolve reviewto prune low-value entries. Do NOT print the advisory when{M - N} <= {N}.
Include a Project Intelligence section in the Phase 7 presentation:
## Project Intelligence (from [N] learnings)
- Fragile: [files] (confidence: [X])
- Sizing: [recommendation]
- Watch: [recurring issues]
- Scope: [guidance]
If no active learnings exist, display: "No project intelligence yet — learnings accumulate after 2+ sessions."
Effectiveness analysis (requires 5+ sessions in sessions.jsonl):
Skip if
.orchestrator/metrics/sessions.jsonldoes not exist or has fewer than 5 entries.
Read .orchestrator/metrics/sessions.jsonl and compute:
effectiveness.completion_rate over last 5 sessions
discovery_stats, check each category in by_category:
findings == 0 across 3+ sessions: "Probe category '[X]' has produced no findings in [N] sessions. Consider excluding via discovery-probes config."findings > 5 consistently but issues are rarely created from that category: "Probe category '[X]' generates many findings ([avg]) but few lead to issues. Consider raising discovery-severity-threshold or discovery-confidence-threshold."effectiveness.carryover / planned_issues > 0.3 across 3+ sessions:
"High carryover rate ([X]%). Consider: smaller scope, longer sessions (deep), or splitting across sessions."If fewer than 5 sessions exist: "Effectiveness analysis: not enough data yet ([N]/5 sessions)."
Include effectiveness insights in the Project Intelligence section of the Phase 7 presentation:
## Project Intelligence (from [N] learnings, [M] sessions)
- Fragile: [files] (confidence: [X])
- Sizing: [recommendation]
- Watch: [recurring issues]
- Scope: [guidance]
- Effectiveness: [completion rate trend, probe value, carryover pattern]
Note: Implementation-specific research (library APIs, best practices for specific code changes) is deferred to session-plan, which knows the exact scope. Session-start focuses on state analysis.
For feature and deep sessions:
For housekeeping sessions:
bash "${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-$PLUGIN_ROOT}}/scripts/token-audit.sh" and include findings in Session Overview. Flag any HIGH/WARN items as recommended housekeeping tasks.Read presentation-format.md in this skill directory for the output structure, templates, and AskUserQuestion examples.
Present your findings following that structure. Key rules:
After user alignment:
run_in_background: false for parallel subagent work — wait for completion.env or .env.local for VCS host, API keys, and service URLsfilePath parameter, work only on new designs, treat completed ones as done| File | Purpose |
|---|---|
soul.md | Identity and communication principles |
presentation-format.md | Phase 7 output templates and AskUserQuestion examples |