Agent skill

Session Retrospective

by jpicklyk in jpicklyk/task-orchestrator

Analyzes the current implementation run — evaluates schema effectiveness, delegation alignment, note quality, and plan-to-execution fit.

MITAuto-check passedProduct & Project Management

Install Session Retrospective

skills CLI
$ npx skills add jpicklyk/task-orchestrator --skill session-retrospective -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jpicklyk/task-orchestrator session-retrospective --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jpicklyk/task-orchestrator.git skills-src && mkdir -p .claude/skills && cp -r skills-src/claude-plugins/task-orchestrator/skills/session-retrospective .claude/skills/session-retrospective && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
session-retrospective
GitHub stars
207
Token cost
~9.5k tokens
SKILL.md length
4,193 words
Files
2 (incl. references)
Skills in repo
28
Repo updated
First seen
Licence
MIT

At a glance

Analyzes the current implementation run — evaluates schema effectiveness, delegation alignment, note quality, and plan-to-execution fit.

  • Works in 10 steps: Mode Check → Gather Scope → Aggregate Note Data → …
  • Says retrospective
  • SKILL.md covers Step 0 — Mode Check, Step 1 — Gather Scope, Step 2 — Aggregate Note Data and Step 3 — Evaluate Across…, plus 4 more sections
  • Calls gh and node

What it does

Session Retrospective is an agent skill from jpicklyk/task-orchestrator. Analyzes the current implementation run — evaluates schema effectiveness, delegation alignment, note quality, and plan-to-execution fit. Captures cross-session trends and proposes improvements when patterns repeat. Use after implementation runs, or when user says 'retrospective', 'session review', 'what did we learn', 'analyze this run', 'how did that go', 'evaluate our process', 'wrap up', 'end of session review'. Also use when the retrospective nudge fires after completetree.

Its SKILL.md is about 9.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/github-feedback.md`).

It sits in Product & Project Management, covering Retrospectives and Session handoff. The repository describes itself as: Server-enforced workflow discipline for AI agents. An MCP server providing persistent work items, dependency graphs, quality gates, and actor attribution. Schemas define what… The licence is MIT.

When your agent uses it

  • Says retrospective
  • What did we learn
  • Analyze this run
  • How did that go

Example prompts

  • “retrospective”
  • “session review”
  • “what did we learn”
  • “/session-retrospective”

Workflow steps

10 steps, taken from the step headings in SKILL.md.

  1. Mode Check
  2. Gather Scope
  3. Aggregate Note Data
  4. Evaluate Across Dimensions
  5. Check Trend Memory
  6. Persist the Retrospective
  7. Update Trend Memory
  8. Create Improvement Proposals
  9. Meta-Evaluation
  10. Report

What it can do on your machine

Read from SKILL.md and the folder at commit 3e83170. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • gh
    • node

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use gh, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Session Retrospective loads about 9.5k tokens when it runs, and up to ~11k if it reads all its reference files. Until then it costs about 126 tokens; SKILL.md has 4,193 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~126
When it runs · the whole SKILL.md, loaded when a task matches
~9.5k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~11k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jpicklyk/task-orchestrator at commit 3e83170, republished under its MIT licence (© jpicklyk). 4,193 words, ~9,471 tokens.

Download SKILL.mdSave it as .claude/skills/session-retrospective/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
session-retrospective
description
Analyzes the current implementation run — evaluates schema effectiveness, delegation alignment, note quality, and plan-to-execution fit. Captures cross-session trends and proposes improvements when patterns repeat. Use after implementation runs, or when user says 'retrospective', 'session review', 'what did we learn', 'analyze this run', 'how did that go', 'evaluate our process', 'wrap up', 'end of session review'. Also use when the retrospective nudge fires after complete_tree.
argument-hint
[optional: root item UUID] [--dry-run to preview without creating items] [--deep: workflow-backed matching, main session only]

Session Retrospective

Structured post-implementation analysis. Evaluates the current run across five dimensions, persists findings in MCP, and maintains cross-session trend memory to surface actionable improvement proposals.


Step 0 — Mode Check

If $ARGUMENTS contains --dry-run, set DRY_RUN = true. In dry-run mode, perform steps 1-4 and render the report (step 9) but skip steps 5-8 (no MCP item creation, no memory updates). Announce at the top of the report: **Dry run** — no items created, no memory updated.


Step 1 — Gather Scope

Determine which items to analyze by collecting distributed session-tracking notes.

1a. Identify items in scope

If $ARGUMENTS contains a UUID (root item ID):

query_items(operation="overview", itemId="<root-uuid>")

This returns the root item and its children. Collect all item UUIDs from the overview.

A supplied root UUID is the authoritative scope — this covers dispatched mode, e.g. a background agent invoked with the root item ID (see the orchestration context's hook-driven Retrospective dispatch, or the retro-trigger hook's background-agent directive). When a root UUID is supplied, run only this overview call and do not run the fallback scan below (neither the get_context calls nor the terminal-items search) — the fallback scan applies only when no UUID argument was provided.

If no root item ID provided:

Check for a known project root: the ## Project Scope section of the session context injected by the SessionStart hook, or a project.rootId entry in the project-level .taskorchestrator/config.yaml. A personal root (## Personal Scope, or the user-level config) is not a project root and takes the unscoped branch below.

If a project rootId is known, scope both fallback calls to that subtree so concurrent runs in other projects sharing the same DB aren't conflated into this retrospective:

get_context(ancestorId="<rootId>") — active, blocked, stalled items within the project subtree
query_items(operation="search", role="terminal", sortBy="modifiedAt", sortOrder="desc", limit=20, modifiedAfter="<ISO now − 24h>", ancestorId="<rootId>")

If no project rootId is configured (including personal scope), fall back to the prior global behavior (unchanged):

get_context() — active, blocked, stalled items
query_items(operation="search", role="terminal", sortBy="modifiedAt", sortOrder="desc", limit=20, modifiedAfter="<ISO now − 24h>")

Build scope from recently completed items. The 24-hour window is applied by the modifiedAfter filter in the call above — list-mode results carry no timestamps (only id, title, tags and role fields), so staleness cannot be judged after the fact.

1b. Collect distributed notes

For each item in scope (up to 20):

query_notes(operation="list", itemId="<uuid>", includeBody=true)

operation is required — query_notes has no default and rejects the call without it (Missing required parameter: operation). Use operation="list" to enumerate an item's notes.

Extract:

  • Notes with key session-tracking — these contain per-item outcome, files changed, deviations, friction, observations, and test results
  • Notes with key delegation-metadata (optional) — orchestrator-recorded model and isolation data (structured provenance line or legacy prose)
1c. Early exit

If no items are found in scope, or no session-tracking notes exist on any item: Exit early with:

No implementation run data found. Nothing to retrospect — run `/implement` first, then try again.

Step 2 — Aggregate Note Data

From the collected session-tracking notes, aggregate across all items:

  • Total item count and outcome distribution (success, partial, failed, skipped)
  • Combined files list — all files changed across items, deduplicated
  • Combined friction list — all friction entries from all items
  • Combined observations — notable observations from all items
  • Test results summary — pass/fail counts across items

If delegation-metadata notes exist on any items, extract:

  • Model used per delegation (haiku, sonnet, opus)
  • Isolation mode (inline, worktree)
  • These feed into delegation alignment analysis (step 3b)

Structured form. A note whose first line matches ^adapter=\S+( [a-z-]+=\S+)+$ is a structured provenance line, not legacy prose: split the line on spaces, then each token on key=value. Each seat:model pair inside seats= is one delegation, typed by seat rather than guessed from prose — planner → architecture/opus; implementer, test-author → sonnet; declarations-extractor → code reading/sonnet; reviewer → opus; any other seat listed is recorded but not scored. Isolation comes from isolation=. model= is ignored whenever seats= is present (per-seat models supersede the single top-level field). Provenance field order is fixed: adapter= run= seats= model= isolation= agents= tokens= duration= deferred= in-run-edges= orchestrator-turns=. Example:

adapter=claude-workflow run=r-20260928-b2d seats=planner:opus,implementer:sonnet,declarations-extractor:sonnet,test-author:sonnet,reviewer:opus model=sonnet isolation=worktree:.claude/worktrees/feat-b2-front-door agents=5 tokens=412800 duration=1860000 deferred=0 in-run-edges=1 orchestrator-turns=3

tokens=/duration= may read see:<short>: the run total lives on that item, so count it once and never sum it per item (in the per-run summary table, show the run's first-item value, never a see: reference). An optional second line extra-seats=<seat>:<model>:<tokens>,... lists seats dispatched outside the run; score each like a seats= pair, typing the seat after stripping a trailing fix-cycle suffix -a<n> (reviewer-a1 scores as reviewer, planner-a2 as planner).

Legacy form (unchanged): free-form prose naming model and isolation, parsed as before. A run that mixes structured and legacy notes across its items scores both forms.

Run get_context() in parallel for the current state snapshot.


Step 3 — Evaluate Across Dimensions

3a. Schema Effectiveness

For each item in scope, examine its actual notes (from step 1b):

  • Which schema-required notes exist? Check for non-empty content.
  • Token count per note: <50 = sparse** (flag), **50-500 = appropriate**, **>500 = potentially verbose (flag for status-type notes; specification notes are exempt from the upper bound)
  • Were any items missing required notes (indicating gate failures or schema-free items)?
  • Score: Fraction of expected schema notes that exist with appropriately sized content
3b. Delegation Alignment

If delegation-metadata notes exist on items, cross-reference against the delegation table:

Task typeExpected model
MCP bulk ops, materialization, simple querieshaiku
Code reading, implementation, test writingsonnet
Architecture, complex tradeoffs, multi-file synthesisopus
  • Flag misalignments (e.g., opus for bulk MCP ops, haiku for architecture), scored per seat delegation for a structured note (one score per seat:model pair in seats=)
  • A substituted= field on a delegation is an "allowlist substitution", not a misalignment — do not flag it against the delegation-alignment score
  • A model-source=self-report field flags the delegation separately, as self-reported rather than orchestrator-recorded — note it, but do not fold it into the misalignment count
  • Score: Fraction of delegations matching expected model for their task type

If no delegation-metadata notes exist: Note "delegation metadata not recorded" and skip scoring for this dimension.

If at least one structured provenance line exists, show a per-run summary table before continuing to 3c:

adapterrunagentstokensdurationorchestrator-turns
<adapter><run><agents><tokens><duration><orchestrator-turns>
3c. Note Effectiveness

For items with both queue-phase notes (specs) and work-phase notes (implementation):

  • Compare spec content themes to implementation note themes
  • If implementation notes mention "deviated from spec", "unexpected", or "assumption was wrong" -> flag as a spec gap
  • If work-phase notes are nearly empty (<30 tokens) -> flag as context loss for downstream agents
  • Score: Qualitative (effective / mixed / ineffective)
3d. Plan-to-Execution Alignment

Compare item creation timestamps to the root item's creation time (or the earliest item in scope if no root provided). Creation times come from query_items(operation="get", itemId="<uuid>", includeTimestamps=true) per in-scope item (at most 20 calls); neither the overview nor list-mode results carry timestamps:

  • Items created significantly after the root (>1 hour) = ad-hoc additions (may be necessary or scope creep)
  • Items still in queue role under the root = planned but skipped
  • Score: Fraction of planned items that reached terminal
3e. Friction Synthesis

Extract friction entries from each item's session-tracking note. Group by type:

  • tool-error — MCP or tool failures
  • excessive-roundtrips — more calls than necessary
  • workaround — agent had to work around a limitation
  • api-confusion — unclear API semantics

Identify themes across entries (e.g., "3 friction entries related to gate failures on items without schemas").


Step 4 — Check Trend Memory

Trend memory lives in MCP as items under a Retrospective Trends container — not in a file. Reads are targeted queries, not a whole-file load.

This container is process-global by design — the shared, cross-project learning layer, same rationale as the Session Retrospectives / Improvement Proposals containers (5a/7a) — it deliberately lives outside any project root and this search stays unscoped even when a project rootId is known.

query_items(operation="search", query="Retrospective Trends", limit=5)

Cross-check with a list-mode search (query_items(operation="search", tags="container", limit=20), filter to title) if the FTS hit is ambiguous or empty — an FTS-desync lesson from other containers in this skill.

If the container is absent or empty AND memory/retrospectives.md exists containing at least one - <kebab-key>: ... entry line: run the one-time migration under Step 6 FIRST, then continue with 4.2 below against the freshly migrated container.

If both are absent (no container, and no legacy file with entries): this is the first retrospective ever run against this database. Skip the rest of Step 4 — all findings are new baselines.

query_items(operation="search", tags="retrospective-trend", role="queue", limit=100)

This is list-mode (structured filter, no query), so it returns id, title and tags only — minimal fields, no summary and no timestamps — for every non-retired trend. The title's kebab key and one-line claim are the match surface (the kebab key is the stable identity). This replaces the old whole-file read outright.

4.3 Match findings

Match each Step 3 dimension finding against the listing by title. For each candidate (a title match, or an uncertain match), fetch its summary with query_items(operation="get", itemId="<trend-uuid>") before deciding:

  • If a finding matches an existing trend (same schema note, same delegation pattern, same friction type), note the incremented session count for Step 6.
  • If a finding is new, mark it as a candidate for a new trend item in Step 6.
  • For uncertain matches where title/summary keyword matching isn't conclusive, run a per-finding FTS query for semantic reach:
    query_items(operation="search", query="<finding keywords>", scope={tags: ["retrospective-trend"]})
Deep mode (--deep, opt-in)

Only when $ARGUMENTS contains --deep, the user invoked this skill in the main session (never a hook-dispatched or background run), and the Workflow tool is callable — otherwise ignore the flag and match inline as above. The retro-analysis workflow then replaces the inline matching; it is read-only, and Step 6 still does every write.

  1. Build retro-analysis/args-v1: contract, runId: "ra-<YYYYMMDD>-<HHMM>", date, mode: "deep", rootId (when a project root is known), findings (each Step 3 finding as {fid: "f<n>", dimension, text, keywords}; dimension maps 3a schema-effectiveness, 3b delegation, 3c note-quality, 3d plan-to-execution, 3e friction), trends (the 4.2 listing as {id, short, title}), observations (one unscoped query_items(operation="search", tags="agent-observation", limit=100), terminal ones dropped), retros (query_items(operation="search", tags="session-retrospective", sortBy="createdAt", sortOrder="desc", limit=10)). Only ids and titles go in; the workflow's agents read summaries and notes themselves.
  2. Unless dry-run, and only when rootId is known: stash {findings, retroScope} (retroScope = the Step 1 root and item ids) with manage_plan_documents(operation="stash", rootId, slug="retro/<runId>", body=<JSON>) and add planDocSlug: "retro/<runId>" to the args.
  3. Launch Workflow({name: "task-orchestrator:retro-analysis", args}) with args as a real object, then end the turn.
  4. On the task notification: if started: false, report its reason and match inline as above. Otherwise the result echoes findings (after compaction, re-read retro/<runId> with manage_plan_documents(operation="get", ...) if needed); resume at Step 5 with it:
    • matched entries are the 4.3 recurrences — Step 6 increments Sessions: N from sessionsBefore, or from a get when it is null;
    • stats.unmatchedShards ([{label, kind, targetIds}]) are shards whose Match agent returned nothing: match the findings against those targetIds inline per 4.3 before calling any finding new, and report stats.missing;
    • newTrends and unresolved fids are new-pattern candidates;
    • staleTrends are retire candidates; observationLinks feed the report.
  5. Skip 4.4 for matched trends whose evidence the result already carries.
4.4 Fetch full evidence (only when it matters)

For matched trends where per-session history changes the assessment (e.g., judging whether a pattern is worsening, stabilizing, or was already flagged as environmental), fetch evidence notes:

query_notes(operation="list", itemId="<trend-uuid>", includeBody=true)

Do not read retrospectives-history.md during a normal run — it stays a frozen provenance archive for the legacy file layout. Read it only when tracing the evidence chain of an entry that cites an archived legacy pattern by name.


Step 5 — Persist the Retrospective

Skip entirely in dry-run mode.

5a. Find or create container

This container is process-global by design — it is the shared, cross-project learning layer, so it deliberately lives outside any project root and this search stays unscoped even when a project rootId is known.

query_items(operation="search", query="Session Retrospectives", limit=5)

If no match with that exact title at depth 0, create it:

manage_items(operation="create", items=[{
  title: "Session Retrospectives",
  summary: "Container for structured post-implementation analyses.",
  type: "container",
  tags: "container",
  priority: "low"
}])
5b. Create retrospective item

If a project rootId (or project name from .taskorchestrator/config.yaml project.name) is known, include it in the title so a shared-DB container holding retrospectives from multiple projects stays attributable:

manage_items(operation="create", items=[{
  title: "Retrospective — <project-name> — <root-item-title> — <YYYY-MM-DD>",
  summary: "<one-sentence summary of key findings>",
  tags: "session-retrospective",
  parentId: "<container-uuid>"
}])

If no project name is known, omit that segment: "Retrospective — <root-item-title> — <YYYY-MM-DD>".

5c. Fill queue-phase notes

The session-retrospective schema has four required notes: three queue-phase (session-metrics, workflow-evaluation, improvement-signals) plus one work-phase actions-taken (a closure record of the proposals created in Step 7). Fill the three queue notes now, in a single batch; actions-taken is filled later, at Step 8b, once the proposals are known:

manage_notes(operation="upsert", notes=[
  {
    itemId: "<retro-uuid>",
    key: "session-metrics",
    role: "queue",
    body: "<Step 3 quantitative data: item counts, outcome distribution, schema usage, token estimates, files changed>"
  },
  {
    itemId: "<retro-uuid>",
    key: "workflow-evaluation",
    role: "queue",
    body: "<Step 3 qualitative assessment: per-dimension scores and key findings>"
  },
  {
    itemId: "<retro-uuid>",
    key: "improvement-signals",
    role: "queue",
    body: "<Step 4 trend analysis: new trends, reinforced trends, proposals>"
  }
])
5d. Advance to work phase

The three queue notes satisfy the queue→work gate. Advance the item to work (the work-phase actions-taken gate stays open until Step 8b):

advance_item(transitions=[{itemId: "<retro-uuid>", trigger: "start"}])

Do not complete the item yet — the actions-taken work-phase note is still required and depends on the Step 7 proposal results. Completion happens at Step 8b.


Step 6 — Update Trend Memory

Skip entirely in dry-run mode.

Write trend items from the Step 3/4 findings as MCP items, batched — one manage_notes call for all evidence-note upserts this run, one manage_items call for all summary updates this run:

  • Recurrence (finding matched an existing trend in Step 4.3): upsert an evidence note evidence-<YYYY-MM-DD>-<retro-short-id> (role work, body = this session's specific evidence: what happened, retro item ID, cost/impact) AND update the trend item's summary — increment Sessions: N, update Last seen: YYYY-MM-DD, and condense the observation if drift warrants it. The Sessions: N you increment is read from the Step 4.3 get of that trend — never inferred from the listing, which carries no summary.
  • New pattern: create a trend item (shape below) with Sessions: 1 in its summary, plus its first evidence note.
  • Retire (a previously-active trend is now addressed, obsolete, superseded, or accepted-environmental): advance_item(itemId="<trend-uuid>", trigger="cancel", summary="archived: <reason>"). cancel is gate-free — it moves any non-terminal role straight to terminal with no note check. statusLabel: cancelled on a trend item means "retired from active watching", not failure; the transition's summary line carries the actual semantic. A cancelled trend drops out of the Step 4.2 active listing automatically (it filters role="queue").
  • Graduation (Step 7 creates a proposal from this trend): record GRADUATED -> proposal <short-id> in the trend's summary. This does not change the trend's role — cancelling a graduated trend, if ever warranted, is a separate later decision once the proposal resolves.

Never call advance_item with start or complete on a trend item — only create, update, note upserts, and cancel. This keeps the lifecycle gate-free under any user's schema config: an external user's default schema could otherwise gate-block start/complete on these untyped items, and trend items carry no note schema of their own to satisfy such a gate.

New trend item shape
manage_items(operation="create", items=[{
  title: "trend: <kebab-key> — <one-line claim>",
  summary: "<distilled observation>. Sessions: 1. Last seen: YYYY-MM-DD.",
  tags: "retrospective-trend,<dimension>",
  parentId: "<trends-container-uuid>",
  priority: "low"
}])

<dimension> is one of schema-effectiveness | delegation | note-quality | plan-to-execution | friction | extension-candidate; append ,positive for a positive pattern. The kebab key in the title is the stable identity to match on across sessions — not exact summary text. Batch up to ~10 creates per call.

Then upsert its first evidence note:

manage_notes(operation="upsert", notes=[{
  itemId: "<new-trend-uuid>",
  key: "evidence-<YYYY-MM-DD>-<retro-short-id>",
  role: "work",
  body: "<this session's specific evidence: what happened, retro item ID, cost/impact>"
}])

Condense, don't accumulate. The trend's summary is the single distilled current truth — rewrite it on every update rather than appending to it. Per-session detail belongs in evidence notes, which are naturally bounded (one per recurrence) rather than growing a single blob indefinitely. Sessions count is derivable as the number of evidence-* notes (query_notes(operation="list", itemId=..., includeBody=false)), but the summary's Sessions: N is a denormalized convenience kept in sync in the same write that adds the evidence note — never let it drift out of step.

Improvement Proposals stay MCP-only, as before. Proposal status, priority, and dates live on the proposal item, never mirrored into a trend's summary beyond the one-line GRADUATED -> proposal <short-id> pointer. Resolve current proposal state on demand with query_items(operation="overview", anchorId="<proposals-container-uuid>", includeChildren=true). Per-proposal outcome narrative belongs on the proposal item's own adoption-decision / outcome-verification notes.

Show full SKILL.md (1,720 more words)Show less
One-time migration from the legacy layout

Replaces the old pointer/history-split migration entirely — any memory/retrospectives.md content, in whatever legacy shape it's in, now migrates to MCP instead of to a history file.

Condition (checked at Step 4.1): the Trends container is absent or empty AND memory/retrospectives.md exists containing at least one - <kebab-key>: ... entry line. This is self-terminating: after migration the file is a pointer stub with no entry lines, so the condition can never match again for this project.

Procedure — create-and-verify BEFORE touching the file. An interrupted migration then leaves content duplicated (recoverable), never lost:

  1. Create the Trends container (if it wasn't already found empty in 4.1).

  2. Read retrospectives.md in full — the last expensive whole-file read this skill will ever do. Parse every - <kebab-key>: ... entry under each ## section, mapping section header to dimension tag:

    Section headerDimension tag
    Schema Effectivenessschema-effectiveness
    Delegation Patternsdelegation
    Note Qualitynote-quality
    Frictionfriction
    Extension Candidatesextension-candidate

    Ignore ## Meta narrative sections and the Improvement Proposals pointer section (already MCP-owned — nothing to migrate there). Entries still marked [ARCHIVED] from a prior partial legacy migration are migrated as trend items and then immediately retired: advance_item(itemId="<uuid>", trigger="cancel", summary="archived: migrated from legacy file, was already archived").

  3. Create one trend item per entry, batched (~10 per manage_items call): title from the kebab key plus a distilled claim; summary = the condensed observation with the existing Sessions: N / Last seen carried over verbatim, plus any GRADUATED -> proposal <id> pointer already present in the entry. Then upsert one evidence-migrated note per item (role work), batched, holding the ORIGINAL entry text verbatim — this is the provenance record for the migration.

  4. Verify: parsed entry count == created item count, via query_items(operation="overview", anchorId="<trends-container-uuid>", includeChildren=true) (or a tags="retrospective-trend" list search scoped to the container). On mismatch, stop and report — do NOT stub the file. Leave the migration to retry on the next run; the condition still matches until the file is stubbed.

  5. Only then rewrite retrospectives.md to a pointer stub containing: the Trends container UUID, the active-trends query snippet from Step 4.2, a note that history stays frozen in retrospectives-history.md (do not migrate it — it remains a provenance archive, never itself migrated), and the migration date + this retrospective's item ID.

  6. Record it in the current retrospective's actions-taken note (Step 8b) — entry count migrated, container UUID.

Multi-project note. retrospectives.md was per-project memory (one file per Claude Code project directory); the Trends container is per-DATABASE. Users running several projects against one MCP server converge on one shared Trends container once each project has migrated — this is intended, the same process-global model already used for Session Retrospectives and Improvement Proposals.

Audit sweep. The retro-analysis workflow's audit mode (a standalone sweep, no findings) returns the same newTrends, staleTrends and observationLinks shapes. Present that result to the user first; only after they confirm, apply this step's create and retire shapes to it.


Step 7 — Create Improvement Proposals

Skip entirely in dry-run mode.

Check the trend items created or updated in Step 6 (their summary field carries Sessions: N). For each trend with Sessions >= 2:

7a. Find or create proposals container

This container is also process-global by design (same rationale as 5a) — it stays outside any project root, and this search stays unscoped even when a project rootId is known.

query_items(operation="search", query="Improvement Proposals", limit=5)

Create if missing (same pattern as 5a — include type: "container" and tags: "container").

7b. Create proposal items — scope-based anchoring

For each graduating trend, first read the scope classification already captured in the improvement-signals note (steps 3/4): global (plugin skills/hooks, the orchestration context, server floor config) or project-specific (one project's schemas/traits/config). If the scope cannot be parsed from the classification, treat it as global — never guess and auto-anchor a proposal under a project on ambiguous evidence.

Global scope — anchor under the process-global container found/created in step 7a (unchanged):

manage_items(operation="create", items=[{
  title: "Proposal: <concrete change description>",
  summary: "<what to change and why — reference retrospective item IDs that surfaced the trend>",
  tags: "improvement-proposal",
  parentId: "<7a-proposals-container-uuid>",
  priority: "low"
}])

Project-specific scope — find or create a per-project "Improvement Proposals" container under that project's rootId instead, and anchor there:

query_items(operation="search", query="Improvement Proposals", ancestorId="<rootId>", limit=5)

If no match, create it:

manage_items(operation="create", items=[{
  title: "Improvement Proposals",
  type: "container",
  tags: "container",
  parentId: "<rootId>",
  priority: "low"
}])

Then create the proposal item exactly as in the global case above, but with parentId: "<per-project-container-uuid>".

The proposal should include a concrete suggestion — not just "this is a problem" but the specific change:

  • Schema edits: include the exact YAML to add/modify
  • Skill updates: reference the section and describe the change
  • Orchestration context / orchestrate skill adjustments: specify the section and content
  • Hook additions: specify the event, matcher, and purpose
7c. File GitHub issues (global proposals only)

For each proposal created in step 7b with global scope this run — never project-scoped ones — attempt to file or link a GitHub issue. Full conventions, the issue template, and the dedup procedure live in references/github-feedback.md; this step carries only the call shapes. Every sub-step here is best-effort: a failure anywhere is caught, recorded as a one-line reason, and the retrospective continues (mirrors the step 8c acknowledgment pattern).

  1. Config gate — read retrospective.github_feedback from the workspace .taskorchestrator/config.yaml (direct file read). Not enabled: true ⇒ skip all of 7c for this run; record github filing: disabled for step 8b.
  2. gh guard — gh auth status via Bash; non-zero exit ⇒ skip filing, record the reason (e.g. gh unavailable/unauthenticated).
  3. Dedup (cheapest first) — check sibling proposals' github-issue: lines (cap 10 note reads), then:
    bash
    gh issue list --repo <repo> --state all --search "<3-5 distinctive keywords>" --json number,title,url --limit 10
    Reuse a matching issue's URL when the same change is already tracked.
  4. File (only if no match found):
    bash
    gh issue create --repo <repo> --title "[proposal] <...>" --body-file <scratchpad-tmp-path> --label enhancement
    Retry once without --label if the label doesn't exist on the repo.
  5. Record back — re-upsert the proposal note with a final github-issue: <url> line appended to its body (see references/github-feedback.md C2).
  6. Every one of the above is best-effort — 7c must never fail the retrospective.

Step 8 — Meta-Evaluation

Skip entirely in dry-run mode.

Query prior retrospectives:

query_items(operation="search", tags="session-retrospective", limit=20)

If 3+ retrospectives exist, evaluate:

Proposal and trend state for both checks below comes from MCP — query the container once and read roles off the result:

query_items(operation="overview", anchorId="<proposals-container-uuid>", includeChildren=true)

If a project rootId is known, also pull project-scoped proposals — these anchor outside the global container per step 7b's scope-based anchoring, so the overview above won't surface them:

query_items(operation="search", tags="improvement-proposal", ancestorId="<rootId>", limit=20)

Fold both result sets into the durability and staleness checks below.

  1. Trend durability: Did previously identified trends get addressed? Query trend items whose summary carries a GRADUATED -> proposal <id> pointer (query_items(operation="search", query="GRADUATED", scope={tags: ["retrospective-trend"]})) and check whether the proposal each one graduated into is terminal.
  2. Proposal staleness: Any proposals created 3+ retrospectives ago with no movement (still in queue)? Also flag any stuck in work — a proposal sitting in-progress across runs is usually a stalled adoption, not active work. When stale queue proposals exist (global or project-scoped), the report (step 9) should suggest running /task-orchestrator:review-proposals. Treat cancelled proposals as resolved-rejected, not stale — read their adoption-decision note before proposing anything similar again (do-not-re-propose rule); a rejected idea resurfacing under a new title is a signal to check history first, not to recreate it.
  3. Self-quality: Are retrospective notes converging on useful patterns, or repeating the same observations without resolution? Are notes too verbose (>800 tokens each) or too shallow (<100 tokens)?

If meta-findings warrant it, add a brief note to the current retrospective's improvement-signals note via:

manage_notes(operation="upsert", notes=[{
  itemId: "<current-retro-uuid>",
  key: "improvement-signals",
  role: "queue",
  body: "<updated body with meta-evaluation appended>"
}])

Step 8b — Fill Closure Note and Complete

Skip entirely in dry-run mode.

Now that Step 7 has determined which improvement proposals were created (or that none graduated), fill the work-phase actions-taken note — the schema's closure record — and complete the item.

manage_notes(operation="upsert", notes=[{
  itemId: "<retro-uuid>",
  key: "actions-taken",
  role: "work",
  body: "<closure record: improvement-proposal items created/updated in Step 7 (title + short-id each); for each **global** proposal append its GitHub filing outcome — `filed <url>`, `linked existing <url>`, or `github filing skipped: <reason>`; for each **project-scoped** proposal append `anchored under project <rootId>`; or 'none graduated (≥2 sessions) this run'; plus trend items created/updated/retired this run (short-ids each); plus, if the one-time legacy migration ran this session, the entry count migrated and the Trends container UUID>"
}])

The actions-taken note satisfies the work→terminal gate. Complete:

advance_item(transitions=[{itemId: "<retro-uuid>", trigger: "complete"}])
8c. Acknowledge the retrospective to the trigger hooks

Run via Bash, from the skill's base directory shown at invocation (<skill-base-dir>):

node "<skill-base-dir>/../../hooks/retro-ack.mjs"

This stamps the hook dedup marker as handled, extending the suppression window so the Stop backstop does not re-prompt for a retrospective — a manual run completing its own item must not look like a new implementation run needing one. This step is best-effort: if the script is missing (plugin layout changed), continue without failing the retrospective.


Step 9 — Report

Render a dashboard using these visual conventions (status symbols: ✓ terminal, ◉ work or review, ⊘ blocked, ○ queue, — cancelled):

## Session Retrospective — <root-item-title>

**<YYYY-MM-DD> · <N> items · <N> schemas used**

### Dimension Scores

| Dimension | Score | Key Finding |
|-----------|-------|-------------|
| Schema effectiveness | <fraction or qualitative> | <one-line summary> |
| Delegation alignment | <fraction or "not recorded"> | <one-line summary> |
| Note effectiveness | <qualitative> | <one-line summary> |
| Plan-to-execution | <fraction> | <one-line summary> |
| Friction | <count> entries, <N> themes | <top theme> |

### Trends

| Pattern | Sessions | Status |
|---------|----------|--------|
| <trend description> | N | new / reinforced / addressed |

### Improvement Proposals Created

| ID | Proposal | Trigger | Issue |
|----|----------|---------|-------|
| `<short-id>` | <description> | <trend that graduated> | <url or —> |

Conditional prefix:

  • Dry-run: **Dry run** — no items created, no memory updated.

Omit sections with no data (e.g., no improvement proposals -> omit that table). If delegation-metadata notes were present, include a delegations count in the header line: delegation count = Σ seats (structured) + Σ extra-seats entries + notes (legacy).


Troubleshooting

No session-tracking notes found

  • Cause: Implementing agents did not fill their session-tracking notes. This happens when items have no matching note schema (schema-free items skip gate enforcement).
  • Solution: Check .taskorchestrator/config.yaml for a default schema that includes session-tracking as a required note. Adding it ensures agents are prompted to fill tracking data.

Schema not recognized (expectedNotes empty)

  • Cause: session-retrospective tag not in .taskorchestrator/config.yaml, or MCP not reconnected after config edit
  • Solution: Run /mcp to reconnect, verify config has the schema

Container not found

  • Cause: First time creating retrospectives, trends, or improvement proposals in this database.
  • Solution: Containers are created lazily — Session Retrospectives at step 5a, Retrospective Trends at step 4.1 (or on the first trend write in step 6), Improvement Proposals at step 7a. No action needed.

Legacy trend file detected

  • Cause: memory/retrospectives.md exists with - <key>: ... entry lines and the Trends container is absent or empty — the one-time migration condition (step 4.1 / step 6) matches.
  • Solution: The skill runs the migration automatically this pass — see "One-time migration from the legacy layout" under step 6. No manual action needed. If the migration reports a count mismatch, it stops without stubbing the file and reports the discrepancy; re-run the retrospective to retry — the condition still matches until the file is stubbed.

Trend item advance blocked by a gate

  • Cause: Should never happen — the skill only ever uses create, update, note upserts, and cancel on trend items, all of which are gate-free. If it does happen, an unexpected schema in the user's config is intercepting an operation this skill assumes is unconditionally safe.
  • Solution: Fill the named required note minimally so the operation can proceed, then record the anomaly as an observation in the current retrospective's own notes — it's worth a bug report against the skill's gate-free assumption.

Retrospective pulled in another project's items

  • Cause: Shared multi-project DB with no project scope configured, so the step 1a fallback scan searched globally instead of within the current project's subtree.
  • Solution: Configure project.rootId in .taskorchestrator/config.yaml, or pass the root item UUID as an argument to the skill:
yaml
project:
  rootId: "<uuid>"
  name: "<project name>"

© jpicklyk, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file (references) in claude-plugins/task-orchestrator/skills/session-retrospective of jpicklyk/task-orchestrator.

  • SKILL.md
  • references/github-feedback.md

Open the folder on GitHubat commit 3e83170

Compare with similar skills

Session Retrospective next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Session Retrospective compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Session Retrospective this skilljpicklyk/task-orchestrator207—~9.5kAutomated safety check: PassMIT
Processnotque/vexjoy-agent438—~2.1kAutomated safety check: NotesMIT
Weekly Engineering Retrogarrytan/gstack136k—~2.4kAutomated safety check: PassMIT
Dough Execute Planterryyin/lizard2.5k—~4.3kAutomated safety check: PassCustom licence
After Action Reportrampstackco/claude-skills9401 repos~2.5kAutomated safety check: PassMIT
Oral Paper SkillAdkid-Zephyr/oral-paper-skill340—~1.9kAutomated safety check: PassNone

Similar skills

  • Process

    notque/vexjoy-agent

    Process: retrospectives, session handoff, pair programming, subagent-driven development, condition-based waiting.

    438 GitHub stars~2.1k tokensUpdated 6 days ago
    Agent WorkflowsAuto-check: notes
  • Builds a weekly engineering retrospective from git history: commit counts, per-person contributions, work patterns and code quality numbers over a chosen window.

    136k GitHub stars~2.4k tokensUpdated yesterday
    Product & Project ManagementAuto-check passed
  • Dough Execute Plan

    terryyin/lizard

    Executes one selected story or bounded retrospective correction through an executable plan, or one authorized planless slice from a selected simple story or a contextual instruction, with…

    2.5k GitHub stars~4.3k tokensUpdated 2 days ago
    Product & Project ManagementAuto-check passed
  • After Action Report

    rampstackco/claude-skills

    Run a structured after-action review (postmortem, retrospective) on a launch, incident, or completed project to capture timeline, root cause analysis, contributing factors, and actionable lessons.

    940 GitHub starsUsed in 1 repo~2.5k tokens
    Product & Project ManagementAuto-check passed
  • Oral Paper Skill

    Adkid-Zephyr/oral-paper-skill

    Help authors learn from exemplary ICLR, ICML, and NeurIPS papers through source-linked manuscript comparisons, concrete writing and experiment suggestions, and guided reflection.

    340 GitHub stars~1.9k tokensUpdated 21 days ago
    Product & Project ManagementAuto-check passed
  • Deck Retro

    asheshgoplani/agent-deck

    Run a fully local agent-deck retrospective over the user's own transcripts, Recall index and logs.

    1k GitHub stars~1.8k tokensUpdated 3 days ago
    Product & Project ManagementAuto-check passed

More from jpicklyk/task-orchestrator

All 28 skills in this repo
  • Task Orchestrator Server Setup

    jpicklyk/task-orchestrator

    Walks through how to launch and reach the MCP Task Orchestrator server container: transport, REST API, port publishing, config mounts and config-sync.

    207 GitHub stars~3.1k tokensUpdated yesterday
    Auto-check passed
  • Run Wave

    jpicklyk/task-orchestrator

    Resolves ready MCP work items into a run plan, shows it to you, then executes it through the Workflow tool or direct subagent dispatch, with post-run verification.

    207 GitHub stars~4.7k tokensUpdated yesterday
    Auto-check passed
  • Adopt Project Scope Migration

    jpicklyk/task-orchestrator

    Migrates an existing unscoped Task Orchestrator database to the project-scoping convention in place, creating one project anchor root and re-parenting work trees under it after a mandatory dry run.

    207 GitHub stars~3.7k tokensUpdated yesterday
    Auto-check passed
  • Bulk Task Completion

    jpicklyk/task-orchestrator

    Completes or cancels a whole feature subtree, a named list of items, or a batch of stale work items at once, previewing the impact and warning before force-completing anything active.

    207 GitHub stars~2.6k tokensUpdated yesterday
    Auto-check passed
  • Task Orchestrator Item Creator

    jpicklyk/task-orchestrator

    Creates an MCP work item from conversation context, anchoring it under the right container, inferring type and priority and pre-filling the required notes.

    207 GitHub stars~4k tokensUpdated yesterday
    Auto-check passed
  • Work Item Dependency Manager

    jpicklyk/task-orchestrator

    Views, creates, deletes and diagnoses BLOCKS, IS_BLOCKED_BY and RELATES_TO links between MCP work items, including why an item cannot start.

    207 GitHub stars~3.5k tokensUpdated yesterday
    Auto-check passed

Questions about Session Retrospective

What does Session Retrospective do?

Analyzes the current implementation run — evaluates schema effectiveness, delegation alignment, note quality, and plan-to-execution fit. Session Retrospective is an agent skill from jpicklyk/task-orchestrator. Analyzes the current implementation run — evaluates schema effectiveness, delegation alignment, note quality, and plan-to-execution fit.

When should I use Session Retrospective?

Session Retrospective fits situations like: says retrospective; what did we learn; analyze this run; how did that go.

How do I install Session Retrospective in Claude Code?

Run `npx skills add jpicklyk/task-orchestrator --skill session-retrospective -a claude-code`. Or copy the skill folder (claude-plugins/task-orchestrator/skills/session-retrospective in jpicklyk/task-orchestrator) into .claude/skills/session-retrospective in your project. Claude Code loads it when a task matches its description.

How do I install Session Retrospective in Codex?

Run `npx skills add jpicklyk/task-orchestrator --skill session-retrospective -a codex`. Or copy the skill folder (claude-plugins/task-orchestrator/skills/session-retrospective in jpicklyk/task-orchestrator) into .agents/skills/session-retrospective in your project. Codex loads it when a task matches its description.

Can I use Session Retrospective in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jpicklyk/task-orchestrator --skill session-retrospective -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/session-retrospective, .gemini/skills/session-retrospective, .github/skills/session-retrospective and .opencode/skills/session-retrospective in your project.

What does Session Retrospective need to run?

Going by SKILL.md and its folder, Session Retrospective needs the command-line tools its instructions call (gh and node).

Does Session Retrospective access the network?

SKILL.md contains no URLs. Its commands use gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Session Retrospective safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Session Retrospective use?

Session Retrospective is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Session Retrospective use?

About 9.5k tokens (SKILL.md is roughly 38k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.2k tokens, read only when the agent opens those files.

What are the alternatives to Session Retrospective?

Skills that share tags, products or a category with Session Retrospective: Process (notque/vexjoy-agent, 438 stars), Weekly Engineering Retro (garrytan/gstack, 136k stars), Dough Execute Plan (terryyin/lizard, 2.5k stars) and After Action Report (rampstackco/claude-skills, 940 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Session Retrospective?

jpicklyk (a GitHub user) maintains it in jpicklyk/task-orchestrator, which has 207 GitHub stars. The repository holds 28 skills in this directory. The repository was last updated on October 8, 2026.

Source: jpicklyk/task-orchestrator on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.