- Restore `-d` flag on codeberg_api POST /issues call (regression fix)
- Do NOT apply `formula` label — dev-agent rejects it, blocking the pipeline
- Keep YAML front matter in body only (structural, harmless to freeform processing)
- Quote YAML var values with @json to handle special characters
- Validate formula name against on-disk formulas/*.toml catalog
- Fall back to freeform if Claude hallucinates a formula name
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Planner: both phases use claude -p (one-shot), not interactive
- Vault: document auto-approve/auto-reject paths, not just human escalation
- CHECK_INFRA_RETRY: env var only, not a TOML toggle — separated from TOML keys
- underspecified label: also set by dev-agent.sh mid-run, not just dev-poll
- ci-helpers.sh: add missing review-poll.sh to sourced-by list
- parse-deps.sh: note it is executed via bash, not sourced
- vault: add PROMPT.md to key files list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract CI-exhaustion check/escalate logic into handle_ci_exhaustion() helper.
All three call sites (orphaned PRs, stuck PRs, backlog PRs) now use the shared
function, eliminating future drift between the copies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Bug: chicken-egg-ci create-per-file-issues was aliased to shellcheck-only
function. Added generic playbook_lint_per_file() that handles any linter
output format. Renamed action to lint-per-file.
- Bug: cascade-rebase fired retry-merge synchronously after async rebase.
Removed retry-merge and re-approve from recipe — rebase settles, CI reruns,
normal flow handles merge on subsequent cycle.
- Warning: jq calls on PR data lacked || true under set -euo pipefail. Fixed.
- Warning: playbook_rebase_pr and playbook_retrigger_ci incremented
_PB_SUB_CREATED before confirming API success. Now check HTTP status code.
- Warning: Python import tomllib fails on < 3.11. Added try/except fallback
to tomli package.
- Nit: failures_on_unchanged regex broadened to handle generic linter formats
(file.sh:line:col patterns in addition to ShellCheck's "In file line N:").
- Info: match_recipe now logs Python stderr on error instead of silently
falling back to generic recipe.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>