From e53cfdb0ae6edd24d928b6d74aacee63edba98a4 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Fri, 10 Jul 2026 11:00:11 +0100 Subject: [PATCH] feat: science projects inherit the PyAuto* API code-gate via refer-back (#47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Create scaffold now generates a thin .claude/settings.json whose PreToolUse(Bash) hook resolves the assistant at runtime ($AUTOLENS_ASSISTANT -> sibling -> sources/ clone) and execs the assistant's validate_pyauto_code.py — nothing vendored, no absolute paths, on by default and fail-open when no assistant clone resolves. The generated AGENTS.md gains a Code gate section with the cross-tool caveat (hooks are Claude Code-only; other harnesses self-enforce via audit_skill_apis.py --code/--file). Validated end-to-end: deny on dead symbol via env-var and sibling resolution, allow on valid symbol, silent fail-open with no assistant. Co-Authored-By: Claude Fable 5 --- skills/start-new-project.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/skills/start-new-project.md b/skills/start-new-project.md index ed44743..841cb0c 100644 --- a/skills/start-new-project.md +++ b/skills/start-new-project.md @@ -76,6 +76,7 @@ reproducible-science subset; generate the thin assistant layer; refer back for e AGENTS.md # thin: project context + refer-back + locate rule (below) CLAUDE.md # one-line `@AGENTS.md` stub .gemini/settings.json # context.fileName -> AGENTS.md + .claude/settings.json # PyAuto* API code-gate via refer-back (below) project.yaml # minimal manifest incl. assistant_ref (below) config/ activate.sh scripts/ # copied above data/ (datasets) @@ -107,6 +108,15 @@ After resolving, compare the clone's commit to `project.yaml`'s `assistant_ref.c differ, mention the provenance drift and offer to re-pin — never block on it and never check out the pinned commit. +## Code gate +This project ships the assistant's PyAuto* **API code-gate** (`.claude/settings.json`): before +Bash runs generated PyAuto* code, a hook resolves the assistant (same order as above) and +validates the symbols against the installed stack, denying code written from memory. It fails +open if no assistant clone is found. Only Claude Code runs `.claude/` hooks — on any other +harness (Codex, Gemini, chat), self-enforce it: run +`python /autoassistant/audit_skill_apis.py --code ""` (or +`--file `) on generated PyAuto* code before executing it; never guess symbols. + ## This project - Context / decisions / results: `wiki/project/` (dated journal + `profile.md`). - Toolchain provenance: `project.yaml` (`assistant_ref`) + per-run `results/manifests/`. @@ -161,6 +171,30 @@ release: { citation_cff: true, license: null, zenodo: planned } source_boundary: { edit_pyauto_source: false } ``` +**`.claude/settings.json`** (generate — the PyAuto* API code-gate via refer-back; **on by +default and fail-open**: if no assistant clone resolves, the hook silently allows): +```json +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "sh -c 'P=\"${CLAUDE_PROJECT_DIR:-.}\"; for d in \"$AUTOLENS_ASSISTANT\" \"$P/../autolens_assistant\" \"$P/sources/autolens_assistant\"; do [ -n \"$d\" ] && [ -f \"$d/.claude/hooks/validate_pyauto_code.py\" ] && exec python3 \"$d/.claude/hooks/validate_pyauto_code.py\"; done; exit 0'" + } + ] + } + ] + } +} +``` +The validator stays in the assistant — `validate_pyauto_code.py` resolves +`audit_skill_apis.py` relative to itself — so the project vendors nothing and bakes in no +absolute paths. The cross-tool caveat (hooks are Claude Code-only; other harnesses +self-enforce) is stated in the generated `AGENTS.md` "Code gate" section above. + **`.gitattributes`**: `* text=auto eol=lf` (+ `*.fits *.png *.npy *.pkl binary`). **`.gitignore`** (exclude data/output/secrets/cloned-assistant; **keep** manifests/figures/journal):