Skip to content

Commit a7ea85f

Browse files
Jammy2211claude
authored andcommitted
Memory faculty: root entry surfaces; retire *_wiki names everywhere (#239)
_memory.py gains the PyAutoMemory root surface (index.md, reading-queue.md, bibliography/README.md, wiki/CLAUDE.md) — the repo's own front door was invisible to the faculty that consumes it; the 722 KB .bib stays excluded by design (documented). The retired pre-2026-07 *_wiki layout names are gone from config/policy.yaml (memory_wikis keys + target_default_wiki values, with autonerves/pyautonerves added beside the legacy autoconf key), from the feature/bug conductors' printed pointers (they named a nonexistent lensing_wiki/index.md), and from the samplers faculty, sampler_pipeline skill (incl. the write instruction that would have created a lint-rejected root methods_wiki/), MIND_TAXONOMY, and the adoption config-surfaces doc (which also mislocated the keyword map). test_policy_seams updated; tests/test_memory_surfaces.py is the faculty's first regression net. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 2b714b8 commit a7ea85f

11 files changed

Lines changed: 140 additions & 32 deletions

File tree

agents/conductors/bug/_bug.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ def emit_human(mode: str, d: dict):
377377
if d["memory_context"]:
378378
print("Relevant context (PyAutoMemory — consult, do not invent):")
379379
for wiki, kws in d["memory_context"].items():
380-
print(f" - {wiki}/index.md ({', '.join(kws)})")
380+
print(f" - PyAutoMemory/wiki/{wiki}/index.md ({', '.join(kws)})")
381381
else:
382382
print("Relevant context: none matched")
383383
print(f"Fix locus: {d['fix_locus']['locus']}")

agents/conductors/feature/MIND_TAXONOMY.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ context when memory has material. Sub-wikis (source: `PyAutoMemory/index.md`):
6767

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

7676
Library targets also pull a default sub-wiki (`autolens`→lensing,
7777
`autogalaxy`→galaxies, `autofit`/`autoarray`/`autoconf`→methods). PyAutoMemory is

agents/conductors/feature/_feature.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ def emit_human(mode: str, decision: dict):
305305
if d["memory_context"]:
306306
print("Relevant context (PyAutoMemory — consult, do not invent):")
307307
for wiki, kws in d["memory_context"].items():
308-
print(f" - {wiki}/index.md ({', '.join(kws)})")
308+
print(f" - PyAutoMemory/wiki/{wiki}/index.md ({', '.join(kws)})")
309309
else:
310310
print("Relevant context: none matched (no scientific context required)")
311311
print(f"Phase decision: {d['phase_decision']}")

agents/faculties/memory/_memory.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
"""agents/faculties/memory/_memory.py — the recall substrate.
33
44
The **memory faculty** is a read-only opinion sink: given a topic/question, it
5-
greps the organism's knowledge surfaces — PyAutoMemory's sub-wikis,
6-
autolens_assistant's skills/wiki pages, and Mind's complete/ records — and
7-
returns a **cited digest**: ranked pages with matching snippets. The consulting
8-
agent reads only the listed pages and synthesises; this script never dumps
9-
content, never writes, and builds no index.
5+
greps the organism's knowledge surfaces — PyAutoMemory's sub-wikis and its
6+
root entry pages (index.md, reading-queue.md, bibliography/README.md, the
7+
wiki schema), autolens_assistant's skills/wiki pages, and Mind's complete/
8+
records — and returns a **cited digest**: ranked pages with matching
9+
snippets. The consulting agent reads only the listed pages and synthesises;
10+
this script never dumps content, never writes, and builds no index.
11+
12+
Deliberately NOT a surface: ``bibliography/*.bib`` — the canonical BibTeX
13+
file is far over ``MAX_FILE_BYTES`` and raw entries are metadata, not digest
14+
text; ``bibliography/README.md`` carries the workflow instead.
1015
1116
Exit codes: 0 digest · 4 no hits or no surface · 5 usage.
1217
"""
@@ -32,6 +37,15 @@ def terms_of(query: str) -> list[str]:
3237
def surfaces(memory: Path | None, assistant: Path | None, mind: Path | None):
3338
"""Yield (surface-name, root, md-file) triples, discovered at query time."""
3439
if memory and memory.is_dir():
40+
# The repo's own entry surfaces: the hand-written index, the reading
41+
# queue, the bibliography workflow, and the wiki schema. Without
42+
# these the front door PyAutoMemory/AGENTS.md points every agent at
43+
# ("index first") was invisible to this faculty (PyAutoBrain#239).
44+
for rel in ("index.md", "reading-queue.md",
45+
"bibliography/README.md", "wiki/CLAUDE.md"):
46+
f = memory / rel
47+
if f.is_file():
48+
yield "PyAutoMemory/root", memory, f
3549
# wiki/<domain>/ is the current layout; root-level *_wiki/ is the
3650
# pre-2026-07 layout, kept for older checkouts and forks.
3751
wikis = sorted(d for d in memory.glob("wiki/*") if d.is_dir())

agents/faculties/samplers/AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ not inventoried.
140140
(prototypes + `_metrics.py` + `output/comparison.txt`),
141141
`autofit_workspace_developer/searches/` (removed-sampler archive),
142142
`autofit_workspace_test/scripts/searches/` (integration scripts).
143-
- **The science**`PyAutoMemory/methods_wiki`:
143+
- **The science**`PyAutoMemory/wiki/methods`:
144144
`concepts/hamiltonian-monte-carlo.md`, `concepts/gpu-nested-sampling.md`,
145145
`concepts/initialization-chaining.md`, `concepts/sampler-benchmarks.md`
146146
(the campaign record), `concepts/nested-sampling.md`. **Privacy seam:**

agents/faculties/samplers/_samplers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def digest(autofit, developer, test, lens_developer=None, profiling=None) -> dic
217217
"instruction": "reason with agents/faculties/samplers/AGENTS.md "
218218
"(sampler<->likelihood match, gradients/JAX, "
219219
"initialization chaining); the science lives in "
220-
"PyAutoMemory/methods_wiki — internal use only, "
220+
"PyAutoMemory/wiki/methods — internal use only, "
221221
"citations never reach public output",
222222
}
223223
minimal = integration = []

config/policy.yaml

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,22 @@ sizing_categories:
2626
extra_workspace_targets: [workspaces]
2727
extra_organism_targets: [autohands]
2828

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

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

6364
# Feature conductor: target -> the sub-wiki consulted by default.
6465
target_default_wiki:
65-
autolens: lensing_wiki
66-
autogalaxy: galaxies_wiki
67-
autofit: methods_wiki
68-
autoarray: methods_wiki
69-
autoconf: methods_wiki
66+
autolens: lensing
67+
autogalaxy: galaxies
68+
autofit: methods
69+
autoarray: methods
70+
autoconf: methods # legacy name — the Nerves repo was PyAutoConf
71+
autonerves: methods
72+
pyautonerves: methods
7073

7174
# Refactor conductor: normalised repo -> the test dir that witnesses
7275
# behaviour preservation.

docs/adoption/config_surfaces.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ framework organs is domain-free logic you pull from upstream.
1313
| `agents/faculties/sizing/_sizing.py` | Brain | The library/workspace repo sets and aliases used to size and route tasks. |
1414
| `agents/conductors/intake/_intake.py``TARGET_SIGNALS` | Brain | Keyword → target-repo routing for raw ideas. |
1515
| `agents/conductors/release/` — the library tuple + `nightly.sh` | Brain | Which libraries the release path drives. |
16-
| `agents/faculties/memory/`the wiki keyword map | Brain | Topic keywords → your Memory's sub-wikis. |
16+
| `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. |
1717
| `heart/readiness.py``DEFAULT_LIBRARIES`; `heart/checks/version_skew.py` — the workspace→(library, package) map | Heart | The release-gate repo sets. |
1818
| `autohands/run_all.py`, `autohands/slow_skip_check.py`, navigator maps | Hands | Which workspaces the validation pipeline runs and skips. |
1919

skills/sampler_pipeline/SKILL.md

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

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

7878
## 3. Promote (or archive)

tests/test_memory_surfaces.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""tests/test_memory_surfaces.py — the memory faculty's corpus (PyAutoBrain#239).
2+
3+
First regression net for `agents/faculties/memory/_memory.py`. What matters:
4+
the root entry surfaces (index.md, reading-queue.md, bibliography/README.md,
5+
wiki/CLAUDE.md) are part of the corpus — they were invisible before #239 even
6+
though PyAutoMemory/AGENTS.md tells every agent to index them first; surface
7+
labels stay repo-name-first (digest()'s exit-4 logic splits on '/'); ranking
8+
and the no-hits path behave; and the conductors' printed PyAutoMemory pointers
9+
name paths that exist under the wiki/<domain>/ layout.
10+
"""
11+
12+
from __future__ import annotations
13+
14+
import sys
15+
from pathlib import Path
16+
17+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]
18+
/ "agents" / "faculties" / "memory"))
19+
20+
import _memory # noqa: E402
21+
22+
23+
def _memory_repo(tmp_path: Path) -> Path:
24+
m = tmp_path / "PyAutoMemory"
25+
(m / "wiki" / "demo" / "concepts").mkdir(parents=True)
26+
(m / "bibliography").mkdir()
27+
(m / "index.md").write_text("# Index\nthe entry surface mentions quasars\n")
28+
(m / "reading-queue.md").write_text("# Reading queue\n\nquasar paper one\n")
29+
(m / "bibliography" / "README.md").write_text("# Bib\nadding a quasar paper\n")
30+
(m / "wiki" / "CLAUDE.md").write_text("# Schema\nstatus flags\n")
31+
(m / "wiki" / "demo" / "concepts" / "quasars.md").write_text(
32+
"---\nstatus: drafted\n---\nquasars lens light\n")
33+
return m
34+
35+
36+
def test_root_entry_surfaces_are_in_the_corpus(tmp_path):
37+
m = _memory_repo(tmp_path)
38+
triples = list(_memory.surfaces(m, None, None))
39+
root_files = {f.name for name, _, f in triples if name == "PyAutoMemory/root"}
40+
assert root_files == {"index.md", "reading-queue.md", "README.md", "CLAUDE.md"}
41+
# the wiki pages still arrive under their sub-wiki label
42+
assert any(name == "PyAutoMemory/demo" for name, _, _ in triples)
43+
44+
45+
def test_labels_stay_repo_name_first(tmp_path):
46+
m = _memory_repo(tmp_path)
47+
for name, _, _ in _memory.surfaces(m, None, None):
48+
assert name.split("/")[0] == "PyAutoMemory"
49+
50+
51+
def test_digest_ranks_and_cites_the_queue(tmp_path):
52+
m = _memory_repo(tmp_path)
53+
d = _memory.digest("quasar reading queue", m, None, None, limit=8)
54+
assert d["surfaces_present"] == ["PyAutoMemory"]
55+
pages = {p["page"] for p in d["pages"]}
56+
assert "reading-queue.md" in pages
57+
assert all(p["hits"] >= 1 and p["snippets"] for p in d["pages"])
58+
59+
60+
def test_no_hits_yields_empty_pages(tmp_path):
61+
m = _memory_repo(tmp_path)
62+
d = _memory.digest("nonexistent-elephant-topic", m, None, None, limit=8)
63+
assert d["pages"] == [] and d["surfaces_present"] == ["PyAutoMemory"]
64+
65+
66+
def test_bib_file_itself_is_not_a_surface(tmp_path):
67+
m = _memory_repo(tmp_path)
68+
(m / "bibliography" / "demo.bib").write_text("@article{Quasar2020}\n")
69+
files = {f.name for _, _, f in _memory.surfaces(m, None, None)}
70+
assert "demo.bib" not in files # metadata, not digest text (by design)
71+
72+
73+
def test_conductor_pointers_name_real_layout_paths(tmp_path):
74+
"""The feature/bug conductors print `PyAutoMemory/wiki/<d>/index.md`
75+
pointers built from the policy wiki names — those names must be the
76+
wiki/<domain>/ layout, and the printed shape must resolve in a real
77+
checkout when one is present."""
78+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]
79+
/ "agents" / "faculties" / "sizing"))
80+
import _sizing
81+
live = Path(__file__).resolve().parents[2] / "PyAutoMemory"
82+
for wiki in _sizing.MEMORY_WIKIS:
83+
assert not wiki.endswith("_wiki")
84+
if live.is_dir():
85+
assert (live / "wiki" / wiki / "index.md").is_file(), (
86+
f"policy names sub-wiki '{wiki}' but "
87+
f"PyAutoMemory/wiki/{wiki}/index.md does not exist")

0 commit comments

Comments
 (0)