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:
86
AGENTS.md
86
AGENTS.md
@@ -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
180
projects/AGENTS.md
Normal 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 5a–5e) 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 5a–5e) 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.
|
||||
Reference in New Issue
Block a user