- dev-agent.sh: add explicit guard that skips formula-labeled issues with a
clear log message instead of silently producing no formula behavior
- BOOTSTRAP.md: rewrite formula label entry to state it is not yet functional
and that dev-agent will skip such issues until feat/formula is merged
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix SC2164: add || exit 1 to bare cd in update-prompt.sh
- Fix SC2155: separate declare and assign in env.sh, supervisor-poll.sh, dev-agent.sh
- Fix SC2034: inline suppression for vars used by sourced helpers
- Remove unused `mergeable` declaration, rename unused loop var to `_w`
- Remove || true from shellcheck CI step — failures are now blocking
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
- 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>
- 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>
- 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>
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>
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>
- 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>
- 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>
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>
## 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>
- 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>
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>
- 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>
- 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>
- 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>
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.