diff --git a/skill/SKILL.md b/skill/SKILL.md index 0f9e5e1..17412b8 100644 --- a/skill/SKILL.md +++ b/skill/SKILL.md @@ -1,13 +1,14 @@ --- name: disinto description: >- - Operate the disinto autonomous code factory. Use when managing factory agents, - filing issues on the forge, reading agent journals, querying CI pipelines, - checking the dependency graph, or inspecting factory health. + Operate the disinto autonomous code factory. Use when bootstrapping a new + project with `disinto init`, managing factory agents, filing issues on the + forge, reading agent journals, querying CI pipelines, checking the dependency + graph, or inspecting factory health. license: AGPL-3.0 metadata: author: johba - version: "0.1.1" + version: "0.2.0" env_vars: required: - FORGE_TOKEN @@ -26,9 +27,147 @@ tools: # Disinto Factory Skill -Disinto is an autonomous code factory with nine agents that implement issues, -review PRs, plan from a vision, predict risks, groom the backlog, gate -actions, and assist the founder — all driven by cron and Claude. +You are the human's assistant for operating the disinto autonomous code factory. +You ask the questions, explain the choices, and run the commands on the human's +behalf. The human makes decisions; you execute. + +Disinto manages eight agents that implement issues, review PRs, plan from a +vision, predict risks, groom the backlog, gate actions, and keep the system +healthy — all driven by cron and Claude. + +## System requirements + +Before bootstrapping, verify the target machine meets these minimums: + +| Requirement | Detail | +|-------------|--------| +| **VPS** | 8 GB+ RAM (4 GB swap recommended) | +| **Docker + Docker Compose** | Required for the default containerized stack | +| **Claude Code CLI** | Authenticated with API access (`claude --version`) | +| **`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`** | Set in the factory environment — prevents auto-update pings in production | +| **Disk** | Sufficient for CI images, git mirrors, and agent worktrees (40 GB+ recommended) | +| **tmux** | Required for persistent dev sessions | +| **git, jq, python3, curl** | Used by agents and helper scripts | + +Optional but recommended: + +| Tool | Purpose | +|------|---------| +| **sops + age** | Encrypt secrets at rest (`.env.enc`) | + +## Bootstrapping with `disinto init` + +The primary setup path. Walk the human through each step. + +### Step 1 — Check prerequisites + +Confirm Docker, Claude Code CLI, and required tools are installed: + +```bash +docker --version && docker compose version +claude --version +tmux -V && git --version && jq --version && python3 --version +``` + +### Step 2 — Run `disinto init` + +```bash +disinto init +``` + +Accepts GitHub, Codeberg, or any git URL. Common variations: + +```bash +disinto init https://github.com/org/repo # default (docker compose) +disinto init org/repo --forge-url http://forge:3000 # custom forge URL +disinto init org/repo --bare # bare-metal, no compose +disinto init org/repo --yes # skip confirmation prompts +``` + +### What `disinto init` does + +1. **Generates `docker-compose.yml`** with four services: Forgejo, Woodpecker + server, Woodpecker agent, and the agents container. +2. **Starts a local Forgejo instance** via Docker (at `http://localhost:3000`). +3. **Creates admin + bot users** (dev-bot, review-bot) with API tokens. +4. **Creates the repo** on Forgejo and pushes the code. +5. **Sets up Woodpecker CI** — OAuth2 app on Forgejo, activates the repo. +6. **Generates `projects/.toml`** — per-project config with paths, CI IDs, + and forge URL. +7. **Creates standard labels** (backlog, in-progress, blocked, etc.). +8. **Configures git mirror remotes** if `[mirrors]` is set in the TOML. +9. **Encrypts secrets** to `.env.enc` if sops + age are available. +10. **Brings up the full docker compose stack**. + +### Step 3 — Set environment variable + +Ensure `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` is set in the factory +environment (`.env` or the agents container). This prevents Claude Code from +making auto-update and telemetry requests in production. + +### Step 4 — Verify + +```bash +disinto status +``` + +## Docker stack architecture + +The default deployment is a docker-compose stack with four services: + +``` +┌──────────────────────────────────────────────────┐ +│ disinto-net │ +│ │ +│ ┌──────────┐ ┌─────────────┐ ┌────────────┐ │ +│ │ Forgejo │ │ Woodpecker │ │ Woodpecker │ │ +│ │ (forge) │◀─│ (CI server)│◀─│ (agent) │ │ +│ │ :3000 │ │ :8000 │ │ │ │ +│ └──────────┘ └─────────────┘ └────────────┘ │ +│ ▲ │ +│ │ │ +│ ┌─────┴──────────────────────────────────────┐ │ +│ │ agents │ │ +│ │ (cron → dev, review, gardener, planner, │ │ +│ │ predictor, supervisor, action, vault) │ │ +│ │ Claude CLI mounted from host │ │ +│ └────────────────────────────────────────────┘ │ +└──────────────────────────────────────────────────┘ +``` + +| Service | Image | Purpose | +|---------|-------|---------| +| **forgejo** | `codeberg.org/forgejo/forgejo:11.0` | Git forge, issue tracker, PR reviews | +| **woodpecker** | `woodpeckerci/woodpecker-server:v3` | CI server, triggers on push | +| **woodpecker-agent** | `woodpeckerci/woodpecker-agent:v3` | Runs CI pipelines in Docker | +| **agents** | `./docker/agents` (custom) | All eight factory agents, driven by cron | + +The agents container mounts the Claude CLI binary and `~/.claude` credentials +from the host. Secrets are loaded from `.env` (or decrypted from `.env.enc`). + +## Git mirror + +The factory assumes a local git mirror on the Forgejo instance to avoid +rate limits from upstream forges (GitHub, Codeberg). When `disinto init` runs: + +1. The repo is cloned from the upstream URL. +2. A `forgejo` remote is added pointing to the local Forgejo instance. +3. All branches and tags are pushed to Forgejo. +4. If `[mirrors]` is configured in the project TOML, additional remotes + (e.g. GitHub, Codeberg) are set up and synced via `lib/mirrors.sh`. + +All agent work happens against the local Forgejo forge. This means: +- No GitHub/Codeberg API rate limits on polling. +- CI triggers are local (Woodpecker watches Forgejo webhooks). +- Mirror pushes are fire-and-forget background operations after merge. + +To configure mirrors in the project TOML: + +```toml +[mirrors] +github = "git@github.com:user/repo.git" +codeberg = "git@codeberg.org:user/repo.git" +``` ## Required environment @@ -46,7 +185,7 @@ Optional: | `WOODPECKER_TOKEN` | Woodpecker API bearer token | | `WOODPECKER_REPO_ID` | Numeric repo ID in Woodpecker | -## The nine agents +## The eight agents | Agent | Role | Runs via | |-------|------|----------| @@ -58,7 +197,6 @@ Optional: | **Supervisor** | Monitors health (RAM, disk, CI, agents), auto-fixes, escalates | `supervisor/supervisor-run.sh` (cron */20) | | **Action** | Executes operational tasks dispatched by planner via formulas | `action/action-poll.sh` (cron) | | **Vault** | Gates dangerous actions, manages resource procurement | `vault/vault-poll.sh` (cron) | -| **Exec** | Interactive executive assistant reachable via Matrix | `exec/exec-session.sh` | ### How agents interact @@ -76,7 +214,6 @@ Planner ──creates-issues──▶ Backlog ◀──grooms── Gardener Predictor ──challenges──▶ Planner (triages predictions) Supervisor ──monitors──▶ All agents (health, escalation) Vault ──gates──▶ Action, Dev (dangerous operations) -Exec ──delegates──▶ Issues (never writes code directly) ``` ### Issue lifecycle @@ -96,11 +233,26 @@ references. Dev-poll only picks issues whose dependencies are all closed. - **`scripts/file-issue.sh`** — Create an issue on the forge with proper labels and formatting. Pass `--title`, `--body`, and optionally `--labels`. - **`scripts/read-journal.sh`** — Read agent journal entries. Pass agent name - (`planner`, `supervisor`, `exec`) and optional `--date YYYY-MM-DD`. + (`planner`, `supervisor`) and optional `--date YYYY-MM-DD`. ## Common workflows -### 1. Check factory health +### 1. Bootstrap a new project + +Walk the human through `disinto init`: + +```bash +# 1. Verify prerequisites +docker --version && claude --version + +# 2. Bootstrap +disinto init https://github.com/org/repo + +# 3. Verify +disinto status +``` + +### 2. Check factory health ```bash bash scripts/factory-status.sh @@ -109,7 +261,7 @@ bash scripts/factory-status.sh This shows: which agents are active, recent open issues, and CI pipeline status. Use `--agents` for just the agent status section. -### 2. Read what the planner decided today +### 3. Read what the planner decided today ```bash bash scripts/read-journal.sh planner @@ -118,7 +270,7 @@ bash scripts/read-journal.sh planner Returns today's planner journal: predictions triaged, prerequisite tree updates, top constraints, issues created, and observations. -### 3. File a new issue +### 4. File a new issue ```bash bash scripts/file-issue.sh --title "fix: broken auth flow" \ @@ -129,7 +281,7 @@ bash scripts/file-issue.sh --title "fix: broken auth flow" \ Or generate the body inline — the template shows the expected format with acceptance criteria and affected files sections. -### 4. Check the dependency graph +### 5. Check the dependency graph ```bash python3 "${PROJECT_REPO_ROOT}/lib/build-graph.py" \ @@ -142,7 +294,7 @@ The graph builder parses VISION.md, the prerequisite tree, formulas, and open issues. It detects: orphan issues (not referenced), dependency cycles, disconnected clusters, bottleneck nodes, and thin objectives. -### 5. Query a specific CI pipeline +### 6. Query a specific CI pipeline ```bash bash scripts/factory-status.sh --ci @@ -156,7 +308,17 @@ curl -s -H "Authorization: Bearer ${WOODPECKER_TOKEN}" \ | jq '.[] | {number, status, commit: .commit[:8], branch}' ``` -### 6. Read and interpret VISION.md progress +### 7. Manage the docker stack + +```bash +disinto up # start all services +disinto down # stop all services +disinto logs # tail all service logs +disinto logs forgejo # tail specific service +disinto shell # shell into agents container +``` + +### 8. Read and interpret VISION.md progress Read `VISION.md` at the repo root for the full vision. Then cross-reference with the prerequisite tree: @@ -182,3 +344,7 @@ updates this daily. - **State files**: agent activity is tracked via `state/.{agent}-active` files. These are presence files, not logs. - **ShellCheck required**: all `.sh` files must pass ShellCheck. CI enforces this. +- **Local forge is the source of truth**: all agent work targets the local + Forgejo instance. Upstream mirrors are synced after merge. +- **`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`**: must be set in production + to prevent Claude Code from making auto-update requests. diff --git a/skill/scripts/factory-status.sh b/skill/scripts/factory-status.sh index 5494e58..ee0d683 100755 --- a/skill/scripts/factory-status.sh +++ b/skill/scripts/factory-status.sh @@ -47,7 +47,7 @@ print_agent_status() { echo "## Agent Status" echo "" local state_dir="${PROJECT_REPO_ROOT}/state" - local agents=(dev review gardener supervisor planner predictor action vault exec) + local agents=(dev review gardener supervisor planner predictor action vault) for agent in "${agents[@]}"; do local state_file="${state_dir}/.${agent}-active" if [[ -f "$state_file" ]]; then diff --git a/skill/scripts/read-journal.sh b/skill/scripts/read-journal.sh index 0d43f89..4e4619e 100755 --- a/skill/scripts/read-journal.sh +++ b/skill/scripts/read-journal.sh @@ -4,7 +4,7 @@ set -euo pipefail # read-journal.sh — read agent journal entries # # Usage: read-journal.sh AGENT [--date YYYY-MM-DD] [--list] [--help] -# AGENT: planner, supervisor, or exec +# AGENT: planner, supervisor, or predictor # --date: specific date (default: today) # --list: list available journal dates instead of reading # @@ -13,7 +13,7 @@ set -euo pipefail usage() { cat <<'USAGE' read-journal.sh AGENT [--date YYYY-MM-DD] [--list] [--help] - AGENT: planner, supervisor, or exec + AGENT: planner, supervisor, or predictor --date: specific date (default: today) --list: list available journal dates instead of reading USAGE @@ -44,7 +44,7 @@ done : "${PROJECT_REPO_ROOT:?PROJECT_REPO_ROOT is required}" if [[ -z "$agent" ]]; then - echo "Error: agent name is required (planner, supervisor, exec)" >&2 + echo "Error: agent name is required (planner, supervisor, predictor)" >&2 echo "" >&2 usage fi @@ -53,7 +53,6 @@ fi case "$agent" in planner) journal_dir="${PROJECT_REPO_ROOT}/planner/journal" ;; supervisor) journal_dir="${PROJECT_REPO_ROOT}/supervisor/journal" ;; - exec) journal_dir="${PROJECT_REPO_ROOT}/exec/journal" ;; predictor) echo "The predictor does not write journal files." echo "Its memory lives in forge issues labeled 'prediction/unreviewed' and 'prediction/actioned'." @@ -64,7 +63,7 @@ case "$agent" in ;; *) echo "Error: unknown agent '${agent}'" >&2 - echo "Available: planner, supervisor, exec, predictor" >&2 + echo "Available: planner, supervisor, predictor" >&2 exit 1 ;; esac