refactor: simplify memory and shadow-detection skills

Trim verbose implementation details that duplicate what the bash helper
scripts already handle. Memory skill: 278 -> 120 lines. Shadow detection
skill: 180 -> 66 lines. All essential protocols, tables, and commands
preserved; removed redundant algorithm descriptions, multiple examples,
and narrative prose.
This commit is contained in:
2026-04-06 20:42:47 +02:00
parent 55a6ba14c9
commit 1baaa79946
2 changed files with 83 additions and 354 deletions

View File

@@ -11,21 +11,14 @@ description: |
# Cross-Run Memory
ArcheFlow forgets everything after each run. If Guardian repeatedly flags the same type of issue (e.g., timeline errors in fiction, missing null checks in code), the next run starts from zero. This skill fixes that by extracting lessons from completed runs and injecting them into future agent prompts.
ArcheFlow forgets everything after each run. This skill extracts lessons from completed runs and injects them into future agent prompts, so recurring issues (timeline errors, missing null checks) are caught proactively.
## Storage
```
.archeflow/memory/lessons.jsonl # Append-only, one lesson per line
```
Each lesson is a single JSON line:
```jsonl
{"id":"m-001","ts":"2026-04-03T14:00:00Z","run_id":"2026-04-03-der-huster","type":"pattern","source":"guardian","description":"Timeline references must match story start day","frequency":2,"severity":"bug","domain":"writing","tags":["continuity","timeline"],"last_seen_run":"2026-04-03-der-huster","runs_since_last_seen":0}
{"id":"m-002","ts":"2026-04-03T15:00:00Z","run_id":"2026-04-03-der-huster","type":"preference","source":"user_feedback","description":"User prefers single bundled PR over many small ones","frequency":1,"severity":"info","domain":"general","tags":["workflow"],"last_seen_run":"","runs_since_last_seen":0}
{"id":"m-003","ts":"2026-04-04T10:00:00Z","run_id":"2026-04-04-auth-fix","type":"archetype_hint","source":"sage","description":"Voice drift most common in long monologue passages","frequency":3,"severity":"warning","domain":"writing","tags":["voice","prose"],"archetype":"story-sage","last_seen_run":"2026-04-04-auth-fix","runs_since_last_seen":0}
{"id":"m-004","ts":"2026-04-04T11:00:00Z","run_id":"2026-04-04-auth-fix","type":"anti_pattern","source":"maker","description":"Splitting auth middleware into per-route handlers causes duplication","frequency":1,"severity":"warning","domain":"code","tags":["auth","middleware"],"last_seen_run":"2026-04-04-auth-fix","runs_since_last_seen":0}
.archeflow/memory/archive.jsonl # Decayed lessons (frequency reached 0)
.archeflow/memory/audit.jsonl # Injection audit trail
```
## Lesson Types
@@ -33,245 +26,95 @@ Each lesson is a single JSON line:
| Type | Source | Description |
|------|--------|-------------|
| `pattern` | Auto-detected | Recurring finding across runs (same category + similar description) |
| `preference` | Manual | User correction or workflow preference (added via CLI) |
| `preference` | Manual | User correction or workflow preference (injected immediately, skips frequency threshold) |
| `archetype_hint` | Auto-detected | Per-archetype insight (e.g., Sage catches voice drift in monologues) |
| `anti_pattern` | Manual or auto | Something that was tried and failed avoid repeating |
| `anti_pattern` | Manual or auto | Something that was tried and failed -- avoid repeating |
## Lesson Fields
## Lesson JSON Fields
| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique ID, format `m-NNN` (monotonically increasing) |
| `ts` | ISO 8601 | When the lesson was created or last updated |
| `id` | string | `m-NNN` (monotonically increasing) |
| `ts` | ISO 8601 | Created or last updated |
| `run_id` | string | Run that created or last triggered this lesson |
| `type` | string | One of: `pattern`, `preference`, `archetype_hint`, `anti_pattern` |
| `source` | string | Archetype or `user_feedback` that originated the lesson |
| `type` | string | `pattern`, `preference`, `archetype_hint`, `anti_pattern` |
| `source` | string | Archetype name or `user_feedback` |
| `description` | string | Human-readable lesson text |
| `frequency` | integer | How many times this lesson was triggered |
| `severity` | string | `bug`, `warning`, `info`, or `recommendation` |
| `frequency` | integer | Times this lesson was triggered |
| `severity` | string | `bug`, `warning`, `info`, `recommendation` |
| `domain` | string | `writing`, `code`, `general`, or project-specific |
| `tags` | string[] | Keywords for matching and filtering |
| `archetype` | string or null | For `archetype_hint` type — which archetype this applies to |
| `last_seen_run` | string | Run ID where this lesson was last matched |
| `runs_since_last_seen` | integer | Counter for decay — incremented each run that does NOT trigger this lesson |
| `archetype` | string? | For `archetype_hint` -- which archetype this applies to |
| `last_seen_run` | string | Run ID where last matched |
| `runs_since_last_seen` | integer | Counter for decay |
Example:
```jsonl
{"id":"m-001","ts":"2026-04-03T14:00:00Z","run_id":"2026-04-03-der-huster","type":"pattern","source":"guardian","description":"Timeline references must match story start day","frequency":2,"severity":"bug","domain":"writing","tags":["continuity","timeline"],"last_seen_run":"2026-04-03-der-huster","runs_since_last_seen":0}
```
---
## Auto-Detection
After each `run.complete`, the orchestrator runs lesson extraction:
After each `run.complete`, extract lessons from findings:
```bash
./lib/archeflow-memory.sh extract .archeflow/events/<run_id>.jsonl
```
### Extraction Algorithm
The script reads `review.verdict` events, matches findings against existing lessons by keyword overlap (50%+ threshold), increments frequency on matches, and creates new candidate lessons (frequency: 1) for unmatched findings with severity >= WARNING.
1. **Read all `review.verdict` events** from the completed run's JSONL.
2. **For each finding** in each verdict:
a. Tokenize the finding description into keywords (lowercase, strip punctuation).
b. Compare keywords against each existing lesson's description + tags.
c. **Match threshold:** 50%+ keyword overlap between finding and lesson.
3. **If match found:** Update the existing lesson:
- Increment `frequency` by 1
- Update `ts` to now
- Update `last_seen_run` to current run ID
- Reset `runs_since_last_seen` to 0
4. **If no match AND severity >= WARNING:** Add as candidate lesson with `frequency: 1`.
5. **Candidates become active** when `frequency >= 2` (triggered in a second run).
### Promotion Rule
A finding that appears in only one run stays at `frequency: 1` — it might be a one-off. Once the same pattern appears in a second run (matched by keyword overlap), it gets promoted to `frequency: 2` and becomes eligible for injection.
This prevents noise from single-run anomalies while still capturing genuine recurring issues quickly.
---
**Promotion rule:** A finding needs `frequency >= 2` (seen in 2+ runs) before injection. This filters out one-off noise. Preferences skip this threshold.
## Injection
At run start, before spawning agents, the orchestrator injects relevant lessons:
Before spawning agents, inject relevant lessons:
```bash
LESSONS=$(./lib/archeflow-memory.sh inject <domain> <archetype>)
```
### Injection Rules
Rules: filters by domain (or `general`), optionally by archetype, requires `frequency >= 2`, sorts by frequency descending, caps at 10 lessons. Lessons with `frequency >= 5` are always injected regardless of filters.
1. Read `lessons.jsonl`.
2. Filter by `domain` (exact match or `general`) and optionally by `archetype`.
3. Only include lessons with `frequency >= 2` (confirmed patterns).
4. Sort by frequency descending (most common first).
5. Cap at **10 lessons** per injection.
6. Lessons with `frequency >= 5` are **always injected** regardless of domain/archetype filter (they are universal enough to matter).
### Injection Format
Append to the agent's system prompt as a structured section:
Injected as a markdown section appended to the agent's system prompt:
```markdown
## Known Issues (from past runs)
- Timeline references must match story start day [seen 3x, guardian]
- Voice drift common in monologue passages >200 words [seen 2x, sage]
- Missing null checks in API response handlers [seen 5x, guardian]
```
### Integration with Run Skill
In the `run` skill, after Step 0 (Initialize) and before Step 1 (Plan Phase):
```bash
# Load cross-run memory for this domain
MEMORY_LESSONS=$(./lib/archeflow-memory.sh inject "$DOMAIN" "")
# Inject into Explorer/Creator prompts if non-empty
if [[ -n "$MEMORY_LESSONS" ]]; then
EXPLORER_PROMPT="${EXPLORER_PROMPT}
${MEMORY_LESSONS}"
CREATOR_PROMPT="${CREATOR_PROMPT}
${MEMORY_LESSONS}"
fi
```
For reviewers in the Check phase, inject archetype-specific lessons:
```bash
GUARDIAN_LESSONS=$(./lib/archeflow-memory.sh inject "$DOMAIN" "guardian")
SAGE_LESSONS=$(./lib/archeflow-memory.sh inject "$DOMAIN" "sage")
```
---
## Decay
Lessons that stop being relevant should fade out. After each `run.complete`, apply decay:
After each `run.complete`, apply decay: lessons not seen for 10 runs lose 1 frequency. When frequency reaches 0, the lesson is archived.
```bash
./lib/archeflow-memory.sh decay
```
### Decay Algorithm
1. For every lesson in `lessons.jsonl`:
- If `last_seen_run` is NOT the current run → increment `runs_since_last_seen` by 1
2. If `runs_since_last_seen >= 10`:
- Decrement `frequency` by 1
- Reset `runs_since_last_seen` to 0
3. If `frequency` drops to 0:
- Move the lesson to `.archeflow/memory/archive.jsonl` (append)
- Remove from `lessons.jsonl`
This means a lesson that was seen 5 times but then stops appearing will survive 50 runs of non-triggering before being fully archived (5 decrements x 10 runs each).
---
## Manual Management
### Add a lesson
```bash
archeflow memory add "User prefers single bundled PR" # Add preference (injected immediately)
archeflow memory list # Show all active lessons
archeflow memory forget m-002 # Archive a lesson
```
## Audit Trail
Track which lessons are injected per run and whether they were effective. Pass `--audit <run_id>` to inject to log records. After a run, `audit-check <run_id>` compares injected lessons against review findings: no matching finding = helpful (issue prevented), matching finding = ineffective (issue repeated despite injection).
```bash
archeflow memory add "User prefers single bundled PR over many small ones"
# Internally: ./lib/archeflow-memory.sh add preference "User prefers single bundled PR over many small ones"
./lib/archeflow-memory.sh inject "$DOMAIN" "" --audit "$RUN_ID"
./lib/archeflow-memory.sh audit-check <run_id>
```
Manually added lessons start at `frequency: 1` but with type `preference`, which means they are injected immediately (preferences skip the frequency >= 2 threshold).
### List lessons
```bash
archeflow memory list
# Internally: ./lib/archeflow-memory.sh list
```
Output:
```
ID Freq Type Domain Description
m-001 3 pattern writing Timeline references must match story start day
m-002 1 preference general User prefers single bundled PR over many small ones
m-003 5 archetype_hint writing Voice drift most common in long monologue passages
m-004 1 anti_pattern code Splitting auth middleware causes duplication
```
### Forget a lesson
```bash
archeflow memory forget m-002
# Internally: ./lib/archeflow-memory.sh forget m-002
```
Moves the lesson to `archive.jsonl` regardless of frequency.
---
## Integration Points
| Moment | Action | Script Command |
|--------|--------|----------------|
| After `run.complete` | Extract lessons from findings | `archeflow-memory.sh extract <events.jsonl>` |
| After extraction | Apply decay to all lessons | `archeflow-memory.sh decay` |
| Before agent spawn (run start) | Inject relevant lessons | `archeflow-memory.sh inject <domain> <archetype>` |
| Before agent spawn | Inject relevant lessons | `archeflow-memory.sh inject <domain> <archetype>` |
| User command | Add/list/forget lessons | `archeflow-memory.sh add/list/forget` |
## Audit Trail
Track which lessons are injected into each run and whether they were effective.
### Storage
```
.archeflow/memory/audit.jsonl # Append-only audit log
```
### Injection Audit Record
When `--audit <run_id>` is passed to the `inject` command, an audit record is written:
```jsonl
{"ts":"2026-04-04T10:00:00Z","run_id":"2026-04-04-auth-fix","domain":"code","archetype":"","lessons_injected":["m-001","m-003"],"lesson_count":2}
```
Usage:
```bash
./lib/archeflow-memory.sh inject "$DOMAIN" "" --audit "$RUN_ID"
```
### Effectiveness Check
After a run completes, check whether injected lessons prevented issues:
```bash
./lib/archeflow-memory.sh audit-check <run_id>
```
This command:
1. Reads `audit.jsonl` for lessons injected in the given run
2. Reads the run's event file for `review.verdict` events
3. For each injected lesson, checks keyword overlap between the lesson's description and review findings
4. **No matching finding** = `helpful` (the lesson likely prevented the issue)
5. **Matching finding** = `ineffective` (the issue repeated despite the lesson being injected)
6. Appends effectiveness results to `audit.jsonl`
### Effectiveness Over Time
By querying `audit.jsonl` for effectiveness records, you can measure:
- Which lessons consistently prevent issues (high `helpful` count)
- Which lessons are not working (high `ineffective` count — consider rewording or removing)
- Overall memory system ROI (ratio of helpful to ineffective across all runs)
```bash
# Count effectiveness per lesson
jq -r 'select(.type == "effectiveness_check") | [.lesson_id, .effectiveness] | @tsv' .archeflow/memory/audit.jsonl | sort | uniq -c
```
---
## Design Principles
1. **Append-only storage.** `lessons.jsonl` is append-only during writes; decay rewrites the file in place but preserves all data (archived lessons move to `archive.jsonl`).
2. **Conservative promotion.** A finding must appear in 2+ runs before injection. One-offs are noise.
3. **Graceful degradation.** If `lessons.jsonl` doesn't exist, injection returns empty — no error, no block.
4. **Cheap.** Keyword matching, not embeddings. `jq` for JSON, `grep` for matching. No external services.
5. **Bounded.** Max 10 lessons injected per prompt. Prevents context pollution.

View File

@@ -5,176 +5,62 @@ description: Use when monitoring agent behavior for dysfunction, when an agent s
# Shadow Detection
Every archetype has a **virtue** (its unique contribution) and a **shadow** (the destructive inversion of that virtue). A shadow activates when the virtue is pushed too far.
Every archetype has a virtue and a shadow (its destructive inversion). Shadow activates when the virtue is pushed too far.
```
Virtue (healthy) → pushed too far → Shadow (dysfunction)
Contextual Clarity → can't stop → Rabbit Hole
Decisive Framing → over-builds → Over-Architect
Execution Discipline → no guardrails → Rogue
Threat Intuition → sees threats only → Paranoid
Assumption Surfacing → questions only → Paralytic
Adversarial Creativity → noise over signal → False Alarm
Maintainability Judgment → reviews only → Bureaucrat
```
| Archetype | Virtue | Shadow |
|-----------|--------|--------|
| Explorer | Contextual Clarity | Rabbit Hole |
| Creator | Decisive Framing | Over-Architect |
| Maker | Execution Discipline | Rogue |
| Guardian | Threat Intuition | Paranoid |
| Skeptic | Assumption Surfacing | Paralytic |
| Trickster | Adversarial Creativity | False Alarm |
| Sage | Maintainability Judgment | Bureaucrat |
---
## Explorer Rabbit Hole
**Virtue inverted:** Contextual Clarity becomes compulsive investigation — or output that dumps without analyzing.
### Explorer -> Rabbit Hole
**Detect** (any): output >2000w without Recommendation | >3 tangents | >15 files no patterns | no synthesis in final 25%
**Correct**: "Summarize top 3 findings and one recommendation in under 300 words."
**Symptoms:**
- Research output keeps growing but never synthesizes
- "I found one more thing to check" repeated 3+ times
- Reading more than 15 files without producing findings
- Output is a raw inventory of files with no analysis or recommendation
### Creator -> Over-Architect
**Detect** (any): >2 new abstractions for a single feature | "future-proof" in rationale | scope exceeds task by >50% | >1 new package for one feature
**Correct**: "Design for the current order of magnitude. Remove abstractions that serve hypothetical requirements."
**Detection Checklist** (trigger on ANY):
- [ ] Output >2000 words without a `### Recommendation` section
- [ ] >3 tangent topics not directly related to the original task
- [ ] >15 files read with no `### Patterns` identified
- [ ] No synthesis language (recommend, suggest, conclusion, finding, summary) in final 25% of output
### Maker -> Rogue
**Detect** (any): zero test files with >=3 files changed | single monolithic commit | diff contains files not in proposal | no evidence of running tests
**Correct**: "Read the proposal. Write a test. Commit what you have. Revert changes to files not in the proposal."
**Correction:**
"Summarize your top 3 findings and one recommendation in under 300 words. If your output has no Recommendation section, add one. A dump is not research."
### Guardian -> Paranoid
**Detect** (any): CRITICAL:WARNING ratio >2:1 (min 3 findings) | zero APPROVED in 3+ reviews | <50% findings include a fix | findings require already-compromised systems
**Correct**: "For each CRITICAL: would a senior engineer block a PR for this? If not, downgrade. Every rejection must include a specific fix."
### Skeptic -> Paralytic
**Detect** (any): >7 challenges in a single review | <50% include alternatives | same concern appears 2+ times reworded | >3 findings outside task scope
**Correct**: "Rank challenges by impact. Keep top 3. Each must include a specific alternative. Delete the rest."
### Trickster -> False Alarm
**Detect** (any): findings reference code untouched by diff | >10 findings for <5 files | impossible deployment scenarios | >3 findings without repro steps
**Correct**: "Delete findings outside the diff. Rank remaining by likelihood x impact. Keep top 3-5."
### Sage -> Bureaucrat
**Detect** (any): review words >2x diff lines | findings reference files not in changeset | >2 "consider" without concrete action | suggesting docs for <5-line functions
**Correct**: "Limit to issues affecting maintainability in the next 6 months. Every finding must end with a specific action."
---
## Creator → Over-Architect
**Virtue inverted:** Decisive Framing becomes designing at the wrong scale.
## Escalation Protocol
**Symptoms:**
- Abstraction layers for one-time operations
- Future-proofing for requirements that don't exist
- Configuration systems for things that could be constants
- Proposal has more infrastructure than business logic
**Detection Checklist** (trigger on ANY):
- [ ] >2 new abstractions (interfaces, base classes, factories, registries) for a single feature
- [ ] "In the future we might need..." or "future-proof" appears in rationale
- [ ] Proposal scope (files changed) exceeds original task scope by >50%
- [ ] More than 1 new package/module introduced for a single feature
**Correction:**
"Design for the current order of magnitude. If the app has 1000 users, design for 10,000 — not 10 million. Remove abstractions that serve hypothetical requirements."
---
## Maker → Rogue
**Virtue inverted:** Execution Discipline becomes reckless shipping — or expanding beyond the plan.
**Symptoms:**
- Writing code before reading the proposal fully
- No tests, or tests written after implementation
- Large uncommitted working tree
- Files changed that aren't mentioned in the proposal
**Detection Checklist** (trigger on ANY):
- [ ] Zero test files (`.test.`, `.spec.`, `_test.`) in the changeset with >=3 files changed
- [ ] Single monolithic commit instead of incremental commits
- [ ] Diff contains files not listed in the Creator's proposal `### Changes` section
- [ ] No evidence of running existing test suite before finishing
**Correction:**
"Read the proposal. Write a test. Commit what you have. Revert changes to files not in the proposal. Then continue."
---
## Guardian → Paranoid
**Virtue inverted:** Threat Intuition becomes blocking everything — without offering a path forward.
**Symptoms:**
- Every finding marked CRITICAL
- Blocking on theoretical risks with < 1% probability
- Rejecting without suggesting how to fix
- Security concerns for internal-only code at external-API severity
**Detection Checklist** (trigger on ANY):
- [ ] CRITICAL:WARNING ratio >2:1 (with minimum 3 total findings)
- [ ] Zero APPROVED verdicts in 3+ consecutive reviews
- [ ] <50% of findings include a suggested fix in the `Fix` column
- [ ] Findings reference attack scenarios that require already-compromised internal systems
**Correction:**
"For each CRITICAL finding, answer: Would a senior engineer block a PR for this? If not, downgrade. Every rejection must include a specific, implementable fix."
---
## Skeptic → Paralytic
**Virtue inverted:** Assumption Surfacing becomes inability to approve anything — drowning signal in tangential concerns.
**Symptoms:**
- More than 7 challenges raised
- Challenges without suggested alternatives
- "What about X?" chains that drift from the task
- Restating the same concern in different words
**Detection Checklist** (trigger on ANY):
- [ ] >7 findings/challenges raised in a single review
- [ ] <50% of findings include an alternative in the `Fix` column
- [ ] Same conceptual concern appears 2+ times with different wording
- [ ] >3 findings reference code or scenarios outside the task scope
**Correction:**
"Rank your challenges by impact. Keep the top 3. Each must include a specific alternative. Delete the rest."
---
## Trickster → False Alarm
**Virtue inverted:** Adversarial Creativity becomes noise — too many low-signal findings drowning the real issues.
**Symptoms:**
- Testing code that wasn't changed
- Reporting non-bugs as bugs (unrealistic test scenarios)
- 20 findings when 3 good ones would cover the real risks
- Edge cases for edge cases (diminishing returns)
**Detection Checklist** (trigger on ANY):
- [ ] Any finding references code untouched by the Maker's diff
- [ ] >10 findings for a change touching <5 files
- [ ] Findings describe scenarios requiring conditions that can't occur in the deployment context
- [ ] >3 findings without reproduction steps
**Correction:**
"Quality over quantity. Delete findings outside the Maker's diff. Rank remaining by likelihood x impact. Keep top 3-5. Three real findings beat twenty noise."
---
## Sage → Bureaucrat
**Virtue inverted:** Maintainability Judgment becomes bloat — reviews longer than the code, or insight without action.
**Symptoms:**
- Review longer than the code change itself
- Requesting documentation for self-evident code
- Suggesting refactors unrelated to the current task
- Deep-sounding analysis that doesn't end with a specific action
**Detection Checklist** (trigger on ANY):
- [ ] Review word count >2x the code change's line count (rough: review words > diff lines x 2)
- [ ] Any finding references files not in the Maker's changeset
- [ ] >2 findings use "consider" or "think about" without a concrete action in the `Fix` column
- [ ] Suggesting documentation for functions with <5 lines or self-descriptive names
**Correction:**
"Limit your review to issues that affect maintainability in the next 6 months. Every finding must end with a specific action. If you can't state the consequence of NOT fixing it, don't raise it."
---
## Shadow Escalation Protocol
1. **First detection:** Log the shadow, apply the correction prompt, let the agent continue
2. **Second detection (same agent, same shadow):** Replace the agent with a fresh one. The shadow is entrenched.
3. **Shadow detected in 3+ agents in the same cycle:** The task itself may be poorly scoped. Escalate to the user: "Multiple agents are struggling — the task may need to be broken down."
1. **1st detection:** Log the shadow, apply the correction prompt, let the agent continue
2. **2nd detection (same agent, same shadow):** Replace the agent -- the shadow is entrenched
3. **3+ agents shadowed in same cycle:** Escalate to user -- the task may need to be broken down
## Shadow Immunity
Some behaviors LOOK like shadows but aren't:
Some behaviors look like shadows but are not. **Rule of thumb:** shadow = behavior disconnected from the goal. Intensity alone is not a shadow.
- Explorer reading 20 files in a monorepo with scattered dependencies **not a rabbit hole** if each file is genuinely relevant
- Creator adding an abstraction **not over-architect** if the abstraction is genuinely needed by the current task
- Guardian blocking with 2 CRITICAL findings → **not paranoid** if both are genuine security vulnerabilities
- Trickster finding 5 edge cases **not false alarm** if all are in the changed code with reproduction steps
- Sage writing a long review **not bureaucrat** if the change is large and every finding is actionable
**Rule of thumb:** Shadow = behavior disconnected from the goal. Intensity alone is not a shadow.
- Explorer reading 20 files in a monorepo with scattered dependencies -- not a rabbit hole if each file is genuinely relevant
- Creator adding an abstraction -- not over-architect if the current task genuinely needs it
- Guardian blocking with 2 CRITICALs -- not paranoid if both are genuine security vulnerabilities
- Trickster finding 5 edge cases -- not false alarm if all are in changed code with repro steps
- Sage writing a long review -- not bureaucrat if the change is large and every finding is actionable