The workflow answers how to install StoryMatrix, run generation, and enforce isolated quality checks.

🧰 Environment and commands

Activate the virtual environment first, and use uv exclusively; pip is never used (AGENTS.md).

source .venv/bin/activate
uv sync
uv sync --extra <profile>

Profiles include minimal, cloud, local, full, dev, test, docs, and deploy (pyproject.toml). The minimal extra adds no packages because core dependencies already sit in the project dependency set.

Run the CLI and resume a failed production from its checkpoint:

uv run storymatrix generate --config storymatrix_config.yaml
uv run storymatrix generate --config storymatrix_config.yaml --resume

Run the test suite and intentionally refresh golden snapshots only after reviewing the output change:

uv run pytest
uv run pytest --snapshot-update

🪝 Pre-commit hooks

The hook set runs from .pre-commit-config.yaml:

HookEnforcement
trailing-whitespaceRemoves trailing spaces; Markdown files are excluded.
end-of-file-fixerEnsures a final newline; Markdown files are excluded.
check-yamlParses YAML while excluding selected legacy/config paths.
check-tomlParses TOML.
check-jsonParses JSON.
check-merge-conflictDetects unresolved merge markers.
check-added-large-filesRejects files over 5000 KB outside generated-data paths.
debug-statementsDetects debugger statements outside archived docs.
ruff-formatFormats Python, stubs, and notebooks outside tests/.

Run the hooks across the checkout with uv run pre-commit run --all-files (.github/workflows/ci.yml).

⚠️ Default install is currently broken

A plain uv sync followed by storymatrix generate raises ModuleNotFoundError: No module named 'nltk': the local SFX adapter imports nltk at module scope, while nltk belongs only to the local and full extras (src/storymatrix/infrastructure/adapters/sfx/local.py, pyproject.toml). Work around the defect with uv sync --extra local; the real fix moves the import inside the adapter factory according to the lazy-inner-import rule. Track the defect at index > b1.

🧪 GitHub workflows

The CI workflow (.github/workflows/ci.yml) installs Python 3.11 and bubblewrap, then runs these exact commands:

curl -LsSf https://astral.sh/uv/install.sh | sh
uv python install 3.11
sudo apt-get update && sudo apt-get install -y bubblewrap
uv sync --locked --extra test --extra dev
uv run pre-commit run --all-files
uv run pytest $REQUIRED_NODES --collect-only
scripts/sandbox-launcher.sh uv run pytest $REQUIRED_NODES
uv run ruff check .
uv run mypy .
scripts/sandbox-launcher.sh uv run pytest tests/

The documentation workflow (.github/workflows/docs-lint.yml) runs:

npx --yes markdownlint-cli2 "**/*.md"
python3 scripts/link_check.py docs README.md CHECKLIST.md

🛡️ Bubblewrap isolation

scripts/sandbox-launcher.sh requires bwrap, strips proxy and provider variables, and invokes bubblewrap with --unshare-net. tests/isolation/sitecustomize.py also blocks non-local socket and asyncio connections and removes provider credentials. CI cannot reach paid provider APIs, so ElevenLabs, PlayAI, and other paid services never receive test traffic. The isolation boundary keeps test behavior deterministic and protects provider credentials.