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
2 changes: 1 addition & 1 deletion agents/conductors/bug/_bug.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def emit_human(mode: str, d: dict):
if d["memory_context"]:
print("Relevant context (PyAutoMemory — consult, do not invent):")
for wiki, kws in d["memory_context"].items():
print(f" - {wiki}/index.md ({', '.join(kws)})")
print(f" - PyAutoMemory/wiki/{wiki}/index.md ({', '.join(kws)})")
else:
print("Relevant context: none matched")
print(f"Fix locus: {d['fix_locus']['locus']}")
Expand Down
10 changes: 5 additions & 5 deletions agents/conductors/feature/MIND_TAXONOMY.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ context when memory has material. Sub-wikis (source: `PyAutoMemory/index.md`):

| Sub-wiki | Domain | Triggered by (examples) |
|----------|--------|--------------------------|
| `lensing_wiki/` | strong gravitational lensing | lens, deflection, source reconstruction, subhalo, time delay, cosmography, SLACS/TDCOSMO |
| `smbh_wiki/` | supermassive black holes | black hole, SMBH, binary, recoil, NANOGrav |
| `cti_wiki/` | charge-transfer inefficiency | CTI, trap, arctic, VIS calibration |
| `methods_wiki/` | statistical / computational methods | Bayesian, sampler, JAX, NUFFT, SBI, graphical models, deep learning |
| `galaxies_wiki/` | galaxy formation & evolution | bulge/disk, MGE, morphology, IFU, kinematics |
| `wiki/lensing/` | strong gravitational lensing | lens, deflection, source reconstruction, subhalo, time delay, cosmography, SLACS/TDCOSMO |
| `wiki/smbh/` | supermassive black holes | black hole, SMBH, binary, recoil, NANOGrav |
| `wiki/cti/` | charge-transfer inefficiency | CTI, trap, arctic, VIS calibration |
| `wiki/methods/` | statistical / computational methods | Bayesian, sampler, JAX, NUFFT, SBI, graphical models, deep learning |
| `wiki/galaxies/` | galaxy formation & evolution | bulge/disk, MGE, morphology, IFU, kinematics |

Library targets also pull a default sub-wiki (`autolens`→lensing,
`autogalaxy`→galaxies, `autofit`/`autoarray`/`autoconf`→methods). PyAutoMemory is
Expand Down
2 changes: 1 addition & 1 deletion agents/conductors/feature/_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ def emit_human(mode: str, decision: dict):
if d["memory_context"]:
print("Relevant context (PyAutoMemory — consult, do not invent):")
for wiki, kws in d["memory_context"].items():
print(f" - {wiki}/index.md ({', '.join(kws)})")
print(f" - PyAutoMemory/wiki/{wiki}/index.md ({', '.join(kws)})")
else:
print("Relevant context: none matched (no scientific context required)")
print(f"Phase decision: {d['phase_decision']}")
Expand Down
24 changes: 19 additions & 5 deletions agents/faculties/memory/_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
"""agents/faculties/memory/_memory.py — the recall substrate.

The **memory faculty** is a read-only opinion sink: given a topic/question, it
greps the organism's knowledge surfaces — PyAutoMemory's sub-wikis,
autolens_assistant's skills/wiki pages, and Mind's complete/ records — and
returns a **cited digest**: ranked pages with matching snippets. The consulting
agent reads only the listed pages and synthesises; this script never dumps
content, never writes, and builds no index.
greps the organism's knowledge surfaces — PyAutoMemory's sub-wikis and its
root entry pages (index.md, reading-queue.md, bibliography/README.md, the
wiki schema), autolens_assistant's skills/wiki pages, and Mind's complete/
records — and returns a **cited digest**: ranked pages with matching
snippets. The consulting agent reads only the listed pages and synthesises;
this script never dumps content, never writes, and builds no index.

Deliberately NOT a surface: ``bibliography/*.bib`` — the canonical BibTeX
file is far over ``MAX_FILE_BYTES`` and raw entries are metadata, not digest
text; ``bibliography/README.md`` carries the workflow instead.

Exit codes: 0 digest · 4 no hits or no surface · 5 usage.
"""
Expand All @@ -32,6 +37,15 @@ def terms_of(query: str) -> list[str]:
def surfaces(memory: Path | None, assistant: Path | None, mind: Path | None):
"""Yield (surface-name, root, md-file) triples, discovered at query time."""
if memory and memory.is_dir():
# The repo's own entry surfaces: the hand-written index, the reading
# queue, the bibliography workflow, and the wiki schema. Without
# these the front door PyAutoMemory/AGENTS.md points every agent at
# ("index first") was invisible to this faculty (PyAutoBrain#239).
for rel in ("index.md", "reading-queue.md",
"bibliography/README.md", "wiki/CLAUDE.md"):
f = memory / rel
if f.is_file():
yield "PyAutoMemory/root", memory, f
# wiki/<domain>/ is the current layout; root-level *_wiki/ is the
# pre-2026-07 layout, kept for older checkouts and forks.
wikis = sorted(d for d in memory.glob("wiki/*") if d.is_dir())
Expand Down
2 changes: 1 addition & 1 deletion agents/faculties/samplers/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ not inventoried.
(prototypes + `_metrics.py` + `output/comparison.txt`),
`autofit_workspace_developer/searches/` (removed-sampler archive),
`autofit_workspace_test/scripts/searches/` (integration scripts).
- **The science** — `PyAutoMemory/methods_wiki`:
- **The science** — `PyAutoMemory/wiki/methods`:
`concepts/hamiltonian-monte-carlo.md`, `concepts/gpu-nested-sampling.md`,
`concepts/initialization-chaining.md`, `concepts/sampler-benchmarks.md`
(the campaign record), `concepts/nested-sampling.md`. **Privacy seam:**
Expand Down
2 changes: 1 addition & 1 deletion agents/faculties/samplers/_samplers.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def digest(autofit, developer, test, lens_developer=None, profiling=None) -> dic
"instruction": "reason with agents/faculties/samplers/AGENTS.md "
"(sampler<->likelihood match, gradients/JAX, "
"initialization chaining); the science lives in "
"PyAutoMemory/methods_wiki — internal use only, "
"PyAutoMemory/wiki/methods — internal use only, "
"citations never reach public output",
}
minimal = integration = []
Expand Down
27 changes: 15 additions & 12 deletions config/policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,22 @@ sizing_categories:
extra_workspace_targets: [workspaces]
extra_organism_targets: [autohands]

# Keyword -> PyAutoMemory sub-wiki (also the science vocabulary difficulty
# scoring keys off). Source of truth for the wiki list: PyAutoMemory/index.md.
# Keyword -> PyAutoMemory sub-wiki (the wiki/<domain>/ layout; also the science
# vocabulary the difficulty scoring keys off). Source of truth for the wiki
# list: PyAutoMemory/index.md.
memory_wikis:
lensing_wiki: [lens, deflection, source reconstruction, caustic, einstein,
lensing: [lens, deflection, source reconstruction, caustic, einstein,
subhalo, substructure, time delay, cosmography, shear,
multipole, mass sheet, slacs, tdcosmo, h0licow, macromodel]
smbh_wiki: [black hole, smbh, binary, recoil, nanograv,
smbh: [black hole, smbh, binary, recoil, nanograv,
gravitational wave background]
cti_wiki: [charge transfer, cti, trap, arctic, vis calibration]
methods_wiki: [bayesian, sampler, nautilus, dynesty, emcee, mcmc,
cti: [charge transfer, cti, trap, arctic, vis calibration]
methods: [bayesian, sampler, nautilus, dynesty, emcee, mcmc,
nested sampling, likelihood, jax, nufft, interpolat,
graphical model, expectation propagation, deep learning, sbi,
simulation based inference, probabilistic, optimis, gradient,
regularis]
galaxies_wiki: [galaxy formation, bulge, disk, morphology, mge, stellar halo,
galaxies: [galaxy formation, bulge, disk, morphology, mge, stellar halo,
ifu, kinematic, elliptical, cosmos]

# Intake keyword -> target repo routing signals.
Expand All @@ -62,11 +63,13 @@ target_signals:

# Feature conductor: target -> the sub-wiki consulted by default.
target_default_wiki:
autolens: lensing_wiki
autogalaxy: galaxies_wiki
autofit: methods_wiki
autoarray: methods_wiki
autoconf: methods_wiki
autolens: lensing
autogalaxy: galaxies
autofit: methods
autoarray: methods
autoconf: methods # legacy name — the Nerves repo was PyAutoConf
autonerves: methods
pyautonerves: methods

# Refactor conductor: normalised repo -> the test dir that witnesses
# behaviour preservation.
Expand Down
2 changes: 1 addition & 1 deletion docs/adoption/config_surfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ framework organs is domain-free logic you pull from upstream.
| `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. |
| `config/policy.yaml` — `memory_wikis` + `target_default_wiki` | Brain | Topic keywords → your Memory's sub-wikis (`wiki/<domain>/`), consumed by the sizing faculty and the feature/bug conductors. |
| `heart/readiness.py` — `DEFAULT_LIBRARIES`; `heart/checks/version_skew.py` — the workspace→(library, package) map | Heart | The release-gate repo sets. |
| `autohands/run_all.py`, `autohands/slow_skip_check.py`, navigator maps | Hands | Which workspaces the validation pipeline runs and skips. |

Expand Down
4 changes: 2 additions & 2 deletions skills/sampler_pipeline/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Read `agents/faculties/samplers/AGENTS.md` for the judgment tables (sampler ↔
likelihood match, gradient/JAX constraints, initialization chaining, promotion
criteria). If the candidate is already prototyped or promoted, resume at the
right stage instead of starting over. The deeper science is in
`PyAutoMemory/methods_wiki` (`hamiltonian-monte-carlo`, `gpu-nested-sampling`,
`PyAutoMemory/wiki/methods` (`hamiltonian-monte-carlo`, `gpu-nested-sampling`,
`initialization-chaining`, `sampler-benchmarks`) — internal use only; its
citations never reach public user-facing output.

Expand Down Expand Up @@ -72,7 +72,7 @@ The prototype contract (what makes its row comparable):
- If the candidate targets real likelihoods (lensing MGE / pixelization /
interferometer), extend to `autolens_profiling` use-case runs before any
promotion argument — the 1D Gaussian alone never justifies promotion.
- Record durable findings in `PyAutoMemory/methods_wiki` (update
- Record durable findings in `PyAutoMemory/wiki/methods` (update
`concepts/sampler-benchmarks.md`).

## 3. Promote (or archive)
Expand Down
87 changes: 87 additions & 0 deletions tests/test_memory_surfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""tests/test_memory_surfaces.py — the memory faculty's corpus (PyAutoBrain#239).

First regression net for `agents/faculties/memory/_memory.py`. What matters:
the root entry surfaces (index.md, reading-queue.md, bibliography/README.md,
wiki/CLAUDE.md) are part of the corpus — they were invisible before #239 even
though PyAutoMemory/AGENTS.md tells every agent to index them first; surface
labels stay repo-name-first (digest()'s exit-4 logic splits on '/'); ranking
and the no-hits path behave; and the conductors' printed PyAutoMemory pointers
name paths that exist under the wiki/<domain>/ layout.
"""

from __future__ import annotations

import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]
/ "agents" / "faculties" / "memory"))

import _memory # noqa: E402


def _memory_repo(tmp_path: Path) -> Path:
m = tmp_path / "PyAutoMemory"
(m / "wiki" / "demo" / "concepts").mkdir(parents=True)
(m / "bibliography").mkdir()
(m / "index.md").write_text("# Index\nthe entry surface mentions quasars\n")
(m / "reading-queue.md").write_text("# Reading queue\n\nquasar paper one\n")
(m / "bibliography" / "README.md").write_text("# Bib\nadding a quasar paper\n")
(m / "wiki" / "CLAUDE.md").write_text("# Schema\nstatus flags\n")
(m / "wiki" / "demo" / "concepts" / "quasars.md").write_text(
"---\nstatus: drafted\n---\nquasars lens light\n")
return m


def test_root_entry_surfaces_are_in_the_corpus(tmp_path):
m = _memory_repo(tmp_path)
triples = list(_memory.surfaces(m, None, None))
root_files = {f.name for name, _, f in triples if name == "PyAutoMemory/root"}
assert root_files == {"index.md", "reading-queue.md", "README.md", "CLAUDE.md"}
# the wiki pages still arrive under their sub-wiki label
assert any(name == "PyAutoMemory/demo" for name, _, _ in triples)


def test_labels_stay_repo_name_first(tmp_path):
m = _memory_repo(tmp_path)
for name, _, _ in _memory.surfaces(m, None, None):
assert name.split("/")[0] == "PyAutoMemory"


def test_digest_ranks_and_cites_the_queue(tmp_path):
m = _memory_repo(tmp_path)
d = _memory.digest("quasar reading queue", m, None, None, limit=8)
assert d["surfaces_present"] == ["PyAutoMemory"]
pages = {p["page"] for p in d["pages"]}
assert "reading-queue.md" in pages
assert all(p["hits"] >= 1 and p["snippets"] for p in d["pages"])


def test_no_hits_yields_empty_pages(tmp_path):
m = _memory_repo(tmp_path)
d = _memory.digest("nonexistent-elephant-topic", m, None, None, limit=8)
assert d["pages"] == [] and d["surfaces_present"] == ["PyAutoMemory"]


def test_bib_file_itself_is_not_a_surface(tmp_path):
m = _memory_repo(tmp_path)
(m / "bibliography" / "demo.bib").write_text("@article{Quasar2020}\n")
files = {f.name for _, _, f in _memory.surfaces(m, None, None)}
assert "demo.bib" not in files # metadata, not digest text (by design)


def test_conductor_pointers_name_real_layout_paths(tmp_path):
"""The feature/bug conductors print `PyAutoMemory/wiki/<d>/index.md`
pointers built from the policy wiki names — those names must be the
wiki/<domain>/ layout, and the printed shape must resolve in a real
checkout when one is present."""
sys.path.insert(0, str(Path(__file__).resolve().parents[1]
/ "agents" / "faculties" / "sizing"))
import _sizing
live = Path(__file__).resolve().parents[2] / "PyAutoMemory"
for wiki in _sizing.MEMORY_WIKIS:
assert not wiki.endswith("_wiki")
if live.is_dir():
assert (live / "wiki" / wiki / "index.md").is_file(), (
f"policy names sub-wiki '{wiki}' but "
f"PyAutoMemory/wiki/{wiki}/index.md does not exist")
10 changes: 7 additions & 3 deletions tests/test_policy_seams.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ def test_aliases_normalise_known_mentions():

def test_memory_wikis_route_science_vocabulary():
wikis = _sizing.MEMORY_WIKIS
assert "lens" in wikis["lensing_wiki"]
assert "sampler" in wikis["methods_wiki"]
# Keys are the wiki/<domain>/ names (the *_wiki root layout is retired).
assert "lens" in wikis["lensing"]
assert "sampler" in wikis["methods"]
assert not any(k.endswith("_wiki") for k in wikis)
assert _sizing.SCIENCE_KEYWORDS # derived, non-empty


Expand All @@ -65,7 +67,9 @@ def test_feature_default_wiki_loads():
sys.path.insert(0, str(BRAIN_HOME / "agents" / "conductors" / "feature"))
import _feature

assert _feature.TARGET_DEFAULT_WIKI["autolens"] == "lensing_wiki"
assert _feature.TARGET_DEFAULT_WIKI["autolens"] == "lensing"
# The Nerves rename is covered both ways (legacy autoconf + autonerves).
assert _feature.TARGET_DEFAULT_WIKI["autonerves"] == "methods"


def test_refactor_test_witness_loads():
Expand Down
Loading