liteagents 2.15.2 → 2.17.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/README.md +8 -7
  3. package/package.json +2 -2
  4. package/packages/ampcode/AGENT.md +2 -2
  5. package/packages/ampcode/agents/quality-assurance.md +1 -1
  6. package/packages/ampcode/commands/docs-builder/docs-builder.cjs +2382 -0
  7. package/packages/ampcode/commands/docs-builder.md +787 -223
  8. package/packages/ampcode/commands/remember/AGENT_RULES.md +13 -43
  9. package/packages/ampcode/commands/remember/{friction.js → friction.cjs} +211 -99
  10. package/packages/ampcode/commands/remember.md +208 -29
  11. package/packages/claude/CLAUDE.md +3 -3
  12. package/packages/claude/commands/docs-builder/docs-builder.cjs +2382 -0
  13. package/packages/claude/commands/docs-builder.md +873 -0
  14. package/packages/claude/commands/remember/AGENT_RULES.md +10 -40
  15. package/packages/claude/commands/remember/{friction.js → friction.cjs} +208 -96
  16. package/packages/claude/commands/remember.md +208 -29
  17. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/package-lock.json +9 -9
  18. package/packages/droid/AGENTS.md +2 -2
  19. package/packages/droid/commands/docs-builder/docs-builder.cjs +2382 -0
  20. package/packages/droid/commands/docs-builder.md +787 -223
  21. package/packages/droid/commands/remember/AGENT_RULES.md +13 -43
  22. package/packages/droid/commands/remember/{friction.js → friction.cjs} +211 -99
  23. package/packages/droid/commands/remember.md +208 -29
  24. package/packages/droid/droids/quality-assurance.md +1 -1
  25. package/packages/opencode/AGENTS.md +2 -2
  26. package/packages/opencode/agent/quality-assurance.md +1 -1
  27. package/packages/opencode/command/docs-builder/docs-builder.cjs +2382 -0
  28. package/packages/opencode/command/docs-builder.md +787 -223
  29. package/packages/opencode/command/remember/AGENT_RULES.md +13 -43
  30. package/packages/opencode/command/remember/{friction.js → friction.cjs} +211 -99
  31. package/packages/opencode/command/remember.md +208 -29
  32. package/packages/opencode/opencode.jsonc +2 -6
  33. package/packages/subagentic-manual.md +31 -32
  34. package/packages/ampcode/commands/docs-builder/templates.md +0 -601
  35. package/packages/claude/skills/docs-builder/SKILL.md +0 -309
  36. package/packages/claude/skills/docs-builder/references/templates.md +0 -601
  37. package/packages/droid/commands/docs-builder/templates.md +0 -601
  38. package/packages/opencode/command/docs-builder/templates.md +0 -601
@@ -4,7 +4,7 @@ description: Consolidate stashes + friction into project memory
4
4
  usage: /remember
5
5
  ---
6
6
 
7
- Run friction analysis, then consolidate session stashes + friction antigens into a single project-local MEMORY.md, and inject into CLAUDE.md. Friction runs automatically (best-effort) — there is no separate `/friction` command.
7
+ Run friction analysis, then consolidate session stashes + friction antigens into a single project-local MEMORY.md, and inject into CLAUDE.md. Friction runs automatically (best-effort) — there is no separate `/friction` command. A docs reconcile check runs at the end, detect-only.
8
8
 
9
9
  **Guardrails**
10
10
  - Favor straightforward, minimal implementations first and add complexity only when requested or clearly required.
@@ -14,9 +14,14 @@ Run friction analysis, then consolidate session stashes + friction antigens into
14
14
  semantic judgment, cheaper/faster than your top reasoning tier (e.g. Claude's Sonnet vs
15
15
  Opus). Use whatever your tool designates as that balanced default; never hardcode a
16
16
  vendor-specific model name.
17
- - **Batch independent subagent calls.** Step 2's per-stash extractions are independent of
18
- each other spawn them concurrently (parallel/background subagent calls in one turn)
19
- where your tool supports it, instead of processing stashes one at a time.
17
+ - **Batch stashes, don't fan out.** Step 2 gives each extraction agent **up to 5 stashes**
18
+ and uses as few agents as possible (3 stashes 1 agent, 7 → 2). One agent reading several
19
+ sessions sees the same lesson recur and writes it once; one agent per stash writes it once
20
+ per stash and leaves the merge to catch the duplicates. If more than one agent is needed,
21
+ run them concurrently.
22
+ - **Hot memory is short snippets, not prose.** A fact is one line, target 160 characters,
23
+ hard stop 180, stating a rule the agent should follow next time. Events, history, and
24
+ narrative are not facts.
20
25
 
21
26
  **What it does**
22
27
 
@@ -30,9 +35,9 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
30
35
  project are behavioral lessons worth keeping everywhere. So point it at the tool's
31
36
  **global sessions root** (all projects), not a per-project directory.
32
37
 
33
- - **Locate `friction.js`** — it is bundled next to this command at `remember/friction.js`
38
+ - **Locate `friction.cjs`** — it is bundled next to this command at `remember/friction.cjs`
34
39
  (the same directory as `remember.md`, whether installed or run from the package). If it
35
- exists nowhere, skip to step 1 (stash-only) and tell the user friction.js is missing.
40
+ exists nowhere, skip to step 1 (stash-only) and tell the user friction.cjs is missing.
36
41
  - **Resolve the global sessions root** — probe this list top-to-bottom, use the first that
37
42
  exists and contains `.jsonl` files (recursively). **Never prompt the user.**
38
43
  ```
@@ -44,10 +49,10 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
44
49
  ~/.codex/sessions/ # Codex CLI (use $CODEX_HOME/sessions/ if set)
45
50
  ~/.gemini/antigravity-cli/brain/ # Antigravity
46
51
  ```
47
- > Note: `friction.js` parses Claude Code's session schema. The Codex/Antigravity roots
52
+ > Note: `friction.cjs` parses Claude Code's session schema. The Codex/Antigravity roots
48
53
  > will resolve but yield no signals until friction learns their formats — open an issue
49
54
  > to request one: https://github.com/hamr0/liteagents/issues
50
- - **Run** `node <friction.js> "<resolved-root>"`. friction writes its output to
55
+ - **Run** `node <friction.cjs> "<resolved-root>"`. friction writes its output to
51
56
  `.claude/remember/friction/` in the current project.
52
57
  - **On any miss — loud, never silent.** If no root resolves, or friction errors, or it
53
58
  finds no usable sessions, print this and continue with stash-only consolidation:
@@ -67,28 +72,59 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
67
72
  the new reference (step 5), and tell the user exactly what moved.
68
73
  - **Bootstrap `AGENT_RULES.md` (one-time, silent-if-present).** If
69
74
  `.claude/remember/AGENT_RULES.md` does not exist, copy it from the bundled template next
70
- to this command (`remember/AGENT_RULES.md`, same directory as `friction.js`). If it
75
+ to this command (`remember/AGENT_RULES.md`, same directory as `friction.cjs`). If it
71
76
  already exists, leave it untouched — never overwrite, even if the bundled template
72
77
  changes in a later version; it becomes user-owned the moment it lands in the project.
73
78
  - Read all `.claude/stash/*.md` files in the current project
74
79
  - Read friction output written in step 0: `.claude/remember/friction/antigen_clusters.json` (preferred) or `.claude/remember/friction/antigen_review.md` (fallback)
75
80
  - Read existing `.claude/remember/MEMORY.md` if it exists — create dir if missing
76
81
  - Read processed manifest at `.claude/remember/.processed` — skip already-processed stashes
77
- - If no unprocessed stashes AND friction produced no new antigens, report "nothing to consolidate" and stop
82
+ - If no unprocessed stashes AND friction produced no new antigens, run the step-8 mechanical
83
+ length check (the same awk: over 180 chars with no >100-char backtick literal) against the
84
+ existing `.claude/remember/MEMORY.md`. If it returns 0 lines, report "nothing to
85
+ consolidate" and stop. If it returns any lines, "no new input" is not a reason to leave
86
+ gate debt in place — do NOT stop: proceed to step 3 and run the Facts rewrite + pre-write
87
+ gate on the existing content with no new input, then continue through step 8 as normal.
78
88
 
79
- 2. **Extract from unprocessed stashes** (spawn one subagent per stash, in parallel — see Guardrails)
80
- - For each unprocessed stash, call the mid-tier model (see Guardrails) to extract:
81
- - **FACTS** (atomic, one-line): stable preferences, decisions, corrections, explicit "remember this"
82
- - **EPISODE** (3-5 bullet narrative): what was the goal, what was tried, outcome, lesson
89
+ 2. **Extract from unprocessed stashes** (up to 5 stashes per agent, as few agents as possible — see Guardrails)
90
+ - Each agent reads its batch of stashes together and calls the mid-tier model (see Guardrails) to extract:
91
+ - **FACTS** (one line each, target 160 chars, hard stop 180): stable preferences, decisions, corrections,
92
+ explicit "remember this". A fact is a **rule that changes future behaviour**, written
93
+ as the current truth — not an event that happened, not its history. A lesson that
94
+ recurs across the batch is written **once**.
95
+ - **EPISODE** (one per stash, 3-5 bullets): what was the goal, what was tried, outcome, lesson
83
96
  - **SKIP**: code details, file paths, errors, mechanical steps, LLM responses
84
97
  - Collect all new facts and episodes
85
98
 
86
99
  3. **Merge into MEMORY.md**
87
100
  - Read existing `.claude/remember/MEMORY.md` and parse its sections (## Facts, ## Episodes, ## Antigens)
88
- - **Facts section**: call the mid-tier model with existing facts + newly extracted facts
89
- - Rules: new updates replace old, contradictions keep new version, duplicates dropped
90
- - Keep facts atomic, one line each
91
- - **Episodes section**: append new episode entries (append-only, timestamped, no dedup)
101
+ - **Facts section rewrite and compress, every run.** Call the mid-tier model with the
102
+ existing facts + the new facts + the lessons of any episodes aging out (below), and have
103
+ it return the **whole section rewritten**, not the old list with lines added:
104
+ - New replaces old; contradictions keep the new version; duplicates fold into one line.
105
+ - Shorten every fact that can be shorter. Target 160 chars, one line, current truth only —
106
+ no "supersedes", no version history, no narrative. The output should normally be
107
+ **shorter** than the input.
108
+ - Facts are never append-only: an old fact that a new one refines is rewritten in place.
109
+ - **Pre-write length gate — runs BEFORE MEMORY.md is written, not after.** A check that
110
+ only runs after the write (step 8) can merely describe damage already on disk; the gate
111
+ has to sit inside the merge, before anything hits the file. This applies to **every**
112
+ line in the draft Facts section, including lines carried over unchanged from the
113
+ previous MEMORY.md — the whole section is rewritten every run (see "Shorten every fact
114
+ that can be shorter" above), so every line is this run's output. "Not introduced this
115
+ run" is not a reason to skip a line. After producing the draft, check every line's
116
+ length: 161-180 chars passes silently. Over 180 MUST be shortened and re-checked. The
117
+ ONLY exemption is mechanical: a line whose single longest backtick-quoted literal is
118
+ itself longer than 100 characters (a path, command, or exact phrasing that genuinely
119
+ cannot be split) — that line is kept verbatim and listed as an exemption in the step-8
120
+ report. No other reason exempts a line — not established formatting, not dense by
121
+ convention, not pre-existing, not load-bearing detail. A line that's long because it holds
122
+ several sentences is shortened by splitting it into several facts or dropping the
123
+ history — never exempted. Only a draft that passes the gate (or has its overruns
124
+ exempted under the 100-char backtick rule) is written to `.claude/remember/MEMORY.md`.
125
+ - **Episodes section**: append new episode entries, keep only the **10 most recent**.
126
+ Every older episode is **folded, then deleted**: its lesson becomes a fact (handed to
127
+ the rewrite above); the narrative is removed. No archive — git has the history.
92
128
  - **Antigens section**: only update from friction output (step 4)
93
129
  - Write merged result to `.claude/remember/MEMORY.md` in the format under step 6.
94
130
 
@@ -155,18 +191,90 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
155
191
  "status": "observing|hot|rejected|escalated",
156
192
  "rule": "<current phrasing>",
157
193
  "attempts": [{ "n": 1, "rule": "<phrasing>", "adopted": "YYYY-MM-DD", "outcome": "active|failed" }],
158
- "evidence": { "sessions": 0, "projects": [], "quotes": [], "last_seen": "YYYY-MM-DD" },
194
+ "evidence": { "sessions": 0, "session_ids": [{ "id": "<project-label>/<MMDD-HHMM>-<hash>", "seen": "YYYY-MM-DD" }], "projects": [], "quotes": [], "last_seen": "YYYY-MM-DD" },
159
195
  "recurred_while_hot": 0,
160
196
  "history": [{ "date": "YYYY-MM-DD", "event": "<transition>" }] }
161
197
  ```
162
198
 
199
+ **Evidence merges by session identity, not by re-counting a re-scan.** Friction re-scans
200
+ the entire corpus every run, so the same old session matches its cluster again on every
201
+ run; without an identity check, that re-detection would masquerade as new recurrence and
202
+ could promote a one-off to hot — the exact false-preference failure the observed-signal
203
+ redesign exists to prevent. Friction's clusters already carry `session_ids`. Identity is
204
+ the **trailing 8-char hash** — the part after the last `-` in the id — because project
205
+ labels can be renamed while the hash, derived from the session filename, is stable. Two
206
+ ids with the same hash are the same session, full stop.
207
+
208
+ Two ids with DIFFERENT hashes can also be one session. A fork or resume writes the same
209
+ conversation to a second session file with its own filename, so the hash alone would
210
+ count one reaction twice. `friction.cjs` collapses these before it emits clusters —
211
+ sessions sharing at least one message `uuid` are one conversation, and the group is
212
+ reported under a single canonical id (the lexicographically smallest). So the ids
213
+ reaching this step are already canonical; do not attempt to re-derive fork identity
214
+ here. Measured on a real 3,158-session corpus: 6 such groups exist, and of ~5M possible
215
+ session pairs only 9 share any uuid at all — every one a genuine duplicate.
216
+
217
+ **Migration (one-time, grandfathered): SEED, DO NOT COUNT.** Existing entries predate
218
+ `session_ids` and carry only a bare `sessions` count with an empty `session_ids` set. This
219
+ is mechanical — do not resolve it by judgment. On the run that first populates such an
220
+ entry's `session_ids` (i.e. `session_ids` is empty going in), do exactly these two things
221
+ and nothing else:
222
+ 1. Write `session_ids` to this run's matched ids (NOT an empty set — the empty set is the
223
+ pre-migration state you are migrating FROM, not what you write).
224
+ 2. Append the history line "identity migration — legacy count grandfathered, growth
225
+ requires new hashes".
226
+
227
+ Change NOTHING else on this run — not `sessions`, not `last_seen`, not
228
+ `recurred_while_hot`, not `status`. In particular, do NOT apply the "no hashes present →
229
+ new conversation" rule here: `session_ids` was empty, so every hash looks absent, and
230
+ counting would treat the entry's own already-counted history as fresh recurrence — on a
231
+ `hot` entry that also fires `recurred_while_hot`, which at 2 marks the phrasing failed and
232
+ rewrites a rule that never actually failed. Counting resumes on the NEXT run, once
233
+ `session_ids` is non-empty and an absent hash set is genuinely new evidence.
234
+
235
+ Observed for real: bareloop's first migration run carried two `hot` entries, each already
236
+ at `recurred_while_hot: 1`. Counting on migration would have taken both to 2 and force-
237
+ rephrased two working rules from re-detected pre-existing sessions. Two separate runs
238
+ avoided it only because whoever ran them noticed and overrode the text — which is the
239
+ definition of a rule that needs to be mechanical rather than prose.
240
+
163
241
  For each surviving antigen from 4a/4b, match against existing entries by `class_hints`
164
- (the mistake class, not the rule wording — rules change, the class doesn't):
165
- - **No match** new entry, `status: "observing"`, attempt 1, history "candidate (N sessions)".
166
- - **Match, `observing`** merge evidence (sessions, quotes, projects, last_seen).
167
- Crosses the 4b hot threshold `status: "hot"`, history "promoted to hot (N sessions)".
168
- - **Match, `hot`** → the mistake happened *while its rule was loaded*:
169
- `recurred_while_hot += 1`, merge evidence, history "recurred while hot (count)".
242
+ (the mistake class, not the rule wording — rules change, the class doesn't). A matched
243
+ cluster represents exactly ONE conversation, no matter how many hashes its `session_ids`
244
+ holds a fork/resume group deliberately carries every member file's hash so the cluster
245
+ can be matched under any of the conversation's filenames.
246
+
247
+ **`sessions` is the authoritative conversation count. `session_ids` is evidence detail —
248
+ a list of the FILES one conversation was written to. NEVER derive a count from
249
+ `len(session_ids)`; a fork or resume makes that number larger than the conversation
250
+ count.** This is mechanical — do not resolve it by judgment. Compare the cluster's hashes
251
+ against the entry's stored hash set as a set, not one at a time, and count per
252
+ conversation, never per hash:
253
+ - **None of the cluster's hashes present** → a genuinely new conversation: add ALL of the
254
+ cluster's hashes to `session_ids`, increment `sessions` by exactly 1 (never by the
255
+ number of hashes in the cluster), refresh `last_seen` to today's run date (session ids
256
+ carry no year), and count it once toward the 4b promotion threshold.
257
+ - **Any of the cluster's hashes already present** → this conversation is already counted:
258
+ add whichever of its hashes are still missing from `session_ids` (they are aliases of
259
+ the same conversation, and storing them keeps future matching robust under any of its
260
+ filenames), but change NOTHING else — not `sessions`, not `last_seen`, not history, not
261
+ `recurred_while_hot`. It is a re-scan re-detecting a conversation already counted, not
262
+ new evidence.
263
+ - **No match, cluster `sessions` >= 2** → new entry, `status: "observing"`, attempt 1,
264
+ history "candidate (N sessions)".
265
+ - **No match, cluster `sessions` == 1** → do NOT create a ledger entry. The ledger tracks
266
+ recurrence, and a single occurrence has no recurrence to track yet — seeding singletons
267
+ grows the ledger by dozens of never-recurring entries per run. Friction re-scans every
268
+ session log on every run, so if this mistake recurs, a later run will match it back to
269
+ 2+ sessions and seed it then. This does not change the Match bullets below — a
270
+ 1-session cluster can still merge into an EXISTING entry; that is recurrence.
271
+ - **Match, `observing`** → apply the new-conversation / already-counted rule above
272
+ (sessions, session_ids, quotes, projects, last_seen). Crosses the 4b hot threshold on a
273
+ genuinely new conversation → `status: "hot"`, history "promoted to hot (N sessions)".
274
+ - **Match, `hot`** → the mistake happened *while its rule was loaded*, and only when the
275
+ match is a genuinely new conversation (per the rule above, not a re-scan of an
276
+ already-present hash): `recurred_while_hot += 1` once per conversation, merge evidence,
277
+ history "recurred while hot (count)".
170
278
  - At `recurred_while_hot >= 2`: the phrasing failed. Mark the current attempt
171
279
  `outcome: "failed"`, draft attempt n+1 — it must differ from **every** prior
172
280
  attempt's text in this entry (failed attempts are the rejected-edit buffer: never
@@ -179,6 +287,20 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
179
287
  them) or accepted limit.
180
288
  - **Match, `escalated`/`rejected`** (rejected = user veto) → merge evidence only; never re-propose.
181
289
 
290
+ **Decay (observing only).** Antigens are the fastest-decaying artifact and, until now,
291
+ had no exit. This is meaningful *because* of the identity fix above — without it,
292
+ `last_seen` would refresh on every re-scan and nothing would ever go stale. After the
293
+ matching pass, sweep every `observing` entry: if its `last_seen` is **older than 8
294
+ weeks** (matching the ~7-week transcript retention — evidence that old can no longer be
295
+ re-verified against the source logs), set `status: "expired"` and append a history line
296
+ "expired — no new evidence in 8+ weeks". The ledger entry is **kept**, never deleted
297
+ (append-only doctrine) — it just stops rendering into MEMORY.md. If a later run's new
298
+ session hash matches an `expired` entry's `class_hints`, merge the evidence and set
299
+ `status` back to `"observing"` with history "reactivated". `hot` entries **never expire
300
+ by age** — a loaded rule that stops recurring is the rule working, not staleness; a hot
301
+ entry leaves hot only via the existing `recurred_while_hot` escalation path above.
302
+ `escalated`/`rejected` are untouched by decay.
303
+
182
304
  Consistency: MEMORY.md's Antigens section is the render; the ledger is the record —
183
305
  after 4c every hot antigen in MEMORY.md has a matching `hot` ledger entry. Mutations
184
306
  are append-friendly: merge evidence and change status, never delete entries or history
@@ -215,7 +337,7 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
215
337
  > Auto-generated by /remember. Do not edit manually.
216
338
 
217
339
  ## Facts
218
- - [atomic fact 1]
340
+ - [one-line rule, target 160 chars, hard stop 180]
219
341
 
220
342
  ## Episodes
221
343
  ### YYYY-MM-DD - [title]
@@ -231,15 +353,71 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
231
353
  ### Low Confidence (needs more data)
232
354
  - [pattern] (evidence: [N] sessions)
233
355
  ```
356
+ The Medium/Low lists render only entries whose ledger `status` is `observing` (or `hot`
357
+ for High) — an entry marked `expired` by the decay rule (step 4c) is skipped here even
358
+ though it stays in `ledger.json`.
234
359
 
235
360
  6. **Update processed manifest**
236
361
  - Append paths of newly processed stashes to `.claude/remember/.processed`
237
362
 
238
- 7. **Report to user**print it AND write the same content to `.claude/remember/report.md`
363
+ 7. **Docs reconcile checkDETECT ONLY** (best-effort, crash-isolated like step 0)
364
+
365
+ `/remember` never reconciles docs, never writes frontmatter, never edits a page. It
366
+ prints at most one nudge line. Wrapped so any failure here can never block the memory
367
+ write that already happened in steps 3-6.
368
+
369
+ - **Locate `docs-builder.cjs`** — bundled next to this command at
370
+ `docs-builder/docs-builder.cjs` (same convention as `remember/friction.cjs`).
371
+ - **Not applicable, stay silent:** if the project has no `docs/` directory, skip without
372
+ saying anything. Most projects have no doc corpus and a nudge every run is noise.
373
+ - **Applicable but could not run — say so, loudly:** if `docs/` exists but the script is
374
+ missing, `git` fails, or the command errors, print one line explaining why the check
375
+ was skipped. Never fail silently.
376
+ - **`docs/` exists but no `docs/.docs-builder/` directory:** docs-builder has never run
377
+ here — print one line telling the user to run `/docs-builder reorg` to organize and
378
+ index the corpus. Do NOT tell them to run `ledger` instead: `ledger` only stamps
379
+ whatever is currently on disk as the baseline, so on an unsorted pile it would record
380
+ the mess as correct and `due` would then report NOT due forever.
381
+ - **`docs/.docs-builder/ledger.json` exists:** run `due` and pass through its verdict, as
382
+ below.
383
+ - Otherwise run it and pass through its verdict:
384
+ ```bash
385
+ node docs-builder/docs-builder.cjs due
386
+ ```
387
+ `due` compares `docs/` against the SHA stamped in `docs/.docs-builder/ledger.json`
388
+ using `git diff --numstat -M`, classifying each doc as new / moved / moved+changed /
389
+ changed (with the line delta and rough percentage) / deleted. It is **due at >=5
390
+ changed docs** — the same derived-not-counted shape as `/stash`'s nudge.
391
+ - If DUE, end with one line and nothing more:
392
+ ```
393
+ docs: 7 changed since 991f72d3 — run /docs-builder reorg
394
+ ```
395
+
396
+ 8. **Report to user** — print it AND write the same content to `.claude/remember/report.md`
239
397
  (overwritten each run; the ledger keeps history — the report is just the latest snapshot)
240
398
  - Number of stashes processed
241
- - Facts count (total, new)
242
- - Episodes count (total, new)
399
+ - Facts count (before → after the rewrite; the number should not grow by the number of new facts)
400
+ - **Mechanical length check** — run, don't estimate. This confirms the step-3 gate rather
401
+ than being the first check to catch an overrun. It implements the SAME mechanical
402
+ exemption as the gate (a line whose longest backtick literal exceeds 100 chars is not
403
+ flagged), so this count and the gate's count can never disagree:
404
+ ```bash
405
+ awk '
406
+ /^## Facts/{f=1} /^## Episodes/{f=0}
407
+ f && /^- / && length($0)>180 {
408
+ line=$0; maxlen=0
409
+ while (match(line, /`[^`]*`/)) {
410
+ seglen = RLENGTH-2
411
+ if (seglen > maxlen) maxlen = seglen
412
+ line = substr(line, RSTART+RLENGTH)
413
+ }
414
+ if (maxlen <= 100) print
415
+ }' .claude/remember/MEMORY.md
416
+ ```
417
+ Print every line it returns and the count. Zero is the target; non-zero means a gate miss
418
+ — every remaining overrun already had its chance to be exempted (100-char backtick
419
+ literal) inside the step-3 gate, so anything printed here should not exist.
420
+ - Episodes count (new, kept hot, folded + deleted)
243
421
  - Antigens count by confidence tier, with how many newly promoted to hot
244
422
  - Ledger lines — one per non-observing entry: id, short rule, status, recurrences since
245
423
  adoption. Highlight rephrased (RECURRED) and ESCALATED entries; escalations need a
@@ -259,5 +437,6 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
259
437
  - Antigen ledger: `.claude/remember/ledger.json` (per-rule evidence trail: class, status, attempts/rejected-buffer, recurrence-while-hot)
260
438
  - Consolidation report: `.claude/remember/report.md` (latest step-7 report, overwritten each run)
261
439
  - Processed manifest: `.claude/remember/.processed`
440
+ - Docs ledger (READ ONLY from here — owned by `/docs-builder`): `docs/.docs-builder/ledger.json`
262
441
  - Friction output (transient, regenerated each run): `.claude/remember/friction/` — `antigen_clusters.json` (preferred input), `antigen_review.md` (fallback), plus raw analysis files
263
442
  - Output: `CLAUDE.md` (managed MEMORY section, plus an AGENT_RULES section once bootstrapped)
@@ -448,9 +448,9 @@
448
448
  "license": "MIT"
449
449
  },
450
450
  "node_modules/fast-uri": {
451
- "version": "3.1.4",
452
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
453
- "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
451
+ "version": "3.1.5",
452
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz",
453
+ "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==",
454
454
  "funding": [
455
455
  {
456
456
  "type": "github",
@@ -585,9 +585,9 @@
585
585
  }
586
586
  },
587
587
  "node_modules/hono": {
588
- "version": "4.12.31",
589
- "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.31.tgz",
590
- "integrity": "sha512-zJIHFrl6bq3RDd2YusFNCDlM8qUprxKswyi/OPzPyzKDdyBXDqWx8bZlZ7R+saTdSTatUmb3O7K4SspGPaEOQg==",
588
+ "version": "4.13.0",
589
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.0.tgz",
590
+ "integrity": "sha512-jhunvfHWxd7J5EFfSgH4xsYJzSe/lfqbUCxiyyeaQasUsXeEHXtzVid+7EOGByc5JnFa23SSFL3Y2RV/z1T+eQ==",
591
591
  "license": "MIT",
592
592
  "engines": {
593
593
  "node": ">=16.9.0"
@@ -636,9 +636,9 @@
636
636
  "license": "ISC"
637
637
  },
638
638
  "node_modules/ip-address": {
639
- "version": "10.2.0",
640
- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
641
- "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
639
+ "version": "10.4.0",
640
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.4.0.tgz",
641
+ "integrity": "sha512-oSK96Grm3aP6OrS263xVxbNDGVL7rzBtYdpGqlDG8iQdoenDoTs/nkki+DflYbAEE8Xl6o5YxhxlrKvI3nqKXQ==",
642
642
  "license": "MIT",
643
643
  "engines": {
644
644
  "node": ">= 12"
@@ -14,7 +14,7 @@ These subagents are available when using Claude Code CLI. Droid can reference th
14
14
  | 2-generate-tasks | 2-Generate Tasks | Detailed Planning - use to break down the PRD into a granular, actionable task list |
15
15
  | 3-process-task-list | 3-Process Task List | Iterative Implementation - use to guide the AI to tackle one task at a time, allowing you to review and approve each change |
16
16
  | code-developer | Full Stack Developer | Use for code implementation, debugging, refactoring, and development best practices |
17
- | context-builder | Context Initializer | Use to initialize project context for new/existing projects, discover and organize documentation, create CLAUDE.md and KNOWLEDGE_BASE.md for optimal token-efficient memory |
17
+ | context-builder | Context Initializer | Use to initialize project context for new/existing projects, discover and organize documentation, create AGENTS.md and KNOWLEDGE_BASE.md for optimal token-efficient memory |
18
18
  | feature-planner | Product Manager | Use for creating epics and user stories, prioritization, backlog navigation, story refinement, and retrospectives |
19
19
  | market-researcher | Business Analyst | Use for market research, brainstorming, competitive analysis, project briefs, and initial project discovery |
20
20
  | orchestrator | Master Orchestrator | Use for workflow coordination, multi-agent tasks, role switching guidance, and when unsure which specialist to consult |
@@ -27,7 +27,7 @@ These subagents are available when using Claude Code CLI. Droid can reference th
27
27
  | ID | Description | Usage | Auto |
28
28
  |---|---|---|---|
29
29
  | brainstorming | Refines rough ideas into fully-formed designs through collaborative questioning | /brainstorming <session-type> <topic> | false |
30
- | docs-builder | Create comprehensive project documentation with structured /docs hierarchy | /docs-builder | false |
30
+ | docs-builder | Reorg a docs corpus, split an oversized doc, search it, keep pages current, index them | /docs-builder [reorg \| cleanup <file.md>] | false |
31
31
  | live-canvas | Design UI variations and collect click-to-annotate feedback from the browser (batch mode only on Droid) | /live-canvas | false |
32
32
  | optimize | Analyze and optimize performance issues | /optimize <target-area> | - |
33
33
  | refactor | Refactor code while maintaining behavior and tests | /refactor <code-section> | - |