# Build autocti_assistant — the CTI calibration domain assistant cell
Type: feature
Target: autocti_assistant
Repos:
- @autocti_assistant
- @PyAutoBrain
Difficulty: large
Autonomy: supervised
Priority: normal
Status: formalised
Build **autocti_assistant**, the science-assistant cell for CTI calibration with
PyAutoCTI, seeded from the mature reference assistant cells. This follows the
CTI resurrection epic (all six phases merged 2026-07-17 — PyAutoCTI,
autocti_workspace and autocti_workspace_test are fully modern:
`complete/2026/07/cti-resurrection-phase{0..5}.md`), which makes the domain
assistant the natural next organ of the CTI cell line.
## Original request (verbatim)
> can you draft the prompt to write the autocti_assistant, which il will run in
> opus
## Routing / gates (read before starting)
- **Route through the Clone Agent** (`/clone`) at start_dev time for the
CloneDecision: exact-clone vs sibling vs seed. `autolens_assistant` is the
mature reference cell (library-domain assistant, closest shape);
`autofit_assistant` and the ic50_assistant build
(`complete/2026/07/build_ic50_assistant_from_autofit_assistant.md`) are the
precedent runs of this playbook.
- **Repo creation is a human interactive gate** — ask name / org / visibility
as a dedicated question before any `gh repo create`. Suggested default:
`PyAutoLabs/autocti_assistant`, public (matching autolens_assistant /
autofit_assistant).
- **Privacy seam**: PyAutoMemory (`wiki/cti/` — trap physics, the arctic
algorithm, Euclid VIS / HST ACS heritage, per-topic source bibliographies) is
the user's private knowledge base. Consult it (via the memory faculty) for
*pointers and structure*, but a public assistant wiki must be **rebuilt from
the public literature** with verifiable citations — never copy PyAutoMemory
pages into a public repo. Bib entries verbatim from the literature; validate
with the assistant `--check-citations` tooling + link CI (the
autolens_assistant PR#41/#42 pattern).
- **Intake-classification trap** (hit on the ic50 build): bare library mentions
steal Target — this is a **new assistant cell**, not a PyAutoCTI change.
PyAutoCTI is a consumed dependency.
- **Judgment tier throughout**: skills and wiki prose are the product (this is
why it runs in Opus). Mechanical validation runs may be delegated.
## Ground truth the assistant must teach (post-resurrection API only)
Everything is grounded against the live stack — grep
`autocti_workspace/scripts/` (all 118 scripts validated 2026-07-17) and
`PyAutoCTI/AGENTS.md`, never memory of the old API:
- **Plotting is the matplotlib function API**: `aplt.subplot_dataset_1d`,
`aplt.subplot_imaging_ci`, `aplt.figure_*`, `aplt.plot_array`/`plot_yx`,
`aplt.plot_cti_1d`, `*_list` combined subplots. There are **no**
`*Plotter` / `MatPlot*` / `Visuals*` objects.
- **Multi-dataset fits are factor graphs**: `af.AnalysisFactor(prior_model=
model, analysis=...)` per dataset → `af.FactorGraphModel(*factors)` →
`search.fit(model=factor_graph.global_prior_model, analysis=factor_graph)`;
results come back as a list (`result_list[0].max_log_likelihood_fit`).
Analysis summing (`analysis + analysis`) no longer exists.
- **arcticpy install recipe** (a top-3 user question, guaranteed): needs
`libgsl-dev` + a C++ toolchain; `pip install numpy cython` first, then
`pip install arcticpy==2.6 --no-build-isolation --no-deps` — a naive pip
install **downgrades numpy below 2.0**. No-root header workaround in
`PyAutoCTI/AGENTS.md`; CI form in
`autocti_workspace_test/.github/scripts/smoke_install.sh`.
- **Test/fast-mode conventions**: the knob is `PYAUTO_TEST_MODE` (2 = sampler
bypass; `PYAUTOFIT_TEST_MODE` does not exist). Known artifact: identical-
prior ordered-trap models tie at prior medians under the bypass and raise
their own assertion (filed autofit issue) — real runs are fine.
- **Domain surface**: `Dataset1D` / `ImagingCI`, `Layout1D`/`Layout2DCI` +
Region objects, FPR/EPER extraction (`layout.extract`, region strings
`"fpr"/"eper"` in 1D and `"parallel_fpr"`… in 2D), `Clocker1D(express=, roe=)`
vs `Clocker2D(parallel_express=, parallel_roe=)` (different kwargs!),
`CTI1D`/`CTI2D`, trap species + `CCDPhase`, correction
(`remove_cti`), noise scaling / hyper fits, the aggregator
(`ac.agg.Dataset1DAgg` etc. over the consolidated `dataset.fits` format).
## Scope sketch (to be firmed at start_dev / clone-agent time; expect phases)
1. **Seed the cell** from the CloneDecision's reference: AGENTS.md (persona:
CTI-calibration assistant; include the chat handshake — "chat use requires
the GitHub connector; tell me if you can actually read the repo"),
CLAUDE.md pointer, config, citation/link tooling, Makefile/activate
conventions (mind the venv trap: clear PYTHONPATH).
2. **Skills** (`skills/ac_*.md`, grounded per-skill against
autocti_workspace's validated scripts): install (incl. arcticpy),
simulate 1D + charge injection, compose + fit a CTI model (single and
factor-graph multi-dataset), masking + FPR/EPER extraction, correction,
plotting (function API), results + aggregator, workspace navigation,
test-mode/fast-run conventions.
3. **Wiki**: `wiki/core/` (what CTI is, trap physics, FPR/EPER anatomy, the
arctic algorithm, calibration strategy, parallel vs serial) and
`wiki/literature/` (concepts/entities/sources for: Massey/Israel-line CTI
correction, the arctic papers, Euclid VIS CTI calibration, HST ACS CTI
history, trap pumping, CTI as a weak-lensing shape systematic) — public
sources only, every citation verified.
4. **Project profile** (`wiki/project/profile.md`): the resurrection state,
what is and is not wired (release-train wiring pending —
`draft/release/autocti/cti_release_train_wiring.md`), Euclid heritage in
`autocti_workspace_test/legacy/`.
5. **Demonstrations** (the assistant must be able to drive these end-to-end,
and they double as its validation): simulate + calibrate a 1D dataset
(recover the input trap density/timescale), simulate + calibrate a small
charge injection image, correct a dataset and show the residual
improvement, load results through the aggregator and plot.
6. **Validation**: `--check-citations` clean, link CI green, the demonstration
fits run, and a cold-session smoke ("new Opus session + this repo only"
answers an install question and a calibration question correctly).
Overview
Build autocti_assistant, the science-assistant cell for CTI calibration with
PyAutoCTI, seeded from
autolens_assistantvia the Clone Agent. This follows theCTI resurrection epic (all six phases merged 2026-07-17), which left PyAutoCTI,
autocti_workspace(118 validated scripts) andautocti_workspace_testfullymodern — making the domain assistant the natural next organ of the CTI cell line.
Planning surfaced a blocker that gates every future assistant birth, not just
this one:
pyauto-brain clone --applyhard-fails (exit 4) because 39 trackedfiles in the reference cell match no template-boundary pattern. Phase 0 clears it
and adds the guard that stops it recurring.
Plan
(the euclid mode, the JOSS
paper/,.mcp.json, the cosmos_web_ring scripts —all shipped after the boundary was last written) in both places that must
agree: the owning prose and the executable patterns. Add a guard test so the
next feature landing in the reference can't silently re-block births.
--apply --mode lightweight-seed. Born private; flips public after Heart'spublish gate. Register in the body map.
ac_*skills. Grounded per-skill against the 118 validatedworkspace scripts, never API memory.
core/reference pages and aliterature/corpus rebuilt from public sources with verified citations.trap models, plus citation/link/cold-chat gates.
Each phase is its own PR (the CTI resurrection
phase0..phase5precedent).Clone Agent decision
bin/pyauto-brain clone PyAutoCTI --workspace autocti_workspace --reference autolens_assistant:eca130ca(74 public symbols) · Workspace: 118 scripts_clone.pygates--applyon--mode lightweight-seed;exact-cloneanddifferentiated-siblingare v2 and unimplemented (exit 5). The agent's ownnext-action recommends seed-first, and the prompt's scope sketch (no
benchmarks/,paper/,modes/,hpc/) is already seed-shaped.Two decisions worth recording
PyAutoBuild/autobuild/clone_seed.pycreates the newborn private and flipsit public only after Heart's publish gate
(
PyAutoHeart/docs/newborn_validation.md, legs 1–3). That is the machinery'sown gate and matches this prompt's constraint that a newborn is not announced
before its validation legs pass. Because the repo ends public, the privacy
seam stays fully in force: PyAutoMemory
wiki/cti/is consulted for pointersand structure only, never copied.
wiki/cti/is thin — 1 concept, 2 entities, 8 sources. It is abibliography pointer, not a corpus. Phase 3 is real research, not transcription.
Detailed implementation plan
Affected Repositories
Branch Survey
No worktree claims collide (
ep-projection-weights,potential-correction-portare unrelated).
Suggested branch:
feature/autocti-assistantWorktree:
~/Code/PyAutoLabs-wt/autocti-assistant/Implementation Steps
Phase 0 — unblock the birth (
autolens_assistant+PyAutoBrain)The gate, in
agents/conductors/clone/_clone.py:The boundary lives in two places that must agree: the prose in
autolens_assistant/modes/maintainer.md("Assistant-as-template", which ownsthe boundary) and the executable patterns in
_clone.py'sREFERENCE_PROFILES.PyAutoBrain/agents/conductors/clone/_clone.py— extend theautolens_assistantprofile:skills/euclid_*.md,.claude/skills/euclid_*.md,wiki/euclid/*→domain (Euclid strong-lensing science; a newborn regrows its own)
paper/*→ domain (autolens's own JOSS paper)scripts/*_cosmos_web_ring.py→ domain (lensing science scripts).mcp.json→ mixed (results-inspector MCP: structure generic, values domain)autolens_assistant/modes/maintainer.md— mirror the same four judgments intothe "Assistant-as-template" prose.
PyAutoBrain/tests/test_clone_conductor.py— add the guard: assertpartition()over the realautolens_assistantcheckout yields zerounclassified. No such guard exists today; its absence is exactly why three
separate features (euclid mode, JOSS paper, MCP) silently re-blocked births.
Make the trap loud at PR time rather than documenting it.
PyAutoBrain/AGENTS.mdandagents/conductors/clone/AGENTS.mdboth claim the Clone Agent is"analysis-only v0 … writes nothing".
--apply --mode lightweight-seedisimplemented and hands a plan to Build. Correct both.
Phase 1 — birth the seed (
autocti_assistant)PyAutoLabs/autocti_assistant). Nevergh repo createunprompted.bin/pyauto-brain clone PyAutoCTI --workspace autocti_workspace --apply --mode lightweight-seed→ 51 generic + 93 mixed files copied with substitutions
(
autolens_assistant→autocti_assistant,al_→ac_,PyAutoLens→PyAutoCTI,autolens→autocti); 257 domain files become thePENDING.mdgrowth queue.The
al_→ac_derivation ispkg[0]+pkg[4]—autocti[4] isc, so theprompt's
ac_*naming falls out correctly.PyAutoMind/repos.yaml(category: assistant), thenpython3 scripts/repos_sync.py --writeto regenerate the routing tables.Phase 2 — the
ac_*skillsGrounded per-skill against the 118 validated
autocti_workspace/scripts/andPyAutoCTI/AGENTS.md— never API memory. Ground truth the skills must teach(all post-resurrection):
aplt.subplot_dataset_1d,aplt.subplot_imaging_ci,aplt.plot_cti_1d,*_list). There are no*Plotter/MatPlot*/Visuals*objects.af.AnalysisFactor(prior_model=model, analysis=...)per dataset →af.FactorGraphModel(*factors)→search.fit(model=fg.global_prior_model, analysis=fg); results come back as alist. Analysis summing (
analysis + analysis) no longer exists.libgsl-dev+ aC++ toolchain;
pip install numpy cythonfirst, thenpip install arcticpy==2.6 --no-build-isolation --no-deps— a naive pip installdowngrades numpy below 2.0. No-root workaround in
PyAutoCTI/AGENTS.md; CIform in
autocti_workspace_test/.github/scripts/smoke_install.sh.PYAUTO_TEST_MODEis the knob (2 = sampler bypass).PYAUTOFIT_TEST_MODEdoes not exist. Known artifact: identical-prior ordered-trap models tie at
prior medians under the bypass and raise their own assertion; real runs are fine.
Clocker1D(express=, roe=)vsClocker2D(parallel_express=, parallel_roe=)— different kwargs.
Dataset1D/ImagingCI,Layout1D/Layout2DCI+ Regionobjects, FPR/EPER extraction (
layout.extract,"fpr"/"eper"in 1D,"parallel_fpr"… in 2D),CTI1D/CTI2D, trap species +CCDPhase,remove_cti, noise scaling / hyper fits,ac.agg.Dataset1DAggover theconsolidated
dataset.fitsformat.Skills: install (incl. arcticpy), simulate 1D + charge injection, compose+fit
(single and factor-graph), masking + FPR/EPER extraction, correction, plotting,
results + aggregator, workspace navigation, test-mode conventions.
Phase 3 — wiki + project profile
wiki/core/— what CTI is, trap physics, FPR/EPER anatomy, the arcticalgorithm, calibration strategy, parallel vs serial.
wiki/literature/— Massey/Israel-line CTI correction, the arctic papers,Euclid VIS calibration, HST ACS CTI history, trap pumping, CTI as a weak-lensing
shape systematic. Public sources only; every citation verified; bib entries
verbatim from the literature (the autolens_assistant PR#41/Checkpoint-and-continue: supervised runs batch questions instead of blocking #42 pattern).
wiki/project/profile.md— resurrection state, what is/isn't wired (releasetrain pending:
draft/release/autocti/cti_release_train_wiring.md), Euclidheritage in
autocti_workspace_test/legacy/.Phase 4 — demonstrations + validation
Demonstrations double as validation — the assistant must drive these end-to-end:
Gates:
--check-citationsclean, link CI green, the demonstration fits actuallyrun, and Heart leg 4 — the cold-session smoke ("new Opus session + this repo
only" answers an install question and a calibration question correctly).
Key Files
PyAutoBrain/agents/conductors/clone/_clone.py—REFERENCE_PROFILES(boundary patterns),
partition(),apply_seed()PyAutoBrain/tests/test_clone_conductor.py— the new unclassified guardautolens_assistant/modes/maintainer.md— "Assistant-as-template" (owns the boundary)PyAutoBuild/autobuild/clone_seed.py— the Hands primitive that executes the birthPyAutoHeart/docs/newborn_validation.md— the publish gate (legs 1–4)PyAutoMind/repos.yaml+scripts/repos_sync.py— body-map registrationautocti_workspace/scripts/— the 118 validated grounding scriptsVerification
bin/pyauto-brain clone PyAutoCTI --workspace autocti_workspacereports
unclassified 0and exits 0; the new guard test fails when a file isunclassified;
--apply --mode lightweight-seed --no-pushbuilds a seed tree inscratch without creating a repo.
repos_sync.py --writeclean.python autoassistant/audit_skill_apis.pyclean;--check-citationsclean; link CI green.cold chat-surface smoke answers install + calibration questions correctly.
Original Prompt
Click to expand starting prompt