diff --git a/AGENTS.md b/AGENTS.md index f27a050..0f6ca10 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -75,15 +75,15 @@ Build never re-derives a decision the Brain already made. Brain agents are not limited to driving organs — they can **consult each other**. The canonical example is the **Build Agent**, which does not query Heart directly: -it consults the **Health Agent**, and only the Health Agent talks to the Heart +it consults the **vitals faculty**, and only the vitals faculty talks to the Heart organ. So the Build Agent's full chain is: ``` -Mind → Build Agent → Health Agent → Heart → GREEN/YELLOW/RED +Mind → Build Agent → vitals faculty → Heart → GREEN/YELLOW/RED → Build Agent → Build (execute) ``` -This generalises: a future Feature Agent can ask the Health Agent whether the +This generalises: a future Feature Agent can ask the vitals faculty whether the tree is fit for a refactor; a future Release Agent can ask the Build Agent to package a release. Reasoning lives in Brain agents that consult one another; the organs (Heart, Hands/Build, Memory) provide capabilities and state. The Build @@ -91,46 +91,82 @@ Agent is the reusable template for this pattern. ## Specialist reasoning agents -Each agent is a directory under `agents//` with: - -- `AGENTS.md` — what the agent reasons about and how to run it. -- a deterministic entrypoint script (`*.sh` / `*.py`) — the part CI and humans - invoke identically, so behaviour isn't re-derived from prose each time. - -Current agents: - -- **`agents/feature/`** — the **growth function**: reasons over PyAutoMind - `feature/*` intent and decides *how the organism should grow*. Selects the next - feature task (or plans a named one), estimates difficulty, decides whether to - phase, consults PyAutoMemory for scientific/architectural context and (for - risky work) the Health Agent, and emits a `FeatureDecision` that the existing - `start_dev → ship_library/ship_workspace` workflow consumes. It reasons; it - never edits source. (Organism-facing name: *Growth Agent*.) -- **`agents/build/`** — the executive function for execution work. Consults the - Health Agent, reasons over the verdict, and on a healthy result delegates to - the appropriate PyAutoBuild capability. The canonical example of the Brain - coordinating *multiple* organs. Has `build` / `deploy` / `release` modes — - release is isolated as a mode now, with a clean seam to a future Release Agent. -- **`agents/release/`** — reasons over `pyauto-heart readiness`, and on green - triggers the PyAutoBuild release executor (`autobuild pre_build` → `release.yml`). -- **`agents/health/`** — reasons over the PyAutoHeart monitoring/readiness surface. +Agents live in **two tiers** under `agents/`, distinguished by one question — +*does it act, or only opine?* + +- **Conductors** (`agents/conductors//`) — front-door agents a human + **drives**. They *decide **and** act*, delegating execution to the organs. + They have side effects in the world (a plan driven into dev, a build, a + release). This is the small, curated set of things you invoke and converse + with. +- **Faculties** (`agents/faculties//`) — read-only reasoning capabilities + the conductors **consult**. They *only opine* — return a judgment and stop; + they never dispatch or mutate. They are *sinks* in the consult graph + (everything reaches into them; they reach out only to their sensor organ). Not + chat-first surfaces, though they stay runnable for a quick read. + +The rule of thumb: **keep the conductor set small and human-meaningful; let +faculties multiply behind them.** A side-effecting decider is a conductor; a +side-effect-free opinion is a faculty. + +Each agent is a directory with an `AGENTS.md` (what it reasons about + how to run +it) and a deterministic entrypoint script (`*.sh` / `*.py`) — the part CI and +humans invoke identically, so behaviour isn't re-derived from prose each time. + +### Conductors + +- **`agents/conductors/feature/`** — the **growth function**: reasons over + PyAutoMind `feature/*` intent and decides *how the organism should grow*. + Selects the next feature task (or plans a named one), estimates difficulty, + decides whether to phase, consults PyAutoMemory for scientific/architectural + context and (for risky work) the vitals faculty, and emits a `FeatureDecision` + that the existing `start_dev → ship_library/ship_workspace` workflow consumes. + It reasons; it never edits source. (Organism-facing name: *Growth Agent*.) +- **`agents/conductors/build/`** — the executive function for execution work. + Consults the vitals faculty, reasons over the verdict, and on a healthy result + delegates to the appropriate PyAutoBuild capability. The canonical example of + 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/health/`** — the organism's **clinician**: runs the health + *loop* with a human — assess → triage → (on your go-ahead) dispatch a + validation leg → re-judge — until Heart goes GREEN. Consults the vitals faculty + for every verdict and delegates all dispatch to the release conductor; it drives + the loop, not the wire. Named for what it manages (the organism's *health*), not + an external visitor. Current scope is *validation + recommend*, checkpointing + every dispatch; *edit-in fixes* are an explicit follow-up. (Skeleton.) + +### Faculties + +- **`agents/faculties/vitals/`** — the read-only **vitals faculty** (it *reads the + Heart's pulse*): adopts the PyAutoHeart readiness verdict and explains it, + mapping each reason to its capability. It is the single component that talks to + Heart; the conductors (build, release, feature, health) all consult it rather + than querying Heart directly. It never dispatches or mutates — that inertness is + why it is safe for everyone to call. > **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/release/` is the older, +> 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 Health Agent *more strictly*, then requesting execution from the +> consulting the vitals faculty *more strictly*, then requesting execution from the > Build Agent / PyAutoBuild. Until then: one agent now, clean seam for two later. More specialist agents are expected over time (Bug / Refactor / Documentation / -Research agents, and a split-out Release agent); the Feature Agent above is the -first of these, the Brain agent that reasons over PyAutoMind `feature/*` intent. -The Build Agent is the reusable template — add new ones as `agents//` -directories following its shape (a concise `AGENTS.md`, a deterministic -entrypoint, and a capability audit of any organ it drives — the Feature Agent's -`MIND_TAXONOMY.md` is that audit for the PyAutoMind/PyAutoMemory surface). +Research agents, cost/risk faculties, …). When adding one, **place it by tier**: +a side-effecting decider you drive → `agents/conductors//`; a read-only +opinion the conductors consult → `agents/faculties//`. Follow the Build +Agent's shape (a concise `AGENTS.md` opening with its `Tier:` line, a +deterministic entrypoint, and a capability audit of any organ it drives — the +Feature Agent's `MIND_TAXONOMY.md` is that audit for the PyAutoMind/PyAutoMemory +surface). Keep the conductor set small; prefer adding a faculty when the new +thing only reasons. ## Running @@ -138,10 +174,11 @@ entrypoint, and a capability audit of any organ it drives — the Feature Agent' bin/pyauto-brain help # list agents bin/pyauto-brain feature # select the best next PyAutoMind feature task bin/pyauto-brain feature feature/autofit/sbi.md # plan a specific feature task -bin/pyauto-brain build # consult health, then delegate execution to Build +bin/pyauto-brain build # consult vitals, then delegate execution to Build bin/pyauto-brain build --dry-run # reason + plan only (emit the BuildDecision) bin/pyauto-brain release # reason about readiness, then release on green -bin/pyauto-brain health # one health tick + the unified dashboard card +bin/pyauto-brain health # (conductor) run the health loop with a human, toward green +bin/pyauto-brain vitals # (faculty) one tick + the unified dashboard card (raw read) ``` Like the other PyAuto repos, PyAutoBrain runs from its checkout (no pip install); diff --git a/README.md b/README.md index ddf46ca..cc84c95 100644 --- a/README.md +++ b/README.md @@ -42,20 +42,40 @@ Brain → Heart (gate) → Build (execute) ## Specialist reasoning agents -- **`agents/build/`** — the executive function for execution work. Consults the - Health Agent, reasons over the verdict, and on a healthy result delegates to - PyAutoBuild. The canonical example of the Brain coordinating multiple organs; - has `build` / `deploy` / `release` modes. -- **`agents/release/`** — reasons over `pyauto-heart readiness` → on green, runs - the PyAutoBuild release executor. -- **`agents/health/`** — reasons over the PyAutoHeart monitoring / readiness surface. - -Brain agents can also **consult one another**: the Build Agent doesn't query -Heart directly — it asks the Health Agent, which is the only agent that talks to -the Heart organ. +Agents live in **two tiers** under `agents/`, split by one question — *does it +act, or only opine?* **Conductors** (`agents/conductors/`) are front doors you +drive: they decide *and* act, delegating execution to the organs. **Faculties** +(`agents/faculties/`) are read-only reasoning capabilities the conductors +consult: they only return a judgment and stop. Keep the conductor set small; let +faculties multiply behind them. + +**Conductors:** + +- **`agents/conductors/feature/`** — the growth function: reasons over PyAutoMind + `feature/*` intent and plans how the organism grows. +- **`agents/conductors/build/`** — the executive function for execution work. + Consults the vitals faculty, reasons over the verdict, and on a healthy result + delegates to PyAutoBuild. Has `build` / `deploy` / `release` modes. +- **`agents/conductors/release/`** — reasons over `pyauto-heart readiness` → on + green, runs the PyAutoBuild release executor; also orchestrates release + validation (`release rehearse` / `release validate`). +- **`agents/conductors/health/`** — the organism's clinician: runs the health + loop with a human — assess → triage → (on your go-ahead) dispatch a validation + leg → re-judge — until Heart goes green. Consults the vitals faculty and + delegates dispatch to the release conductor. (Skeleton; validation + recommend.) + +**Faculties:** + +- **`agents/faculties/vitals/`** — read-only: reads the Heart's pulse — adopts the + PyAutoHeart readiness verdict and explains it. The single component that talks + to Heart. + +Brain agents **consult one another**: a conductor doesn't query Heart directly — +it asks the vitals faculty, which is the only agent that talks to the Heart +organ. ``` -Mind → Build Agent → Health Agent → Heart → GREEN/YELLOW/RED +Mind → Build Agent → vitals faculty → Heart → GREEN/YELLOW/RED → Build Agent → Build (execute) ``` @@ -67,9 +87,10 @@ release/build/deploy execution), isolated so it can split into a dedicated ```bash bin/pyauto-brain help # list agents -bin/pyauto-brain build # consult health, then delegate execution to Build +bin/pyauto-brain build # consult vitals, then delegate execution to Build bin/pyauto-brain release # reason about readiness, then release on green -bin/pyauto-brain health # one health tick + the unified dashboard card +bin/pyauto-brain health # (conductor) run the health loop with a human, toward green +bin/pyauto-brain vitals # (faculty) one tick + the unified dashboard card (raw read) ``` PyAutoBrain runs from its checkout (no pip install), resolving the sibling diff --git a/agents/_common.sh b/agents/_common.sh index 2ed2397..eb0b14e 100755 --- a/agents/_common.sh +++ b/agents/_common.sh @@ -73,41 +73,48 @@ readiness_verdict() { } # _agents_dir — directory holding the sibling agents (this file lives in it). +# Agents are organised into two tiers beneath it: conductors/ (front-door agents +# a human drives) and faculties/ (read-only reasoning capabilities the conductors +# consult). This helper returns the tier-parent (agents/); callers add the tier. _agents_dir() { cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd } -# consult_health_agent_verdict [--refresh] — ask the *sibling Health Agent* for -# the readiness verdict, rather than querying PyAutoHeart directly. This is the -# Brain-agent-consults-Brain-agent pattern: a specialist agent reasons *with* -# another specialist agent, and only the Health Agent talks to the Heart organ. -# It keeps the Build Agent decoupled from Heart's surface and lets future agents -# (Feature, Release, ...) consult one another the same way. +# consult_vitals_verdict [--refresh] — ask the *sibling vitals faculty* for the +# readiness verdict, rather than querying PyAutoHeart directly. This is the +# Brain-agent-consults-Brain-agent pattern: a conductor reasons *with* a +# read-only faculty, and only the vitals faculty talks to the Heart organ. It +# keeps the conductors (build, release, feature, health) decoupled from Heart's +# surface and lets them all read the verdict the same way. # -# --refresh ask the Health Agent to refresh Heart's state first (a fresh +# (Back-compat: `consult_health_agent_verdict` remains as an alias below — the +# faculty was renamed health -> vitals, and the loop conductor took the name +# `health`.) +# +# --refresh ask the vitals faculty to refresh Heart's state first (a fresh # gate); release-grade work uses this, ordinary build work does not. # # Echoes one of: green | yellow | red | unknown. Never fails the caller — an # unresolvable/again-unknown verdict is reported as "unknown" (treated as YELLOW # by callers), never silently as green. -consult_health_agent_verdict() { +consult_vitals_verdict() { local refresh=0 [[ "${1:-}" == "--refresh" ]] && refresh=1 - local health - health="$(_agents_dir)/health/health.sh" - if [[ ! -f "$health" ]]; then + local vitals + vitals="$(_agents_dir)/faculties/vitals/vitals.sh" + if [[ ! -f "$vitals" ]]; then echo "unknown" return 0 fi if [[ "$refresh" -eq 1 ]]; then - bash "$health" tick >/dev/null 2>&1 || true + bash "$vitals" tick >/dev/null 2>&1 || true fi # Capture into a variable rather than piping straight out: the caller may have # `set -o pipefail`, under which a non-zero exit from the (possibly - # Heart-less) Health Agent would otherwise double-fire a fallback. The python + # Heart-less) vitals faculty would otherwise double-fire a fallback. The python # below always prints exactly one token, even on empty/garbage input. local out - out="$(bash "$health" readiness --json 2>/dev/null | python3 -c ' + out="$(bash "$vitals" readiness --json 2>/dev/null | python3 -c ' import json, sys try: v = json.load(sys.stdin).get("verdict", "unknown") @@ -117,3 +124,6 @@ except Exception: ' 2>/dev/null)" printf '%s\n' "${out:-unknown}" } + +# Back-compat alias for the pre-rename name (faculty: health -> vitals). +consult_health_agent_verdict() { consult_vitals_verdict "$@"; } diff --git a/agents/build/AGENTS.md b/agents/conductors/build/AGENTS.md similarity index 85% rename from agents/build/AGENTS.md rename to agents/conductors/build/AGENTS.md index dc319e6..207dcb9 100644 --- a/agents/build/AGENTS.md +++ b/agents/conductors/build/AGENTS.md @@ -1,12 +1,16 @@ # Build agent +> **Tier: conductor** — a front-door agent you *drive*. It decides *whether/what* +> to build and drives execution, delegating the *building* to PyAutoBuild and the +> *health decision* to the read-only vitals faculty. It acts; it does not measure. + The second canonical **PyAutoBrain** reasoning agent, and the reference example of how the Brain coordinates *multiple* organs. It is the executive function for execution work: it owns the build *workflow* but delegates the *building* to -PyAutoBuild and the *health decision* to the Health Agent. +PyAutoBuild and the *health decision* to the vitals faculty. ``` -Mind → Build Agent → Health Agent → Heart → GREEN/YELLOW/RED +Mind → Build Agent → vitals faculty → Heart → GREEN/YELLOW/RED → Build Agent → PyAutoBuild (execute) ``` @@ -20,10 +24,10 @@ PyAutoBuild executes. It must never duplicate PyAutoBuild functionality. ## Brain agents consult one another The Build Agent does not call PyAutoHeart directly. It **consults the sibling -Health Agent**, which is the only agent that talks to the Heart organ. This is +vitals faculty**, which is the only agent that talks to the Heart organ. This is the society-of-agents pattern: specialist Brain agents reason *with* each other, while the organs (Heart, Hands, Memory) provide capabilities and state. Future -agents generalise the same way — a Feature Agent asking the Health Agent if the +agents generalise the same way — a Feature Agent asking the vitals faculty if the tree is fit for a refactor; a Release Agent asking the Build Agent to package. ## Modes (one agent now, clean seam for a Release Agent later) @@ -39,7 +43,7 @@ later with no churn to build mode. | `deploy` | `generate` | cautious — GREEN proceeds, YELLOW needs `--force`, RED aborts | `generate`, `bump_colab_urls` | | `release` | `pre_build` | strict — refreshes health first; GREEN proceeds, YELLOW needs `--force`, RED aborts | `pre_build`, `tag_and_merge`, `generate_release_notes`, `create_analysis_issue`, `aggregate_results` | -Release consults health *more strictly*: it asks the Health Agent to refresh +Release consults health *more strictly*: it asks the vitals faculty to refresh Heart's state first (`--refresh`) so a release is never gated on a stale verdict. An **unknown** verdict collapses to YELLOW — never silently GREEN. @@ -47,8 +51,8 @@ An **unknown** verdict collapses to YELLOW — never silently GREEN. 1. Receive a build request (mode + action). 2. Validate the action against the mode (reject health-shim commands — those are - Heart's surface, reached via `pyauto-brain health`). -3. Consult the Health Agent for the readiness verdict. + Heart's surface, reached via `pyauto-brain vitals`). +3. Consult the vitals faculty for the readiness verdict. 4. Interpret it: **GREEN** proceed · **YELLOW** caution (proceed in build mode, else `--force`) · **RED** abort with blockers. 5. Invoke the appropriate PyAutoBuild capability. @@ -97,9 +101,9 @@ A future Python `BuildAgent().execute(...)` wrapper can return this same shape. - Build, package, tag, or publish anything itself — that is PyAutoBuild's job. - Query PyAutoHeart directly or re-derive a readiness verdict — consult the - Health Agent. + vitals faculty. - Re-own a health-shim command (`verify_install`, `url_check`, `watch`, `status`, - `tick`, `fix`) — those belong to Heart, reached via `pyauto-brain health`. + `tick`, `fix`) — those belong to Heart, reached via `pyauto-brain vitals`. - Mix release-specific reasoning into generic build execution — keep it in release mode. diff --git a/agents/build/BUILD_CAPABILITIES.md b/agents/conductors/build/BUILD_CAPABILITIES.md similarity index 94% rename from agents/build/BUILD_CAPABILITIES.md rename to agents/conductors/build/BUILD_CAPABILITIES.md index ff0b619..46ec138 100644 --- a/agents/build/BUILD_CAPABILITIES.md +++ b/agents/conductors/build/BUILD_CAPABILITIES.md @@ -45,8 +45,8 @@ PyAutoHeart, which keeps a `pyauto-pulse` back-compat shim): - `watch` / `status` / `tick` / `fix` — monitoring-daemon shims. **Decision:** these are health concerns, not build actions. The Build Agent -**refuses to route them** and points the caller at `pyauto-brain health ` -instead. They belong to PyAutoHeart and are reached through the Health Agent — +**refuses to route them** and points the caller at `pyauto-brain vitals ` +instead. They belong to PyAutoHeart and are reached through the vitals faculty — never re-owned by the Build Agent, and never duplicated in Brain. No non-trivial readiness logic was found living *inside* PyAutoBuild itself (the shims only delegate); if any ever appears, migrate it to PyAutoHeart and leave only @@ -55,8 +55,8 @@ delegation in PyAutoBuild. This keeps the architecture clean: ``` -reasoning → PyAutoBrain (Build Agent, Health Agent) -health → PyAutoHeart (via the Health Agent) +reasoning → PyAutoBrain (Build Agent, vitals faculty) +health → PyAutoHeart (via the vitals faculty) execution → PyAutoBuild (via the Build Agent) ``` @@ -75,7 +75,7 @@ anywhere the agent must re-derive at runtime beyond the per-mode allowlists in - **GREEN** — proceed; invoke the requested PyAutoBuild capability. - **YELLOW** — build mode proceeds with a warning; deploy/release require `--force`. An unknown verdict is treated as YELLOW. -- **RED** — abort; surface Heart's blockers (via the Health Agent) and do not +- **RED** — abort; surface Heart's blockers (via the vitals faculty) and do not execute. The Build Agent may sequence, plan, and explain execution, but it must never run diff --git a/agents/build/build.sh b/agents/conductors/build/build.sh similarity index 91% rename from agents/build/build.sh rename to agents/conductors/build/build.sh index 8495d19..b8038a8 100755 --- a/agents/build/build.sh +++ b/agents/conductors/build/build.sh @@ -8,12 +8,12 @@ # # Call chain (the Brain coordinating multiple organs): # -# Mind -> Build Agent -> Health Agent -> Heart -> GREEN/YELLOW/RED +# Mind -> Build Agent -> vitals faculty -> Heart -> GREEN/YELLOW/RED # -> Build Agent -> PyAutoBuild (execute) # -# Note the consult step goes through the *sibling Health Agent*, not Heart +# Note the consult step goes through the *sibling vitals faculty*, not Heart # directly: Brain agents consult one another (a society of reasoning agents), -# and only the Health Agent talks to the Heart organ. +# and only the vitals faculty talks to the Heart organ. # # Modes (one agent now, clean seam for a future Release Agent): # build generic execution (generate notebooks, run scripts, aggregate). @@ -39,13 +39,13 @@ set -uo pipefail HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" -source "$HERE/../_common.sh" +source "$HERE/../../_common.sh" # ----- mode -> allowed actions, default action, gate strictness ----- # Actions are PyAutoBuild capabilities. The Build Agent calls them; it never # reimplements them. Health-shim commands (verify_install, url_check, watch, # status, tick, fix) are deliberately NOT routable here — those are Heart's -# surface, reached through the Health Agent, never re-owned by Build. +# surface, reached through the vitals faculty, never re-owned by Build. BUILD_ACTIONS="generate run run_python run_all script_matrix aggregate_results slow_skip_check repro_command bump_colab_urls" DEPLOY_ACTIONS="generate bump_colab_urls" RELEASE_ACTIONS="pre_build tag_and_merge generate_release_notes create_analysis_issue aggregate_results" @@ -85,7 +85,7 @@ esac # Reject health-shim commands with a pointer to the right organ. if [[ " $HEALTH_SHIMS " == *" $action "* ]]; then echo "build agent: '$action' is a health concern owned by PyAutoHeart, not a" >&2 - echo " build action. Consult it via: pyauto-brain health $action" >&2 + echo " build action. Consult it via: pyauto-brain vitals $action" >&2 exit 5 fi if [[ " $allowed " != *" $action "* ]]; then @@ -94,12 +94,12 @@ if [[ " $allowed " != *" $action "* ]]; then exit 5 fi -# ----- consult the sibling Health Agent (not Heart directly) ----- -[[ "$json_only" -eq 1 ]] || echo "== build agent ($mode): consulting Health Agent for readiness ==" +# ----- consult the sibling vitals faculty (not Heart directly) ----- +[[ "$json_only" -eq 1 ]] || echo "== build agent ($mode): consulting vitals faculty for readiness ==" if [[ "$mode" == "release" ]]; then - verdict="$(consult_health_agent_verdict --refresh)" + verdict="$(consult_vitals_verdict --refresh)" else - verdict="$(consult_health_agent_verdict)" + verdict="$(consult_vitals_verdict)" fi # ----- reason: map (mode, verdict) -> decision ----- @@ -110,12 +110,12 @@ eff="$verdict" decision="" ; decision_code=0 warnings=() ; blockers=() ; follow_up=() -[[ "$verdict" == "unknown" ]] && warnings+=("Readiness verdict unknown; treated as YELLOW. Run 'pyauto-brain health' to refresh.") +[[ "$verdict" == "unknown" ]] && warnings+=("Readiness verdict unknown; treated as YELLOW. Run 'pyauto-brain vitals' to refresh.") case "$eff" in red) decision="abort"; decision_code=3 - blockers+=("PyAutoHeart reports RED. Resolve the blockers (see 'pyauto-brain health') before $mode work.") + blockers+=("PyAutoHeart reports RED. Resolve the blockers (see 'pyauto-brain vitals') before $mode work.") ;; yellow) if [[ "$mode" == "build" ]]; then diff --git a/agents/feature/AGENTS.md b/agents/conductors/feature/AGENTS.md similarity index 90% rename from agents/feature/AGENTS.md rename to agents/conductors/feature/AGENTS.md index 94388b1..0b7b8cd 100644 --- a/agents/feature/AGENTS.md +++ b/agents/conductors/feature/AGENTS.md @@ -1,5 +1,9 @@ # Feature agent +> **Tier: conductor** — a front-door agent you *drive*. It decides how the +> organism grows and drives that plan into the dev workflow; it *consults* the +> read-only vitals faculty (`--check-health`) but never queries Heart directly. + The **growth function** of PyAutoBrain. It reasons over the feature *intent* stored in PyAutoMind and decides **how the organism should grow** — which feature task to work on, how hard it is, whether it must be phased, what scientific @@ -12,7 +16,7 @@ Mind (PyAutoMind feature/*) → Feature Agent → start_dev → start_library / ship_library → start_workspace / ship_workspace consults ↘ ↙ consults - Health Agent PyAutoMemory (scientific / architectural context) + vitals faculty PyAutoMemory (scientific / architectural context) ``` > Long term this is the organism-facing **Growth Agent**; *Feature Agent* is the @@ -28,9 +32,8 @@ handed to the existing workflow. ## Brain agents consult one another Like the Build Agent, the Feature Agent is a citizen of the society of agents. -For risky / multi-repo / release-bound work it **consults the sibling Health -Agent** (`--check-health`) rather than querying the Heart organ directly — only -the Health Agent talks to Heart. It also consults **PyAutoMemory** for scientific +For risky / multi-repo / release-bound work it **consults the sibling vitals faculty** (`--check-health`) rather than querying the Heart organ directly — only +the vitals faculty talks to Heart. It also consults **PyAutoMemory** for scientific and architectural context, and **never invents science** when memory has material. See [`MIND_TAXONOMY.md`](./MIND_TAXONOMY.md) for the PyAutoMind taxonomy it reasons over and the PyAutoMemory routing it uses. @@ -68,7 +71,7 @@ bin/pyauto-brain feature feature/autofit/sbi.md # specific mode bin/pyauto-brain feature select --difficulty easy # easy task bin/pyauto-brain feature select --model strong --limit 5 # ambitious shortlist bin/pyauto-brain feature select --impact # highest-leverage -bin/pyauto-brain feature --check-health feature/autolens/x.md # also consult Health +bin/pyauto-brain feature --check-health feature/autolens/x.md # also consult vitals bin/pyauto-brain feature --json select # machine-readable ``` @@ -107,7 +110,7 @@ body, not the folder (per PyAutoMind `ROUTING.md`). - Edit source, open PRs, or run builds itself — that is the Build Agent / PyAutoBuild via `start_dev` / `ship_*`. -- Query PyAutoHeart directly — consult the Health Agent (`--check-health`). +- Query PyAutoHeart directly — consult the vitals faculty (`--check-health`). - Invent scientific or architectural context when PyAutoMemory has material — cite the sub-wiki instead. - Just pick the first prompt in selection mode — rank, and explain the choice. diff --git a/agents/feature/MIND_TAXONOMY.md b/agents/conductors/feature/MIND_TAXONOMY.md similarity index 98% rename from agents/feature/MIND_TAXONOMY.md rename to agents/conductors/feature/MIND_TAXONOMY.md index 466e714..16d4b62 100644 --- a/agents/feature/MIND_TAXONOMY.md +++ b/agents/conductors/feature/MIND_TAXONOMY.md @@ -105,7 +105,7 @@ must re-derive at runtime. intent → PyAutoMind (feature/* prompts, active/planned/queue state) reasoning → PyAutoBrain (Feature Agent — this) knowledge → PyAutoMemory (via direct file reads; cited, never invented) -health → PyAutoHeart (via the Health Agent, never queried directly) +health → PyAutoHeart (via the vitals faculty, never queried directly) execution → PyAutoBuild (via start_dev / ship_* — never run by this agent) ``` diff --git a/agents/feature/_feature.py b/agents/conductors/feature/_feature.py similarity index 98% rename from agents/feature/_feature.py rename to agents/conductors/feature/_feature.py index 39974dd..21ce195 100755 --- a/agents/feature/_feature.py +++ b/agents/conductors/feature/_feature.py @@ -294,8 +294,8 @@ def health_consideration(level: str, factors: dict, workflow: str): if workflow == "combined": reasons.append("requires coordinated library + workspace PRs") if not reasons: - return "Optional: tree is likely fit; consult the Health Agent if recent CI is unknown." - return ("Consult the Health Agent (pyauto-brain health) before starting — this task " + return "Optional: tree is likely fit; consult the vitals faculty if recent CI is unknown." + return ("Consult the vitals faculty (pyauto-brain vitals) before starting — this task " + ", ".join(reasons) + ".") @@ -516,7 +516,7 @@ def main(argv=None): emit_human(mode, decision) print("\nWhy this task: highest-ranked under the active constraint after " "down-ranking in-flight work; confirm against PyAutoMind priorities " - "(planned.md / active.md) and a Health Agent check before committing.") + "(planned.md / active.md) and a vitals faculty check before committing.") return 0 diff --git a/agents/feature/feature.sh b/agents/conductors/feature/feature.sh similarity index 88% rename from agents/feature/feature.sh rename to agents/conductors/feature/feature.sh index 18ef3b4..76bec00 100755 --- a/agents/feature/feature.sh +++ b/agents/conductors/feature/feature.sh @@ -12,8 +12,8 @@ # -> start_workspace / ship_workspace # # Like the Build Agent, it is a society-of-agents citizen: for risky / multi-repo -# / release-bound work it can consult the sibling Health Agent (and only the -# Health Agent talks to the Heart organ). It consults PyAutoMemory for scientific +# / release-bound work it can consult the sibling vitals faculty (and only the +# vitals faculty talks to the Heart organ). It consults PyAutoMemory for scientific # and architectural context — it never invents science when memory has material. # # Modes: @@ -28,7 +28,7 @@ # [--model weak|strong] [--budget] [--ambitious] # [--impact] [--limit N] # feature.sh [--json] ... # machine-readable FeatureDecision -# feature.sh [--check-health] ... # also consult the Health Agent +# feature.sh [--check-health] ... # also consult the vitals faculty # # The analysis core lives in _feature.py (stdlib-only, never writes). This script # resolves the PyAutoMind / PyAutoMemory checkouts and, optionally, the verdict. @@ -39,7 +39,7 @@ set -uo pipefail HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" -source "$HERE/../_common.sh" +source "$HERE/../../_common.sh" check_health=0 as_json=0 @@ -69,12 +69,12 @@ elif [[ "${forward[0]}" != "select" && "${forward[0]}" != "specific" \ forward=(specific "${forward[@]}") fi -# Optionally consult the sibling Health Agent up front (society-of-agents). This +# Optionally consult the sibling vitals faculty up front (society-of-agents). This # does not gate the decision — it annotates it — so the agent still reasons even # when Heart is unreachable. if [[ "$check_health" -eq 1 ]]; then - echo "== feature agent: consulting Health Agent for tree readiness ==" - verdict="$(consult_health_agent_verdict)" + echo "== feature agent: consulting vitals faculty for tree readiness ==" + verdict="$(consult_vitals_verdict)" echo " readiness verdict: $verdict" echo fi diff --git a/agents/conductors/health/AGENTS.md b/agents/conductors/health/AGENTS.md new file mode 100644 index 0000000..20ff2c6 --- /dev/null +++ b/agents/conductors/health/AGENTS.md @@ -0,0 +1,81 @@ +# Health agent + +> **Tier: conductor** — a front-door agent you *drive*. The organism's +> clinician; the brain's vagus-nerve link to the Heart. It reads the Heart's +> pulse (via the read-only **vitals faculty**) and works with you, dispatch by +> dispatch, to restore the organism to green. Named for what it manages +> (the organism's *health*), not for an external visitor. + +A PyAutoBrain conductor. Where the **vitals faculty** only *opines* (adopts +PyAutoHeart's verdict and explains it, read-only), the health conductor +**acts**: it runs the whole health *loop* with a human in the seat — assess, +triage, dispatch a validation leg, re-judge — until Heart reports GREEN. It is +the single conversational point of contact for "let's get the organism healthy", +tying together the pieces that already exist rather than adding new machinery. + +``` +Mind → Health (conduct the loop) → { vitals (judge) · release (dispatch) } → Heart (measure) → GREEN +``` + +## What it does (and doesn't) + +The health conductor **owns no checks and no dispatch of its own**. It +coordinates: + +- **Assess** — consult the **vitals faculty** for the authoritative verdict and + render the unified card. The verdict is Heart's; the conductor adopts it + verbatim and never re-derives it. +- **Triage** — map each reason to its capability (via Heart's manifest), and + separate *expected first-run gaps* (no validation report yet) from *real + problems* (a failing CI, a dirty tree). +- **Recommend + checkpoint** — surface the single most useful next action and + **stop for your go-ahead**. Every dispatch is a human checkpoint. +- **Dispatch (delegated)** — on your confirmation, the actual GitHub work is + driven by the **release conductor** (`pyauto-brain release validate`), which + owns the MCP boundary. This conductor never dispatches or mutates a repo itself. +- **Re-judge + loop** — after a leg lands, re-assess and repeat until GREEN or + you stop. + +## Scope (this cut) and the follow-up + +- **Validation + recommend.** It runs the *assess* step deterministically and + *recommends* the next dispatch; it does not auto-run it, and it does not edit + repositories. +- **Checkpoint every dispatch.** Nothing is dispatched without your explicit + go-ahead in the loop. +- **Follow-up (not yet):** *edit-in fixes* — letting the health conductor + branch/edit/push to clear a red (CI failure, dirty tree) — is a deliberate + later milestone. Until then, real code fixes are handed to you / a feature-agent + session, and the conductor cites the `pyauto-heart fix ` + entry point where Heart offers one. + +## Run + +```bash +bin/pyauto-brain health # assess: render the card, adopt the verdict, recommend the next checkpoint +bin/pyauto-brain health assess # same as the no-arg assess +``` + +For just the raw read (no loop), consult the faculty directly: +`bin/pyauto-brain vitals`. + +Exit codes mirror the adopted verdict so a caller can branch: +`0` green · `2` yellow · `3` red · `4` unknown. A CLI usage error (unknown +subcommand) exits `5`, kept distinct so misuse is never read as a real YELLOW. + +The conversational loop itself is mediated by the Brain reasoning layer on top of +`health.sh`; the script supplies the deterministic footing (current card + +adopted verdict + the single recommended checkpoint). The human and the Brain +reason together over that footing, one confirmed dispatch at a time. + +## Boundaries (non-negotiable) + +- **Adopt, never re-derive, the verdict.** Judging is the vitals faculty's job + (and Heart's). This conductor consults; it does not recompute a gate. +- **Delegate every dispatch.** All GitHub dispatch/poll/download is the release + conductor's job, across the MCP boundary. The health conductor drives the + *loop*, not the wire. +- **No repo writes in this cut.** Validation + recommend only; edit-in fixes are + a later, explicitly-scoped follow-up. +- **Never escalate an unknown to GREEN or RED.** An unknown is YELLOW — surface + it, recommend the leg that resolves it, and checkpoint. diff --git a/agents/conductors/health/health.sh b/agents/conductors/health/health.sh new file mode 100755 index 0000000..4408250 --- /dev/null +++ b/agents/conductors/health/health.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +# agents/conductors/health/health.sh — the health conductor (SKELETON). +# +# The health conductor is the organism's clinician: the brain's vagus-nerve link +# to the Heart. It runs the health loop *with a human* — assess -> triage -> (on +# your go-ahead) dispatch a validation leg -> re-judge -> repeat — until +# PyAutoHeart goes GREEN. It is a CONDUCTOR: it decides and drives, delegating +# every action to the agent that owns it, and reimplements no check of its own. +# +# Boundaries (this cut): +# * It CONSULTS the vitals faculty for every verdict (read-only). Only the +# vitals faculty / Heart measures; this conductor never re-derives a verdict. +# * It DELEGATES all GitHub dispatch to the release conductor +# (`pyauto-brain release validate ...`), which owns the MCP boundary. It +# never dispatches or mutates a repo itself. +# * Scope = validation + recommend. It runs the *assess* step deterministically +# and RECOMMENDS the next dispatch; it does NOT auto-run it. Every dispatch is +# a human checkpoint (you confirm, then the Brain session drives the leg). +# Repo-editing fixes are a deliberate FOLLOW-UP, not in this skeleton. +# +# The conversational fix loop itself is mediated by the Brain reasoning layer on +# top of this scaffold; health.sh supplies the deterministic footing: the current +# verdict + card, and the single recommended next checkpoint. +# +# Usage: +# health.sh # assess: render the card, read the verdict, recommend +# health.sh assess # same as the no-arg assess +# health.sh -h|--help # this header +# +# Exit codes mirror the verdict so a caller can branch: 0 green · 2 yellow · +# 3 red · 4 unknown. A CLI usage error (unknown subcommand) exits 5 — kept +# distinct from the verdict codes so misuse is never read as a real YELLOW. + +set -uo pipefail + +HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" +source "$HERE/../../_common.sh" + +case "${1:-assess}" in + -h|--help) + sed -n '2,33p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//' + exit 0 + ;; + assess) : ;; + *) + echo "health: unknown subcommand '${1:-}' (this skeleton supports: assess)" >&2 + exit 5 # usage error — distinct from the verdict codes (2=YELLOW) + ;; +esac + +echo "== health: assessing organism health (consulting the vitals faculty) ==" + +# 1. Show the human the unified board (the vitals faculty renders Heart's card). +vitals="$(_agents_dir)/faculties/vitals/vitals.sh" +if [[ -f "$vitals" ]]; then + bash "$vitals" || true +else + echo "health: vitals faculty not found at $vitals" >&2 +fi + +echo +# 2. Read the authoritative verdict *through* the faculty — never re-derived here. +verdict="$(consult_vitals_verdict --refresh)" +echo "== health: adopted verdict = ${verdict} ==" +echo + +# 3. Triage -> the single recommended next checkpoint. This conductor RECOMMENDS; +# the human confirms; the Brain session then drives the leg. Nothing is +# dispatched from here. +case "$verdict" in + green) + echo "GREEN — the organism is release-healthy. No action needed." + echo " (A conductor such as 'pyauto-brain release' may now proceed.)" + exit 0 + ;; + yellow) + cat <<'EOF' +YELLOW — mostly healthy; something is unknown or cautionary. Typical first-run +cause: no fresh release-validation for the current source. Recommended next +checkpoint (needs your go-ahead — the health conductor will NOT run it for you): + + pyauto-brain release validate # Stage 0-3: TestPyPI rehearsal + + # wheel integration -> ingest -> re-judge + +After that leg lands, re-run `pyauto-brain health` to re-assess. Repeat until +GREEN. For a specific warning, ask the health conductor to map it to its +capability and, where Heart offers one, the +`pyauto-heart fix ` entry point (validation+recommend +scope — code-editing fixes are a follow-up). +EOF + exit 2 + ;; + red) + cat <<'EOF' +RED — a real blocker. Do NOT dispatch a release. Ask the health conductor to map +each blocking reason to its capability and the remediation entry point; resolve +the blockers (outside this validation+recommend skeleton), then re-run +`pyauto-brain health` to re-assess. +EOF + exit 3 + ;; + *) + echo "UNKNOWN — could not obtain a verdict from the vitals faculty." + echo " Recommended: 'pyauto-brain vitals' to refresh, then re-run the health conductor." + exit 4 + ;; +esac diff --git a/agents/release/AGENTS.md b/agents/conductors/release/AGENTS.md similarity index 90% rename from agents/release/AGENTS.md rename to agents/conductors/release/AGENTS.md index 9e71a09..d21fd93 100644 --- a/agents/release/AGENTS.md +++ b/agents/conductors/release/AGENTS.md @@ -1,5 +1,9 @@ # Release agent +> **Tier: conductor** — a front-door agent you *drive*. It decides whether/when to +> release and orchestrates release validation (dispatch/poll/download across the +> MCP boundary), *consulting* the read-only vitals faculty for the verdict. + A specialist **PyAutoBrain** reasoning agent. It decides whether and when a release should happen, then drives it through the canonical chain: @@ -38,14 +42,14 @@ Exit codes: `0` released/delegated · `2` yellow (use --force) · `3` red blocke Beyond gating a real release, the Release Agent **orchestrates release validation**: it proves the exact source about to ship was built, published to TestPyPI, installed from the wheel, and exercised at release fidelity — then -consults the Health Agent for the verdict. It does this without ever letting +consults the vitals faculty for the verdict. It does this without ever letting Heart dispatch a build (Heart is ingest-and-judge only). The full chain (M2 builds the dispatch+ingest half; M3/M4 add release-fidelity integration + full orchestration): ``` -Mind -> Release Agent (orchestrate) -> Heart (measure) -> Health Agent (judge) -> Hands/Build (promote on GREEN) +Mind -> Release Agent (orchestrate) -> Heart (measure) -> vitals faculty (judge) -> Hands/Build (promote on GREEN) ``` `rehearse.sh` is a two-phase driver. Cloud/mobile sessions have **no `gh`**, so @@ -69,7 +73,7 @@ poll `mcp__github__actions_get` to completion → download the `testpypi-rehearsal-version` artifact → `mcp__github__get_commit` each library's `main` HEAD into `commit_shas.json`. Phase 2 hands the artifacts to `pyauto-heart validate --ingest` (Heart writes `validation_report.json`), then -calls `consult_health_agent_verdict --refresh` so the **read-only Health Agent** +calls `consult_vitals_verdict --refresh` so the **read-only vitals faculty** reports GREEN/YELLOW/RED from the freshly-ingested report. Exit codes (phase 2): `0` green (release-ready) · `2` yellow (use --force) · @@ -120,7 +124,7 @@ bin/pyauto-brain release validate --ingest --force # accept a YELLOW - **Final ingest + verdict** delegates to `rehearse.sh --ingest` (reused verbatim), so `pyauto-heart validate --ingest` folds Stage 2's `rehearsal.json`/`commit_shas.json` and Stage 3's `stage_report.json` - together, then the Health Agent judges. Exit codes are identical to Stage 2's. + together, then the vitals faculty judges. Exit codes are identical to Stage 2's. Exit codes: preflight RED `3`; a phase that can't proceed (missing artifacts) `1`; phase-C ingest `0` green · `2` yellow (`--force`) · `3` red · `4` unknown · @@ -140,13 +144,11 @@ but both originate from Stage 2, which stays authoritative by construction. ## What this agent must never do -- Re-derive or second-guess the readiness verdict (that is Heart's / the Health - Agent's job). +- Re-derive or second-guess the readiness verdict (that is Heart's / the vitals faculty's job). - Run any packaging/tagging/publish step itself (that is Build's job). - Write into PyAutoHeart or PyAutoBuild repos. -## What only this agent does (not the Health Agent) +## What only this agent does (not the vitals faculty) -- Dispatch/poll/download GitHub workflows and artifacts (via MCP). The Health - Agent is strictly read-and-reason — it never dispatches. Heart never dispatches +- Dispatch/poll/download GitHub workflows and artifacts (via MCP). The vitals faculty is strictly read-and-reason — it never dispatches. Heart never dispatches either. All release-validation dispatching is the Release Agent's job. diff --git a/agents/release/rehearse.sh b/agents/conductors/release/rehearse.sh similarity index 94% rename from agents/release/rehearse.sh rename to agents/conductors/release/rehearse.sh index c5c2a62..50fde16 100755 --- a/agents/release/rehearse.sh +++ b/agents/conductors/release/rehearse.sh @@ -10,7 +10,7 @@ # -> download the `testpypi-rehearsal-version` artifact # -> capture the current main HEAD sha of each library # -> hand it all to `pyauto-heart validate --ingest` (Heart measures) -# -> consult the Health Agent for the verdict (Health judges) +# -> consult the vitals faculty for the verdict (vitals judges) # # BOUNDARY. Dispatch/poll/download are GitHub actions, done via Brain's MCP # GitHub tools (cloud/mobile sessions have no `gh`). Bash cannot call MCP, so @@ -40,7 +40,7 @@ set -uo pipefail HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" -source "$HERE/../_common.sh" +source "$HERE/../../_common.sh" # The Build repo + workflow the rehearsal is dispatched against (M1). BUILD_REPO="PyAutoLabs/PyAutoBuild" @@ -165,14 +165,14 @@ Bash cannot call GitHub; execute these steps with Brain's MCP GitHub tools 5. NEXT (continue the pipeline): $next_cmd -After the final ingest, the Health Agent (read-only) reports GREEN/YELLOW/RED +After the final ingest, the vitals faculty (read-only) reports GREEN/YELLOW/RED from the freshly-ingested validation_report — it does NOT dispatch anything. EOF exit 0 fi # --------------------------------------------------------------------------- -# Phase 2: ingest the downloaded artifacts, then consult the Health Agent. +# Phase 2: ingest the downloaded artifacts, then consult the vitals faculty. # --------------------------------------------------------------------------- if [[ ! -d "$ingest_dir" && ! -f "$ingest_dir" ]]; then echo "release rehearse: artifacts path '$ingest_dir' not found" >&2 @@ -191,11 +191,11 @@ if ! "$heart" "${ingest_args[@]}"; then exit 1 fi -# Consult the sibling Health Agent (read-only) for the verdict. --refresh runs a +# Consult the sibling vitals faculty (read-only) for the verdict. --refresh runs a # fresh Heart tick so state.json re-aggregates the just-written # validation_report.json before readiness recomputes the gate. -[[ "$json_only" -eq 1 ]] || echo "== release agent: consulting Health Agent for the release-validation verdict ==" -verdict="$(consult_health_agent_verdict --refresh)" +[[ "$json_only" -eq 1 ]] || echo "== release agent: consulting vitals faculty for the release-validation verdict ==" +verdict="$(consult_vitals_verdict --refresh)" eff="$verdict"; [[ "$eff" == "unknown" ]] && eff="yellow" decision=""; decision_code=0; blockers=(); warnings=(); next=() @@ -212,7 +212,7 @@ case "$eff" in warnings+=("Readiness YELLOW; proceeding under --force.") else decision="hold"; decision_code=2 - blockers+=("Readiness is YELLOW — likely no fresh release-fidelity run yet, stale rehearsal, or source moved. See 'pyauto-brain health'. Re-run with --force to accept the caution.") + blockers+=("Readiness is YELLOW — likely no fresh release-fidelity run yet, stale rehearsal, or source moved. See 'pyauto-brain vitals'. Re-run with --force to accept the caution.") fi ;; red) diff --git a/agents/release/release.sh b/agents/conductors/release/release.sh similarity index 96% rename from agents/release/release.sh rename to agents/conductors/release/release.sh index ef4f1e6..44cfbd2 100755 --- a/agents/release/release.sh +++ b/agents/conductors/release/release.sh @@ -23,11 +23,11 @@ set -uo pipefail HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" -source "$HERE/../_common.sh" +source "$HERE/../../_common.sh" # `release rehearse ...` drives the M2 release-VALIDATION rehearsal (Stage 2 # alone: dispatch the TestPyPI rehearsal, ingest the report into Heart, consult -# the Health Agent) — distinct from the real-release delegation below. +# the vitals faculty) — distinct from the real-release delegation below. if [[ "${1:-}" == "rehearse" ]]; then shift exec bash "$HERE/rehearse.sh" "$@" diff --git a/agents/release/validate.sh b/agents/conductors/release/validate.sh similarity index 98% rename from agents/release/validate.sh rename to agents/conductors/release/validate.sh index 17b5706..484c306 100755 --- a/agents/release/validate.sh +++ b/agents/conductors/release/validate.sh @@ -24,10 +24,10 @@ # final ingest+verdict hand Stage 2's rehearsal.json/commit_shas.json AND # Stage 3's stage_report.json together to # `pyauto-heart validate --ingest`, then consult the -# Health Agent — reused AS-IS from rehearse.sh's phase 2. +# vitals faculty — reused AS-IS from rehearse.sh's phase 2. # # BOUNDARY (unchanged from M2, non-negotiable). Heart never dispatches, never -# talks to GitHub, never mutates a repo — ingest-and-judge only. The Health Agent +# talks to GitHub, never mutates a repo — ingest-and-judge only. The vitals faculty # is strict read-and-reason. ALL dispatch/poll/download across all four stages is # the Release Agent's job, done via Brain's MCP GitHub tools (cloud/mobile has no # gh; bash cannot call MCP). So — exactly as rehearse.sh already does for Stage 2 — @@ -51,7 +51,7 @@ # # Phase C — once Stage 3 artifacts exist, ingest everything + get the verdict: # validate.sh --ingest [--commit-shas FILE] [--profile P] [--force] [--json] # delegates to rehearse.sh --ingest (reused verbatim) so the ingest + -# Health-Agent consult + decision + exit codes are IDENTICAL to Stage 2's. +# vitals-faculty consult + decision + exit codes are IDENTICAL to Stage 2's. # # Exit codes: preflight RED -> 3; a phase that cannot proceed (missing artifacts) # -> 1; phase-C ingest -> 0 green · 2 yellow (use --force) · 3 red · 4 unknown · @@ -74,7 +74,7 @@ set -uo pipefail HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" -source "$HERE/../_common.sh" +source "$HERE/../../_common.sh" # Stage 3 target: Heart's workspace-validation.yml (the M3 mode=release path). # Dispatched on Heart's own main (where the merged workflow lives) — the LIBRARY @@ -120,7 +120,7 @@ done # --------------------------------------------------------------------------- # Phase C: final ingest + verdict (Stage 2 + Stage 3 artifacts together). -# Reuse rehearse.sh --ingest VERBATIM so the ingest + Health-Agent consult + +# Reuse rehearse.sh --ingest VERBATIM so the ingest + vitals-faculty consult + # decision + exit codes are identical to the Stage-2-only path — the "mode" in # the emitted verdict JSON is stamped "validate" to attribute it to this flow. # --------------------------------------------------------------------------- diff --git a/agents/health/AGENTS.md b/agents/faculties/vitals/AGENTS.md similarity index 82% rename from agents/health/AGENTS.md rename to agents/faculties/vitals/AGENTS.md index afde68c..205771f 100644 --- a/agents/health/AGENTS.md +++ b/agents/faculties/vitals/AGENTS.md @@ -1,6 +1,13 @@ -# Health agent +# Vitals faculty -A PyAutoBrain specialist reasoning agent. It decides whether the PyAuto organism +> **Tier: faculty** — a read-only reasoning capability the conductors *consult*, +> not a front door you drive to get work done. It *reads the Heart's pulse*: it +> only *opines* — adopts PyAutoHeart's verdict and explains it, and never +> dispatches or mutates anything. It is the single component that talks to Heart; +> everything else asks it. (Runnable directly as a quick "what's my status?" +> read — e.g. the **health conductor** consults it every loop.) + +A PyAutoBrain read-only reasoning faculty. It judges whether the PyAuto organism is healthy enough to proceed with work, by **reasoning over PyAutoHeart's outputs** — never by performing health checks itself. @@ -10,10 +17,10 @@ Mind (intent) -> Brain (reasoning) -> Heart (gate) -> Hands/Build (execute) - **PyAutoHeart measures health.** It owns every check and the authoritative green/yellow/red verdict. -- **The Health Agent reasons about health.** It invokes Heart, interprets the +- **The vitals faculty reasons about health.** It invokes Heart, interprets the results, and produces a clear GREEN / YELLOW / RED decision with an explanation and recommendations. -- The agent **must not** implement testing, validation, or gating logic. That +- The faculty **must not** implement testing, validation, or gating logic. That remains owned entirely by PyAutoHeart. ## Treat PyAutoHeart as an abstract health provider @@ -23,7 +30,7 @@ PyAutoHeart's capability manifest — `health_agent/capabilities.yaml` in the PyAutoHeart checkout (Heart self-describing its surface; it is **never vendored or copied into Brain**). The manifest lists the provider, the primary query, the gate semantics, and every continuous/deep check, workflow, and operation. When -Heart gains or renames a check, the manifest changes *there* and this agent +Heart gains or renames a check, the manifest changes *there* and this faculty adapts with no edits. The local [`HEART_CAPABILITIES.md`](./HEART_CAPABILITIES.md) is a human-readable cross-reference to that same surface. @@ -38,20 +45,22 @@ via the manifest — reason about *categories of signal*, not fixed names. ## Run ```bash -bin/pyauto-brain health # one tick + the unified dashboard card -bin/pyauto-brain health dashboard --json # forward: the board as one machine card -bin/pyauto-brain health readiness --json # forward: pyauto-heart readiness --json (no tick) -bin/pyauto-brain health status # forward to: pyauto-heart status -bin/pyauto-brain health watch 300 # forward to: pyauto-heart watch 300 +bin/pyauto-brain vitals # one tick + the unified dashboard card +bin/pyauto-brain vitals dashboard --json # forward: the board as one machine card +bin/pyauto-brain vitals readiness --json # forward: pyauto-heart readiness --json (no tick) +bin/pyauto-brain vitals status # forward to: pyauto-heart status +bin/pyauto-brain vitals watch 300 # forward to: pyauto-heart watch 300 ``` -The entrypoint (`health.sh`) refreshes Heart's state and renders the **unified +The entrypoint (`vitals.sh`) refreshes Heart's state and renders the **unified dashboard card** (`pyauto-heart dashboard` — verdict, score, every check, and the release-validation state, from the one renderer in `heart/dashboard.py`); any -explicit subcommand is forwarded verbatim to `pyauto-heart`, so this agent is a +explicit subcommand is forwarded verbatim to `pyauto-heart`, so this faculty is a thin, named driver of Heart rather than a second implementation of any check. The board is the same one the GitHub Pages page and the venv one-liner show — the -surfaces cannot disagree. +surfaces cannot disagree. (For the *actioning* loop that drives these signals to +green, use the **health conductor** — `pyauto-brain health` — which consults this +faculty every cycle.) ## Procedure @@ -125,9 +134,10 @@ Status: (score <0-100>, snapshot ) ## Day-to-day defaults (operating agreement) -On a routine run, how `pyauto-brain health` should render and reason. These are -presentation/triage conventions layered *on top of* the procedure above — they -never change the verdict, which is always adopted from Heart verbatim. +On a routine run, how the vitals faculty (and the **health conductor** that +consults it) should render and reason. These are presentation/triage conventions +layered *on top of* the procedure above — they never change the verdict, which is +always adopted from Heart verbatim. - **Default surface.** Lead with the `pyauto-heart dashboard --md` mobile card (verdict · score · warnings · tiles), then the structured report beneath it. @@ -169,13 +179,13 @@ never change the verdict, which is always adopted from Heart verbatim. - **RED** — blocked. The caller must not proceed with release work until the blocking issues are resolved. -The agent only ever returns the decision and its reasoning. Execution belongs to +The faculty only ever returns the decision and its reasoning. Execution belongs to Hands/PyAutoBuild, which acts **only after** receiving this GREEN/YELLOW/RED decision — it never re-runs the checks or re-derives the gate. ## Hard boundaries -- Never write into any repo, run a build, or trigger a release. The agent is a +- Never write into any repo, run a build, or trigger a release. The faculty is a read-and-reason role. - Never implement or duplicate a health check. If a needed signal is missing, recommend that PyAutoHeart add the check — do not compute it here. diff --git a/agents/health/HEART_CAPABILITIES.md b/agents/faculties/vitals/HEART_CAPABILITIES.md similarity index 89% rename from agents/health/HEART_CAPABILITIES.md rename to agents/faculties/vitals/HEART_CAPABILITIES.md index 5901cfd..c740b9b 100644 --- a/agents/health/HEART_CAPABILITIES.md +++ b/agents/faculties/vitals/HEART_CAPABILITIES.md @@ -1,6 +1,6 @@ -# PyAutoHeart capabilities known to the Health Agent +# PyAutoHeart capabilities known to the vitals faculty -This audit records the health surface the PyAutoBrain Health Agent reasons over. +This audit records the health surface the PyAutoBrain vitals faculty reasons over. The agent must treat every item here as a PyAutoHeart capability, not as logic to reimplement inside Brain. @@ -12,7 +12,7 @@ reimplement inside Brain. - `pyauto-heart readiness --json` — machine-readable gate for agents/scripts. - `pyauto-heart dashboard [--oneline|--md|--html|--json|--badge]` — the ONE unified health board (verdict + every check + release-validation state); reads - cache only, never ticks. The Health Agent's mobile card is the `--json`/`--md` + cache only, never ticks. The vitals faculty's mobile card is the `--json`/`--md` view of this board. - `pyauto-heart watch [seconds]` / `live` — continuous monitoring daemon. - `pyauto-heart stop` / `stop --all` — daemon lifecycle control. @@ -53,7 +53,7 @@ reimplement inside Brain. - **Heart is ingest-and-judge only** — it never dispatches `release.yml` or `workspace-validation.yml`. Dispatching/polling/downloading the artifacts is the **Release Agent's** job (`pyauto-brain release rehearse`), via MCP GitHub tools. - The **Health Agent stays read-only**: it reports the resulting verdict, it does + The **vitals faculty stays read-only**: it reports the resulting verdict, it does not dispatch. ## Unified health dashboard (M5) @@ -66,14 +66,14 @@ reimplement inside Brain. - **Three surfaces:** GitHub Pages (`https://pyautolabs.github.io/PyAutoHeart/`) + `$GITHUB_STEP_SUMMARY` + a README badge/block (all published by `pulse-health.yml`); the `pyauto-heart dashboard` CLI + a sourceable venv hook - (`heart/shell/heart_prompt.sh`); and this Health Agent's mobile card. -- **The Health Agent renders the card from `pyauto-heart dashboard --json`/`--md`** + (`heart/shell/heart_prompt.sh`); and this vitals faculty's mobile card. +- **The vitals faculty renders the card from `pyauto-heart dashboard --json`/`--md`** — the same board, not raw verdict JSON. It is exposed as the `dashboard` capability + `published_board` URL in Heart's `health_agent/capabilities.yaml`. - **Observer-only.** The dashboard SHOWS health; the `readiness` verdict stays the gate. Everything the dashboard writes stays within PyAutoHeart's own repo (gh-pages / README / `[heart-health]` issue), the job step summary, or - `~/.pyauto-heart/`. The Health Agent stays read-and-reason. + `~/.pyauto-heart/`. The vitals faculty stays read-and-reason. ## Heart implementation assets @@ -100,7 +100,7 @@ Heart/Brain and the shims are confirmed to delegate only. Do not duplicate those checks in Brain. If any shim contains non-trivial readiness logic, migrate that logic to PyAutoHeart and leave only delegation in PyAutoBuild. -## Health Agent decision policy +## vitals faculty decision policy - GREEN: Heart reports no blocking or cautionary issues. Build may proceed automatically if the calling agent requested execution. @@ -108,6 +108,6 @@ logic to PyAutoHeart and leave only delegation in PyAutoBuild. is recommended before release/deployment. - RED: Heart reports blocking issues. Build must not proceed automatically. -The Health Agent may explain, rank, and recommend actions from Heart output, but +The vitals faculty may explain, rank, and recommend actions from Heart output, but it must never independently measure repo health, run tests directly, classify files, or re-derive release readiness. diff --git a/agents/health/health.sh b/agents/faculties/vitals/vitals.sh similarity index 52% rename from agents/health/health.sh rename to agents/faculties/vitals/vitals.sh index 9708693..9aaa1cc 100755 --- a/agents/health/health.sh +++ b/agents/faculties/vitals/vitals.sh @@ -1,38 +1,41 @@ #!/usr/bin/env bash -# agents/health/health.sh — the health agent (a PyAutoBrain reasoning agent). +# agents/faculties/vitals/vitals.sh — the vitals faculty (a PyAutoBrain +# read-only reasoning capability). It reads the Heart's pulse. # # Reasons over the PyAutoHeart monitoring surface. By default it runs one # refresh cycle and renders the unified dashboard card (the same board every # other surface shows — the authoritative readiness verdict at its head, plus # every check and the release-validation state). Any subcommand -# is forwarded straight to `pyauto-heart`, so this agent is a thin, named driver -# of Heart rather than a second implementation of any check. The Brain reasons -# about health; PyAutoHeart measures it. +# is forwarded straight to `pyauto-heart`, so this faculty is a thin, named +# driver of Heart rather than a second implementation of any check. The Brain +# reasons about health; PyAutoHeart measures it. This faculty only *opines* — +# it never dispatches or mutates; it is the single component that talks to Heart, +# and the conductors (build, release, feature, health) consult it. # # Usage: -# health.sh # one tick, then render the unified dashboard card -# health.sh status # forward: pyauto-heart status -# health.sh watch [secs] # forward: pyauto-heart watch (continuous) -# health.sh ... # forward verbatim to pyauto-heart +# vitals.sh # one tick, then render the unified dashboard card +# vitals.sh status # forward: pyauto-heart status +# vitals.sh watch [secs] # forward: pyauto-heart watch (continuous) +# vitals.sh ... # forward verbatim to pyauto-heart # # The no-arg card is the SAME unified board every other surface shows (one # renderer in heart/dashboard.py) — verdict, score, top blockers, and the # release-validation state — not raw verdict JSON. On a phone the reasoning # agent pulls `pyauto-heart dashboard --json` / `--md` for the same card. # -# Future: several health agents may each reason over a different slice of Heart -# (CI, worktree drift, timing, ...). For now this single agent covers the whole +# Future: several vitals faculties may each read a different slice of Heart +# (CI, worktree drift, timing, ...). For now this single faculty covers the whole # surface via pyauto-heart. set -uo pipefail HERE="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" -source "$HERE/../_common.sh" +source "$HERE/../../_common.sh" heart="$(resolve_heart)" || exit $? if [[ $# -eq 0 ]]; then - echo "== health agent: refreshing PyAutoHeart state ==" + echo "== vitals faculty: refreshing PyAutoHeart state ==" "$heart" tick echo # Render the ONE unified board (readiness verdict + every check + the diff --git a/bin/pyauto-brain b/bin/pyauto-brain index 6a83f81..c74f379 100755 --- a/bin/pyauto-brain +++ b/bin/pyauto-brain @@ -4,15 +4,22 @@ # PyAutoBrain is the reasoning layer of the PyAuto organism: it figures out HOW # work should be done and coordinates the organs that do it. The subcommand # pattern mirrors PyAutoBuild/bin/autobuild and PyAutoHeart/bin/pyauto-heart so -# the CLIs feel the same. Each subcommand is a specialist reasoning agent under -# agents//. +# the CLIs feel the same. Agents live in two tiers under agents/: # -# pyauto-brain feature [args] reason over PyAutoMind feature tasks, plan growth -# pyauto-brain build [args] coordinate execution: consult health, run Build -# pyauto-brain release [args] reason about readiness, then release on green +# agents/conductors// — front-door agents a human DRIVES (they decide +# AND act, delegating execution to the organs). +# agents/faculties// — read-only reasoning capabilities the conductors +# CONSULT (they only opine; never dispatch or +# mutate). Runnable directly for a quick read. +# +# 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 # (release rehearse: Stage-2 TestPyPI rehearsal; # release validate: full Stages 0-3 orchestrator) -# pyauto-brain health [args] reason over the PyAutoHeart health surface +# pyauto-brain health [args] (conductor) the organism's clinician: run the health +# loop with a human, dispatch by dispatch, toward green +# pyauto-brain vitals [args] (faculty) read-only: read the Heart's pulse (the verdict) # pyauto-brain help [name] list agents or show one agent's docs # # Back-compat: the former name `pyauto-agent` is kept as a thin shim that execs @@ -24,25 +31,36 @@ _self="$(readlink -f "${BASH_SOURCE[0]}")" BRAIN_HOME="$(cd "$(dirname "$_self")/.." && pwd)" AGENTS_DIR="$BRAIN_HOME/agents" +CONDUCTORS_DIR="$AGENTS_DIR/conductors" +FACULTIES_DIR="$AGENTS_DIR/faculties" + declare -A AGENT_SCRIPT=( - [feature]="$AGENTS_DIR/feature/feature.sh" - [build]="$AGENTS_DIR/build/build.sh" - [release]="$AGENTS_DIR/release/release.sh" - [health]="$AGENTS_DIR/health/health.sh" + [feature]="$CONDUCTORS_DIR/feature/feature.sh" + [build]="$CONDUCTORS_DIR/build/build.sh" + [release]="$CONDUCTORS_DIR/release/release.sh" + [health]="$CONDUCTORS_DIR/health/health.sh" + [vitals]="$FACULTIES_DIR/vitals/vitals.sh" ) declare -A AGENT_DESC=( [feature]="Reason over PyAutoMind feature tasks: select, size, phase, plan for start_dev" - [build]="Coordinate execution: consult the Health Agent, then delegate to PyAutoBuild" + [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" - [health]="Reason over the PyAutoHeart monitoring / readiness surface" + [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)" ) -AGENT_ORDER=(feature build release health) +# Conductors are the front doors a human drives; faculties are consulted (and +# runnable read-only). Both are dispatchable, but the menu groups them by tier. +CONDUCTOR_ORDER=(feature build release health) +FACULTY_ORDER=(vitals) +AGENT_ORDER=("${CONDUCTOR_ORDER[@]}" "${FACULTY_ORDER[@]}") cmd_help() { if [[ $# -gt 0 ]]; then local name="$1" - local doc="$AGENTS_DIR/$name/AGENTS.md" - if [[ -f "$doc" ]]; then + # The doc lives beside the agent's script, wherever its tier put it. + local script="${AGENT_SCRIPT[$name]:-}" + local doc="${script:+$(dirname "$script")/AGENTS.md}" + if [[ -n "$doc" && -f "$doc" ]]; then cat "$doc" return 0 fi @@ -60,10 +78,15 @@ Call chain: Brain -> Heart (gate) -> Build (execute) Usage: pyauto-brain [args...] pyauto-brain help [agent] -Specialist reasoning agents: +Conductors (front doors you drive — decide AND act): EOF local name - for name in "${AGENT_ORDER[@]}"; do + for name in "${CONDUCTOR_ORDER[@]}"; do + printf ' %-10s %s\n' "$name" "${AGENT_DESC[$name]}" + done + echo + echo "Faculties (read-only; the conductors consult these — also runnable directly):" + for name in "${FACULTY_ORDER[@]}"; do printf ' %-10s %s\n' "$name" "${AGENT_DESC[$name]}" done echo diff --git a/skills/WORKFLOW.md b/skills/WORKFLOW.md index 03899e4..adf0a99 100644 --- a/skills/WORKFLOW.md +++ b/skills/WORKFLOW.md @@ -27,9 +27,9 @@ skill never re-implements another organ's job. ``` start_dev → Brain Feature Agent → Mind task + Memory context → plan → start_library/start_workspace -ship_library → Brain dev-workflow → Brain Health Agent → Heart (GREEN/YELLOW/RED) → commit / push / feature-PR -ship_workspace → Brain dev-workflow → Brain Health Agent → Heart → commit / push / feature-PR -release (later)→ Brain Build/Release Agent → Brain Health Agent → Heart → PyAutoBuild (tag / notebooks / PyPI) +ship_library → Brain dev-workflow → Brain vitals faculty → Heart (GREEN/YELLOW/RED) → commit / push / feature-PR +ship_workspace → Brain dev-workflow → Brain vitals faculty → Heart → commit / push / feature-PR +release (later)→ Brain Build/Release Agent → Brain vitals faculty → Heart → PyAutoBuild (tag / notebooks / PyPI) ``` `ship_*` is **feature-development** work: the commit/push/feature-PR is the dev @@ -38,8 +38,8 @@ release/packaging only; `ship_*` reaches Build solely to trigger the release ste once changes are ready to publish. Brain agents consult one another — e.g. the Build Agent never queries Heart -directly; it asks the Health Agent, and only the Health Agent talks to the Heart -organ. The same applies when the dev workflow consults the Health Agent for its +directly; it asks the vitals faculty, and only the vitals faculty talks to the Heart +organ. The same applies when the dev workflow consults the vitals faculty for its ship gate. ## Brain agent entry points @@ -48,9 +48,9 @@ Reasoning is delegated to PyAutoBrain agents (`PyAutoBrain/AGENTS.md` is authori ```bash bin/pyauto-brain feature [//.md] # classify + plan a task (Feature/Bug/Refactor/… routing) -bin/pyauto-brain build [--dry-run] # consult Health, then delegate execution to Build +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 health # one health tick + the unified dashboard card +bin/pyauto-brain vitals # one health tick + the unified dashboard card ``` If a dedicated agent for a work type does not exist yet (e.g. Bug/Refactor/Docs), @@ -82,7 +82,7 @@ pyauto-heart readiness --json # authoritative GREEN / YELLOW / RED verdict - **RED** → stop; report what failed. Do not ship. Tests/smoke runs that feed the verdict are Heart's domain — invoke them through -the Health Agent rather than re-deriving pass/fail criteria in the skill. +the vitals faculty rather than re-deriving pass/fail criteria in the skill. ## Execution environments diff --git a/skills/ship_library/SKILL.md b/skills/ship_library/SKILL.md index 23d029e..368dada 100644 --- a/skills/ship_library/SKILL.md +++ b/skills/ship_library/SKILL.md @@ -6,7 +6,7 @@ description: Ship PyAutoLabs source-library changes. Use when Codex needs to ins # Ship Library A PyAutoBrain development-workflow entry point. Shipping a library feature is -**feature-dev** work: dev-workflow → Health Agent → Heart readiness gate → +**feature-dev** work: dev-workflow → vitals faculty → Heart readiness gate → commit/push/feature-PR, with PyAutoMind holding task state. It is **not** a Build task — Build is release/packaging only (PyPI/tags/notebooks) and `ship_*` reaches it solely for the release step. Shared organ boundary, the readiness gate and the diff --git a/skills/ship_library/reference.md b/skills/ship_library/reference.md index 2e18aee..1f96a9d 100644 --- a/skills/ship_library/reference.md +++ b/skills/ship_library/reference.md @@ -55,7 +55,7 @@ See full details below. ## Execution contract (feature-dev — the mechanical ship step) This is the dev workflow's own git execution (commit/push/feature-PR), not a -Build/release step. Per repo, after the Health Agent / Heart verdict is GREEN: +Build/release step. Per repo, after the vitals faculty / Heart verdict is GREEN: 1. `source "$WT_ROOT/activate.sh"`; run `python -m pytest / -x` from inside `"$WT_ROOT/"` (skip only if the repo has no test dir). These diff --git a/skills/ship_library/ship_library.md b/skills/ship_library/ship_library.md index 517b209..e030026 100644 --- a/skills/ship_library/ship_library.md +++ b/skills/ship_library/ship_library.md @@ -7,7 +7,7 @@ own execution, gated by Heart. It is **not** a Build task (Build is release/packaging only; `ship_*` reaches it solely for the release step): ``` -ship_library → Brain dev-workflow → Brain Health Agent → Heart (GREEN/YELLOW/RED) → commit / push / feature-PR +ship_library → Brain dev-workflow → Brain vitals faculty → Heart (GREEN/YELLOW/RED) → commit / push / feature-PR ``` Workflow entry point — not an agent. Read [`../WORKFLOW.md`](../WORKFLOW.md) for @@ -39,14 +39,14 @@ and the full PR body. Writing the `## API Changes` section is judgement-heavy an stays in the reasoning model — follow [`reference.md`](reference.md) → "Writing the `## API Changes` section" and "Full PR format". -### 3. Gate readiness through the Health Agent → Heart +### 3. Gate readiness through the vitals faculty → Heart -Consult the Brain Health Agent, which is the only one that talks to the Heart +Consult the Brain vitals faculty, which is the only one that talks to the Heart organ (do **not** route this through the Build Agent — shipping a feature is not a release): ```bash -bin/pyauto-brain health # reason over the readiness surface (Health Agent → Heart) +bin/pyauto-brain vitals # reason over the readiness surface (vitals faculty → Heart) pyauto-heart readiness --json # authoritative GREEN / YELLOW / RED ``` diff --git a/skills/ship_workspace/SKILL.md b/skills/ship_workspace/SKILL.md index 526b0ff..6fbf4ab 100644 --- a/skills/ship_workspace/SKILL.md +++ b/skills/ship_workspace/SKILL.md @@ -6,7 +6,7 @@ description: Ship PyAutoLabs workspace and tutorial repository changes. Use when # Ship Workspace A PyAutoBrain development-workflow entry point. Shipping a workspace feature is -**feature-dev** work: dev-workflow → Health Agent → Heart readiness gate → +**feature-dev** work: dev-workflow → vitals faculty → Heart readiness gate → commit/push/feature-PR/merge, with PyAutoMind holding task state. It is **not** a Build task — Build is release/packaging only. Shared organ boundary, the readiness gate and the execution-environment model are in diff --git a/skills/ship_workspace/ship_workspace.md b/skills/ship_workspace/ship_workspace.md index 350aa16..25d8bf4 100644 --- a/skills/ship_workspace/ship_workspace.md +++ b/skills/ship_workspace/ship_workspace.md @@ -7,7 +7,7 @@ HowToLens) for every workspace repo touched by the task. This is release/packaging only). Same flow as `/ship_library`: ``` -ship_workspace → Brain dev-workflow → Brain Health Agent → Heart (GREEN/YELLOW/RED) → smoke / commit / push / feature-PR / merge +ship_workspace → Brain dev-workflow → Brain vitals faculty → Heart (GREEN/YELLOW/RED) → smoke / commit / push / feature-PR / merge ``` Ships **scripts, notebooks and configs only** — never library source. Workflow @@ -39,13 +39,13 @@ body — which **must** include `## Scripts Changed`. If a "Library PR Created" comment exists on the issue, capture the library PR URL for `## Upstream PR`. Format in [`reference.md`](reference.md) → "PR body format". -### 3. Gate readiness through the Health Agent → Heart +### 3. Gate readiness through the vitals faculty → Heart -Consult the Brain Health Agent (not the Build Agent — shipping a feature is not a +Consult the Brain vitals faculty (not the Build Agent — shipping a feature is not a release): ```bash -bin/pyauto-brain health # reason over the readiness surface (Health Agent → Heart) +bin/pyauto-brain vitals # reason over the readiness surface (vitals faculty → Heart) pyauto-heart readiness --json # GREEN / YELLOW / RED ```