chore: gardener housekeeping 2026-04-09
This commit is contained in:
parent
d5e63a801e
commit
faaaeb0a1f
10 changed files with 31 additions and 35 deletions
28
AGENTS.md
28
AGENTS.md
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: 60086973550d5f6a7ea0774efee5614da6b0de9f -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Disinto — Agent Instructions
|
||||
|
||||
## What this repo is
|
||||
|
|
@ -67,8 +67,6 @@ disinto-ops/ (ops repo — {project}-ops)
|
|||
└── RESOURCES.md accounts, tokens (refs), infra inventory
|
||||
```
|
||||
|
||||
> **Note:** Journal directories (`journal/planner/` and `journal/supervisor/`) still exist in the ops repo. Agent journals are now stored in each agent's `.profile` repo on Forgejo.
|
||||
|
||||
## Agent .profile Model
|
||||
|
||||
Each agent has a `.profile` repository on Forgejo storing `knowledge/lessons-learned.md` (injected into each session prompt) and `journal/` reflection entries (digested into lessons). Pre-session: `formula_prepare_profile_context()` loads lessons. Post-session: `profile_write_journal` records reflections. See `lib/formula-session.sh`.
|
||||
|
|
@ -152,23 +150,13 @@ Issues flow: `backlog` → `in-progress` → PR → CI → review → merge →
|
|||
|
||||
### Dependency conventions
|
||||
|
||||
Issues declare dependencies in their body using a `## Dependencies` or
|
||||
`## Depends on` section listing `#N` references. The dev-poll scheduler uses
|
||||
`lib/parse-deps.sh` to extract these and only picks issues whose dependencies
|
||||
are all closed.
|
||||
|
||||
### Single-threaded pipeline
|
||||
|
||||
Each project processes one issue at a time. Dev-poll will not start new work
|
||||
while an open PR is waiting for CI or review. This keeps context clear and
|
||||
prevents merge conflicts between concurrent changes.
|
||||
Issues declare dependencies via `## Dependencies` / `## Depends on` sections listing `#N` refs. `lib/parse-deps.sh` extracts these; dev-poll only picks issues whose deps are all closed. See AD-002 for single-threaded pipeline rules.
|
||||
|
||||
---
|
||||
|
||||
## Addressables
|
||||
## Addressables and Observables
|
||||
|
||||
Concrete artifacts the factory has produced or is building. The gardener
|
||||
maintains this table during grooming — see `formulas/run-gardener.toml`.
|
||||
Concrete artifacts the factory has produced or is building. Observables have measurement wired — the gardener promotes addressables once an evidence process is connected.
|
||||
|
||||
| Artifact | Location | Observable? |
|
||||
|----------|----------|-------------|
|
||||
|
|
@ -177,14 +165,6 @@ maintains this table during grooming — see `formulas/run-gardener.toml`.
|
|||
| Skill | ClawHub (in progress) | No |
|
||||
| GitHub org | github.com/Disinto | No |
|
||||
|
||||
## Observables
|
||||
|
||||
Addressables with measurement wired — the factory can read structured
|
||||
feedback from these. The gardener promotes addressables here once an
|
||||
evidence process is connected.
|
||||
|
||||
None yet.
|
||||
|
||||
---
|
||||
|
||||
## Architecture Decisions
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Architect — Agent Instructions
|
||||
|
||||
## What this agent is
|
||||
|
|
@ -40,11 +40,16 @@ the steps for:
|
|||
|
||||
Run via `architect/architect-run.sh`, which:
|
||||
- Acquires a cron lock and checks available memory
|
||||
- Cleans up per-issue scratch files from previous runs (`/tmp/architect-{project}-scratch-*.md`)
|
||||
- Sources shared libraries (env.sh, formula-session.sh)
|
||||
- Uses FORGE_ARCHITECT_TOKEN for authentication
|
||||
- Loads the formula and builds context from VISION.md, AGENTS.md, and ops repo
|
||||
- Executes the formula via `agent_run`
|
||||
|
||||
**Multi-sprint pitching**: The architect pitches up to 3 sprints per run. The pitch budget is `3 − <open architect PRs>`. After handling existing PRs (accept/reject/answer parsing), the architect selects up to `pitch_budget` vision issues (skipping any already with an open architect PR or `in-progress` label), then writes one per-issue scratch file (`/tmp/architect-{project}-scratch-{issue_number}.md`) and creates one sprint PR per scratch file.
|
||||
|
||||
**Session resumption (answer_parsing)**: When processing human answers on a PR in the `questions` phase (PR body has `## Design forks` + question comments), `architect-run.sh` resumes the prior Claude session (from `SID_FILE`) rather than starting fresh. This preserves deep codebase understanding from the research phase so sub-issues include specific file references.
|
||||
|
||||
## Cron
|
||||
|
||||
Suggested cron entry (every 6 hours):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Dev Agent
|
||||
|
||||
**Role**: Implement issues autonomously — write code, push branches, address
|
||||
|
|
@ -14,7 +14,7 @@ in-progress issues are also picked up. The direct-merge scan runs before the loc
|
|||
check so approved PRs get merged even while a dev-agent session is active.
|
||||
|
||||
**Key files**:
|
||||
- `dev/dev-poll.sh` — Cron scheduler: finds next ready issue, handles merge/rebase of approved PRs, tracks CI fix attempts. `BOT_USER` is resolved once at startup via the Forge `/user` API and cached for all assignee checks. Formula guard skips issues labeled `formula`, `prediction/dismissed`, or `prediction/unreviewed`. **Race prevention**: checks issue assignee before claiming — skips if assigned to a different bot user. **Stale branch abandonment**: closes PRs and deletes branches that are behind `$PRIMARY_BRANCH` (restarts poll cycle for a fresh start). **Stale in-progress recovery**: on each poll cycle, scans for issues labeled `in-progress`. If the issue is assigned to `$BOT_USER` (this agent), checks for pending review feedback first — if an open PR has `REQUEST_CHANGES`, spawns the dev-agent to address it before setting `BLOCKED_BY_INPROGRESS=true`; otherwise just sets blocked. If assigned to another agent, logs and falls through (does not block). If no assignee, no open PR, and no agent lock file — removes `in-progress`, adds `blocked` with a human-triage comment. **Per-agent open-PR gate**: before starting new work, filters open waiting PRs to only those assigned to this agent (`$BOT_USER`). Other agents' PRs do not block this agent's pipeline (#358, #369). **Pre-lock merge scan own-PRs only**: the direct-merge scan only merges PRs whose linked issue is assigned to this agent — skips PRs owned by other bot users (#374).
|
||||
- `dev/dev-poll.sh` — Cron scheduler: finds next ready issue, handles merge/rebase of approved PRs, tracks CI fix attempts. `BOT_USER` is resolved once at startup via the Forge `/user` API and cached for all assignee checks. Formula guard skips issues labeled `formula`, `prediction/dismissed`, or `prediction/unreviewed`. **Race prevention**: checks issue assignee before claiming — skips if assigned to a different bot user. **Stale branch abandonment**: closes PRs and deletes branches that are behind `$PRIMARY_BRANCH` (restarts poll cycle for a fresh start). **Stale in-progress recovery**: on each poll cycle, scans for issues labeled `in-progress`. If the issue has a `vision` label, sets `BLOCKED_BY_INPROGRESS=true` and skips further stale checks (vision issues are managed by the architect). If the issue is assigned to `$BOT_USER` (this agent), checks for pending review feedback first — if an open PR has `REQUEST_CHANGES`, spawns the dev-agent to address it before setting `BLOCKED_BY_INPROGRESS=true`; otherwise just sets blocked. If assigned to another agent, logs and falls through (does not block). If no assignee, no open PR, and no agent lock file — removes `in-progress`, adds `blocked` with a human-triage comment. **Per-agent open-PR gate**: before starting new work, filters open waiting PRs to only those assigned to this agent (`$BOT_USER`). Other agents' PRs do not block this agent's pipeline (#358, #369). **Pre-lock merge scan own-PRs only**: the direct-merge scan only merges PRs whose linked issue is assigned to this agent — skips PRs owned by other bot users (#374).
|
||||
- `dev/dev-agent.sh` — Orchestrator: claims issue, creates worktree + tmux session with interactive `claude`, monitors phase file, injects CI results and review feedback, merges on approval
|
||||
- `dev/phase-test.sh` — Integration test for the phase protocol
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Gardener Agent
|
||||
|
||||
**Role**: Backlog grooming — detect duplicate issues, missing acceptance
|
||||
|
|
|
|||
|
|
@ -1 +1,12 @@
|
|||
[]
|
||||
[
|
||||
{
|
||||
"action": "edit_body",
|
||||
"issue": 454,
|
||||
"body": "Flagged by AI reviewer in PR #453.\n\n## Problem\n\n`vault/vault-env.sh` `validate_vault_action` (line 70-73) validates field names against an allowlist that does NOT include `blast_radius`:\n\n```\nid|formula|context|secrets|model|tools|timeout_minutes\n```\n\nIf an operator adds `blast_radius = \"low\"` to a vault action TOML (as documented in `vault/SCHEMA.md` and supported by `vault/classify.sh`), the validator rejects it with \"ERROR: Unknown fields in TOML: blast_radius\". The feature is documented and implemented but cannot be exercised without triggering a validation error.\n\n## Fix\n\nAdd `blast_radius` to the allowed fields list in `validate_vault_action` in `vault/vault-env.sh`.\n\n---\n*Auto-created from AI review*\n\n## Affected files\n\n- `vault/vault-env.sh` (line 76 — `id|formula|context|secrets|model|tools|timeout_minutes|dispatch_mode` allowlist)\n\n## Acceptance criteria\n\n- [ ] `blast_radius` is added to the allowed fields list in `validate_vault_action` in `vault/vault-env.sh`\n- [ ] A vault action TOML containing `blast_radius = \"low\"` passes `validate_vault_action` without error\n- [ ] A vault action TOML containing an unrecognised field (e.g. `bogus_field = \"x\"`) still fails validation\n- [ ] `vault/validate.sh` and existing tests continue to pass after the change"
|
||||
},
|
||||
{
|
||||
"action": "add_label",
|
||||
"issue": 454,
|
||||
"label": "backlog"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Shared Helpers (`lib/`)
|
||||
|
||||
All agents source `lib/env.sh` as their first action. Additional helpers are
|
||||
|
|
@ -22,7 +22,7 @@ sourced as needed.
|
|||
| `lib/worktree.sh` | Reusable git worktree management: `worktree_create(path, branch, [base_ref])` — create worktree, checkout base, fetch submodules. `worktree_recover(path, branch, [remote])` — detect existing worktree, reuse if on correct branch (sets `_WORKTREE_REUSED`), otherwise clean and recreate. `worktree_cleanup(path)` — `git worktree remove --force`, clear Claude Code project cache (`~/.claude/projects/` matching path). `worktree_cleanup_stale([max_age_hours])` — scan `/tmp` for orphaned worktrees older than threshold, skip preserved and active tmux worktrees, prune. `worktree_preserve(path, reason)` — mark worktree as preserved for debugging (writes `.worktree-preserved` marker, skipped by stale cleanup). | dev-agent.sh, supervisor-run.sh, planner-run.sh, predictor-run.sh, gardener-run.sh |
|
||||
| `lib/pr-lifecycle.sh` | Reusable PR lifecycle library: `pr_create()`, `pr_find_by_branch()`, `pr_poll_ci()`, `pr_poll_review()`, `pr_merge()`, `pr_is_merged()`, `pr_walk_to_merge()`, `build_phase_protocol_prompt()`. Requires `lib/ci-helpers.sh`. | dev-agent.sh (future) |
|
||||
| `lib/issue-lifecycle.sh` | Reusable issue lifecycle library: `issue_claim()` (add in-progress, remove backlog), `issue_release()` (remove in-progress, add backlog), `issue_block()` (post diagnostic comment with secret redaction, add blocked label), `issue_close()`, `issue_check_deps()` (parse deps, check transitive closure; sets `_ISSUE_BLOCKED_BY`, `_ISSUE_SUGGESTION`), `issue_suggest_next()` (find next unblocked backlog issue; sets `_ISSUE_NEXT`), `issue_post_refusal()` (structured refusal comment with dedup). Label IDs cached in globals on first lookup. Sources `lib/secret-scan.sh`. | dev-agent.sh (future) |
|
||||
| `lib/vault.sh` | **Vault PR helper** — create vault action PRs on ops repo via Forgejo API (works from containers without SSH). `vault_request <action_id> <toml_content>` validates TOML (using `validate_vault_action` from `vault/vault-env.sh`), creates branch `vault/<action-id>`, writes `vault/actions/<action-id>.toml`, creates PR targeting `main` with title `vault: <action-id>` and body from context field, returns PR number. Idempotent: if PR exists, returns existing number. Requires `FORGE_TOKEN`, `FORGE_URL`, `FORGE_REPO`, `FORGE_OPS_REPO`. Uses the calling agent's own token (saves/restores `FORGE_TOKEN` around sourcing `vault-env.sh`), so approval workflow respects individual agent identities. | dev-agent (vault actions), future vault dispatcher |
|
||||
| `lib/vault.sh` | **Vault PR helper** — create vault action PRs on ops repo via Forgejo API (works from containers without SSH). `vault_request <action_id> <toml_content>` validates TOML (using `validate_vault_action` from `vault/vault-env.sh`), creates branch `vault/<action-id>`, writes `vault/actions/<action-id>.toml`, creates PR targeting `main` with title `vault: <action-id>` and body from context field, returns PR number. Idempotent: if PR exists, returns existing number. **Low-tier bypass**: if the action's `blast_radius` classifies as `low` (via `vault/classify.sh`), `vault_request` calls `_vault_commit_direct()` which commits directly to ops `main` using `FORGE_ADMIN_TOKEN` — no PR, no approval wait. Returns `0` (not a PR number) for direct commits. Requires `FORGE_TOKEN`, `FORGE_ADMIN_TOKEN` (low-tier only), `FORGE_URL`, `FORGE_REPO`, `FORGE_OPS_REPO`. Uses the calling agent's own token (saves/restores `FORGE_TOKEN` around sourcing `vault-env.sh`), so approval workflow respects individual agent identities. | dev-agent (vault actions), future vault dispatcher |
|
||||
| `lib/branch-protection.sh` | Branch protection helpers for Forgejo repos. `setup_vault_branch_protection()` — configures admin-only merge protection on main (require 1 approval, restrict merge to admin role, block direct pushes). `setup_profile_branch_protection()` — same protection for `.profile` repos. `verify_branch_protection()` — checks protection is correctly configured. `remove_branch_protection()` — removes protection (cleanup/testing). Handles race condition after initial push: retries with backoff if Forgejo hasn't processed the branch yet. Requires `FORGE_TOKEN`, `FORGE_URL`, `FORGE_OPS_REPO`. | bin/disinto (hire-an-agent) |
|
||||
| `lib/agent-sdk.sh` | `agent_run([--resume SESSION_ID] [--worktree DIR] PROMPT)` — one-shot `claude -p` invocation with session persistence. Saves session ID to `SID_FILE`, reads it back on resume. `agent_recover_session()` — restore previous session ID from `SID_FILE` on startup. **Nudge guard**: skips nudge injection if the worktree is clean and no push is expected, preventing spurious re-invocations. Callers must define `SID_FILE`, `LOGFILE`, and `log()` before sourcing. | formula-driven agents (dev-agent, planner-run, predictor-run, gardener-run) |
|
||||
| `lib/forge-setup.sh` | `setup_forge()` — Forgejo instance provisioning: creates admin user, bot accounts, org, repos (code + ops), configures webhooks, sets repo topics. Extracted from `bin/disinto`. Requires `FORGE_URL`, `FORGE_TOKEN`, `FACTORY_ROOT`. **Password storage (#361)**: after creating each bot account, stores its password in `.env` as `FORGE_<BOT>_PASS` (e.g. `FORGE_PASS`, `FORGE_REVIEW_PASS`, etc.) for use by `forge-push.sh`. | bin/disinto (init) |
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Planner Agent
|
||||
|
||||
**Role**: Strategic planning using a Prerequisite Tree (Theory of Constraints),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Predictor Agent
|
||||
|
||||
**Role**: Abstract adversary (the "goblin"). Runs a 2-step formula
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Review Agent
|
||||
|
||||
**Role**: AI-powered PR review — post structured findings and formal
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- last-reviewed: ebadff09a1ce3c0140e4975985d383136a9a5504 -->
|
||||
<!-- last-reviewed: d5e63a801ed48f9bd54c77e4915bc076b7490958 -->
|
||||
# Supervisor Agent
|
||||
|
||||
**Role**: Health monitoring and auto-remediation, executed as a formula-driven
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue