#+TITLE: Contributing to Passepartout #+AUTHOR: Passepartout Contributors #+STARTUP: content #+FILETAGS: :docs:contributing: * 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: 1. *Think in org* — write reasoning and goals in the .org file 2. *Write contract* — define each function's behavior in a ~** Contract~ section 3. *TDD from contract* — each contract item becomes a ~fiveam:test~; prove RED then GREEN 4. *Reflect in org* — ensure implementation is in .org source 5. *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 corresponding =org/= file - All ~#+begin_src lisp~ blocks 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: #+begin_src bash 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 #+end_src 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: 1. *Contract* — what the skill guarantees 2. *Implementation* — the code, tangled to ~lisp/~ via ~#+PROPERTY: header-args:lisp~ 3. *Skill Registration* — a ~defskill~ form with ~:priority~, ~:trigger~, ~:probabilistic~ / ~:deterministic~ 4. *Test Suite* — ~fiveam:test~ forms verifying the contract Example: #+begin_src lisp (defskill :passepartout-example :priority 100 :trigger (lambda (ctx) ...) :probabilistic (lambda (ctx) ...) :deterministic (lambda (action ctx) ...)) #+end_src * 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: #+begin_src bash ln -sf ../../scripts/pre-commit-repl-check .git/hooks/pre-commit #+end_src 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) #+begin_src bash 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 #+end_src ** Swank (Emacs REPL for TUI) 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)