Skip to content
Merged
5 changes: 3 additions & 2 deletions ORGANISM.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ organs plan, build, test and release it, and you make every judgment call.
| **Hands** | PyAutoHands | Builds and releases — packaging, tagging, notebook generation, PyPI via `release.yml`. A pure executor: runs no readiness checks and never re-derives a gate decision. |
| **Pulse** | PyAutoPulse | Feels *how fast the organism runs* across the `<lib>_profiling` project repos. Owns profiling campaign intent and pending domain tasks, the profiling instance registry, the versioned `profiling-summary` read contract, the ingest receipts (resolved commit per project per render) and the cross-project board. Validates the exchange contract only; project repos own producers, results, pins, drift policy and their own Pages page. Never moves pins, combines unmatched timings, applies the compile threshold to runtime, computes an ecosystem-wide speed score or issues a readiness verdict; the Brain's profiling conductor (`triage`) is the only judge. |
| **Insight** | PyAutoInsight | Owns inference campaign intent and pending domain tasks, the cross-project inference instance registry, versioned `inference-summary` read contract, ingest receipts and evidence dashboard. Projects own execution, producers and raw samples; Cortex owns scientific run records, observations and human conclusions; Mind owns bounded implementation lifecycle and repository claims. Never infers scientific acceptance from execution, ranks incompatible runs or submits compute on refresh. |
| **Broca** | PyAutoBroca | Owns assistant evidence — evaluation history, collection receipts and the assistant upkeep board (public, so committed evidence must be publishable: no raw transcripts or private data). Public assistants keep their definitions and runners and never depend on Broca; Brain interprets the evidence and routes accepted changes through Mind. Missing or incomparable results never establish a pass, and Broca never launches model or HPC campaigns. |
| **DNA** | PyAutoDNA | Owns software-stack specifications, environment inventory receipts, compatibility decisions, upgrade campaigns and adoption history across local, RAL and CI. Brain coordinates updates; Heart owns validation/readiness; Hands owns release execution/provenance; Nerves owns runtime compatibility. Package repositories remain authoritative for requirements. Collection never upgrades an environment or treats missing observations as passing evidence. |
| **Nerves** | PyAutoNerves | The configuration/serialization layer (`autonerves`) — layered config with overrides, the workspace↔library version handshake, `test_mode`, FITS/JSON I/O. Connects the organism's conventions to every library; the base layer the scientific libraries all import. |
| **Gut** | PyAutoGut | Owns the lifecycle of *condemned self-material* — stale branches, stashes, dead code/tests. Holds each as a durable, recoverable git ref through a transit window and **voids** it on a sweep. The storage mirror of Memory (retention ↔ release); the hygiene conductor drives it, as vitals reads Heart. |
Expand Down Expand Up @@ -118,8 +119,8 @@ human types); let faculties multiply behind them.

New capability grows as a **faculty** (cheap: one directory, one doc, one
script), not as a repo. A new organ costs an `AGENTS.md`, install wiring, a body-map row and boundary prose — it must earn that by
owning state or effects no existing organ can. Five capabilities have earned
organ status that way. Configuration/signalling is the **Nerves**
owning state or effects no existing organ can. Capabilities keep earning
organ status that way; the first five were these. Configuration/signalling is the **Nerves**
(PyAutoNerves), the base config/serialization layer every library imports — new
config surfaces belong there, not in a new organ. Keeping track of what is
true is the **Cortex** (PyAutoCortex), the second organ to earn it: it owns
Expand Down
48 changes: 42 additions & 6 deletions agents/conductors/intake/_intake.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
WORK_TYPES, HUMAN_REVIEW, MANUAL_ONLY_WORK_TYPES,
LIBRARY_REPOS, WORKSPACE_REPOS, ORGANISM_REPOS, KNOWN_REPOS,
RISK_KEYWORDS, AMBIGUITY_KEYWORDS, normalise_repo, norm_work_type,
declared_header, LANE_VALUES,
declared_header, LANE_VALUES, _body_map_specs,
declared_inline, effective_difficulty, strip_declarations, _hits,
effective_consequence, effective_unattended, effective_review_minutes,
policy as _sizing_policy, BODY_MAP_PATH,
Expand Down Expand Up @@ -781,6 +781,12 @@ def _next_action(proposed, confidence, work_type=None):
# prompt with no hits, or filed on a box with no PyAutoMemory, gets no line at
# all: an empty `Memory:` would read as "nothing is known", which is a claim
# this has no standing to make.
#
# Nor does a prompt that targets an organ (Brain, Mind, Heart, ...: the body
# map's `category: organ` repos, i.e. ORGANISM_REPOS). Its subject is the
# organism's own machinery, so there is no science question to answer, and the
# digest only ever matched on shared vocabulary ("profile", "model") — every
# organ prompt filed got galaxy-wiki citations that had to be hand-removed.
MEMORY_CITATIONS = 3
MEMORY_QUERY_WORDS = 200

Expand Down Expand Up @@ -811,9 +817,37 @@ def memory_citations(mind: Path, title: str, body_text: str,
return [page["page"] for page in d["pages"]][:limit]


def _with_memory(header: str, pages: list) -> str:
"""`Memory: a.md; b.md` under the optional keys, or the header unchanged."""
if not pages:
def _organs_dir_repos() -> frozenset:
"""Normalised names of body-map repos checked out under `organs/`."""
try:
specs = _body_map_specs()
except (OSError, KeyError, ValueError):
return frozenset()
return frozenset(normalise_repo(name) for name, spec in specs.items()
if str(spec.get("path", "")).startswith("organs/"))


_ORGANS_DIR_REPOS = _organs_dir_repos()


def _cites_memory(target: str | None) -> bool:
"""Whether a prompt with this `Target:` key carries a `Memory:` line.

False for an organ target: see the block comment above. "Organ" here also
covers any repo whose body-map `path` sits under `organs/` (e.g. the
umbrella landing repo, `category: project` but organism machinery, not
science).
"""
key = normalise_repo(target or "")
return key not in ORGANISM_REPOS and key not in _ORGANS_DIR_REPOS


def _with_memory(header: str, pages: list, target: str | None = None) -> str:
"""`Memory: a.md; b.md` under the optional keys, or the header unchanged.

Unchanged when there are no pages, or when `target` is an organ repo.
"""
if not pages or not _cites_memory(target):
return header
line = "Memory: " + "; ".join(pages)
lines = header.split("\n")
Expand Down Expand Up @@ -841,9 +875,11 @@ def write_prompt(mind: Path, decision: dict, body_text: str, source_note: str):
# touches no filesystem, and a citation is only worth computing for a
# prompt that is actually going to exist. The decision carries the header
# that was written, so `--json` reports the file's real contents.
cites = memory_citations(mind, decision.get("title", ""), body_text)
target = decision.get("target")
cites = (memory_citations(mind, decision.get("title", ""), body_text)
if _cites_memory(target) else [])
decision["memory"] = cites
decision["header"] = _with_memory(decision["header"], cites)
decision["header"] = _with_memory(decision["header"], cites, target)
# The input's own header block (and its heading) is already rendered in
# the decision's header — do not echo it into the body (PyAutoBrain#472).
_heading, header_lines, body = _split_header(body_text)
Expand Down
2 changes: 1 addition & 1 deletion bin/project_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def main() -> int:
parser.add_argument('mode', choices=('write', 'check', 'starter-write', 'starter-check'))
parser.add_argument('repos', nargs='*')
parser.add_argument('--root', type=Path, default=Path(os.environ.get('PYAUTO_ROOT', '.')))
args = parser.parse_args()
args = parser.parse_intermixed_args() # install.sh puts --root before the repo names
try:
if args.mode.startswith('starter-'):
if args.repos:
Expand Down
7 changes: 7 additions & 0 deletions board/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ verbatim. This adapter supports retained sources; it does not re-enable
retired overnight collection. Legacy explicit diagnostic helpers remain for
compatibility, separate from board publication.

The board's one remaining GitHub leg is upkeep: key
`search/issues?q=org:<org>+is:issue+is:open&per_page=1`
(`open_issues_endpoint()`), value GitHub's search response verbatim (the leg
reads `total_count`). Versions, community and resume are retired and not
collected, so `bin/version_drift.sh` and the community scan need no seam of
their own; a retired leg returns only through this same endpoint-keyed map.

`BOARD_GH` and `BOARD_PAGES_BASE` support hermetic fixtures. A failed Pages
read may use an owning repo's local published artifact; it must not manufacture
freshness. Public artifacts must never leak private local paths or credentials.
Expand Down
16 changes: 14 additions & 2 deletions board/_board.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def derive_org(homes):
# ---------------------------------------------------------------------------
# The injection seam (--github-data)
#
# Eleven of this board's legs read GitHub through `gh api`, and a Claude Code
# The legs of this board that read GitHub do so through `gh api`, and a Claude Code
# remote session — the surface the board is actually read from on a phone — has
# no `gh` at all. Its GitHub access is the `mcp__github__*` tool surface, which
# is an AGENT capability: this file is a subprocess and cannot reach it, however
Expand Down Expand Up @@ -475,10 +475,22 @@ def extract_heart_performance(board, board_url=""):
}


def open_issues_endpoint(org):
"""The upkeep leg's `gh api` endpoint — also its `--github-data` key.

Upkeep is the board's only remaining GitHub leg (versions, community and
resume were retired with the agents/workflows simplification and are not
collected at all), so this is the one key a gh-less gatherer must supply.
The response is GitHub's search payload verbatim; the leg reads
`total_count`.
"""
return f"search/issues?q=org:{org}+is:issue+is:open&per_page=1"


def collect_open_issues(org, degraded):
"""Total open issues across the org — the /issue_cleanup pointer count
(the audit itself stays that skill's confirmation-gated job)."""
res = gh_json([f"search/issues?q=org:{org}+is:issue+is:open&per_page=1"])
res = gh_json([open_issues_endpoint(org)])
if res is None:
degraded.append("upkeep: open-issue count unavailable")
return None
Expand Down
6 changes: 6 additions & 0 deletions docs/_extra/organs/build.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!doctype html>
<html lang="en"><head><meta charset="utf-8">
<title>Moved: Hands</title>
<link rel="canonical" href="hands.html">
<meta http-equiv="refresh" content="0; url=hands.html">
</head><body><p>This page moved to <a href="hands.html">Hands — PyAutoHands</a>.</p></body></html>
2 changes: 1 addition & 1 deletion docs/board-orchestration.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Supply the lowercase `organ` key for the approved action heading. The shared
`prompt_heading(organ, heading_id=None)` helper also serves existing owner-specific
controls without changing their prompts. It selects fixed text and emphasizes only
the organ name with `strong`; it never accepts arbitrary heading HTML. Titles for
legacy callers remain escaped plain text. All thirteen organ headings live in
legacy callers remain escaped plain text. Every organ heading lives in
`board/_theme.py`; reuse that mapping rather than copying sentences into renderers.
Keep each heading on one line with responsive typography; do not hide overflow or
truncate words. Omit explanatory subtitles and preserve work links/copy controls.
Expand Down
22 changes: 15 additions & 7 deletions docs/concepts/organism.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ working with libraries and projects. Their boundaries are load-bearing. The cano
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.
it and adds the framework/instance distinction an adopter needs. The list of
organs grows over time; when this table and ORGANISM.md disagree, ORGANISM.md
and the Mind's `repos.yaml` (every repo with `category: organ`) win.

| Organ | Repo | Job |
|-------|------|-----|
Expand All @@ -19,7 +21,9 @@ it and adds the framework/instance distinction an adopter needs.
| **Hands** | PyAutoHands | *Does* — packaging, tagging, notebook generation, PyPI releases. A pure executor: never re-derives a gate decision. |
| **Pulse** | PyAutoPulse | *Feels* — the cross-project profiling registry, the versioned `profiling-summary` read contract, ingest receipts and dashboard. Project repos produce and hold timings; Pulse validates the exchange and links to them. The Brain's profiling conductor handles judgment. |
| **Insight** | PyAutoInsight | Coordinates inference campaign intent and domain tasks; owns the inference summary contract, registry, receipts and evidence board. Projects execute and retain samples; Cortex records scientific conclusions; Mind holds implementation lifecycle and claims. |
| **DNA** | PyAutoDNA | *Remembers what it is made of* — software-stack specifications, environment inventory receipts, support rationale and upgrade/adoption history. Brain coordinates upgrades, Heart validates, Hands releases, Nerves enforces runtime compatibility; collection never upgrades an environment. |
| **Nerves** | PyAutoNerves | *Connects* — the configuration/serialization layer (`autonerves`): layered config, the workspace↔library version handshake, `test_mode`, FITS/JSON I/O. The base layer every library imports. |
| **Broca** | PyAutoBroca | *Watches the assistants* — assistant evaluation history, upkeep evidence, collection receipts and the upkeep board. Brain interprets; Mind tracks fixes; the public assistants stay independent of it. |
| **Gut** | PyAutoGut | *Sheds* — the lifecycle of condemned self-material (stale branches, stashes, dead code/tests): holds each as a durable, recoverable git ref through a transit window, then **voids** it on a sweep. The storage mirror of Memory (retention ↔ release); the hygiene conductor drives it, as vitals reads Heart. |

Everything else — the libraries being developed, their example workspaces,
Expand All @@ -38,7 +42,7 @@ is the container, and a workspace is one familiar kind of project.
These roles do not replace the {doc}`repository categories <../satellites>` or
change their workflow and release gates. Profiling, inference and visualization
repos illustrate the project role; Eyes, Pulse and Insight provide cross-project organ
views over the visualization and profiling projects. The project-to-organ
views over the visualization, profiling and inference projects. The project-to-organ
boundary is described in {doc}`../organs/eyes` and {doc}`../organs/pulse`.

## The call chain
Expand All @@ -61,11 +65,15 @@ The organs split on one line that matters for adoption:
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, Cortex, Memory, Eyes, Ears, Pulse, Insight, Gut.** Committed
state, ledgers, knowledge, visualization and profiling registries and shed
material. These are *inherently yours*: an adopter never forks the upstream
Mind, Cortex, Memory, Eyes, Ears, Pulse, Insight or Gut content, they create their own repos with the same documented
shape.
- **Instance organs — every other organ except Nerves.** Mind, Cortex,
Memory, Eyes, Ears, Pulse, Insight, DNA, Broca and Gut hold committed
state: ledgers, knowledge, visualization, profiling and inference
registries, stack records, assistant evidence and shed material. These are
*inherently yours*: an adopter never forks their upstream content, but
creates their own repos with the same documented shape.
- **Nerves sits outside the split.** It is an organ that also ships a library
package (`autonerves`) the scientific libraries import. You adopt it only if
your own libraries want that config layer; see {doc}`../organs/nerves`.

One more principle worth knowing before you read anything else:
**one canonical page per fact.** Organ boundaries live in ORGANISM.md;
Expand Down
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
language = "en"

html_static_path = ["_static"]
html_extra_path = ["_extra"] # e.g. organs/build.html -> hands.html after the rename
html_css_files = ["pyauto.css"]

html_theme_options = {
Expand Down
11 changes: 7 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

PyAutoScientist is a working, opinionated reference implementation of an
**AI-agent development organism** for human-led, natural-language software
development: a set of ten git repositories — Brain, Mind, Cortex, Memory,
Eyes, Ears, Heart, Hands, Pulse, Insight, Nerves, Gut — through which you lead a multi-repo project in
plain English. You
development: a set of git repositories called **organs** (Brain, Mind,
Cortex, Memory and the rest; {doc}`the organism <concepts/organism>` lists
them all) through which you lead a multi-repo project in plain English. You
describe what you want; AI agents plan, implement, test, gate and release
it; you make every judgment call.

Expand Down Expand Up @@ -60,9 +60,12 @@ organs/memory
organs/eyes
organs/ears
organs/heart
organs/build
organs/hands
organs/pulse
organs/insight
organs/dna
organs/nerves
organs/broca
organs/gut
```

Expand Down
39 changes: 39 additions & 0 deletions docs/organs/broca.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Broca — PyAutoBroca

**What it owns:** the evidence on how the AI assistants are doing. Broca keeps
assistant evaluation history, upkeep evidence, collection receipts and the
assistant upkeep board.

**Repo:** [PyAutoLabs/PyAutoBroca](https://github.com/PyAutoLabs/PyAutoBroca)

## The defining function: watching the assistants speak

Broca's area is the part of the brain tied to producing language. This organ
watches the organism's public assistants and records how well they work.
Benchmarks and maintenance inventory are kept as separate kinds of evidence,
and a missing or incomparable result never counts as a pass.

## The boundary that matters

The public assistants stay independent. They keep their own definitions and
reproducible runners, anyone can use them on their own, and they never depend
on Broca.

Broca records; it does not judge or act.

- **Brain** interprets the evidence and routes accepted changes through Mind.
- **Mind** tracks the fixes.
- **Cortex** keeps science records and **Heart** keeps readiness, as everywhere
else.

Broca is a public repository, so everything committed to it must be suitable
for publication. Raw transcripts and private project data are excluded. It
does not launch model or HPC campaigns on its own, and its Actions workflow
publishes only the rendered saved snapshot, without collecting new evidence.

## For an adopter

Broca is an **instance organ**: its evidence is about *your* assistants. If you
publish assistants of your own, create a Broca with the same shape. The full
boundary is the
[Broca section of ORGANISM.md](https://github.com/PyAutoLabs/PyAutoBrain/blob/main/ORGANISM.md#broca--assistant-evidence).
Loading
Loading