Files
passepartout/docs/CONTRIBUTING.org

4.7 KiB

Contributing to Passepartout

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:

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:

  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 Suitefiveam:test forms 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)

  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)