From session-orchestrator
Extracts session patterns into reusable learnings. Modes: analyze (from history), review (edit/manage), list (display). Manages .orchestrator/metrics/learnings.jsonl.
npx claudepluginhub kanevry/session-orchestrator --plugin session-orchestratorThis skill uses the workspace's default tool permissions.
> **Platform Note:** State files use the platform's native directory: `.claude/` (Claude Code), `.codex/` (Codex CLI), or `.cursor/` (Cursor IDE). Shared metrics live in `.orchestrator/metrics/` (v2) with fallback to `<state-dir>/metrics/` for pre-v2.0 legacy data. See `skills/_shared/platform-tools.md`.
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.
Platform Note: State files use the platform's native directory:
.claude/(Claude Code),.codex/(Codex CLI), or.cursor/(Cursor IDE). Shared metrics live in.orchestrator/metrics/(v2) with fallback to<state-dir>/metrics/for pre-v2.0 legacy data. Seeskills/_shared/platform-tools.md.
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.
Extract persistence from $CONFIG. If persistence is false, abort with message:
"Learnings require persistence to be enabled in Session Config. Add
persistence: trueto your Session Config block (CLAUDE.md for Claude Code, AGENTS.md for Codex CLI)."
Read mode from $ARGUMENTS:
analyzeanalyze, review, listLazy-create defensive (#185): If .orchestrator/metrics/learnings.jsonl does not exist (pre-#185 repo or bootstrap skipped), create an empty file and emit an info log — do NOT hard-fail:
LEARNINGS_FILE=".orchestrator/metrics/learnings.jsonl"
if [[ ! -f "$LEARNINGS_FILE" ]]; then
mkdir -p "$(dirname "$LEARNINGS_FILE")"
: > "$LEARNINGS_FILE"
echo "info(#185): auto-created $LEARNINGS_FILE (was missing)" >&2
fi
This defensive step is idempotent and cheap — it ensures /evolve analyze|review|list never fails because of a missing artifact file.
.orchestrator/metrics/sessions.jsonl (session history). If it does not exist, check <state-dir>/metrics/sessions.jsonl as a legacy fallback (where <state-dir> is .claude/, .codex/, or .cursor/ per platform). If neither exists, warn: "No session history found. Run at least one session first.".orchestrator/metrics/learnings.jsonl if it exists. If not found, check <state-dir>/metrics/learnings.jsonl as a legacy fallback.expires_at < current date (expired)Route based on mode:
analyze → Phase 3review → Phase 4list → Phase 5Extract learnings from session history.
Vault Integration: If
vault-integration.enabledistruein Session Config, confirmed learnings are mirrored to the configured Obsidian vault after the atomic write (Step 3.5, step 9). Seedocs/session-config-reference.mdfor thevault-integrationconfig block.
.orchestrator/metrics/sessions.jsonl (or <state-dir>/metrics/sessions.jsonl if the v2 path does not exist — see Phase 1.4 fallback)completed_at descending (most recent first)For each of the 6 learning types, apply these heuristics:
fragile-file)files_changed within a session, it is fragilefiles_changed, flag iteffective-sizing)total_agents and total_waves across session typesdeep-session-sizing or feature-session-sizingrecurring-issue)agent_summary — if failed or partial > 0 across multiple sessions, flagquality fields — repeated failures indicate recurring issuesscope-guidance)effectiveness.planned_issues vs effectiveness.completion_rateeffectiveness field (early sessions may not have it)optimal-scope-per-session-typedeviation-pattern)Ownership Reference: See
skills/_shared/state-ownership.md. evolve has read-only access to STATE.md.
<state-dir>/STATE.md if it exists and check ## Deviations sectionstagnation-class-frequency)stagnation_events from the most recent 5 sessions in sessions.jsonl (skip sessions lacking the field — they predate #84).(file, error_class) pair appearing in ≥2 sessions, extract a candidate:
<file>:<error_class> (e.g., skills/wave-executor/wave-loop.md:edit-format-friction)If no patterns were extracted across all 6 types, report: "No patterns found in session history. This can happen with very few sessions or sessions that lack detailed wave/agent data." and skip to end (do not proceed to AskUserQuestion).
For each extracted pattern, check if a learning with same type + subject already exists in learnings.jsonl:
Present extracted patterns to the user for confirmation. Use AskUserQuestion with multiSelect: true:
On Codex CLI where AskUserQuestion is unavailable, present as a numbered Markdown list.
AskUserQuestion({
questions: [{
question: "Which learnings should be saved?\n\nExtracted patterns from session history:",
header: "Evolve — Confirm Learnings",
options: [
{
label: "[type] subject",
description: "insight | evidence: ... | confidence: 0.5 (new) or +0.15 (update)"
},
...
{
label: "Skip all",
description: "Do not save any learnings this time"
}
],
multiSelect: true
}]
})
If user selects "Skip all" or selects nothing, abort gracefully: "No learnings saved."
For confirmed learnings, use atomic rewrite strategy:
Read ALL existing lines from .orchestrator/metrics/learnings.jsonl (if exists) into memory. If not found, check <state-dir>/metrics/learnings.jsonl as a legacy fallback. If legacy data is found, it will be migrated to the v2 path on write (step 8).
Apply confidence updates for confirmed existing learnings:
expires_at to current date + learning-expiry-days (default: 30)Apply confidence decrements for contradicted learnings (-0.2) — do NOT reset expires_at for contradicted learnings (let them decay naturally)
Append new learnings with:
id: generate a uuid-v4 (use uuidgen or equivalent)type: one of fragile-file, effective-sizing, recurring-issue, scope-guidance, deviation-pattern, stagnation-class-frequencysubject: the pattern subjectinsight: human-readable description of the patternevidence: specific data points that support the patternconfidence: 0.5 for new learningssource_session: session ID from which the pattern was extractedcreated_at: current ISO 8601 dateexpires_at: current date + learning-expiry-days (default: 30) (ISO 8601)Verify write: Read back the first line of the written file to confirm valid JSON. If read-back fails or is not valid JSON, report error to user.
Prune: remove entries where expires_at < current date OR confidence <= 0.0
Consolidate duplicates: if same type + subject appears more than once, keep the entry with highest confidence
Write entire result back to .orchestrator/metrics/learnings.jsonl with > (atomic rewrite, NOT append >>)
Vault mirror (conditional): Check $CONFIG."vault-integration".enabled via jq. If the field is missing or false, skip this step entirely — skill behavior is unchanged.
If enabled is true:
a. Check $CONFIG."vault-integration".mode. If mode is off, skip the mirror invocation (treat as disabled). If mode is absent, default to warn.
b. Resolve the vault directory: use $CONFIG."vault-integration"."vault-dir" if non-null, otherwise fall back to the $VAULT_DIR environment variable. If neither is set, emit a warning and skip.
c. Invoke the mirror script:
node "$PLUGIN_ROOT/scripts/vault-mirror.mjs" \
--vault-dir "<vault-dir>" \
--source .orchestrator/metrics/learnings.jsonl \
--kind learning
d. Handle the exit code according to mode:
warn (default): on non-zero exit, surface a warning in evolve output (e.g. "Warning: vault mirror failed — learnings saved locally but not mirrored.") but do NOT fail the skill.strict: on non-zero exit, fail the skill immediately and report the error to the user.e. On success (exit 0), report: "Mirrored N learnings to <vault-dir>/40-learnings/."
Report: "Saved N new learnings, updated M existing. Total active: K."
Interactive management of existing learnings.
.orchestrator/metrics/learnings.jsonl. If not found, check <state-dir>/metrics/learnings.jsonl as a legacy fallback./evolve analyze first."Present a formatted table grouped by type:
## Active Learnings
| # | Type | Subject | Confidence | Expires | Insight |
|---|------|---------|------------|---------|---------|
| 1 | fragile-file | src/lib/auth.ts | 0.80 | 2026-07-05 | Changed in 4 of last 5 sessions |
| 2 | effective-sizing | feature-session-sizing | 0.65 | 2026-06-20 | Feature sessions work well with 3 agents/wave |
| ... | ... | ... | ... | ... | ... |
Summary: N active learnings (M high confidence, K expiring soon)
Use AskUserQuestion with options:
On Codex CLI where AskUserQuestion is unavailable, present as a numbered Markdown list.
AskUserQuestion({
questions: [{
question: "What would you like to do with your learnings?",
header: "Evolve — Review",
options: [
{ label: "Boost confidence", description: "Select learnings to boost (+0.15)" },
{ label: "Reduce confidence", description: "Select learnings to reduce (-0.2)" },
{ label: "Delete specific learnings", description: "Select learnings to remove" },
{ label: "Extend expiry", description: "Reset expires_at by learning-expiry-days from now" },
{ label: "Done — no changes", description: "Exit without changes" }
]
}]
})
If user selects "Boost confidence", "Reduce confidence", "Delete specific learnings", or "Extend expiry", present a follow-up AskUserQuestion with multiSelect: true listing all learnings by # | type | subject so the user can select which ones to modify.
On Codex CLI where AskUserQuestion is unavailable, present as a numbered Markdown list.
Use the same atomic rewrite strategy as Phase 3, Step 3.5:
learnings.jsonllearning-expiry-dayslearning-expiry-daysexpires_at < current date OR confidence <= 0.0> (atomic rewrite)Report: "Updated N learnings. Total active: K."
Simple read-only display.
.orchestrator/metrics/learnings.jsonl. If not found, check <state-dir>/metrics/learnings.jsonl as a legacy fallback./evolve analyze to extract patterns from session history."Display a formatted table grouped by type:
## Active Learnings
### fragile-file
| Subject | Confidence | Expires | Insight |
|---------|------------|---------|---------|
| ... | ... | ... | ... |
### effective-sizing
| Subject | Confidence | Expires | Insight |
|---------|------------|---------|---------|
| ... | ... | ... | ... |
(repeat for each type that has entries)
Display summary line:
N active learnings (M high confidence, K expiring soon)
learnings.jsonl without reading it first — race condition preventionuuidgen or equivalent bash command)expires_at to current date + learning-expiry-days from config (default: 30) for new learnings>) — never append with >>learnings.jsonl — always use atomic rewrite (read all, modify, write all)