https://github.com/escotilha/oxison
Reads any repo and writes its product docs (PRODUCT/MANUAL/STACK), plans a roadmap, and builds the work — powered by Claude Code. Read-only by default, sandboxed when it writes.
https://github.com/escotilha/oxison
ai-agents anthropic autonomous-agents claude claude-code cli code-comprehension code-documentation developer-tools documentation-generator llm python
Last synced: 10 days ago
JSON representation
Reads any repo and writes its product docs (PRODUCT/MANUAL/STACK), plans a roadmap, and builds the work — powered by Claude Code. Read-only by default, sandboxed when it writes.
- Host: GitHub
- URL: https://github.com/escotilha/oxison
- Owner: escotilha
- License: mit
- Created: 2026-06-15T16:02:15.000Z (10 days ago)
- Default Branch: main
- Last Pushed: 2026-06-15T18:22:11.000Z (10 days ago)
- Last Synced: 2026-06-15T18:24:47.702Z (10 days ago)
- Topics: ai-agents, anthropic, autonomous-agents, claude, claude-code, cli, code-comprehension, code-documentation, developer-tools, documentation-generator, llm, python
- Language: Python
- Homepage: https://github.com/escotilha/oxison
- Size: 290 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# oxison
[](https://github.com/escotilha/oxison/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.python.org/downloads/)
[](https://github.com/astral-sh/ruff)
**Reads any repo and writes its product docs (PRODUCT/MANUAL/STACK), plans a roadmap, and builds the work — powered by Claude Code. Read-only by default, sandboxed when it writes.**
`oxison` reads a repository, understands it by driving the
[Claude Code](https://claude.com/claude-code) CLI as a **read-only**
subprocess, and writes product artifacts into its own output directory.
It never modifies the repo it analyzes.
```bash
oxison run /path/to/repo
# → ./oxison-output/{PRODUCT,MANUAL,STACK}.md
# + ROADMAP-ANALYSIS.md (if the repo has a roadmap) or SECURITY-NOTES.md (if not)
# + COMPREHENSION.md + repomap.json + .oxison-run.json
```
## Requirements
- **Python ≥ 3.11**
- The **[Claude Code](https://claude.com/claude-code) CLI**, installed and signed in
(oxison drives it as a subprocess; by default it uses your existing Claude Code login —
see [Auth](#auth))
## Safety model
`oxison run` and `oxison plan` **never modify the target repo.** Two invariants
enforce it:
1. **The AI worker is *structurally* read-only** — launched with
`--allowedTools Read,Glob,Grep`: no shell, no write tools. It physically
cannot modify, create, delete, or execute anything — not just "told not to."
(`Bash` is deliberately **excluded**: under `--permission-mode
bypassPermissions` a shell is a full write/exec primitive, so it belongs to
the build tier, not here.) A unit test asserts the exclusion against the
built command line, so it can't silently regress.
2. **oxison owns every write**, exclusively into `./oxison-output/`.
Workers return markdown; oxison writes the files.
After a `run`/`plan`, the target repo's git working tree is byte-for-byte
unchanged (`git status` clean, `HEAD` unmoved).
### `oxison build` is different — it writes code, by design
The Oxfaz build worker (`oxison build`) is the one stage that **writes**: it has
full read/write tools (`Bash` included) so it can implement a task and run the
project's tests. It is contained by three layers:
1. **A filesystem + network sandbox (`srt`), on by default.** Each worker is
wrapped in Anthropic's [`@anthropic-ai/sandbox-runtime`](https://github.com/anthropic-experimental/sandbox-runtime)
(`sandbox-exec` on macOS, `bubblewrap` on Linux). Writes are confined to the
worker's **worktree** + the scoped parts of `.git` it needs to commit (NOT
`.git/config` or `.git/hooks`) + Claude's own state; egress is limited to an
allowlist (the Anthropic API + package registries + your git host); and
credentials (`~/.ssh`, `~/.aws`, …) are unreadable. So even a
prompt-injected worker cannot escape the worktree, install a git hook, or
exfiltrate. **Requires Node + `npm i -g @anthropic-ai/sandbox-runtime`**
(verified against `srt` 1.0.0); if it's missing, `oxison build` fails at
preflight with an install hint. `--no-sandbox` disables it (loud stderr
warning) for trusted local runs.
> **Why the sandbox is the default — and what `--no-sandbox` gives up.** A
> build worker's prompt is assembled from the roadmap, which derives from
> repository and (in greenfield) web-fetched content — i.e. **untrusted
> input**. A malicious README or page could attempt prompt injection to steer
> the write-capable worker. The srt sandbox is what contains that: an injected
> worker still can't escape the worktree, read credentials, or exfiltrate.
> `--no-sandbox` removes that containment, so only use it on repos and sources
> you fully trust. (The grader in step 3 is a backstop, not a substitute — it
> inspects the *diff*, not the worker's runtime behavior.)
2. **Worktree isolation** — each worker runs in its own git worktree under
`oxison-build/worktrees/`, so the repo's main working tree is never edited.
3. **A grader** — rejects any diff that touches a protected path
(`.github/workflows`, `.env`, lockfiles, `.git/`, `oxison-build/`).
With the srt sandbox on, build mode is safe to point at repos you don't fully
trust.
#### Stronger filesystem isolation: the container sandbox (`--sandbox-layer container`)
For CI, or to isolate a worker more strongly than srt's allowlist, run each
worker **inside a rootless container**. This is the stronger *filesystem*
boundary; note the container currently keeps **default network egress** (see the
caveat below), so for a fully-hostile repo also narrow egress — that tightening
is tracked, not yet shipped.
```bash
# one-time: a container runtime + the worker image
brew install podman && podman machine init && podman machine start # or docker
podman build -t localhost/oxfaz-worker:latest docker/oxfaz-worker
# then build with Layer 2 (needs an API key — see auth note)
ANTHROPIC_API_KEY=… oxison build ./oxison-output --repo ~/code/myrepo --sandbox-layer container
```
How it's stronger than srt: the worker runs in a container whose **only
bind-mount is its workspace**, so the host filesystem — `~/.ssh`, the main repo,
every credential — is **physically absent**, not merely denied (mount-namespace
isolation, `--cap-drop ALL`, `--security-opt no-new-privileges`). The worker
builds + commits in a self-contained **clone** mounted at `/work` (a linked
worktree's `.git` would point outside the mount), and oxison reads the diff from
that clone afterwards.
Two requirements:
- **Auth is bare-mode.** The macOS Keychain / OAuth store isn't reachable inside
a Linux container, so the worker authenticates with an `ANTHROPIC_API_KEY`
(forwarded by name into the container, never baked into the image). `oxison
build --sandbox-layer container` fails at preflight if no key is set.
- **macOS: the repo must live under `$HOME`.** A path only mounts into the
podman VM if it's on a shared host dir; `$HOME` is shared by default, `/tmp`
is not. Repos under `~/code` work; repos under `/tmp` or external volumes
won't mount.
Verified end-to-end (macOS, podman): a real worker clones the target, builds +
commits its task inside the container, and the host grades + records it — with
`/Users`, `~/.ssh`, and out-of-`/work` writes all confirmed inaccessible from
inside. Egress narrowing (the container currently keeps default egress; srt's
domain proxy can run inside it as a follow-up) is the remaining tightening,
tracked in `docs/superpowers/specs/2026-06-15-oxfaz-worker-sandbox-design.md`.
## What it produces
| File | Contents |
|---|---|
| `PRODUCT.md` | What the software is, who it's for, core features, mental model |
| `MANUAL.md` | Prerequisites, install, configuration, usage, workflows |
| `STACK.md` | Languages, dependencies + versions, runtime, infra/services (grounded in the manifests) |
| `ROADMAP-ANALYSIS.md` | *(if a roadmap exists)* Analysis of planned work, feasibility vs. current code, sequencing, recommended next items |
| `SECURITY-NOTES.md` | *(if no roadmap)* Lightweight read-only security surface scan + a nudge to add a roadmap |
| `COMPREHENSION.md` | The intermediate whole-repo understanding the docs are built from |
| `repomap.json` | The deterministic repo map (languages, deps, entry points, services) |
| `.oxison-run.json` | Per-step status + cost; enables `--resume` |
**See it for real:** [`examples/oxison-self/`](examples/oxison-self/) is oxison's
own docs, generated by running oxison on this repo — real, unedited output.
## How it works
```
map (deterministic, no AI) → repomap.json
└─ language histogram, dependency manifests, entry points, services
comprehend (read-only AI) → COMPREHENSION.md
└─ single-pass for small repos; map-reduce (slice by top-level dir
+ synthesis) when the estimated token surface exceeds the threshold
generate (read-only AI, parallel) → PRODUCT.md, MANUAL.md, STACK.md
branch (read-only AI) → ROADMAP-ANALYSIS.md or SECURITY-NOTES.md
```
The risky part — the `claude -p` subprocess wrapper — is hardened:
process-group isolation, concurrent stdout/stderr drain, a 1 MB stream
limit, an env whitelist, a wall-clock timeout, and cost extraction, all
using argv-form spawning (a prompt can never be shell-interpreted).
## Multi-source ingestion (Oxicome)
oxison can comprehend a repo **plus additional non-repo sources** — PDFs,
presentations, Word documents, plain markdown, and audio/video recordings —
merging them into one provenance-tagged comprehension pass.
```bash
# Feed individual files alongside the repo
oxison run /path/to/repo --add spec.pdf --add deck.pptx --add notes.md
# Or ingest a whole folder at once
oxison run /path/to/repo --sources ./inputs/
# Opt-in OCR for scanned/image-heavy PDFs
oxison run /path/to/repo --add scanned.pdf --ocr
# Transcribe an audio/video recording via a cloud STT API
oxison run /path/to/repo --add demo.mp4 --stt-key $KEY --stt-provider deepgram
```
`--add PATH` is repeatable; `--sources DIR` ingests every supported file in the
directory. Source types are detected by extension (`.pdf`, `.pptx`, `.ppt`,
`.docx`, `.doc`, `.md`, `.txt`, `.mp3`, `.mp4`, `.wav`, …).
### The `comprehension.json` artifact
When any source is added, oxison emits a `comprehension.json` alongside the
usual markdown outputs. It is a structured, provenance-tagged envelope — schema
version `1.0` — containing:
- the human-readable PRODUCT / MANUAL / STACK comprehension;
- a machine-readable ledger of every source ingested (path, type, byte size,
whether it was extracted successfully).
`comprehension.json` is the stable contract for downstream tooling (CI
pipelines, dashboards, other agents) that need to consume oxison's output
programmatically.
### Installing the source adapters
```bash
pip install 'oxi-son[sources]' # adds PDF, pptx, and docx support
```
The `sources` extra bundles `pypdf`, `python-pptx`, and `python-docx`. Without
it, those adapters degrade gracefully (the file is logged as skipped-with-reason
rather than raising an error).
### Caveats
- **OCR** (`--ocr`) requires an optional, unpublished `document_extraction`
package to be importable — it brings the heavy PaddleOCR stack. It is **not**
an oxison dependency; scanned PDFs fall back to skip-with-reason if the
package is absent.
- **Recordings** (`--stt-key`) upload audio/video to a third-party cloud STT
API (e.g. Deepgram). This is the **one path that sends data off-host** — it
is entirely opt-in and requires an explicit key. All other adapters process
files locally.
### Safety invariant
oxison's read-only guarantee extends to every source adapter: oxison reads the
files you point it at and never modifies them. No adapter writes back to any
input path.
## Start from an idea — `oxison ideate` (greenfield)
You don't need a repo at all. **`oxison ideate`** starts from **zero** — a
plain-text project idea plus any non-repo inputs (slide decks, recordings,
PDFs, markdown, and **website links**) — and produces a reviewable plan for a
product that doesn't exist yet: a comprehension, a `PRODUCT.md` vision/spec, and
an initial **`ROADMAP`**.
```bash
# from just an idea
oxison ideate --brief "a CLI that turns a folder of Markdown notes into a daily Slack standup"
# idea + supporting material (decks, recordings, and links you want it to read)
oxison ideate \
--brief-file ./pitch.md \
--add deck.pptx --add call-recording.m4a \
--url https://a-competitor.example --url https://some-reference.example
```
What you get in `./oxison-output/`: `COMPREHENSION.md` + `comprehension.json`
(the synthesized understanding, provenance-tagged by source — `brief:idea`,
`web:host`, `pptx:deck#slide-4`), `PRODUCT.md` (the product to build), and
`ROADMAP.md` / `roadmap.json` (a sequenced, from-scratch build plan whose tasks
carry observable acceptance criteria — the same gated contract `oxison plan`
produces, ready for `oxison build`).
It needs **at least one input** (`--brief`/`--brief-file`, `--add`, `--sources`,
or `--url`). To refine the plan, re-run with `--answers-file notes.txt` (your
guidance steers the roadmap). See [`examples/ideate-standup/`](examples/ideate-standup/)
for real output.
**"Research" in v1 means synthesis of what you give it** — including the content
of the `--url` links it fetches — not open-web search. Fetching a URL is the one
extra thing greenfield does over the read-only flows: it issues an HTTP GET to
the links **you** provide (http/https only, with size/time caps). There is no
model-initiated browsing; the AI workers stay read-only (`Read,Glob,Grep`).
> Greenfield is **plan-only** today — it stops at the roadmap. Scaffolding a repo
> and running the build loop (`oxison build`) from that roadmap is the documented
> next step.
## Planning (Oxipensa)
`comprehension.json` answers *"what is this and where is it at?"*. **Oxipensa**
turns that into *"what should we build next?"* — it reads a `comprehension.json`
and emits a prioritized, gated **`roadmap.json`** plus a human-readable
**`ROADMAP.md`**.
```bash
# plan from a comprehension produced by `oxison run`
oxison plan ./oxison-output
# ground the planner in the actual repo (read-only), and refine with guidance
oxison plan ./oxison-output --repo /path/to/repo --answers-file notes.txt
```
What you get (`roadmap.json`, schema `1.0` — the Oxipensa→Oxfaz contract):
- a prioritized task list, each task carrying a **deterministic identifier**
(stable across re-plans, so a builder can dedup), **provenance** (the
comprehension locators it traces to), **dependency sequencing**, and at least
one **observable acceptance criterion** (a checkable end-state, not "works
well");
- the planner's `summary` and any `open_questions` (merged with the
comprehension's, the hook for refining the plan with `--answers-file`).
How it stays trustworthy: every proposed roadmap passes a deterministic
**plan-gate** before it is written — non-empty titles, valid kinds, real
acceptance criteria, no dependency cycles or dangling links, and **no task may
target a protected path** (CI config, `.env`, lockfiles, `.git/`). A roadmap
that fails the gate is fed back to the planner for one self-correcting pass; a
roadmap that still fails is never written. The planner worker is **read-only**
like every other oxison AI call — it reasons and returns JSON; oxison owns the
writes.
## Building (Oxfaz)
**Oxfaz** is the third stage: it consumes an Oxipensa `roadmap.json` and runs an
autonomous build loop, dispatching one write-worker per task **in an isolated
git worktree** and recording every outcome in a durable taskstore.
```bash
# see what would be built — ingest the roadmap, spawn NO workers
oxison build ./oxison-output --repo /path/to/repo --dry-run
# run the build loop with explicit guardrails
oxison build ./oxison-output --repo /path/to/repo \
--max-ticks 20 --budget-ceiling-usd 50 --no-progress-ticks 5
```
> ⚠️ **Build mode writes code.** Unlike `run`/`plan` (read-only), Oxfaz workers
> have full read/write tools. Each runs in its own worktree under
> `oxison-build/worktrees/`; the repo's main working tree is never touched
> directly. Start with `--dry-run`.
How it stays safe and bounded:
- **The spine** (`oxison-build/state.db`) is the durable source of truth — a
2-table SQLite store (task + lock) with crash-safe, idempotent writes. A task
is marked dispatched **before** its worker spawns and the transition is guarded
(`WHERE status='planned'`), so a crash or a double-tick can never re-dispatch
in-flight work.
- **The grader** re-runs the protected-path matcher on each worker's *actual
diff* — a worker that touches CI config, `.env`, lockfiles, `.git/`, or
`oxison-build/` fails the grade even if the plan looked clean.
- **Three guardrails** bound every run on a different axis: an **iteration cap**
(`--max-ticks`), a **no-progress halt** (`--no-progress-ticks` consecutive
ticks with nothing advancing), and a **budget ceiling** (`--budget-ceiling-usd`;
a timed-out worker is charged its per-worker cap as a floor, so the meter is
honest). An unset ceiling is simply inactive — it never reads as infinite.
The full production-grade build stack (AI critics, GitHub PR + CI integration,
auto-merge, deploy-green gating, the three-layer dead-worker reaper) is the
documented follow-on; this is the contract-driven core that takes a roadmap from
`planned` to a graded build.
## Install
Install straight from this repo — no PyPI needed:
```bash
# zero-install, always-latest (recommended)
uvx --from git+https://github.com/escotilha/oxison oxison run /path/to/repo
# pin to a release
pip install "git+https://github.com/escotilha/oxison.git@v0.3.0"
```
Or from a local clone:
```bash
uvx --from . oxison run /path/to/repo # zero-install, from a clone
# or
pip install -e . && oxison run /path/to/repo
```
Requires **Python ≥ 3.11** and the **Claude Code CLI** installed and signed in.
## Auth
By default oxison uses your existing Claude Code login (OAuth) — nothing
to configure. For CI, use `--bare` with `OXISON_API_KEY` or
`ANTHROPIC_API_KEY`.
## Model providers (Kimi, Grok)
oxison drives `claude -p`, which speaks the Anthropic Messages API — so any
model with an **Anthropic-compatible endpoint** can run the whole pipeline.
Two are built in via `--provider`:
```bash
export KIMI_API_KEY=... # or MOONSHOT_API_KEY
oxison run /path/to/repo --provider kimi # Kimi K2 (default model: kimi-k2.7-code)
export XAI_API_KEY=... # or GROK_API_KEY
oxison run /path/to/repo --provider grok # Grok (default model: grok-4.3)
oxison run /path/to/repo --provider grok --model grok-build-0.1 # agentic-build model
```
`--provider` works on every command — `run`, `plan`, `ideate`, and `build`. It
reads the provider key from the env var shown (or `--api-key`), points the
worker at the provider's endpoint via `ANTHROPIC_BASE_URL` + `ANTHROPIC_AUTH_TOKEN`,
and defaults the model to the provider's (override with `--model`). oxison never
reads `ANTHROPIC_*` from your ambient environment — the provider overlay is
constructed only from your explicit `--provider` choice, so it can't silently
override a normal Anthropic run. For sandboxed `oxison build`, the provider's API
host is added to the worker egress allowlist automatically.
## Usage
```bash
oxison run /path/to/repo
oxison run /path/to/repo --output-dir ./docs
oxison run /path/to/repo --model claude-sonnet-4-6 # cheaper than the Opus default
oxison run /path/to/repo --max-budget-usd 5 # cap spend per AI call
oxison run /path/to/repo --resume # skip steps already completed
oxison run /path/to/repo --chunk-threshold 60000 # tune map-reduce cutover
```
Run `oxison run --help` for the full flag list.
## Cost
oxison makes 5 AI calls for a small repo (comprehend + 3 docs + branch),
more for large repos (one comprehension worker per top-level directory +
a synthesis pass). It uses your Claude Code default model, which is
**Opus** — powerful but pricey (~$1–2 per call). For routine runs, pass
`--model claude-sonnet-4-6` and/or `--max-budget-usd` to cap spend. Every
call's cost is reported and recorded in `.oxison-run.json`.
## Resume
If a run is interrupted (or you want to regenerate only part of it),
`--resume` reads `.oxison-run.json` and skips steps already marked done.
The deterministic map always re-runs (it's free); cached AI steps are
skipped.
## Exit codes
| Code | Meaning |
|---|---|
| 0 | success |
| 2 | config error (bad target path, bad flag) |
| 3 | preflight failed (Claude CLI missing / not authed) |
| 4 | comprehension failed |
| 5 | artifact generation failed |
| 6 | branch (roadmap/security) failed |
## Optional roadmap-parser enrichment
If a private `oxi_core` roadmap-parser package happens to be importable,
oxison opportunistically uses it to add structure to `ROADMAP-ANALYSIS.md`.
It is **not** a dependency and is not published; the roadmap analysis works
on any roadmap format via the AI pass regardless of whether it's present.
## Run it from Claude Code (no terminal needed)
oxison ships as a [Claude Code](https://claude.com/claude-code) **plugin**, so
you can install and run it entirely from inside Claude Code — no shell, no
`pip`, no `cp`. From any Claude Code session:
```text
/plugin marketplace add escotilha/oxison # one time
/plugin install oxison@oxison # or pick it from the /plugin menu
```
Then just point it at a repo:
```text
/oxison /path/to/repo
```
…or simply ask **"document this repo"**. The skill resolves the `oxison` CLI
itself (zero-install via `uvx` if it isn't already on your `PATH` — see
[Install](#install)), defaults to Sonnet with a per-call budget cap for cost
safety, runs the read-only pipeline, and verifies the target repo was left
untouched after every run. Pass `--opus` for oxison's Opus default or
`--full-budget` to drop the budget cap.
> Updates: leave it on auto-update, or run `/plugin marketplace update oxison`
> to pull the latest.
Manual install (skill only, without the plugin system)
The skill lives at [`skills/oxison/SKILL.md`](skills/oxison/SKILL.md). To install
it directly instead of via the plugin:
```bash
mkdir -p ~/.claude/skills
cp -r skills/oxison ~/.claude/skills/oxison
```
## Development
```bash
uv venv --python 3.12 && . .venv/bin/activate
uv pip install -e ".[dev]"
ruff check src tests && mypy src && pytest -q
```
## License
MIT