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
21 changes: 11 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,12 @@ humans invoke identically, so behaviour isn't re-derived from prose each time.
leg → re-judge — until Heart goes GREEN. Delegates all dispatch to the
release conductor. Current scope is *validate + recommend*, checkpointing
every dispatch; edit-in fixes are an explicit follow-up. (Skeleton.)
- **`agents/conductors/clone/`** — the *Mitosis Agent* (**design only** — see
its `DESIGN.md`; no CLI yet): will reproduce a mature domain assistant
- **`agents/conductors/clone/`** — the *Mitosis Agent* (**analysis-only v0** —
see its `DESIGN.md`): analyzes how to reproduce a mature domain assistant
(reference: `autolens_assistant`) into a new specialised assistant cell —
domain analysis, template-boundary partition, a `CloneDecision` with an
exact-clone/sibling/seed question, generation delegated to Build, newborn
validation by Heart.
validation by Heart. Its current CLI emits the decision and writes nothing.

### Faculties

Expand Down Expand Up @@ -203,9 +203,9 @@ it resolves the sibling `pyauto-heart` and `autobuild` binaries from PATH or the
## The command surface (Brain implicit)

The `bin/pyauto-brain <agent>` CLI above is the machinery; humans drive it through
short verb commands installed into `~/.claude/commands/`. The Brain stays
**implicit** — you type a verb (or plain natural language) and the Brain routes it
to the right agent; normal usage never says "PyAutoBrain".
short verb commands in Claude Code or discoverable skills in Claude and Codex.
The Brain stays **implicit** — you type a verb (or plain natural language) and
the Brain routes it to the right agent; normal usage never says "PyAutoBrain".

> **Users speak in short commands; PyAutoBrain performs the routing.**

Expand All @@ -228,10 +228,11 @@ never for symmetry — the Refactor Agent earned its promotion via the `ideas.md
backlog bullet, the skill's own recorded follow-up, and the autonomy series.
Every command routes **through** the Brain; none replaces it.

The command bodies live in `skills/<verb>/<verb>.md` (thin; installed as flat
commands by `bin/install.sh`); the shared architecture prose is in
[`skills/COMMANDS.md`](skills/COMMANDS.md). The work-type taxonomy the router and
work-type entries use is `PyAutoMind/ROUTING.md`.
The command bodies live in `skills/<verb>/<verb>.md`; thin `SKILL.md` wrappers
make the same canonical workflows discoverable to skill-aware harnesses.
`bin/install.sh` installs both surfaces without duplicating their bodies. Shared
architecture prose is in [`skills/COMMANDS.md`](skills/COMMANDS.md). The
work-type taxonomy the router and work-type entries use is `PyAutoMind/ROUTING.md`.

## Never rewrite history

Expand Down
17 changes: 10 additions & 7 deletions bin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Executable tooling for the PyAuto organism.

- **`pyauto-brain`** — the PyAutoBrain CLI (reasoning-layer entry point).
- **`install.sh`** — the cross-organ Claude skill/command **installer**.
- **`install.sh`** — the cross-organ Claude/Codex skill and command installer.
- **`check_skill_line_counts.sh`** — the skill line-count **guard** (primary
skill `.md` files must stay < 200 lines).

Expand All @@ -14,7 +14,8 @@ admin_jammy hosts no skills and is slated to leave `PyAutoLabs/`.
## install.sh

Auto-discovers (no hardcoded skill list) by scanning each organ repo's
`skills/` dir for `*/` subdirs, then symlinks each into `~/.claude/`:
`skills/` dir for `*/` subdirs, then symlinks each supported surface into its
harness home:

- **`PyAutoMind/skills/`** — registry-coupled skills (`create_issue`).
- **`PyAutoBrain/skills/`** — development-workflow skills (`start_dev`,
Expand All @@ -32,15 +33,17 @@ Auto-discovers (no hardcoded skill list) by scanning each organ repo's
- **`admin_jammy/skills/`** — vestigial: hosts no skills; scanned only so an old
checkout still resolves, auto-skipped once admin_jammy leaves.

Discovery rule per root:
Discovery rules per root are independent, so a directory may expose both:

- A directory with `SKILL.md` → **skill**, symlinked to `~/.claude/skills/<name>/`.
- A directory with `<dirname>.md` (and no `SKILL.md`) → **command**, symlinked to
`~/.claude/commands/<name>.md`.
- `SKILL.md` → skill directory symlinked to Claude under its source-directory
name and to Codex under the hyphenated frontmatter `name`.
- `<dirname>.md` → command symlinked to `~/.claude/commands/<name>.md`.

Roots that aren't checked out are skipped. It is idempotent — existing symlinks
are replaced, non-symlink files are left alone, and broken symlinks pointing into
a PyAuto root are pruned. Re-run it after pulling updates.
a PyAuto root are pruned. `CLAUDE_HOME` and `CODEX_HOME` may override the
destinations for isolated tests or non-default installations. Re-run it after
pulling updates.

## Bootstrap on a new machine

Expand Down
2 changes: 1 addition & 1 deletion bin/check_skill_line_counts.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Report any *primary* skill .md file over the line limit (default 200).
#
# Claude skill guidance keeps primary skill files short; long background,
# Agent skill guidance keeps primary skill files short; long background,
# templates and examples belong in supporting docs (`reference.md`, shared
# `WORKFLOW.md`), which are exempt here. A "primary" file is a skill's `SKILL.md`
# or its command body `<dirname>.md`.
Expand Down
57 changes: 36 additions & 21 deletions bin/install.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#!/usr/bin/env bash
# Bootstrap Claude Code skills/commands into ~/.claude/ from every PyAuto
# organism repo that hosts skills.
# Bootstrap Claude Code commands and Claude/Codex skills from every PyAuto
# organism repo that hosts them.
#
# This installer lives in PyAutoBrain (the reasoning/orchestration organ). It
# scans every organ repo's skills/ dir and symlinks their skills+commands into
# ~/.claude/. Roots that aren't checked out are simply skipped.
# scans every organ repo's skills/ dir and symlinks skills into both harnesses;
# Claude-only command files remain available as slash commands. Roots that
# aren't checked out are simply skipped.
#
# Discovery roots (scanned in order):
# - admin_jammy/skills/ — vestigial: admin_jammy hosts no skills and is
Expand All @@ -19,10 +20,10 @@
# (PyAutoBuild's root is for its own release/packaging-execution skills only — it
# owns NO dev-workflow skills; the ship_* skills merely call its release step.)
#
# Auto-discovers skills in each root:
# - A directory with SKILL.md → installed as ~/.claude/skills/<name>/
# - A directory with <name>.md (and no SKILL.md) → installed as a flat
# command at ~/.claude/commands/<name>.md
# Auto-discovers surfaces in each root independently:
# - SKILL.md → installed in both the Claude and Codex skill roots
# - <name>.md → installed as a flat Claude command
# A directory may contain both; neither surface suppresses the other.
#
# Safe to re-run — existing symlinks are replaced, non-symlink files are skipped.
#
Expand All @@ -32,13 +33,16 @@
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PYAUTO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DEFAULT_PYAUTO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
PYAUTO_ROOT="${PYAUTO_ROOT:-$DEFAULT_PYAUTO_ROOT}"
ADMIN_SKILLS_DIR="$PYAUTO_ROOT/admin_jammy/skills"
MIND_SKILLS_DIR="$PYAUTO_ROOT/PyAutoMind/skills"
BRAIN_SKILLS_DIR="$PYAUTO_ROOT/PyAutoBrain/skills"
HEART_SKILLS_DIR="$PYAUTO_ROOT/PyAutoHeart/skills"
BUILD_SKILLS_DIR="$PYAUTO_ROOT/PyAutoBuild/skills"
PROFILING_SKILLS_DIR="$PYAUTO_ROOT/autolens_profiling/skills"
CLAUDE_HOME="${CLAUDE_HOME:-$HOME/.claude}"
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"

# ---------- Execution-environment note ----------
#
Expand All @@ -53,7 +57,7 @@ else
fi
echo ""

mkdir -p "$HOME/.claude/skills" "$HOME/.claude/commands"
mkdir -p "$CLAUDE_HOME/skills" "$CLAUDE_HOME/commands" "$CODEX_HOME/skills"

# ---------- Prune stale symlinks ----------
#
Expand All @@ -76,8 +80,9 @@ prune_stale_symlinks() {
done
}

prune_stale_symlinks "$HOME/.claude/skills"
prune_stale_symlinks "$HOME/.claude/commands"
prune_stale_symlinks "$CLAUDE_HOME/skills"
prune_stale_symlinks "$CLAUDE_HOME/commands"
prune_stale_symlinks "$CODEX_HOME/skills"

# ---------- Install one source dir's skills/commands ----------

Expand All @@ -101,17 +106,27 @@ install_from_dir() {
# Skip the install.sh dir itself, or any non-skill dirs
[ "$name" = "skills" ] && continue

local found=0
if [ -f "$entry/SKILL.md" ]; then
# Skill — symlink the directory
local dst="$HOME/.claude/skills/$name"
_link_symlink "$entry" "$dst" "skill"
_link_symlink "$entry" "$CLAUDE_HOME/skills/$name" "Claude skill"
installed_count=$((installed_count + 1))
elif [ -f "$entry/$name.md" ]; then
# Command — symlink the flat .md file
local dst="$HOME/.claude/commands/$name.md"
_link_symlink "$entry/$name.md" "$dst" "command"
found=1

local skill_name
skill_name="$(sed -n 's/^name:[[:space:]]*//p' "$entry/SKILL.md" | head -1)"
if [ -z "$skill_name" ] || [[ "$skill_name" == *[!a-z0-9-]* ]]; then
echo " SKIP $name (Codex skill name invalid or missing: ${skill_name:-<empty>})"
else
_link_symlink "$entry" "$CODEX_HOME/skills/$skill_name" "Codex skill"
installed_count=$((installed_count + 1))
fi
fi
if [ -f "$entry/$name.md" ]; then
_link_symlink "$entry/$name.md" "$CLAUDE_HOME/commands/$name.md" "Claude command"
installed_count=$((installed_count + 1))
else
found=1
fi
if [ "$found" -eq 0 ]; then
echo " SKIP $name (no SKILL.md or $name.md found)"
fi
done
Expand Down Expand Up @@ -149,4 +164,4 @@ install_from_dir "$PROFILING_SKILLS_DIR" "autolens_profiling/skills/ — science

# ---------- Summary ----------

echo "Done. Restart Claude Code to pick up changes."
echo "Done. Restart Claude Code and Codex to pick up changes."
19 changes: 13 additions & 6 deletions skills/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,18 @@ symmetry. The taxonomy they tag is `PyAutoMind/ROUTING.md`.
- **`/brain <agent> [args]`** — explicit, un-veneered passthrough to
`bin/pyauto-brain` for debugging. Free-text `/brain` defers to `/route`.

Codex skills also expose the remaining public CLI agents directly: the
analysis-only `clone` conductor, the `release` conductor, and the read-only
`vitals`, `review`, `memory`, and `samplers` faculties. They do not gain new
slash commands; `brain` remains Claude's low-level passthrough.

## How these are installed

Each command is a directory `skills/<verb>/` containing only `<verb>.md` (no
`SKILL.md`). `bin/install.sh` turns that into a flat `~/.claude/commands/<verb>.md`
symlink — a typed slash command, not an auto-triggered skill. This file
(`COMMANDS.md`) sits at the `skills/` root, so the installer's directory scan
skips it: it is reference-only. Keep command bodies short and this file the single
place architecture prose lives (guarded by `bin/check_skill_line_counts.sh`).
Each command directory keeps `<verb>.md` as its canonical command body and may
add a thin `SKILL.md` discovery wrapper. `bin/install.sh` treats the two files
independently: it installs the command into `~/.claude/commands/` and the skill
into both `~/.claude/skills/` and `~/.codex/skills/` (using the skill's
hyphenated frontmatter name for Codex). This file (`COMMANDS.md`)
sits at the `skills/` root, so the directory scan skips it; it is reference-only.
Keep wrappers and command bodies short and keep shared architecture prose here
(guarded by `bin/check_skill_line_counts.sh`).
18 changes: 8 additions & 10 deletions skills/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,13 @@ file and `PyAutoBrain/AGENTS.md`, and note that the agent was emulated.

## Model delegation (judgment tier plans, execution tier ships)

The workflow skills split work across **model tiers**, not named models — the
doctrine survives model access changing:
The workflow skills split work across **capability tiers**, not named models or
harness-specific tool names, so the doctrine survives model access changing:

- **Judgment tier** — the strongest model available to the session (currently
**Fable 5**; previously, and as fallback, **Opus**). Planning, orchestration,
risk judgment, anything user-facing.
- **Execution tier** — a fast, cheap model (currently **Sonnet**) for
mechanical shell/git phases, delegated as subagents (`Agent` tool,
`model: "sonnet"`).
- **Judgment tier** — the strongest reasoning model available to the session.
Planning, orchestration, risk judgment, and anything user-facing.
- **Execution tier** — a fast, lower-cost model for mechanical shell/git phases,
delegated through the harness's subagent mechanism when available.

The main session stays on the judgment tier; bulk execution moves to the
execution tier — no manual model toggling.
Expand Down Expand Up @@ -170,8 +168,8 @@ the vitals faculty rather than re-deriving pass/fail criteria in the skill.
- If the user gives a development task with **no** PyAutoMind prompt path,
first write a concise prompt under the right `<work-type>/<target>/` folder
(original request verbatim), then continue with that path.
- Where a body delegates mechanical execution to an execution-tier subagent, a harness
without subagents performs the same steps directly, preserving the
- Where a body delegates mechanical execution to an execution-tier subagent, a
harness without subagents performs the same steps directly, preserving the
judgment/mechanical split above.

## Execution environments
Expand Down
10 changes: 10 additions & 0 deletions skills/brain/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: brain
description: Run a named PyAutoBrain conductor or faculty directly through bin/pyauto-brain. Use for low-level agent invocation, agent help, or debugging the Brain router.
---

# Brain

Follow [`brain.md`](brain.md) exactly. Use [`../COMMANDS.md`](../COMMANDS.md)
for the shared command-surface contract. Keep agent behavior in the deterministic
CLI and its adjacent `AGENTS.md`; do not reimplement it here.
6 changes: 3 additions & 3 deletions skills/brain/brain.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Shared routing context: `PyAutoBrain/skills/COMMANDS.md`.

## Do

- `/brain <agent> [args...]` where `agent ∈ {feature, build, release, health,
vitals}` → run `bin/pyauto-brain <agent> [args...]` and report the output
verbatim.
- `/brain <agent> [args...]` where `agent ∈ {intake, feature, bug, refactor,
profiling, clone, build, release, health, vitals, review, memory, samplers}` →
run `bin/pyauto-brain <agent> [args...]` and report the output verbatim.
- `/brain help [agent]` → run `bin/pyauto-brain help [agent]`.
- `/brain <free text>` with no known agent → defer to **`/route`**.
10 changes: 10 additions & 0 deletions skills/bug/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: bug
description: Classify and plan PyAutoLabs bugs, regressions, failing tests, incorrect output, or PyAutoHeart findings through the PyAutoBrain Bug Agent before starting development.
---

# Bug

Follow [`bug.md`](bug.md) exactly. Use [`../COMMANDS.md`](../COMMANDS.md) for
shared routing. Let `bin/pyauto-brain bug` produce the decision; do not bypass
the Brain or implement the repair inside this skill.
6 changes: 3 additions & 3 deletions skills/bug/bug.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ Shared routing context: `PyAutoBrain/skills/COMMANDS.md`.
carrying forward). Then tell the user it is **safe to `/clear` before the next
`/bug`**: the transcript now holds only disposable investigation scratch (file
reads, repro runs, tool output), so a fresh session loses nothing and context
stays lean across many bugs in one sitting. Claude cannot self-clear — this is a
deliberate one-keystroke user step, and the externalised state above is what makes
it lossless.
stays lean across many bugs in one sitting. An agent cannot clear its own host
transcript — this is a deliberate one-keystroke user step, and the externalised
state above is what makes it lossless.

The Bug Agent **reasons; it never edits source**, and its first question is always
*where the fix belongs*: prefer a general library-source fix, and **never degrade a
Expand Down
9 changes: 9 additions & 0 deletions skills/build/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: build
description: Coordinate PyAuto build, deploy, or release execution through the PyAutoBrain Build Agent, including its vitals consultation and PyAutoBuild delegation. Use when the user asks to build, publish, deploy, or release.
---

# Build

Follow [`build.md`](build.md) exactly. Preserve the Brain -> vitals -> Heart ->
Build boundary and all human release gates.
10 changes: 10 additions & 0 deletions skills/clone/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: clone
description: Analyze how a mature PyAuto domain assistant should be reproduced as an exact clone, sibling, or seed through the PyAutoBrain Clone Agent. Use for assistant-cell cloning decisions; the current agent is analysis-only and must not generate files.
---

# Clone

Read [`../../agents/conductors/clone/AGENTS.md`](../../agents/conductors/clone/AGENTS.md)
completely, then run `bin/pyauto-brain clone` with the documented arguments.
Return its `CloneDecision` and preserve the agent's no-write boundary.
4 changes: 4 additions & 0 deletions skills/clone/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Clone Agent"
short_description: "Analyze assistant cloning boundaries"
default_prompt: "Use $clone to analyze how a PyAuto domain assistant should be cloned."
9 changes: 9 additions & 0 deletions skills/docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: docs
description: Start PyAutoLabs documentation, tutorial, notebook, example, or narrative-prose work through the Brain development workflow with the docs work type fixed.
---

# Docs

Follow [`docs.md`](docs.md) exactly. Route the task through `start-dev`; this is
a work-type entry, not a separate documentation conductor.
3 changes: 2 additions & 1 deletion skills/docs/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ Treat the request as PyAutoMind work-type **`docs/`** — documentation, example
notebooks, or tutorial prose. If no prompt path exists, create one under
`PyAutoMind/docs/<target>/<name>.md` (original request verbatim), then run
**`/start_dev`** on it. `start_dev` routes through the Brain, and the tutorial
Opus/Sonnet split in `../WORKFLOW.md` applies. Taxonomy: `PyAutoMind/ROUTING.md`.
The judgment/execution tier split in `../WORKFLOW.md` applies. Taxonomy:
`PyAutoMind/ROUTING.md`.
9 changes: 9 additions & 0 deletions skills/feature/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: feature
description: Select, size, phase, or plan a PyAutoLabs feature through the PyAutoBrain Feature Agent, then route an approved task into start-dev. Use for new capabilities and next-task selection.
---

# Feature

Follow [`feature.md`](feature.md) exactly. Let `bin/pyauto-brain feature`
produce the structured decision before development starts.
9 changes: 9 additions & 0 deletions skills/health/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: health
description: Use the single PyAuto health door for readiness assessment, validation sweeps, active-work status, release-run status, or worktree status through the Brain and Heart-owned procedures.
---

# Health

Follow [`health.md`](health.md) exactly. Keep health judgment in PyAutoHeart and
dispatch through the documented Brain conductor or reference leg.
9 changes: 9 additions & 0 deletions skills/intake/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: intake
description: Turn raw PyAutoLabs ideas, bug reports, or loose requirements into classified and sized PyAutoMind prompt files through the PyAutoBrain Intake Agent. Use before start-dev when intent is not yet formalized.
---

# Intake

Follow [`intake.md`](intake.md) exactly. Run the deterministic intake agent as a
dry run first and apply only after reviewing its decision.
10 changes: 10 additions & 0 deletions skills/memory/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: memory
description: Recall cited PyAuto scientific, architectural, assistant, or task-history context through the read-only PyAutoBrain Memory Faculty. Use before substantial planning when prior decisions or domain knowledge could change the approach.
---

# Memory

Read [`../../agents/faculties/memory/AGENTS.md`](../../agents/faculties/memory/AGENTS.md)
completely, then run `bin/pyauto-brain memory "<topic>"`. Read only the cited
pages needed for the task and preserve the documented privacy boundary.
Loading