Commit graph

41 commits

Author SHA1 Message Date
openhands
b7e09d17ef fix: Extract lib/pr-lifecycle.sh — walk-PR-to-merge library (#795)
New reusable library with clean function boundaries for the PR lifecycle:
- pr_create, pr_find_by_branch — PR creation and lookup
- pr_poll_ci — poll CI with infra vs code failure classification
- pr_poll_review — poll for review verdict (bot comments + formal reviews)
- pr_merge, pr_is_merged — merge with 405 handling and race detection
- pr_walk_to_merge — full orchestration loop (CI → review → merge)
- build_phase_protocol_prompt — git push instructions for agent prompts

The pr_walk_to_merge function uses agent_run() which callers must define
(guarded stub provided). This bridges to the synchronous SDK architecture
where the orchestrator bash loop IS the state machine — no phase files.

Extracted from: dev/phase-handler.sh, dev/dev-poll.sh, lib/ci-helpers.sh
Smoke test updated to include the new library.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:01:06 +00:00
openhands
fb44a9b248 fix: agent-smoke: use [(][)] for literal parens in BRE regex
Some BusyBox grep builds treat bare () as grouping operators even in BRE
mode, causing get_fns to miss function definitions like ci_commit_status.
Using [(][)] is unambiguous across all grep implementations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:18:42 +00:00
johba
ef544f58f9 fix: disinto init: auto-generate WOODPECKER_TOKEN for repo activation (#779) (#790)
Fixes #779

## Changes
Auto-generate WOODPECKER_TOKEN during disinto init by automating the Forgejo OAuth2 login flow after the compose stack starts. Adds generate_woodpecker_token() function that: logs into Forgejo web UI, drives the OAuth2 authorize/consent flow, completes the Woodpecker callback to get a session token, then creates a persistent personal access token via Woodpecker API. Saves to .env so activate_woodpecker_repo() can use it immediately. Failures are non-fatal (guarded with || true).

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/790
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-27 14:01:28 +01:00
openhands
4ce448b4c0 ci: run agent-smoke only on PRs, not push events
Push events test the raw branch which may be behind main.
PR events test the merge result, which is what matters.
This eliminates false CI failures that block the dev-agent.
2026-03-27 06:55:26 +00:00
johba
4251f9fb0e fix: disinto init: fails late if git user.name/user.email not configured (#778) (#780)
Fixes #778

## Changes
Add git identity warning to preflight_check() (warns if user.name/user.email missing) and auto-configure repo-local identity in setup_ops_repo() before the seed commit. This prevents init from failing late when git identity is not configured globally.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/780
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-27 06:59:06 +01:00
johba
f918e26cce dev: rebase on target branch before every push (#770) (#775)
Fixes #770

The dev agent was pushing fixes without rebasing. If main moved since the branch was created, the PR becomes unmergeable.

This adds a rebase step before every git push in the dev agent workflow:
- Initial push after implementing
- Push after CI fix
- Push after review feedback

Rebasing ensures PRs stay up-to-date with the target branch and avoids merge conflicts.

Co-authored-by: johba <johba@users.codeberg.org>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/775
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 21:46:21 +01:00
openhands
f830f3672a fix: smoke test treats function definitions as calls in BusyBox awk (#773)
Add "(" to the get_candidates skip list so that function definition
lines (e.g. memory_guard() {) are not extracted as call candidates.
Previously this was masked by get_fns also being broken on BusyBox
awk, but fixing get_fns exposed the get_candidates gap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:28:18 +00:00
openhands
46970377bb fix: disinto init: race condition in post-push empty check (#773)
Replace the single-shot Forgejo API emptiness check in push_to_forge()
with a retry loop (up to 5 attempts, 2s apart). Forgejo needs a brief
delay to index pushed refs, so the immediate check could see stale
metadata reporting empty=true even though the push succeeded.

Also fix agent-smoke.sh get_fns() to use POSIX character classes and
bracket-escaped parens for BusyBox awk compatibility in Alpine CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:12:57 +00:00
openhands
23949083c0 fix: Remove Matrix integration — notifications move to forge + OpenClaw (#732)
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>
2026-03-26 14:53:56 +00:00
johba
cc4c6d7efa Remove exec agent — replaced by OpenClaw skill + vault API (#722)
## What

Removes the exec agent (PR #697). Its functionality is replaced by:

1. **OpenClaw skill** — teaches any OpenClaw instance to be the factory's face
2. **Vault API** — structured interface for proposals, approvals, rejections

The exec agent was rebuilding OpenClaw in bash. Every piece has a native OpenClaw equivalent:
- CHARACTER.md → SOUL.md
- exec/MEMORY.md → MEMORY.md
- exec-session.sh → session management
- exec-briefing.sh → heartbeats/cron
- Matrix dispatch → channel plugins

## Why

Prudence isn't a separate agent. She's what OpenClaw becomes when it has the disinto skill. One LLM, one vault API, no LLM-to-LLM.

## Related

- #721 — remove escalation, route through vault
- #709 — skill registry research
- #466 — example project (vault should have handled this, not escalation)

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/722
2026-03-26 10:36:27 +01:00
disinto-exec
18cea8cad5 merge: integrate origin/main to resolve CI (matrix_send_ctx)
Merge main into feat/exec-agent to pick up ba1ab6e which added
matrix_send_ctx to lib/env.sh and action/action-agent.sh. Without
this merge, CI smoke test fails on the PR merge commit.

Re-applied exec changes on top of main:
- .env.example, AGENTS.md, bin/disinto, lib/matrix_listener.sh
- .woodpecker/agent-smoke.sh: exec scripts added to checks
2026-03-25 16:37:49 +00:00
openhands
687bf0ad5b fix: move tea-helpers.sh out of LIB_FUNS loop in smoke test (#666)
On Alpine/busybox, adding tea-helpers.sh to the LIB_FUNS for-loop
caused forge_api to go missing from the extracted function set.
Since no other script currently calls tea_* functions, tea-helpers.sh
is checked standalone via check_script instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:22:56 +00:00
openhands
44cbbbde62 feat: integrate tea CLI for forge issue/label/comment operations (#666)
- Add lib/tea-helpers.sh with tea_file_issue, tea_relabel, tea_comment,
  tea_close — thin wrappers preserving secret scanning on write ops
- Add tea 0.9.2 binary to docker/agents/Dockerfile
- Configure tea login in docker/agents/entrypoint.sh from FORGE_TOKEN/FORGE_URL
- Derive TEA_LOGIN in lib/env.sh (codeberg vs local forgejo)
- Source tea-helpers.sh conditionally when tea binary is available
- Migrate predictor formula from inline curl to tea CLI commands
- Register tea-helpers.sh in smoke test function resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:20:15 +00:00
openhands
55a22912d3 fix: run Forgejo as git user — refuses to run as root (#668)
Forgejo 11.0 refuses to run as root with a fatal error. Use su-exec
to run all forgejo commands as the 'git' user (pre-created in the
Forgejo Docker image). chown /data to git:git before starting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:19:31 +00:00
openhands
78e478e69d fix: use Forgejo image as step container for CLI access (#668)
The install endpoint POST returned 404 because FORGEJO__database__DB_TYPE
env var auto-configured Forgejo, bypassing install mode.

Fix: run the Forgejo image as the step container instead of a service.
This gives CLI access to `forgejo admin user create` for bootstrap
admin setup — no install endpoint needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 09:58:47 +00:00
openhands
9c2a5634ff fix: feat: end-to-end disinto init smoke test in CI (#668)
Add tests/smoke-init.sh — an end-to-end smoke test that runs
disinto init --bare --yes against a real Forgejo instance
(started as a Woodpecker service container).

The test validates:
- Forgejo API responds after init
- Admin and bot users created with tokens
- Repo created with labels on Forgejo
- Project TOML generated correctly
- .env written with FORGE_TOKEN and FORGE_REVIEW_TOKEN
- Cron entries installed (dev-poll, review-poll, gardener)

Uses mock binaries for docker (routes user creation to Forgejo
admin API), claude, tmux, and crontab to run in CI without
Docker-in-Docker.

Wired into CI via .woodpecker/smoke-init.yml (separate pipeline
with Forgejo service, runs on push and pull_request).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 09:37:36 +00:00
openhands
e535ed776f fix: feat: active-state files — per-cron guard with self-off semantics (#622)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:46:59 +00:00
openhands
d3f831f39e fix: Register lib/mirrors.sh in CI smoke test (#614)
Add mirrors.sh to the LIB_FUNS scan and check_script list so the
agent-smoke function resolution test recognizes mirror_push.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:20:59 +00:00
openhands
a66bd91721 fix: Replace Codeberg dependency with local Forgejo instance (#611)
- Add setup_forge() to bin/disinto: provisions Forgejo via Docker,
  creates admin + bot users (dev-bot, review-bot), generates API
  tokens, creates repo, and pushes code — all automated
- Rename env vars: CODEBERG_TOKEN→FORGE_TOKEN, REVIEW_BOT_TOKEN→
  FORGE_REVIEW_TOKEN, CODEBERG_REPO→FORGE_REPO, CODEBERG_API→
  FORGE_API, CODEBERG_WEB→FORGE_WEB, CODEBERG_BOT_USERNAMES→
  FORGE_BOT_USERNAMES (with backwards-compat fallbacks)
- Rename API helpers: codeberg_api()→forge_api(), codeberg_api_all()
  →forge_api_all() (with compat aliases)
- Add forge_url field to project TOML; load-project.sh derives
  FORGE_API/FORGE_WEB from forge_url + repo
- Update parse_repo_slug() to accept any host URL, not just codeberg
- Forgejo data stored under ~/.disinto/forgejo/ (not in factory repo)
- Update all 58 files: agent scripts, formulas, docs, site HTML

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:57:12 +00:00
openhands
446e6ef0a8 fix: Remove legacy predictor (prediction-poll.sh + prediction-agent.sh + cron entry) (#419)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:40:07 +00:00
openhands
b630c6fcc1 fix: gardener migration — run-gardener.toml via direct cron, remove legacy scripts (#490)
Rewrite gardener-run.sh as direct cron runner (matching supervisor/planner/
predictor pattern): lock guard, memory check, worktree, tmux session with
Claude sonnet + formulas/run-gardener.toml, phase monitoring, cleanup.

- Delete gardener-poll.sh and gardener-agent.sh (superseded)
- Extract consume_escalation_reply() to lib/formula-session.sh (shared
  by gardener and supervisor, eliminates duplicate blocks)
- Update AGENTS.md, gardener/AGENTS.md, lib/AGENTS.md, CI smoke test,
  and cross-references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:09:17 +00:00
openhands
2cc538d4fc fix: register lib/secret-scan.sh in CI smoke test function resolution
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 09:55:58 +00:00
openhands
20c02944c0 fix: address review — add check_script for lib/env.sh, fix comment alignment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 06:49:34 +00:00
openhands
e69ceddeb3 fix: Smoke test has no coverage for inline-sourced lib files beyond the four listed (#180)
- Add check_script calls for all inline-sourced lib files (agent-session.sh,
  ci-helpers.sh, file-action-issue.sh, formula-session.sh, load-project.sh)
  so their internal function calls are verified
- Add check_script calls for standalone lib scripts (ci-debug.sh,
  matrix_listener.sh, parse-deps.sh) and legacy prediction scripts
- Add documentation comment on LIB_FUNS listing included/excluded lib files
  with rationale for each

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 06:41:48 +00:00
openhands
53169f2514 fix: add supervisor and predictor scripts to agent-smoke CI test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:30:22 +00:00
johba
a15623b747 fix: fix: action-agent shares phase handler with dev-agent — review lifecycle + cleanup (#388) (#403)
Fixes #388

## Changes
Action-agent now sources dev/phase-handler.sh and enters monitor_phase_loop after prompt injection. Two paths: (A) git output triggers the same PR/CI/review lifecycle as dev-agent, (B) no-git output writes PHASE:done for cleanup. Adds docker compose down on terminal phases, escalation to supervisor on idle timeout, and proper temp file cleanup.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/403
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-20 17:39:44 +01:00
openhands
5bac4a8409 fix: extract lib/formula-session.sh to eliminate duplicate code blocks
Shared helpers for formula-driven cron agents: lock, memory guard,
formula loading, context building, session startup, crash recovery.

- planner-run.sh uses shared helpers instead of inline code
- gardener-agent.sh delegates crash recovery to formula_phase_callback
- agent-smoke.sh updated for renamed planner script + new lib file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:53:33 +00:00
openhands
59b6d76afa fix: extract file_action_issue helper to eliminate duplicate code blocks
CI duplicate-detection flagged shared action-issue filing pattern between
gardener-run.sh and planner-poll.sh. Extract into lib/file-action-issue.sh
and refactor both scripts to use it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:49:08 +00:00
openhands
9c51f4dbe2 fix: agent-smoke get_fns — use literal [ \t] for busybox awk compat
Busybox awk in Alpine CI has incomplete POSIX character class support;
[[:space:]] intermittently fails to match, causing function definitions
to be missed from LIB_FUNS. Replace with literal [ \t] patterns.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:02:40 +00:00
openhands
c3714380d7 fix: agent-smoke — explicit source for gardener monitor_phase_loop
Add lib/agent-session.sh as explicit extra definition source for the
gardener-agent.sh check in agent-smoke.sh. Alpine busybox awk in CI
intermittently fails to resolve monitor_phase_loop from LIB_FUNS;
listing it as a direct cross-source makes the check robust.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:46:40 +00:00
openhands
6c7557e87b fix: feat: planner as cron-driven formula (no issue tracking) (#232)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:00:56 +00:00
openhands
5e4b00f9a3 fix: duplicate-detection CI step fails on pre-existing duplicates unrelated to PR (#296)
Add baseline comparison to detect-duplicates.py: when DIFF_BASE is set
(via CI_COMMIT_TARGET_BRANCH for PRs), the script compares findings
against the base branch and only fails on new duplicates introduced by
the PR. Pre-existing duplicates are reported as informational.

For push events (no DIFF_BASE), the script reports all findings but
exits 0 (informational only). Removes failure:ignore from the CI step
so new duplicates properly block PRs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:03:18 +00:00
openhands
268ddc398c fix: use awk instead of grep -Eo in smoke test for Alpine compatibility (#296)
busybox grep on Alpine handles ERE character classes [(][)] differently
from GNU grep, causing get_fns to miss function definitions like
handle_ci_exhaustion(). awk is portable and works identically on all
platforms.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 19:43:42 +00:00
johba
d5c2c213a3 fix: bug: gardener hangs forever when Claude finishes without writing phase file (#261) (#263)
Fixes #261

## Changes
Fixed gardener hanging forever when Claude skips phase protocol. Three changes: (1) gardener-agent.sh: replaced 999999s timeout with 7200s (2h, matching dev-agent); (2) lib/agent-session.sh: added idle-prompt detection to monitor_phase_loop — if Claude returns to the ❯ prompt for 3 consecutive polls with no phase file written, exits immediately with _MONITOR_LOOP_EXIT=idle_prompt (only fires when phase file is empty, so awaiting_ci/review waits are unaffected); (3) gardener prompt: removed 'no time limit' wording, replaced with explicit phase-write requirement.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/263
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-19 13:47:10 +01:00
openhands
4e56d14e6a fix: feat: action-agent — tmux + Claude + formula for operational tasks (#139)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 07:25:25 +00:00
openhands
7e008991a7 fix: agent-smoke.sh: use [(][)] instead of \(\) for BusyBox grep ERE compat
BusyBox grep (Alpine CI) does not treat \( as a literal paren in -E mode,
causing inject_formula to appear undefined even though it is defined in
lib/agent-session.sh. Using [(][)] is unambiguous in both GNU grep and
BusyBox grep.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 21:24:27 +00:00
openhands
55b5628e24 feat: CI smoke test — syntax check + function resolution for all agent scripts (#177)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 17:11:02 +00:00
openhands
bd02330b22 fix: shellcheck TODO has no enforcement — || true may never be removed (#71)
- 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>
2026-03-18 01:53:02 +00:00
openhands
29d76c6d8b fix: make shellcheck non-blocking until existing warnings are fixed
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.
2026-03-17 16:35:12 +00:00
openhands
f541bcb073 fix: address AI review findings for CI pipeline and duplicate detection
- 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>
2026-03-17 10:18:39 +00:00
openhands
ee1af38390 fix: feat: Woodpecker CI pipeline with ShellCheck + duplicate code detection (#45)
- Add .woodpecker/ci.yml: two-step pipeline (shellcheck + duplicate detection)
- Add .woodpecker/detect-duplicates.py: sliding-window hash detection (5-line
  windows, 2+ files) plus grep-based anti-pattern checks (hardcoded CI_STATE,
  hardcoded WOODPECKER_REPO_ID). Runs as failure: ignore so CI stays green
  while findings are visible in logs.
- Add .shellcheckrc: disable SC1090/SC1091 (dynamic source paths are
  intentional; all scripts use the same lib/env.sh pattern)
- Update projects/disinto.toml: woodpecker_repo_id = 4, remove bypass comment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 10:02:58 +00:00