Commit graph

910 commits

Author SHA1 Message Date
openhands
a8d10931f6 fix: address review findings from issue #74
- 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>
2026-03-18 01:41:14 +00:00
openhands
530ce7319f fix: feat: gardener bundles dust into ore before promoting to backlog (#74)
- Add dust/ore rule to gardener LLM prompt: trivial tech-debt (comment
  fix, rename, style-only, single-line) outputs DUST: JSON instead of
  promoting individually
- Parse DUST lines from LLM output, validate JSON, append to dust.jsonl
  with timestamp
- After evaluation pass: check groups with 3+ items, create bundled
  backlog issue, close source issues with cross-reference
- Add gardener/dust.jsonl to .gitignore
- Create gardener/PROMPT.md documenting the dust vs ore philosophy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 01:33:09 +00:00
johba
e5f075eb97 Merge pull request 'fix: feat: supervisor auto-retriggers infra CI failures (#75)' (#104) from fix/issue-75 into main 2026-03-18 02:27:22 +01:00
openhands
1c5d3e7bbd fix: address review findings from issue #75
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 01:18:34 +00:00
openhands
57fdec9504 fix: feat: supervisor auto-retriggers infra CI failures (#75)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 01:08:35 +00:00
johba
f1959101e6 Merge pull request 'fix: feat: Matrix notifications — contextual, linked, conversational (#76)' (#102) from fix/issue-76 into main 2026-03-18 01:54:11 +01:00
openhands
8034b50315 fix: address review findings from issue #76
- Fix double-injection bug: flat-file write only when direct tmux inject didn't happen
- Fix ci_exhausted href='#' fallback to use CODEBERG_WEB/pulls/N
- Remove duplicate $THREAD_FILE in rm command
- HTML-escape CI snippet before embedding in <pre> block
- notify_ctx falls back to plain matrix_send when no thread exists
- Thread root uses HTML-formatted message for consistency
- Deduplicate _ci_pipeline_url variable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 00:42:00 +00:00
openhands
814706bf90 fix: feat: Matrix notifications — contextual, linked, conversational (#76)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 00:20:11 +00:00
johba
7cc9ce1b39 Merge pull request 'fix: feat: persistent Claude tmux session for reviewer (#78)' (#101) from fix/issue-78 into main 2026-03-18 01:11:28 +01:00
openhands
bf4c70086e fix: address review findings from issue #78
- Guard inject_into_session wait_for_claude_ready with || true
- Guard all tmux calls in inject_into_session with || true
- Add worktree cleanup to idle-timeout branch in review-poll.sh
- Check phase before sleep in wait_for_review_output (no 10s delay)
- Prune review-thread-map entries during session cleanup
- Skip human question injection during active review (phase check)
- Remove no-op tmux kill-session after has-session returns false
- Add ASCII fallback for Claude prompt detection (locale safety)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 00:04:30 +00:00
openhands
85d05cdee2 fix: feat: persistent Claude tmux session for reviewer (#78)
Rewrite review-pr.sh to use persistent tmux sessions instead of one-shot
claude -p. Re-reviews inject incremental diffs into the same session so
Claude remembers what it flagged and can verify fixes were addressed.

- review-pr.sh: tmux session review-{project}-{pr}, phase protocol
  (PHASE:review_complete), JSON output via file, retry on invalid JSON
- review-poll.sh: session lifecycle cleanup (merged/closed PRs, 4h idle)
- matrix_listener.sh: route human questions to review sessions via
  /tmp/review-thread-map

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 23:56:04 +00:00
johba
5ec587a7b6 Merge pull request 'fix: fix: review agent posts duplicate reviews when formal review submission fails (#96)' (#99) from fix/issue-96 into main 2026-03-18 00:34:31 +01:00
openhands
70c899040b fix: review agent posts duplicate reviews when formal review submission fails (#96)
Add fallback dedup check against comment watermarks before the formal
Codeberg review check. When the formal review submission fails silently,
the existing <!-- reviewed: SHA --> watermark in posted comments now
prevents the next poll cycle from re-reviewing the same commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 23:15:21 +00:00
johba
b9eea10835 Merge pull request 'fix: feat: dev-poll.sh injects CI results into tmux session (#81)' (#98) from fix/issue-81 into main 2026-03-18 00:09:40 +01:00
openhands
63e60de9d6 fix: address round 2 review findings from issue #81
- Move atomic mv inside gardener loop so reply is only claimed when a
  matching needs_human session exists (fixes reply-loss regression)
- Delay rm of claimed file until after successful injection in both
  supervisor and gardener (OOM/SIGKILL leaves file recoverable)
- Fix matrix_listener ack message: 'next poll' instead of 'next supervisor poll'

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 22:59:05 +00:00
openhands
bfe0c09b5c fix: address review findings from issue #81
- Fix dev-agent.sh comment: gardener-poll.sh is the backup injector, not review-poll.sh
- Add renotify marker cleanup to gardener injection path
- Use atomic mv to claim reply file, preventing double-injection race between supervisor and gardener
- Add break after supervisor injection for symmetry with gardener
- Remove overly prescriptive PHASE:awaiting_ci hardcode from injection instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 22:40:54 +00:00
openhands
48683e508c fix: feat: supervisor-poll.sh and gardener-poll.sh inject human replies into needs_human dev sessions (#81)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 22:33:28 +00:00
johba
9c9b3b3bde Merge pull request 'fix: poll for claude readiness before injecting prompt into tmux' (#97) from fix/dev-agent-prompt-injection into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/97
2026-03-17 23:23:25 +01:00
openhands
515c528e10 fix: poll for claude readiness before injecting prompt into tmux
Replace fixed sleep(3) + paste-buffer race with a wait_for_claude_ready()
function that polls the tmux pane for the ❯ prompt (up to 120s). This
fixes the bug where the initial prompt was pasted before Claude Code
finished initializing, resulting in a stuck session with an empty prompt.

Observed on issue #81: session sat idle for 42+ minutes because the
paste arrived during Claude's startup splash screen.

Changes:
- Add wait_for_claude_ready() that polls tmux capture-pane for ❯
- Call it inside inject_into_session() before every paste
- Use inject_into_session() for initial prompt (was inline paste-buffer)
- Remove fixed sleep(3) from session creation and recovery paths
- Fail hard if claude doesn't become ready within timeout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 23:23:12 +01:00
review_bot
ee881086d3 feat: add disinto.ai landing page to repo (#91)
## Summary
- Move the static landing page from the standalone `disinto-site` directory into `site/` so it lives in the repo
- Includes `index.html`, optimized images (`al76.jpg`, `al76.webp`), and the original magazine cover (`amazing-stories-1942.jpg`)
- Skipped the large `al76.png` (3MB) since the HTML only references the `.jpg` and `.webp` versions

## Test plan
- [ ] Verify `site/index.html` renders correctly when served
- [ ] Confirm images load properly with relative paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/91
Co-authored-by: review_bot <review_bot@noreply.codeberg.org>
Co-committed-by: review_bot <review_bot@noreply.codeberg.org>
2026-03-17 23:11:40 +01:00
johba
afdcdeb78f Merge pull request 'fix: feat: review-poll.sh injects review feedback into dev tmux session (#82)' (#89) from fix/issue-82 into main 2026-03-17 22:30:35 +01:00
openhands
4d0658dcdf fix: address review findings from issue #82
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:19:47 +00:00
openhands
88d04d9edb fix: feat: review-poll.sh injects review feedback into dev tmux session (#82)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 20:52:51 +00:00
johba
efc1745399 Merge pull request 'fix: feat: tmux session manager in dev-agent.sh (#80)' (#88) from fix/issue-80 into main 2026-03-17 21:46:16 +01:00
openhands
d59c09eb5b fix: address review findings from issue #80 phase protocol
- Add missing MAX_CI_FIXES=3 and MAX_REVIEW_ROUNDS=5 constants to the
  config section; referencing undefined variables with set -euo pipefail
  caused an abort on first CI failure or REQUEST_CHANGES review.

- cleanup() trap now calls kill_tmux_session() so any unexpected exit
  (SIGTERM, errexit, unbound variable) kills the Claude session rather
  than leaving it running autonomously without an orchestrator.

- do_merge() initial CI wait loop now breaks and returns 1 immediately
  on failure/error states, avoiding a full 10-minute poll before a
  merge attempt that would also fail.

- Inner review-poll loop no longer updates LAST_PHASE_MTIME when it
  detects a mid-wait phase-file change; leaving it stale ensures the
  outer loop detects and dispatches the new phase on its next tick
  (previously the phase was silently swallowed).

- post_refusal_comment dedup now fetches the last 5 comments and checks
  any of them, so a human reply between two agent runs no longer causes
  a duplicate refusal comment.

- Remove duplicate DELETE labels/backlog call in claim section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 20:40:35 +00:00
openhands
db92bc13b5 fix: feat: tmux session manager in dev-agent.sh (#80)
Replace fire-and-forget `claude -p` calls with a persistent tmux session
that Claude Code runs in interactively. The orchestrator (dev-agent.sh)
monitors a phase file and reacts to Claude's signals:

- Session lifecycle: create `dev-{project}-{issue}` tmux session, send
  the full initial prompt (issue body + phase protocol instructions) via
  `tmux load-buffer` / `tmux paste-buffer`, then enter a phase monitor loop.

- Phase monitor loop: polls `/tmp/dev-session-{project}-{issue}.phase`
  every 30s for mtime changes. Handles all five phase sentinels:
  - PHASE:awaiting_ci   → create PR if needed, poll CI, inject result
  - PHASE:awaiting_review → poll for review comment, inject verdict
  - PHASE:needs_human  → send Matrix notification, wait for injection
  - PHASE:done         → call do_merge(), exit on success
  - PHASE:failed       → detect refusal JSON vs genuine failure, post
                          comment / escalate, kill session, restore backlog

- Crash recovery: if the tmux session dies unexpectedly, dev-agent.sh
  restarts it in the same worktree and injects a recovery prompt with
  the last known phase and git diff.

- Idle timeout: 2h with no phase update kills the session gracefully.

- PR creation moved into the PHASE:awaiting_ci handler; Claude pushes the
  branch and writes the phase, orchestrator creates the PR and starts CI.

- Summary file `/tmp/dev-impl-summary-{project}-{issue}.txt` carries the
  implementation summary (for PR body) and refusal JSON between Claude and
  the orchestrator.

- All existing logic preserved: dep preflight, label management, do_merge()
  with rebase retry, CI escalation, prior art detection, log rotation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 20:20:38 +00:00
johba
fc4248cf6b Merge pull request 'fix: feat: auto-pull factory code on every agent spawn (#85)' (#87) from fix/issue-85 into main 2026-03-17 21:03:27 +01:00
openhands
1b29baebc3 fix: feat: auto-pull factory code on every agent spawn (#85)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 19:35:29 +00:00
johba
64b53aaad5 Merge pull request 'fix: feat: define phase-signaling protocol for persistent Claude sessions (#79)' (#84) from fix/issue-79 into main 2026-03-17 20:32:51 +01:00
openhands
2b534bb7ec fix: address review findings from issue #79 phase protocol
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 19:27:11 +00:00
openhands
275b92e8b5 fix: address review findings from issue #79 phase protocol
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 19:21:01 +00:00
openhands
d87b7db8f3 fix: feat: define phase-signaling protocol for persistent Claude sessions (#79)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 18:53:15 +00:00
johba
a74eb8ba08 Merge pull request 'fix: refactor: move escalation processing from supervisor to gardener (#67)' (#73) from fix/issue-67 into main 2026-03-17 19:36:48 +01:00
openhands
df2522a7cb fix: address review findings from issue #67 escalation refactor
- supervisor: skip *.done.jsonl in escalation glob (bug: wildcard matched
  harb.done.jsonl producing spurious 'pending' log noise every cycle)
- supervisor: use wc -l instead of grep -c . for line counting (style nit)
- supervisor: consume gardener-esc-resolved.log via fixed() so escalation
  resolutions appear in end-of-cycle supervisor reporting
- dev-poll: update all 'escalated to supervisor' log/matrix strings to
  'escalated to gardener' (lines 263, 268, 344, 420)
- gardener: track _esc_total_created across all escalation entries and
  write count to supervisor/gardener-esc-resolved.log after processing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 18:30:57 +00:00
openhands
150ede5605 fix: refactor: move escalation processing from supervisor to gardener (#67)
- dev-poll.sh: write escalations to per-project files
  (supervisor/escalations-{PROJECT_NAME}.jsonl) and add "project" field
  so each project's escalations are isolated; update is_escalated() to
  read from the same per-project paths
- gardener-poll.sh: add escalation processing block that reads the
  per-project escalation file, fetches CI logs via Woodpecker, and
  creates per-file ShellCheck sub-issues or generic CI failure issues
  labeled backlog — runs with the correct CODEBERG_API and
  WOODPECKER_REPO_ID already loaded from the project TOML
- supervisor-poll.sh: remove the escalation processing block; replace
  with a simple flog report counting pending escalations per project

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 17:32:56 +00:00
johba
2797325d00 Merge pull request 'fix: feat: Woodpecker CI pipeline with ShellCheck + duplicate code detection (#45)' (#48) from fix/issue-45 into main 2026-03-17 18:17:22 +01:00
johba
c5dd03b106 Merge pull request 'fix: chore: create formula label in Codeberg + add more formula templates (#22)' (#66) from fix/issue-22 into main 2026-03-17 18:08:55 +01:00
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
openhands
29d76c6d8b fix: make shellcheck non-blocking until existing warnings are fixed
ShellCheck finds real issues in existing code. Making it blocking
means the CI pipeline PR can't pass its own CI (chicken-and-egg).

Report warnings but don't fail — fix them incrementally via backlog.
2026-03-17 16:35:12 +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