Commit graph

132 commits

Author SHA1 Message Date
openhands
b8c9334880 fix: Set CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC in factory sessions and disinto init (#725)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:21:22 +00:00
openhands
af39b833af fix: Session lock must not block during idle phases (awaiting_review/awaiting_ci) (#724)
Restructure session.lock from command-wrapper flock to fd-based flock so
the lock can be released when Claude is idle and re-acquired before
injecting the next prompt.

- agent-session.sh: add session_lock_acquire/release helpers, open fd in
  create_agent_session instead of wrapping claude with flock, auto-acquire
  in agent_inject_into_session before injecting
- phase-handler.sh: call session_lock_release at start of awaiting_ci and
  awaiting_review handlers (Claude is idle during CI polling / review wait)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:11:50 +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
openhands
ec5de7d2e0 chore: gardener housekeeping 2026-03-26 2026-03-26 06:06:51 +00:00
Gardener
99933bef7b chore: gardener housekeeping 2026-03-26 2026-03-26 00:05:34 +00:00
openhands
ff8d773d7a fix: use flock -w 300 instead of -n to queue concurrent agent sessions
Non-blocking flock (-n) silently drops work items when concurrent agents
race for the lock. Switch to -w 300 so sessions queue up to 5 minutes,
and single-quote the lock path to handle spaces in $HOME.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:54:48 +00:00
openhands
cf6400e8f3 fix: shared Claude OAuth credentials in containers — mount + flock to prevent token rotation race (#693)
- Make ~/.claude volume mount read-write (was :ro) so containers can
  write back refreshed OAuth tokens
- Wrap Claude CLI in flock(1) inside tmux sessions using
  ~/.claude/session.lock — prevents concurrent token refresh races
  across agents sharing the same credentials
- Add ANTHROPIC_API_KEY detection in entrypoint.sh: when set, skips
  OAuth entirely (no rotation issues, metered billing)
- Log active auth method (API key vs OAuth vs missing) at container
  startup for easier 401 debugging
- Document 'claude auth login' requirement in disinto init output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:48:21 +00:00
disinto-exec
c3acce7f8f refactor: cherry-pick improvements from dev-agent's PR #700
Two wins from the dev-agent's implementation:

1. exec-briefing.sh: rewritten to just call exec-inject.sh with a
   briefing prompt (57 lines, down from 154). No more duplicated
   compass/character/context loading.

2. exec-inject.sh: response capture now uses agent_wait_for_claude_ready
   + pane line diff instead of custom EXEC-RESPONSE-START/END markers.
   Claude just responds naturally — no special output format needed.

Also: matrix listener uses nohup for robustness and validates TOML
path before passing to exec-inject.sh.
2026-03-25 16:15:10 +00:00
disinto-exec
d1ba4bc579 feat: add exec agent — interactive executive assistant
New agent: exec — message-driven executive assistant reachable via Matrix.
Unlike cron-driven agents, the exec activates on demand when the executive
sends a message, maintains persistent conversation context, and has a
distinct character defined in CHARACTER.md.

The CHARACTER.md defines the exec as an animal of light — born from data,
dedicated to bringing more light into the world. But it deliberately
refuses to define what light and darkness are, forcing deliberation
from first principles every time (cat questions | grep knowledge).

Components:
- exec-session.sh: spawn/reattach persistent Claude tmux session
- exec-inject.sh: message injection + response capture + Matrix posting
- exec-briefing.sh: optional daily morning briefing (cron)
- CHARACTER.md: personality and moral compass
- PROMPT.md: system prompt template reference
- MEMORY.md: persistent memory across sessions (seed)

Integration:
- Matrix listener: new exec dispatch case (spawn on demand)
- Root AGENTS.md: updated agent count (8→9), table, directory layout
- Graph analysis available on demand (not injected by default)
2026-03-25 15:28:29 +00:00
openhands
12d871c865 fix: extract build_graph_section helper to eliminate duplicate code (#667)
Move graph report generation into build_graph_section() in
lib/formula-session.sh. Both planner-run.sh and predictor-run.sh
now call the shared helper instead of duplicating the same 11 lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:50:33 +00:00
openhands
50b5cea2cb fix: tea_relabel uses edit subcommand, add sha256 checksum for tea binary (#666)
- tea_relabel: use `tea issues edit` instead of `tea issues labels`
  (the latter is the list subcommand and ignores --labels)
- Dockerfile: verify tea binary sha256 after download

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:34:58 +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
8a912ec87e chore: gardener housekeeping 2026-03-25 2026-03-25 12:07:39 +00:00
openhands
ab8f88303c fix: fix: check_active guard should log to stderr when skipping — silent agent dropout on missing state file (#663)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 08:00:29 +00:00
openhands
709217af33 fix: agents container cannot reach Forgejo — lib/env.sh overrides compose FORGE_URL with .env localhost (#660)
Skip sourcing .env/.env.enc when DISINTO_CONTAINER=1 since compose
already injects the correct env vars via env_file + environment
overrides.  Re-sourcing .env was clobbering compose-level values
like FORGE_URL=http://forgejo:3000 with the localhost default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 07:10:55 +00:00
openhands
40093e92e2 chore: gardener housekeeping 2026-03-25 2026-03-25 06:06:48 +00:00
openhands
a0cdf87a21 fix: move setup_matrix after compose up, use Python for .env writes
- Critical: setup_matrix now runs after docker compose up -d so Dendrite
  is actually running when provisioning is attempted
- Minor: replace sed with Python for .env credential writes to avoid
  delimiter collisions with opaque Matrix access tokens
- Info: update matrix_listener.sh header to mention container mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:35:20 +00:00
openhands
b86edd7e5d fix: Add Dendrite to docker-compose stack (#619)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:28:04 +00:00
openhands
b8dc01b06f chore: gardener housekeeping 2026-03-25 2026-03-25 00:07:52 +00:00
openhands
4d429b274a fix: use undirected reachability for reviewer affected-objectives tracing
The directed graph has mixed edge directions along the path from
agent/formula to objective (agent→formula→label←issue→objective),
so descendants() never reaches objectives.  Use undirected connected
components for reachability instead.  Also fix closed-issues query
to use forge_get (bounded at 50) instead of forge_get_all (unbounded).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:31:55 +00:00
openhands
3a7b95046d fix: Project knowledge graph for structural defect detection (#629)
Add lib/build-graph.py that builds a NetworkX DiGraph from project docs
and forge API, runs structural analyses (orphans, cycles, disconnected
clusters, thin objectives, bottlenecks), and outputs a JSON report.

Predictor and reviewer agents now call build-graph.py before launching
their Claude sessions and inject the report as context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:24:20 +00:00
johba
9a9b82eea5 Merge pull request 'fix: Containerize full stack with docker-compose (#618)' (#625) from fix/issue-618 into main 2026-03-24 21:43:39 +01:00
openhands
32c336f3df fix: escalation notifications should @mention human on Matrix (#624)
Add MATRIX_MENTION_USER config to project TOML and include a Matrix
mention pill in escalation notify_ctx calls so humans get notified
even in muted rooms.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:21:46 +00:00
openhands
e38866ab61 fix: Containerize full stack with docker-compose (#618)
Add docker-compose.yml generation, agent Dockerfile, and new CLI
commands (up/down/logs/shell) so the full stack runs containerized.
The --bare flag preserves the current bare-metal setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:53:55 +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
7bc74caa63 fix: Push to public mirrors after merge (#614)
Add fire-and-forget mirror push support so merges to the primary branch
are automatically pushed to configured public mirrors (GitHub, Codeberg,
etc.). Mirror failures are logged but never block the pipeline.

- lib/mirrors.sh: new shared mirror_push() helper
- lib/load-project.sh: parse [mirrors] TOML section into MIRROR_* env vars
- dev/phase-handler.sh: call mirror_push after do_merge() success
- dev/dev-poll.sh: call mirror_push after try_direct_merge() success
- gardener/gardener-run.sh: call mirror_push after _gardener_merge() success
- bin/disinto: set up mirror remotes during init, add commented mirrors to
  generated TOML
- projects/*.toml.example: show [mirrors] section (commented out)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:19:16 +00:00
openhands
3e2f8f9623 fix: Address review feedback on SOPS integration (#613)
- Warn on stderr when .env.enc decryption fails instead of silent || true
- Guard ensure_age_key() against empty age-keygen -y output
- Fix stale comment on write_secrets_encrypted()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:04:58 +00:00
openhands
5ccf09b28d fix: Encrypt secrets at rest with SOPS + age (#613)
- lib/env.sh: Two-tier secret loader (SOPS .env.enc > plaintext .env),
  remove ~/.netrc fallback
- bin/disinto: Add age key generation and SOPS encryption during init,
  remove write_netrc(), add `disinto secrets` subcommand (edit/show/migrate),
  add sops+age to preflight warnings
- .env.example: Annotate vars as [SECRET] or [CONFIG]
- .gitignore: Allow .env.enc and .sops.yaml to be committed
- BOOTSTRAP.md: Document SOPS + age setup, key backup, secret management
- AGENTS.md: Update AD-005 and coding conventions for .env.enc

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:58:33 +00:00
openhands
d9427ebe78 chore: gardener housekeeping 2026-03-23 2026-03-23 18:05:26 +00:00
openhands
50dff34b89 fix: Wire Woodpecker CI to local Forgejo (#612)
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>
2026-03-23 17:19:01 +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
0775514bf8 chore: gardener housekeeping 2026-03-23 2026-03-23 12:47:32 +00:00
openhands
38f4b385cc chore: gardener housekeeping 2026-03-23
- Update all AGENTS.md watermarks to f6fb79d (current HEAD)
- lib/AGENTS.md: document nudge behavior in agent-session.sh stop hook
- pending-actions.json: enrich #598 body + promote to backlog
2026-03-23 12:08:26 +00:00
openhands
c7d7ee9cfb fix: parse-deps.sh inline regex matches every line — awk /pattern/i flag is invalid (#600)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:59:47 +00:00
openhands
742b64e743 fix: stop hook should nudge Claude when PHASE file is empty — prevents silent exit without PHASE:done (#585)
When Claude finishes a response but hasn't written to the PHASE file,
the stop hook now injects a nudge into the tmux session instead of just
marking idle. This gives Claude another chance to complete the phase
protocol before the monitor loop times out.

Key changes:
- on-idle-stop.sh: check phase file emptiness, nudge via tmux (max 2)
- agent-session.sh: pass phase_file + session to stop hook, clean up
  nudge counter on session teardown

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 09:56:49 +00:00
openhands
b769eaa182 fix: monitor_phase_loop docstring lists 'break' as a possible _MONITOR_LOOP_EXIT value but it is never set (#435)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 09:39:48 +00:00
openhands
0be64bdf31 fix: Hook scripts don't follow #!/usr/bin/env bash convention from AGENTS.md (#330)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 08:59:56 +00:00
openhands
30cc5688bd chore: gardener housekeeping 2026-03-23
- Update AGENTS.md watermarks to current HEAD (9ec0c02)
- lib/AGENTS.md: document parse-deps.sh inline scan now skips fenced
  code blocks to prevent false positives from code examples in issue bodies
- No blocked issues to review
- Pending actions: none

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 06:03:14 +00:00
openhands
2bda20f207 fix: rename awk variable to avoid CI smoke test false positive
The agent-smoke function resolution check flags underscore-containing
identifiers as potential undefined bash functions. Rename in_code to
incode to match the convention used by the existing capture variable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 02:26:49 +00:00
openhands
1cca1a7b7f fix: parse-deps.sh false positive — inline scan should skip fenced code blocks (#574)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 02:25:21 +00:00
openhands
d2db178d30 chore: gardener housekeeping 2026-03-23
- Update AGENTS.md watermarks to current HEAD (e8df73e)
- No code changes since last gardener run — watermark-only refresh
- No blocked issues to review
- Pending actions: none

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 00:47:57 +00:00
openhands
149211c78d chore: gardener housekeeping 2026-03-23
- dev/AGENTS.md: document two-tier priority queue (priority+backlog first,
  then plain backlog); note do_merge() HTTP 405 already-merged detection
- gardener/AGENTS.md: document merge-through protocol (stay alive through
  CI/review/merge); note session kill on PHASE:escalate
- lib/AGENTS.md: add ensure_priority_label() to ci-helpers.sh entry;
  document optional CALLBACK param in run_formula_and_monitor()
- predictor/AGENTS.md: update watermark (content already current from v2 PR)
- Update watermarks for action, planner, review, supervisor, vault, root

Grooming actions:
- #574: added ## Affected files section (lib/parse-deps.sh) to meet quality gate
- #568: escalated — needs human decision on guard/merge architecture
- #466: escalated — dep #393 closed; needs decision on external vs in-repo example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 00:23:02 +00:00
openhands
578a6ec81d fix: feat: gardener should stay alive until its PR merges — address review feedback, rebase if needed (#571)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 20:48:07 +00:00
openhands
604d1f13ca fix: feat: dev-poll checks priority-labeled issues before plain backlog (#555)
Add two-tier backlog pickup in dev-poll.sh:
1. in-progress issues (existing)
2. priority + backlog issues (FIFO within tier)
3. plain backlog issues (FIFO within tier)

The priority label coexists with backlog (not a replacement).
ensure_priority_label() auto-creates the label if missing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 13:41:57 +00:00
openhands
f37546c6fc chore: gardener housekeeping 2026-03-22
- Update all AGENTS.md watermarks to current HEAD (251d160)
- dev/AGENTS.md: document dev-poll's early direct-merge scan (before lock
  check) — approved PRs now merge without waiting for active dev sessions;
  chore/gardener PRs merge without issue numbers in branch name
- planner/AGENTS.md: document dispatch-idle-formulas phase (step 4); note
  that planner reads both factory and project-specific formulas; clarify
  that all planner artifacts use $PROJECT_REPO_ROOT, not $FACTORY_ROOT

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 12:07:31 +00:00
openhands
ea4c55dbbf chore: gardener housekeeping 2026-03-22 2026-03-22 10:43:58 +01:00
openhands
575ab427d2 Revert "Merge pull request 'fix: inject skipDangerousModePermissionPrompt into worktree settings (#514)' (#522) from fix/agent-session-skip-permissions into main"
This reverts commit 0631b71aa5, reversing
changes made to 93d8249d3a.
2026-03-21 20:48:41 +00:00
openhands
c642ebf81d fix: bundled dust cleanup — set-euo-pipefail (#516)
Add missing `set -euo pipefail` to three scripts per AGENTS.md conventions:
- lib/ci-helpers.sh
- lib/parse-deps.sh
- supervisor/supervisor-poll.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:59:55 +00:00
johba
0631b71aa5 Merge pull request 'fix: inject skipDangerousModePermissionPrompt into worktree settings (#514)' (#522) from fix/agent-session-skip-permissions into main 2026-03-21 20:54:02 +01:00
openhands
bc6fe1beee fix: inject skipDangerousModePermissionPrompt into worktree settings
Project-level .claude/settings.json overrides global ~/.claude/settings.json.
When agent-session.sh creates settings with hooks but without the skip flag,
Claude shows an interactive bypass-permissions confirmation dialog that blocks
all non-interactive tmux agent sessions.

Fixes #514.
2026-03-21 19:50:49 +00:00