diff --git a/{{cookiecutter.project_name}}/.github/pull_request_template.md b/{{cookiecutter.project_name}}/.github/pull_request_template.md
index 944e99e..2edff44 100644
--- a/{{cookiecutter.project_name}}/.github/pull_request_template.md
+++ b/{{cookiecutter.project_name}}/.github/pull_request_template.md
@@ -1,23 +1,29 @@
-## Changes
+
-
+**Task:** :
-- ...
+## Deliverables
-## Bug fixes
+
-
+## Method and decisions
-- ...
+
-## New
+| decision | value | by | why |
+| --- | --- | --- | --- |
+| | | | |
-
+## Findings
-- ...
+
-## Related issues
+## Needs you
-
+
-Closes #
+## Related
+
+
diff --git a/{{cookiecutter.project_name}}/AGENTS.md b/{{cookiecutter.project_name}}/AGENTS.md
index 0759c3e..5ce31b0 100644
--- a/{{cookiecutter.project_name}}/AGENTS.md
+++ b/{{cookiecutter.project_name}}/AGENTS.md
@@ -34,3 +34,6 @@ test config.
| Run Python | `pixi run python script.py` |
| Run tests | `pixi run test` |
| Add a conda / PyPI package | `pixi add ` / `pixi add --pypi ` |
+
+The `gpu` environment (Linux with NVIDIA) adds rapids-singlecell: use it over scanpy for neighbors, UMAP and
+clustering on more than about 100k cells, in a GPU job.
diff --git a/{{cookiecutter.project_name}}/README.md b/{{cookiecutter.project_name}}/README.md
index 23d6b2d..42af25f 100644
--- a/{{cookiecutter.project_name}}/README.md
+++ b/{{cookiecutter.project_name}}/README.md
@@ -153,12 +153,9 @@ Or edit `pixi.toml` directly and run `pixi install`.
📓 Data and notebook conventions
- **Notebook naming**: `[INITIALS]-[YYYY]-[MM]-[DD]_description.ipynb`
-- **Data layout** (one folder per dataset, gitignored):
- - `data//raw/` — bytes as they arrived; never written by analysis
- - `data//resources/` — curated inputs that are not data: gene lists, marker tables
- - `data//processed/` — objects code loads to do new work, as AnnData `.zarr`
- - `data//results/` — a notebook's own outputs, file names prefixed with the notebook's stem
-- **Figures**: `figures//`
+- **Data layout and the notebook lane**: the analysis-workflow skill's
+ [Data](https://github.com/quadbio/analysis-workflow/blob/main/skills/analysis-workflow/SKILL.md#data) and
+ [Two lanes](https://github.com/quadbio/analysis-workflow/blob/main/skills/analysis-workflow/SKILL.md#two-lanes)
- **Import paths** via the local package:
```python
diff --git a/{{cookiecutter.project_name}}/REVIEW_GUIDE.md b/{{cookiecutter.project_name}}/REVIEW_GUIDE.md
index bc5f484..ec2ade7 100644
--- a/{{cookiecutter.project_name}}/REVIEW_GUIDE.md
+++ b/{{cookiecutter.project_name}}/REVIEW_GUIDE.md
@@ -4,9 +4,8 @@ PR review playbook for **review agents running on GitHub**. Imperative voice.
**Scope: review only.** Comment and suggest. Do not push commits or apply fixes.
-> Everything above "This repo" comes from the analysis template, which takes it from the analysis-workflow
-> plugin; change it there and pull it with `cruft update`. Reviewers cannot load the plugin, which is why this
-> copy exists.
+> Everything above "This repo" comes from the analysis template; change it there and pull it with `cruft update`.
+> It tells reviewers, who cannot load the analysis-workflow plugin, what to check of its rules.
The code has usually already run. That is not a reason to lower the bar: requiring a rerun in better shape is a
normal outcome. Say what to redo, not just what was wrong.
@@ -35,24 +34,24 @@ A write to a working object goes through `commit_adata`, gated behind a dry run.
### 2. Promotions, which leave no diff
`data/` is gitignored, so an object written into `data//processed/` appears nowhere in the diff; the task
-README's `Write-back` section is the only trace. The right subdirectory is not guessable. Check that the PR *says*
-where it went and that it was agreed, while moving it is still cheap.
+README's `Write-back` section is the only trace. The right subdirectory is not guessable. Check that the README
+*says* where it went, that the PR body flags it for sign-off and that it was agreed, while moving it is still cheap.
### 3. The task contract
-Agent work belongs in a task directory `analysis//.../_vN/` with a `README.md` naming real inputs,
-outputs and write-back keys. Outputs go through `task_paths(__file__)` to the task's own `results/`, `reports/`,
-`figures/`, `outputs/`. Writes to `data//results/` or the central `figures/` are the human lane and are a
-finding.
+Agent work belongs in a task directory `analysis//.../_vN/`. Check that its README's content is real:
+the actual input files, the deliverables agreed with the human, a short summary of each PR. An edit to an earlier
+task's directory is a finding: analysis moves forward, and a new version names the one it follows. Writes to
+`data//results/` or the central `figures/` are the human lane and are a finding.
Every key committed to a shared object carries the task's version suffix **and** appears in that README: an
unrecorded key can't be traced back, an unsuffixed one collides with the next version.
### 4. Scientific correctness
-The point of the repo. Check that the claim in the PR body follows from what the code computes: the right cells,
-the right grouping, a control where one is needed, and a comparison not confounded by condition, time point,
-sample or batch. A number that reaches a figure is worth more scrutiny than anything below.
+The point of the repo. Check that each finding in the PR body follows from what the code computes: the right cells,
+the right grouping, a control where one is needed, and a comparison not confounded by condition, time point, sample
+or batch. A number that reaches a deliverable is worth more scrutiny than anything below.
### 5. Reinvention
@@ -60,15 +59,18 @@ New code needs a reason to exist. Look outward before accepting it: scverse and
repo's sibling code packages, then earlier task directories; a near-match found by grep counts. Name the
candidate and what's wrong with it rather than concluding nothing fits.
-The acute case is a helper defined twice in one task or copied between tasks: copies drift, and when they compute
-a quantity compared *across* tasks, the result is a wrong conclusion. Copying figure code between versions of one
-task is fine.
+The acute case is a helper defined twice in one task or copied between tasks: copies drift, and when they compute a
+quantity compared *across* tasks, the result is a wrong conclusion. Copying code from the version a task follows is
+fine.
### 6. Conciseness
Prose is reviewed like code. READMEs, docstrings, comments and the PR body: no restating the diff, no filler
preamble, no exhaustive caveats. Padding rots the same way dead code does, and these docs are load-bearing for
-the next agent.
+the next agent. Among the files that keep changing, each fact is written once: findings in the deliverables, the
+overview in the task README, which gives each PR a short summary. A PR's body, laid out by
+`.github/pull_request_template.md`, is its record as of the merge and may state what the deliverables showed then. A
+living file that restates another instead of linking to it is a finding, because the copies drift.
## Do not report
@@ -76,13 +78,15 @@ the next agent.
- Lock files, and anything under `data/`.
- Committed notebook outputs: review changed cells' code, never the output blobs.
- Absolute paths built from `main_checkout()`: task outputs are anchored there deliberately.
+- A task directory's layout and its README's headings: a hook holds them to the plugin's task template.
- Worktree, temp-dir and cwd-relative `data/`/`figures/` path literals in `analysis/` code: a hook blocks them
before the file is written.
## Drift older than the diff
Parts of a repo may predate these rules. When a PR touches such a file, report the drift once at the lowest
-severity and don't block; it gets fixed when a task next touches it. Search the open issues before filing one.
+severity and don't block; it gets fixed when a task next touches it. Earlier task directories are not drift: they
+stay as they are. Search the open issues before filing one.
## This repo