liteagents 2.18.0 → 2.20.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 +37 -0
- package/package.json +1 -1
- package/packages/ampcode/commands/docs-builder/docs-builder.cjs +27 -7
- package/packages/ampcode/commands/docs-builder.md +7 -1
- package/packages/ampcode/commands/remember/AGENT_RULES.md +26 -26
- package/packages/ampcode/commands/remember.md +26 -10
- package/packages/claude/commands/docs-builder/docs-builder.cjs +27 -7
- package/packages/claude/commands/docs-builder.md +7 -1
- package/packages/claude/commands/remember/AGENT_RULES.md +26 -26
- package/packages/claude/commands/remember.md +26 -10
- package/packages/droid/commands/docs-builder/docs-builder.cjs +27 -7
- package/packages/droid/commands/docs-builder.md +7 -1
- package/packages/droid/commands/remember/AGENT_RULES.md +26 -26
- package/packages/droid/commands/remember.md +26 -10
- package/packages/opencode/command/docs-builder/docs-builder.cjs +27 -7
- package/packages/opencode/command/docs-builder.md +7 -1
- package/packages/opencode/command/remember/AGENT_RULES.md +26 -26
- package/packages/opencode/command/remember.md +26 -10
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
15
|
- Enhanced testing capabilities
|
|
16
16
|
- Performance optimizations
|
|
17
17
|
|
|
18
|
+
## [2.20.0] - 2026-08-29
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **`AGENT_RULES.md` template (all 4 kits): the spec layer now requires the interview to
|
|
22
|
+
happen but leaves its shape free.** PRD is defined as a portal with 5 minimum fields
|
|
23
|
+
(problem & goal, go/no-go, out of scope, modules, open questions) that every POC refines.
|
|
24
|
+
- **Four one-sentence execution-order rules (Sequence / Selection / Iteration / Verify) added
|
|
25
|
+
to Operating Flow.**
|
|
26
|
+
- **"Build incrementally" replaced by "One module at a time"** (works alone, then connects,
|
|
27
|
+
both proven) and a separate "No fitting to pass" rule, with a matching Red Flag.
|
|
28
|
+
- **New safeguard: never commit to `main`** — branch, then propose `/code-review` followed by
|
|
29
|
+
`/release`; merge/release only on a named go.
|
|
30
|
+
- **Removed restated content**: the "AI Agent Instructions" section, the "Safety First"
|
|
31
|
+
bullet, the "POC scope" bullet, and duplicated spec/POC prose in the Communication Protocol
|
|
32
|
+
and the CLAUDE.md stub.
|
|
33
|
+
|
|
34
|
+
## [2.19.0] - 2026-08-26
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- **`docs/index.md` rows now list each doc's H2 headings, one per line, with a line range.**
|
|
38
|
+
The index is meant to let an agent find and slice-read a section without opening the doc —
|
|
39
|
+
previously each row carried only an H1, a line count, and a link, so an agent still had to
|
|
40
|
+
open the file to find anything inside it. Each H2 line reuses the exact `headings()` +
|
|
41
|
+
`fenceMask()` boundaries `scan` already writes to `outline.json` (no second parser), so a
|
|
42
|
+
heading inside a fenced code block still never appears. Archive rows stay H1-only — an
|
|
43
|
+
archived doc is frozen history, not a live section to route into.
|
|
44
|
+
- **`/remember` step 7 self-heals `docs/index.md` every run, not just at reorg time.** Any
|
|
45
|
+
drift `due` reports (new/moved/changed/deleted, not only the >=5-doc DUE threshold) now
|
|
46
|
+
also re-runs `index-flat` — script-only, no model call — so the index stays current between
|
|
47
|
+
full `/docs-builder reorg` passes instead of silently drifting until the next one.
|
|
48
|
+
- **`AGENT_RULES.md` demoted from an `@`-include to a plain path pointer.** It was wired into
|
|
49
|
+
CLAUDE.md as `@.claude/remember/AGENT_RULES.md`, which hot-loads the whole file into every
|
|
50
|
+
session even though it's documented as "not hot context" — measured at ~6.5k tokens/session
|
|
51
|
+
of standards prose loaded despite the file's own claim otherwise. `MEMORY.md` stays
|
|
52
|
+
`@`-referenced (it is hot); `AGENT_RULES.md` is now a plain path line, read only when
|
|
53
|
+
designing or building something new.
|
|
54
|
+
|
|
18
55
|
## [2.18.0] - 2026-08-26
|
|
19
56
|
|
|
20
57
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "liteagents",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.20.0",
|
|
4
4
|
"description": "AI development toolkit with 11 specialized agents and 18 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": {
|
|
@@ -728,14 +728,33 @@ function plan(outlineF, labelsF) {
|
|
|
728
728
|
// tripwire, never a prune, never a collapse, never a delete.
|
|
729
729
|
const ARCHIVE_WARN_ROWS = 100; // stated default, not measured — see docs-builder-v3-spec.md
|
|
730
730
|
|
|
731
|
-
|
|
731
|
+
// `includeH2` is false for archive rows: an archived doc is frozen history, not a live
|
|
732
|
+
// section a reader is being routed into, so its row stays H1 + line count + link only.
|
|
733
|
+
function indexRow(rel, dest, includeH2) {
|
|
732
734
|
const text = read(rel);
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
+
const lines = text.split('\n');
|
|
736
|
+
// Same headings()+fenceMask() path scan() uses -- no second parser -- so an H2 inside a
|
|
737
|
+
// ``` fence is masked out here exactly as it is there.
|
|
738
|
+
const mask = fenceMask(lines);
|
|
739
|
+
const { h1, heads } = headings(lines, mask);
|
|
735
740
|
// Read from INSIDE index.md, so the link must resolve relative to index.md's own
|
|
736
741
|
// directory, not the repo root.
|
|
737
742
|
const relLink = path.relative(path.dirname(dest), repoPath(rel)).split(path.sep).join('/');
|
|
738
|
-
|
|
743
|
+
let row = `- [${h1 || path.basename(rel)}](${relLink}) — ${lines.length} lines\n`;
|
|
744
|
+
if (!includeH2) return row;
|
|
745
|
+
// One line per H2, each with its own line range: from the `## ` heading's own 1-based
|
|
746
|
+
// line through the line before the next heading of level <= 2 (H1 or H2), or EOF for the
|
|
747
|
+
// last one -- the SAME boundary scan() uses to write s/e into outline.json, re-derived
|
|
748
|
+
// here from the same heads array rather than duplicated as a second computation. Lets an
|
|
749
|
+
// agent jump straight to (and slice-read) a section without opening the doc at all.
|
|
750
|
+
const boundaries = heads.filter(h => h.lvl <= 2);
|
|
751
|
+
boundaries.forEach((h, i) => {
|
|
752
|
+
if (h.lvl !== 2) return;
|
|
753
|
+
const start = h.line;
|
|
754
|
+
const end = i + 1 < boundaries.length ? boundaries[i + 1].line - 1 : lines.length;
|
|
755
|
+
row += ` - ${h.text} (L${start}–${end})\n`;
|
|
756
|
+
});
|
|
757
|
+
return row;
|
|
739
758
|
}
|
|
740
759
|
|
|
741
760
|
function renderSection(title, rows) {
|
|
@@ -767,9 +786,10 @@ function indexFlat() {
|
|
|
767
786
|
const outRel = process.env.OUT || 'docs/index.md';
|
|
768
787
|
const dest = repoPath(outRel);
|
|
769
788
|
const productRows = [...productFiles, ...pageFiles].sort()
|
|
770
|
-
.map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
771
|
-
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
772
|
-
|
|
789
|
+
.map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
790
|
+
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
791
|
+
// Archive rows are deliberately H1-only -- frozen history, not a live section to route into.
|
|
792
|
+
const archiveRows = archiveFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, false) }));
|
|
773
793
|
|
|
774
794
|
let s = '# Index\n\n';
|
|
775
795
|
// Unconditional — not gated on row count, unlike ARCHIVE_WARN_ROWS below: a reader should
|
|
@@ -747,7 +747,13 @@ Writes **one** `docs/index.md` covering the whole corpus, in three sections: `##
|
|
|
747
747
|
(one row per file under `docs/product/`, plus any pages under `PAGES` — default `docs/wiki/`
|
|
748
748
|
— if they exist, plus any doc still sitting in place elsewhere), `## Logs` (one row per file
|
|
749
749
|
under `docs/logs/`), and `## Archive` (one row per file under `docs/archive/`). Each row is
|
|
750
|
-
an H1 title, a line count, and a link
|
|
750
|
+
an H1 title, a line count, and a link, plus one indented line per H2 heading (in document
|
|
751
|
+
order) so an agent can find and slice-read a section without opening the doc — each H2
|
|
752
|
+
line carries its own `(Lstart–end)` line range, reusing the SAME `headings()`+`fenceMask()`
|
|
753
|
+
boundaries `scan` already writes to `outline.json` (no second parser). Omitted when the doc
|
|
754
|
+
has no H2s. `## Archive` rows are H1-only, never H2 lines — an archived doc is frozen
|
|
755
|
+
history, not a live section to route into. No theme grouping, no `labels.json`, no model
|
|
756
|
+
call.
|
|
751
757
|
Default destination `docs/index.md` — **the only writer of that default path** in this whole
|
|
752
758
|
pipeline (nothing else writes an index at all).
|
|
753
759
|
`search` reads `outline.json`, never `index.md`. Prints the row counts and records a `log.md`
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
7. [Development Workflow](#development-workflow)
|
|
11
11
|
8. [Twelve-Factor Checklist](#twelve-factor-checklist)
|
|
12
12
|
9. [AGENT.md Stub](#agentmd-stub)
|
|
13
|
-
10. [AI Agent Instructions](#ai-agent-instructions)
|
|
14
13
|
|
|
15
14
|
---
|
|
16
15
|
|
|
@@ -18,10 +17,25 @@
|
|
|
18
17
|
|
|
19
18
|
Every task runs through three layers. Do not skip ahead to code.
|
|
20
19
|
|
|
21
|
-
1. **Spec —
|
|
22
|
-
|
|
20
|
+
1. **Spec — the interview must happen; its shape is yours.** Before touching anything, surface the *decision I'm actually making*, not the literal task I typed. Ask what you need to know — no more; how you ask is your call. Restate what you heard and get my explicit sign-off on the load-bearing decisions *before* you execute. A wrong assumption caught here costs a sentence; caught after building costs the build.
|
|
21
|
+
|
|
22
|
+
Write the outcome down as a **PRD**. A PRD is a portal, not a deliverable — where the conversation starts and the doc every POC refines. Minimum content, whatever the form:
|
|
23
|
+
- **Problem & goal** — what we're solving and why now
|
|
24
|
+
- **Go / no-go** — the 1–2 capabilities the product stands or falls on; usually module 0's riskiest assumption (e.g. "can a phone camera read the ID?"). Fails → stop
|
|
25
|
+
- **Out of scope** — what we're explicitly not doing
|
|
26
|
+
- **Modules** — the pieces to build, in order (see [*One module at a time*](#validate-before-you-build))
|
|
27
|
+
- **Open questions** — unknowns that don't block; never silently assumed
|
|
28
|
+
|
|
29
|
+
Every POC result updates the PRD; one that flips the go/no-go or a module's assumption is a spec change, not a footnote.
|
|
30
|
+
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`. When the work is done, propose `/code-review` and then `/release` — you never merge or release on your own (see [Required Safeguards](#required-safeguards-always--ask--never)). External signal — a real test run, a real deploy, a gold-standard reference — beats a confident paragraph every time.
|
|
23
31
|
3. **Environment — the standing context.** This file primes every session. Critical-path protections (secrets, auth, schema, CI) are stated as **Always / Ask / Never** below and bind you as written. Where your tool offers a permission allow/ask/deny list, mirror them there so they are enforced and not merely requested.
|
|
24
32
|
|
|
33
|
+
**Execution order — work the way a program runs, in this order, nothing skipped:**
|
|
34
|
+
1. **Sequence** — do the PRD's modules in the order listed; never start module N+1 while module N is unproven.
|
|
35
|
+
2. **Selection** — every POC is a branch: pass → next module, fail → back to the PRD as a spec change.
|
|
36
|
+
3. **Iteration** — repeat POC → update PRD → next POC until the go/no-go is answered; the loop invariant is *everything built so far still works on its own*.
|
|
37
|
+
4. **Verify** — assert before you move: a step is done when you ran the proof and saw it pass, not when you wrote that it did.
|
|
38
|
+
|
|
25
39
|
> 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.
|
|
26
40
|
|
|
27
41
|
---
|
|
@@ -29,16 +43,14 @@ Every task runs through three layers. Do not skip ahead to code.
|
|
|
29
43
|
## Communication Protocol
|
|
30
44
|
|
|
31
45
|
### Core Rules
|
|
32
|
-
- **Spec
|
|
33
|
-
- **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
|
|
46
|
+
- **Spec first, then checkpoint**: see [Operating Flow §1](#operating-flow). Never run ahead on an unverified assumption — flag it and stop
|
|
34
47
|
- **Fact-Based**: Base all recommendations on verified, current information. Prefer external signal (a real run, a real source) over a confident guess
|
|
35
48
|
- **Simplicity Advocate**: Call out overcomplications and suggest simpler alternatives
|
|
36
|
-
- **Safety First**: Never modify critical systems without explicit understanding and approval
|
|
37
49
|
|
|
38
50
|
### User Profile
|
|
39
51
|
- **Technical Level**: Non-coder but technically savvy
|
|
40
52
|
- **Learning Style**: Understands concepts, needs executable instructions
|
|
41
|
-
- **Expects**: Step-by-step guidance
|
|
53
|
+
- **Expects**: Step-by-step guidance, ready-to-run commands, and the *why* behind each recommendation
|
|
42
54
|
- **Comfortable with**: Command-line operations and scripts
|
|
43
55
|
- **Builds a lot of web apps** — assume any UI work will be consumed on phones as well as desktop
|
|
44
56
|
|
|
@@ -49,6 +61,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
49
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
50
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.amp/settings.json`
|
|
51
63
|
- **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
|
|
64
|
+
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/code-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
52
65
|
|
|
53
66
|
---
|
|
54
67
|
|
|
@@ -57,12 +70,12 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
57
70
|
### Validate Before You Build
|
|
58
71
|
|
|
59
72
|
- **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
|
|
60
|
-
- **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
|
|
61
73
|
- **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
|
|
62
|
-
- **Aim the POC at the load-bearing claim — not the easy part.**
|
|
74
|
+
- **Aim the POC at the load-bearing claim — not the easy part.** Cover the happy path and 2-3 common edges, but 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
|
|
63
75
|
- **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
|
|
64
76
|
- **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
|
|
65
|
-
- **
|
|
77
|
+
- **One module at a time.** Build the PRD's modules in order, never several at once. Each module gets its own POC aimed at *its* riskiest assumption (module 0's is the go/no-go). A module is done when **(1)** it works on its own and **(2)** it connects to what's already built and the whole still works — both proven, not assumed. Only then start the next
|
|
78
|
+
- **No fitting to pass.** Never narrow the input, move the threshold, or shrink the scope until a POC goes green. Report the failure and take it back to the PRD
|
|
66
79
|
|
|
67
80
|
### Dependency Hierarchy
|
|
68
81
|
|
|
@@ -106,6 +119,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
106
119
|
- Skipping POC validation for unproven ideas
|
|
107
120
|
- POC-ing only the easy part while hand-waving the risky mechanism, or claiming a cost ("cheap"/"fast"/"constant") you never measured
|
|
108
121
|
- 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
|
|
122
|
+
- Fitting a POC to pass (narrowed input, moved threshold, shrunk scope) instead of reporting the failure; starting module N+1 while module N is unproven
|
|
109
123
|
|
|
110
124
|
---
|
|
111
125
|
|
|
@@ -269,9 +283,9 @@ Copy this to any project's AGENT.md. These are mandatory rules, not suggestions.
|
|
|
269
283
|
```markdown
|
|
270
284
|
## Dev Rules
|
|
271
285
|
|
|
272
|
-
**
|
|
286
|
+
**Spec first.** Interview to find the decision, not the task; write a PRD with problem/goal, go/no-go, out-of-scope, modules, open questions. POCs refine it.
|
|
273
287
|
|
|
274
|
-
**
|
|
288
|
+
**POC first, one module at a time.** Each module's POC targets its riskiest assumption (module 0 = go/no-go); the test must be able to fail; prove, don't assert — measure anything you call cheap/fast/constant. No fitting to pass. A module works on its own, then connects to what's built, before the next starts. Never ship the POC.
|
|
275
289
|
|
|
276
290
|
**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).
|
|
277
291
|
|
|
@@ -283,17 +297,3 @@ Copy this to any project's AGENT.md. These are mandatory rules, not suggestions.
|
|
|
283
297
|
|
|
284
298
|
For full development and testing standards, see `.amp/remember/AGENT_RULES.md`.
|
|
285
299
|
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## AI Agent Instructions
|
|
290
|
-
|
|
291
|
-
When working with this user:
|
|
292
|
-
1. **Interview before building** — extract the real goal and surface load-bearing decisions for sign-off before you execute (see [Operating Flow](#operating-flow))
|
|
293
|
-
2. **Provide step-by-step** instructions with clear explanations
|
|
294
|
-
3. **Include ready-to-run** scripts and commands
|
|
295
|
-
4. **Explain the "why"** behind technical recommendations
|
|
296
|
-
5. **Flag potential issues** before they become problems — name the assumption, don't bury it
|
|
297
|
-
6. **Suggest simpler alternatives** when appropriate
|
|
298
|
-
7. **Ask first** before touching auth, DB schema/migrations, CI, or settings; **never** commit secrets
|
|
299
|
-
8. **Always identify** which files will be affected by changes
|
|
@@ -346,12 +346,13 @@ Reads all raw material (`.amp/stash/*.md` + `.amp/remember/friction/antigen_clus
|
|
|
346
346
|
inline duplication is needed
|
|
347
347
|
- If `.amp/remember/AGENT_RULES.md` exists (bootstrapped in step 1), compose a second,
|
|
348
348
|
independent section between `<!-- AGENT_RULES:START -->` and `<!-- AGENT_RULES:END -->`
|
|
349
|
-
markers
|
|
349
|
+
markers. Unlike MEMORY.md above, this is a **plain path pointer, never `@`-referenced**
|
|
350
|
+
— an `@`-reference hot-loads the whole file into every session, and this is a standards
|
|
351
|
+
guide to consult when designing/building something new, not hot context:
|
|
350
352
|
```
|
|
351
353
|
<!-- AGENT_RULES:START -->
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
@.amp/remember/AGENT_RULES.md
|
|
354
|
+
Standards guide (read when designing/building something new, not hot context):
|
|
355
|
+
.amp/remember/AGENT_RULES.md
|
|
355
356
|
<!-- AGENT_RULES:END -->
|
|
356
357
|
```
|
|
357
358
|
- Each marker pair is independent: if AGENT.md already has a given pair, replace the
|
|
@@ -411,11 +412,12 @@ Reads all raw material (`.amp/stash/*.md` + `.amp/remember/friction/antigen_clus
|
|
|
411
412
|
6. **Update processed manifest**
|
|
412
413
|
- Append paths of newly processed stashes to `.amp/remember/.processed`
|
|
413
414
|
|
|
414
|
-
7. **Docs reconcile check
|
|
415
|
+
7. **Docs reconcile check + auto re-index** (best-effort, crash-isolated like step 0)
|
|
415
416
|
|
|
416
|
-
`/remember` never reconciles
|
|
417
|
-
|
|
418
|
-
|
|
417
|
+
`/remember` never reconciles doc CONTENT, never writes frontmatter, never edits a page —
|
|
418
|
+
the only write here is the generated `docs/index.md` itself, via the same deterministic
|
|
419
|
+
`index-flat` script `/docs-builder` already uses, never a model call. Wrapped so any
|
|
420
|
+
failure here can never block the memory write that already happened in steps 3-6.
|
|
419
421
|
|
|
420
422
|
- **Locate `docs-builder.cjs`** — bundled next to this command at
|
|
421
423
|
`docs-builder/docs-builder.cjs` (same convention as `remember/friction.cjs`). Call it by
|
|
@@ -444,7 +446,19 @@ Reads all raw material (`.amp/stash/*.md` + `.amp/remember/friction/antigen_clus
|
|
|
444
446
|
- If `due` prints "no ledger yet" (no `docs/.docs-builder/ledger.json` to compare against),
|
|
445
447
|
do NOT relay it — print the same `/docs-builder reorg` line as the no-`docs/.docs-builder/`
|
|
446
448
|
case above, for the same reason: `ledger` would stamp an unsorted pile as correct.
|
|
447
|
-
-
|
|
449
|
+
- **Auto re-index — script only, no model, in addition to the DUE advisory below, not a
|
|
450
|
+
replacement for it.** If `due`'s output was NOT `docs unchanged since <sha>. NOT due.`
|
|
451
|
+
(i.e. it printed a row table -- any new/moved/moved+changed/changed/deleted doc, whether
|
|
452
|
+
or not the >=5 threshold below was crossed), the index has drifted and self-heals right
|
|
453
|
+
here, unconditionally:
|
|
454
|
+
```bash
|
|
455
|
+
node <docs-builder.cjs> index-flat
|
|
456
|
+
```
|
|
457
|
+
Same script `/docs-builder reorg` already calls, run standalone — no model call, no
|
|
458
|
+
interview, nothing moves. Note in the step-8 report that `docs/index.md` (and
|
|
459
|
+
`docs/log.md`, if `index-flat` touched it) were regenerated, so they are included
|
|
460
|
+
alongside whatever step 3-6 already changed when this run is committed.
|
|
461
|
+
- If DUE (the row count crossed the >=5 threshold), ALSO end with one line:
|
|
448
462
|
```
|
|
449
463
|
docs: 7 changed since 991f72d3 — run /docs-builder reorg
|
|
450
464
|
```
|
|
@@ -489,12 +503,14 @@ Reads all raw material (`.amp/stash/*.md` + `.amp/remember/friction/antigen_clus
|
|
|
489
503
|
ledger: ag-002 "literal scoped ask" ESCALATED → Fact; 2 phrasings failed. Hook or accept?
|
|
490
504
|
```
|
|
491
505
|
- If AGENT_RULES.md was bootstrapped this run, say so (one line)
|
|
506
|
+
- If step 7 ran the auto re-index, say so and name the regenerated files
|
|
507
|
+
(`docs/index.md`, plus `docs/log.md` if touched) so they are staged with this run
|
|
492
508
|
- Confirm MEMORY.md and AGENT.md updated
|
|
493
509
|
|
|
494
510
|
**File locations (all project-local — two dirs: `/stash` owns `.amp/stash/`, `/remember` owns `.amp/remember/`)**
|
|
495
511
|
- Stash files: `.amp/stash/*.md`
|
|
496
512
|
- Memory file: `.amp/remember/MEMORY.md` (single source of truth, referenced as `@.amp/remember/MEMORY.md`)
|
|
497
|
-
- Rules template: `.amp/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced
|
|
513
|
+
- Rules template: `.amp/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced by a plain path pointer, not `@`-referenced — see step 5)
|
|
498
514
|
- Antigen ledger: `.amp/remember/ledger.json` (per-rule evidence trail: class, status, attempts/rejected-buffer, recurrence-while-hot)
|
|
499
515
|
- Consolidation report: `.amp/remember/report.md` (latest step-8 report, overwritten each run)
|
|
500
516
|
- Processed manifest: `.amp/remember/.processed`
|
|
@@ -728,14 +728,33 @@ function plan(outlineF, labelsF) {
|
|
|
728
728
|
// tripwire, never a prune, never a collapse, never a delete.
|
|
729
729
|
const ARCHIVE_WARN_ROWS = 100; // stated default, not measured — see docs-builder-v3-spec.md
|
|
730
730
|
|
|
731
|
-
|
|
731
|
+
// `includeH2` is false for archive rows: an archived doc is frozen history, not a live
|
|
732
|
+
// section a reader is being routed into, so its row stays H1 + line count + link only.
|
|
733
|
+
function indexRow(rel, dest, includeH2) {
|
|
732
734
|
const text = read(rel);
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
+
const lines = text.split('\n');
|
|
736
|
+
// Same headings()+fenceMask() path scan() uses -- no second parser -- so an H2 inside a
|
|
737
|
+
// ``` fence is masked out here exactly as it is there.
|
|
738
|
+
const mask = fenceMask(lines);
|
|
739
|
+
const { h1, heads } = headings(lines, mask);
|
|
735
740
|
// Read from INSIDE index.md, so the link must resolve relative to index.md's own
|
|
736
741
|
// directory, not the repo root.
|
|
737
742
|
const relLink = path.relative(path.dirname(dest), repoPath(rel)).split(path.sep).join('/');
|
|
738
|
-
|
|
743
|
+
let row = `- [${h1 || path.basename(rel)}](${relLink}) — ${lines.length} lines\n`;
|
|
744
|
+
if (!includeH2) return row;
|
|
745
|
+
// One line per H2, each with its own line range: from the `## ` heading's own 1-based
|
|
746
|
+
// line through the line before the next heading of level <= 2 (H1 or H2), or EOF for the
|
|
747
|
+
// last one -- the SAME boundary scan() uses to write s/e into outline.json, re-derived
|
|
748
|
+
// here from the same heads array rather than duplicated as a second computation. Lets an
|
|
749
|
+
// agent jump straight to (and slice-read) a section without opening the doc at all.
|
|
750
|
+
const boundaries = heads.filter(h => h.lvl <= 2);
|
|
751
|
+
boundaries.forEach((h, i) => {
|
|
752
|
+
if (h.lvl !== 2) return;
|
|
753
|
+
const start = h.line;
|
|
754
|
+
const end = i + 1 < boundaries.length ? boundaries[i + 1].line - 1 : lines.length;
|
|
755
|
+
row += ` - ${h.text} (L${start}–${end})\n`;
|
|
756
|
+
});
|
|
757
|
+
return row;
|
|
739
758
|
}
|
|
740
759
|
|
|
741
760
|
function renderSection(title, rows) {
|
|
@@ -767,9 +786,10 @@ function indexFlat() {
|
|
|
767
786
|
const outRel = process.env.OUT || 'docs/index.md';
|
|
768
787
|
const dest = repoPath(outRel);
|
|
769
788
|
const productRows = [...productFiles, ...pageFiles].sort()
|
|
770
|
-
.map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
771
|
-
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
772
|
-
|
|
789
|
+
.map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
790
|
+
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
791
|
+
// Archive rows are deliberately H1-only -- frozen history, not a live section to route into.
|
|
792
|
+
const archiveRows = archiveFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, false) }));
|
|
773
793
|
|
|
774
794
|
let s = '# Index\n\n';
|
|
775
795
|
// Unconditional — not gated on row count, unlike ARCHIVE_WARN_ROWS below: a reader should
|
|
@@ -747,7 +747,13 @@ Writes **one** `docs/index.md` covering the whole corpus, in three sections: `##
|
|
|
747
747
|
(one row per file under `docs/product/`, plus any pages under `PAGES` — default `docs/wiki/`
|
|
748
748
|
— if they exist, plus any doc still sitting in place elsewhere), `## Logs` (one row per file
|
|
749
749
|
under `docs/logs/`), and `## Archive` (one row per file under `docs/archive/`). Each row is
|
|
750
|
-
an H1 title, a line count, and a link
|
|
750
|
+
an H1 title, a line count, and a link, plus one indented line per H2 heading (in document
|
|
751
|
+
order) so an agent can find and slice-read a section without opening the doc — each H2
|
|
752
|
+
line carries its own `(Lstart–end)` line range, reusing the SAME `headings()`+`fenceMask()`
|
|
753
|
+
boundaries `scan` already writes to `outline.json` (no second parser). Omitted when the doc
|
|
754
|
+
has no H2s. `## Archive` rows are H1-only, never H2 lines — an archived doc is frozen
|
|
755
|
+
history, not a live section to route into. No theme grouping, no `labels.json`, no model
|
|
756
|
+
call.
|
|
751
757
|
Default destination `docs/index.md` — **the only writer of that default path** in this whole
|
|
752
758
|
pipeline (nothing else writes an index at all).
|
|
753
759
|
`search` reads `outline.json`, never `index.md`. Prints the row counts and records a `log.md`
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
7. [Development Workflow](#development-workflow)
|
|
11
11
|
8. [Twelve-Factor Checklist](#twelve-factor-checklist)
|
|
12
12
|
9. [CLAUDE.md Stub](#claudemd-stub)
|
|
13
|
-
10. [AI Agent Instructions](#ai-agent-instructions)
|
|
14
13
|
|
|
15
14
|
---
|
|
16
15
|
|
|
@@ -18,10 +17,25 @@
|
|
|
18
17
|
|
|
19
18
|
Every task runs through three layers. Do not skip ahead to code.
|
|
20
19
|
|
|
21
|
-
1. **Spec —
|
|
22
|
-
|
|
20
|
+
1. **Spec — the interview must happen; its shape is yours.** Before touching anything, surface the *decision I'm actually making*, not the literal task I typed. Ask what you need to know — no more; how you ask is your call. Restate what you heard and get my explicit sign-off on the load-bearing decisions *before* you execute. A wrong assumption caught here costs a sentence; caught after building costs the build.
|
|
21
|
+
|
|
22
|
+
Write the outcome down as a **PRD**. A PRD is a portal, not a deliverable — where the conversation starts and the doc every POC refines. Minimum content, whatever the form:
|
|
23
|
+
- **Problem & goal** — what we're solving and why now
|
|
24
|
+
- **Go / no-go** — the 1–2 capabilities the product stands or falls on; usually module 0's riskiest assumption (e.g. "can a phone camera read the ID?"). Fails → stop
|
|
25
|
+
- **Out of scope** — what we're explicitly not doing
|
|
26
|
+
- **Modules** — the pieces to build, in order (see [*One module at a time*](#validate-before-you-build))
|
|
27
|
+
- **Open questions** — unknowns that don't block; never silently assumed
|
|
28
|
+
|
|
29
|
+
Every POC result updates the PRD; one that flips the go/no-go or a module's assumption is a spec change, not a footnote.
|
|
30
|
+
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`. When the work is done, propose `/code-review` and then `/release` — you never merge or release on your own (see [Required Safeguards](#required-safeguards-always--ask--never)). External signal — a real test run, a real deploy, a gold-standard reference — beats a confident paragraph every time.
|
|
23
31
|
3. **Environment — the standing context.** This file primes every session. Critical-path protections (secrets, auth, schema, CI) are stated as **Always / Ask / Never** below and bind you as written. Where your tool offers a permission allow/ask/deny list, mirror them there so they are enforced and not merely requested.
|
|
24
32
|
|
|
33
|
+
**Execution order — work the way a program runs, in this order, nothing skipped:**
|
|
34
|
+
1. **Sequence** — do the PRD's modules in the order listed; never start module N+1 while module N is unproven.
|
|
35
|
+
2. **Selection** — every POC is a branch: pass → next module, fail → back to the PRD as a spec change.
|
|
36
|
+
3. **Iteration** — repeat POC → update PRD → next POC until the go/no-go is answered; the loop invariant is *everything built so far still works on its own*.
|
|
37
|
+
4. **Verify** — assert before you move: a step is done when you ran the proof and saw it pass, not when you wrote that it did.
|
|
38
|
+
|
|
25
39
|
> 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.
|
|
26
40
|
|
|
27
41
|
---
|
|
@@ -29,16 +43,14 @@ Every task runs through three layers. Do not skip ahead to code.
|
|
|
29
43
|
## Communication Protocol
|
|
30
44
|
|
|
31
45
|
### Core Rules
|
|
32
|
-
- **Spec
|
|
33
|
-
- **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
|
|
46
|
+
- **Spec first, then checkpoint**: see [Operating Flow §1](#operating-flow). Never run ahead on an unverified assumption — flag it and stop
|
|
34
47
|
- **Fact-Based**: Base all recommendations on verified, current information. Prefer external signal (a real run, a real source) over a confident guess
|
|
35
48
|
- **Simplicity Advocate**: Call out overcomplications and suggest simpler alternatives
|
|
36
|
-
- **Safety First**: Never modify critical systems without explicit understanding and approval
|
|
37
49
|
|
|
38
50
|
### User Profile
|
|
39
51
|
- **Technical Level**: Non-coder but technically savvy
|
|
40
52
|
- **Learning Style**: Understands concepts, needs executable instructions
|
|
41
|
-
- **Expects**: Step-by-step guidance
|
|
53
|
+
- **Expects**: Step-by-step guidance, ready-to-run commands, and the *why* behind each recommendation
|
|
42
54
|
- **Comfortable with**: Command-line operations and scripts
|
|
43
55
|
- **Builds a lot of web apps** — assume any UI work will be consumed on phones as well as desktop
|
|
44
56
|
|
|
@@ -49,6 +61,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
49
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
50
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.claude/settings.json`
|
|
51
63
|
- **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
|
|
64
|
+
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/code-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
52
65
|
|
|
53
66
|
---
|
|
54
67
|
|
|
@@ -57,12 +70,12 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
57
70
|
### Validate Before You Build
|
|
58
71
|
|
|
59
72
|
- **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
|
|
60
|
-
- **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
|
|
61
73
|
- **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
|
|
62
|
-
- **Aim the POC at the load-bearing claim — not the easy part.**
|
|
74
|
+
- **Aim the POC at the load-bearing claim — not the easy part.** Cover the happy path and 2-3 common edges, but 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
|
|
63
75
|
- **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
|
|
64
76
|
- **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
|
|
65
|
-
- **
|
|
77
|
+
- **One module at a time.** Build the PRD's modules in order, never several at once. Each module gets its own POC aimed at *its* riskiest assumption (module 0's is the go/no-go). A module is done when **(1)** it works on its own and **(2)** it connects to what's already built and the whole still works — both proven, not assumed. Only then start the next
|
|
78
|
+
- **No fitting to pass.** Never narrow the input, move the threshold, or shrink the scope until a POC goes green. Report the failure and take it back to the PRD
|
|
66
79
|
|
|
67
80
|
### Dependency Hierarchy
|
|
68
81
|
|
|
@@ -106,6 +119,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
106
119
|
- Skipping POC validation for unproven ideas
|
|
107
120
|
- POC-ing only the easy part while hand-waving the risky mechanism, or claiming a cost ("cheap"/"fast"/"constant") you never measured
|
|
108
121
|
- 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
|
|
122
|
+
- Fitting a POC to pass (narrowed input, moved threshold, shrunk scope) instead of reporting the failure; starting module N+1 while module N is unproven
|
|
109
123
|
|
|
110
124
|
---
|
|
111
125
|
|
|
@@ -269,9 +283,9 @@ Copy this to any project's CLAUDE.md. These are mandatory rules, not suggestions
|
|
|
269
283
|
```markdown
|
|
270
284
|
## Dev Rules
|
|
271
285
|
|
|
272
|
-
**
|
|
286
|
+
**Spec first.** Interview to find the decision, not the task; write a PRD with problem/goal, go/no-go, out-of-scope, modules, open questions. POCs refine it.
|
|
273
287
|
|
|
274
|
-
**
|
|
288
|
+
**POC first, one module at a time.** Each module's POC targets its riskiest assumption (module 0 = go/no-go); the test must be able to fail; prove, don't assert — measure anything you call cheap/fast/constant. No fitting to pass. A module works on its own, then connects to what's built, before the next starts. Never ship the POC.
|
|
275
289
|
|
|
276
290
|
**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).
|
|
277
291
|
|
|
@@ -283,17 +297,3 @@ Copy this to any project's CLAUDE.md. These are mandatory rules, not suggestions
|
|
|
283
297
|
|
|
284
298
|
For full development and testing standards, see `.claude/remember/AGENT_RULES.md`.
|
|
285
299
|
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## AI Agent Instructions
|
|
290
|
-
|
|
291
|
-
When working with this user:
|
|
292
|
-
1. **Interview before building** — extract the real goal and surface load-bearing decisions for sign-off before you execute (see [Operating Flow](#operating-flow))
|
|
293
|
-
2. **Provide step-by-step** instructions with clear explanations
|
|
294
|
-
3. **Include ready-to-run** scripts and commands
|
|
295
|
-
4. **Explain the "why"** behind technical recommendations
|
|
296
|
-
5. **Flag potential issues** before they become problems — name the assumption, don't bury it
|
|
297
|
-
6. **Suggest simpler alternatives** when appropriate
|
|
298
|
-
7. **Ask first** before touching auth, DB schema/migrations, CI, or settings; **never** commit secrets
|
|
299
|
-
8. **Always identify** which files will be affected by changes
|
|
@@ -346,12 +346,13 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
|
|
|
346
346
|
inline duplication is needed
|
|
347
347
|
- If `.claude/remember/AGENT_RULES.md` exists (bootstrapped in step 1), compose a second,
|
|
348
348
|
independent section between `<!-- AGENT_RULES:START -->` and `<!-- AGENT_RULES:END -->`
|
|
349
|
-
markers
|
|
349
|
+
markers. Unlike MEMORY.md above, this is a **plain path pointer, never `@`-referenced**
|
|
350
|
+
— an `@`-reference hot-loads the whole file into every session, and this is a standards
|
|
351
|
+
guide to consult when designing/building something new, not hot context:
|
|
350
352
|
```
|
|
351
353
|
<!-- AGENT_RULES:START -->
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
@.claude/remember/AGENT_RULES.md
|
|
354
|
+
Standards guide (read when designing/building something new, not hot context):
|
|
355
|
+
.claude/remember/AGENT_RULES.md
|
|
355
356
|
<!-- AGENT_RULES:END -->
|
|
356
357
|
```
|
|
357
358
|
- Each marker pair is independent: if CLAUDE.md already has a given pair, replace the
|
|
@@ -411,11 +412,12 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
|
|
|
411
412
|
6. **Update processed manifest**
|
|
412
413
|
- Append paths of newly processed stashes to `.claude/remember/.processed`
|
|
413
414
|
|
|
414
|
-
7. **Docs reconcile check
|
|
415
|
+
7. **Docs reconcile check + auto re-index** (best-effort, crash-isolated like step 0)
|
|
415
416
|
|
|
416
|
-
`/remember` never reconciles
|
|
417
|
-
|
|
418
|
-
|
|
417
|
+
`/remember` never reconciles doc CONTENT, never writes frontmatter, never edits a page —
|
|
418
|
+
the only write here is the generated `docs/index.md` itself, via the same deterministic
|
|
419
|
+
`index-flat` script `/docs-builder` already uses, never a model call. Wrapped so any
|
|
420
|
+
failure here can never block the memory write that already happened in steps 3-6.
|
|
419
421
|
|
|
420
422
|
- **Locate `docs-builder.cjs`** — bundled next to this command at
|
|
421
423
|
`docs-builder/docs-builder.cjs` (same convention as `remember/friction.cjs`). Call it by
|
|
@@ -444,7 +446,19 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
|
|
|
444
446
|
- If `due` prints "no ledger yet" (no `docs/.docs-builder/ledger.json` to compare against),
|
|
445
447
|
do NOT relay it — print the same `/docs-builder reorg` line as the no-`docs/.docs-builder/`
|
|
446
448
|
case above, for the same reason: `ledger` would stamp an unsorted pile as correct.
|
|
447
|
-
-
|
|
449
|
+
- **Auto re-index — script only, no model, in addition to the DUE advisory below, not a
|
|
450
|
+
replacement for it.** If `due`'s output was NOT `docs unchanged since <sha>. NOT due.`
|
|
451
|
+
(i.e. it printed a row table -- any new/moved/moved+changed/changed/deleted doc, whether
|
|
452
|
+
or not the >=5 threshold below was crossed), the index has drifted and self-heals right
|
|
453
|
+
here, unconditionally:
|
|
454
|
+
```bash
|
|
455
|
+
node <docs-builder.cjs> index-flat
|
|
456
|
+
```
|
|
457
|
+
Same script `/docs-builder reorg` already calls, run standalone — no model call, no
|
|
458
|
+
interview, nothing moves. Note in the step-8 report that `docs/index.md` (and
|
|
459
|
+
`docs/log.md`, if `index-flat` touched it) were regenerated, so they are included
|
|
460
|
+
alongside whatever step 3-6 already changed when this run is committed.
|
|
461
|
+
- If DUE (the row count crossed the >=5 threshold), ALSO end with one line:
|
|
448
462
|
```
|
|
449
463
|
docs: 7 changed since 991f72d3 — run /docs-builder reorg
|
|
450
464
|
```
|
|
@@ -489,12 +503,14 @@ Reads all raw material (`.claude/stash/*.md` + `.claude/remember/friction/antige
|
|
|
489
503
|
ledger: ag-002 "literal scoped ask" ESCALATED → Fact; 2 phrasings failed. Hook or accept?
|
|
490
504
|
```
|
|
491
505
|
- If AGENT_RULES.md was bootstrapped this run, say so (one line)
|
|
506
|
+
- If step 7 ran the auto re-index, say so and name the regenerated files
|
|
507
|
+
(`docs/index.md`, plus `docs/log.md` if touched) so they are staged with this run
|
|
492
508
|
- Confirm MEMORY.md and CLAUDE.md updated
|
|
493
509
|
|
|
494
510
|
**File locations (all project-local — two dirs: `/stash` owns `.claude/stash/`, `/remember` owns `.claude/remember/`)**
|
|
495
511
|
- Stash files: `.claude/stash/*.md`
|
|
496
512
|
- Memory file: `.claude/remember/MEMORY.md` (single source of truth, referenced as `@.claude/remember/MEMORY.md`)
|
|
497
|
-
- Rules template: `.claude/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced
|
|
513
|
+
- Rules template: `.claude/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced by a plain path pointer, not `@`-referenced — see step 5)
|
|
498
514
|
- Antigen ledger: `.claude/remember/ledger.json` (per-rule evidence trail: class, status, attempts/rejected-buffer, recurrence-while-hot)
|
|
499
515
|
- Consolidation report: `.claude/remember/report.md` (latest step-8 report, overwritten each run)
|
|
500
516
|
- Processed manifest: `.claude/remember/.processed`
|
|
@@ -728,14 +728,33 @@ function plan(outlineF, labelsF) {
|
|
|
728
728
|
// tripwire, never a prune, never a collapse, never a delete.
|
|
729
729
|
const ARCHIVE_WARN_ROWS = 100; // stated default, not measured — see docs-builder-v3-spec.md
|
|
730
730
|
|
|
731
|
-
|
|
731
|
+
// `includeH2` is false for archive rows: an archived doc is frozen history, not a live
|
|
732
|
+
// section a reader is being routed into, so its row stays H1 + line count + link only.
|
|
733
|
+
function indexRow(rel, dest, includeH2) {
|
|
732
734
|
const text = read(rel);
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
+
const lines = text.split('\n');
|
|
736
|
+
// Same headings()+fenceMask() path scan() uses -- no second parser -- so an H2 inside a
|
|
737
|
+
// ``` fence is masked out here exactly as it is there.
|
|
738
|
+
const mask = fenceMask(lines);
|
|
739
|
+
const { h1, heads } = headings(lines, mask);
|
|
735
740
|
// Read from INSIDE index.md, so the link must resolve relative to index.md's own
|
|
736
741
|
// directory, not the repo root.
|
|
737
742
|
const relLink = path.relative(path.dirname(dest), repoPath(rel)).split(path.sep).join('/');
|
|
738
|
-
|
|
743
|
+
let row = `- [${h1 || path.basename(rel)}](${relLink}) — ${lines.length} lines\n`;
|
|
744
|
+
if (!includeH2) return row;
|
|
745
|
+
// One line per H2, each with its own line range: from the `## ` heading's own 1-based
|
|
746
|
+
// line through the line before the next heading of level <= 2 (H1 or H2), or EOF for the
|
|
747
|
+
// last one -- the SAME boundary scan() uses to write s/e into outline.json, re-derived
|
|
748
|
+
// here from the same heads array rather than duplicated as a second computation. Lets an
|
|
749
|
+
// agent jump straight to (and slice-read) a section without opening the doc at all.
|
|
750
|
+
const boundaries = heads.filter(h => h.lvl <= 2);
|
|
751
|
+
boundaries.forEach((h, i) => {
|
|
752
|
+
if (h.lvl !== 2) return;
|
|
753
|
+
const start = h.line;
|
|
754
|
+
const end = i + 1 < boundaries.length ? boundaries[i + 1].line - 1 : lines.length;
|
|
755
|
+
row += ` - ${h.text} (L${start}–${end})\n`;
|
|
756
|
+
});
|
|
757
|
+
return row;
|
|
739
758
|
}
|
|
740
759
|
|
|
741
760
|
function renderSection(title, rows) {
|
|
@@ -767,9 +786,10 @@ function indexFlat() {
|
|
|
767
786
|
const outRel = process.env.OUT || 'docs/index.md';
|
|
768
787
|
const dest = repoPath(outRel);
|
|
769
788
|
const productRows = [...productFiles, ...pageFiles].sort()
|
|
770
|
-
.map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
771
|
-
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
772
|
-
|
|
789
|
+
.map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
790
|
+
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
791
|
+
// Archive rows are deliberately H1-only -- frozen history, not a live section to route into.
|
|
792
|
+
const archiveRows = archiveFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, false) }));
|
|
773
793
|
|
|
774
794
|
let s = '# Index\n\n';
|
|
775
795
|
// Unconditional — not gated on row count, unlike ARCHIVE_WARN_ROWS below: a reader should
|
|
@@ -747,7 +747,13 @@ Writes **one** `docs/index.md` covering the whole corpus, in three sections: `##
|
|
|
747
747
|
(one row per file under `docs/product/`, plus any pages under `PAGES` — default `docs/wiki/`
|
|
748
748
|
— if they exist, plus any doc still sitting in place elsewhere), `## Logs` (one row per file
|
|
749
749
|
under `docs/logs/`), and `## Archive` (one row per file under `docs/archive/`). Each row is
|
|
750
|
-
an H1 title, a line count, and a link
|
|
750
|
+
an H1 title, a line count, and a link, plus one indented line per H2 heading (in document
|
|
751
|
+
order) so an agent can find and slice-read a section without opening the doc — each H2
|
|
752
|
+
line carries its own `(Lstart–end)` line range, reusing the SAME `headings()`+`fenceMask()`
|
|
753
|
+
boundaries `scan` already writes to `outline.json` (no second parser). Omitted when the doc
|
|
754
|
+
has no H2s. `## Archive` rows are H1-only, never H2 lines — an archived doc is frozen
|
|
755
|
+
history, not a live section to route into. No theme grouping, no `labels.json`, no model
|
|
756
|
+
call.
|
|
751
757
|
Default destination `docs/index.md` — **the only writer of that default path** in this whole
|
|
752
758
|
pipeline (nothing else writes an index at all).
|
|
753
759
|
`search` reads `outline.json`, never `index.md`. Prints the row counts and records a `log.md`
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
7. [Development Workflow](#development-workflow)
|
|
11
11
|
8. [Twelve-Factor Checklist](#twelve-factor-checklist)
|
|
12
12
|
9. [AGENTS.md Stub](#agentsmd-stub)
|
|
13
|
-
10. [AI Agent Instructions](#ai-agent-instructions)
|
|
14
13
|
|
|
15
14
|
---
|
|
16
15
|
|
|
@@ -18,10 +17,25 @@
|
|
|
18
17
|
|
|
19
18
|
Every task runs through three layers. Do not skip ahead to code.
|
|
20
19
|
|
|
21
|
-
1. **Spec —
|
|
22
|
-
|
|
20
|
+
1. **Spec — the interview must happen; its shape is yours.** Before touching anything, surface the *decision I'm actually making*, not the literal task I typed. Ask what you need to know — no more; how you ask is your call. Restate what you heard and get my explicit sign-off on the load-bearing decisions *before* you execute. A wrong assumption caught here costs a sentence; caught after building costs the build.
|
|
21
|
+
|
|
22
|
+
Write the outcome down as a **PRD**. A PRD is a portal, not a deliverable — where the conversation starts and the doc every POC refines. Minimum content, whatever the form:
|
|
23
|
+
- **Problem & goal** — what we're solving and why now
|
|
24
|
+
- **Go / no-go** — the 1–2 capabilities the product stands or falls on; usually module 0's riskiest assumption (e.g. "can a phone camera read the ID?"). Fails → stop
|
|
25
|
+
- **Out of scope** — what we're explicitly not doing
|
|
26
|
+
- **Modules** — the pieces to build, in order (see [*One module at a time*](#validate-before-you-build))
|
|
27
|
+
- **Open questions** — unknowns that don't block; never silently assumed
|
|
28
|
+
|
|
29
|
+
Every POC result updates the PRD; one that flips the go/no-go or a module's assumption is a spec change, not a footnote.
|
|
30
|
+
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`. When the work is done, propose `/code-review` and then `/release` — you never merge or release on your own (see [Required Safeguards](#required-safeguards-always--ask--never)). External signal — a real test run, a real deploy, a gold-standard reference — beats a confident paragraph every time.
|
|
23
31
|
3. **Environment — the standing context.** This file primes every session. Critical-path protections (secrets, auth, schema, CI) are stated as **Always / Ask / Never** below and bind you as written. Where your tool offers a permission allow/ask/deny list, mirror them there so they are enforced and not merely requested.
|
|
24
32
|
|
|
33
|
+
**Execution order — work the way a program runs, in this order, nothing skipped:**
|
|
34
|
+
1. **Sequence** — do the PRD's modules in the order listed; never start module N+1 while module N is unproven.
|
|
35
|
+
2. **Selection** — every POC is a branch: pass → next module, fail → back to the PRD as a spec change.
|
|
36
|
+
3. **Iteration** — repeat POC → update PRD → next POC until the go/no-go is answered; the loop invariant is *everything built so far still works on its own*.
|
|
37
|
+
4. **Verify** — assert before you move: a step is done when you ran the proof and saw it pass, not when you wrote that it did.
|
|
38
|
+
|
|
25
39
|
> 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.
|
|
26
40
|
|
|
27
41
|
---
|
|
@@ -29,16 +43,14 @@ Every task runs through three layers. Do not skip ahead to code.
|
|
|
29
43
|
## Communication Protocol
|
|
30
44
|
|
|
31
45
|
### Core Rules
|
|
32
|
-
- **Spec
|
|
33
|
-
- **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
|
|
46
|
+
- **Spec first, then checkpoint**: see [Operating Flow §1](#operating-flow). Never run ahead on an unverified assumption — flag it and stop
|
|
34
47
|
- **Fact-Based**: Base all recommendations on verified, current information. Prefer external signal (a real run, a real source) over a confident guess
|
|
35
48
|
- **Simplicity Advocate**: Call out overcomplications and suggest simpler alternatives
|
|
36
|
-
- **Safety First**: Never modify critical systems without explicit understanding and approval
|
|
37
49
|
|
|
38
50
|
### User Profile
|
|
39
51
|
- **Technical Level**: Non-coder but technically savvy
|
|
40
52
|
- **Learning Style**: Understands concepts, needs executable instructions
|
|
41
|
-
- **Expects**: Step-by-step guidance
|
|
53
|
+
- **Expects**: Step-by-step guidance, ready-to-run commands, and the *why* behind each recommendation
|
|
42
54
|
- **Comfortable with**: Command-line operations and scripts
|
|
43
55
|
- **Builds a lot of web apps** — assume any UI work will be consumed on phones as well as desktop
|
|
44
56
|
|
|
@@ -49,6 +61,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
49
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
50
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.factory/settings.json`
|
|
51
63
|
- **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
|
|
64
|
+
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/code-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
52
65
|
|
|
53
66
|
---
|
|
54
67
|
|
|
@@ -57,12 +70,12 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
57
70
|
### Validate Before You Build
|
|
58
71
|
|
|
59
72
|
- **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
|
|
60
|
-
- **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
|
|
61
73
|
- **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
|
|
62
|
-
- **Aim the POC at the load-bearing claim — not the easy part.**
|
|
74
|
+
- **Aim the POC at the load-bearing claim — not the easy part.** Cover the happy path and 2-3 common edges, but 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
|
|
63
75
|
- **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
|
|
64
76
|
- **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
|
|
65
|
-
- **
|
|
77
|
+
- **One module at a time.** Build the PRD's modules in order, never several at once. Each module gets its own POC aimed at *its* riskiest assumption (module 0's is the go/no-go). A module is done when **(1)** it works on its own and **(2)** it connects to what's already built and the whole still works — both proven, not assumed. Only then start the next
|
|
78
|
+
- **No fitting to pass.** Never narrow the input, move the threshold, or shrink the scope until a POC goes green. Report the failure and take it back to the PRD
|
|
66
79
|
|
|
67
80
|
### Dependency Hierarchy
|
|
68
81
|
|
|
@@ -106,6 +119,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
106
119
|
- Skipping POC validation for unproven ideas
|
|
107
120
|
- POC-ing only the easy part while hand-waving the risky mechanism, or claiming a cost ("cheap"/"fast"/"constant") you never measured
|
|
108
121
|
- 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
|
|
122
|
+
- Fitting a POC to pass (narrowed input, moved threshold, shrunk scope) instead of reporting the failure; starting module N+1 while module N is unproven
|
|
109
123
|
|
|
110
124
|
---
|
|
111
125
|
|
|
@@ -269,9 +283,9 @@ Copy this to any project's AGENTS.md. These are mandatory rules, not suggestions
|
|
|
269
283
|
```markdown
|
|
270
284
|
## Dev Rules
|
|
271
285
|
|
|
272
|
-
**
|
|
286
|
+
**Spec first.** Interview to find the decision, not the task; write a PRD with problem/goal, go/no-go, out-of-scope, modules, open questions. POCs refine it.
|
|
273
287
|
|
|
274
|
-
**
|
|
288
|
+
**POC first, one module at a time.** Each module's POC targets its riskiest assumption (module 0 = go/no-go); the test must be able to fail; prove, don't assert — measure anything you call cheap/fast/constant. No fitting to pass. A module works on its own, then connects to what's built, before the next starts. Never ship the POC.
|
|
275
289
|
|
|
276
290
|
**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).
|
|
277
291
|
|
|
@@ -283,17 +297,3 @@ Copy this to any project's AGENTS.md. These are mandatory rules, not suggestions
|
|
|
283
297
|
|
|
284
298
|
For full development and testing standards, see `.factory/remember/AGENT_RULES.md`.
|
|
285
299
|
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## AI Agent Instructions
|
|
290
|
-
|
|
291
|
-
When working with this user:
|
|
292
|
-
1. **Interview before building** — extract the real goal and surface load-bearing decisions for sign-off before you execute (see [Operating Flow](#operating-flow))
|
|
293
|
-
2. **Provide step-by-step** instructions with clear explanations
|
|
294
|
-
3. **Include ready-to-run** scripts and commands
|
|
295
|
-
4. **Explain the "why"** behind technical recommendations
|
|
296
|
-
5. **Flag potential issues** before they become problems — name the assumption, don't bury it
|
|
297
|
-
6. **Suggest simpler alternatives** when appropriate
|
|
298
|
-
7. **Ask first** before touching auth, DB schema/migrations, CI, or settings; **never** commit secrets
|
|
299
|
-
8. **Always identify** which files will be affected by changes
|
|
@@ -346,12 +346,13 @@ Reads all raw material (`.factory/stash/*.md` + `.factory/remember/friction/anti
|
|
|
346
346
|
inline duplication is needed
|
|
347
347
|
- If `.factory/remember/AGENT_RULES.md` exists (bootstrapped in step 1), compose a second,
|
|
348
348
|
independent section between `<!-- AGENT_RULES:START -->` and `<!-- AGENT_RULES:END -->`
|
|
349
|
-
markers
|
|
349
|
+
markers. Unlike MEMORY.md above, this is a **plain path pointer, never `@`-referenced**
|
|
350
|
+
— an `@`-reference hot-loads the whole file into every session, and this is a standards
|
|
351
|
+
guide to consult when designing/building something new, not hot context:
|
|
350
352
|
```
|
|
351
353
|
<!-- AGENT_RULES:START -->
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
@.factory/remember/AGENT_RULES.md
|
|
354
|
+
Standards guide (read when designing/building something new, not hot context):
|
|
355
|
+
.factory/remember/AGENT_RULES.md
|
|
355
356
|
<!-- AGENT_RULES:END -->
|
|
356
357
|
```
|
|
357
358
|
- Each marker pair is independent: if AGENTS.md already has a given pair, replace the
|
|
@@ -411,11 +412,12 @@ Reads all raw material (`.factory/stash/*.md` + `.factory/remember/friction/anti
|
|
|
411
412
|
6. **Update processed manifest**
|
|
412
413
|
- Append paths of newly processed stashes to `.factory/remember/.processed`
|
|
413
414
|
|
|
414
|
-
7. **Docs reconcile check
|
|
415
|
+
7. **Docs reconcile check + auto re-index** (best-effort, crash-isolated like step 0)
|
|
415
416
|
|
|
416
|
-
`/remember` never reconciles
|
|
417
|
-
|
|
418
|
-
|
|
417
|
+
`/remember` never reconciles doc CONTENT, never writes frontmatter, never edits a page —
|
|
418
|
+
the only write here is the generated `docs/index.md` itself, via the same deterministic
|
|
419
|
+
`index-flat` script `/docs-builder` already uses, never a model call. Wrapped so any
|
|
420
|
+
failure here can never block the memory write that already happened in steps 3-6.
|
|
419
421
|
|
|
420
422
|
- **Locate `docs-builder.cjs`** — bundled next to this command at
|
|
421
423
|
`docs-builder/docs-builder.cjs` (same convention as `remember/friction.cjs`). Call it by
|
|
@@ -444,7 +446,19 @@ Reads all raw material (`.factory/stash/*.md` + `.factory/remember/friction/anti
|
|
|
444
446
|
- If `due` prints "no ledger yet" (no `docs/.docs-builder/ledger.json` to compare against),
|
|
445
447
|
do NOT relay it — print the same `/docs-builder reorg` line as the no-`docs/.docs-builder/`
|
|
446
448
|
case above, for the same reason: `ledger` would stamp an unsorted pile as correct.
|
|
447
|
-
-
|
|
449
|
+
- **Auto re-index — script only, no model, in addition to the DUE advisory below, not a
|
|
450
|
+
replacement for it.** If `due`'s output was NOT `docs unchanged since <sha>. NOT due.`
|
|
451
|
+
(i.e. it printed a row table -- any new/moved/moved+changed/changed/deleted doc, whether
|
|
452
|
+
or not the >=5 threshold below was crossed), the index has drifted and self-heals right
|
|
453
|
+
here, unconditionally:
|
|
454
|
+
```bash
|
|
455
|
+
node <docs-builder.cjs> index-flat
|
|
456
|
+
```
|
|
457
|
+
Same script `/docs-builder reorg` already calls, run standalone — no model call, no
|
|
458
|
+
interview, nothing moves. Note in the step-8 report that `docs/index.md` (and
|
|
459
|
+
`docs/log.md`, if `index-flat` touched it) were regenerated, so they are included
|
|
460
|
+
alongside whatever step 3-6 already changed when this run is committed.
|
|
461
|
+
- If DUE (the row count crossed the >=5 threshold), ALSO end with one line:
|
|
448
462
|
```
|
|
449
463
|
docs: 7 changed since 991f72d3 — run /docs-builder reorg
|
|
450
464
|
```
|
|
@@ -489,12 +503,14 @@ Reads all raw material (`.factory/stash/*.md` + `.factory/remember/friction/anti
|
|
|
489
503
|
ledger: ag-002 "literal scoped ask" ESCALATED → Fact; 2 phrasings failed. Hook or accept?
|
|
490
504
|
```
|
|
491
505
|
- If AGENT_RULES.md was bootstrapped this run, say so (one line)
|
|
506
|
+
- If step 7 ran the auto re-index, say so and name the regenerated files
|
|
507
|
+
(`docs/index.md`, plus `docs/log.md` if touched) so they are staged with this run
|
|
492
508
|
- Confirm MEMORY.md and AGENTS.md updated
|
|
493
509
|
|
|
494
510
|
**File locations (all project-local — two dirs: `/stash` owns `.factory/stash/`, `/remember` owns `.factory/remember/`)**
|
|
495
511
|
- Stash files: `.factory/stash/*.md`
|
|
496
512
|
- Memory file: `.factory/remember/MEMORY.md` (single source of truth, referenced as `@.factory/remember/MEMORY.md`)
|
|
497
|
-
- Rules template: `.factory/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced
|
|
513
|
+
- Rules template: `.factory/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced by a plain path pointer, not `@`-referenced — see step 5)
|
|
498
514
|
- Antigen ledger: `.factory/remember/ledger.json` (per-rule evidence trail: class, status, attempts/rejected-buffer, recurrence-while-hot)
|
|
499
515
|
- Consolidation report: `.factory/remember/report.md` (latest step-8 report, overwritten each run)
|
|
500
516
|
- Processed manifest: `.factory/remember/.processed`
|
|
@@ -728,14 +728,33 @@ function plan(outlineF, labelsF) {
|
|
|
728
728
|
// tripwire, never a prune, never a collapse, never a delete.
|
|
729
729
|
const ARCHIVE_WARN_ROWS = 100; // stated default, not measured — see docs-builder-v3-spec.md
|
|
730
730
|
|
|
731
|
-
|
|
731
|
+
// `includeH2` is false for archive rows: an archived doc is frozen history, not a live
|
|
732
|
+
// section a reader is being routed into, so its row stays H1 + line count + link only.
|
|
733
|
+
function indexRow(rel, dest, includeH2) {
|
|
732
734
|
const text = read(rel);
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
+
const lines = text.split('\n');
|
|
736
|
+
// Same headings()+fenceMask() path scan() uses -- no second parser -- so an H2 inside a
|
|
737
|
+
// ``` fence is masked out here exactly as it is there.
|
|
738
|
+
const mask = fenceMask(lines);
|
|
739
|
+
const { h1, heads } = headings(lines, mask);
|
|
735
740
|
// Read from INSIDE index.md, so the link must resolve relative to index.md's own
|
|
736
741
|
// directory, not the repo root.
|
|
737
742
|
const relLink = path.relative(path.dirname(dest), repoPath(rel)).split(path.sep).join('/');
|
|
738
|
-
|
|
743
|
+
let row = `- [${h1 || path.basename(rel)}](${relLink}) — ${lines.length} lines\n`;
|
|
744
|
+
if (!includeH2) return row;
|
|
745
|
+
// One line per H2, each with its own line range: from the `## ` heading's own 1-based
|
|
746
|
+
// line through the line before the next heading of level <= 2 (H1 or H2), or EOF for the
|
|
747
|
+
// last one -- the SAME boundary scan() uses to write s/e into outline.json, re-derived
|
|
748
|
+
// here from the same heads array rather than duplicated as a second computation. Lets an
|
|
749
|
+
// agent jump straight to (and slice-read) a section without opening the doc at all.
|
|
750
|
+
const boundaries = heads.filter(h => h.lvl <= 2);
|
|
751
|
+
boundaries.forEach((h, i) => {
|
|
752
|
+
if (h.lvl !== 2) return;
|
|
753
|
+
const start = h.line;
|
|
754
|
+
const end = i + 1 < boundaries.length ? boundaries[i + 1].line - 1 : lines.length;
|
|
755
|
+
row += ` - ${h.text} (L${start}–${end})\n`;
|
|
756
|
+
});
|
|
757
|
+
return row;
|
|
739
758
|
}
|
|
740
759
|
|
|
741
760
|
function renderSection(title, rows) {
|
|
@@ -767,9 +786,10 @@ function indexFlat() {
|
|
|
767
786
|
const outRel = process.env.OUT || 'docs/index.md';
|
|
768
787
|
const dest = repoPath(outRel);
|
|
769
788
|
const productRows = [...productFiles, ...pageFiles].sort()
|
|
770
|
-
.map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
771
|
-
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest) }));
|
|
772
|
-
|
|
789
|
+
.map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
790
|
+
const logsRows = logsFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, true) }));
|
|
791
|
+
// Archive rows are deliberately H1-only -- frozen history, not a live section to route into.
|
|
792
|
+
const archiveRows = archiveFiles.sort().map(f => ({ file: f, row: indexRow(f, dest, false) }));
|
|
773
793
|
|
|
774
794
|
let s = '# Index\n\n';
|
|
775
795
|
// Unconditional — not gated on row count, unlike ARCHIVE_WARN_ROWS below: a reader should
|
|
@@ -747,7 +747,13 @@ Writes **one** `docs/index.md` covering the whole corpus, in three sections: `##
|
|
|
747
747
|
(one row per file under `docs/product/`, plus any pages under `PAGES` — default `docs/wiki/`
|
|
748
748
|
— if they exist, plus any doc still sitting in place elsewhere), `## Logs` (one row per file
|
|
749
749
|
under `docs/logs/`), and `## Archive` (one row per file under `docs/archive/`). Each row is
|
|
750
|
-
an H1 title, a line count, and a link
|
|
750
|
+
an H1 title, a line count, and a link, plus one indented line per H2 heading (in document
|
|
751
|
+
order) so an agent can find and slice-read a section without opening the doc — each H2
|
|
752
|
+
line carries its own `(Lstart–end)` line range, reusing the SAME `headings()`+`fenceMask()`
|
|
753
|
+
boundaries `scan` already writes to `outline.json` (no second parser). Omitted when the doc
|
|
754
|
+
has no H2s. `## Archive` rows are H1-only, never H2 lines — an archived doc is frozen
|
|
755
|
+
history, not a live section to route into. No theme grouping, no `labels.json`, no model
|
|
756
|
+
call.
|
|
751
757
|
Default destination `docs/index.md` — **the only writer of that default path** in this whole
|
|
752
758
|
pipeline (nothing else writes an index at all).
|
|
753
759
|
`search` reads `outline.json`, never `index.md`. Prints the row counts and records a `log.md`
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
7. [Development Workflow](#development-workflow)
|
|
11
11
|
8. [Twelve-Factor Checklist](#twelve-factor-checklist)
|
|
12
12
|
9. [AGENTS.md Stub](#agentsmd-stub)
|
|
13
|
-
10. [AI Agent Instructions](#ai-agent-instructions)
|
|
14
13
|
|
|
15
14
|
---
|
|
16
15
|
|
|
@@ -18,10 +17,25 @@
|
|
|
18
17
|
|
|
19
18
|
Every task runs through three layers. Do not skip ahead to code.
|
|
20
19
|
|
|
21
|
-
1. **Spec —
|
|
22
|
-
|
|
20
|
+
1. **Spec — the interview must happen; its shape is yours.** Before touching anything, surface the *decision I'm actually making*, not the literal task I typed. Ask what you need to know — no more; how you ask is your call. Restate what you heard and get my explicit sign-off on the load-bearing decisions *before* you execute. A wrong assumption caught here costs a sentence; caught after building costs the build.
|
|
21
|
+
|
|
22
|
+
Write the outcome down as a **PRD**. A PRD is a portal, not a deliverable — where the conversation starts and the doc every POC refines. Minimum content, whatever the form:
|
|
23
|
+
- **Problem & goal** — what we're solving and why now
|
|
24
|
+
- **Go / no-go** — the 1–2 capabilities the product stands or falls on; usually module 0's riskiest assumption (e.g. "can a phone camera read the ID?"). Fails → stop
|
|
25
|
+
- **Out of scope** — what we're explicitly not doing
|
|
26
|
+
- **Modules** — the pieces to build, in order (see [*One module at a time*](#validate-before-you-build))
|
|
27
|
+
- **Open questions** — unknowns that don't block; never silently assumed
|
|
28
|
+
|
|
29
|
+
Every POC result updates the PRD; one that flips the go/no-go or a module's assumption is a spec change, not a footnote.
|
|
30
|
+
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`. When the work is done, propose `/code-review` and then `/release` — you never merge or release on your own (see [Required Safeguards](#required-safeguards-always--ask--never)). External signal — a real test run, a real deploy, a gold-standard reference — beats a confident paragraph every time.
|
|
23
31
|
3. **Environment — the standing context.** This file primes every session. Critical-path protections (secrets, auth, schema, CI) are stated as **Always / Ask / Never** below and bind you as written. Where your tool offers a permission allow/ask/deny list, mirror them there so they are enforced and not merely requested.
|
|
24
32
|
|
|
33
|
+
**Execution order — work the way a program runs, in this order, nothing skipped:**
|
|
34
|
+
1. **Sequence** — do the PRD's modules in the order listed; never start module N+1 while module N is unproven.
|
|
35
|
+
2. **Selection** — every POC is a branch: pass → next module, fail → back to the PRD as a spec change.
|
|
36
|
+
3. **Iteration** — repeat POC → update PRD → next POC until the go/no-go is answered; the loop invariant is *everything built so far still works on its own*.
|
|
37
|
+
4. **Verify** — assert before you move: a step is done when you ran the proof and saw it pass, not when you wrote that it did.
|
|
38
|
+
|
|
25
39
|
> 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.
|
|
26
40
|
|
|
27
41
|
---
|
|
@@ -29,16 +43,14 @@ Every task runs through three layers. Do not skip ahead to code.
|
|
|
29
43
|
## Communication Protocol
|
|
30
44
|
|
|
31
45
|
### Core Rules
|
|
32
|
-
- **Spec
|
|
33
|
-
- **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
|
|
46
|
+
- **Spec first, then checkpoint**: see [Operating Flow §1](#operating-flow). Never run ahead on an unverified assumption — flag it and stop
|
|
34
47
|
- **Fact-Based**: Base all recommendations on verified, current information. Prefer external signal (a real run, a real source) over a confident guess
|
|
35
48
|
- **Simplicity Advocate**: Call out overcomplications and suggest simpler alternatives
|
|
36
|
-
- **Safety First**: Never modify critical systems without explicit understanding and approval
|
|
37
49
|
|
|
38
50
|
### User Profile
|
|
39
51
|
- **Technical Level**: Non-coder but technically savvy
|
|
40
52
|
- **Learning Style**: Understands concepts, needs executable instructions
|
|
41
|
-
- **Expects**: Step-by-step guidance
|
|
53
|
+
- **Expects**: Step-by-step guidance, ready-to-run commands, and the *why* behind each recommendation
|
|
42
54
|
- **Comfortable with**: Command-line operations and scripts
|
|
43
55
|
- **Builds a lot of web apps** — assume any UI work will be consumed on phones as well as desktop
|
|
44
56
|
|
|
@@ -49,6 +61,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
49
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
50
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.opencode/settings.json`
|
|
51
63
|
- **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
|
|
64
|
+
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/code-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
52
65
|
|
|
53
66
|
---
|
|
54
67
|
|
|
@@ -57,12 +70,12 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
57
70
|
### Validate Before You Build
|
|
58
71
|
|
|
59
72
|
- **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
|
|
60
|
-
- **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
|
|
61
73
|
- **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
|
|
62
|
-
- **Aim the POC at the load-bearing claim — not the easy part.**
|
|
74
|
+
- **Aim the POC at the load-bearing claim — not the easy part.** Cover the happy path and 2-3 common edges, but 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
|
|
63
75
|
- **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
|
|
64
76
|
- **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
|
|
65
|
-
- **
|
|
77
|
+
- **One module at a time.** Build the PRD's modules in order, never several at once. Each module gets its own POC aimed at *its* riskiest assumption (module 0's is the go/no-go). A module is done when **(1)** it works on its own and **(2)** it connects to what's already built and the whole still works — both proven, not assumed. Only then start the next
|
|
78
|
+
- **No fitting to pass.** Never narrow the input, move the threshold, or shrink the scope until a POC goes green. Report the failure and take it back to the PRD
|
|
66
79
|
|
|
67
80
|
### Dependency Hierarchy
|
|
68
81
|
|
|
@@ -106,6 +119,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
106
119
|
- Skipping POC validation for unproven ideas
|
|
107
120
|
- POC-ing only the easy part while hand-waving the risky mechanism, or claiming a cost ("cheap"/"fast"/"constant") you never measured
|
|
108
121
|
- 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
|
|
122
|
+
- Fitting a POC to pass (narrowed input, moved threshold, shrunk scope) instead of reporting the failure; starting module N+1 while module N is unproven
|
|
109
123
|
|
|
110
124
|
---
|
|
111
125
|
|
|
@@ -269,9 +283,9 @@ Copy this to any project's AGENTS.md. These are mandatory rules, not suggestions
|
|
|
269
283
|
```markdown
|
|
270
284
|
## Dev Rules
|
|
271
285
|
|
|
272
|
-
**
|
|
286
|
+
**Spec first.** Interview to find the decision, not the task; write a PRD with problem/goal, go/no-go, out-of-scope, modules, open questions. POCs refine it.
|
|
273
287
|
|
|
274
|
-
**
|
|
288
|
+
**POC first, one module at a time.** Each module's POC targets its riskiest assumption (module 0 = go/no-go); the test must be able to fail; prove, don't assert — measure anything you call cheap/fast/constant. No fitting to pass. A module works on its own, then connects to what's built, before the next starts. Never ship the POC.
|
|
275
289
|
|
|
276
290
|
**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).
|
|
277
291
|
|
|
@@ -283,17 +297,3 @@ Copy this to any project's AGENTS.md. These are mandatory rules, not suggestions
|
|
|
283
297
|
|
|
284
298
|
For full development and testing standards, see `.opencode/remember/AGENT_RULES.md`.
|
|
285
299
|
```
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## AI Agent Instructions
|
|
290
|
-
|
|
291
|
-
When working with this user:
|
|
292
|
-
1. **Interview before building** — extract the real goal and surface load-bearing decisions for sign-off before you execute (see [Operating Flow](#operating-flow))
|
|
293
|
-
2. **Provide step-by-step** instructions with clear explanations
|
|
294
|
-
3. **Include ready-to-run** scripts and commands
|
|
295
|
-
4. **Explain the "why"** behind technical recommendations
|
|
296
|
-
5. **Flag potential issues** before they become problems — name the assumption, don't bury it
|
|
297
|
-
6. **Suggest simpler alternatives** when appropriate
|
|
298
|
-
7. **Ask first** before touching auth, DB schema/migrations, CI, or settings; **never** commit secrets
|
|
299
|
-
8. **Always identify** which files will be affected by changes
|
|
@@ -346,12 +346,13 @@ Reads all raw material (`.opencode/stash/*.md` + `.opencode/remember/friction/an
|
|
|
346
346
|
inline duplication is needed
|
|
347
347
|
- If `.opencode/remember/AGENT_RULES.md` exists (bootstrapped in step 1), compose a second,
|
|
348
348
|
independent section between `<!-- AGENT_RULES:START -->` and `<!-- AGENT_RULES:END -->`
|
|
349
|
-
markers
|
|
349
|
+
markers. Unlike MEMORY.md above, this is a **plain path pointer, never `@`-referenced**
|
|
350
|
+
— an `@`-reference hot-loads the whole file into every session, and this is a standards
|
|
351
|
+
guide to consult when designing/building something new, not hot context:
|
|
350
352
|
```
|
|
351
353
|
<!-- AGENT_RULES:START -->
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
@.opencode/remember/AGENT_RULES.md
|
|
354
|
+
Standards guide (read when designing/building something new, not hot context):
|
|
355
|
+
.opencode/remember/AGENT_RULES.md
|
|
355
356
|
<!-- AGENT_RULES:END -->
|
|
356
357
|
```
|
|
357
358
|
- Each marker pair is independent: if AGENTS.md already has a given pair, replace the
|
|
@@ -411,11 +412,12 @@ Reads all raw material (`.opencode/stash/*.md` + `.opencode/remember/friction/an
|
|
|
411
412
|
6. **Update processed manifest**
|
|
412
413
|
- Append paths of newly processed stashes to `.opencode/remember/.processed`
|
|
413
414
|
|
|
414
|
-
7. **Docs reconcile check
|
|
415
|
+
7. **Docs reconcile check + auto re-index** (best-effort, crash-isolated like step 0)
|
|
415
416
|
|
|
416
|
-
`/remember` never reconciles
|
|
417
|
-
|
|
418
|
-
|
|
417
|
+
`/remember` never reconciles doc CONTENT, never writes frontmatter, never edits a page —
|
|
418
|
+
the only write here is the generated `docs/index.md` itself, via the same deterministic
|
|
419
|
+
`index-flat` script `/docs-builder` already uses, never a model call. Wrapped so any
|
|
420
|
+
failure here can never block the memory write that already happened in steps 3-6.
|
|
419
421
|
|
|
420
422
|
- **Locate `docs-builder.cjs`** — bundled next to this command at
|
|
421
423
|
`docs-builder/docs-builder.cjs` (same convention as `remember/friction.cjs`). Call it by
|
|
@@ -444,7 +446,19 @@ Reads all raw material (`.opencode/stash/*.md` + `.opencode/remember/friction/an
|
|
|
444
446
|
- If `due` prints "no ledger yet" (no `docs/.docs-builder/ledger.json` to compare against),
|
|
445
447
|
do NOT relay it — print the same `/docs-builder reorg` line as the no-`docs/.docs-builder/`
|
|
446
448
|
case above, for the same reason: `ledger` would stamp an unsorted pile as correct.
|
|
447
|
-
-
|
|
449
|
+
- **Auto re-index — script only, no model, in addition to the DUE advisory below, not a
|
|
450
|
+
replacement for it.** If `due`'s output was NOT `docs unchanged since <sha>. NOT due.`
|
|
451
|
+
(i.e. it printed a row table -- any new/moved/moved+changed/changed/deleted doc, whether
|
|
452
|
+
or not the >=5 threshold below was crossed), the index has drifted and self-heals right
|
|
453
|
+
here, unconditionally:
|
|
454
|
+
```bash
|
|
455
|
+
node <docs-builder.cjs> index-flat
|
|
456
|
+
```
|
|
457
|
+
Same script `/docs-builder reorg` already calls, run standalone — no model call, no
|
|
458
|
+
interview, nothing moves. Note in the step-8 report that `docs/index.md` (and
|
|
459
|
+
`docs/log.md`, if `index-flat` touched it) were regenerated, so they are included
|
|
460
|
+
alongside whatever step 3-6 already changed when this run is committed.
|
|
461
|
+
- If DUE (the row count crossed the >=5 threshold), ALSO end with one line:
|
|
448
462
|
```
|
|
449
463
|
docs: 7 changed since 991f72d3 — run /docs-builder reorg
|
|
450
464
|
```
|
|
@@ -489,12 +503,14 @@ Reads all raw material (`.opencode/stash/*.md` + `.opencode/remember/friction/an
|
|
|
489
503
|
ledger: ag-002 "literal scoped ask" ESCALATED → Fact; 2 phrasings failed. Hook or accept?
|
|
490
504
|
```
|
|
491
505
|
- If AGENT_RULES.md was bootstrapped this run, say so (one line)
|
|
506
|
+
- If step 7 ran the auto re-index, say so and name the regenerated files
|
|
507
|
+
(`docs/index.md`, plus `docs/log.md` if touched) so they are staged with this run
|
|
492
508
|
- Confirm MEMORY.md and AGENTS.md updated
|
|
493
509
|
|
|
494
510
|
**File locations (all project-local — two dirs: `/stash` owns `.opencode/stash/`, `/remember` owns `.opencode/remember/`)**
|
|
495
511
|
- Stash files: `.opencode/stash/*.md`
|
|
496
512
|
- Memory file: `.opencode/remember/MEMORY.md` (single source of truth, referenced as `@.opencode/remember/MEMORY.md`)
|
|
497
|
-
- Rules template: `.opencode/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced
|
|
513
|
+
- Rules template: `.opencode/remember/AGENT_RULES.md` (bootstrapped once from the bundled package template on first `/remember` run, never overwritten again — user-owned after that; referenced by a plain path pointer, not `@`-referenced — see step 5)
|
|
498
514
|
- Antigen ledger: `.opencode/remember/ledger.json` (per-rule evidence trail: class, status, attempts/rejected-buffer, recurrence-while-hot)
|
|
499
515
|
- Consolidation report: `.opencode/remember/report.md` (latest step-8 report, overwritten each run)
|
|
500
516
|
- Processed manifest: `.opencode/remember/.processed`
|