# AGENTS.md ## Development Cycle (every change) 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 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. ## 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`.