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
28 changes: 28 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Docs

# Docs build check is defined once, centrally, in PyAutoHeart's reusable
# workflow (Heart owns all health/readiness checking). This thin caller
# builds the Sphinx docs on PRs and fails on warning-count regression
# against docs/sphinx_warning_baseline.txt. PyAutoBrain is not a pip
# package, so it uses the workflow's docs-only mode.

on:
push:
branches: [main]
paths:
- "docs/**"
- ".readthedocs.yaml"
- ".github/workflows/docs.yml"
pull_request:
paths:
- "docs/**"
- ".readthedocs.yaml"
- ".github/workflows/docs.yml"
workflow_dispatch:

jobs:
docs:
uses: PyAutoLabs/PyAutoHeart/.github/workflows/docs-build.yml@main
with:
package: pyautoscientist
secrets: inherit
14 changes: 14 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2

build:
os: ubuntu-22.04
tools:
python: "3.12"

python:
install:
- requirements: docs/requirements.txt

sphinx:
configuration: docs/conf.py
fail_on_warning: false
25 changes: 25 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Contributing

The PyAutoScientist organs (PyAutoBrain, PyAutoMind, PyAutoHeart,
PyAutoBuild, PyAutoMemory) are a **living reference implementation** — the
maintainer's daily working system, not a stable library.

What that means in practice:

- **`main` moves fast** — hundreds of commits a quarter — and there are
**no compatibility promises**. Anything may be renamed, rewired or
removed when the live system needs it.
- **Adopt by fork-and-pull, never by tracking.** Fork the organs, confine
your changes to the declared config surfaces, and pull upstream at your
own pace — the model is documented in the
[adoption guide](https://pyautoscientist.readthedocs.io/en/latest/adoption/guide.html).
Pin what you depend on.
- **Issues and PRs are welcome**, and read with interest — but triage pace
is set by the live instance's needs, and PRs that genericise working
production prompts (`skills/*.md`) or add abstraction for hypothetical
users will be declined.
- The best contribution while the project is young: **adopt it, and report
the friction** you hit following the adoption guide.

Docs: <https://pyautoscientist.readthedocs.io> · the organism:
[ORGANISM.md](https://github.com/PyAutoLabs/PyAutoBrain/blob/main/ORGANISM.md)
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ bash bin/install.sh # symlink every organ's skills into ~/.claude

Runs straight from its checkout — no pip install. Agent contracts and the
organ boundary are in [AGENTS.md](AGENTS.md); how much a run may do without
a human is the autonomy contract, [AUTONOMY.md](AUTONOMY.md).
a human is the autonomy contract, [AUTONOMY.md](AUTONOMY.md). The full
organism documentation — including how to fork and run your own — is at
<https://pyautoscientist.readthedocs.io> (source: `docs/`).
32 changes: 32 additions & 0 deletions docs/_static/pyauto.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* PyAuto shared docs brand layer — identical file in PyAutoFit, PyAutoGalaxy,
PyAutoLens (docs/_static/pyauto.css). The per-project accent is set via
Furo's color-brand-* variables in each repo's conf.py; this file carries
the elements common to the whole stack. */

/* The PyAuto family signature: a thin gradient strip across the top of every
docs page, running through the three stack accents (Fit / Galaxy / Lens). */
body::before {
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, #c2410c 0%, #0f766e 50%, #7c4dff 100%);
z-index: 1000;
pointer-events: none;
}
@media (prefers-color-scheme: dark) {
body:not([data-theme="light"])::before {
background: linear-gradient(90deg, #f28c38 0%, #2dd4bf 50%, #9d7aff 100%);
}
}
body[data-theme="dark"]::before {
background: linear-gradient(90deg, #f28c38 0%, #2dd4bf 50%, #9d7aff 100%);
}

/* Project wordmark in the sidebar. */
.sidebar-brand-text {
font-weight: 700;
letter-spacing: -0.01em;
}
52 changes: 52 additions & 0 deletions docs/adoption/config_surfaces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# The declared config surfaces

A fork's diff should touch these — and only these. Everything else in the
framework organs is domain-free logic you pull from upstream.

## The primary surfaces

| Surface | Organ | What it declares |
|---------|-------|------------------|
| `repos.yaml` | Mind (yours) | The body map — every repo's GitHub home, category, role. The single source the rest are checked against. |
| `config/repos.yaml` | Heart | What to poll and gate: repo groups, required CI workflows, thresholds, dirty-file noise patterns. |
| `pre_build.sh` — the `run_workspace` table | Hands | One row per workspace: repo, package, flags, parent library. |
| `agents/faculties/sizing/_sizing.py` | Brain | The library/workspace repo sets and aliases used to size and route tasks. |
| `agents/conductors/intake/_intake.py` — `TARGET_SIGNALS` | Brain | Keyword → target-repo routing for raw ideas. |
| `agents/conductors/release/` — the library tuple + `nightly.sh` | Brain | Which libraries the release path drives. |
| `agents/faculties/memory/` — the wiki keyword map | Brain | Topic keywords → your Memory's sub-wikis. |
| `heart/readiness.py` — `DEFAULT_LIBRARIES`; `heart/checks/version_skew.py` — the workspace→(library, package) map | Heart | The release-gate repo sets. |
| `autobuild/run_all.py`, `autobuild/slow_skip_check.py`, navigator maps | Hands | Which workspaces the validation pipeline runs and skips. |

The honest state: some of these are clean policy files (Heart's
`config/repos.yaml`), others are constant tables inside code files. A
demand-gated later phase teaches `repos_sync --write` to stamp the tables
from the body map; until then, replacing them by hand is a one-time cost at
fork, and the drift checks below make sure they can't disagree afterwards.

(tenant-firewall)=
## The tenant firewall

`PyAutoMind/scripts/repos_sync.py --check` includes a **tenant-firewall
check**: it scans every `*.py` / `*.sh` file in Brain, Heart and Hands for
*instance facts* — satellite repo names from the body map, GitHub owners,
the workspace home path — and fails on any occurrence outside a frozen
per-file allowlist (`FIREWALL_ALLOWLIST`, which *is* the machine-checked
inventory of the surfaces above plus the legacy remainder scheduled for
extraction).

Two firing modes: a **new** instance fact in an allowlisted file, or **any**
instance fact in a new file. Together they guarantee the property adoption
depends on: as upstream churns daily, no new code path can silently
hardcode the live instance — so your fork's `git pull` stays a config-diff
pull.

## What is *not* a config surface

- **`skills/*.md`** — the Brain's skill bodies are production prompts. They
mention the live instance in worked examples; that is deliberate and
harmless (they parameterise through the body map at the points that
matter). Never run a "genericisation pass" over them.
- **`AGENTS.md` / `ORGANISM.md` / `AUTONOMY.md`** — doctrine, shared as-is.
- **Markdown generally** — the firewall scans code, not prose; generated
doc blocks (`repos_sync:begin/end` markers) restamp from *your* body map
when you run `--write`.
69 changes: 69 additions & 0 deletions docs/adoption/guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Adopting PyAutoScientist

The adoption model is a **config-diff fork**: one upstream (the live
organs), N private organisms downstream. You fork the framework organs,
confine your diff to the declared config surfaces, and `git pull` upstream
improvements cleanly forever after. There is deliberately no shared
deployment, no "generic edition", and no stability promise on `main` — see
{ref}`the disclaimer <stability>` below.

## Prerequisites — what PyAutoScientist *is*

These are the product, not incidental choices. If they don't fit how you
work, this system is not for you (and that's fine):

- **Claude Code** as the agent harness — the Brain's skills and verb
commands install into `~/.claude` and are written for it.
- **The GitHub CLI (`gh`)** and GitHub-hosted repos — issues, PRs and CI
state are read and written through it.
- **A trunk-based, single-maintainer flow** with task worktrees under a
common workspace root (`~/Code/<YourLabs>/` + `<YourLabs>-wt/`).
- **GitHub Actions + PyPI** for the release pipeline, if you release
packages.

## The walkthrough

1. **Fork Brain, Heart, Hands** (keep the repo names — they are framework
identity).
2. **Create your Mind** with the documented shape
([PyAutoMind/REFERENCE.md](https://github.com/PyAutoLabs/PyAutoMind/blob/main/REFERENCE.md)):
the registry files, the work-type prompt folders, a copy of `scripts/`,
and — the load-bearing part — **your own `repos.yaml` body map** listing
your libraries, workspaces and their categories per the
{doc}`category contract <../satellites>`.
3. **Replace the config surfaces** in your forks with rows for your repos —
the complete inventory with file paths is {doc}`config_surfaces`. The
big three: Heart's `config/repos.yaml` (what to poll and gate), the
Hands' `run_workspace` table in `pre_build.sh` (what the pipeline runs),
and the Brain's constant tables (sizing sets, routing keywords, the
release library tuple).
4. **Regenerate and check.** `python3 <YourMind>/scripts/repos_sync.py
--write` stamps the generated doc blocks from your body map; `--check`
verifies every mirror agrees — including the tenant firewall, which
fails if an upstream instance fact survives anywhere outside the
declared surfaces you just replaced.
5. **Install the command surface**: `bash <YourBrain>/bin/install.sh`
symlinks every organ's skills into `~/.claude`.
6. **Create your Memory when you need it** — the shape is documented in
{doc}`the Memory page <../organs/memory>`; the organism runs fine
without one until your domain knowledge accumulates.
7. **Go.** Write your first prompt in your Mind and run `/start_dev` on it.

## Staying current

Because your diff is confined to config surfaces, `git pull upstream main`
in each framework organ stays clean: you take every improvement the
upstream ships, and your instance facts never collide with it. The tenant
firewall is what keeps this true over time — upstream runs it in `--check`,
so new upstream code cannot silently hardcode an instance fact that would
land in your fork.

(stability)=
## The stability disclaimer

The upstream organs are a **living reference implementation** — the
maintainer's daily working system, moving fast (hundreds of commits a
quarter), with no compatibility promises on `main`. Fork-and-pull at your
own pace; pin what you depend on; expect churn. Issues and PRs are welcome,
but the pace is set by the live instance's needs. Each organ carries this
disclaimer in its `CONTRIBUTING.md`.
52 changes: 52 additions & 0 deletions docs/concepts/agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Conductors and faculties

The Brain hosts the specialist agents, split into two tiers by a single
question: **does it act, or only opine?**

- **Conductors** (`agents/conductors/<name>/`) are the front doors a human
drives. They decide *and* act — a plan driven into development, a build, a
release. Each is a directory with an `AGENTS.md` (what it reasons about)
and a deterministic entrypoint script, so its behaviour is invoked
identically by humans and CI rather than re-derived from prose each time.
- **Faculties** (`agents/faculties/<name>/`) are read-only opinions the
conductors consult. They return a judgment and stop — never dispatch,
never mutate.

The live conductor set: **intake** (raw idea → formal Mind prompt),
**feature** (plan the next growth task), **bug** (classify and route a
repair), **refactor** (behaviour-preserving restructuring), **profiling**
(the organism's sense of its own effort), **build**, **release**, and
**health** (the clinician loop toward GREEN). The faculties behind them:
**vitals** (the only component that talks to Heart), **review** (the
automatic-review leg of the ship gate), **memory** (cited digests over the
Memory organ), and **samplers** (domain expertise for the live instance).

## The consult graph is a DAG

Conductors consult faculties; each faculty reads its sensor organ; **only
the vitals faculty talks to Heart**. A conductor never consults another
conductor — if it wants one's opinion, that opinion should be extracted
into a faculty. (A conductor may *delegate execution* to another organ,
which is the normal call chain, not consultation.)

This shape is what keeps a society of agents debuggable: opinions are
side-effect-free and reusable, actions have exactly one owner, and there is
never a hidden path to an organ.

## The growth rule

New capability grows as a **faculty** by default — one directory, one doc,
one script. A conductor is added only when a genuinely new human-driven verb
earns it, and a new *organ* must own state or effects no existing organ can.
The conductor set stays small and human-meaningful; faculties multiply
behind them. Symmetry is never a reason to add an agent.

## The command surface

Humans don't type agent names — they type short verbs (`/intake`, `/bug`,
`/feature`, `/health`, `/route`) or plain natural language, and the Brain
routes to the right agent. The command bodies are the Brain's `skills/`
directory, installed into the agent harness (Claude Code's `~/.claude`) by
`bin/install.sh`. The skills are **production prompts**: battle-tested
operating procedure, not documentation. This site describes them; it never
restates them.
53 changes: 53 additions & 0 deletions docs/concepts/organism.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# The organism

The system is organised as a body: each repository is an **organ** with one
job, and the boundaries between them are load-bearing. The canonical
definition lives in the Brain repo as
[ORGANISM.md](https://github.com/PyAutoLabs/PyAutoBrain/blob/main/ORGANISM.md)
— one page every organ links to instead of restating. This page summarises
it and adds the framework/instance distinction an adopter needs.

| Organ | Repo | Job |
|-------|------|-----|
| **Mind** | PyAutoMind | Decides *what* — intent, goals, priorities, workflow state, the prompt registry, and the body map (`repos.yaml`). |
| **Brain** | PyAutoBrain | Figures out *how* — reasoning, planning, routing; hosts the specialist agents. Owns no state, no health checks, no execution mechanics. |
| **Heart** | PyAutoHeart | Decides whether the organism is *healthy*. `pyauto-heart readiness` is the authoritative GREEN/YELLOW/RED release gate. An observer: never writes into other repos, never triggers a build. |
| **Hands** | PyAutoBuild | *Does* — packaging, tagging, notebook generation, PyPI releases. A pure executor: never re-derives a gate decision. |
| **Memory** | PyAutoMemory | *Knows* — long-term domain knowledge: literature wikis, concepts, bibliographies. Pull-only; consulted, never load-bearing at runtime. |

Everything else — the libraries being developed, their example workspaces,
test suites, tutorials — is a **satellite**: a capability the organism works
*on*, not part of the organism itself. The satellite kinds and what the
organism expects of each are the {doc}`category contract <../satellites>`.

## The call chain

```
Brain → Heart (gate) → Hands (execute)
```

Always in that order. The Brain asks Heart for the readiness verdict,
reasons over it, and only on GREEN triggers the Hands. Heart never triggers
a build; the Hands never re-check readiness. Each boundary exists so that no
organ has to be trusted to police itself.

## Framework vs instance

The five organs split on one line that matters for adoption:

- **Framework organs — Brain, Heart, Hands.** Code, agents, checks,
pipelines. Domain facts appear only in declared config surfaces (tables
and policy files, not logic), and a drift check — the
{ref}`tenant firewall <tenant-firewall>` — keeps it that way.
- **Instance organs — Mind, Memory.** Committed state and knowledge. These
are *inherently yours*: an adopter never forks the upstream Mind or Memory
content, they create their own repos with the same documented shape.

One more principle worth knowing before you read anything else:
**one canonical page per fact.** Organ boundaries live in ORGANISM.md;
autonomy rules live in
[AUTONOMY.md](https://github.com/PyAutoLabs/PyAutoBrain/blob/main/AUTONOMY.md);
repo identity lives in the Mind's `repos.yaml`. Everything else links. When
prose is duplicated it rots, and an agent acting on rotten prose does real
damage — so the system treats duplication as a bug, and backs the important
cases with machine drift-checks.
53 changes: 53 additions & 0 deletions docs/concepts/workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# The development workflow

Every task follows the same lifecycle, whatever its size:

```
idea → prompt file → issue → worktree → PR(s) → merge → registry
(Mind) (GitHub) (isolated) (gated) (human) (Mind)
```

1. **Intent is written down first.** A task starts as a markdown file in the
Mind under `<work-type>/<target>/<name>.md` — plain English, no template.
The work-type folder (`feature/`, `bug/`, `refactor/`, `docs/`, …) tells
the Brain what kind of reasoning the task needs.
2. **`start_dev`** routes the prompt through the Brain's Feature Agent:
classify, plan at two levels (human bullets + a detailed plan a fresh
session could resume from), survey the affected branches, create a
tracked GitHub issue, and register the task in the Mind's `active.md`.
3. **Work happens in a task worktree** (`~/Code/PyAutoLabs-wt/<task>/`) on a
`feature/<task>` branch across every claimed repo, so parallel tasks
never collide. `active.md` records the claim; a conflict check blocks
double-claiming a repo.
4. **`ship_*`** gates the finish: test suites, the review faculty, and the
Heart readiness verdict. GREEN ships; YELLOW needs an explicit human
acknowledgement; RED stops. One PR per repo, always.
5. **Merge is always human.** After merge, the task entry moves from
`active.md` to `complete.md` — the organism's operational history.

The registry files (`active.md`, `planned.md`, `complete.md`) are shared
state in the Mind repo, so any machine or session — laptop, web, CI — can
read the current picture and resume an in-flight task with no handoff
ceremony.

## The autonomy contract

How much of that lifecycle runs without a human is not ad-hoc: it is defined
once, in
[AUTONOMY.md](https://github.com/PyAutoLabs/PyAutoBrain/blob/main/AUTONOMY.md).
Each prompt carries `Autonomy: safe | supervised | human-required`; each
work-type has a cap; the effective level is the minimum of the two, and it
binds only when a run is explicitly launched with `--auto`. The contract
pins the invariants: merge is always human, autonomous runs end at PR-open,
Heart RED always stops, and a `safe` run's four-leg ship gate (tests, smoke,
automatic review, Heart) must pass before anything is pushed. Every
autonomous run appends to a calibration log, and raising a cap requires
citing it.

## Model tiers

The workflow splits across model tiers, not named models: a **judgment
tier** (the strongest available model) does planning, risk calls, and any
prose a reader will learn from; an **execution tier** (a fast, cheap model)
runs the mechanical shell/git phases as subagents. The doctrine survives
model generations changing underneath it.
Loading
Loading