Lost during #160 refactor. These are dev-agent specific (reference
$ISSUE, $THREAD_FILE, $LOGFILE) so they belong in the agent script,
not the shared library.
Library functions need explicit session name argument — they no longer
have closure over $SESSION_NAME from the parent script.
- agent_kill_session: add $SESSION_NAME to all 11 call sites
- agent_inject_into_session: add $SESSION_NAME to all call sites in
phase-handler.sh and gardener-agent.sh
- agent_kill_session: guard against missing arg (defensive)
Both dev-agent.sh and gardener-agent.sh call these functions but they
were never implemented during the #158 extraction. Adds:
- create_agent_session(session, workdir) — tmux + claude + wait for ready
- inject_formula(session, text) — alias for agent_inject_into_session
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>