The learning loop
QA Orchestra has no memory system, no vector database, no auto-indexed history. What it has is a discipline: when an agent learns something about your project that wasn't in CONTEXT.md, it writes the finding to a plain Markdown file in context/annotations/. Over time, those files become the project's institutional memory — and because they live in git, they compound across engineers and sessions.
"Auto-learning" suggests something autonomous. It isn't. There is no scheduler, no hook, no script watching agent output for novel facts. Growth happens because each agent is prompted to append its discoveries, and the prompts in AGENTS.md make that a rule. If you never run agents, annotations never grow.
The four annotation files
Every QA Orchestra workspace ships with four files under context/annotations/. Each covers one kind of learning.
domain.md
Business logic nuances that aren't spelled out in tickets. "Discount applies before tax, not after." "Guest checkout skips the loyalty hook." Domain truths discovered during review.
services.md
Backend service quirks and behaviors. "The cart-service returns 200 with an empty body on stale sessions." "The email queue batches every 30s, not in real time."
environments.md
Environment-specific flakiness and differences. "Port 3000 is used by another service on CI." "Localhost backend needs NODE_TLS_REJECT_UNAUTHORIZED=0 for the staging API."
test-patterns.md
Patterns specific to this codebase's test suite. "All interactive elements carry data-testid." "Fixtures live in qa/fixtures, not inline."
The required entry format
Every annotation follows the same shape. Agents use it, and so should you when adding entries by hand. The shape is what makes annotations scannable — a future agent or engineer can skim a file in seconds.
### [Date] — [Topic]
**Context**: [what task revealed this]
**Learning**: [what was learned]
**Impact**: [which agent or scenario this affects]
A real example
### 2026-04-07 — Cart Service
**Context**: Functional review of PROJ-456 (discount calculation)
**Learning**: Discount is applied BEFORE tax. AC implied after-tax. Verified in cart-service.ts:142.
**Impact**: All checkout test scenarios involving discounts must verify pre-tax calculation.
Three things make this entry useful:
- The date — lets a reader judge whether the learning is still current.
- A code citation —
cart-service.ts:142means the claim can be verified, not just trusted. - An impact line — tells downstream agents what scenarios need to change.
How an agent's loop actually runs
- Before the task — the agent scans
context/annotations/for files relevant to its current work. A functional-reviewer working on checkout readsservices.mdanddomain.mdif either mentions carts or payments. - During the task — the agent does its job (reviews the diff, designs scenarios, validates in the browser).
- After the task — the agent asks itself: "did I learn something project-specific that isn't in CONTEXT.md or annotations yet?" If yes, it appends a new entry to the right file using the format above.
The per-agent rule lives in AGENTS.md §7 (Learning loop). Individual agents like functional-reviewer and manual-validator repeat the instruction in their own files, so the discipline is applied at two levels.
Git workflow: why commits matter
Annotations are plain Markdown, tracked in git like everything else. That's not a coincidence — it's what makes the system work for teams:
- A learning captured by one engineer is visible to the whole team on the next
git pull. - Code review catches hasty or wrong annotations before they mislead future agents.
git blameon an annotation tells you which task produced it — useful when the learning turns out to be stale.- Reverting a bad annotation is a normal git operation, not a special tool.
Treat annotation changes like code changes. Commit them with a meaningful message ("annotations: cart service discount timing") and review them in PRs.
What to write, what to skip
DO
- Surprises that contradicted an AC or assumption
- Non-obvious service behaviors with a code citation
- Environment quirks that caused a flaky result
- Test-suite conventions you had to infer from reading code
- Short, scannable entries — 3-5 lines each
DON'T
- Stream-of-consciousness debug notes
- Facts that already live in
CONTEXT.md - One-off ticket details — put those in the ticket
- Long narratives — a future agent will skim, not read
- Speculation — only write what you verified
Dumping every discovery into domain.md regardless of category. The four files exist so relevant content is easy to find; if everything ends up in one file, the categorization breaks and agents stop trusting it.
Pruning and revising
Annotations don't self-expire. When a service is rewritten, a test convention is dropped, or a business rule changes, the corresponding annotation becomes a lie — and a worse kind of lie than a missing annotation, because a future agent will act on it.
Two habits keep the files honest:
- When you change code that matches an annotation, search
context/annotations/in the same PR. Update or delete the matching entry. - Review the oldest entries periodically. Anything older than a few months is worth re-verifying before a reviewer trusts it again.
Annotations vs. CONTEXT.md: where does a fact go?
| If the fact is… | It belongs in… |
|---|---|
| A setup command, URL, credential, or stack detail you can write down up front | context/CONTEXT.md |
| A convention that applies to every agent (tone, language, terminology) | context/CONTEXT.md → Preferences |
| A surprise discovered during a task (service quirk, business rule, test pattern) | The matching file in context/annotations/ |
| A one-off detail for a specific ticket | The ticket itself, not annotations |
Next
- How context works — the CONTEXT.md schema and who reads what
- Creating a new agent — adding a specialist that participates in the learning loop
- Annotations folder on GitHub