From 01ff57096ee086b9db0b6e981b215b4466d0c8cf Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Thu, 7 May 2026 16:45:17 -0400 Subject: [PATCH] passepartout: v0.4.1 Design Cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submodule: 25 files changed — system-prompt-augment removal, 10 cognitive tools, vector count 9-10, README rewrite, ROADMAP updates, CONTRIBUTING rewrite, tangle normalization. AGENTS.md: rewritten compact (180-50 lines). --- AGENTS.md | 203 ++++++++---------------------------------- projects/passepartout | 2 +- 2 files changed, 38 insertions(+), 167 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 0e8c3ad..83d90fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,179 +1,50 @@ -# AGENTS.md — OpenCode Tool Usage Guide +# AGENTS.md -This file tells AI coding agents which tools are available and when to use them. -It is read by agents working on the Memex / Passepartout project. +## Development Cycle (every change) -## Development Workflow (Must Follow) - -All development MUST follow this cycle, beginning to end: - -1. **Start in REPL** — Everything begins and ends in the Passepartout REPL (port 9105) -2. **TDD in REPL** — Red-Green-Refactor cycle: - 1. Write a FAILING test first (use `(passepartout:deftest name ...)` or `fiveam:test`) - 2. **Prove RED**: Run `(passepartout:run-test 'test-name)` — it MUST fail. - If it passes before code exists, the test is broken or testing nothing. - Record the failure output. - 3. Develop code in REPL to make the test pass - 4. Use lisp-structural-check to validate code while developing - 5. Evaluate forms with `eval-defun` or equivalent - 6. Run tests again → they should PASS - 7. Repeat until feature is complete -3. **Reflect in Org** — Once code works in REPL, reflect it in the .org literate source file -4. **Tangle with Emacs** — Use `org-babel-tangle` to generate .lisp from .org -5. **Validate tangled lisp** — Run `lisp-structural-check` on the result -6. **Commit** — Only after validation passes - -**When tools fail**: -- If any recommended tool fails, you MUST explain: - - Why it failed (specific error, missing dependency, etc.) - - How we can make it work (fix, configuration, alternative approach) -- Then **PAUSE** and ask for permission before trying a different method - -**Rule**: Do not leave the REPL to develop. If something can't be done in REPL, explain why and ask before proceeding otherwise. - ---- - -## Available Tools — Use These First - -### 1. Passepartout REPL (port 9105) -The daemon runs with ALL skills loaded. Use it instead of the deploy-crash-cycle. - -**Send forms via Python bridge:** -```python -import socket -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -s.connect(("127.0.0.1", 9105)) -msg = '(:type :event :payload (:sensor :repl-eval :code "(+ 1 2)"))' -s.sendall(f"{len(msg):06x}".encode() + msg.encode()) -``` - -**Or via SBCL directly (attached to daemon):** -```lisp -(sb-bsd-sockets:socket-send sock payload len) -``` - -**Key functions available:** -- `(passepartout:lisp-structural-check "code-string")` — returns (values t nil) or (values nil "error") -- `(passepartout:lisp-validate "code-string" :semantic t)` — full validation -- `(passepartout:log-message "format ~a" arg)` — write to daemon log -- Any exported symbol from `passepartout` package - -### 2. Lisp Structural Tools (pre-deploy validation) -**ALWAYS run these before tangling/deploying Lisp changes.** - -`lisp-structural-check` works on ANY Lisp string, not just Org blocks: -```lisp -;; Via REPL — send to port 9105: -(passepartout:lisp-structural-check "") -;; Returns: (values t nil) on success, (values nil "error details") on failure -``` - -For Org files: -```lisp -(passepartout:literate-block-balance-check "/path/to/file.org") -``` - -These catch paren mismatches in <1 second vs. the 60-second deploy-crash cycle. - -### 3. Emacs Interactive -Use Emacs for interactive Lisp development: -- `forward-sexp` / `backward-sexp` — navigate balanced expressions -- `show-paren-mode` — visual paren matching -- `eval-defun` (C-M-x) — evaluate the current top-level form -- `eval-region` — evaluate selected region -- `org-babel-tangle` — tangle a single file: `M-x org-babel-tangle` -- Batch tangle: `emacs --batch --eval "(progn (require 'org) (find-file \"file.org\") (org-babel-tangle) (kill-buffer))"` - -### 4. Tmux (for TUI testing) -```bash -# Start TUI in detached session -tmux new-session -d -s test "passepartout tui 2>&1 | tee /tmp/tui.log" - -# Send keys -tmux send-keys -t test "hello world" Enter - -# Capture output -tmux capture-pane -t test -p -S -200 - -# Clean up -tmux kill-session -t test -``` - -### 5. Pre-Commit Hook -Validates staged org files by tangling + compiling in daemon: -``` -ln -sf ../../scripts/pre-commit-repl-check .git/hooks/pre-commit -``` -Run manually: `passepartout setup` or `git commit` (hook auto-runs). - -### 6. TUI REPL (via /eval + Swank) -The TUI process has its own REPL for live development: - -**Built-in /eval command** — type in the TUI input: -- `/eval (+ 1 2)` → `=> 3` displayed in chat -- `/eval *state*` → inspect full TUI state plist -- `/eval (view-status sw)` → force status bar re-render -- `/eval (add-msg :system "test")` → inject a test message - -**Emacs + Swank REPL** — connect Emacs to the TUI process: -1. Start TUI: `passepartout tui` -2. In Emacs: `M-x slime-connect RET 127.0.0.1 RET 4006` -3. `C-M-x` any form from `org/gateway-tui.org` → evaluates in live TUI process -4. Configure port: `export TUI_SWANK_PORT=4009` (default: 4006) - -**Croatoan note**: Rendering functions (`view-status`, `view-chat`, `view-input`) write to the terminal and can't be fully tested from Emacs. Inspect return values instead, and test rendering with `/eval` commands in the TUI itself. - ---- +1. **Think in org** — write your reasoning, goals, and approach in the .org file first +2. **Write contract** — define a `** Contract` section listing each function's behavior: + `(fn-name args)`: description. Returns/guarantees ... +3. **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 +4. **Reflect in org** — once tests pass, ensure the implementation is in the .org source +5. **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 +6. **Commit** — only when asked. Ask first. ## Commands -- Validate code: Send to REPL at port 9105 using socket bridge (see Development Workflow) -- Run tests: `(passepartout:run-tests)` in REPL -- Tangle org: `emacs --batch --eval "(progn (require 'org) (find-file \"file.org\") (org-babel-tangle) (kill-buffer))"` +Tangle a single file: + emacs --batch --eval "(progn (require 'org) (find-file \"org/FILE.org\") (org-babel-tangle) (kill-buffer))" -## Project Structure +Validate structural integrity: + sbcl --noinform --eval '(with-open-file (f "lisp/FILE.lisp") (loop (read f nil (return))))' --quit -- Source (literate): `org/` -- Source (tangled): `lisp/` -- Tests: `tests/` -- Scripts: `scripts/` -- Deployment: `~/.local/share/passepartout/` -- TODO tracking: `docs/ROADMAP.org` +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 -## When Done Means +For error details: bind fiveam:*on-failure* to :debug -- Red proof recorded: Test was run and confirmed FAILING before implementation code existed -- Tests pass: `(passepartout:run-tests)` returns success -- Code validated: `lisp-structural-check` returns `(values t nil)` -- Org reflected: Code exists in .org source file -- Org tangled: .lisp generated from .org -- Committed: Only after all above pass +## REPL (port 9105) — preferred when available -## Boundaries +Start: `passepartout daemon` +Send code: + msg = '(:type :event :payload (:sensor :repl-eval :code "(+ 1 2)"))' + s.sendall(f'{len(msg):06x}'.encode() + msg.encode()) -- **Always do**: Use REPL first for all development, use TDD, prove tests fail FIRST before writing code, validate with lisp-structural-check -- **Ask first**: Before editing .lisp directly (skip org), before deploying, before git commit -- **Never do**: Edit .lisp files manually (they're autogenerated), skip validation before commit +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. -## Iteration +## Rules -When the agent makes the same mistake twice, add a rule to this file to prevent recurrence. - ---- - -## Project Architecture - -- **Thin harness, fat skills** — core provides hooks (`defskill`, `register-actuator`, `*probabilistic-backends*`), skills provide handlers -- **Org is source of truth** — `.org` files tangle to `.lisp`. Never edit `.lisp` directly -- **Package:** `passepartout` exports all symbols in `lisp/core-defpackage.lisp` -- **XDG data dir:** `~/.local/share/passepartout/` (deployed lisp/org files) -- **Config:** `~/.config/passepartout/.env` - ---- - -## Key Libraries - -- **Croatoan** — 0-based coordinates, `(setf (cursor-position win) '(y x))` for cursor, `add-string` with `:y`/`:x` keyword args. Source: `~/quicklisp/dists/quicklisp/software/croatoan-20241012-git/src/` -- **Babel** — string encoding/decoding -- **usocket** — TCP sockets -- **bordeaux-threads** — threading primitives +- .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 diff --git a/projects/passepartout b/projects/passepartout index c7e9893..639bc34 160000 --- a/projects/passepartout +++ b/projects/passepartout @@ -1 +1 @@ -Subproject commit c7e9893e68674567bf818713084f838d2a006355 +Subproject commit 639bc348d96ee52359e4fb97dd7b0d9000a64a0f