memex: split AGENTS.md into monorepo overview and per-project workflow

Move the development workflow details (TDD, REPL, literate programming,
branch policy) from top-level AGENTS.md into projects/AGENTS.md.
Top-level AGENTS.md now describes only the monorepo structure and
project list.
This commit is contained in:
2026-05-12 20:13:32 -04:00
parent f6094abb7b
commit 0290feccc1
2 changed files with 188 additions and 78 deletions

View File

@@ -1,82 +1,12 @@
# AGENTS.md
## Development Cycle (every change)
This is the memex monorepo. It contains multiple Common Lisp projects, each
in `projects/`. See `projects/AGENTS.md` for the general development workflow
(ROADMAP-driven, TDD in REPL, literate programming, branch policy).
1. **Read the next TODO** — find the next unreached `*** TODO` item in
`docs/ROADMAP.org` (search `*** TODO`). Read its prose, `:PROPERTIES:`,
and estimated line budget. That item is the target for this change cycle.
2. **Think in org** — write your reasoning, goals, and approach in the .org file first
3. **Write contract** — define a `** Contract` section listing each function's behavior:
`(fn-name args)`: description. Returns/guarantees ...
4. **TDD from contract** — each contract item becomes a `fiveam:test` in `* Test Suite`
a. Write the test first → tangle → run → prove it FAILS (RED)
b. Write the implementation → tangle → run → prove it PASSES (GREEN)
c. Record both failure and success output
5. **Reflect in org** — once tests pass, ensure the implementation is in the .org source, put each function in a separate code block.
6. **Update literate prose** — write/update the explanatory text around the code:
what it does, why it exists, how it connects to the rest of the system
7. **Mark the origin TODO DONE** — in `docs/ROADMAP.org`, change the
`*** TODO` item to `*** DONE` and add a `:LOGBOOK:` entry with the
completion date:
#+begin_src org
:LOGBOOK:
- State "DONE" from "TODO" [YYYY-MM-DD Day]
:END:
#+end_src
8. **Commit** — only when asked. Ask first.
## Project list
## Commands
Tangle a single file:
emacs --batch --eval "(progn (require 'org) (find-file \"org/FILE.org\") (org-babel-tangle) (kill-buffer))"
Validate structural integrity:
emacs --batch -Q --eval '(progn (find-file "org/FILE.org") (check-parens) (kill-buffer))'
Run tests:
sbcl --noinform \
--eval '(load (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname)))' \
--eval '(ql:quickload :passepartout :silent t)' \
--eval '(load "lisp/FILE.lisp")' \
--eval '(fiveam:run (intern "SUITE-NAME" :passepartout-TESTS))' --quit
For error details: bind fiveam:*on-failure* to :debug
## REPL (port 9105) — preferred when available
Start: `passepartout daemon`
Send code:
msg = '(:type :event :payload (:sensor :repl-eval :code "(+ 1 2)"))'
s.sendall(f'{len(msg):06x}'.encode() + msg.encode())
When REPL is up: TDD in-image first, then reflect to .org and tangle.
When REPL is down: fall back to the SBCL cycle above.
## Rules
- .org is source of truth; .lisp is generated — never edit .lisp directly
- Every code change starts with a contract and a failing test
- Prove RED before writing implementation
- Validate before committing
- If a tool fails, explain why and ask before trying alternatives
- Before shipping a version, run the `** File Update Checklist` in `docs/ROADMAP.org`
- **YOU MAY NOT** push a version tag (e.g., `v0.5.0`), create a GitHub release, or run `git push`
that triggers CI/CD version workflows without explicit permission. Ask first.
- **YOU MAY NOT add files to `passepartout.asd` `:components` without asking for permission.**
ASDF `:components` is the core harness. Files there load on every daemon boot,
cannot be hot-reloaded, and a bug there kills the agent's brainstem.
- When you want to add a new module, **ask first**. Provide:
1. Why it cannot be a skill (the self-repair criterion — can the agent fix it
if corrupted without human help?) Demonstrate specifically how a broken
version of this file prevents the agent from perceiving, reasoning,
or acting — not just degrading performance or losing a feature.
2. What it depends on and what depends on it
3. Why it cannot use `fboundp` guards from core
- **Default: everything is a skill.** Skills load via `skill-initialize-all`,
are hot-reloadable, self-repairable, and a bug in a skill degrades the agent
but doesn't kill it. The harness stays thin.
- **The self-repair criterion**: a file belongs in core only if, when corrupted,
the agent *cannot* fix it without human help. Corrupted core = dead brain,
dead hands, or unreachable. Corrupted skill = degraded but self-repairable.
This criterion is documented in `docs/ARCHITECTURE.org` and
`docs/DESIGN_DECISIONS.org`.
| Project | Description | Runtime |
|---------|-------------|---------|
| passepartout | Neurosymbolic agent | `passepartout daemon` |
| cl-tui | Reusable terminal UI framework | `sbcl` + `(ql:quickload :cl-tui)` |

180
projects/AGENTS.md Normal file
View File

@@ -0,0 +1,180 @@
# AGENTS.md
## Development Cycle (every change)
0. **Start the runtime** — boot the Lisp image that loads your project.
For passepartout: `passepartout daemon` (loads the entire project into one SBCL image).
For standalone CL projects: SBCL with `(ql:quickload :your-project)`.
The running image IS the development environment. The REPL is mandatory.
The SBCL fallback below exists only for bootstrapping (when the runtime cannot
start) and CI.
1. **Read the next TODO** — find the next unreached `*** TODO` item in
`docs/ROADMAP.org` (search `*** TODO`). Read its prose, `:PROPERTIES:`,
and estimated line budget. That item is the target for this change cycle.
2. **Create a branch**`git checkout -b feature/<version>-<name>` from main.
Every feature develops in its own branch. Branches are cheap, disposable,
and keep abandoned work off main. Name the branch after the version and
a short slug: `feature/v0.1.0-layout-engine`, `feature/v0.9.0-eval-harness`.
Complex features that span multiple phases may use a single branch with
multiple commits rather than one branch per phase.
3. **Think in org** — write your reasoning, goals, and approach in the .org file first.
4. **Write contract** — define a `** Contract` section listing each function's behavior:
`(fn-name args)`: description. Returns/guarantees ...
5. **TDD in REPL** — the inner loop runs entirely in the running image:
a. **Write tests in org** — add `fiveam:test` forms to the `* Test Suite` section
of the .org source file. Tests are definitions, not explorations — write them
in the file first.
b. **Send tests to REPL → RED** — evaluate the test forms in the running image.
Run the suite. It must FAIL — the implementation doesn't exist yet.
Record the failure output in the .org file under the test.
c. **Develop implementation in REPL** — redefine functions directly in the
running image. Explore. Discover the real argument shapes, edge cases, and
helper functions through interaction, not speculation. Each `defun` in the
REPL is immediate — no tangle, no reload, sub-second feedback.
d. **Run tests → GREEN** — after each change, re-run the suite from the REPL.
When all tests pass, the implementation is complete. If still RED, return to
step c. Record the passing output in the .org file under the test.
e. **Copy code to org** — copy each finished function from the REPL into its
own `#+begin_src lisp` block in the .org file. The code is already working;
the file is now its permanent home. One function per block. Never write a
function in a file that hasn't been proven in the image.
6. **Update literate prose** — write/update the explanatory text around the code:
what it does, why it exists, how it connects to the rest of the system.
7. **Tangle** — generate the .lisp file from the .org source:
```
emacs --batch --eval "(progn (require 'org) (find-file \"org/FILE.org\") (org-babel-tangle) (kill-buffer))"
```
Tangling is a finalization step, not part of the inner loop. The inner loop
(steps 5a5e) happens entirely in the REPL. Tangle once, when the file is
ready to commit.
8. **Run full test suite** — from the REPL, run every test suite in the project:
```
(fiveam:run-all-tests)
```
This catches regressions across the entire system. A function that passes its
own tests but breaks another module is not done.
9. **Validate block balance** — check that every `#+begin_src lisp` block in the
modified .org files has balanced parentheses. Use your project's equivalent
function or the SBCL fallback below.
10. **Commit on the branch** — include the RED and GREEN test output recorded
in the .org file as part of the commit message evidence:
```
git add org/ lisp/ docs/
git commit -m "v0.9.0: eval harness — 10 tasks, regression detection
RED: 0/10 pass (tasks not yet defined)
GREEN: 10/10 pass"
```
11. **Mark the origin TODO DONE** — in `docs/ROADMAP.org`, change the
`*** TODO` item to `*** DONE` and add a `:LOGBOOK:` entry with the
completion date. This is a separate commit on the branch:
#+begin_src org
:LOGBOOK:
- State "DONE" from "TODO" [YYYY-MM-DD Day]
:END:
#+end_src
12. **Merge to main** — the merge IS the release. Rebase onto main first
to keep history linear, then fast-forward merge:
```
git checkout main
git merge feature/v0.9.0-eval-harness
```
13. **Bump the submodule** — if the project is a submodule in the parent
`memex` repo (e.g., passepartout), stage the submodule pointer and commit:
```
git add projects/passepartout
git commit -m "bump passepartout → v0.9.0"
```
Standalone projects skip this step.
14. **Delete the branch** — `git branch -d feature/v0.9.0-eval-harness`.
Abandoned branches can be deleted before merge with no cleanup needed.
## Branch Policy
- Every feature starts on a branch from main. Branch names: `feature/<version>-<slug>`.
- ROADMAP.org changes (DONE markers, LOGBOOK entries) happen on the branch, not
on main directly. They merge to main with the feature.
- If a feature fails or is abandoned, delete the branch. No revert commits, no
dead code on main, no `;; OBSOLETE` comments. Git history preserves the
experiment if you need to reference it later.
- Rebase onto main before merging. Keep history linear. No merge commits.
- Complex features that span multiple roadmap versions may live on one branch
with multiple commits, merging to main when the entire chain is stable.
- **Bug fixes, typos, docs-only edits, and single-session jobs do not get a
branch.** Commit them directly to main. The heuristic: if it can be finished
in one session and has no plausible alternative that could replace it, it
goes to main. If it spans sessions or might be abandoned for a better
approach, it gets a branch.
## Commands
Tangle a single file:
emacs --batch --eval "(progn (require 'org) (find-file \"org/FILE.org\") (org-babel-tangle) (kill-buffer))"
Validate structural integrity (org/ source files only):
emacs --batch -Q --eval '(progn (find-file "org/FILE.org") (check-parens) (kill-buffer))'
Run tests (from REPL):
(fiveam:run (intern "SUITE-NAME" :project-TESTS))
(fiveam:run-all-tests)
Run tests (SBCL fallback — only when the runtime cannot start):
sbcl --noinform \
--eval '(load (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname)))' \
--eval '(ql:quickload :your-project :silent t)' \
--eval '(load "lisp/FILE.lisp")' \
--eval '(fiveam:run (intern "SUITE-NAME" :project-TESTS))' --quit
For error details: bind fiveam:*on-failure* to :debug
## REPL — mandatory
All development happens in a running Lisp image. Start your runtime:
- Passepartout: `passepartout daemon` — boots the entire project, listens on port 9105
- Standalone CL projects: `sbcl` with `(ql:quickload :your-project)`
Send code from opencode using the `lisp` tool (any SBCL project) or the `repl`
tool (passepartout daemon on port 9105). The inner loop (step 5a5e) never leaves
the REPL:
1. Send test forms from .org to REPL → RED
2. Redefine functions in REPL → test → iterate
3. Send tests → GREEN
4. Copy working code back to .org
Tangle only when the file is complete and ready to commit. Never batch-compile
outside the image when the runtime is available. Use the SBCL fallback above only
when the runtime itself cannot start.
## Rules
- .org is source of truth; .lisp is generated — never edit .lisp directly
- Every code change starts with a contract and a failing test
- Prove RED before writing implementation
- Implementation is developed in the REPL, then copied to .org — never write
code in a file that hasn't been proven in the image
- Validate before committing
- If a tool fails, explain why and ask before trying alternatives
- Before shipping a version, run the `** File Update Checklist` in `docs/ROADMAP.org`
- **YOU MAY NOT** push a version tag (e.g., `v0.5.0`), create a GitHub release,
or run `git push` that triggers CI/CD version workflows without explicit
permission. Ask first.