# Contributing to solstone Thank you for your interest in contributing to solstone. This guide covers developing on solstone from a source checkout. If you just want to run the software, see [INSTALL.md](INSTALL.md). ## Prerequisites solstone development uses a source checkout, a repo-local Python environment, and the `uv` package manager. Required everywhere: - Python 3.11 or later - [uv](https://docs.astral.sh/uv/) - Git - ripgrep (`rg`) - ffmpeg for audio processing - minisign 0.12 for transparency signing checks Linux is the primary development platform. macOS is supported. Source-checkout installs on Apple Silicon need Xcode command line tools to build the CoreML parakeet helper; packaged host installs (`uv tool install solstone-journal && uv tool install solstone`) on macOS 14 or newer ship the helper as a pre-built binary. Fedora/RHEL: ```bash sudo dnf install python3 git ripgrep ffmpeg minisign libgomp pipewire gstreamer1-plugins-base gstreamer1-plugin-pipewire pulseaudio-utils curl -LsSf https://astral.sh/uv/install.sh | sh ``` Ubuntu/Debian: ```bash sudo apt install python3 git ripgrep ffmpeg minisign libgomp1 pipewire gstreamer1.0-tools gstreamer1.0-pipewire pulseaudio-utils curl -LsSf https://astral.sh/uv/install.sh | sh ``` Arch: ```bash sudo pacman -S python git ripgrep ffmpeg minisign libgomp pipewire gstreamer gst-plugin-pipewire libpulse curl -LsSf https://astral.sh/uv/install.sh | sh ``` macOS: ```bash xcode-select --install brew install python git ripgrep ffmpeg minisign uv ``` ## Source-checkout install ```bash git clone https://github.com/solpbc/solstone-journal.git cd solstone-journal make install .venv/bin/journal setup ``` `make install` creates `.venv/`, syncs dependencies from `pyproject.toml` and `uv.lock`, installs the package in editable mode, regenerates router skill references, and refreshes the `sol` + `journal` project skill symlinks into the journal. In a source checkout, bare `uv sync` removes the published speakers-analyze helper because the workspace config prunes that package from the active dev environment; `make speakers-analyze-helper` puts the published helper back, and `make install` runs it after the final sync. Use `uv sync --inexact` when you intentionally need a prune-free sync. From inside this workspace, `uv pip install` of the helper can report success with exit code 0 while installing nothing unless `--no-config` is passed, so use the Make target instead of hand-running uv. `.venv/bin/journal setup` runs doctor diagnostics, confirms the journal path, installs local transcription models, installs the `sol` user skill for Claude Code / Codex / Gemini when those agents are configured, installs the `sol` + `journal` router skills into the journal, creates or refreshes the source-checkout wrappers at `~/.local/bin/sol` and `~/.local/bin/journal`, and starts the background service. The default web interface listens on http://localhost:5015. Use `.venv/bin/journal setup --port 8000` to choose another port on the first run. After the first setup run, the wrapper lets you use `sol` from anywhere: ```bash journal service status journal setup ``` The source-checkout journal lives at `journal/` inside the repo unless you pass `--journal` or have already configured another path. Configure API keys in `journal/config/journal.json`. This file is the only key configuration method for source-checkout development: ```bash mkdir -p journal/config cat > journal/config/journal.json << 'EOF' { "env": { "GOOGLE_API_KEY": "your-key-here" } } EOF chmod 600 journal/config/journal.json ``` Replace `your-key-here` with your Google AI API key. Optional provider keys can be added to the same `env` object: ```json { "env": { "GOOGLE_API_KEY": "your-gemini-key", "OPENAI_API_KEY": "your-openai-key", "ANTHROPIC_API_KEY": "your-anthropic-key" } } ``` `journal.json` contains API keys and credentials. Keep it private and restricted (`chmod 600`). ### Seeding a dev/test journal from public media If you want a journal seeded with public-domain audio and screen media instead of your own journal material — useful for contributors who shouldn't be exposed to a maintainer's personal journal, integration-test scenarios, or a clean dev environment — see [docs/FIELD_JOURNAL.md](docs/FIELD_JOURNAL.md). The `setup_field_journal.sh` script at the repo root populates `journal/chronicle/` from a local clone of [solpbc/field_journal](https://github.com/solpbc/field_journal). It is opt-in and deliberately not part of `make install` or `journal setup`. ## Repo layout Start with [AGENTS.md](AGENTS.md) or [CLAUDE.md](CLAUDE.md) for the developer-facing repo map, layer hygiene rules, make targets, and coding invariants. Most implementation work lives in `solstone/think/`, `solstone/observe/`, `solstone/convey/`, `solstone/apps/`, `solstone/talent/`, and `tests/`. For app work, read [docs/APPS.md](docs/APPS.md) before changing `solstone/apps/`. For provider work, read [docs/PROVIDERS.md](docs/PROVIDERS.md). For journal layout, use `solstone/talent/journal/SKILL.md`. ## Running the test suite Use the Makefile targets. The high-signal commands are: ```bash make test-only TEST=tests/test_utils.py::test_foo make test-app APP=settings make test make ci ``` Use `make test-only` and `make test-app` as the development loop. `make test` runs all unit tests — `tests/` plus every `solstone/apps/*/tests/`, in one parallel run — after a format check. `make ci` is the canonical full gate: install checks plus the full unit suite. Run it once on the settled final tree before submitting, merging, or releasing, not before every intermediate commit. ```bash make test-only TEST="-k test_foo" # one test by name/pattern ``` All tests are fast unit/component tests (no real browser, live network, or API keys). For user-visible web changes, use the API verification target and review the live UI in a sandbox when relevant: ```bash make verify-api # check API baselines against a sandbox make sandbox # start a sandbox to review the live UI (make sandbox-stop when done) ``` See [AGENTS.md](AGENTS.md) for the full Makefile command table and [docs/testing.md](docs/testing.md) for test isolation details. ## Developing on AI features ### macOS Apple Silicon: CoreML-accelerated parakeet Packaged installs of solstone on Apple Silicon Macs running macOS 14 or newer ship the CoreML transcription helper as a pre-built, signed, and notarized binary. No build step is required for owners using a packaged install. Source-checkout installs build the helper locally so you can iterate on the Swift source: ```bash make parakeet-helper ``` The built binary lives at: ```text solstone/observe/transcribe/parakeet_helper/.build/release/parakeet-helper ``` If you change the helper source, rebuild it before testing the CoreML parakeet path. Note that the runtime resolver prefers `solstone/observe/transcribe/parakeet_helper/_bin/parakeet-helper` (the location populated by `make wheel-macos` for platform-wheel packaging) over the `.build/release/` path; if you previously ran `make wheel-macos`, run `make wheel-macos-clean` to clear the `_bin/` copy so your local rebuild takes effect. ### Skills and talents Talent prompts live under `solstone/talent/.md`; apps may add app-specific talent files under `solstone/apps//talent/`. Talent frontmatter declares type, schedule, provider/model behavior, hooks, priority, and output expectations. The installed project skills are the two router skills under `solstone/talent/sol/` and `solstone/talent/journal/`. App command fragments under `solstone/apps//talent//SKILL.md` feed the generated router references; they are not installed as top-level skills. After changing a router skill or an app command fragment, run: ```bash make skills ``` That target first runs `scripts/build_skill_references.py` to regenerate the checked-in references, then refreshes the `sol` + `journal` router skill symlinks inside the journal. `make install` also runs this target, and `make ci` / `make install-checks` runs `scripts/build_skill_references.py --check` to catch stale generated references. ## Migrating from a source install to a packaged install A packaged host install puts `sol`, `solstone`, `journal`, and `mlx-vlm-server` on PATH directly. `pip install solstone-journal` exposes those commands in one environment; uv tool and pipx expose each tool's own commands, so install both the journal tool and the thin `solstone` tool. It does not use the source-checkout managed wrapper, and it does not use `.venv/bin/sol`. `make uninstall` is disabled by design. To migrate cleanly from a source checkout to a packaged install, remove user-runtime artifacts explicitly: ```bash journal service uninstall sol skills uninstall python -m solstone.think.install_guard uninstall uv tool install solstone-journal && uv tool install solstone journal setup ``` For pip or pipx packaged installs, use `pip install solstone-journal` or `pipx install solstone-journal && pipx install solstone` before `journal setup`. Your journal is preserved at `~/journal`; solstone does not remove it during install or uninstall. Do not add backwards-compatibility shims for the old source-checkout layout. This migration is a clean break. ## License of Contributions By contributing to this repository, you agree that your contributions are licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-only), the same license as the project. You represent that you have the right to submit the contribution and that it does not include proprietary, confidential, or third-party code that is incompatible with the AGPL. ## Developer Certificate of Origin (DCO) All contributions must be signed off using: git commit -s This certifies compliance with the Developer Certificate of Origin (DCO).