Commit graph

1021 commits

Author SHA1 Message Date
johba
e8328fb297 Merge pull request 'fix: Restore dev-poll.sh scheduler on SDK (#799)' (#809) from fix/issue-799 into main 2026-03-28 07:21:50 +01:00
openhands
8f93ea3af1 fix: Restore dev-poll.sh scheduler on SDK (#799)
Rewrite dev-poll.sh to remove all tmux session management and use
SDK shared libraries instead:

- Remove _inject_into_session(), handle_active_session() — no tmux
- Replace try_direct_merge() raw curl with pr_merge() from lib/pr-lifecycle.sh
- Replace _post_ci_blocked_comment() with issue_block() from lib/issue-lifecycle.sh
- Check PID lockfile instead of tmux sessions for active agent detection
- Clean up .sid files instead of .phase files
- Remove preflight wait loop (dev-agent.sh handles its own labels)
- Extract extract_issue_from_pr() helper to DRY up issue number extraction

Preserved from main:
- Ready-issue scanning (backlog label + deps met)
- Priority tier system (orphaned > priority+backlog > backlog)
- Orphaned issue detection (in-progress label but no active agent)
- Direct merge shortcut (approved + CI green -> merge without spawning agent)
- CI fix exhaustion tracking (per-PR counter, max 3 attempts -> blocked label)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 06:12:40 +00:00
johba
27c5ab996d Merge pull request 'fix: Migrate dev-agent.sh to SDK + shared libraries (#798)' (#808) from fix/issue-798 into main 2026-03-27 22:45:15 +01:00
openhands
bf44557897 fix: Deduplicate issue-fetch error guard (#798)
Collapse the 3-line error check into a single line to avoid triggering
the duplicate-detection CI check against action-agent.sh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:23:48 +00:00
openhands
76b149dc97 fix: Update smoke test cross-source refs for dev-agent migration (#798)
dev-agent.sh no longer sources phase-handler.sh. Update the smoke test
to resolve phase-handler.sh callbacks against action-agent.sh (which
still sources it and defines cleanup_labels/cleanup_worktree).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:20:55 +00:00
openhands
3e1f1c47f9 fix: Migrate dev-agent.sh to SDK + shared libraries (#798)
Rewrite dev-agent.sh from tmux session manager to synchronous bash loop:

- Replace tmux + phase-handler with synchronous claude -p invocations
- Define agent_run() wrapping claude -p with --resume for session continuity
- Use .sid file to persist session_id across crash recovery
- Delegate CI/review loop to pr_walk_to_merge() from lib/pr-lifecycle.sh
- Replace inline label management with lib/issue-lifecycle.sh
  (issue_claim, issue_release, issue_block, issue_close, issue_check_deps)
- Replace inline worktree management with lib/worktree.sh
  (worktree_create, worktree_recover, worktree_cleanup)
- Use pr_create/pr_find_by_branch from lib/pr-lifecycle.sh
- Use build_phase_protocol_prompt for push instructions
- Keep: issue fetch, recovery mode, prior art, prompt composition,
  concurrency lock, memory guard, refusal handling

The script drops from 745 to ~500 lines. No tmux sessions, no phase
file monitoring, no phase-handler.sh dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:15:04 +00:00
johba
37f3c0416d Merge pull request 'fix: Extract lib/worktree.sh — create, recover, cleanup (#797)' (#806) from fix/issue-797 into main 2026-03-27 20:28:15 +01:00
openhands
c5c24cda67 fix: Extract lib/worktree.sh — create, recover, cleanup (#797)
Extract reusable worktree management into lib/worktree.sh:
- worktree_create: git worktree add + checkout + submodules
- worktree_recover: detect existing worktree, reuse or recreate
- worktree_cleanup: remove worktree + clear Claude Code project cache
- worktree_cleanup_stale: scan /tmp for orphaned worktrees, skip preserved
- worktree_preserve: mark worktree for debugging (skip stale cleanup)

Update callers:
- dev-agent.sh: use worktree_create/worktree_recover/worktree_cleanup
- action-agent.sh: use worktree_cleanup/worktree_preserve
- formula-session.sh: delegate cleanup_stale_crashed_worktrees, use worktree_preserve
- All formula agents source lib/worktree.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:06:31 +00:00
johba
1c5970f4bf Merge pull request 'fix: Extract lib/issue-lifecycle.sh — claim, release, block, deps (#796)' (#805) from fix/issue-796 into main 2026-03-27 19:56:18 +01:00
openhands
9c172703d9 fix: refactor issue_block comment to avoid duplicate-detection false positive
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:31:10 +00:00
openhands
694fff5ebb fix: Extract lib/issue-lifecycle.sh — claim, release, block, deps (#796)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:28:17 +00:00
johba
52ae9ef307 Merge pull request 'fix: Extract lib/pr-lifecycle.sh — walk-PR-to-merge library (#795)' (#804) from fix/issue-795 into main 2026-03-27 19:08:52 +01:00
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
johba
779584be2d Merge pull request 'fix: disinto init: project TOML uses localhost forge_url, breaks agents container (#782)' (#794) from fix/issue-782 into main 2026-03-27 17:40:17 +01: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
openhands
1a72ddc1bd fix: disinto init: project TOML uses localhost forge_url, breaks agents container (#782)
When DISINTO_CONTAINER=1, load-project.sh now skips overriding env vars
that are already set by docker-compose (FORGE_URL, PROJECT_REPO_ROOT,
OPS_REPO_ROOT, etc.).  This prevents the TOML's host-perspective values
(localhost, /home/johba/…) from clobbering the correct container values
(forgejo:3000, /home/agent/…).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:13:59 +00:00
johba
bf50647545 Merge pull request 'fix: agents container: dev-poll fails because factory is mounted read-only (#781)' (#793) from fix/issue-781 into main 2026-03-27 16:54:51 +01:00
openhands
423268115c fix: supervisor-poll.sh: migrate remaining FACTORY_ROOT log paths to DISINTO_LOG_DIR
Fix 4 missed references in supervisor-poll.sh:
- Log truncation loop (disk pressure)
- Log rotation loop (>5MB)
- Pipeline stall detection (DEV_LOG)
- Dev-agent productivity check (DEV_LOG_FILE)

Without this, container mode has broken log rotation and false p2 alerts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:03:54 +00:00
openhands
9f5a6f9942 fix: agents container: dev-poll fails because factory is mounted read-only (#781)
Add DISINTO_LOG_DIR to lib/env.sh: points to $HOME/data/logs inside the
container (writable volume) and $FACTORY_ROOT on the host (existing behavior).

Update all agent scripts to write logs, CI fix tracker, metrics, and vault
locks to DISINTO_LOG_DIR instead of FACTORY_ROOT. This keeps the factory
mount read-only while ensuring all writable state lands on the persistent
data volume.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:29:22 +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
johba
2401e6b74a Merge pull request 'ci: run agent-smoke only on PRs, not push events' (#791) from ci/smoke-pr-only into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/791
2026-03-27 07:56:07 +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
johba
e0f977be20 Merge pull request 'fix: disinto init: race condition in post-push empty check (#773)' (#776) from fix/issue-773 into main 2026-03-26 21:44:52 +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
c3719618a4 fix: preserve skip-verification on API-unreachable path (#773)
Set is_empty="skipped" before breaking out of the retry loop when
the API is unreachable, so the post-loop guard does not misfire
with a false "still reports empty" failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:21:16 +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
220b5c4004 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.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:09:24 +00:00
johba
c62bdfdf5b Merge pull request 'fix: Dev-poll must inject CI failures and review feedback into running sessions (#771)' (#774) from fix/issue-771 into main 2026-03-26 20:52:21 +01:00
openhands
c5e5a14b91 fix: Dev-poll must inject CI failures and review feedback into running sessions (#771)
When a dev-agent tmux session is alive, dev-poll and review-poll
previously skipped it entirely — leaving the agent deaf to CI results
and review feedback if the orchestrator (dev-agent.sh) had died.

Changes in dev-poll.sh:
- Add handle_active_session() helper that checks running sessions for
  injectable events instead of blindly skipping
- Detect externally merged/closed PRs and clean up stale sessions
- Inject CI success/failure into sessions in PHASE:awaiting_ci
- Inject review feedback into sessions in PHASE:awaiting_review
- SHA-based sentinel prevents duplicate injections across poll cycles
- Replace all 7 tmux skip blocks with handle_active_session calls

Changes in review-poll.sh:
- inject_review_into_dev_session() now falls back to formal forge
  reviews when no bot review comment is found
- Call injection when skipping already-reviewed PRs (previously only
  called after performing new reviews)

Evidence: PR #767 (#757) — CI failed twice with agent stuck in
awaiting_ci; PR merged manually with session blocking new backlog.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 19:35:44 +00:00
johba
e132059933 Merge pull request 'fix: disinto init: setup_forge fails because .env does not exist yet (#769)' (#772) from fix/issue-769 into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/772
2026-03-26 20:11:42 +01:00
openhands
f087771bb1 fix: disinto init: setup_forge fails because .env does not exist yet (#769)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 19:10:05 +00:00
johba
71fe89cdd0 fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757

## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
johba
a899fd0733 Merge pull request 'chore: gardener housekeeping 2026-03-26' (#768) from chore/gardener-20260326-1814 into main
Reviewed-on: https://codeberg.org/johba/disinto/pulls/768
2026-03-26 19:19:32 +01:00
openhands
1f9b5e6444 chore: gardener housekeeping 2026-03-26 2026-03-26 18:14:35 +00:00
johba
f32707ba65 Merge pull request 'fix: Vault-gated deployment promotion via Woodpecker environments (#755)' (#766) from fix/issue-755 into main 2026-03-26 18:28:57 +01:00
openhands
3372da594b fix: Vault-gated deployment promotion via Woodpecker environments (#755)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 17:16:39 +00:00
johba
04696b35a9 Merge pull request 'fix: External actions (publish, deploy, post) must go through vault — agents cannot hold tokens directly (#745)' (#763) from fix/issue-745 into main 2026-03-26 18:07:26 +01:00
openhands
569313ac93 fix: External actions (publish, deploy, post) must go through vault — agents cannot hold tokens directly (#745)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:59:57 +00:00
johba
320236080e Merge pull request 'fix: Secure action runtime — ephemeral container with vault-injected secrets (#748)' (#762) from fix/issue-748 into main 2026-03-26 17:53:22 +01:00
openhands
cb5252588c fix: Secure action runtime — ephemeral container with vault-injected secrets (#748)
Split secrets into two SOPS-encrypted files:
- .env.enc for agent secrets (FORGE_TOKEN, CLAUDE_API_KEY, etc.)
- .env.vault.enc for vault secrets (GITHUB_TOKEN, deploy keys, etc.)

Add ephemeral vault-runner container (profiles: ["vault"]) that receives
only vault secrets at runtime. Agents never see vault secrets; vault-runner
never sees agent secrets.

Key changes:
- bin/disinto: vault-run subcommand, dual-file secrets management,
  vault-runner service in compose template
- vault/vault-fire.sh: delegates action execution to vault-runner
  container via disinto vault-run (bare-metal fallback preserved)
- vault/vault-poll.sh: new phase 5 detects vault-bot authorized
  comments on issues with action label
- vault/vault-run-action.sh: entrypoint for ephemeral container,
  dispatches to action handlers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:41:27 +00:00
johba
ac4eaf93d6 Merge pull request 'fix: Per-agent Forgejo accounts — identity and permissions via authorship (#747)' (#760) from fix/issue-747 into main 2026-03-26 17:29:02 +01:00
openhands
6dcf35c5f9 fix: Extract vault-env.sh to deduplicate vault token override
Moves shared env.sh sourcing + vault-bot token override into
vault/vault-env.sh so the three vault sub-scripts no longer share
a duplicate 5-line block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:20:40 +00:00
openhands
89628e50e2 fix: Per-agent Forgejo accounts — identity and permissions via authorship (#747)
Each agent now gets its own Forgejo account (dev-bot, review-bot,
planner-bot, gardener-bot, vault-bot, supervisor-bot, predictor-bot,
action-bot) with a dedicated API token. This enables:

- Audit trail: every forge action attributable to a specific agent
- Permission boundaries: agents act under their own identity
- Vault authorization model: vault-bot comments = proof of approval

Changes:
- bin/disinto: setup_forge() creates all 8 bot accounts during init,
  stores per-agent tokens (FORGE_*_TOKEN) in .env, adds all bots as
  repo collaborators
- lib/env.sh: exports per-agent token vars with fallback to FORGE_TOKEN
  for backwards compat; sets FORGE_BOT_USERNAMES default to all 8 bots
- Agent scripts: each agent overrides FORGE_TOKEN with its per-agent
  token after sourcing env.sh (gardener, planner, supervisor, predictor,
  vault, action)
- .env.example: documents all per-agent token fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:16:13 +00:00
johba
9e9a209000 Merge pull request 'fix: Track addressables and observables in root AGENTS.md — gardener maintains lifecycle (#744)' (#759) from fix/issue-744 into main 2026-03-26 17:03:38 +01:00
openhands
b157cc432b fix: Track addressables and observables in root AGENTS.md — gardener maintains lifecycle (#744)
Add mandatory Addressables and Observables sections to AGENTS.md so all
agents have a concrete inventory of what the factory has produced.

- AGENTS.md: add Addressables table (website, repo, skill, GitHub org)
  and empty Observables section
- run-gardener.toml: add portfolio lifecycle duties (add, promote,
  remove, flag) to the grooming step
- run-planner.toml: reference portfolio as planning input
- run-predictor.toml: reference portfolio for weakness detection
2026-03-26 15:56:10 +00:00
johba
a24f1705dc Merge pull request 'fix: Remove Matrix integration — notifications move to forge + OpenClaw (#732)' (#758) from fix/issue-732 into main 2026-03-26 16:19:03 +01:00
openhands
daa8350085 fix: Address review — remove stale Matrix references from runtime prompts
Critical fixes:
- vault/vault-agent.sh: Update comment and prompt to use PHASE:escalate
  instead of "send a Matrix message"
- dev/dev-agent.sh: Update escalation instruction from "reply via Matrix"
  to "respond via the forge"
- dev/phase-handler.sh: Update build_phase_protocol_prompt() escalation
  text from "reply via Matrix" to "respond via the forge"

Minor fixes:
- bin/disinto: Remove duplicate comment line in docker-compose header
- README.md: Update vault table row from "via Matrix" to "via vault/forge"
- BOOTSTRAP.md: Remove "Matrix credentials" from TOML description
- lib/AGENTS.md: Remove "callers may follow up via Matrix" from
  formula_phase_callback description

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:11:44 +00:00
openhands
d8dab4a18a fix: Extract memory_guard() to lib/env.sh to deduplicate poll scripts
The memory guard block in action-poll.sh and dev-poll.sh became
identical after removing matrix_send calls, triggering the
duplicate-detection CI check. Extract to a shared function in
lib/env.sh (already sourced by both scripts).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:00:12 +00:00