Pi × EvoX Loop — Agent Experience Inheritance Skill
Let every pitfall be encountered only once per agent: failed experiences are automatically stored (guard-filtered), and verified fixes for similar tasks are recalled automatically.
Terminology convention (0.29): The main text uses English; technical fields are noted with the original English term in parentheses on first occurrence (e.g., "signal matching signals_match"), and thereafter consistently use English. For a complete Chinese-English glossary, see
docs/faq.mdQ17.Document map (0.21 layered):
- New users only need to read three sections: 30-second quick start → Flow A → Flow B (about 60 lines); the rest as needed.
- One-minute decision guide:
docs/one-pager.md(new in 0.30)- Best practices central hub:
examples/quickstart.md(5-minute closed loop) +docs/overview.md(project overview) +docs/common-mistakes.md(14 anti-patterns) — three documents covering "start/overview/avoid traps".- The rest of this file = triggers/safety summary/anti-pattern quick reference/navigation;
docs/advanced.md= backfill addressing/timeline/harvest/concurrency lock/shared pool/host integration/operations/security gate details;docs/common-mistakes.md= complete list of common usage errors;docs/config-errors.md= common configuration errors;docs/faq.md= complete FAQ.docs/research.md= Flow C controlled experiments + trap design discipline — research-only, most users need not open it.
30-Second Quick Start
EN: Requires Node >= 22. Optional
@evomap/evolverintegration is GPL-3.0-or-later (only if you install and use--engine evolver); the default light backend is MIT, zero-dependency, zero-exfiltration. Three things only: A recall validated fixes at task start, B deposit after fixing a non-obvious failure, C (optional, research) controlled experiments. Daily use = A/B only. ⚠️ Prerequisite: Node ≥ 22 (check withnode -v; older versions are not supported and must be upgraded first). Optional@evomap/evolverintegration is GPL-3.0-or-later — only relevant if you actively install and use--engine evolver; the default light backend is MIT, zero-dependency, zero-exfiltration.This Skill does only three things: A recall validated fixes at task start, B deposit after fixing a non-obvious failure, C (optional, research) quantify benefits with controlled experiments. Daily use only A/B; C is fully off by default. Do not use C in production.
# A — At task start, targeted recall (replace with your task description)
node code/evolver-recall.mjs --query "Handle GBK encoded file errors" --top 5
# B — After fixing a non-obvious failure, paste the original error, generate a draft, then commit FIX to store
node code/light-cli.mjs draft --error "<original error>" --tool <tool name> --context "<what you were doing>"
node code/light-cli.mjs draft --error "<original error>" --strategy "AVOID: <what NOT to do> FIX: <specific parameters/commands/encoding>" --commit
All commands should be executed from the repository root; if dependencies are not installed, see the "Installation" section below.
First Run · 3 Steps to Ready (Self-Check First, Then Deposit)
- Install Node ≥ 22 (required by traps generator and pi/evolver; see FAQ·Q8);
- Self-check environment:
node code/light-cli.mjs doctor— validates Node version, experience store directory writability, and hit registration directory reachability (provides guidance for failures); - Light up the experience store: An empty store with no recallable fixes is normal. Deposit the first fix using Flow B below to light it up.
Newcomer Essentials (Quick FAQ Overview)
- First run recall shows "No recallable fixes"? Normal — the store starts empty; run Flow B once to deposit and light it up (FAQ·Q1).
- Node version requirement? Must be ≥ 22 (traps generator also needs Python 3); too low and pi/evolver will fail to start (FAQ·Q8).
- More questions in
docs/faq.md(complete 14 entries) and the anti-pattern quick reference below.
Installation (One-Time)
EN: One-time setup. A/B flows need ONLY Node >= 22 — zero npm dependencies. Get the folder by any of three paths below; any location works (a "skill" is just a folder — put it wherever your host expects, e.g.
~/.claude/skills/pi-evox-lab). Default backend = built-in light (pure Node, MIT). evolver is an optional integration (--engine evolver, needsnpm install). Flow C additionally needs Pi CLI + an OpenAI-compatible LLM key.
Three ways to obtain (choose any):
# Path 1: git clone (recommended)
git clone https://github.com/stwhwing/pi-evox-lab.git && cd pi-evox-lab
# Path 2: Restricted network → Download Release zip (with sha256), extract and use
# https://github.com/stwhwing/pi-evox-lab/releases (domestic accessible mirrors in FAQ Q7)
# Path 3: One-click marketplace install — search pi-evox-loop on skillhub.cn / ClawHub (for WorkBuddy/OpenClaw users)
node -v # Prerequisite: Node >= 22 (the only hard dependency)
node code/light-cli.mjs doctor # 30-second self-check — if passed, it's ready, no install steps needed
- A/B daily flow has zero npm dependencies; the following
npm installis only for optional integration/experimental mode C:
Provider Configuration (Only for Flow C)
EN: Flow C only - any OpenAI-compatible endpoint;
$ENVinterpolation needs pi >= 0.85.1. Examples + domestic endpoints (DeepSeek/Bailian/SiliconFlow/Zhipu):docs/providers.md.
Flow A: At Task Start — Recall Experience (Any Non-Trivial Task)
EN: Flow A - recall at task start.
--querywith the task text does targeted recall (unrelated experience is never injected - injection is gated by signals_match x query-token overlap, below threshold = no injection). On error (T3), the raw error text IS the query. Multiple matches: geneConflicts drops anti_patterns-mutual low scorers; no targeted hit = no injection. Register the hit at task end with--register-hit --gene <id>(id-addressed, concurrency-safe).
# Common domestic scenario (Chinese Windows logs / CSV default GBK, reading as utf-8 will fail) — after running starter with an empty store, try this first for best effect
node code/evolver-recall.mjs --query "Reading Chinese logs encounters UnicodeDecodeError" --top 5
# Recommended: use task text for targeted recall (experience irrelevant to the task will not be injected)
node code/evolver-recall.mjs --query "<a one-line description/key signal of the current task>" --top 5
# When encountering an error (T3): the original error text is the query — the error itself is the reminder
node code/evolver-recall.mjs --error "UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc4"
- Outputs only a list of gene IDs that are audited AND passed the fix guard AND targeted to the query (an empty store gives a clear prompt, which is normal);
- Default parameters:
--topdefaults to 5 entries (soft prompt injection has context cost; less is better); the experience store has no hard capacity limit, but it's recommended to keep a single store below 500 entries (above which targeting accuracy decreases; use a shared pool to distribute); - Targeting rule: scored by intersection of gene
signals_matchhits and query tokens; below threshold, the entire entry is not injected (avoiding non-targeted injection which increases costs); - Multi-gene conflicts: the
geneConflictsguard automatically removesanti_patternsmutually exclusive low-scoring items; if multiple remain, take the highest scorer; if no targeted item exists, it's better not to inject rather than using irrelevant genes; - When relevant to the task, prioritize its use; at task end, if a particular gene was actually used, register a hit (
--gene <id>addressed by id, concurrency-safe):
node code/evolver-recall.mjs --register-hit --gene <asset_id or gene_id> --note "<one-line task description>"
- Do not force irrelevant experience; unadopted entries need not be registered.
Flow B: After Fixing a Failure — Deposit Experience
EN: Flow B - deposit after fixing a non-obvious failure. Deposit bar (any one): docs/2+ tries needed, environment-specific, counter-intuitive error, or second occurrence. Guided path:
draft --errorauto-extracts signals + pre-fills AVOID + writes anti_patterns; fill in FIX then--commit. Manual path:distillwith explicit signals. strategy MUST be an executable fix (params/commands/encodings) - success summaries are filtered by the repair-signal guard.--shareableonly for genes meant for the shared pool. Deposit criteria (any one qualifies):
- Troubleshooting required checking documentation / trial and error ≥ 2 times to resolve;
- Depends on machine or environment characteristics (encoding, path conventions, shell differences, network environment);
- Error message is counter-intuitive or inconsistent with documentation;
- The same pitfall has appeared a second time in historical tasks. (If none of the criteria are met, a normal failure need not be deposited — to avoid noise in the experience store.)
Recommended path: Guided (paste original error; signals and "negative experience" are automatically extracted)
# 1) Generate draft: auto-extract signals_match + pre-fill AVOID template + write anti_patterns (negative experience tokens)
node code/light-cli.mjs draft --error "<original error text>" --tool <tool name> --context "<what you were doing>"
# 2) Complete FIX according to the draft, then deposit (--strategy overrides pre-filled placeholders)
node code/light-cli.mjs draft --error "<original error text>" \
--strategy "AVOID: <what NOT to do> FIX: <specific parameters/commands/encoding>" --commit
# 3) Audit (four-state state machine — see the 'Audit State Machine' section below; approve automatically runs evidence collection first)
node code/light-cli.mjs approve <gene_id>
AVOID/FIX template boundaries (write clearly to avoid guard rejection):
| Section | What to Write | Boundary |
|---|---|---|
AVOID: | What NOT to do (negative experience, may contain dangerous words — those are warnings) | One to two sentences; do not write success summaries |
FIX: | Executable fix specific to parameters/commands/encoding | Must be genuinely filled — placeholders/retry logs/narrations will be rejected by the depositionGate (fail-closed) |
anti_patterns: | Single token literal (e.g., assume-default-utf8) | Conflict determination matches the entire string; do not write kebab-case long phrases |
signals_match: | Recall targeting signal words | Only recallable if there's overlap with the query words; do not stack irrelevant words |
Alternative path: Manual (when signals are already clear)
node code/light-cli.mjs distill --category repair --signals bash,exception \
--strategy "<one-line fix; multiple steps separated by semicolons; must be specific to parameters/commands/encoding>" \
--summary "<one-line description of the pitfall>" [--shareable]
- strategy must be written as an executable fix (including specific parameters/commands), do not write success summaries — the recall side has a fix guard that will filter out success summaries (quality over quantity);
--shareableonly when you want the gene to enter the shared pool (default not shared = no external transmission);- Deposit threshold's real data (honest boundaries): The density of "clean fix pairs" that can be automatically extracted in real production sessions is very low (measured
distillablePairs=0) — the library's genes mainly come from manual/guided deposits.
Deposit Quality Gate depositionGate (0.17.0, fail-closed)
EN: Quality gate at DEPOSITION time (fail-closed): rejects unfilled placeholder / retry-log repetition / narration openings / missing repair-signal words / AVOID-without-FIX. Non-interactive deposits default to quarantined. Full review semantics: the「Audit State Machine」section below. On
distill/draft --commit, each entry is checked; invalid entries are directly rejected (not written to disk):
| Rejection Condition | Reason | Next Step |
|---|---|---|
FIX is an unfilled placeholder <fill in executable fix here> | Useless after injection | Fill in the real fix in the draft and re-submit |
retry with corrected args (retry log paraphrase) | "Retried and it worked" is not a fix | Write AVOID (why wrong) + FIX (how to do it) |
| Narration opening (Now I understand…) | Reasoning stream is not executable | Same as above |
| Missing fix signal words | Does not describe a pitfall and fix | Same as above |
| Has AVOID but no FIX (half-baked) | Only pitfall without fix; useless after injection (0.22 review evidence: all 3 truncated deposits were this form) | Add executable fix (parameters/commands/encoding) |
Audit State Machine (Single Source of Truth · 0.36 Convergence)
All audit semantics from gene entry to injectability are maintained only in this section; all other documents point here (preventing multiple statement drift — called out in 0.35 evaluation). EN: The single source of truth for all review semantics; other docs only point here.
| Scenario | Default Behavior | Override Method |
|---|---|---|
Local interactive deposit (draft --commit / distill, with TTY) | Auto-approved | config --auto-approve off to switch to manual; only affects local deposits |
| Local non-interactive deposit (script/cron/pipe, no TTY) | Default quarantined | Explicit --auto-approve to pass |
approve <gene_id> | Auto-runs evidence first — local four ledgers (tool errors/recall/injection/backfill) three-level output (strong evidence/weak context/no evidence); approve only if consistent | --skip-evidence is an explicit emergency exit for known no-evidence scenarios (not encouraged); keep quarantined and logged if conclusions overturned by later events |
Pool import gene import / gene pull | official tier direct pass (signature verification); community default quarantined | Determined by --tier |
- Why approve is tied to evidence: In 0.20.3, the
evidencecommand was created but relied on "remembering to run it" — all 6 reviews that day bypassed evidence collection. The mechanism must be bound to the action node (T3 philosophy: the error itself is the reminder). - The status ledger
review.jsonlis LWW append-only; approve/quarantine are bidirectional reversible; "pending" ininfomeans the last state is neither approved nor quarantined. - Relationship with the two quality gates: depositionGate rejects before entry (previous section), the four guards filter on the recall side (next section) — rejection by either layer means no injection.
- Genes without local evidence (shared pool/other machines/starter pack source) are audited based on content and source, with a note at approval.
EN: Review-with-evidence (0.20.3): before
approve, runevidence <gene_id>to check the four local ledgers for events matching the gene's claimed failure/fix. Approve only when consistent; genes whose conclusions were overturned by later events stay quarantined with an audit note. Genes without local evidence (pool imports / other machines / starter pack) are reviewed on content and source, noted at approval.
Gene Signature and Provenance (0.21)
EN: Every deposit is signed with this machine's Ed25519 identity (private key 0600, never leaves the machine); pool imports verify signatures - tampered content is REJECTED. Version-by-version details (v2 canonicalization, source attribution, source_kv, decay):
docs/advanced.md§Provenance.
- Deposit auto-signs, embedded when entering the pool, signature verified on import: content tampered → import rejected; unsigned older genes are accepted as-is (legacy);
- Private key never leaves the machine; public key accompanies genes in/out of the pool for verification by other machines — the trust model is "trace by keyid", not a centralized CA;
- Provenance fields are automatically recorded with deposit/backfill (
source_model/source_host/source_kvcompression scheme family); gene validity decays based on feedback (90-day time half-life + negative pressure, floor 0.25, no feedback = no decay) — version-by-version details (v2 canonicalization / precise attribution / phase logging / decay parameters) indocs/advanced.md§Provenance.
Deployment and Distribution (0.23)
EN: Download paths, host integration, pool collaboration, concurrency semantics and scoring; version-by-version detail in
docs/advanced.md§Deployment.
- Download: GitHub Release zip / npm (domestic mirrors in FAQ Q7, sha256 included for verification);
- Host integration:
light-cli.mjs install <claude-code|cursor|codex|agents-md>(--yesto write to disk); for OpenClaw/Hermes, useinstall-hooks; trigger rules can be written into any instruction file viainstall-snippet; - Gene pool collaboration:
gene pull --pool <URL|name> --tier official [--scene <scene>](signature verification);gene submit --bundle <file>to return to maintainer; named pools in~/.evomap/pools.json; contribution terms in CONTRIBUTING.md (CC-BY-4.0); - Concurrency semantics (three layers, full behavior table in
docs/boundary-and-triggers.md§5): single-machine multi-session = withLock file lock; cross-machine = gene pool with Git (LWW ledger arbitration); multi-host addressed by gene_id (since 0.18); - Recall scoring and thresholds (public values): signal hit +3 each + query body token overlap +1 each + load balancing bias ±2; below threshold of 2 points, not injected (non-targeted injection is worse than no injection, measured +36pp); tokenization = ASCII tokens (≥3 characters) + Chinese 2-character bigrams — multi-character Chinese phrases in signals are invalid (
fix-signalscan check); - Session fencing (0.27):
session open "<task>"completes T1 recall + accounting in one step;session close "<conclusion>"finalizes — unpaired open/close will be rejected by the build gate (audit bound); - Effect quantification and backfill:
reportweekly report (L1 activity/L2 backfill rate/L3 recurrence,--jsonmachine-readable);recall --record "<conclusion>"backfill verification conclusion;license verify <token>verify Ed25519 signature license; - IO resilience and error codes (0.34): Transient errors auto-retry (3 times, 3s interval) → circuit breaker after 5 consecutive failures for 10s (closes when IO recovers); all failures include named error codes
[E_USAGE]/[E_ARGS]/[E_GUARD]/[E_NOTFOUND]/[E_INTERNAL](preserving exit codes 0/1/2) — parameters and full table indocs/advanced.md; - Theoretical origin: The problem awareness of heterogeneous verification comes from arXiv:2512.05117 (see README acknowledgments and
docs/research.mdfor details); version-by-version details (provenance/alias trigger words/license/decay parameters) indocs/advanced.md§Deployment.
Security: Four Gates (0.16.0)
EN: Four gates: repair-signal guard, narration guard, injection guard (malice; AVOID=warning allowed vs FIX=instruction blocked), redaction gate (privacy, fail-closed off-machine). Per-gate details:
docs/security-and-license.md§Gates.
| # | Gate | What it Checks | Where it Applies |
|---|---|---|---|
| 1 | Fix Guard | Is there a real fix? (no executable content → no injection; quality over quantity) | Recall |
| 2 | Narration Guard | Is it a narration stream? (narration is zero information to agents, measured +36pp noise) | Recall |
| 3 | Injection Guard | Is it a malicious instruction? (prompt injection → no injection; main defense against "gene reverse control of host") | Recall (CLI / Pi extension bridge simplified version / orchestrator) + Import + Export |
| 4 | Redaction Gate | Does it leak private content? (IP/path/keys → block outbound) | Export + Import |
- Degradation semantics: Export/Import fail-closed (guard module missing = execution rejected); recall side only skips the injection gate, the other three gates operate normally (host bootstrap path should not be blocked by guard failures for the user — read-only is not blocked, writes must be closed).
- What each gate specifically scans, behavior upon hit, two missed detections fixed in 0.31 and regression test cases: all in
docs/security-and-license.md§Gates — this document does not repeat injection trigger characteristics to avoid being used as a sample by scanners (this repo has a precedent of releasing a version for this reason).
Capability Boundaries Quick Reference (When Not to Expect It)
6 categories of non-applicable scenarios (multiple machines writing to a single library / 100% pitfall avoidance guarantee / real-time synchronized library / one-time tasks / as an authoritative knowledge base / direct reuse across architectures) and quantitative boundaries (default injection 5 entries, library size limit not measured, no cross-machine distributed lock, Node ≥22) all in
docs/boundary-and-triggers.md§1–§2. EN: Capability limits ("when NOT to use") and quantitative bounds:docs/boundary-and-triggers.md§1–§2.
When to Remind: Five Trigger Points (Core Design of 0.16.0)
EN: Recall bound to concrete action nodes, never left to memory: T1 task start, T2 before first side-effecting action, T3 on error (the error text IS the query), T4 after fixing, T5 task end (register-hit/negate). Full spec:
docs/boundary-and-triggers.md. "Skill installed but no one calls it" is the most fundamental failure mode of this project — even the author forgets (measured: relevant genes can rank #1 in recall, yet the same pitfall is repeated because recall was not run before acting). Therefore, we cannot rely on users to remember; recall must be bound to concrete action nodes.
| # | Trigger Point | Timing | Command | What Happens If Missed |
|---|---|---|---|---|
| T1 | Task Start | When receiving a non-trivial task, before planning | recall --query "<task>" | Preventive failure: the avoidable pitfall is hit again |
| T2 | Before Action | Just before the first irreversible action (writing a file/committing code/deploying/calling an external API/deleting or modifying data); for similar actions within the same task, trigger only once, subsequent actions use the same conclusion | Same as above (query = the specific action about to be performed, e.g., "batch modify files with a script") | Close-proximity prevention (optional) |
| T3 | Encountering an Error | Tool returns an error, before preparing a retry | recall --error "<original error text>" | Most regrettable: the fix is already in the store, yet the agent blindly retries |
| T4 | After Fixing a Pitfall | When a non-obvious pitfall has been fixed | draft --error ... (deposit) | Experience is lost; the next machine will hit the same pitfall |
| T5 | Task End | Finalization | --register-hit --gene <id> / --negate --gene <id> | Cannot measure; invalid fixes are never discovered |
T3 highlighted separately (highest benefit, yet most easily overlooked): The only trigger point where "you don't need to remember" — the error itself is the reminder. When a tool returns an error, before preparing a retry, use the original error text directly as the query (don't summarize it yourself): node code/evolver-recall.mjs --error "<original error text>"; if a fix is hit, retry according to it; if still failing → proceed to T4 for deposit.
Complete trigger specifications all in
docs/boundary-and-triggers.md— including T2 determination criteria with 3 examples, multi-host concurrency matrix, trigger word ↔ command mapping, three host integration methods, domestic mirrors, and "installed but not working" self-check. This document only retains the core table above; the two locations no longer drift independently. Trigger words are invocation hints, not recall matching mechanisms (matches rely onsignals_match × query-tokentargeting); when a task starts, as long as it's judged as "non-trivial", T1 is executed; no specific word trigger is needed.
Common Misuses (Anti-Pattern Quick Reference)
EN: Anti-pattern quick list - each row explains the MECHANISM, not just the symptom. Full 14-item catalog with [A] evidence:
docs/common-mistakes.md. Key ones: success-summary strategies are noise (+36pp worse than nothing), model-may-fail traps have unreliable hit rates, token deltas need a no-injection control group (~-22% repeat-execution baseline), error counting must use authoritative flags (isError=true), cold start needs flow-B deposits first. Each entry includes "Why it's wrong" — explains mechanism rather than phenomenon. Complete list (with more entries) indocs/common-mistakes.md.
| Wrong Practice | Why It's Wrong (Mechanism) | Correct Method |
|---|---|---|
strategy contains only a success summary ("Fixed it by checking encoding") | Success summaries are noise; they are filtered by the fix guard at deposit time but waste a deposit slot; if bypassed, they will be filtered by the narration guard at recall time, adding irrelevant latency; +36pp worse than nothing | Write AVOID (what NOT to do) + FIX (specific parameters/commands/encoding) |
Using a "model may fail" trap (auto-refine-model can fail) as T2 query | hit rate depends on the model's exact phrasing — unreliable; low signal-to-noise ratio | T3 (error trigger) is the correct scenario; model-probable-fail traps should use concrete task context as query |
| Using token cost delta (e.g., -30% tokens) to measure inheritance effect without a no-injection control group (measuring what would have cost) | token delta is noisy; any no-injection baseline is needed; without it, ~-22% is the repeat execution baseline, not the effect | Use the full controlled experiment (Flow C): R1 (no injection) → R2 (with injection), compare over multiple tasks |
Using tool return value stderr !== "" to count errors | tools often print warnings to stderr; only isError=true is an authoritative flag | Count errors using [E_*] codes in the actual output or the tool's isError attribute |
| Cold start: run Flow A recall first, expecting hits | An empty store has no genes to recall (FAQ·Q1) — but the user is led to think recall is useless | Run at least one Flow B deposit first to light up the experience store; then recall |
Calling session close without matching session open | Unpaired session records bypass the audit gate binding, generating false reports | Always write session open (T1) and close (T5) in matching pairs; run session audit to verify |
| Submitting all failure fixes to the shared pool | Deposits without environment signal filter contaminate the shared pool with low-quality genes | Only submit with --shareable for generic fixes that are cross-platform cross-architecture |
Using --register-hit for any gene used in the script | Hit registration is only for genes actually responded to during user-visible actions; it measures real value | Only register hits for genes that triggered an actionable response during debugging; write a log for the rest |
Navigation Map (All Documents)
Each path points to the logical entry; Click to open. Version-by-version updates:
CHANGELOG.md.
| Path | Signature | Audience | Reading Priority |
|---|---|---|---|
examples/quickstart.md | 5-minute closed-loop example | Beginners | ★★★ (start here) |
docs/overview.md | Mind map + field glossary | All users | ★★★ |
docs/one-pager.md | One minute decision guide | Skeptical / managers | ★★☆ (optional) |
docs/common-mistakes.md | 14 fallacies + mechanism explanations | Daily users | ★★☆ (browse to avoid pitfalls) |
docs/boundary-and-triggers.md | Trigger conditions + boundary tables + integration | Power users | ★★☆ (read when needed) |
docs/advanced.md | Backfill/Concurrency/Provenance/Operations | Maintainers | ★☆☆ (as needed) |
docs/security-and-license.md | Gate details + compliance | Security auditors | ★☆☆ (recommended) |
docs/config-errors.md | Common configuration mistakes | All users | ★☆☆ (troubleshoot) |
docs/research.md | Theory and experiments | Researchers | ★☆☆ (low priority) |
docs/faq.md | 14 Frequently Asked Questions | All users | ★☆☆ (as needed) |
CONTRIBUTING.md | Pool contributions | Contributors | When submitting genes |
All documents above are in this repository; some paths are under development. If a document path lacks content, please raise an Issue. This Skill comes from the pi-evox-lab project, integrating
evolverandpiframeworks.