Remove all Matrix/Dendrite infrastructure:
- Delete lib/matrix_listener.sh (long-poll daemon), lib/matrix_listener.service
(systemd unit), lib/hooks/on-stop-matrix.sh (response streaming hook)
- Remove matrix_send() and matrix_send_ctx() from lib/env.sh
- Remove MATRIX_HOMESERVER auto-detection, MATRIX_THREAD_MAP from lib/env.sh
- Remove [matrix] section parsing from lib/load-project.sh
- Remove Matrix hook installation from lib/agent-session.sh
- Remove notify/notify_ctx helpers and Matrix thread tracking from
dev/dev-agent.sh and action/action-agent.sh
- Remove all matrix_send calls from dev-poll.sh, phase-handler.sh,
action-poll.sh, vault-poll.sh, vault-fire.sh, vault-reject.sh,
review-poll.sh, review-pr.sh, supervisor-poll.sh, formula-session.sh
- Remove Matrix listener startup from docker/agents/entrypoint.sh
- Remove append_dendrite_compose() and setup_matrix() from bin/disinto
- Remove --matrix flag from disinto init
- Clean Matrix references from .env.example, projects/*.toml.example,
formulas/*.toml, AGENTS.md, BOOTSTRAP.md, README.md, RESOURCES.md,
PHASE-PROTOCOL.md, and all agent AGENTS.md/PROMPT.md files
Status visibility now via Codeberg PR/issue activity. Human interaction
via vault items through forge. Proactive alerts via OpenClaw heartbeats.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detect which git remote matches FORGE_URL by comparing the host portion
of FORGE_URL against remote push URLs. Store the result in FORGE_REMOTE
(defaults to "origin" when no match — preserving existing behavior for
Codeberg-direct setups).
Replace every hardcoded "origin" in fetch, push, worktree-add, and
prompt-injection commands across:
- dev/dev-agent.sh (worktree setup, phase protocol prompt)
- dev/phase-handler.sh (CI retrigger, review feedback, rebase instructions)
- review/review-poll.sh (review feedback injection)
- action/action-agent.sh (worktree setup, push instructions)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ci_commit_status() and ci_pipeline_number() helpers to
lib/ci-helpers.sh that query Woodpecker directly with a forge API
fallback. Replace all 12 inline forge commit status calls across 6
files with the new helpers.
Add setup_woodpecker() to bin/disinto init that creates a Forgejo
OAuth2 app for Woodpecker and activates the repo.
Document manual Woodpecker+Forgejo setup in BOOTSTRAP.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: two code paths injected merge curl commands into Claude's
session (review-poll.sh APPROVE injection and dev-agent.sh prompt
instructions). The PreToolUse guard correctly blocked these, causing
Claude to write PHASE:escalate instead of merging.
The bash phase handler already handles merging via do_merge() — which
runs outside Claude tool use and is not subject to the guard. Remove
the merge/close curl instructions from both Claude-facing prompts so
the bash orchestrator handles merges as intended.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove dead ROOM_ENCODED and EVENT_ID variables from matrix_listener.sh
(were suppressed with SC2034 instead of removed)
- Remove dead REPO variable from dev-poll.sh and review-poll.sh
- Update header comment in matrix_listener.sh to list all 5 reply-routing
cases (supervisor, gardener, dev, review, vault, action)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- matrix_listener.sh: review case now reads PR number from column 4 of
the standard $THREAD_MAP instead of column 2 of /tmp/review-thread-map
- review-pr.sh: pass PR_NUMBER as context_tag (4th arg) to matrix_send
so the standard MATRIX_THREAD_MAP has it in column 4; remove separate
/tmp/review-thread-map write
- review-poll.sh: prune from MATRIX_THREAD_MAP instead of the removed
/tmp/review-thread-map
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
review-pr.sh: After APPROVE verdict, kill tmux session, remove phase
file, review output, sentinel files, and review worktree. Same cleanup
for unknown verdicts. REQUEST_CHANGES keeps session alive per #300.
review-poll.sh: Add safety net in stale session cleanup loop — kill
sessions in terminal phase (PHASE:review_complete) even if review-pr.sh
cleanup was interrupted.
dev/phase-handler.sh: Add sentinel file cleanup (/tmp/ci-result-*,
/tmp/review-injected-*) to PHASE:done and PHASE:failed handlers.
dev-agent.sh: Add sentinel file cleanup to idle_timeout/idle_prompt
exit handler. Add belt-and-suspenders done) case to post-loop handler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After REQUEST_CHANGES/DISCUSS, review-pr.sh now writes PHASE:awaiting_changes
(with the reviewed SHA) instead of PHASE:review_complete. review-poll.sh gains
a re-review section that detects awaiting_changes sessions with new commits
and CI passing, then re-invokes review-pr.sh in the same tmux session.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add diff_has_code_files() and ci_required_for_pr() helpers to
ci-helpers.sh. Non-code PRs (docs/*, formulas/*, evidence/*, *.md)
that have no CI results now skip the CI gate instead of being stuck
forever.
Applied to:
- review-pr.sh: CI gate skipped for non-code PRs
- review-poll.sh: CI gate skipped for non-code PRs
- dev-poll.sh: CI state treated as "success" for non-code PRs in
orphan, stuck-PR, and backlog merge paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The APPROVE injection previously told the dev-agent to write PHASE:done
and let the orchestrator merge. Now the dev-agent merges directly, so the
injection includes the full merge + issue-close curl commands matching the
pattern already in the dev-agent.sh prompt.
Co-Authored-By: Claude Sonnet 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>
- 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>
- Fix anti-pattern regex 2 to match quoted form '"$CI_STATE" != "success"'
(was r'\$CI_STATE\s*!=\s*"success"', now r'"?\$CI_STATE"?\s*!=\s*"success"')
- Update both anti-pattern messages to say 'extract ci_passed() to lib/'
instead of implying it already exists as a shared helper in dev-poll.sh
- Add explicit 'when: event: [push, pull_request]' trigger block to ci.yml
- Add '-r' to xargs in shellcheck step to handle zero .sh files gracefully
- Fix operator precedence bug in review-poll.sh:62: scope the OR clause
with braces so CI_STATE=pending bypass only applies when WOODPECKER_REPO_ID=0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Projects with woodpecker_repo_id=0 (like disinto) have no CI status.
Review-poll treated empty CI state as failure and skipped all PRs.
Now treats empty/pending CI as pass when no CI is configured.