- Bump AGENTS.md watermarks to HEAD (c363ee0) across all 9 per-directory files
- supervisor/AGENTS.md: document dual-container trigger (agents + edge) and SUPERVISOR_INTERVAL env var added by P1/#801
- lib/AGENTS.md: document agents-llama-all compose service (all 7 roles) added to generators.sh by P1/#801
- pending-actions.json: comment #623 (all deps now closed, ready for planner decomposition), comment #758 (needs human Forgejo admin action to unblock ops repo writes)
Replace write_result's direct filesystem write with commit_result_via_git,
which clones the ops repo into a scratch directory, writes the result file,
commits as vault-bot, and pushes. This removes the requirement for a shared
bind-mount between the dispatcher container and the host ops-repo clone.
- Idempotent: skips if result.json already exists upstream
- Retry loop: handles push conflicts with rebase-and-push (up to 3 attempts)
- Scratch dir: cleaned up via RETURN trap regardless of outcome
- Works identically under docker and future nomad backends
Prevents infinite retry loops when secret resolution or mount alias
validation fails before the docker run is attempted.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add supervisor role to entrypoint.sh polling loop (SUPERVISOR_INTERVAL,
default 20 min) and include it in default AGENT_ROLES
- Add agents-llama-all compose service (profile: agents-llama-all) with
all 7 roles: review, dev, gardener, architect, planner, predictor, supervisor
- Add agents-llama-all to lib/generators.sh for disinto init generation
- Update docs/agents-llama.md with profile table and usage instructions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make `disinto init` safe to re-run on the same box:
- Store admin token as FORGE_ADMIN_TOKEN in .env; preserve on re-run
(previously deleted and recreated every run, churning DB state)
- Fix human token creation: use admin_pass for basic-auth since
human_user == admin_user (previously used a random password that
never matched the actual user password, so HUMAN_TOKEN was never
created successfully)
- Preserve HUMAN_TOKEN in .env on re-run (same pattern as bot tokens)
- Bot tokens were already idempotent (preserved unless --rotate-tokens)
Add --dry-run flag that reports every intended action (file writes,
API calls, docker commands) based on current state, then exits 0
without touching state. Useful for CI gating and cutover confidence.
Update smoke test:
- Add dry-run test (verifies exit 0 and no .env modification)
- Add idempotency state diff (verifies .env is unchanged on re-run)
- Verify FORGE_ADMIN_TOKEN and HUMAN_TOKEN are stored in .env
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- _hvault_err: use jq instead of printf to produce valid JSON on all inputs
- hvault_kv_get: use jq --arg for key lookup to prevent filter injection
- hvault_kv_put: build payload entirely via jq to properly escape keys
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sites touched:
- lib/generators.sh: WOODPECKER_BACKEND_DOCKER_NETWORK now reads from
${WOODPECKER_CI_NETWORK:-disinto_disinto-net} so nomad jobspecs can
override the compose-generated network name.
- lib/forge-setup.sh: bare-mode _forgejo_exec() and setup_forge() use
${FORGEJO_CONTAINER_NAME:-disinto-forgejo} instead of hardcoding the
container name. Compose mode is unaffected (uses service name).
Documented exceptions (container_name directives in generators.sh
compose template output): these define names inside docker-compose.yml,
which is compose-specific output. Under nomad the generator is not used.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- FORGE_API is repo-scoped; /repos/migrate needs the global FORGE_API_BASE
- Use jq -n --arg for safe JSON construction (no shell interpolation)
- Update docs to reference FORGE_API_BASE
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded host-side bind-mount paths with env vars so Nomad
jobspecs can reuse the same variables at cutover:
- CLAUDE_BIN_DIR: path to claude CLI binary (resolved at init time)
- CLAUDE_CONFIG_FILE: path to .claude.json (default ${HOME}/.claude.json)
- CLAUDE_DIR: path to .claude directory (default ${HOME}/.claude)
- AGENT_SSH_DIR: path to SSH keys (default ${HOME}/.ssh)
- SOPS_AGE_DIR: path to SOPS age keys (default ${HOME}/.config/sops/age)
generators.sh now writes CLAUDE_BIN_DIR to .env instead of sed-replacing
CLAUDE_BIN_PLACEHOLDER in docker-compose.yml.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
`name` is not a valid subdirective of the global `servers` block in
Caddyfile syntax — Caddy would reject the config on startup. The
dynamic server discovery in `_discover_server_name()` already handles
routing to the correct server regardless of its auto-generated name.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- install.sh: use Caddy `servers { name edge }` global option so the
emitted Caddyfile produces a predictably-named server
- lib/caddy.sh: add `_discover_server_name` that queries the admin API
for the first server listening on :80/:443 — add_route and remove_route
use dynamic discovery instead of hardcoding `/servers/edge/`
- lib/caddy.sh: add_route, remove_route, and reload_caddy now check HTTP
status codes (≥400 → return 1 with error message) instead of only
checking curl exit code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Planner phase 5 pushed ops repo changes directly to main, which branch
protection blocks. Replace with the same PR-based flow architect uses:
- planner-run.sh: create branch planner/run-YYYY-MM-DD in ops repo before
agent_run, then pr_create + pr_walk_to_merge after agent completes
- run-planner.toml: formula now pushes HEAD (the branch) instead of
PRIMARY_BRANCH directly
- planner/AGENTS.md: update phase 5 description to reflect PR flow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add docker/Caddyfile to .gitignore (generated artifact, not tracked)
- Document generate_caddyfile as canonical source in lib/generators.sh
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add `_regen_file` helper that idempotently regenerates a file: moves
existing file aside, runs the generator, compares output byte-for-byte,
and either restores the original (preserving mtime) or keeps the new
version with a `.prev` backup.
- `disinto_up` now calls `generate_compose` and `generate_caddyfile`
before bringing the stack up, ensuring generator changes are applied.
- Pass `--build --remove-orphans` to `docker compose up -d` so image
rebuilds and orphan container cleanup happen automatically.
- Add `--no-regen` escape hatch that skips regeneration and prints a
warning for operators debugging generators or testing hand-edits.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>