liteagents 2.12.1 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -17,6 +17,66 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
17
 
18
18
  ---
19
19
 
20
+ ## [2.15.0] - 2026-07-13
21
+
22
+ ### Changed
23
+ - `/stash` delegates the write-up to a mid-tier-model subagent, dispatched in the background
24
+ where the tool supports it, instead of writing inline on the top-tier session model —
25
+ drafting stays inline (only the running session has conversation context), but formatting
26
+ and file I/O move off the main turn. Falls back to inline writing if subagent/background
27
+ dispatch isn't available.
28
+
29
+ ---
30
+
31
+ ## [2.14.1] - 2026-07-10
32
+
33
+ ### Changed
34
+ - **`/remember` extraction is parallel and model-agnostic.** Step 2's per-stash extraction
35
+ calls are now spawned as concurrent subagent calls instead of one at a time. Every
36
+ hardcoded `sonnet` mention (steps 2, 3, 4a) is replaced with "the mid-tier model" — a new
37
+ Guardrails note explains the intent (capable of semantic judgment, cheaper/faster than
38
+ your top reasoning tier; Sonnet is the Claude example, not a requirement) so the
39
+ instructions work unmodified across Claude/opencode/ampcode/droid regardless of which
40
+ models each tool has configured. Identical across all four packages.
41
+
42
+ ---
43
+
44
+ ## [2.14.0] - 2026-07-10
45
+
46
+ ### Added
47
+ - **`/remember` bootstraps a standards-guide template.** A new `AGENT_RULES.md` (an AI
48
+ agent collaboration/coding-standards guide) ships bundled next to `friction.js` in all
49
+ four packages. On first `/remember` run in a project, if `<tool-dir>/remember/AGENT_RULES.md`
50
+ doesn't already exist, it's copied from the bundled template — never overwritten again
51
+ after that, so local edits persist. When present, it's injected into CLAUDE.md/AGENTS.md/
52
+ AGENT.md via its own independent marker pair (`<!-- AGENT_RULES:START/END -->`), separate
53
+ from the MEMORY.md block and framed as a guide to consult when building something new —
54
+ not hot context loaded every session. This repo dogfoods it: its own copy moved from
55
+ `.claude/memory/AGENT_RULES.md` to `.claude/remember/AGENT_RULES.md`. Design + pipeline
56
+ walkthrough: `docs/remember-README.md`.
57
+
58
+ ### Docs
59
+ - **Antigen-gate PRD (§10):** deferred entry for a local classifier model as a paraphrase-blocking *proposer* between friction's shingle clustering and `/remember`'s LLM merge (LLM always disposes each shortlisted merge). Un-defer condition: offline measurement on the existing candidate corpus shows shingle-missed paraphrase merges would move at least one class across a recurrence tier.
60
+
61
+ ---
62
+
63
+ ## [2.13.0] - 2026-07-08
64
+
65
+ ### Added
66
+ - **Antigen ledger (`/remember` step 4c).** Every behavioral rule now carries an evidence trail in `<tool-dir>/remember/ledger.json`: which mistake-class it targets (`class_hints` dedup key), the evidence that promoted it, and every phrasing ever tried (`attempts` — failed attempts are the rejected-edit buffer, never re-proposed). A class that fires again *while its rule is loaded* increments `recurred_while_hot`: at 2 the phrasing is marked failed and rephrased; after 2 failed phrasings the antigen is **ESCALATED** — removed from hot, recorded as a Fact, flagged for a human decision. Failure detection without statistics; instructions-only (no new code), identical across all four packages. Design + the POC evidence that killed the statistical ON/OFF gate (deferred, un-defer condition named): `docs/antigen-gate-prd.md`.
67
+ - **`/remember` writes its run report** to `<tool-dir>/remember/report.md` (latest snapshot, overwritten each run).
68
+
69
+ ### Changed
70
+ - **Pipeline consolidated to two dirs, each owned by its command:** `<tool-dir>/stash/` (`/stash`) and `<tool-dir>/remember/` (MEMORY.md, ledger.json, report.md, `.processed`, transient `friction/` output). Was three (`stash/`, `friction/`, `memory/`). `/remember` performs a one-time loud migration: pipeline files move, user-owned files in the old `memory/` stay put, stale friction output is discarded (always regenerated fresh). Validated live on this repo's own memory.
71
+ - **Claude's bundled dir joins the naming convention:** `packages/claude/commands/friction/` → `commands/remember/` — a command's helper dir is named after the owning command in **all four** packages now (2.12.1 did the other three).
72
+ - **docs: `friction-README.md` → `remember-README.md`** — updated for the new layout + ledger, linked from README as the pipeline explainer.
73
+
74
+ ### Fixed
75
+ - **Hot memory was silently not loading in Claude Code.** The managed CLAUDE.md section injected a bare `@MEMORY.md`, which resolves relative to the containing file — i.e. a nonexistent root-level file. Now an explicit `@<tool-dir>/remember/MEMORY.md` path in all four packages' injection instructions.
76
+ - **`/remember` step 4b tier ambiguity:** LLM-merged antigen groups now explicitly obey the recurrence tiers (merging consolidates evidence, never elevates it) — surfaced by dogfooding the ledger's first live run.
77
+
78
+ ---
79
+
20
80
  ## [2.12.1] - 2026-07-07
21
81
 
22
82
  ### Fixed
package/README.md CHANGED
@@ -80,8 +80,10 @@ Liteagents ships a two-command pipeline that turns Claude Code's session logs in
80
80
  capture analyze + consolidate
81
81
  ```
82
82
 
83
- - **`/stash`** — snapshot the current session's context before compaction or handoff; nudges you to consolidate once a few stashes pile up
84
- - **`/remember`** — runs friction analysis automatically (mining JSONL session logs across *all* your projects for frustration signals, failed flows, and abandonment patterns, clustered into antigen candidates), then consolidates stashes + friction antigens into `.claude/memory/MEMORY.md`; auto-injected into `CLAUDE.md` via `@MEMORY.md` so every future session benefits
83
+ - **`/stash`** — snapshot the current session's context before compaction or handoff; nudges you to consolidate once a few stashes pile up. The write-up runs on a mid-tier model, dispatched as a background subagent where your tool supports it, so the session isn't blocked on formatting/file I/O
84
+ - **`/remember`** — runs friction analysis automatically (mining JSONL session logs across *all* your projects for frustration signals, failed flows, and abandonment patterns, clustered into antigen candidates), then consolidates stashes + friction antigens into `.claude/remember/MEMORY.md`; auto-injected into `CLAUDE.md` via `@MEMORY.md` so every future session benefits. Per-stash extraction runs as concurrent subagent calls on a mid-tier model — no model name hardcoded, so it works with whatever your tool has configured
85
+
86
+ `/remember` also bootstraps a one-time `AGENT_RULES.md` coding-standards template into `.claude/remember/` on first run (never overwritten again after that), referenced separately in `CLAUDE.md` for the assistant to consult when building something new — a static guide, not something the pipeline learns or extracts.
85
87
 
86
88
  What you get is a memory that *learns from your own mistakes and interventions*, grows quietly in your repo, and works anywhere Claude Code runs. The friction pass inside `/remember` scans all your projects and gives you a per-repo reliability verdict:
87
89
 
@@ -97,7 +99,7 @@ BEST: web-client/0202-2121-8d8608e1 peak=0 turns=4
97
99
  Verdict: USEFUL Intervention predictability: 93%
98
100
  ```
99
101
 
100
- Results land in `.claude/friction/antigen_review.md` with projects, error patterns, and offending tool sequences called out per cluster — which `/remember` then encodes as rules the next session sees.
102
+ Results land in `.claude/remember/friction/antigen_review.md` with projects, error patterns, and offending tool sequences called out per cluster — which `/remember` then encodes as rules the next session sees.
101
103
 
102
104
  > This is the thing in liteagents that nothing else ships. Normal skill bundles give you instructions. The hot-memory pipeline gives you instructions the assistant wrote for itself, from your own logs.
103
105
 
@@ -133,7 +135,7 @@ Results land in `.claude/friction/antigen_review.md` with projects, error patter
133
135
 
134
136
  *Hot Memory Pipeline (2)* — see the [Hot Memory](#hot-memory--project-local-learning-from-your-own-sessions) section above for the full walkthrough:
135
137
  - **stash** - Snapshot session context to `.claude/stash/` before compaction, handoff, or ending complex work
136
- - **remember** - Consolidate stashes + friction antigens into `.claude/memory/MEMORY.md`; auto-injected via `@MEMORY.md`
138
+ - **remember** - Consolidate stashes + friction antigens into `.claude/remember/MEMORY.md`; auto-injected via `@MEMORY.md`
137
139
 
138
140
  *Design*:
139
141
  - **live-canvas** - Design UI variations with click-to-annotate feedback in the browser; ships a companion MCP channel plugin for Claude Code so Saves stream into the session in real time. Other tools use batch mode.
@@ -162,6 +164,7 @@ Results land in `.claude/friction/antigen_review.md` with projects, error patter
162
164
  |----------|-------------|
163
165
  | **[INSTALLER_GUIDE.md](docs/INSTALLER_GUIDE.md)** | Complete installation guide, troubleshooting, and FAQ |
164
166
  | **[subagentic-manual.md](packages/subagentic-manual.md)** | Detailed agent/command reference |
167
+ | **[remember-README.md](docs/remember-README.md)** | How hot memory works — the `/stash` → `/remember` pipeline, the friction sensor, and the antigen ledger |
165
168
 
166
169
  ---
167
170
 
@@ -612,7 +612,7 @@ class PackageManager {
612
612
 
613
613
  if (!fs.existsSync(itemPath)) {
614
614
  // A command may ship as a bundled helper subdirectory (no .md doc),
615
- // e.g. friction/friction.js run by /remember. The installer bundles
615
+ // e.g. remember/friction.js run by /remember. The installer bundles
616
616
  // such subdirs; accept them here so validation matches install.
617
617
  if (allowBundleDir) {
618
618
  const bundleDir = path.join(categoryDir, item);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "liteagents",
3
- "version": "2.12.1",
3
+ "version": "2.15.0",
4
4
  "description": "AI development toolkit with 11 specialized agents and 17 commands including live-canvas UI design with click-to-annotate feedback. Simple one-question installer for Claude, Opencode, Ampcode, and Droid.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -93,7 +93,7 @@ digraph ContextBuilder {
93
93
 
94
94
  **Rule:** Plain text paths only (no @ triggers) in Tier 1 and 2
95
95
 
96
- **Permanent reference:** `@MEMORY.md` from `.amp/memory/MEMORY.md` — this is the only file allowed to use @ for direct loading. It contains project memory (facts, episodes, preferences) auto-generated by `/remember`. Always check for it during discovery. If it exists, include it as a source and ensure AGENT.md references it.
96
+ **Permanent reference:** the explicit-path `@` reference to `.amp/remember/MEMORY.md` — this is the only file allowed to use @ for direct loading. It contains project memory (facts, episodes, preferences) auto-generated by `/remember`. Always check for it during discovery. If it exists, include it as a source and ensure AGENT.md references it.
97
97
 
98
98
  # Anti-Patterns
99
99
 
@@ -0,0 +1,329 @@
1
+ # AI Agent Collaboration Guide
2
+
3
+ ## Table of Contents
4
+ 1. [Operating Flow](#operating-flow)
5
+ 2. [Communication Protocol](#communication-protocol)
6
+ 3. [Development Standards](#development-standards)
7
+ 4. [Testing Standards](#testing-standards)
8
+ 5. [Security & Robustness Invariants](#security--robustness-invariants)
9
+ 6. [Guardrails (Enforced, Not Requested)](#guardrails-enforced-not-requested)
10
+ 7. [Environment](#environment)
11
+ 8. [Development Workflow](#development-workflow)
12
+ 9. [Twelve-Factor Checklist](#twelve-factor-checklist)
13
+ 10. [CLAUDE.md Stub](#claudemd-stub)
14
+ 11. [AI Agent Instructions](#ai-agent-instructions)
15
+
16
+ ---
17
+
18
+ ## Operating Flow
19
+
20
+ Every task runs through three layers. Do not skip ahead to code.
21
+
22
+ 1. **Spec — agree on intent before touching anything.** Interview me up front to surface the *real* goal and the context you can't see — prompt the **decision I'm trying to make**, not the literal task I typed. Break the scope into small buckets with checkpoints. **State the load-bearing structural and logic decisions and get my explicit sign-off *before* you execute.** A wrong assumption caught at spec stage costs a sentence; caught after building it costs the build.
23
+ 2. **Verify — define "good" up front, then prove it.** Write down what success looks like *before* changing code. Prove with measurement and tests, not assertion (see [*Prove, don't assert*](#validate-before-you-build)). Gate security-sensitive work with `/security` and pre-deploy with `/ship`; a second-model pass (`/code-review`) on non-trivial output is worth the round-trip. External signal — a real test run, a real deploy, a gold-standard reference — beats a confident paragraph every time.
24
+ 3. **Environment — the guardrails are enforced, not requested.** This file is the standing context that primes every session. Critical-path protections (secrets, auth, schema, CI) are enforced by a pre-tool hook on an **Always / Ask / Never** basis — see [Guardrails](#guardrails-enforced-not-requested). Where the hook isn't wired, the same rules still bind you.
25
+
26
+ > The model is brilliant at execution and blind to intent. You can outsource the typing; you cannot outsource the understanding. Surface assumptions — don't bury them.
27
+
28
+ ---
29
+
30
+ ## Communication Protocol
31
+
32
+ ### Core Rules
33
+ - **Spec before build**: Don't wait for ambiguity to block you — interview me up front to extract the real goal and the context you can't see. Prompt the *decision*, not the literal task. Restate what you heard before building
34
+ - **Checkpoint before executing**: State the load-bearing structural and logic decisions and get my explicit sign-off *before* you write code. Never run ahead on an unverified assumption — flag it and stop
35
+ - **Fact-Based**: Base all recommendations on verified, current information. Prefer external signal (a real run, a real source) over a confident guess
36
+ - **Simplicity Advocate**: Call out overcomplications and suggest simpler alternatives
37
+ - **Safety First**: Never modify critical systems without explicit understanding and approval. Where the [guardrail hook](#guardrails-enforced-not-requested) is wired, this is enforced before the tool runs, not after
38
+
39
+ ### User Profile
40
+ - **Technical Level**: Non-coder but technically savvy
41
+ - **Learning Style**: Understands concepts, needs executable instructions
42
+ - **Expects**: Step-by-step guidance with clear explanations
43
+ - **Comfortable with**: Command-line operations and scripts
44
+ - **Builds a lot of web apps** — assume any UI work will be consumed on phones as well as desktop
45
+
46
+ ### Required Safeguards (Always / Ask / Never)
47
+
48
+ Not courtesies — where the [guardrail hook](#guardrails-enforced-not-requested) is wired these are enforced *before* the tool runs. When it isn't, they still bind you.
49
+
50
+ - **Always** identify affected files before making changes, and explain what will change and why
51
+ - **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.claude/settings.json`
52
+ - **Never** write secrets into the tree (`.env`/`*.env`, keys, credentials). They load from the environment at runtime; only a value-less `.env.example` is committed
53
+
54
+ ---
55
+
56
+ ## Development Standards
57
+
58
+ ### Validate Before You Build
59
+
60
+ - **POC everything first.** Before committing to a design, build a quick proof-of-concept (~15 min) that validates the core logic. Keep it stupidly simple — manual steps are fine, hardcoded values are fine, no tests needed yet
61
+ - **POC scope:** Cover the happy path, 2-3 common edge cases, **and the riskiest assumption (see below) — not just the parts that are easy to check**. If those hold, the idea is sound
62
+ - **Graduation criteria:** POC validates logic and covers most common scenarios → stop, design properly, then build with structure, tests, and error handling. Never ship the POC — rewrite it
63
+ - **Aim the POC at the load-bearing claim — not the easy part.** Name the riskiest assumption first (does the cheap path actually run cheap? does the library really do X? does the perf hold?), then point the spike straight at *that*. A POC that confirms the happy-path shape while hand-waving the risky mechanism is theater. If you catch yourself writing "production would do X" instead of *doing* X in the spike, the POC has not validated X — go do X
64
+ - **Prove, don't assert — a POC's output is evidence you ran, not prose you wrote.** Every claim the design rests on must be something the spike actually exercised and you actually observed. **Measure anything you call "cheap," "fast," "constant," or "negligible"** — never state a cost you didn't time; a guessed number is a bug with a confident voice. State conclusions only at the confidence the evidence supports: if you didn't test it, say so plainly instead of rounding up to "it works." Better a small honest finding than a big-mouthed claim that measurement later falsifies
65
+ - **The test must be able to FAIL — pre-flight check, not an afterthought.** Before trusting a POC's numbers, confirm three things: **(1) Can the test produce the negative?** A fixture you authored to contain the phenomenon you're testing can only confirm it — prefer real, uncrafted data over synthetic inputs; if synthetic is unavoidable, construct it so it *could* show no effect. **(2) Is the harness free of confounds?** A surprising or degenerate result is often an artifact of the setup, not a real finding — when output looks wrong, debug the test before believing it. **(3) Did the test actually exercise the variable?** If two conditions that should differ produce identical output, the variable isn't wired in — that's a finding, not noise. Run this checklist every time, especially when a result confirms what you hoped
66
+ - **Build incrementally.** After POC graduates, break the work into small, independent modules. Focus on one at a time. Each piece must work on its own before integrating with the next
67
+
68
+ ### Dependency Hierarchy
69
+
70
+ Always exhaust the simpler option before reaching for the next:
71
+
72
+ 1. **Vanilla language** — Write it yourself using only language primitives. If it's <50 lines and not security-critical, this is the answer
73
+ 2. **Standard library** — Use built-in modules (`os`, `json`, `pathlib`, `http`, `fs`, `crypto`). The stdlib is tested, maintained, and has zero supply chain risk
74
+ 3. **External library** — Only when both vanilla and stdlib are insufficient. Must pass the checklist below
75
+
76
+ ### External Dependency Checklist
77
+
78
+ Before adding any external dependency, all of these must be true:
79
+ - **Necessity:** Can't reasonably implement this with stdlib in <100 lines
80
+ - **Maintained:** Active commits in the last 6 months, responsive maintainer
81
+ - **Lightweight:** Few transitive dependencies (check the dep tree, not just the top-level)
82
+ - **Established:** Widely used, not a single-maintainer hobby project for production-critical code
83
+ - **Security-aware:** For security-critical domains (crypto, auth, sanitization, parsing untrusted input), a vetted library is *required* — never roll your own
84
+
85
+ ### Language Selection
86
+
87
+ - **Use widely-adopted languages only** — Python, JavaScript/TypeScript, Go, Rust. No niche languages unless the domain demands it
88
+ - **Pick the lightest language that fits the domain:** shell scripts for automation, Python for data/backend/CLI, TypeScript for web, Go for systems/infra, Rust for performance-critical
89
+ - **Minimize the polyglot tax.** Every language in the stack adds CI config, tooling, and onboarding friction. Do not add a new language for one microservice — use what's already in the stack unless there's a compelling reason
90
+ - **Vanilla over frameworks.** Express over NestJS, Flask over Django, unless the project genuinely needs the framework's structure. Structure can always be added later; removing a framework is painful
91
+
92
+ ### Build Rules
93
+
94
+ - **Open-source only.** Always use open-source solutions. No vendor lock-in
95
+ - **Lightweight over complex.** If two solutions solve the same problem, use the one with fewer moving parts, fewer dependencies, and less configuration
96
+ - **Every line must have a purpose.** No speculative code, no "might need this later", no abstractions for one use case
97
+ - **Simple > clever.** Readable code that a junior can follow beats elegant code that requires a PhD to debug
98
+ - **Containerize only when necessary.** Start with a virtualenv or bare metal. Docker adds value for deployment parity and isolation — not for running a script
99
+ - **Responsive web UI is mandatory in dev projects.** Any web UI must be usable on mobile by default — fluid layouts, viewport meta tag, breakpoints for narrow screens, no horizontal scroll. Test in DevTools device emulation before declaring a UI task done. POCs are exempt (validate the idea first), but the moment a POC graduates to a real project this becomes a hard requirement
100
+ - **Surgical changes only.** Touch what the task requires; nothing else. Don't "improve" adjacent code, comments, or formatting. Match existing style even if you'd do it differently. Only clean up orphans your own change created — leave pre-existing dead code alone unless asked. Every changed line should trace directly to the request
101
+
102
+ ### Red Flags — Stop and Flag These
103
+ - Over-engineering simple problems
104
+ - Adding external dependencies for trivial operations
105
+ - Frameworks where a library or stdlib would suffice
106
+ - Vendor-specific implementations when open alternatives exist
107
+ - Skipping POC validation for unproven ideas
108
+ - POC-ing only the easy part while hand-waving the risky mechanism, or claiming a cost ("cheap"/"fast"/"constant") you never measured
109
+ - Authoring a fixture/corpus that *guarantees* the result (a test that can't return the negative), or trusting a degenerate-looking number without auditing the harness for confounds — use real uncrafted data; the test must be able to fail
110
+
111
+ ---
112
+
113
+ ## Testing Standards
114
+
115
+ ### Rules
116
+
117
+ **Test behavior, not implementation.** A test suite must give you confidence to refactor freely. If changing internal code (without changing behavior) breaks tests, those tests are liabilities, not assets.
118
+
119
+ **Follow the Testing Trophy** (not the Testing Pyramid):
120
+ - Few unit tests — only for pure logic, algorithms, and complex calculations
121
+ - Many integration tests — the sweet spot; test real components working together
122
+ - Some E2E tests — cover critical user journeys end-to-end
123
+ - Static analysis — types and linters catch bugs cheaper than tests
124
+
125
+ ### When to Write Tests
126
+
127
+ - **After the design stabilizes, not during exploration.** Do not TDD a prototype — you'll write 500 tests for code you delete tomorrow. First make it work (POC), then make it right (refactor + tests), then make it fast
128
+ - **Write tests when the code has users.** If a function is called by other modules or exposed to users, it needs tests. Internal helpers that only serve one caller don't need their own test file
129
+ - **Write tests for bugs.** Every bug fix must include a regression test that fails before the fix and passes after. This is the highest-value test you can write
130
+ - **Write tests before refactoring.** Before changing working code, write characterization tests first to lock in current behavior, then refactor with confidence
131
+ - **Do not write tests for glue code.** Code that just wires components together (calls A then B then C) is tested at the integration level, not unit level
132
+
133
+ ### TDD: When It Works and When It Doesn't
134
+
135
+ - **TDD works for:** Pure functions, algorithms, parsers, validators, data transformations — anything with clear inputs and outputs
136
+ - **TDD does not work for:** Exploring a design, building a POC, or unstable interfaces. Writing tests for unstable APIs creates churn and false confidence
137
+ - **The rule:** You must understand what you're building before you TDD it. TDD is a design tool for known problems, not a discovery tool for unknown ones
138
+ - **Red-green-refactor discipline:** If you do TDD, follow the cycle strictly. Write a failing test, write minimal code to pass, refactor. Do not write 20 tests then implement — that's front-loading waste
139
+
140
+ ### What Makes a Good Test
141
+
142
+ - **Tests real behavior.** Call the public API, assert on observable output. Do not reach into internals
143
+ - **Fails for the right reason.** A good test fails when the feature is broken, not when the implementation changes
144
+ - **Reads like a spec.** Someone unfamiliar with the code must understand what the feature does by reading the test
145
+ - **Self-contained.** Each test sets up its own state, runs, and cleans up. No ordering dependencies between tests
146
+ - **Fast and deterministic.** Flaky tests erode trust. If a test depends on timing, network, or global state, fix that dependency
147
+
148
+ ### Anti-Patterns — Do Not Do These
149
+
150
+ - **Mocking more than 60% of the test.** If most of the test is mock setup, you're testing mocks, not code. Use real implementations with `tmp_path`, `:memory:` SQLite, or test containers
151
+ - **Smoke tests.** `assert result is not None` proves nothing. Assert on specific values, structure, or side effects
152
+ - **Testing private methods.** If you need to test a private method, either it should be public or the public method's tests should cover it
153
+ - **Mirroring implementation.** Tests that replicate the source code line-by-line break on every refactor and catch zero bugs
154
+ - **Test-only production code.** Never add methods, flags, or branches to production code solely for testing. Use dependency injection instead
155
+
156
+ ### Test Organization
157
+
158
+ - **Co-locate tests with packages:** `packages/<pkg>/tests/` not a root `tests/` directory. Each package owns its tests
159
+ - **Separate by type:**
160
+ ```
161
+ packages/<pkg>/tests/
162
+ unit/ # Fast, isolated, mocked deps, <1s each
163
+ integration/ # Real DB, filesystem, multi-component, <10s each
164
+ e2e/ # Full workflows, subprocess calls, <60s each
165
+ conftest.py # Shared fixtures for this package
166
+ ```
167
+ - **One test file per module** (not per function). `test_auth.py` tests the auth module, not `test_login.py` + `test_logout.py` + `test_session.py`
168
+ - **No duplicate test files.** Before creating a new test file, check if one already exists for that module
169
+
170
+ ### Markers and Signals
171
+
172
+ | Marker | Purpose | CI Behavior |
173
+ |--------|---------|-------------|
174
+ | `@pytest.mark.slow` | Runtime > 5s | Run in full suite, skip in quick checks |
175
+ | `@pytest.mark.ml` | Requires ML deps (torch, etc.) | Skip if deps not installed |
176
+ | `@pytest.mark.real_api` | Calls external APIs | Skip in CI — run manually before release |
177
+
178
+ **CI runs for fast signals:**
179
+ - `pytest -m "not slow and not ml and not real_api"` — fast gate on every push (~30s)
180
+ - `pytest` — full suite on PR merge or nightly
181
+ - Package-level runs for targeted debugging: `pytest packages/core/tests/`
182
+
183
+ ### Coverage and Ratios
184
+
185
+ - **Do not chase a coverage number.** 80% coverage with meaningless tests is worse than 40% with behavior-testing integration tests
186
+ - **Cover the critical path first.** Data layer, auth, payment, core business logic — before helper utilities
187
+ - **Coverage tells you what's NOT tested, not what IS tested.** High coverage with bad assertions is false confidence
188
+ - **Delete tests that don't catch bugs.** If a test has never failed (or only fails on refactors), it's not providing value
189
+
190
+ **Target ratio:** ~20% unit, ~60% integration, ~15% E2E, ~5% manual/exploratory
191
+
192
+ ### Test Tooling Standards
193
+
194
+ - Use `tmp_path` for filesystem tests, `:memory:` or `tmp_path` SQLite for DB tests
195
+ - Use dependency injection over `@patch` — it's more readable and survives refactors
196
+ - Tests must be self-sufficient — no dependency on project directories, user config, or environment state
197
+ - Use factories or builders for test data, not raw constructors with 15 arguments
198
+ - Keep test fixtures close to where they're used. Shared fixtures in `conftest.py`, not a global test utilities package
199
+
200
+ ---
201
+
202
+ ## Security & Robustness Invariants
203
+
204
+ These are the failure classes that show up in nearly every quickly-built app, regardless of stack or language. Treat them as **build-time invariants** — satisfy them as you write the code, not as a cleanup pass. Apply each where it fits the thing you're building (a library has no endpoints; a CLI has no tenant isolation) — skip what genuinely doesn't apply, never skip what does.
205
+
206
+ Throwaway POCs are exempt while you validate logic (per **POC first** above) — hardcoded values and missing error handling are fine in a 15-minute spike. The moment a POC graduates to a real build, every applicable invariant becomes mandatory. The one item that holds even for a POC: never commit a real secret.
207
+
208
+ 1. **No secrets in the repo.** Keys, tokens, and credentials load from the environment / a secret store at runtime — never hardcoded, never logged. `.env` is gitignored; only a value-less `.env.example` is committed. Scan history before trusting a repo. One leaked key is a breached database or a runaway bill.
209
+ 2. **Scope every data access to its owner.** Each record read or written is constrained to the requesting principal — via DB-level rules (RLS / row policies) and/or an application-layer ownership check. Never trust a client-supplied id without a gate. If the storage layer offers row-level policies, enabling them is not optional, and "on but too broad" still fails.
210
+ 3. **Bound every reachable endpoint.** Rate-limit public routes AND authenticated mutation/write routes AND abuse-prone inbound paths (mail, webhooks). An unbounded route is a free DoS and bill amplifier — a script in a loop should not be able to take the service down.
211
+ 4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch.
212
+ 5. **Authorization is not authentication.** "Logged in" never implies "allowed". Every state-changing or privileged action checks ownership AND role/permission. If swapping an id in a request would expose or mutate someone else's data, it's a bug — return 403.
213
+ 6. **Data access scales.** No queries inside loops, no per-render repeated round-trips, indexes on every filtered/joined column. Code that's fine at 10 users and collapses at 1,000 is a latent outage.
214
+
215
+ Also hold the line on: input validation at every trust boundary (untrusted uploads, inbound mail, webhooks, and spoofable headers like `X-Forwarded-For` — trust them only behind a vetted proxy); parameterized queries (never string-built SQL); vetted libraries for crypto / auth / sanitization (never roll your own); and least-privilege binding (loopback, not `0.0.0.0`, unless the port is deliberately public).
216
+
217
+ **Verify at two moments, not one.**
218
+ - **While building** — this list shapes the code as it's written.
219
+ - **Before deploy/merge** — run **`/security`** on security-sensitive changes and **`/ship`** as the pre-deploy gate. A Critical/High finding blocks the ship; lower-severity findings get logged and triaged, not silently shipped. Proactively remind the user to run them whenever a change touches auth, data access, endpoints, secrets, or untrusted input.
220
+
221
+ ---
222
+
223
+ ## Guardrails (Enforced, Not Requested)
224
+
225
+ A prompt rule is a request the model can rationalise past. For anything that actually matters — secrets, auth, schema — don't rely on soft instruction. Enforce it with a **pre-tool hook** that intercepts the call *before* it runs and decides on an **Always / Ask / Never** basis:
226
+
227
+ - **Never** — writing `.env`/`*.env`, keys, or credential files is blocked outright (secrets load from the environment, never the tree). Destructive shell (`rm -rf` of a root-ish target, redirecting into a secret) is blocked too.
228
+ - **Ask** — touching auth, DB schema/migrations, CI workflows, or `.claude/settings.json` forces a human confirmation. Same for force-push / push to a default branch.
229
+ - **Always / allow** — everything else proceeds through the normal permission flow; the hook stays out of the way.
230
+
231
+ The reference implementation ships in this repo at [`.claude/hooks/guardrails.py`](.claude/hooks/guardrails.py) — stdlib only, no deps, fails open on a malformed event so it can never wedge the agent. The Never/Ask lists are constants at the top; **tune them per project**. To wire it up, add to the project's `.claude/settings.json`:
232
+
233
+ ```json
234
+ {
235
+ "hooks": {
236
+ "PreToolUse": [
237
+ {
238
+ "matcher": "Write|Edit|MultiEdit|NotebookEdit|Bash",
239
+ "hooks": [
240
+ { "type": "command", "command": "python3 .claude/hooks/guardrails.py" }
241
+ ]
242
+ }
243
+ ]
244
+ }
245
+ }
246
+ ```
247
+
248
+ The hook is the hard line; the prose rules above are why it exists. Keep them in sync — when you tighten one, tighten the other.
249
+
250
+ ---
251
+
252
+ ## Environment
253
+
254
+ - **OS**: Fedora Linux (use `dnf` for packages, `systemctl` for services)
255
+ - **Testing**: pytest (Python), Jest/Vitest (JS/TS), Playwright (browser automation)
256
+
257
+ ---
258
+
259
+ ## Development Workflow
260
+
261
+ ### Environments
262
+ - **Development**: Local machines
263
+ - **Staging**: VPS with isolated database
264
+ - **Production**: VPS with containerized setup
265
+
266
+ ### Deployment Strategy
267
+
268
+ **Simple Projects:** `Local → GitHub → VPS (direct deployment)`
269
+
270
+ **Complex Projects:** `Local → GitHub → GHCR → VPS (containerized)`
271
+
272
+ ---
273
+
274
+ ## Twelve-Factor Checklist
275
+
276
+ The [Twelve-Factor App](https://12factor.net) methodology for modern, scalable applications:
277
+
278
+ | # | Factor | Rule |
279
+ |---|--------|------|
280
+ | 1 | Codebase | One repo per app, multiple deploys from same codebase |
281
+ | 2 | Dependencies | Explicitly declare and isolate all dependencies |
282
+ | 3 | Config | Store config in environment variables, never in code |
283
+ | 4 | Backing Services | Treat databases, caches, queues as attached resources |
284
+ | 5 | Build, Release, Run | Strict separation between build, release, and run stages |
285
+ | 6 | Processes | Run as stateless processes, persist state externally |
286
+ | 7 | Port Binding | Apps are self-contained, export services via port binding |
287
+ | 8 | Concurrency | Scale out via the process model, not bigger instances |
288
+ | 9 | Disposability | Fast startup, graceful shutdown, idempotent operations |
289
+ | 10 | Dev/Prod Parity | Keep dev, staging, and production as similar as possible |
290
+ | 11 | Logs | Treat logs as event streams to stdout |
291
+ | 12 | Admin Processes | Run admin/maintenance tasks as one-off processes |
292
+
293
+ ---
294
+
295
+ ## CLAUDE.md Stub
296
+
297
+ Copy this to any project's CLAUDE.md. These are mandatory rules, not suggestions.
298
+
299
+ ```markdown
300
+ ## Dev Rules
301
+
302
+ **POC first.** Always validate logic with a ~15min proof-of-concept before building. Cover happy path + common edges. POC works → design properly → build with tests. Never ship the POC. **Aim the spike at the riskiest assumption, not the easy part; prove, don't assert — measure anything you call "cheap"/"fast"/"constant," and claim only what the evidence supports (no big-mouthed conclusions measurement can falsify). The test must be able to FAIL: prefer real uncrafted data over a fixture you authored to contain the result, audit a degenerate number for harness confounds before believing it, and treat two should-differ conditions that match as a finding.**
303
+
304
+ **Build incrementally.** Break work into small independent modules. One piece at a time, each must work on its own before integrating.
305
+
306
+ **Dependency hierarchy — follow strictly:** vanilla language → standard library → external (only when stdlib can't do it in <100 lines). External deps must be maintained, lightweight, and widely adopted. Exception: always use vetted libraries for security-critical code (crypto, auth, sanitization).
307
+
308
+ **Lightweight over complex.** Fewer moving parts, fewer deps, less config. Express over NestJS, Flask over Django, unless the project genuinely needs the framework. Simple > clever. Readable > elegant.
309
+
310
+ **Open-source only.** No vendor lock-in. Every line of code must have a purpose — no speculative code, no premature abstractions.
311
+
312
+ **Responsive web UI is mandatory.** Any web UI must work on mobile by default — fluid layouts, viewport meta, breakpoints, no horizontal scroll. Verify in DevTools device emulation before claiming a UI task is done. POCs exempt; real projects are not.
313
+
314
+ For full development and testing standards, see `.claude/memory/AGENT_RULES.md`.
315
+ ```
316
+
317
+ ---
318
+
319
+ ## AI Agent Instructions
320
+
321
+ When working with this user:
322
+ 1. **Interview before building** — extract the real goal and surface load-bearing decisions for sign-off before you execute (see [Operating Flow](#operating-flow))
323
+ 2. **Provide step-by-step** instructions with clear explanations
324
+ 3. **Include ready-to-run** scripts and commands
325
+ 4. **Explain the "why"** behind technical recommendations
326
+ 5. **Flag potential issues** before they become problems — name the assumption, don't bury it
327
+ 6. **Suggest simpler alternatives** when appropriate
328
+ 7. **Ask first** before touching auth, DB schema/migrations, CI, or settings; **never** commit secrets — enforced by the [guardrail hook](#guardrails-enforced-not-requested) where wired
329
+ 8. **Always identify** which files will be affected by changes
@@ -6,7 +6,7 @@
6
6
  * node friction.js <sessions-directory>
7
7
  * node friction.js ~/.claude/projects/-home-hamr-PycharmProjects-liteagents/
8
8
  *
9
- * Outputs (all in .amp/friction/):
9
+ * Outputs (all in .amp/remember/friction/):
10
10
  * friction_analysis.json - Per-session analysis
11
11
  * friction_summary.json - Aggregate stats
12
12
  * friction_raw.jsonl - Raw signals
@@ -1483,7 +1483,7 @@ function analyzeMain(sessionsDir) {
1483
1483
  }
1484
1484
 
1485
1485
  // Create output dir
1486
- const outputDir = '.amp/friction';
1486
+ const outputDir = '.amp/remember/friction';
1487
1487
  fs.mkdirSync(outputDir, { recursive: true });
1488
1488
 
1489
1489
  // Process each session
@@ -1641,12 +1641,12 @@ function analyzeMain(sessionsDir) {
1641
1641
 
1642
1642
  // Output files
1643
1643
  console.log('Outputs:');
1644
- console.log(' \uD83D\uDCCA .amp/friction/report.md (detailed analysis)');
1645
- console.log(' \uD83D\uDCCB .amp/friction/antigen_review.md (clustered failure patterns)');
1646
- console.log(` \uD83D\uDCC1 .amp/friction/*.json (raw data: ${allSignals.length} signals, ${analyses.length} sessions)`);
1644
+ console.log(' \uD83D\uDCCA .amp/remember/friction/report.md (detailed analysis)');
1645
+ console.log(' \uD83D\uDCCB .amp/remember/friction/antigen_review.md (clustered failure patterns)');
1646
+ console.log(` \uD83D\uDCC1 .amp/remember/friction/*.json (raw data: ${allSignals.length} signals, ${analyses.length} sessions)`);
1647
1647
  console.log();
1648
1648
 
1649
- console.log('Next: Review .amp/friction/report.md');
1649
+ console.log('Next: Review .amp/remember/friction/report.md');
1650
1650
  console.log('='.repeat(60));
1651
1651
 
1652
1652
  if (errors.length > 0) {
@@ -2196,9 +2196,9 @@ function clusterCandidates(allCandidates) {
2196
2196
 
2197
2197
  function extractMain(sessionsDir) {
2198
2198
  // Load friction analysis
2199
- const analysisFile = '.amp/friction/friction_analysis.json';
2199
+ const analysisFile = '.amp/remember/friction/friction_analysis.json';
2200
2200
  if (!fs.existsSync(analysisFile)) {
2201
- console.log('Error: Run friction analysis first to generate .amp/friction/friction_analysis.json');
2201
+ console.log('Error: Run friction analysis first to generate .amp/remember/friction/friction_analysis.json');
2202
2202
  return 1;
2203
2203
  }
2204
2204
 
@@ -2211,7 +2211,7 @@ function extractMain(sessionsDir) {
2211
2211
  }
2212
2212
 
2213
2213
  // Load raw signals
2214
- const rawFile = '.amp/friction/friction_raw.jsonl';
2214
+ const rawFile = '.amp/remember/friction/friction_raw.jsonl';
2215
2215
  let signals = [];
2216
2216
  if (fs.existsSync(rawFile)) {
2217
2217
  const rawContent = fs.readFileSync(rawFile, 'utf-8');
@@ -2266,7 +2266,7 @@ function extractMain(sessionsDir) {
2266
2266
  console.log();
2267
2267
 
2268
2268
  // Save outputs
2269
- const outputDir = '.amp/friction';
2269
+ const outputDir = '.amp/remember/friction';
2270
2270
  fs.mkdirSync(outputDir, { recursive: true });
2271
2271
 
2272
2272
  // Raw candidates (kept for debugging)
@@ -2340,7 +2340,7 @@ function extractMain(sessionsDir) {
2340
2340
  });
2341
2341
 
2342
2342
  fs.writeFileSync(path.join(outputDir, 'antigen_review.md'), reviewLines.join(''));
2343
- console.log('Output: .amp/friction/antigen_review.md\n');
2343
+ console.log('Output: .amp/remember/friction/antigen_review.md\n');
2344
2344
 
2345
2345
  return 0;
2346
2346
  }
@@ -2358,7 +2358,7 @@ Usage:
2358
2358
  node friction.js <sessions-directory>
2359
2359
  node friction.js ~/.claude/projects/-home-hamr-PycharmProjects-liteagents/
2360
2360
 
2361
- Outputs (all in .amp/friction/):
2361
+ Outputs (all in .amp/remember/friction/):
2362
2362
  friction_analysis.json - Per-session analysis
2363
2363
  friction_summary.json - Aggregate stats
2364
2364
  friction_raw.jsonl - Raw signals
@@ -2385,7 +2385,7 @@ Outputs (all in .amp/friction/):
2385
2385
  analyzeMain(sessionsDir);
2386
2386
 
2387
2387
  // Check if analysis produced output
2388
- const analysisFile = '.amp/friction/friction_analysis.json';
2388
+ const analysisFile = '.amp/remember/friction/friction_analysis.json';
2389
2389
  if (!fs.existsSync(analysisFile)) {
2390
2390
  console.log('\nNo analysis output. Check session directory.');
2391
2391
  return 1;
@@ -2401,7 +2401,7 @@ Outputs (all in .amp/friction/):
2401
2401
  console.log(' DONE');
2402
2402
  console.log('='.repeat(60));
2403
2403
 
2404
- const reviewFile = '.amp/friction/antigen_review.md';
2404
+ const reviewFile = '.amp/remember/friction/antigen_review.md';
2405
2405
  if (fs.existsSync(reviewFile)) {
2406
2406
  console.log('\nReview your antigens:');
2407
2407
  console.log(` cat ${reviewFile}`);