Develop in an isolated deterministic runtime¶
Use new-feature to create feature branches with dedicated worktrees and local Pynchy services. Each managed feature and the CI runtime lane uses the same deterministic profile: dedicated server, gateway, and Temporal ports; SQLite, Temporal, and PostgreSQL data; and a namespaced Docker resource namespace.
Prerequisites¶
Install uv, then run the repository bootstrapper:
The bootstrapper verifies Docker and installs Pynchy's pinned new-feature (v1.1.6) and Codex CLIs into ~/.local/bin. It installs the pinned Temporal release in the selected bin directory and verifies its SHA-256 archive digest before installation. It does not install or start Docker because that requires platform-specific system administration. Run with --check to diagnose without installing.
CI and standalone deterministic runtime tests only need Docker and Temporal:
This mode skips the new-feature and Codex CLIs. Add its --bin-dir to PATH when you use a non-default directory.
Deterministic profile¶
Runtime setup generates its own data/personalization/ tree and .env. It never copies the control checkout's .env, personalization tree, provider credentials, or channel credentials. LiteLLM exposes one pynchy-deterministic route to an in-network OpenAI-compatible sidecar that returns a fixed response. The profile makes no provider calls and does not download or run a local model.
The generated .env contains only runtime-owned values, including an ephemeral gateway key. The gateway and sidecar share a namespaced Docker network. Runtime-owned HOME/XDG directories and the credential policy keep ambient provider, channel, and GitHub credentials out of the test agent.
The profile builds a locked, minimal agent-runner image from pinned base images and the nested agent_runner/uv.lock. This image runs the real OpenAI agent core and persistent file-IPC loop without the mutable CLI and plugin installation in the production agent image. The first setup downloads the pinned image and locked Python artifacts when the local cache lacks them. Its tag combines the runtime namespace and source digest; harness teardown removes that exact test image after its owned containers have stopped.
Interactive runtime tests enter through a harness-only loopback route enabled by PYNCHY_RUNTIME_HARNESS=1. The route calls the same inbound orchestration boundary as a channel; it never exists in a normal Pynchy process. Tests inspect the harness-owned SQLite database for durable results instead of exposing production chat-history endpoints.
Run runtime integration tests locally¶
From an isolated, otherwise clean checkout, run the same command as CI:
Do not use run in a worktree whose runtime is already running; stop that runtime first so this command owns setup and teardown. The command stops its owned processes and containers when it finishes. On failure, inspect logs/pynchy-runtime/ and data/.
To verify the runtime that new-feature already started, use exec instead. It keeps the sandbox running for diagnosis. exec rejects diagnostic state left by a failed run, because that command has already stopped its live resources; inspect its logs and data, then run stop before a fresh setup:
Create a feature¶
Pynchy's shared configuration launches the built-in Codex agent when --agent is omitted. Individual agent preferences can override that in the ignored .new-feature.local.toml sidecar. The shared push = false policy is deliberate: pushing main deploys Pynchy, so deployment stays an explicit operator action.
Run lifecycle commands from the control checkout:
Setup creates .worktrees/<slug>, installs dependencies, initializes messages.db and memories.db, starts a dedicated Temporal server, and launches Pynchy with namespaced LiteLLM, PostgreSQL, and deterministic OpenAI sidecar containers. PostgreSQL uses a namespaced Docker volume so container ownership cannot prevent worktree removal. Generated configuration, logs, process state, and databases remain ignored inside the feature worktree.
When an agent already runs in the control checkout, prevent a nested agent:
Read .new-feature/manifest.toml when the existing shell needs the allocated values. The generated .env and personalization files let commands run normally from the feature worktree.
Inspect or restart the sandbox from its worktree:
Merge and remove a feature¶
Commit the feature work, return to the control checkout, then run:
Merge stops the development sandbox, starts a fresh deterministic runtime from the current worktree, and runs the runtime suite. Its harness always stops live runtime resources before prek hooks run. It then performs a no-commit merge into main and runs both Pynchy and agent-runner tests against the integrated tree. A failed check aborts the merge; runtime logs and data remain available for diagnosis. Merge does not push main, so deployment remains an explicit operator action.
Teardown stops any remaining processes, removes only the feature's namespaced LiteLLM and PostgreSQL resources, and then removes the worktree, branch, manifest entry, and local databases.