- Remove system-prompt-augment mechanism, introduce *standing-mandates* - Fix false token-overhead claims in DESIGN_DECISIONS + ROADMAP - Update security vector count 9-10 across all docs and dispatcher docstring - Rewrite README with agent section, soften aspirational claims - Register 10 cognitive tools in programming-tools.org with test suite - Enforce NO-HARDCODED-CONSTANTS in .env.example - ROADMAP: mark v0.3.x patches DONE, add LOGBOOKs, mark releases - AGENTS.md: rewrite compact (180 to 50 lines), move refs to CONTRIBUTING - Normalize org tangle directives to file-level PROPERTY inheritance
4.7 KiB
Contributing to Passepartout
- Philosophy
- Development Workflow
- Literate Programming
- Contracts and Tests
- Skill Creation Standard
- Project Structure
- Key Libraries
- Protocol
- Pre-Commit Hook
- Testing Tools
Philosophy
Passepartout is built on a "Zero-Bloat" mandate. The core kernel is mathematically pure, pushing all peripheral logic, API integrations, and routing to hot-reloadable "Skills".
Development Workflow
The full development cycle is described in AGENTS.md. In summary:
- Think in org — write reasoning and goals in the .org file
- Write contract — define each function's behavior in a
** Contractsection - TDD from contract — each contract item becomes a
fiveam:test; prove RED then GREEN - Reflect in org — ensure implementation is in .org source
- Update literate prose — explain the code: what, why, how it connects
Literate Programming
.org files in org/ are the source of truth. lisp/ files are generated by org-babel-tangle.
- Never edit
lisp/files directly — always modify the correspondingorg/file - All
#+begin_src lispblocks in a file inherit their tangle destination from the file-level#+PROPERTY: header-args:lisp :tangle ../lisp/FILE.lisp - Every architectural decision, constraint, and implementation detail must be documented alongside the code
Contracts and Tests
Every code change starts with a contract and a failing test. Write a ** Contract section listing each function's behavior, then create a fiveam:test in the * Test Suite section for each contract item.
To run tests for a specific file:
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
No test may be committed without proof it was first run to failure (RED).
Skill Creation Standard
A skill is a .org file in org/ that defines:
- Contract — what the skill guarantees
- Implementation — the code, tangled to
lisp/via#+PROPERTY: header-args:lisp - Skill Registration — a
defskillform with:priority,:trigger,:probabilistic/:deterministic - Test Suite —
fiveam:testforms verifying the contract
Example:
(defskill :passepartout-example
:priority 100
:trigger (lambda (ctx) ...)
:probabilistic (lambda (ctx) ...)
:deterministic (lambda (action ctx) ...))
Project Structure
| Directory | Purpose |
|---|---|
org/ |
Literate source files (edit these) |
lisp/ |
Tangled .lisp output (never edit) |
docs/ |
ROADMAP, ARCHITECTURE, DESIGN_DECISIONS, etc. |
scripts/ |
Build and utility scripts |
| ~/.local/share/passepartout/= | XDG data dir — deployed lisp files |
| ~/.config/passepartout/= | Config (.env) |
Key Libraries
| Library | Purpose |
|---|---|
| Croatoan | TUI (terminal UI) |
| usocket | TCP sockets (daemon protocol) |
| bordeaux-threads | Threading (reader thread) |
| dexador | HTTP client (LLM API calls) |
| cl-ppcre | Regex (search-files, dispatcher) |
| ironclad | SHA-256 (Merkle hashing) |
| hunchentoot | HTTP server |
| cl-json | JSON encoding/decoding |
Protocol
All inter-process communication uses the Unified Envelope protocol over TCP (port 9105). Message types: :REQUEST, :EVENT, :RESPONSE, :STATUS, :LOG. Each message includes a :META block with routing metadata.
Pre-Commit Hook
Validates staged org files by tangling + structural-checking:
ln -sf ../../scripts/pre-commit-repl-check .git/hooks/pre-commit
Runs automatically on git commit.
Testing Tools
TUI REPL (/eval)
The TUI has a built-in command for live evaluation:
/eval (+ 1 2)→ result displayed in chat window/eval (add-msg :system "test")→ inject a test message
Tmux (TUI integration testing)
tmux new-session -d -s test "passepartout tui 2>&1 | tee /tmp/tui.log"
tmux send-keys -t test "hello world" Enter
tmux capture-pane -t test -p -S -200
tmux kill-session -t test
Swank (Emacs REPL for TUI)
- Start TUI:
passepartout tui - In Emacs:
M-x slime-connect RET 127.0.0.1 RET 4006 C-M-xany form fromorg/gateway-tui.org→ evaluates in live TUI process- Configure port:
export TUI_SWANK_PORT=4009(default: 4006)