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
4 changes: 3 additions & 1 deletion REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
|---|---|---|
Expand Down
320 changes: 0 additions & 320 deletions projects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
17 changes: 16 additions & 1 deletion scripts/cortex.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}$")
Expand Down Expand Up @@ -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:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_cortex.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
# --------------------------------------------------------------------------- #
Expand Down
Loading