From be69ddb87b13b57e1406f2c7e4cc4014e28302c4 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Wed, 30 Sep 2026 09:56:48 +0100 Subject: [PATCH 1/2] =?UTF-8?q?cortex:=20de-duplicate=20projects.yaml=20?= =?UTF-8?q?=E2=80=94=20drop=20the=20two=20byte-identical=20copies=20introd?= =?UTF-8?q?uced=20by=2025e0168=20(610=20=E2=86=92=20290=20lines,=2017=20ke?= =?UTF-8?q?ys=20unchanged)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lines 292-610 repeated the 11 rows analytic_gaussian..autolens_inference twice more (identical to copy 1 except copy 1 also holds the retired euclid_sersics row). yaml.safe_load kept the last copy, so the parsed key set (17 projects) is unchanged. The trailing blank line left at 291 is dropped too, so the file is 290 lines ending in a single newline. Co-Authored-By: Claude Fable 5.1 --- projects.yaml | 320 -------------------------------------------------- 1 file changed, 320 deletions(-) diff --git a/projects.yaml b/projects.yaml index 3d0d535..9a6ab51 100644 --- a/projects.yaml +++ b/projects.yaml @@ -288,323 +288,3 @@ euclid_sersics: partition: ral status: retired note: "retired 2026-09-25: retire euclid_sersics as well" - -analytic_gaussian: - remote: none - local_path: /mnt/c/Users/Jammy/Science/analytic_gaussian - ral_root: /mnt/ral/jnightin/analytic_gaussian - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, logs, sync, status, submit, push-submit, jobs, sacct, cancel, tail, du, check] - ledger: wiki/project/state.md - assistant: autofit_assistant - witness_file: results/**/*.json - partition: ral - status: active - note: "born 2026-09-09 as the graphical-ep campaign's phase-1 keystone at ensemble scale; benchmark model with a closed-form posterior, borrowed from autofit_workspace_test scripts/graphical (PR #92 lineage); CPU-only, no dataset (every draw is simulated in memory from its seed); remote none until the human runs gh repo create PyAutoLabs/analytic_gaussian --private" - -ep_toy_gaussian: - remote: PyAutoLabs/ep_toy_gaussian - local_path: /mnt/c/Users/Jammy/Science/ep_toy_gaussian - ral_root: /mnt/ral/jnightin/ep_toy_gaussian - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, logs, sync, status, submit, push-submit, jobs, sacct, cancel, tail, du, check] - ledger: wiki/project/state.md - assistant: autofit_assistant - witness_file: results/**/*.json - partition: ral - status: active - note: "born 2026-09-10 as the graphical-ep campaign's confidence test on the PyAutoFit#1405 collapse toy at N=50: joint BlackJAX NUTS vs EP x3 on identical data; model and EP settings verbatim from complete/2026/07 ep_toy_diagnostic; CPU-only, data simulated in memory from its seed; remote PyAutoLabs/ep_toy_gaussian (private) created 2026-09-10" - -# --------------------------------------------------------------------------- # -# dormant — git repos only. The non-git trees (subhalo, euclid_group, z_*) are -# storage, not projects, and aris_PJ011646 is an assistant clone; none get a -# row. `ral_root` is the planned path and `sync_verbs` is unverified on every -# row below — each note says so. -# --------------------------------------------------------------------------- # -profiling: - remote: none - local_path: /mnt/c/Users/Jammy/Science/profiling - ral_root: /mnt/ral/jnightin/profiling - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "2026-05 checkpointed sweep harness, PyAutoNSS venv; name collides with autolens_profiling; ral_root planned, sync_verbs unverified" - -cowls_diana: - remote: none - local_path: /mnt/c/Users/Jammy/Science/cowls_diana - ral_root: /mnt/ral/jnightin/cowls_diana - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "local git, no remote; ral_root planned, sync_verbs unverified" - -subhalo_simulations: - remote: none - local_path: /mnt/c/Users/Jammy/Science/subhalo_simulations - ral_root: /mnt/ral/jnightin/subhalo_simulations - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "git init, zero commits, 21 GB; ral_root planned, sync_verbs unverified" - -slope_hierarchy: - remote: Jammy2211/slope_hierarchy - local_path: /mnt/c/Users/Jammy/Science/z_projects_complete/slope_hierarchy - ral_root: /mnt/ral/jnightin/slope_hierarchy - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: retired - note: "retired 2026-09-08: wrapped up 2026-07-22 at N=5; succeeded by slope_hierarchy_scale; tree vaulted under z_projects_complete/" - -slope_hierarchy_scale: - remote: PyAutoLabs/slope_hierarchy_scale - local_path: /mnt/c/Users/Jammy/Science/slope_hierarchy_scale - ral_root: /mnt/ral/jnightin/slope_hierarchy_scale - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, sync, status, submit, push-submit, jobs, tail, check] - ledger: wiki/project/state.md - assistant: autolens_assistant - witness_file: results/**/*.json - partition: both - status: active - note: "born 2026-09-08 as graphical-ep phase 3, code borrowed from slope_hierarchy (vaulted under z_projects_complete/); private remote created 2026-09-08" - -pj011646: - remote: Jammy2211/PJ011646 - local_path: /mnt/c/Users/Jammy/Science/PJ011646 - ral_root: /mnt/ral/jnightin/PJ011646 - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "personal remote, recorded as a fact — not a PyAutoLabs repo; ral_root planned, sync_verbs unverified" - -concr: - remote: Jammy2211/cosmology_and_cancer - local_path: /mnt/c/Users/Jammy/Science/concr - ral_root: /mnt/ral/jnightin/concr - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "personal remote Jammy2211/cosmology_and_cancer, recorded as a fact; ral_root planned, sync_verbs unverified" - -ic50_workspace: - remote: Jammy2211/ic50_workspace - local_path: /mnt/c/Users/Jammy/Science/ic50_workspace - ral_root: /mnt/ral/jnightin/ic50_workspace - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, logs, sync, push-data-init, pull-full, status, submit, push-submit, jobs, sacct, cancel, wait-and-pull, tail, du, check, clear-logs] - ledger: NOTES.md - assistant: none - witness_file: results/**/*.json - partition: ral - status: active - note: "personal remote, recorded as a fact — not a PyAutoLabs repo; activated 2026-09-09 for graphical-ep phase 4, ral_root created and first runs submitted; NOTES.md predates the graphical/HPC work and needs a refresh" - -autolens_inference: - remote: PyAutoLabs/autolens_inference - local_path: /home/jammy/Code/PyAutoLabs/lens/autolens_inference - ral_root: /mnt/ral/jnightin/autolens_inference - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull, logs, status, submit, jobs, sacct, cancel, tail, du, check] - ledger: wiki/project/state.md - assistant: autolens_assistant - witness_file: results/**/*.json - partition: both - status: active - note: "born 2026-09-10 as the from-scratch restart of inference_programme (retired PyAutoCortex#22); nothing inherited; phase 1 = birth (PyAutoMind#399), first task slam_hst_base" - -analytic_gaussian: - remote: none - local_path: /mnt/c/Users/Jammy/Science/analytic_gaussian - ral_root: /mnt/ral/jnightin/analytic_gaussian - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, logs, sync, status, submit, push-submit, jobs, sacct, cancel, tail, du, check] - ledger: wiki/project/state.md - assistant: autofit_assistant - witness_file: results/**/*.json - partition: ral - status: active - note: "born 2026-09-09 as the graphical-ep campaign's phase-1 keystone at ensemble scale; benchmark model with a closed-form posterior, borrowed from autofit_workspace_test scripts/graphical (PR #92 lineage); CPU-only, no dataset (every draw is simulated in memory from its seed); remote none until the human runs gh repo create PyAutoLabs/analytic_gaussian --private" - -ep_toy_gaussian: - remote: PyAutoLabs/ep_toy_gaussian - local_path: /mnt/c/Users/Jammy/Science/ep_toy_gaussian - ral_root: /mnt/ral/jnightin/ep_toy_gaussian - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, logs, sync, status, submit, push-submit, jobs, sacct, cancel, tail, du, check] - ledger: wiki/project/state.md - assistant: autofit_assistant - witness_file: results/**/*.json - partition: ral - status: active - note: "born 2026-09-10 as the graphical-ep campaign's confidence test on the PyAutoFit#1405 collapse toy at N=50: joint BlackJAX NUTS vs EP x3 on identical data; model and EP settings verbatim from complete/2026/07 ep_toy_diagnostic; CPU-only, data simulated in memory from its seed; remote PyAutoLabs/ep_toy_gaussian (private) created 2026-09-10" - -# --------------------------------------------------------------------------- # -# dormant — git repos only. The non-git trees (subhalo, euclid_group, z_*) are -# storage, not projects, and aris_PJ011646 is an assistant clone; none get a -# row. `ral_root` is the planned path and `sync_verbs` is unverified on every -# row below — each note says so. -# --------------------------------------------------------------------------- # -profiling: - remote: none - local_path: /mnt/c/Users/Jammy/Science/profiling - ral_root: /mnt/ral/jnightin/profiling - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "2026-05 checkpointed sweep harness, PyAutoNSS venv; name collides with autolens_profiling; ral_root planned, sync_verbs unverified" - -cowls_diana: - remote: none - local_path: /mnt/c/Users/Jammy/Science/cowls_diana - ral_root: /mnt/ral/jnightin/cowls_diana - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "local git, no remote; ral_root planned, sync_verbs unverified" - -subhalo_simulations: - remote: none - local_path: /mnt/c/Users/Jammy/Science/subhalo_simulations - ral_root: /mnt/ral/jnightin/subhalo_simulations - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "git init, zero commits, 21 GB; ral_root planned, sync_verbs unverified" - -slope_hierarchy: - remote: Jammy2211/slope_hierarchy - local_path: /mnt/c/Users/Jammy/Science/z_projects_complete/slope_hierarchy - ral_root: /mnt/ral/jnightin/slope_hierarchy - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: retired - note: "retired 2026-09-08: wrapped up 2026-07-22 at N=5; succeeded by slope_hierarchy_scale; tree vaulted under z_projects_complete/" - -slope_hierarchy_scale: - remote: PyAutoLabs/slope_hierarchy_scale - local_path: /mnt/c/Users/Jammy/Science/slope_hierarchy_scale - ral_root: /mnt/ral/jnightin/slope_hierarchy_scale - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, sync, status, submit, push-submit, jobs, tail, check] - ledger: wiki/project/state.md - assistant: autolens_assistant - witness_file: results/**/*.json - partition: both - status: active - note: "born 2026-09-08 as graphical-ep phase 3, code borrowed from slope_hierarchy (vaulted under z_projects_complete/); private remote created 2026-09-08" - -pj011646: - remote: Jammy2211/PJ011646 - local_path: /mnt/c/Users/Jammy/Science/PJ011646 - ral_root: /mnt/ral/jnightin/PJ011646 - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "personal remote, recorded as a fact — not a PyAutoLabs repo; ral_root planned, sync_verbs unverified" - -concr: - remote: Jammy2211/cosmology_and_cancer - local_path: /mnt/c/Users/Jammy/Science/concr - ral_root: /mnt/ral/jnightin/concr - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull] - ledger: README.md - assistant: none - witness_file: results/**/*.json - partition: both - status: dormant - note: "personal remote Jammy2211/cosmology_and_cancer, recorded as a fact; ral_root planned, sync_verbs unverified" - -ic50_workspace: - remote: Jammy2211/ic50_workspace - local_path: /mnt/c/Users/Jammy/Science/ic50_workspace - ral_root: /mnt/ral/jnightin/ic50_workspace - mirror: none - sync_cli: hpc/sync - sync_verbs: [push, pull, logs, sync, push-data-init, pull-full, status, submit, push-submit, jobs, sacct, cancel, wait-and-pull, tail, du, check, clear-logs] - ledger: NOTES.md - assistant: none - witness_file: results/**/*.json - partition: ral - status: active - note: "personal remote, recorded as a fact — not a PyAutoLabs repo; activated 2026-09-09 for graphical-ep phase 4, ral_root created and first runs submitted; NOTES.md predates the graphical/HPC work and needs a refresh" - -autolens_inference: - remote: PyAutoLabs/autolens_inference - local_path: /home/jammy/Code/PyAutoLabs/lens/autolens_inference - ral_root: /mnt/ral/jnightin/autolens_inference - mirror: none - sync_cli: hpc/sync - sync_verbs: [pull, logs, status, submit, jobs, sacct, cancel, tail, du, check] - ledger: wiki/project/state.md - assistant: autolens_assistant - witness_file: results/**/*.json - partition: both - status: active - note: "born 2026-09-10 as the from-scratch restart of inference_programme (retired PyAutoCortex#22); nothing inherited; phase 1 = birth (PyAutoMind#399), first task slam_hst_base" From ccc98011a33ae935889e09ffbe2302b643247e99 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Wed, 30 Sep 2026 09:58:18 +0100 Subject: [PATCH 2/2] cortex: reject duplicate project keys in projects.yaml (load_projects guard + test + REFERENCE note) yaml.safe_load silently keeps the last of a repeated mapping key, which is how 25e0168 tripled 11 rows without `cortex.py check` noticing. parse_projects now scans the raw column-0 keys before safe_load and reports each repeat as `projects.yaml: duplicate project key 'X' (lines a, b, c)`; the rest of the file is still validated (non-fatal, like the per-row problems). Run against the pre-fix 610-line file it names all 11 tripled keys. Co-Authored-By: Claude Fable 5.1 --- REFERENCE.md | 4 +++- scripts/cortex.py | 17 ++++++++++++++++- tests/test_cortex.py | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 62ed857..a89ce1f 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -106,7 +106,9 @@ writes nothing. The science body map. **Code, not ledger** — `sync_cli` and `local_path` are paths a conductor executes under. Real YAML read with `yaml.safe_load`; the -shape is validated by `cortex.py`: +shape is validated by `cortex.py`. A project key may appear only once — since +`yaml.safe_load` silently keeps the last of a repeated key, `cortex.py check` +scans the raw column-0 keys and reports every duplicate with its line numbers: | Field | Value | Notes | |---|---|---| diff --git a/scripts/cortex.py b/scripts/cortex.py index 02a2f00..9001393 100644 --- a/scripts/cortex.py +++ b/scripts/cortex.py @@ -77,6 +77,7 @@ # grammars # --------------------------------------------------------------------------- # PROJECT_KEY_RE = re.compile(r"^[a-z][a-z0-9_]*$") +PROJECT_KEY_LINE_RE = re.compile(r"^([a-z][a-z0-9_]*):\s*(#.*)?$") LEDGER_FILE_RE = re.compile(r"^projects/([a-z][a-z0-9_]*)\.md$") DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}$") WALL_RE = re.compile(r"^\d+:\d{2}$") @@ -185,8 +186,22 @@ def _replace_section(text: str, name: str, body: "list[str]") -> str: # --------------------------------------------------------------------------- # # projects.yaml # --------------------------------------------------------------------------- # +def _duplicate_key_problems(text: str) -> "list[str]": + """`yaml.safe_load` silently keeps the last of a repeated mapping key, so a + project row pasted twice would vanish from view: scan the raw column-0 + keys first and name every repeat with its line numbers.""" + seen: "dict[str, list[int]]" = {} + for n, line in enumerate(text.split("\n"), 1): + m = PROJECT_KEY_LINE_RE.match(line) + if m: + seen.setdefault(m.group(1), []).append(n) + return [f"projects.yaml: duplicate project key {key!r} " + f"(lines {', '.join(map(str, lines))})" + for key, lines in seen.items() if len(lines) > 1] + + def parse_projects(text: str) -> "tuple[dict[str, dict], list[str]]": - problems: "list[str]" = [] + problems: "list[str]" = _duplicate_key_problems(text) try: doc = yaml.safe_load(text) except yaml.YAMLError as e: diff --git a/tests/test_cortex.py b/tests/test_cortex.py index 78bda7a..84ac0b2 100644 --- a/tests/test_cortex.py +++ b/tests/test_cortex.py @@ -222,6 +222,24 @@ def test_projects_yaml_is_validated(tmp_path): assert any("unknown field `colour` on example" in p for p in _problems(root)) +def test_projects_yaml_rejects_duplicate_project_keys(tmp_path): + # yaml.safe_load keeps the last of a repeated key silently; the raw-line + # guard must name the repeat (25e0168 tripled 11 rows this way). + root = _copy(tmp_path) + path = root / "projects.yaml" + text = path.read_text() + lines = text.split("\n") + first = lines.index("example:") + 1 + start = text.index("example:\n") + row = text[start:text.index("\n\n", start) + 1] + path.write_text(text.rstrip("\n") + "\n\n" + row) + second = len(text.rstrip("\n").split("\n")) + 2 + problems = _problems(root) + assert f"projects.yaml: duplicate project key 'example' (lines {first}, {second})" in problems + assert not any("duplicate project key 'single'" in p for p in problems) + assert _problems(SKELETON) == [] + + # --------------------------------------------------------------------------- # # the writing verbs # --------------------------------------------------------------------------- #