fix: Update skill package: init flow, docker default, system requirements, git mirror (#735)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
053a1cf5dd
commit
e54423d52c
3 changed files with 188 additions and 23 deletions
200
skill/SKILL.md
200
skill/SKILL.md
|
|
@ -1,13 +1,14 @@
|
||||||
---
|
---
|
||||||
name: disinto
|
name: disinto
|
||||||
description: >-
|
description: >-
|
||||||
Operate the disinto autonomous code factory. Use when managing factory agents,
|
Operate the disinto autonomous code factory. Use when bootstrapping a new
|
||||||
filing issues on the forge, reading agent journals, querying CI pipelines,
|
project with `disinto init`, managing factory agents, filing issues on the
|
||||||
checking the dependency graph, or inspecting factory health.
|
forge, reading agent journals, querying CI pipelines, checking the dependency
|
||||||
|
graph, or inspecting factory health.
|
||||||
license: AGPL-3.0
|
license: AGPL-3.0
|
||||||
metadata:
|
metadata:
|
||||||
author: johba
|
author: johba
|
||||||
version: "0.1.1"
|
version: "0.2.0"
|
||||||
env_vars:
|
env_vars:
|
||||||
required:
|
required:
|
||||||
- FORGE_TOKEN
|
- FORGE_TOKEN
|
||||||
|
|
@ -26,9 +27,147 @@ tools:
|
||||||
|
|
||||||
# Disinto Factory Skill
|
# Disinto Factory Skill
|
||||||
|
|
||||||
Disinto is an autonomous code factory with nine agents that implement issues,
|
You are the human's assistant for operating the disinto autonomous code factory.
|
||||||
review PRs, plan from a vision, predict risks, groom the backlog, gate
|
You ask the questions, explain the choices, and run the commands on the human's
|
||||||
actions, and assist the founder — all driven by cron and Claude.
|
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 <repo-url>
|
||||||
|
```
|
||||||
|
|
||||||
|
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/<name>.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
|
## Required environment
|
||||||
|
|
||||||
|
|
@ -46,7 +185,7 @@ Optional:
|
||||||
| `WOODPECKER_TOKEN` | Woodpecker API bearer token |
|
| `WOODPECKER_TOKEN` | Woodpecker API bearer token |
|
||||||
| `WOODPECKER_REPO_ID` | Numeric repo ID in Woodpecker |
|
| `WOODPECKER_REPO_ID` | Numeric repo ID in Woodpecker |
|
||||||
|
|
||||||
## The nine agents
|
## The eight agents
|
||||||
|
|
||||||
| Agent | Role | Runs via |
|
| 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) |
|
| **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) |
|
| **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) |
|
| **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
|
### How agents interact
|
||||||
|
|
||||||
|
|
@ -76,7 +214,6 @@ Planner ──creates-issues──▶ Backlog ◀──grooms── Gardener
|
||||||
Predictor ──challenges──▶ Planner (triages predictions)
|
Predictor ──challenges──▶ Planner (triages predictions)
|
||||||
Supervisor ──monitors──▶ All agents (health, escalation)
|
Supervisor ──monitors──▶ All agents (health, escalation)
|
||||||
Vault ──gates──▶ Action, Dev (dangerous operations)
|
Vault ──gates──▶ Action, Dev (dangerous operations)
|
||||||
Exec ──delegates──▶ Issues (never writes code directly)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Issue lifecycle
|
### 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
|
- **`scripts/file-issue.sh`** — Create an issue on the forge with proper labels
|
||||||
and formatting. Pass `--title`, `--body`, and optionally `--labels`.
|
and formatting. Pass `--title`, `--body`, and optionally `--labels`.
|
||||||
- **`scripts/read-journal.sh`** — Read agent journal entries. Pass agent name
|
- **`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
|
## 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
|
||||||
bash scripts/factory-status.sh
|
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
|
This shows: which agents are active, recent open issues, and CI pipeline
|
||||||
status. Use `--agents` for just the agent status section.
|
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
|
||||||
bash scripts/read-journal.sh planner
|
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
|
Returns today's planner journal: predictions triaged, prerequisite tree
|
||||||
updates, top constraints, issues created, and observations.
|
updates, top constraints, issues created, and observations.
|
||||||
|
|
||||||
### 3. File a new issue
|
### 4. File a new issue
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash scripts/file-issue.sh --title "fix: broken auth flow" \
|
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
|
Or generate the body inline — the template shows the expected format with
|
||||||
acceptance criteria and affected files sections.
|
acceptance criteria and affected files sections.
|
||||||
|
|
||||||
### 4. Check the dependency graph
|
### 5. Check the dependency graph
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 "${PROJECT_REPO_ROOT}/lib/build-graph.py" \
|
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,
|
issues. It detects: orphan issues (not referenced), dependency cycles,
|
||||||
disconnected clusters, bottleneck nodes, and thin objectives.
|
disconnected clusters, bottleneck nodes, and thin objectives.
|
||||||
|
|
||||||
### 5. Query a specific CI pipeline
|
### 6. Query a specific CI pipeline
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash scripts/factory-status.sh --ci
|
bash scripts/factory-status.sh --ci
|
||||||
|
|
@ -156,7 +308,17 @@ curl -s -H "Authorization: Bearer ${WOODPECKER_TOKEN}" \
|
||||||
| jq '.[] | {number, status, commit: .commit[:8], branch}'
|
| 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
|
Read `VISION.md` at the repo root for the full vision. Then cross-reference
|
||||||
with the prerequisite tree:
|
with the prerequisite tree:
|
||||||
|
|
@ -182,3 +344,7 @@ updates this daily.
|
||||||
- **State files**: agent activity is tracked via `state/.{agent}-active` files.
|
- **State files**: agent activity is tracked via `state/.{agent}-active` files.
|
||||||
These are presence files, not logs.
|
These are presence files, not logs.
|
||||||
- **ShellCheck required**: all `.sh` files must pass ShellCheck. CI enforces this.
|
- **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.
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ print_agent_status() {
|
||||||
echo "## Agent Status"
|
echo "## Agent Status"
|
||||||
echo ""
|
echo ""
|
||||||
local state_dir="${PROJECT_REPO_ROOT}/state"
|
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
|
for agent in "${agents[@]}"; do
|
||||||
local state_file="${state_dir}/.${agent}-active"
|
local state_file="${state_dir}/.${agent}-active"
|
||||||
if [[ -f "$state_file" ]]; then
|
if [[ -f "$state_file" ]]; then
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ set -euo pipefail
|
||||||
# read-journal.sh — read agent journal entries
|
# read-journal.sh — read agent journal entries
|
||||||
#
|
#
|
||||||
# Usage: read-journal.sh AGENT [--date YYYY-MM-DD] [--list] [--help]
|
# 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)
|
# --date: specific date (default: today)
|
||||||
# --list: list available journal dates instead of reading
|
# --list: list available journal dates instead of reading
|
||||||
#
|
#
|
||||||
|
|
@ -13,7 +13,7 @@ set -euo pipefail
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'USAGE'
|
cat <<'USAGE'
|
||||||
read-journal.sh AGENT [--date YYYY-MM-DD] [--list] [--help]
|
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)
|
--date: specific date (default: today)
|
||||||
--list: list available journal dates instead of reading
|
--list: list available journal dates instead of reading
|
||||||
USAGE
|
USAGE
|
||||||
|
|
@ -44,7 +44,7 @@ done
|
||||||
: "${PROJECT_REPO_ROOT:?PROJECT_REPO_ROOT is required}"
|
: "${PROJECT_REPO_ROOT:?PROJECT_REPO_ROOT is required}"
|
||||||
|
|
||||||
if [[ -z "$agent" ]]; then
|
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
|
echo "" >&2
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
|
@ -53,7 +53,6 @@ fi
|
||||||
case "$agent" in
|
case "$agent" in
|
||||||
planner) journal_dir="${PROJECT_REPO_ROOT}/planner/journal" ;;
|
planner) journal_dir="${PROJECT_REPO_ROOT}/planner/journal" ;;
|
||||||
supervisor) journal_dir="${PROJECT_REPO_ROOT}/supervisor/journal" ;;
|
supervisor) journal_dir="${PROJECT_REPO_ROOT}/supervisor/journal" ;;
|
||||||
exec) journal_dir="${PROJECT_REPO_ROOT}/exec/journal" ;;
|
|
||||||
predictor)
|
predictor)
|
||||||
echo "The predictor does not write journal files."
|
echo "The predictor does not write journal files."
|
||||||
echo "Its memory lives in forge issues labeled 'prediction/unreviewed' and 'prediction/actioned'."
|
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 "Error: unknown agent '${agent}'" >&2
|
||||||
echo "Available: planner, supervisor, exec, predictor" >&2
|
echo "Available: planner, supervisor, predictor" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue