kill_tmux_session → agent_kill_session
inject_into_session → agent_inject_into_session
wait_for_claude_ready → agent_wait_for_claude_ready
Also restore status() function lost during #160 refactor.
Fixes dev-agent and gardener-agent crash on startup:
line 149: status: command not found
line 280: kill_tmux_session: command not found
Fixes#160
## Changes
Extracted phase callback functions (post_refusal_comment, do_merge, _on_phase_change) from dev/dev-agent.sh into new dev/phase-handler.sh. dev-agent.sh now sources both lib/agent-session.sh and dev/phase-handler.sh. Replaced inline dependency extraction with lib/parse-deps.sh. dev-agent.sh reduced from 1516 to 684 lines (55% reduction). AGENTS.md shellcheck command updated to include the new files.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/173
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
- `ci_fix_check_and_increment` now accepts an optional `check_only` arg:
- count < 3, check_only: returns `ok:N` without incrementing (deferred
to launch time, preserving the WAITING_PRS protection)
- count < 3, non-check_only: increments and returns `ok:N` (unchanged)
- count == 3 (any mode): atomically bumps to 4 and returns
`exhausted_first_time:3` — only one concurrent poller can win this
- count > 3 (any mode): returns `exhausted:N` with no write
- `handle_ci_exhaustion` unified to a single code path for both
check_only and non-check_only:
- Writes escalation JSONL + matrix_send only when sentinel is
`exhausted_first_time` — never on a bare integer comparison outside
a lock
- Removes the two separate `ci_fix_increment` bump-to-4 calls that
were racy (the sentinel bump is now inside the flock in Python)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the head -10 cap from TECH_DEBT_ISSUES so Claude sees all
tech-debt issues, not just the first 10. Apply a head -50 guard on
the list passed in PROBLEMS to avoid oversized prompts while still
feeding far more than the old cap. Update the problem label to drop
"max 10 per run" text which contradicted the zero-tech-debt objective.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous commit introduced a counter leak in the backlog scan path:
handle_ci_exhaustion (without check_only) atomically incremented the CI
fix counter before the WAITING_PRS guard, so an exit 0 that never spawned
a dev-agent would silently consume one of the three allowed fix attempts.
Restore the READY_PR_FOR_INCREMENT / deferred-increment mechanism:
- Backlog scan calls handle_ci_exhaustion with "check_only" (read-only,
no increment) to detect exhaustion without touching the counter.
- The counter is bumped atomically at LAUNCH time via handle_ci_exhaustion
(without check_only), so the increment only happens when we are certain
a dev-agent is being spawned. If a concurrent poller already exhausted
the counter between scan and launch, the LAUNCH call returns 0 and we
bail out cleanly without double-spawning.
The in-progress, stuck-PR, and try_merge_or_rebase paths are unaffected:
they call handle_ci_exhaustion without check_only, which continues to use
the atomic ci_fix_check_and_increment to prevent concurrent double-spawning.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add ci_fix_check_and_increment() that performs read + threshold-check +
conditional increment in a single flock-protected Python call, replacing
the prior three-step sequence (ci_fix_count / bash check / ci_fix_increment)
that allowed two concurrent poll invocations to both pass the threshold and
spawn duplicate dev-agents for the same PR.
handle_ci_exhaustion now calls ci_fix_check_and_increment atomically and
returns the new count in CI_FIX_ATTEMPTS; all separate ci_fix_increment
calls after handle_ci_exhaustion (including the deferred READY_PR_FOR_INCREMENT
mechanism) are removed. Log messages updated from CI_FIX_ATTEMPTS+1 to
CI_FIX_ATTEMPTS to reflect the post-increment count.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove || break from the codeberg_api call in the pagination loop.
With set -euo pipefail in all callers, a failed fetch now exits the
function non-zero — matching the original curl -sf behaviour where a
network or auth error aborted the script rather than returning empty
results and risking a duplicate review.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace ${CODEBERG_WEB} with inline https://codeberg.org/${CODEBERG_REPO}
to avoid unbound variable crash in gardener-poll.sh (set -euo pipefail)
- Change sub-issue title prefix from fix: to chore: since it's an
investigation task, not a code fix
- Add emoji prefix to idle_timeout matrix notification for consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap ci_fix_count(), ci_fix_increment(), and ci_fix_reset() with flock
on a shared lockfile to prevent concurrent modification of the JSON
tracker. Uses flock(1) in command-wrapping mode so each Python process
holds an exclusive lock for the duration of its read-modify-write cycle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>