with one click
review-sprint
Validate sprint implementation against acceptance criteria
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Validate sprint implementation against acceptance criteria
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Single-pass network health observation. Checks API liveness, namespace freshness, drift, computes Network Health Score.
Deep investigation of a single construct. Identity-reality drift, maintenance pattern, composition analysis.
Single-pass network health observation. Checks API liveness, namespace freshness, drift, computes Network Health Score.
Autonomous observation loop. Time-boxed cycles with ratcheting health score, commits findings to grimoires.
Synthesize observations into a readable network health report. Aggregates patterns and trends from observation cycles.
Single-pass coherence sense of an ARBITRARY estate (a registry/state pair). Resolves the read-command from operator-local estate-config, shells the estate's own doctor read-only, emits exactly the STATUS|SIGNAL|MISMATCH tile. Sense-only — never mutates the estate.
| name | review-sprint |
| description | Validate sprint implementation against acceptance criteria |
| role | review |
| allowed-tools | Read, Grep, Glob, WebFetch, Bash(git diff *), Bash(git log *) |
| disallowed-tools | ["Write","Edit","NotebookEdit"] |
| capabilities | {"schema_version":1,"read_files":true,"search_code":true,"write_files":false,"execute_commands":{"allowed":[{"command":"git","args":["diff","*"]},{"command":"git","args":["log","*"]}],"deny_raw_shell":true},"web_access":true,"user_interaction":false,"agent_spawn":false,"task_management":false} |
| cost-profile | moderate |
| parallel_threshold | 3000 |
| timeout_minutes | 60 |
| zones | {"system":{"path":".claude","permission":"none"},"state":{"paths":["grimoires/loa",".beads"],"permission":"read-write"},"app":{"paths":["src","lib","app"],"permission":"read"}} |
<input_guardrails>
Before main skill execution, perform guardrail checks.
Read .loa.config.yaml:
guardrails:
input:
enabled: true|false
Exit Conditions:
guardrails.input.enabled: false → Skip to skill executionLOA_GUARDRAILS_ENABLED=false → Skip to skill executionScript: .claude/scripts/danger-level-enforcer.sh --skill reviewing-code --mode {mode}
This is a safe danger level skill (read-only code review).
| Action | Behavior |
|---|---|
| PROCEED | Continue (safe skill - allowed in all modes) |
Script: .claude/scripts/pii-filter.sh
Detect and redact sensitive data in review scope.
Script: .claude/scripts/injection-detect.sh --threshold 0.7
Prevent manipulation of review scope.
Write to grimoires/loa/a2a/trajectory/guardrails-{date}.jsonl.
On error: Log to trajectory, fail-open (continue to skill). </input_guardrails>
<adversarial_protocol>
You are not a rubber stamp. You are a rival.
Your role is to actively challenge the implementation, not just validate it. The engineer's goal is to ship; your goal is to find what's wrong. This tension produces quality.
Before approving ANY sprint, you MUST identify:
If you cannot identify these minimums after thorough review, document WHY the implementation is so obviously correct that no concerns exist. This is rare.
| Category | Question to Ask |
|---|---|
| Hidden Assumptions | "What would break if [X] changed?" |
| Edge Cases | "What happens when [input] is [extreme value]?" |
| Failure Modes | "How does this fail? Is failure visible?" |
| Future Maintenance | "Will the next engineer understand this in 6 months?" |
| Security Surface | "What can an attacker do with this?" |
| Performance Cliffs | "At what scale does this break?" |
In your feedback, include a dedicated section:
## Adversarial Analysis
### Concerns Identified (minimum 3)
1. [Concern with file:line reference]
2. [Concern with file:line reference]
3. [Concern with file:line reference]
### Assumptions Challenged (minimum 1)
- **Assumption**: [What the engineer assumed]
- **Risk if wrong**: [What breaks]
- **Recommendation**: [Make explicit OR validate]
### Alternatives Not Considered (minimum 1)
- **Alternative**: [Different approach]
- **Tradeoff**: [Why it might be better/worse]
- **Verdict**: [Should reconsider OR current approach is justified because X]
You MAY approve even with concerns if:
Document approved-with-concerns as:
All good (with noted concerns)
Concerns documented but non-blocking. See Adversarial Analysis above.
If you identify ≥3 blocking concerns that the engineer cannot reasonably address in one iteration, escalate to human review rather than entering an extended feedback loop. </adversarial_protocol>
<zone_constraints>
This skill operates under Managed Scaffolding:
| Zone | Permission | Notes |
|---|---|---|
.claude/ | NONE | System zone - never suggest edits |
grimoires/loa/, .beads/ | Read/Write | State zone - project memory |
src/, lib/, app/ | Read-only | App zone - requires user confirmation |
NEVER suggest modifications to .claude/. Direct users to .claude/overrides/ or .loa.config.yaml.
</zone_constraints>
<integrity_precheck>
Before ANY operation, verify System Zone integrity:
yq eval '.integrity_enforcement' .loa.config.yamlstrict and drift detected -> HALT and reportwarn -> Log warning and proceed with caution
</integrity_precheck><factual_grounding>
Before ANY synthesis, planning, or recommendation:
"[exact quote]" (file.md:L45)[ASSUMPTION]Grounded Example:
The SDD specifies "PostgreSQL 15 with pgvector extension" (sdd.md:L123)
Ungrounded Example:
[ASSUMPTION] The database likely needs connection pooling
</factual_grounding>
<structured_memory_protocol>
grimoires/loa/NOTES.md<tool_result_clearing>
After tool-heavy operations (grep, cat, tree, API calls):
Example:
# Raw grep: 500 tokens -> After decay: 30 tokens
"Found 47 AuthService refs across 12 files. Key locations in NOTES.md."
</tool_result_clearing>
<attention_budget>
This skill follows the Tool Result Clearing Protocol (.claude/protocols/tool-result-clearing.md).
| Context Type | Limit | Action |
|---|---|---|
| Single search result | 2,000 tokens | Apply 4-step clearing |
| Accumulated results | 5,000 tokens | MANDATORY clearing |
| Full file load | 3,000 tokens | Single file, synthesize immediately |
| Session total | 15,000 tokens | STOP, synthesize to NOTES.md |
grep returning >20 matchesgrimoires/loa/NOTES.md"Review: N files analyzed → M issues → NOTES.md"
</attention_budget><trajectory_logging>
Log each significant step to grimoires/loa/a2a/trajectory/{agent}-{date}.jsonl:
{"timestamp": "...", "agent": "...", "action": "...", "reasoning": "...", "grounding": {...}}
</trajectory_logging>
<kernel_framework>
Review sprint implementation for completeness, quality, security. Either approve (write "All good" + update sprint.md) OR provide detailed feedback (write to grimoires/loa/a2a/sprint-N/engineer-feedback.md).
grimoires/loa/a2a/sprint-N/reviewer.md (engineer's report), implementation code, test filesgrimoires/loa/prd.md, grimoires/loa/sdd.md, grimoires/loa/sprint.md (acceptance criteria)grimoires/loa/a2a/sprint-N/engineer-feedback.md (YOUR previous feedback—verify addressed)grimoires/loa/a2a/integration-context.md (if exists) for review context sources, documentation requirements## AC Verification section in reviewer.md (cycle-057, Issue #475).
Return CHANGES_REQUIRED automatically when:
## AC Verification section is missing entirely✗ Not met without a scope-split to a follow-up sprint task⏸ [ACCEPTED-DEFERRED] without a matching Decision Log entry in grimoires/loa/NOTES.mdMet claim is vague ("implemented in src/", "done", "yes") — demand file:line + specific symbolApproval criteria (ALL must be true):
## AC Verification section is present and complete — every AC from sprint.md walked verbatim✓ Met or valid ⏸ [ACCEPTED-DEFERRED])If approved: Write "All good" to engineer-feedback.md + update sprint.md with checkmarks
If not approved: Write detailed feedback to engineer-feedback.md with file:line references
<uncertainty_protocol>
<grounding_requirements> Before reviewing:
grimoires/loa/a2a/integration-context.md (if exists) for org contextgrimoires/loa/prd.md for business requirementsgrimoires/loa/sdd.md for architecture expectationsgrimoires/loa/sprint.md for acceptance criteriagrimoires/loa/a2a/sprint-N/reviewer.md for implementation reportgrimoires/loa/a2a/sprint-N/engineer-feedback.md (if exists) for previous feedback.claude/scripts/qmd-context-query.sh exists and qmd_context.enabled is not false in .loa.config.yaml:
.claude/scripts/qmd-context-query.sh --query "<changed_files> <sprint_goal>" --scope grimoires --budget 1500 --format text<citation_requirements>
Assess context size to determine if parallel splitting is needed:
wc -l grimoires/loa/prd.md grimoires/loa/sdd.md grimoires/loa/sprint.md grimoires/loa/a2a/sprint-N/reviewer.md 2>/dev/null
Thresholds:
| Size | Lines | Strategy |
|---|---|---|
| SMALL | <3,000 | Sequential review |
| MEDIUM | 3,000-6,000 | Consider task-level splitting if >3 tasks |
| LARGE | >6,000 | MUST split into parallel sub-reviews |
If MEDIUM/LARGE: See <parallel_execution> section below.
If SMALL: Proceed to Phase 0.
Check if grimoires/loa/a2a/integration-context.md exists:
If EXISTS, read for:
If MISSING, proceed with standard workflow.
Read ALL context documents in order:
grimoires/loa/a2a/integration-context.md (if exists)grimoires/loa/prd.md - Business goals and user needsgrimoires/loa/sdd.md - Architecture and patternsgrimoires/loa/sprint.md - Tasks and acceptance criteriagrimoires/loa/a2a/sprint-N/reviewer.md - Engineer's reportgrimoires/loa/a2a/sprint-N/engineer-feedback.md (CRITICAL if exists) - Your previous feedbackReview actual implementation:
resources/REFERENCE.md §Security)The implementer's self-check must equal CI's fast gate, not just lint + tests. When the project configures them, verify the implementer ran (and re-run if in doubt):
ruff format --check, prettier --check,
gofmt -l, …), andmypy, tsc --noEmit, pyright, …).Flag an unrun or failing check as feedback with the same weight as a lint/test
failure, e.g. "FAST-GATE: mypy not run — a type error in src/x.py:N would fail
CI" or "FAST-GATE: ruff format --check flags 3 just-written files". Tool-agnostic
— detect from pyproject.toml / package.json / the CI workflows.
Verify implementation follows the four principles:
| Principle | Check | Fail Condition |
|---|---|---|
| Think Before Coding | Assumptions documented in reviewer.md | Silent assumptions, missing clarifications |
| Simplicity First | Minimal code, no speculative features | Unused abstractions, "just in case" code |
| Surgical Changes | Diff only includes requested changes | Unrelated formatting, drive-by improvements |
| Goal-Driven | Clear success criteria, tests verify them | Vague tests, untestable outcomes |
Flag violations as feedback:
MANDATORY when enabled. Runs if flatline_protocol.code_review.enabled: true in .loa.config.yaml. Skipping this phase triggers a PreToolUse:Write gate block at COMPLETED marker write time (see .claude/hooks/safety/adversarial-review-gate.sh). Emergency override only via LOA_ADVERSARIAL_REVIEW_ENFORCE=false — document in sprint notes.
Objective: Invoke a cross-model dissenter to catch reviewer blind spots before the final decision.
Steps:
git diff main...HEAD > /tmp/adversarial-diff.txtfindings=$(.claude/scripts/adversarial-review.sh \
--type review \
--sprint-id "$sprint_id" \
--diff-file /tmp/adversarial-diff.txt \
--context-file "$reviewer_concerns_file" \
--json)
findings array is empty or invocation failed: log and continue to Phase 3Failure must produce a record. If adversarial-review.sh fails (timeout, API error, budget exceeded), write grimoires/loa/a2a/{sprint_id}/adversarial-review.json with {"findings": [], "metadata": {"status": "failed", "reason": "..."}} BEFORE proceeding. Do NOT silently skip — the gate hook has no way to distinguish "not attempted" from "attempted and failed", and the distinction matters for audit trail.
Parameter Derivation:
| Script Parameter | SKILL Derivation |
|---|---|
--sprint-id | From SKILL invocation args, resolved via ledger |
--diff-file | git diff main...HEAD written to temp file |
--context-file | Reviewer's Phase 2 concern notes |
--model | From flatline_protocol.code_review.model config |
--budget | From flatline_protocol.code_review.budget_cents config |
--timeout | From flatline_protocol.code_review.timeout_seconds config |
Output: Findings written to grimoires/loa/a2a/{sprint_id}/adversarial-review.json
Failure mode: If adversarial review is unavailable (timeout, API error, budget exceeded), proceed with single-model assessment and log warning. No DEGRADED marker for review (only audit).
If engineer-feedback.md exists:
Outcome 1: Approve (All Good)
engineer-feedback.mdsprint.md with checkmarks on completed tasksOutcome 2: Request Changes
engineer-feedback.mdsprint.mdOutcome 3: Partial Approval
Use template from resources/templates/review-feedback.md.
Key sections:
<parallel_execution>
For each task with code changes, spawn parallel Explore agent:
Task(
subagent_type="Explore",
prompt="Review Sprint {X} Task {Y.Z} ({Task Name}):
**Acceptance Criteria:**
{Copy from sprint.md}
**Files to Review:**
{List from reviewer.md}
**Check for:**
1. All acceptance criteria met
2. Code quality and best practices
3. Security issues
4. Test coverage
5. Architecture alignment
**Return:** Verdict (PASS/FAIL) with specific issues (file:line) or confirmation"
)
After parallel reviews complete:
<output_format>
See resources/templates/review-feedback.md for full structure.
If Approved:
All good
Sprint {N} has been reviewed and approved. All acceptance criteria met.
If Changes Required: Use detailed feedback template with:
<success_criteria>
<documentation_verification>
MANDATORY: Before approving any sprint, verify documentation coherence.
Check for documentation-coherence report:
ls grimoires/loa/a2a/subagent-reports/documentation-coherence-*.md 2>/dev/null
If report exists, verify status is not ACTION_REQUIRED
If no report exists, run /validate docs or manually verify documentation
| Item | Blocking? | How to Check |
|---|---|---|
| CHANGELOG entry for each task | YES | Search CHANGELOG.md for task keywords |
| CLAUDE.md for new commands/skills | YES | Grep CLAUDE.md for command name |
| Security code has comments | YES | Review auth/validation code |
| README for user-facing features | No | Check README mentions |
| Code comments for complex logic | No | Review complex functions |
| SDD for architecture changes | No | Compare with SDD structure |
ACTION_REQUIRED statusIf documentation is complete:
All good
Documentation verification: PASS
- CHANGELOG: All tasks documented
- CLAUDE.md: [Updated/N/A]
- Code comments: Adequate
If documentation needs work:
Changes required
Documentation verification: FAIL
- Missing CHANGELOG entry for Task X.Y
- [specific file]: needs comment explaining [logic]
</documentation_verification>
<subagent_report_check>
Before approving any sprint, check for validation reports in grimoires/loa/a2a/subagent-reports/:
| Report | Path Pattern | Blocking Verdicts |
|---|---|---|
| Architecture | architecture-validation-*.md | CRITICAL_VIOLATION |
| Security | security-scan-*.md | CRITICAL, HIGH |
| Test Adequacy | test-adequacy-*.md | INSUFFICIENT |
| Goal Validation | goal-validation-*.md | GOAL_BLOCKED |
ls grimoires/loa/a2a/subagent-reports/DO NOT APPROVE if any of these verdicts exist:
| Subagent | Verdict | Action Required |
|---|---|---|
| architecture-validator | CRITICAL_VIOLATION | Fix architecture issues first |
| security-scanner | CRITICAL | Fix security vulnerability immediately |
| security-scanner | HIGH | Fix security issue before merge |
| test-adequacy-reviewer | INSUFFICIENT | Add missing tests |
These verdicts are informational—use reviewer discretion:
| Subagent | Verdict | Recommendation |
|---|---|---|
| architecture-validator | DRIFT_DETECTED | Note in feedback, may proceed |
| security-scanner | MEDIUM | Recommend fix, may proceed |
| security-scanner | LOW | Optional fix |
| test-adequacy-reviewer | WEAK | Note gaps, may proceed |
If no subagent reports exist:
/validate was not run (optional step)/validate in feedback# Check for blocking issues
grep -l "Verdict.*CRITICAL" grimoires/loa/a2a/subagent-reports/*.md 2>/dev/null
grep -l "Verdict.*HIGH" grimoires/loa/a2a/subagent-reports/*.md 2>/dev/null
grep -l "Verdict.*INSUFFICIENT" grimoires/loa/a2a/subagent-reports/*.md 2>/dev/null
If any match found, block approval until issues are resolved. </subagent_report_check>
See `resources/REFERENCE.md` for complete checklists: - Versioning (SemVer Compliance) - 4 items - Completeness - 4 items - Functionality - 4 items - Code Quality - 5 items - Testing - 7 items - Security - 7 items - Performance - 5 items - Architecture - 5 items - Blockchain/Crypto - 7 items (if applicable)Red Flags (immediate feedback required):
<complexity_review>
Check code for excessive complexity during every review. These are blocking issues.
| Check | Threshold | Finding |
|---|---|---|
| Function length | >50 lines | "Function too long: {file}:{line} ({X} lines). Split into smaller functions." |
| Parameter count | >5 params | "Too many parameters: {func}() has {X} params. Use options object." |
| Nesting depth | >3 levels | "Deep nesting: {file}:{line}. Refactor with early returns or extract." |
| Cyclomatic complexity | >10 | "High complexity: {func}(). Simplify conditional logic." |
| Check | Threshold | Finding |
|---|---|---|
| Repeated patterns | >3 occurrences | "Duplicate code found in {file1}, {file2}, {file3}. Extract to shared function." |
| Copy-paste code | >10 similar lines | "Near-duplicate blocks at {file}:{line1} and {file}:{line2}. DRY violation." |
| Check | Issue | Finding |
|---|---|---|
| Circular imports | Any | "Circular dependency: {A} → {B} → {A}. Restructure modules." |
| Unnecessary deps | Unused | "Unused import: {file}:{line} imports {module} but never uses it." |
| Heavy deps | For simple task | "Consider lighter alternative to {dep} for this use case." |
| Check | Issue | Finding |
|---|---|---|
| Unclear names | Ambiguous | "Unclear name: {name} at {file}:{line}. Use descriptive name." |
| Abbreviations | Non-standard | "Avoid abbreviation: '{abbr}' → '{full}' at {file}:{line}." |
| Inconsistent | Style varies | "Inconsistent naming: {fileA} uses camelCase, {fileB} uses snake_case." |
| Check | Issue | Finding |
|---|---|---|
| Unused functions | Never called | "Dead code: {func}() at {file}:{line} is never called. Remove." |
| Commented code | Large blocks | "Remove commented code at {file}:{lines}. Use version control." |
| Unreachable code | After return | "Unreachable code after return at {file}:{line}." |
During Phase 2 (Code Review), add complexity checks:
## Complexity Analysis
### Functions Reviewed
- `{func1}()`: OK (25 lines, 3 params, nesting 2)
- `{func2}()`: **ISSUE** (67 lines - too long)
### Duplication Found
- None detected / {description of duplicates}
### Dependency Issues
- None detected / {description of issues}
### Naming Issues
- None detected / {list of naming concerns}
### Dead Code
- None detected / {list of dead code}
BLOCK approval if:
3 duplicate code blocks
Note in feedback but allow:
Tag each over-engineering finding so the engineer gets a crisp delete-list
(reuse the existing SIMPLICITY: feedback template):
| Tag | Meaning | Example finding |
|---|---|---|
delete | Needn't exist (YAGNI) | SIMPLICITY[delete]: unused config layer — remove |
stdlib | Reinvents the standard library | SIMPLICITY[stdlib]: hand-rolled debounce — use stdlib |
native | Reinvents a native platform feature | SIMPLICITY[native]: custom date widget — native input |
yagni | Speculative flexibility/abstraction | SIMPLICITY[yagni]: generic iface for one caller — inline |
shrink | Correct but larger than needed | SIMPLICITY[shrink]: 40 lines that fit in 5 |
A loa:shortcut: marker that names a ceiling with no upgrade trigger is a
SIMPLICITY[shrink] finding — the deferred work rots without a trigger.
End an over-engineering pass with the only metric that matters:
net: -<N> lines possible. If nothing should be cut, say Lean already. Ship.
and stop. Never flag the one required acceptance-check behind non-trivial logic
(the smallest runnable check) for deletion — that is the YAGNI minimum, not bloat.
</complexity_review>
<beads_workflow>
When beads_rust (br) is installed, use it to record review feedback:
br sync --import-only # Import latest state from JSONL
# Add review comment to task
br comments add <task-id> "REVIEW: [feedback summary]"
# Mark task status based on review outcome
br label add <task-id> review-approved # If approved
br label add <task-id> needs-revision # If changes required
| Label | Meaning | When to Apply |
|---|---|---|
needs-review | Awaiting review | Before review |
review-approved | Passed review | After "All good" |
needs-revision | Changes requested | After feedback |
br sync --flush-only # Export SQLite → JSONL before commit
Protocol Reference: See .claude/protocols/beads-integration.md
</beads_workflow>
<visual_communication>
Follow .claude/protocols/visual-communication.md for diagram standards.
Code review feedback may benefit from visual aids for:
If including diagrams in feedback, use Mermaid with preview URLs:
### Suggested Refactoring
Current flow has unnecessary complexity:
```mermaid
graph TD
A[Input] --> B[Validate]
B --> C[Process]
C --> D[Transform]
D --> E[Output]
Preview: View diagram
### Theme Configuration
Read theme from `.loa.config.yaml` visual_communication.theme setting.
Diagram inclusion is **optional** for code reviews - use when visual explanation helps.
</visual_communication>
<retrospective_postlude>
## Invisible Retrospective
After completing main skill logic, scan session for learning opportunities.
**CRITICAL**: This postlude executes SILENTLY. Only surface findings that pass quality gates.
### Step 1: Check Configuration
Read `.loa.config.yaml`:
```yaml
invisible_retrospective:
enabled: true|false
skills:
reviewing-code: true|false
Exit Conditions (skip all processing if any are true):
invisible_retrospective.enabled: false → Log action: DISABLED, exitinvisible_retrospective.skills.reviewing-code: false → Log action: DISABLED, exitcontinuous-learning → Exit silently (but this skill is reviewing-code, so proceed)Search the current conversation for these patterns:
| Signal | Detection Patterns | Weight |
|---|---|---|
| Error Resolution | "bug", "issue", "fixed", "corrected", "the problem was" | 3 |
| Multiple Attempts | "tried", "attempted", "finally", "after reviewing", "looked at" | 3 |
| Unexpected Behavior | "surprisingly", "actually", "turns out", "noticed", "realized" | 2 |
| Workaround Found | "instead", "alternative", "better approach", "refactor to" | 2 |
| Pattern Discovery | "pattern", "convention", "code style", "always use", "prefer" | 1 |
Scoring: Sum weights for each candidate discovery.
Output: List of candidate discoveries (max 5 per skill invocation, from config max_candidates)
If no candidates found:
For each candidate, evaluate these 4 gates:
| Gate | Question | PASS Condition |
|---|---|---|
| Depth | Required multiple investigation steps? | Not just a quick glance - involved analysis, comparison, tracing |
| Reusable | Generalizable beyond this instance? | Applies to similar code patterns, not specific to this review |
| Trigger | Can describe when to apply? | Clear code patterns or conditions that indicate this applies |
| Verified | Solution confirmed working? | Fix verified or pattern validated in this session |
Scoring: Each gate passed = 1 point. Max score = 4.
Threshold: From config surface_threshold (default: 3)
CRITICAL: Before logging or surfacing ANY candidate, sanitize descriptions to prevent sensitive data leakage.
Apply these redaction patterns:
| Pattern | Replacement |
|---|---|
API Keys (sk-*, ghp_*, AKIA*) | [REDACTED_API_KEY] |
Private Keys (-----BEGIN...PRIVATE KEY-----) | [REDACTED_PRIVATE_KEY] |
JWT Tokens (eyJ...) | [REDACTED_JWT] |
Webhook URLs (hooks.slack.com/*, hooks.discord.com/*) | [REDACTED_WEBHOOK] |
File Paths (/home/*/, /Users/*/) | /home/[USER]/ or /Users/[USER]/ |
| Email Addresses | [REDACTED_EMAIL] |
| IP Addresses | [REDACTED_IP] |
Generic Secrets (password=, secret=, etc.) | $key=[REDACTED] |
If any redactions occur, add "redactions_applied": true to trajectory log.
Write to grimoires/loa/a2a/trajectory/retrospective-{YYYY-MM-DD}.jsonl:
{
"type": "invisible_retrospective",
"timestamp": "{ISO8601}",
"skill": "reviewing-code",
"action": "DETECTED|EXTRACTED|SKIPPED|DISABLED|ERROR",
"candidates_found": N,
"candidates_qualified": N,
"candidates": [
{
"id": "learning-{timestamp}-{hash}",
"signal": "error_resolution|multiple_attempts|unexpected_behavior|workaround|pattern_discovery",
"description": "Brief description of the review learning",
"score": N,
"gates_passed": ["depth", "reusable", "trigger", "verified"],
"gates_failed": [],
"qualified": true|false
}
],
"extracted": ["learning-id-001"],
"latency_ms": N
}
IF any candidates score >= surface_threshold:
Add to NOTES.md ## Learnings section:
CRITICAL - Markdown Escape: Before inserting description, escape these characters:
# → \#, * → \*, [ → \[, ] → \], \n → ## Learnings
- [{timestamp}] [reviewing-code] {ESCAPED Brief description} → skills-pending/{id}
If ## Learnings section doesn't exist, create it after ## Session Log.
Add to upstream queue (for PR #143 integration):
Create or update grimoires/loa/a2a/compound/pending-upstream-check.json:
{
"queued_learnings": [
{
"id": "learning-{timestamp}-{hash}",
"source": "invisible_retrospective",
"skill": "reviewing-code",
"queued_at": "{ISO8601}"
}
]
}
Show brief notification:
────────────────────────────────────────────
Learning Captured
────────────────────────────────────────────
Pattern: {brief description}
Score: {score}/4 gates passed
Added to: grimoires/loa/NOTES.md
────────────────────────────────────────────
IF no candidates qualify:
On ANY error during postlude execution:
Log to trajectory:
{
"type": "invisible_retrospective",
"timestamp": "{ISO8601}",
"skill": "reviewing-code",
"action": "ERROR",
"error": "{error message}",
"candidates_found": 0,
"candidates_qualified": 0
}
Continue silently - do NOT interrupt the main workflow
Do NOT surface error to user
Respect these limits from config:
max_candidates: Maximum candidates to evaluate per invocation (default: 5)max_extractions_per_session: Maximum learnings to extract per session (default: 3)Track session extractions in trajectory log and skip extraction if limit reached.
</retrospective_postlude>