No description
- Add dedup guard: skip dust entries for issues already in dust.jsonl - Inject already-staged issue list into LLM prompt to prevent re-emission - Guard mv after jq: only overwrite dust.jsonl if jq succeeded - Use sort -nu for numeric dedup of issue numbers - Compute bundle count from distinct issues, not raw entries - Add 30-day TTL expiry for sub-threshold dust groups - Fix inconsistent heading levels in bundle body (all ###) - Add scope note to PROMPT.md (human docs only, not injected) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .woodpecker | ||
| dev | ||
| docs | ||
| formulas | ||
| gardener | ||
| lib | ||
| planner | ||
| projects | ||
| review | ||
| site | ||
| supervisor | ||
| vault | ||
| .env.example | ||
| .gitignore | ||
| .shellcheckrc | ||
| AGENTS.md | ||
| al76.png | ||
| BOOTSTRAP.md | ||
| README.md | ||
| RESOURCES.example.md | ||
| VISION.md | ||
Disinto
Autonomous code factory — disinto.ai
A mining robot, lost and confused, builds a Disinto from scrap —
a device so powerful it vaporizes three-quarters of a mountain on a single battery.
— Isaac Asimov, "Robot AL-76 Goes Astray" (1942)
Point it at a Codeberg repo with a Woodpecker CI pipeline and it will pick up issues, implement them, review PRs, and keep the system healthy — all on its own.
Architecture
cron (*/10) ──→ supervisor-poll.sh ← supervisor (bash checks, zero tokens)
├── all clear? → exit 0
└── problem? → claude -p (diagnose, fix, or escalate)
cron (*/10) ──→ dev-poll.sh ← pulls ready issues, spawns dev-agent
└── dev-agent.sh ← claude -p: implement → PR → CI → review → merge
cron (*/10) ──→ review-poll.sh ← finds unreviewed PRs, spawns review
└── review-pr.sh ← claude -p: review → approve/request changes
cron (daily) ──→ gardener-poll.sh ← backlog grooming (duplicates, stale, tech-debt)
└── claude -p: triage → promote/close/escalate
systemd ──→ matrix_listener.sh ← long-poll daemon for human replies
└── dispatches thread replies → supervisor/gardener
all agents ──→ matrix_send() ← status updates, escalations, merge notifications
Prerequisites
Required:
- Claude CLI —
claudein PATH, authenticated - Codeberg account with an API token — disinto reads issues, opens PRs, posts comments, and merges via the Codeberg API
- A second Codeberg account for the review bot — reviews posted under a separate identity so the dev-agent doesn't review its own PRs (
REVIEW_BOT_TOKEN) - Woodpecker CI — local instance connected to your Codeberg repo; disinto monitors pipelines, retries failures, and queries the Woodpecker Postgres DB directly
- PostgreSQL client (
psql) — for Woodpecker DB queries (pipeline status, build counts) jq,curl,git
Optional:
- Matrix homeserver (Dendrite or Synapse) — real-time notifications, escalation threads with human-in-the-loop replies
- Foundry (
forge,cast,anvil) — only needed if your target project uses Solidity - Node.js — only needed if your target project uses Node
Setup
# 1. Clone
git clone ssh://git@codeberg.org/johba/disinto.git
cd disinto
# 2. Configure
cp .env.example .env
Edit .env with your values:
# Target repo
CODEBERG_REPO=yourorg/yourproject # Codeberg org/repo slug
CODEBERG_API=https://codeberg.org/api/v1/repos/yourorg/yourproject
PROJECT_REPO_ROOT=/path/to/your/project # local clone of the target repo
# Auth tokens
CODEBERG_TOKEN=... # main account — or put it in ~/.netrc
REVIEW_BOT_TOKEN=... # separate Codeberg account for code reviews
# Woodpecker CI
WOODPECKER_SERVER=http://localhost:8000
WOODPECKER_TOKEN=...
WOODPECKER_DB_PASSWORD=...
WOODPECKER_DB_USER=woodpecker
WOODPECKER_DB_HOST=127.0.0.1
WOODPECKER_DB_NAME=woodpecker
# Tuning
CLAUDE_TIMEOUT=7200 # max seconds per Claude invocation (default: 2h)
# 3. Install cron (staggered to avoid overlap)
crontab -e
# Add:
# 0,10,20,30,40,50 * * * * /path/to/disinto/supervisor/supervisor-poll.sh
# 3,13,23,33,43,53 * * * * /path/to/disinto/review/review-poll.sh
# 6,16,26,36,46,56 * * * * /path/to/disinto/dev/dev-poll.sh
# 15 8 * * * /path/to/disinto/gardener/gardener-poll.sh
# 4. Verify
bash supervisor/supervisor-poll.sh # should log "all clear"
Directory Structure
disinto/
├── .env.example # Template — copy to .env, add secrets + project config
├── .gitignore # Excludes .env, logs, state files
├── lib/
│ ├── env.sh # Shared: load .env, PATH, API helpers, matrix_send()
│ ├── ci-debug.sh # Woodpecker CI log/failure helper
│ ├── matrix_listener.sh # Matrix long-poll daemon (dispatches replies)
│ └── matrix_listener.service # systemd unit for the listener
├── dev/
│ ├── dev-poll.sh # Cron entry: find ready issues
│ └── dev-agent.sh # Implementation agent (claude -p)
├── review/
│ ├── review-poll.sh # Cron entry: find unreviewed PRs
│ └── review-pr.sh # Review agent (claude -p)
├── gardener/
│ ├── gardener-poll.sh # Cron entry: backlog grooming
│ └── best-practices.md # Gardener knowledge base
└── supervisor/
├── supervisor-poll.sh # Supervisor: health checks + claude -p
├── PROMPT.md # Supervisor's system prompt
├── update-prompt.sh # Self-learning: append to best-practices
└── best-practices/ # Progressive disclosure knowledge base
├── memory.md
├── disk.md
├── ci.md
├── codeberg.md
├── dev-agent.md
├── review-agent.md
└── git.md
Agents
| Agent | Trigger | Job |
|---|---|---|
| Supervisor | Every 10 min | Health checks (RAM, disk, CI, git). Calls Claude only when something is broken. Self-improving via best-practices/. |
| Dev | Every 10 min | Picks up backlog-labeled issues, creates a branch, implements, opens a PR, monitors CI, responds to review, merges. |
| Review | Every 10 min | Finds PRs without review, runs Claude-powered code review, approves or requests changes. |
| Gardener | Daily | Grooms the issue backlog: detects duplicates, promotes tech-debt to backlog, closes stale issues, escalates ambiguous items. |
Design Principles
- Bash for checks, AI for judgment — polling and health checks are shell scripts; Claude is only invoked when something needs diagnosing or deciding
- Pull over push — dev-agent derives readiness from merged dependencies, not labels or manual assignment
- Progressive disclosure — the supervisor reads only the best-practices file relevant to the current problem, not all of them
- Self-improving — when Claude fixes something new, the lesson is appended to best-practices for next time
- Project-agnostic — all project-specific values (repo, paths, CI IDs) come from
.env, not hardcoded scripts