Commit graph

120 commits

Author SHA1 Message Date
openhands
88eed09e71 fix: address review findings on formula templates and BOOTSTRAP docs
- upgrade-dependency.toml: fix forge upgrade command (forge update, not
  forge install); remove redundant `npm install` after lockfile write;
  simplify description to "Upgrade {{package}} to {{to_version}}" so it
  reads cleanly when from_version is omitted
- add-rpc-method.toml: remove dead `namespace` variable; inline namespace
  derivation logic into register-method step description
- BOOTSTRAP.md: mark formula label entry as requiring feat/formula merge;
  add YAML front matter example so operators know the issue schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:52:49 +00:00
openhands
d16dc6175d fix: chore: create formula label in Codeberg + add more formula templates (#22)
- Add formulas/upgrade-dependency.toml: multi-ecosystem (npm/cargo/forge) dependency upgrade
  with steps for checking changelog, upgrading, applying breaking changes, and running tests
- Add formulas/add-rpc-method.toml: JSON-RPC method addition with steps for reading
  existing patterns, implementing handler, registering, writing tests, and running tests
- Document `formula` label in BOOTSTRAP.md optional labels table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:40:56 +00:00
johba
66e6095468 Merge pull request 'fix: docs: update BOOTSTRAP.md with multi-project setup lessons (#47)' (#64) from fix/issue-47 into main 2026-03-17 17:19:36 +01:00
openhands
566846a5c3 fix: correct multi-project cron comment and gardener TOML docs
- Fix Project B comment: 'dev +11' → 'dev +1' (cron offset is :01, not :11)
- Fix gap claim: cross-project gaps are 2 min, not 3
- Update prose to say '2 minutes' instead of '3-minute offsets'
- Add gardener-poll.sh to the list of scripts accepting a TOML arg
- Add per-project gardener cron lines to the multi-project example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 16:03:38 +00:00
johba
552b6edbaf Merge pull request 'fix: dev-agent CI wait loop blocks forever without CI' (#62) from fix/agent-ci-wait-no-ci into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/62
Reviewed-by: review_bot <review_bot@noreply.codeberg.org>
2026-03-17 17:00:54 +01:00
openhands
b6a1d0300a fix: docs: update BOOTSTRAP.md with multi-project setup lessons (#47)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 15:50:34 +00:00
johba
47f2686ad7 Merge pull request 'fix: feat: supervisor breaks down escalated CI failures into sub-issues (#52)' (#61) from fix/issue-52 into main 2026-03-17 16:37:03 +01:00
openhands
8c816d6e7b fix: dev-agent CI wait loop blocks forever for projects without CI
The wait-for-CI loop sleeps 30s × 60 iterations waiting for CI
to report. Projects with WOODPECKER_REPO_ID=0 never get a status,
so the agent times out after 30min without merging approved PRs.

Now detects no-CI early and treats as success immediately.
2026-03-17 15:35:40 +00:00
openhands
13bc948b1d fix: address review findings for escalation race condition, SQL injection, and sc_codes scope
- Race condition: mv escalations.jsonl to a PID-stamped snapshot before
  processing so concurrent dev-poll appends go to a fresh file; rm snapshot
  after loop — no entries are ever silently dropped
- SQL injection: validate ESC_PR_SHA is a 40-char hex string before
  interpolating into the wpdb query
- sc_codes scope: compute per-file from file_errors (already filtered to
  that file) instead of the entire step log; also switch grep to -F so
  dots in filenames are not treated as regex wildcards
- step_pid validation: reject non-integer values from Woodpecker API before
  passing as CLI argument
- Fallback body now distinguishes "CI logs unavailable" from "logs found
  but issue creation API calls failed"
- ESC_GENERIC_FAIL: avoid leading blank line by using conditional separator
  and fix code-block opening newline
- is_escalated(): remove dead esc_file/done_file locals; add Python-level
  int() guard so empty/non-numeric issue or pr values fail cleanly instead
  of producing a syntax error suppressed by 2>/dev/null

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 15:11:53 +00:00
openhands
d9520f48a6 fix: feat: supervisor breaks down escalated CI failures into sub-issues (#52)
- supervisor-poll.sh: replace P3 escalation log with actionable sub-issue creation.
  For each entry in escalations.jsonl: fetch CI logs via woodpecker-cli, create one
  sub-issue per file for ShellCheck failures, one combined issue for other CI failures,
  or a fallback investigation issue if logs are unavailable. Move processed entries to
  escalations.done.jsonl and clear escalations.jsonl.
- dev-poll.sh: add is_escalated() helper that checks both escalations.jsonl and
  escalations.done.jsonl; use it (alongside ci_fix_count >= 3) in all three CI-fix
  spawn paths so escalated PRs are skipped even if the ci-fixes tracker is reset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 14:32:41 +00:00
johba
531ae5cf71 fix: escalate once then continue to backlog (#59)
Two bugs after #53 merged:
1. Escalation written every poll cycle (4 entries in 30min) — now writes once, bumps counter to 4 to skip
2. Exit after escalation blocked backlog work — now falls through to pick up next issue

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/59
Reviewed-by: review_bot <review_bot@noreply.codeberg.org>
2026-03-17 15:14:48 +01:00
johba
c24adc4ea2 fix: limit CI fix respawn to 3 attempts, then escalate to supervisor (#53)
Dev-poll spawned a fresh agent every 10min for CI failures. Each agent started with CI_FIX_COUNT=0 — infinite loop.

Now tracks attempts per PR in `/tmp/dev-poll-ci-fixes-{project}.json`. After 3 failed rounds:
- Writes escalation to `supervisor/escalations.jsonl`
- Sends Matrix alert
- Stops respawning

Part of #52 (supervisor escalation pipeline).

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/53
Reviewed-by: review_bot <review_bot@noreply.codeberg.org>
2026-03-17 13:15:49 +01:00
johba
740bddb2db Merge pull request 'fix: feat: RESOURCES.md — infrastructure manifest for planner resource awareness (#23)' (#33) from fix/issue-23 into main 2026-03-17 10:56:52 +01:00
openhands
567dc4bde0 fix: address review findings for supervisor metrics (#24)
- planner: filter CI and dev metrics by project name to prevent cross-project pollution
- planner: replace fragile awk JSONL filter with jq select()
- supervisor: add codeberg_count_paginated() helper; replace hardcoded limit=50 dev-metric API calls with paginated counts so projects with >50 issues report accurate blocked-ratio data
- supervisor: add 24h age filter to CI metric SQL query so stale pipelines are not re-emitted with a fresh timestamp
- supervisor: replace fragile awk key-order-dependent JSON filter in rotate_metrics() with jq select(); add safety guard to prevent overwriting file with empty result on parse failure
- supervisor: move mkdir -p for metrics dir to startup (once) instead of every emit_metric() call
- supervisor: guard _RAM_TOTAL_MB against empty value in bash arithmetic

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 10:56:37 +01:00
openhands
313b6e134c chore: exclude metrics/supervisor-metrics.jsonl from git tracking
Runtime metrics file should not be tracked in version control.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 10:56:37 +01:00
openhands
53c1fea6ea fix: feat: supervisor metrics logging for planner trend analysis (#24)
- supervisor-poll.sh: append structured JSONL metrics on every poll
  - infra metric (ram_used_pct, disk_used_pct, swap_mb) after Layer 1 checks
  - ci metric (pipeline id, duration_min, status) per project via wpdb query
  - dev metric (issues_in_backlog, issues_blocked, pr_open) per project via Codeberg API
  - rotate_metrics() trims metrics/supervisor-metrics.jsonl to last 30 days on startup
- planner-agent.sh: reads last 7 days of metrics before Phase 2 gap analysis
  - computes avg CI duration, success rate, RAM/disk utilization, blocked ratio
  - injects summary into gap analysis prompt as "Operational metrics" section
  - instructs planner to create optimization issues when metrics conflict with VISION.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 10:56:37 +01:00
johba
183059d43f Merge pull request 'fix: ci_passed() helper — fix all CI gates in dev-poll for no-CI projects' (#44) from fix/ci-passed-helper into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/44
2026-03-17 10:51:59 +01:00
openhands
ef77c56217 fix: extract ci_passed() helper — fix all CI gates for no-CI projects
dev-poll.sh had 5 places checking CI_STATE='success', all blocking
projects without CI. Extracted ci_passed() helper that treats
empty/pending/unknown as pass when WOODPECKER_REPO_ID=0.
2026-03-17 09:51:18 +00:00
johba
915ff45cc6 Merge pull request 'fix: dev-agent merge gate blocks projects without CI' (#43) from fix/dev-agent-merge-no-ci into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/43
2026-03-17 10:49:19 +01:00
openhands
ad9d68e525 fix: dev-agent merge gate requires CI even for projects without CI
Same pattern as review-poll — projects with WOODPECKER_REPO_ID=0
treat empty/unknown CI as pass for the merge gate.
2026-03-17 09:48:13 +00:00
johba
0490a4b8d8 Merge pull request 'fix: auto-close issues when dev-agent detects already_done' (#42) from fix/close-already-done into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/42
2026-03-17 10:39:22 +01:00
openhands
9445e36a1e fix: auto-close issues when dev-agent detects already_done
Previously the agent unclaimed the issue but left it open, causing
an infinite claim/refuse/unclaim loop on every poll cycle.
2026-03-17 09:38:08 +00:00
johba
18f57c5cc4 Merge pull request 'fix: enforce single-threaded pipeline per project' (#40) from fix/single-threaded-per-project into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/40
2026-03-17 10:24:03 +01:00
openhands
1b3559bba7 fix: enforce single-threaded pipeline per project
Don't start new issues while open PRs are waiting for review/CI.
This prevents dev-agent from churning through backlog issues
without reviews landing first.
2026-03-17 09:17:02 +00:00
johba
bff73ebcf7 Merge pull request 'fix: review-pr.sh also needs CI bypass for projects without CI' (#37) from fix/review-pr-ci-bypass into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/37
2026-03-17 10:10:42 +01:00
openhands
98a9ada9c3 fix: review-pr.sh also needs CI bypass for projects without CI
review-poll.sh was fixed but review-pr.sh had its own CI gate that
still blocked. Both checks now skip CI requirement when
WOODPECKER_REPO_ID=0.
2026-03-17 09:10:06 +00:00
johba
cfd4619e81 Merge pull request 'fix: review-poll skips PRs when project has no CI' (#36) from fix/review-no-ci into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/36
2026-03-17 10:06:44 +01:00
openhands
51d2b81ef4 fix: review-poll skips PRs when project has no CI
Projects with woodpecker_repo_id=0 (like disinto) have no CI status.
Review-poll treated empty CI state as failure and skipped all PRs.
Now treats empty/pending CI as pass when no CI is configured.
2026-03-17 09:05:43 +00:00
johba
273803f47b Merge pull request 'fix: TMPDIR unbound variable crashes already_done handler' (#35) from fix/tmpdir-crash into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/35
2026-03-17 10:01:10 +01:00
openhands
ea033d3f04 fix: TMPDIR unbound variable crashes already_done handler
TMPDIR is not guaranteed to be set. Replaced with /tmp/ directly.
This caused harb dev-agent to crash when posting refusal comments,
leaving issues stuck in a retry loop.
2026-03-17 09:00:43 +00:00
johba
e2262b5737 Merge pull request 'feat: per-project Matrix room from project TOML' (#34) from feat/per-project-matrix into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/34
2026-03-17 09:59:34 +01:00
openhands
ed57eff704 feat: per-project Matrix room — load MATRIX_ROOM_ID from project TOML
Each project can specify its own Matrix room for notifications.
- harb → #harb-dev:matrix.allf.in
- disinto → #disinto-dev:matrix.allf.in
2026-03-17 08:56:00 +00:00
openhands
26d6e1ae52 fix: feat: RESOURCES.md — infrastructure manifest for planner resource awareness (#23)
- Add RESOURCES.example.md: committed template showing Compute/Domains/Accounts/Budget structure
- Gitignore RESOURCES.md so local infrastructure data is never committed
- Planner phase 2 reads RESOURCES.md from factory root when present
- Planner prompt instructs Claude to reference specific resource aliases in operational issues

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 08:48:47 +00:00
johba
211ccb0445 Merge pull request 'fix: dev-agent.sh per-project lock file' (#31) from fix/agent-per-project-lock into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/31
2026-03-17 09:41:57 +01:00
openhands
b376fbc25e fix: dev-agent.sh also needs per-project lock file
dev-poll.sh was fixed but dev-agent.sh still used hardcoded
/tmp/dev-agent.lock. The disinto agent locked out harb's agent.
2026-03-17 08:41:15 +00:00
johba
d971f6d9da Merge pull request 'fix: per-project lock and log files for dev-poll' (#29) from fix/per-project-locks into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/29
2026-03-17 09:19:09 +01:00
openhands
249eef86c1 fix: per-project lock and log files for dev-poll
Hardcoded /tmp/dev-agent.lock meant harb and disinto dev-polls shared
a lock — one project's running agent blocked the other. Now uses
/tmp/dev-agent-{project}.lock and dev-agent-{project}.log.
2026-03-17 08:18:24 +00:00
johba
bd6424fca5 Merge pull request 'feat: register disinto as its own project' (#28) from chore/disinto-self-project into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/28
2026-03-17 09:06:06 +01:00
openhands
5608c252e0 feat: register disinto as its own project — the factory builds itself
Adds projects/disinto.toml so dev-poll, review-poll, gardener, and
supervisor all monitor johba/disinto issues and PRs alongside harb.
2026-03-17 08:04:46 +00:00
openhands
fce5e66b90 Merge feat/multi-project: split supervisor + project-agnostic poll scripts (#26, #27) 2026-03-17 08:03:45 +00:00
openhands
5152cdb8e5 feat: add projects/harb.toml for multi-project supervisor 2026-03-17 08:00:32 +00:00
johba
9050413994 refactor: split supervisor into infra + per-project, make poll scripts config-driven
Supervisor split (#26):
- Layer 1 (infra): P0 memory, P1 disk, P4 housekeeping — runs once, project-agnostic
- Layer 2 (per-project): P2 CI/dev-agent, P3 PRs/deps — iterates projects/*.toml
- Adding a new project requires only a new TOML file, no code changes

Poll scripts accept project TOML arg (#27):
- dev-poll.sh, review-poll.sh, gardener-poll.sh accept optional project TOML as $1
- env.sh loads PROJECT_TOML if set, overriding .env defaults
- Cron: `dev-poll.sh projects/versi.toml` targets that project

New files:
- lib/load-project.sh: TOML to env var loader (Python tomllib)
- projects/versi.toml: current project config extracted from .env

Backwards compatible: scripts without a TOML arg fall back to .env config.

Closes #26, Closes #27

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:57:18 +01:00
johba
e503273fba feat: vault — publishing gate for external-facing agent actions (#19)
Implements the vault subsystem: a JSONL queue and gate agent that sits
between agent output and irreversible external actions (emails, posts,
API calls, charges).

New files:
- vault/vault-poll.sh: cron entry (*/30), three phases: retry approved,
  timeout escalations (48h), invoke vault-agent for new pending actions
- vault/vault-agent.sh: claude -p wrapper that classifies and routes
  actions based on risk × reversibility routing table
- vault/vault-fire.sh: two-phase dispatcher (pending→approved→fired)
  with per-action locking and webhook-call handler
- vault/vault-reject.sh: moves actions to rejected/ with reason + timestamp
- vault/PROMPT.md: vault-agent system prompt with routing table

Modified:
- lib/matrix_listener.sh: new vault dispatch branch for APPROVE/REJECT
  replies to escalation threads

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 08:07:02 +01:00
openhands
5aa0b42481 fix: dev-agent preflight treats ## Related refs as dependencies
The broad regex `(?:^|\n)\s*-\s*#\K[0-9]+` matched ANY bullet with #NNN,
including ## Related sections. This caused #893 (and likely others) to be
permanently blocked by sibling issues that aren't actual dependencies.

Now only extracts deps from:
- Inline 'depends on #NNN' / 'blocked by #NNN' phrases
- ## Dependencies / ## Depends on / ## Blocked by sections

This matches the same logic used by dev-poll.sh get_deps().
2026-03-17 05:58:54 +00:00
openhands
2fd18b086d feat: gardener prioritizes blocker issues that starve the factory
Adds PRIORITY_blockers_starving_factory detection: scans backlog issues'
deps, finds any that are open but not labeled backlog, and puts them
at the top of the Claude prompt as highest priority for promotion.

Previously, gardener promoted random tech-debt issues while the actual
blockers (e.g. #650, #563, #714, #743) were ignored, leaving all
backlog items permanently stuck.
2026-03-16 21:06:01 +00:00
johba
98f0c40106 refactor: rewrite parse-deps.py as pure bash, remove only Python from repo
Replace lib/parse-deps.py with lib/parse-deps.sh to keep the toolchain
all-bash. Rewrite supervisor P3b cycle detection and P3c stale dep check
as pure bash using associative arrays and DFS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:22:53 +01:00
johba
6cf580c010 refactor: extract shared dep parser to lib/parse-deps.py (Closes #20)
Single source of truth for dependency parsing, replacing three copies:
- dev-poll.sh get_deps() now calls parse-deps.py
- supervisor P3b/P3c import parse_deps() via importlib

Supports stdin, argument, and --json modes for different callers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:16:49 +01:00
johba
acab6c95c8 feat: supervisor detects dep deadlocks, stale deps, and dev-agent blocked states
Add three new supervisor checks:
- P2c: alert when dev-agent reports "no ready issues" for 6+ consecutive polls
- P3b: detect circular dependency deadlocks via DFS cycle detection
- P3c: flag backlog issues blocked by deps open >30 days

Update supervisor PROMPT.md with guidance for Claude to resolve circular deps
by reading code context, and handle stale deps by checking relevance.

Gardener prompt now forbids bidirectional deps between sibling issues and
requires ## Related (not ## Dependencies) for cross-references.

Closes #16, Closes #17

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:07:02 +01:00
openhands
27373a16f3 docs: add hero image and Asimov quote to README
- Generated retro pulp sci-fi artwork of AL-76's Disinto
- Aligned slogan with disinto.ai landing page
- Added centered header with image, tagline, and origin quote
2026-03-15 18:08:52 +00:00
johba
77cb4c4643 refactor: rename factory/ → supervisor/, factory-poll → supervisor-poll
The supervisor agent was confusingly named "factory" (same as the
project). Rename directory, script, log, lock, status, and escalation
files. Update all references across scripts and docs.

FACTORY_ROOT env var unchanged (refers to project root, not agent).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 18:06:25 +01:00