Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,11 @@ humans invoke identically, so behaviour isn't re-derived from prose each time.
the Brain coordinating *multiple* organs. Has `build` / `deploy` / `release`
modes — release is isolated as a mode now, with a clean seam to the release
conductor.
- **`agents/conductors/release/`** — reasons over `pyauto-heart readiness`, and on
green triggers the PyAutoBuild release executor (`autobuild pre_build` →
`release.yml`); also orchestrates release validation (`release rehearse` /
`release validate`) across the MCP boundary.
- **`agents/conductors/release/`** — the release door and release-validation
orchestrator: `release rehearse` / `release validate` drive the TestPyPI
rehearsal and the full Stages 0–3 validation; plain `release` delegates the
readiness gate and execution to the Build Agent's release mode (one gate
implementation, not two).
Comment on lines +97 to +101
- **`agents/conductors/health/`** — the *clinician*: runs the health loop with
a human — assess (vitals) → triage → (on your go-ahead) dispatch a validation
leg → re-judge — until Heart goes GREEN. Delegates all dispatch to the
Expand All @@ -111,14 +112,12 @@ humans invoke identically, so behaviour isn't re-derived from prose each time.
capability. The single component that talks to Heart; every conductor
consults it rather than querying Heart directly. Never dispatches or mutates.

> **Build Agent vs. release mode vs. the release agent.** The Build Agent owns
> all execution orchestration and keeps release as one of its modes (broad build
> scope: generate, run, aggregate, package, tag). `agents/conductors/release/` is the older,
> narrower readiness→`pre_build` driver. The mature architecture splits a
> dedicated **Release Agent** out of the Build Agent's release mode — making
> release-specific decisions (versioning, changelogs, PyPI/tags, human approval),
> consulting the vitals faculty *more strictly*, then requesting execution from the
> Build Agent / PyAutoBuild. Until then: one agent now, clean seam for two later.
> **Build Agent vs. the release conductor — resolved.** The Build Agent's
> release mode owns the **single** readiness-gate + execution path
> (`build.sh --mode release` → `pre_build`). The release conductor owns
> release-*validation* orchestration (`rehearse` / `validate`) and, for plain
> releases, is a door that delegates through that mode. There is deliberately
> no second gate implementation.

New agents are added on **demonstrated need, never for symmetry**. Place by
tier: a side-effecting decider you drive → `agents/conductors/<name>/`; a
Expand Down
2 changes: 1 addition & 1 deletion agents/conductors/build/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ plan_cmd="autobuild $action"
plan=("$plan_cmd")

if [[ "$mode" == "release" ]]; then
follow_up+=("Release reasoning lives in 'release mode'; it may later split into a dedicated PyAutoBrain Release Agent.")
follow_up+=("This release mode is the single gate+execution path; the release conductor delegates plain releases through it and owns rehearse/validate.")
fi
Comment on lines 148 to 150

# ----- emit the BuildDecision (structured) -----
Expand Down
26 changes: 11 additions & 15 deletions agents/conductors/release/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,25 @@ Brain → Heart (gate) → Build (execute)

## Responsibility

1. Refresh and read PyAutoHeart's authoritative readiness verdict
(`pyauto-heart readiness --json`).
2. **Reason over it** — block unless the verdict is green:
- **RED** → a real release blocker; refuse (exit 3).
- **YELLOW** → caution; refuse unless `--force` (exit 2).
- **GREEN** → proceed.
3. On green, delegate to the PyAutoBuild executor — `autobuild pre_build`, which
prepares the workspaces and dispatches `release.yml`.

The agent holds **no health logic and no release mechanics of its own**. The
health decision is Heart's; the execution is Build's. The Brain only reasons
about the verdict and decides to proceed.
1. **Release-validation orchestration** (this conductor's own machinery):
`release rehearse` (Stage-2 TestPyPI rehearsal) and `release validate` (the
full Stages 0–3 orchestrator) — see `rehearse.sh` / `validate.sh` below.
2. **The release door**: plain `release [--force]` delegates the readiness gate
*and* execution to the Build Agent's release mode
Comment on lines +16 to +20
(`build.sh --mode release`), the **single** gate implementation — GREEN
proceeds, YELLOW needs `--force`, RED blocks; on a pass `autobuild
pre_build` dispatches `release.yml`. This conductor holds no second copy of
that gate.

## Run

```bash
bin/pyauto-brain release # reason about readiness, release on green
bin/pyauto-brain release # release door → Build Agent release mode
bin/pyauto-brain release --force # also proceed on yellow (cautions ack'd)
bin/pyauto-brain release -- 2 # forward `2` (minor_version) to pre_build
```

Exit codes: `0` released/delegated · `2` yellow (use --force) · `3` red blocked
· `1/4` could not obtain a verdict / unknown verdict.
Gate outcomes and exit codes are the Build Agent's (release mode).

## Release-validation rehearsal (M2) — `release rehearse`

Expand Down
74 changes: 20 additions & 54 deletions agents/conductors/release/release.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
#!/usr/bin/env bash
# agents/release/release.sh — the release agent (a PyAutoBrain reasoning agent).
# agents/release/release.sh — the release conductor.
#
# Call chain: Brain -> Heart (gate) -> Build (execute).
# Two jobs:
# release rehearse|validate — release-VALIDATION orchestration, this
# conductor's own machinery (rehearse.sh /
# validate.sh).
# release [--force] [-- <args>] — the release door: delegates the readiness
# gate AND execution to the Build Agent's
# release mode (build.sh --mode release),
# the single gate implementation. GREEN
# proceeds, YELLOW needs --force, RED
# blocks; <args> forward to pre_build.
#
# 1. Ask PyAutoHeart for the authoritative readiness verdict.
# 2. Reason over it: block unless it is green (red = a real blocker;
# yellow = caution).
# 3. On green, delegate to the PyAutoBuild executor (`autobuild pre_build`,
# which prepares the workspaces and dispatches release.yml).
#
# This agent contains NO health logic and NO release mechanics of its own — it
# reasons over Heart's verdict and delegates execution to Build. The health
# decision is Heart's; the work is Build's. The Brain only decides whether and
# when to proceed.
#
# Usage:
# release.sh [--force] [-- <args forwarded to `autobuild pre_build`>]
#
# --force Proceed on a YELLOW verdict (cautions acknowledged). RED always
# blocks. Use only when you know what you are doing.
# This conductor holds no second copy of the gate logic — one gate
# implementation lives in the Build Agent; this door routes through it.

set -uo pipefail

Expand Down Expand Up @@ -51,40 +46,11 @@ while [[ $# -gt 0 ]]; do
esac
done

echo "== release agent: reasoning over pyauto-heart readiness =="

heart="$(resolve_heart)" || exit $?

# Refresh the verdict from a fresh tick so the gate is not stale, then read it.
"$heart" tick >/dev/null 2>&1 || echo " (warning: tick failed; using last cached state)" >&2

verdict="$(readiness_verdict)" || { echo "release agent: could not obtain readiness verdict" >&2; exit 1; }

# Show the human-readable readiness block too.
"$heart" readiness || true

case "$verdict" in
green)
echo "== readiness GREEN — delegating to PyAutoBuild executor =="
;;
yellow)
if [[ "$force" -eq 1 ]]; then
echo "== readiness YELLOW — proceeding (--force) =="
else
echo "release agent: readiness is YELLOW (caution). Re-run with --force to proceed." >&2
exit 2
fi
;;
red)
echo "release agent: readiness is RED — release blocked. Fix the blockers above." >&2
exit 3
;;
*)
echo "release agent: unknown readiness verdict '$verdict' — refusing to release." >&2
exit 4
;;
esac
echo "== release conductor: delegating gate + execution to the Build Agent (release mode) =="

autobuild="$(resolve_autobuild)" || exit $?
echo "== exec: autobuild pre_build ${forward[*]:-} =="
exec "$autobuild" pre_build "${forward[@]}"
# One gate implementation, not two: the Build Agent's release mode refreshes
# health via the vitals faculty, applies GREEN / YELLOW(--force) / RED, and on
# a pass runs `autobuild pre_build` (which dispatches release.yml).
args=(--mode release)
[[ "$force" -eq 1 ]] && args+=(--force)
exec bash "$HERE/../build/build.sh" "${args[@]}" -- "${forward[@]}"
4 changes: 2 additions & 2 deletions bin/pyauto-brain
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#
# pyauto-brain feature [args] (conductor) reason over PyAutoMind tasks, plan growth
# pyauto-brain build [args] (conductor) coordinate execution: consult vitals, run Build
# pyauto-brain release [args] (conductor) reason about readiness, then release on green
# pyauto-brain release [args] (conductor) release door → Build Agent release mode (gate + pre_build)
# (release rehearse: Stage-2 TestPyPI rehearsal;
# release validate: full Stages 0-3 orchestrator)
# pyauto-brain health [args] (conductor) the organism's clinician: run the health
Expand Down Expand Up @@ -48,7 +48,7 @@ declare -A AGENT_DESC=(
[feature]="Reason over PyAutoMind feature tasks: select, size, phase, plan for start_dev"
[bug]="The immune system: classify a bug/regression/Heart finding, locate the fix, plan the repair"
[build]="Coordinate execution: consult the vitals faculty, then delegate to PyAutoBuild"
[release]="Reason about readiness + run release on green; 'release rehearse'/'release validate' drive release validation"
[release]="Release door → the Build Agent release mode (single gate); 'release rehearse'/'release validate' drive release validation"
[health]="The organism's clinician: run the health loop with a human, dispatch by dispatch, toward green"
[vitals]="Read-only: read the Heart's pulse — the PyAutoHeart readiness verdict (consulted by the conductors)"
)
Expand Down
2 changes: 1 addition & 1 deletion skills/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Reasoning is delegated to PyAutoBrain agents (`PyAutoBrain/AGENTS.md` is authori
```bash
bin/pyauto-brain feature [<work-type>/<target>/<task>.md] # classify + plan a task (Feature/Bug/Refactor/… routing)
bin/pyauto-brain build [--dry-run] # consult vitals, then delegate execution to Build
bin/pyauto-brain release # reason over readiness, release on green
bin/pyauto-brain release # release door → Build Agent release mode (gate + pre_build)
bin/pyauto-brain vitals # one health tick + the unified dashboard card
```

Expand Down