Repository navigation
Description
Overview
Phase 2 of the cortex-checkin epic. Phase 1 shed the review-slot and gate apparatus and left the check-in primitives decoupled (run_pull, score_phase, collect_report, apply_ops, the payload builders, dashboard --apply). This phase composes them into one door — pyauto-brain cortex checkin — so that "check in on my science" is a single command: pull every active project, score every live phase, move what finished, regenerate the board, optionally push the ledger, and print a summary keyed by project that a fresh chat can paste from. It also installs /cortex, which skills/COMMANDS.md has advertised since the conductor was born but which was never symlinked, and rewrites the skill body so it is the check-in sequence rather than a verb menu.
Stacked on the unmerged phase-1 PRs (PyAutoBrain#348, PyAutoCortex#10) — both repos branch from feature/cortex-checkin-p1-shed-review-slot and the PRs target it; they retarget to main when phase 1 merges.
Plan
- Add a
checkinverb to the Cortex conductor that composes phase 1's primitives: sync → score → render → (optionally) push → summarise. --dry-runlists everystatus: activeproject with the exact<local_path>/<sync_cli> pullit would run and every live phase it would score; it touches nothing and never reaches the cluster.--applyruns each project's own sync CLI with its output streamed, isolates per-project failures (a non-zero pull is recorded and the sweep continues), writes/merges<pull root>/.cortex/pull.json, scores everysubmitted|runningphase, applies the state moves, and regeneratesdashboard.md/.html.--push(guarded:gh auth statussucceeds and the Cortex checkout is clean onmain) cutsclaude/checkin-<date>from a freshorigin/main, refuses a code-classified diff, commits ledger paths explicitly, pushes, and states thatledger_merge.ymlwill land it. Nevermain, never--force.- The last thing printed is the by-project summary: state counts, each live/awaiting/ready phase with its health verdict and the copy-ready prompt that already exists for that state, the project's paths and the run directories the scorer touched.
- Rewrite
skills/cortex/SKILL.md+cortex.mdso the body is the check-in sequence (verbs demoted to an appendix), refresh the stale/cortexrow inCOMMANDS.mdand the conductor'sAGENTS.md, install the slash command viabin/install.sh(Claude commands + committed.claude/.codexdiscovery), and add a short "check in" pointer to PyAutoCortex's README/AGENTS plus a## Check-insection inREFERENCE.mddocumenting the.cortex/pull.jsonkeys. - Brain tests cover the dry-run listing, per-project pull-failure isolation, manifest write/merge, the no-push path and the push refusal on a code-classified diff.
Detailed implementation plan
Affected Repositories
- PyAutoBrain (primary) — the conductor, the skill, the tests, the installed command
- PyAutoCortex — docs only (README/AGENTS pointer,
REFERENCE.md"Check-in")
Branch Survey
| Repository | Current Branch | Dirty? |
|---|---|---|
| ./PyAutoBrain | main | clean |
| ./PyAutoCortex | main | clean |
Suggested branch: feature/cortex-checkin-p2-the-door, cut from origin/feature/cortex-checkin-p1-shed-review-slot in both repos (stacked; PRs target that branch).
Implementation Steps
agents/conductors/cortex/_cortex.py— new section# ---- the check-in ----holding:checkin_projects(mod, root, projects, only)→ the ordered project keys: every row withstatus: active, plus any project owning a phase insubmitted|running, narrowed by--project.pull_cmd(row)→(cmd, cwd)or a reason string when the row has nopullverb.run_pull_streamed(projects, keys)→ runs each CLI with output inherited (not captured — a pull takes minutes), returns{key: (rc, note)}; a non-zero exit or anOSErroris recorded and the sweep continues.pull_root(row)→mirrorif set elselocal_path;write_pull_manifest(root_dir, key, cmd, rc, phases_live)→ merges{project, pulled_at, cmd, rc, phases_live}into any existing.cortex/pull.json(autolens_profiling's own sync CLI writes a richer one — keys are merged, never clobbered).project_digest(mod, key, row, rows, scored)→ one project's summary block;checkin_summary(...)→ the whole by-project summary (printed last).push_preflight(root)→(ok, reason)fromgh auth status+ branchmain+ clean tree, evaluated before any write;push_ledger(root, paths, date)→ fetch,checkout -b claude/checkin-<date> origin/main,ledger_merge.py classify <paths>(refuse on code),add -- <paths>, commit, push, print the auto-merge expectation.cmd_checkin(root, mod, a)→ the door.
build_parser()—checkinsub-parser:--dry-run,--apply,--push/--no-push,--project KEY(repeatable),--skip-pull,--refreshed ISO,--cortex DIR. Default is dry-run; push defaults to the preflight verdict and the resolution is printed.main()— dispatchcheckinbesidecollect, with the sameCortexError/OSErrorhandling.- Module docstring +
agents/conductors/cortex/AGENTS.md—checkindocumented as the front door,collectas the primitive it composes. skills/cortex/SKILL.md+skills/cortex/cortex.md— body becomes the check-in sequence; the verb table moves to an appendix; the staleplan/gates --graderows (retired in phase 1) go.skills/COMMANDS.md— the/cortexrow names the check-in, not the retired verbs.tests/test_cortex_conductor.py— a# --- the check-in ---block over the existingboardfixture: dry-run listing, per-project pull failure isolation (a fakesync_cliexiting 1 for one project only), manifest write + merge of an existing manifest, the no-push path, and the push refusal on a code-classified diff (a throwaway git repo, no remote).bash bin/install.sh— installs~/.claude/commands/cortex.md+ the Claude/Codex skills;--write-project-discoveryadds the committed.claude/.codexlinks for the cortex skill.- PyAutoCortex:
README.md+AGENTS.mdshort "check in" pointer;REFERENCE.mdnew## Check-insection documenting the.cortex/pull.jsonkeys and the merge rule.
Key Files
PyAutoBrain/agents/conductors/cortex/_cortex.py— the conductor (the door lands here)PyAutoBrain/agents/conductors/cortex/AGENTS.md— the conductor's own docPyAutoBrain/skills/cortex/{SKILL.md,cortex.md}— the/cortexbodyPyAutoBrain/skills/COMMANDS.md— the command veneer indexPyAutoBrain/tests/test_cortex_conductor.py,PyAutoBrain/tests/_cortex_board.py— the fixture and testsPyAutoCortex/{README.md,AGENTS.md,REFERENCE.md}— the pointer and the manifest contract
Testing
python3 -m pytest tests/test_cortex_conductor.py in the Brain worktree (with PYAUTO_CORTEX pointed at the Cortex worktree), plus the full Brain suite. No real hpc/sync pull is run at any point — every pull under test is a fake sync_cli script; the only live exercise is checkin --dry-run, which SSHes nowhere. The known worktree-only failure test_cortex_conductor::test_a_fixture_tree_finds_the_schema_its_checkout_ships is expected.
Original Prompt
Click to expand starting prompt
# `/cortex` — the one check-in door: pull every active project, score, render, push, hand back prompts
Type: feature
Target: pyautobrain
Repos:
- PyAutoBrain
- PyAutoCortex
Themes:
- mind-workflow
Difficulty: medium
Autonomy: supervised
Priority: high
Status: draft
Consequence: judge
Witness: `pyauto-brain cortex checkin --dry-run` lists every `status: active` project in `projects.yaml` with the exact `<local_path>/<sync_cli> pull` it would run and every live phase it would score; `pyauto-brain cortex checkin --apply --no-push` on the live tree pulls each (a failing pull is reported per project and does not abort the sweep), writes `<local_path>/.cortex/pull.json` for each project pulled, scores every submitted/running phase, applies `running → pulled → awaiting-ruling`, regenerates `dashboard.md`/`.html` (`--check` current), and prints a summary keyed BY PROJECT (state counts, live phases with health, the existing rule / launch / jobs prompts) that a fresh chat can paste from; with `--push` it commits the ledger diff on a `claude/checkin-<YYYY-MM-DD>` branch with explicit paths, pushes, and reports that `ledger_merge.yml` will land it; `~/.claude/commands/cortex.md` exists and `/cortex` in Claude reads `skills/cortex/SKILL.md`, whose body is the check-in sequence, not a verb menu; Brain + Cortex tests cover dry-run, per-project pull failure isolation, manifest write and the no-push path
Review-minutes: 20
Unattended: ready
Epic: cortex-checkin
Phase: 2
Filed: 2026-09-03
Phase 2 of `cortex-checkin`. Branch from phase 1's branches (stacked) if they
are unmerged. Two PRs (Brain, Cortex — the Cortex side is docs + a
`checkin` pointer in README/AGENTS + any `check` rule the manifest needs).
## The door — `pyauto-brain cortex checkin`
Composes the primitives phase 1 kept. Flags: `--dry-run`, `--apply`,
`--push` / `--no-push` (default: `--no-push` in a cloud session, ask-free
`--push` on a laptop where `gh auth status` succeeds — state the rule),
`--project <key>` to narrow, `--skip-pull` for an offline re-score.
1. **Sync.** Iterate `projects.yaml` rows with `status: active` (plus any row
that owns a phase in `submitted|running`). For each, run
`<local_path>/<sync_cli> pull` (the verb every CLI implements — verified
2026-09-03 across all seven), streaming its output under a project
heading. A non-zero exit is recorded per project and the sweep continues.
After a successful pull write `<local_path>/.cortex/pull.json`
`{project, pulled_at, cmd, rc, phases_live: [...]}` so the scorer's
checkpoint leg stops reading UNOBSERVABLE everywhere except
autolens_profiling (which already writes its own — do not clobber a
richer manifest; merge keys).
2. **Score.** Run the decoupled `collect` scorer over every submitted/running
phase; `--apply` performs the state moves. No batch record.
3. **Render + push.** `dashboard --apply`; then, with `--push`, in the Cortex
checkout: `git checkout -b claude/checkin-<date>` from a fresh `origin/main`,
commit the phase files + dashboard pages with explicit paths, push, and
print the auto-merge expectation (`ledger_merge.yml`). If the diff
classifies as code (`scripts/ledger_merge.py classify <paths>`), stop
before pushing and say why. Never push `main` directly, never force.
4. **Summarise, by project.** For each active project: state counts, each
live/awaiting/ready phase with its health verdict and the copy-ready
prompt that already exists for that state (`_ruling_payload`,
`launch_payload`, `_live_payload`), the project's `local_path`, `mirror`,
`ral_root` and the run directories the scorer touched. Phase 3 enriches
this; here it must at least exist and be keyed by project. Print it as
the LAST thing so a chat sees it above the fold.
## Install `/cortex`
The slash command is advertised in `skills/COMMANDS.md` but
`~/.claude/commands/cortex.md` does not exist. Rewrite
`skills/cortex/SKILL.md` + `cortex.md` so the body IS the check-in
sequence (run `checkin`, read the summary, offer the prompts; the individual
verbs become an appendix) and install the symlink the same way the other 29
commands are installed (find the installer — PyAutoBrain owns discovery per
PyAutoMind/AGENTS.md — and add `cortex`; if installation is a documented
manual step, do it and document it). Codex discovery likewise if the others
have it.
## Guardrails
Never arm a timer, subscription, cron or loop; the door runs once and ends.
Never touch `rulings/` (append-only, human's turn). `hpc/sync pull` may take
minutes per project — stream output, do not buffer. RAL is reached only via
the projects' own CLIs; the door adds no SSH of its own.
Activity
Jammy2211 commentedon Sep 4, 2026
Shipped to PR-open (merge stays human).
feature/cortex-checkin-p2-the-door→ feat(cortex): one check-in door — pull, score, render, push, summarise by project #350, basefeature/cortex-checkin-p1-shed-review-slot(stacked on maintenance: retire the science review slot from the batch conductor #348)feature/cortex-checkin-p2-the-door→ docs: the check-in door and the .cortex/pull.json contract PyAutoCortex#11, basefeature/cortex-checkin-p1-shed-review-slot(stacked on PyAutoCortex#10)Both retarget to
mainonce phase 1 merges. Merge order: PyAutoBrain#348 → PyAutoCortex#10 → PyAutoBrain#350 → PyAutoCortex#11.The CLI as shipped
--dry-runis the default and reaches nothing.--pushresolves from the rule —gh auth statussucceeds and the Cortex is clean onmain— read before any write, and stated in the output either way.Live check, no RAL traffic:
checkin --dry-runon the real tree lists 3 active projects (euclid,inference_programme,subhalo_validation), the exactcd … && hpc/sync pullfor each, and 2 live phases (bothsubhalo_validation).--applywas exercised only against fixtures — a real pull is minutes of cluster traffic and the human's call.Tests: Brain 874 passed / 3 failed → one was this branch's (
test_gh_surface, fixed); the twotest_branch_sweepfailures reproduce unchanged on the phase-1 base. Targeted re-run: 68 passed. Cortex:cortex.py checkOK, 115 passed, dashboard current./cortexinstalled:bash PyAutoBrain/bin/install.shcreated~/.claude/commands/cortex.md,~/.claude/skills/cortexand~/.codex/skills/cortex(and pruned two stale links,register-and-iterate/run-queue, whose skills no longer exist). The installer needed no change — nobody had run it since the skill dir was added.Heart: RED at ship time, unacknowledged —
release validation FAILED (stage integrate)(red) andPyAutoArray: open PR 11d old(yellow). Both are release-chain facts about other repos; neither of these two is in the release chain. PRs opened, nothing merged.Jammy2211 commentedon Sep 4, 2026
Shipped
Phase 2 of the
cortex-checkinepic — the/cortexcheck-in door.9a039d92a5ac2c9c1ebce52636bc3b42acedd4e8284097de3787aac22156dd1337e2c6749a9d5088Both merged to
mainon 2026-09-04, Brain before Cortex, after phase 1(PyAutoBrain#348 / PyAutoCortex#10) had landed. GitHub retargeted both PRs from
the phase-1 branch to
mainautomatically once phase 1 merged.PyAutoBrain#350:
Brain Testsgreen on 3.12 and 3.13,docs / docs-buildgreen. PyAutoCortex#11's effective diff against
mainis three documentationfiles (
AGENTS.md,README.md,REFERENCE.md), which match no path filter ineither Cortex workflow, so no run fired — by design, not a missing check.
Heart was RED at merge time with two reasons — "release validation FAILED
(stage integrate)" and "PyAutoArray: open PR 12d old" — both release-chain facts
about other repos, neither of which is in the release chain. Merged under an
explicit human acknowledgement.
Closed by
/prm.