Learning
/rota-learn pulls durable knowledge out of a session and writes it to
KNOWLEDGE.md so future runs don’t rediscover the same gotchas.
/rota-learn
/rota-learn scans the current session, extracts non-obvious knowledge, groups
the entries by topic, and writes them to .rota/KNOWLEDGE.md. After writing, it
updates the managed rota-knowledge block in the project instructions file (AGENTS.md) so the topic list stays
in sync. /rota-work reads that index to decide when the current task should
consult KNOWLEDGE.md.
With an external knowledge base configured, /rota-learn also sorts each learning: project-specific ones stay in KNOWLEDGE.md, general platform or technology ones go to the shared repo. It states the call per learning in one line. Without the knowledge.external key it behaves as described here.
What gets captured (and what doesn’t)
Captured:
- Gotchas: non-obvious failure modes
- Conventions: project-specific patterns that aren’t obvious from reading code
- Constraints: invariants, compatibility rules
- Debugging insights: root causes for bugs that took effort to track down
- Decisions with rationale
- Tool quirks
Not captured:
- Things already documented in code or README
- Transient session state
- Obvious facts derivable from the codebase
- Restatements of framework docs
- Personal preferences
How KNOWLEDGE.md is organized
Entries are grouped under short topic headings such as Build & Tooling,
Testing, or Networking. Within each topic, the newest bullets sit at the
top. New entries carry an HTML-comment date stamp (<!-- YYYY-MM-DD -->) so
you can tell at a glance how fresh a piece of knowledge is.
In umbrella mode, KNOWLEDGE.md is hybrid: cross-repo learnings live in
the umbrella .rota/KNOWLEDGE.md, repo-local ones in
.rota/knowledge/<name>/KNOWLEDGE.md. /rota-learn (and --term Glossary
entries) routes to the scope resolved from cwd or an explicit --repo; at
the umbrella root it asks once whether a learning is umbrella-shared or
sub-repo-scoped. DECISIONS stays umbrella-only. Single-repo projects are
unaffected. Full model: references/persistence-skills.md.
Recall before editing
With rota hook install, Claude Code’s Edit and Write tools receive matching
knowledge and active decisions before the tool runs, once per entry per session.
Add file scopes to a project learning with repeatable --path flags:
rota knowledge add --topic Architecture --title "Storage seam" --body-file tip.txt --path 'internal/storage/**/*.go' --path 'cmd/server/*.go'
This writes <!-- paths: ["internal/storage/**/*.go","cmd/server/*.go"] -->
before the bullet’s date stamp. /rota-decide can put the same optional comment
inside a decision entry. Existing query verbs preserve it; use knowledge replace
to change a learning’s field. Decisions keep their existing skill write flow.
Globs use slash-separated paths relative to the project root, or the registered
repo root for repo-local knowledge. *, ? and character classes match within a
path segment; a ** segment spans zero or more directories. No scope means topic
consult only. Deprecated learnings and retired or superseded decisions are skipped.
External knowledge has no project path scope. Re-run rota hook install to update
an older Bash-only installation; rota hook uninstall removes the marked hook.
Promotion lifecycle
KNOWLEDGE.md bullets carry a tier (provisional, confirmed, or deprecated) tracked in a sidecar (.rota/knowledge-tier.json) along with a hit counter. Tiers separate “we wrote this down once” from “we’ve validated this repeatedly in real cycles.”
| Tier | Meaning |
|---|---|
provisional |
Default for new bullets. Same advisory weight as before, but not yet load-bearing. |
confirmed |
Promoted after learn.promoteThreshold clean hits (default 3) or manually via /rota-learn --promote. |
deprecated |
Manually marked stale via /rota-learn --deprecate, or auto-flagged for review when a contradiction lands. |
Hit tracking
Every time /rota-work or /rota-review consults a bullet and the consuming step actually uses it (not just reads past it), the bullet’s hit counter increments via rota knowledge hit. Hits accumulate across sessions; the counter is durable.
At the learn.promoteThreshold mark, a provisional bullet auto-promotes to confirmed. Two skip conditions: the bullet already has a pending contradiction (auto-promotion stays blocked until you resolve it), or the threshold is 0 (in which case provisional is bypassed entirely on insert: a config choice, not a normal mode).
See learn.promoteThreshold for tuning.
Contradiction queue
When /rota-work or /rota-review consumes a confirmed bullet and observes behavior that contradicts it (the rule said X, the code or test shows ¬X), the bullet lands in .rota/knowledge-contradictions.json rather than getting silently demoted. Mid-cycle is the wrong moment to commit to a demotion: the contradiction might be the bug under investigation, not a stale truth.
/rota-learn reads the queue at the start of a session and prompts for each pending entry:
- Demote (Recommended): flips the bullet to
deprecated. - Keep, false positive: leaves the tier unchanged.
- Defer to next session: leaves the tier unchanged and keeps the entry queued.
Each demoted or kept entry is cleared from the queue as it is handled. Deferred entries stay, so the next session asks again.
Manual lifecycle flags
Three explicit flags bypass the heuristic flow when you already know what you want:
/rota-learn --promote <topic> "<title>": sets the bullet toconfirmedwithout waiting for hits. Use for a brand-new lesson you trust on the strength of the session that produced it./rota-learn --deprecate <topic> "<title>": marksdeprecated. Manual deprecations do NOT touch the contradiction queue. That queue is for heuristic candidates only./rota-learn --amend <topic> "<title>": rewrites the body of one bullet while preserving its tier and hits. Use when you want sharper wording without resetting the validation history.
All three operate on (topic, title) pairs. The tier sidecar is the source of truth for the lifecycle state. KNOWLEDGE.md itself stays human-readable without tier annotations.
Retrospective: --retro [<session-id|path>]
/rota-learn --retro looks at the session’s mistakes instead of its discoveries. It reads the newest session transcript for this worktree, or the one you name with --retro <session-id|path> (Claude Code under ~/.claude/projects/, Codex under ~/.codex/sessions/) and cites the line or entry for each repeated-work, ignored-plan or skipped-step mistake; one with no citable evidence is marked unverified, not filed. With no transcript it falls back to session memory and recent commits and says so. It sorts each into one of five classes: a guardrail (lint, test, hook or CI check), a written standard (a KNOWLEDGE.md bullet or a decision), a navigation pointer (a map entry or an AGENTS.md line), a tool-economy fix or an information-access gap (logs not captured, no read-only service access; filed as an item like a guardrail). Guardrail candidates are filed as items with rota item create and never built in the same run. The retro also lists bullets that look like no-ops (never hit, or restating code) as removal candidates. It does not delete or deprecate them; you decide, then use --deprecate. It also audits AGENTS.md, CLAUDE.md and your global instructions, reporting lines that restate code or docs, dead lines and file size without editing them, and reports a repo whose check command runs in no CI workflow or hook as a no-guardrail finding.
When to invoke
Invoke /rota-learn after a session that surfaced discoveries: two or more
gotchas resolved in a cycle, a broad change touching many files, or a hard bug
whose root cause wasn’t obvious. Skip it for single-item fixes and mechanical
changes where nothing worth re-using was learned.
Skills nudge or auto-invoke /rota-learn depending on your
autonomy level. With off you get a one-line nudge; with roundtrip or auto,
/rota-ship runs it after integrating. /rota-work only nudges.
Verification
learn.verify in .rota/config.json controls a second-opinion pass, off by
default. Set it to true, or pass --strict for one run, and /rota-learn dispatches a fresh Opus subagent that cold-reads KNOWLEDGE.md and the
managed index block (no session context) and judges each new bullet on five
criteria: durable (not ephemeral), sharp (concrete claim, not vague),
non-obvious, correctly topic’d, and non-duplicate. On PASS_WITH_NOTES the
skill rewords weak bullets, removes duplicates and moves wrong-topic bullets;
on FAIL it removes the new entries and reports why.
| Value | Behavior |
|---|---|
true or --strict |
After writing, run the verifier. Catches weak, duplicate, or wrong-topic entries before they accrete. Adds one Opus roundtrip per /rota-learn call. |
false (default) |
Skip the verifier. /rota-learn writes and reports immediately. Faster and cheaper. |
See configuration for the full learn.verify setting.
CLAUDE.md integration
Each run, /rota-learn rewrites the managed rota-knowledge block in the project instructions file (AGENTS.md when present, else CLAUDE.md) to match the topic headings in KNOWLEDGE.md.
Knowledge vs decisions
If you find yourself wanting to write “we will never X” or “X is forbidden in
this codebase,” that belongs in a decision. Knowledge is
advisory (“remember this if relevant”). Decisions are hard boundaries that FAIL
review when violated. Use /rota-decide for the latter. It captures
rule + why + forbids + permits and is consulted as a constraint by /rota-work,
/rota-debug, /rota-plan, /rota-refactor, /rota-review, and /rota-vision.
See also
- Sibling persistence skill:
docs/usage/decisions.md