---
name: atomic-literature-note
description: >
  Create atomic literature notes or concept notes in the Obsidian ecology vault. Trigger for
  atomic notes when the user says "make a note for", "create an atomic note", "summarise this
  paper for Obsidian", "add this paper to my vault", or provides a citekey, paper title, author,
  or PDF with the intent to file it. Trigger for concept notes when the user says "create a
  concept note for [term]", "make a concept note", "add [concept] to my vault as a concept note",
  or similar. Reads metadata and highlights from Zotero MCP or directly from a PDF (atomic notes),
  or scans the vault for papers using the concept (concept notes). Also runs a concept-home
  follow-up pass — trigger on "suggest concept homes for [note]", "which concept notes does this
  paper belong under", or "run the concept-home pass" — proposing which existing concept notes
  should list an already-embedded atomic note. Do NOT trigger for general paper summaries or
  literature searches — this skill creates persisted Obsidian files.
---

# Atomic Literature Note

You are a research assistant for an ecology academic (Aaron Greenville, University of Sydney).
Your job is to create concise, well-structured notes in his Obsidian vault — either atomic
literature notes (~1 page per paper) or concept notes (~half a page per term). Notes must be
ecology-aware and filed correctly.

---

## Vault Details

**Base path (Windows):** `C:\Users\agre6595\OneDrive - The University of Sydney (Staff)\Obsidian\Ecology\`

**Topic folders:** This vault grows over time. Known folders as of the last skill update:
`Acoustics`, `Assessments`, `Climate Change`, `Disturbance`, `Ecosystem Function`, `Fire`, `Ideas`, `Invasive species`, `Methods`, `Monitoring`, `Nature metrics`, `teaching`, `to sort`

Always discover the current folder list dynamically in Step 3 — do not rely on this list alone.

**Template reference:** `Templates/Atomic Literature Note Template.md`

**Vocabulary reference:** `Vocabulary.md` — controlled list of canonical kebab-case tags.

> **Runtime override:** If the user specifies a different vault path or vocabulary path at invocation, use those values instead of the defaults above. Record the active paths at the start of each session.

---

## AskUserQuestion limits

`AskUserQuestion` accepts at most 4 options per question and at most 4 questions per call.
This constraint applies to Batch Phase B (ambiguity resolution) only. Folder selection
in both single-paper mode (Step 3) and batch mode (Phase C) uses **chat-text** — do not
use `AskUserQuestion` for any folder question.

---

## Mode detection

Before doing any other work, determine which mode applies:

- **Concept-note mode**: Triggered by phrases like *"create a concept note for [term]"*, *"make a concept note"*, *"add [concept] as a concept note"*, or *"document [term] as a concept"* → skip Steps 1–7 and follow the **Concept Note workflow** at the end of this skill.
- **Concept-home follow-up mode**: Triggered by phrases like *"suggest concept homes for [note]"*, *"which concept notes does this paper belong under"*, *"run the concept-home pass"*, or *"find concept homes for recent notes"* → skip Steps 1–7 and follow the **Concept-home follow-up pass** at the end of this skill.
- **Atomic-note mode** (default): All other requests involving papers, PDFs, citekeys, authors, or staged .md files → continue with the Batch detection block below.

---

## Batch detection

Count the number of distinct papers in the user's request (citekeys, titles, PDFs, staged .md files, or author references).

> **Staging folder:** If the user provides a folder path (or the phrase "atomic-staging folder"), use the Glob tool (pattern `*.md`, path = staging folder) to list all `.md` files. Read the frontmatter of each to confirm `ecology_review_source: true`. Count confirmed files as the paper count and proceed directly to batch mode (Phase A–D). Each paper's Phase A subagent should use the Staged file path (Step 2) instead of the Zotero or PDF path for any file with `ecology_review_source: true`.

- **1 paper → single-paper mode:** Continue with Step 1 below. All existing interactive prompts remain active.
- **2 or more papers → batch mode:** Do not proceed to Step 1. Follow the Batch workflow below instead.

---

## Batch workflow

**Context-budget rule (read this before running any batch):** Two things exhaust context mid-batch and cause earlier papers' detail to get lost or summarized away: (1) gathering Zotero metadata and reading full PDFs for multiple papers inline in this same thread, and (2) running the per-paper vault search and holding full draft notes in the orchestrator. As the vault grew past ~220 atomic notes, a whole-vault search run once per paper in the orchestrator became the single biggest leak. To prevent both, **every paper in a batch is processed end-to-end by its own subagent** (Agent tool, `general-purpose` type). Each subagent owns the entire pipeline for its paper — metadata gathering, PDF reading, the bounded vault search (Step 5), the duplicate check and file Write (Step 6), and the Zotero import-note patch (Step 7) — and returns only a compact **~12-line receipt** (see Phase A). The orchestrating thread (this conversation) never gathers data inline, never runs a per-paper whole-vault search, and never holds note bodies, raw PDF text, full Zotero metadata payloads, or `get_content` output. The orchestrator's only retained central jobs are duplicate arbitration across the batch, same-batch link stitching, and assembling the final summary from receipts — all grep/receipt-level and cheap. This applies uniformly — there is no "small batch, do it inline" exception.

### Batch Phase A — Parallel subagent dispatch (each subagent writes its own note)

**Pre-dispatch prep (orchestrator, cheap):**

- **Dedupe** the input paper list by citekey so the same paper is never dispatched twice.
- Build a **batch manifest**: every other paper in the batch (citekey + suggested tags where known) so each subagent can add same-batch cross-links itself.
- Run **one** scoped `^subtopic:` Grep over the likely target folders + `Ideas/concept-notes/` to capture the subtopic values already in use, and pass that list into every prompt (subtopic-drift mitigation — subagents reuse an existing value and flag any new coinage).

**Dispatch:**

1. Group the paper list into rounds of up to 4 papers. (Matches the existing 4-item cap used elsewhere in this skill for `AskUserQuestion` — keeps each round of parallel agents manageable.) Run rounds in sequence so later rounds' subagents can see files written by earlier rounds.
2. For each round, send **one message containing one `Agent` tool call per paper** — multiple tool-use blocks in a single message run as true parallel dispatch. Wait for the entire round to return before starting the next round.
3. Each subagent has no memory of this conversation, so its prompt must be self-contained. Include:
   - The vault base path, `Vocabulary.md` path, and `Templates/Atomic Literature Note Template.md` path.
   - The paper's identifying info exactly as the user gave it (citekey / title / author / PDF path / staged `.md` path).
   - The **batch manifest** (other papers' citekeys + tags) and the **existing subtopic list** from the pre-dispatch prep.
   - The full text of Step 1 (input type), Step 2 (Zotero / PDF / Staged path — including the 3-tier citekey resolution method), Step 4 (content rules, tag vocabulary, frontmatter field rules), **Step 5 (the bounded scoped vault search), Step 6 (duplicate check + Zotero import-note existence check + Write), and Step 7 (patch the Zotero import note)** from this skill, so the subagent can gather data, build a correctly-formatted note, run the bounded search, write the file, and patch the import note entirely on its own.
   - If `get_content` output is too large to read directly: read it in ~80K-char bash slices (`python3 -c "print(open('PATH').read()[A:B])"`) **within this same subagent** — there is no need to spawn a further nested agent, since this subagent's entire context is already dedicated to one paper.
   - An explicit instruction that the subagent **writes the finished note to disk itself** (Step 6 Write) into its chosen `suggested_folder`, patches the Zotero import note (Step 7), and returns **only** the receipt below — never the note markdown, raw PDF text, abstract/annotation dumps, or tool-call output.

**Required subagent return format** (one ~12-line receipt per paper — never the note body):

```
STATUS: ok | duplicate | ambiguous | error
citekey: <bbtCitekey or constructed fallback>
citekey_tier: 1 | 2 | 3
written_path: <folder/citekey — Short title.md, or "—" if not written>
folder: <folder the note was written to>
content_source: full-text | full-text+annotations | abstract-only
applicable_to_au: yes | partial | no | unclear
tags: [tag1, tag2, tag3]
subtopic: <kebab-case value used; mark "(new)" if newly coined>
links_made: related=<n>, papers=<n>, concepts=<n>, same_batch=<n>
import_note: patched | sentinel (add when imported) | n/a
notes: [duplicate path, new-subtopic flag, unverified-citekey warning, or other one-line flags]
ambiguous_candidates: [present only if STATUS: ambiguous — top 3 Zotero matches, same shape Phase B uses]
error_detail: [present only if STATUS: error]
```

If `STATUS: ambiguous`, the subagent must stop right after the Zotero search and return the candidates — it must not guess which one is correct, read a PDF, write a note, or patch an import note for an unconfirmed item. If `STATUS: duplicate` (a note with this citekey already exists), the subagent writes nothing and reports the existing path in `written_path`.

After all rounds have returned, proceed to Batch Phase B.

---

### Batch Phase B — Resolve ambiguities (one pass)

If any papers came back `STATUS: ambiguous` from Phase A, present them all together in a single `AskUserQuestion`. Format each ambiguous item as:

> Paper 3: searched for "Smith disturbance 2021" — found 3 results:
> A) Smith et al. 2021 — Disturbance ecology in arid systems (Ecology Letters)
> B) Smith & Jones 2021 — Post-fire recovery (AREES)
> C) Smithson et al. 2021 — Arid zone mammals (J. Ecology)

Use `multiSelect: false` per ambiguous paper. Present up to 4 ambiguous papers per `AskUserQuestion` call; if more than 4 are ambiguous, resolve in sequential groups of 4.

After AG picks the correct candidate for an ambiguous paper, dispatch **one follow-up subagent** for that paper only — same prompt shape as Phase A, now pre-confirmed to the chosen Zotero item — to gather metadata, read the PDF, and draft the note. Do not gather this data inline: a re-resolved paper carries the same full-PDF context cost as any other paper in the batch. Dispatch follow-up subagents for multiple resolved papers in parallel, same as Phase A.

If no papers are ambiguous, skip Phase B entirely and proceed to Phase C.

---

### Batch Phase C — Report folder assignments and apply overrides (post-write)

By this point every non-duplicate, non-ambiguous paper has **already been written** by its subagent into the folder that subagent chose (`folder` / `written_path` in the receipt). Phase C is therefore a **reporting and override pass**, not a pre-write gate.

> **Confirm-first option:** If the user explicitly asked to confirm folders *before* writing, do not dispatch Phase A with Write enabled — instead have the subagents stop after producing `suggested_folder`, run this confirmation, then dispatch the Write. Default behaviour is post-write reporting.

Print the full paper-to-folder mapping as chat text — a markdown table built from the receipts. For example:

```
| # | Citekey | Written to | Basis |
|---|---------|-----------|-------|
| 1 | greenvilleWildfire2024 | Fire/ | tag: wildfire |
| 2 | smithAcoustics2022 | Acoustics/ | tag: acoustic-monitoring |
| 3 | jonesMammals2023 | SKIPPED — duplicate | existing note kept |
| 4 | brownClimate2020 | to sort/ | no clear tag match |
```

Do NOT use `AskUserQuestion` to present this list.

If you want to sanity-check a subagent's folder choice, use the heuristic table below — but the subagent's tag-based choice is the default and is already on disk.

| If paper's dominant topic tags include… | Suggest folder |
|----------------------------------------|----------------|
| `wildfire`, `megafire` | Fire |
| `drought` | Disturbance or Climate Change (pick by abstract) |
| `acoustic-monitoring` | Acoustics |
| `monitoring`, `methods`, `multivariate-methods` | Methods |
| `ecosystem-function` | Ecosystem Function |
| `climate-change` | Climate Change |
| `invasive-species` | Invasive species |
| `mammals`, `birds`, `reptiles`, `frogs`, `invertebrates` | Monitoring |
| `conservation`, `threatened-species` | Nature metrics |
| `vegetation-structure`, `functional-traits`, `plants` | Fire or Disturbance (pick by abstract) |
| `niche-ecology`, `reference-states` | Disturbance or Methods (pick by abstract) |
| No clear match | to sort |

**Note on `to sort`:** if any subagent reports it could not find the `to sort` folder, surface that here: "Note: folder `to sort` does not yet exist — create it in Obsidian."

After printing the table, add the following as chat text:

> Reply `approve` to keep all notes where they were written, or list overrides as `Paper N → FolderName, Paper M → FolderName` (comma-separated, any order) and I'll move those files.

**Parse rules (apply in order):**
1. `approve` or empty reply → leave all notes as written; proceed to Phase D.
2. Any other reply → parse override pairs (`Paper N → FolderName`). For each, **move** the already-written file from its current folder to the requested folder (read it, Write to the new path, delete the old — or a bash `mv`), update `written_path`, and re-patch the Zotero import note's `atomic_note` link (Step 7) to the new path. Then proceed to Phase D.
3. If any paper number or folder name in the overrides is unrecognised: re-prompt once, listing only the unresolved items (e.g. "Could not parse: 'Paper 7 → Mammal' — valid paper numbers are 1–4, valid folders are …"). After the second reply, apply any newly resolved moves; for anything still unresolved, keep the note where it is and proceed to Phase D.

After applying any moves, record the final folder for each paper. No further folder questions are asked during the loop.

---

### Batch Phase D — Stitch same-batch links and report (cheap; receipts only)

The notes are already on disk and the receipts carry everything the orchestrator needs. This phase runs in the **orchestrating thread itself**, but it is now a light **stitch-and-report** pass — no PDF reads, no note bodies held in context, no per-paper whole-vault search. Run the following:

**Pass-2 same-batch link stitch (grep H1 only).** Subagents in earlier rounds could not see notes written by later rounds. To close that gap, for each pair of papers in the batch whose receipts share ≥1 topic tag, confirm the target note exists (Glob `**/*<citekey>*`) and, if a cross-link is warranted and not already present, add the `[[folder/citekey — Short title]]` wikilink into the **Connections → Related papers** line of each note using a targeted Edit (read only the few lines needed to confirm the H1 — never the whole note). Keep this minimal: most within-round links were already made by the subagents themselves; this pass only catches across-round gaps.

**Pass-2 collision check.** If two receipts report the same `written_path`, flag it — a citekey collision slipped past the pre-dispatch dedupe. Report it; do not silently overwrite.

**Report.** Build the run report entirely from the receipts (do not re-read the notes). Print a one-line status per paper:

```
✓ 1/4 — greenvilleWildfire2024 → Fire/greenvilleWildfire2024 — Savanna fire regimes.md
✓ 2/4 — smithAcoustics2022     → Acoustics/smithAcoustics2022 — Frog call detection.md
⚠ 3/4 — jonesMammals2023       → SKIPPED (duplicate at Monitoring/jonesMammals2023 — Arid mammals.md)
✓ 4/4 — brownClimate2020        → to sort/brownClimate2020 — Rainfall shifts arid zones.md
```

Then a final summary, including any flags carried up in receipts (new subtopics coined, unverified citekeys, missing `to sort`, path collisions):

```
Batch complete: 3 saved, 1 skipped (duplicate). Flags: 1 new subtopic (paper 4: rainfall-variability). Review skipped items manually if needed.
```

---

## Step 1 — Determine input type

Check whether the user has provided:
- A **Zotero reference** (citekey, paper title, author name, or Zotero item key) → follow Zotero path
- A **PDF file path or attachment** → follow PDF path
- A **staged .md file** (a file with `ecology_review_source: true` in its frontmatter, produced by the /ecology-literature-review skill) → follow the Staged file path
- Both a Zotero reference and a PDF → prefer the Zotero path; use the PDF as supplementary content

If unclear, ask: "Are you working from a Zotero reference, a PDF file, or a staged .md file from the ecology-literature-review skill?"

---

## Step 2 — Gather data

### Zotero path

1. Use `mcp__zotero-mcp__search_library` to find the item using the title, author, or citekey as the query.
2. If multiple results are returned, show the top 3 to the user and ask which one to use.
3. Use `mcp__zotero-mcp__get_item_details` on the confirmed item (mode: `complete`) to retrieve full bibliographic metadata (title, authors, year, journal, volume, issue, pages, DOI, attachments). Note: the MCP does **not** return the BBT citekey — resolve it in step 3b.
3b. **Resolve the BBT citekey** — try each tier in order, stop at the first success. The citekey must match the Zotero import note filename exactly, so getting this right is essential for two-way linking.
   - **Tier 1 — Vault search (highest confidence):** Use the Grep tool with the paper's DOI as the pattern, glob `Zotero_import/*.md`, output mode `files_with_matches`, on the vault base path. If a file is returned, its filename minus `.md` is the BBT citekey.
   - **Tier 2 — Construct and verify:** Build the candidate using the BBT formula: `auth.lower` (first author last name, all lowercase) + `shorttitle(3)` (first **3 non-trivial** title words — skip articles *a, an, the* — each kept as a **full word with the first letter capitalised**, NOT truncated) + 4-digit year. Examples from this vault: `alquezarAirportNoiseWildlife2019`, `gearyOptimisingFirePredator2026`, `wartonManyVariablesJoint2015`. For Greenville et al. 2024 'Drought intensity and duration of native rodents…' → `greenvilleDroughtIntensityDuration2024`. Then call `mcp__zotero-mcp__search_library` with that candidate string as the query — if the same item comes back (matched by Zotero key or DOI), the citekey is confirmed. BBT registers citekeys as searchable.
   - **Tier 3 — Provisional with warning:** If both tiers fail, use the constructed citekey but add a YAML comment `# ⚠ citekey unverified — confirm in Zotero/BBT` immediately after the `citekey:` line, and tell the user at the end of the session.
4. Use `mcp__zotero-mcp__get_item_abstract` to retrieve the abstract.
5. Use `mcp__zotero-mcp__get_annotations` to retrieve any highlights and notes added to the PDF in Zotero. Note the count of annotations found — these inform the note content but do not appear verbatim in the atomic note (they live in the Zotero import note).
6. **Read the full PDF** using `mcp__zotero-mcp__get_content` with the parent itemKey (not the attachment key): mode `complete`, contentControl `{allowExtended: true, prioritizeCompleteness: true}`. Do **not** use the Read tool on the attachment `path` field — the Zotero storage folder is outside connected session paths and will return an error.
   - If the response fits in context: extract key findings, methods detail, author-stated limitations, and notable discussion points directly.
   - If output exceeds context limits: the MCP saves the full text to a file in `outputs/.claude/projects/.../tool-results/`. Read it in ~80K-char bash slices (`python3 -c "print(open('PATH').read()[A:B])"`). In single-paper mode, do this slicing via a subagent (Agent tool) to keep the main thread's context lean, and instruct it to return: main findings, methods, author-stated limitations, key concepts, and 2–3 verbatim quotes. In batch mode this slicing already happens inside the paper's own Phase A/B subagent (see Batch workflow above) — no further nesting needed there.
   - Set `content_source` based on what was available: `full-text` (get_content succeeded, no annotations), `full-text+annotations` (both), or `abstract-only` (get_content failed — fall back to abstract + annotations and note this in Gaps & limitations).

### PDF path

1. Use the Read tool to read the PDF. For PDFs longer than 10 pages, read in successive 20-page ranges (e.g. `pages: "1-20"`, then `"21-40"`).
2. Extract: title, authors, year, journal, DOI, abstract, methods description, key results.
3. **Before constructing a fallback citekey, search Zotero by DOI:** use `mcp__zotero-mcp__search_library` with the extracted DOI as the query. If a match is found, switch to the Zotero path: use `mcp__zotero-mcp__get_item_details` to retrieve the BBT citekey and full metadata, then continue from Zotero path step 4 above. This prevents a broken `zotero_note` link when the paper is already in the Zotero library.
4. If no DOI is available or no Zotero match is found — construct a fallback citekey: first author surname (no accents) + 4-digit year. This fallback will not match a BBT citekey if the item is later added to Zotero.
5. Set `zotero_note` to `"add when imported"` as a placeholder.

### Staged file path

1. Read the .md file using the Read tool.
2. Parse the YAML frontmatter. All content fields are pre-populated — use them directly:
   - `citekey` → BBT citekey (filename without .md confirms this)
   - `full_citation`, `doi`, `year`, `journal`, `authors` → frontmatter metadata
   - `main_findings` → Main findings bullets (up to 4; use as-is or lightly edit for sentence clarity)
   - `methods_design`, `methods_region`, `methods_ecosystem`, `methods_data`, `methods_analysis` → Methods section fields
   - `transferability_note` → Transferability to AU line in "What this changes for me"
   - `gaps_limitations` → Gaps & limitations section
   - `topic_tags_suggested` → candidate tags; validate against Vocabulary.md in Step 4 (keep matches, discard non-matches; if VOCABULARY_PATH is `none`, use as-is)
3. Still run Zotero lookup using the DOI to confirm the citekey:
   - Tier 1: Grep vault `Zotero_import/*.md` for the DOI — if a file is found, its filename is the confirmed citekey
   - Tier 2: Search Zotero library with the constructed citekey string — if the same item returns, confirmed
   - Tier 3: Use the frontmatter citekey as provisional and add `# ⚠ citekey unverified` comment
4. Call `mcp__zotero-mcp__get_annotations` to retrieve any highlights — if found, prepend the most important annotation as main_findings bullet 1 (shifting others down, max 4 total).
5. Set `content_source: ecology-review-staged` in the note frontmatter.
6. Set `applicable_to_au` heuristic from `methods_region`:
   - Contains Australia / NZ / Pacific → `partial` (default; user upgrades to `yes` if study is directly AU)
   - Contains Europe / North America / Asia / Africa → `no`
   - Not reported or unclear → `unclear`
7. Proceed to Step 3 (folder selection). All subsequent steps (3 → 7) are unchanged.

---

## Step 3 — Ask which folder to save to

### Discover current topic folders

First, use the **Glob tool** to discover the vault's current top-level topic folders:
- **Pattern:** `*/`
- **Path:** `C:\Users\agre6595\OneDrive - The University of Sydney (Staff)\Obsidian\Ecology\`

From the returned paths, extract the folder names. Exclude system/utility folders:
`Templates`, `Zotero_import`, `Clippings`, `.obsidian`

The remaining folders are the valid topic choices. This ensures the skill automatically
picks up any new folders (e.g. `Mammals`, `Invasives`, `Climate`) without needing a skill update.

### Confirm folder with AG (chat-text — no popup)

Based on the paper's content and tags, identify the single most appropriate folder from
the dynamically discovered list. This is the **recommended folder**.

Do NOT use `AskUserQuestion`. Instead, print the following as chat text:

**Line 1 — Recommendation:**

> Suggested folder: **[RecommendedFolder]** — [one short basis phrase, e.g. "matches tags `wildfire`, `fire-regime`" or "abstract is primarily about post-fire recovery"]

**Line 2 — Full folder list (alphabetical, numbered, mark recommended):**

List every discovered topic folder in alphabetical order, one per line, as:
```
1. Acoustics
2. Climate Change
3. **Disturbance** ← (Recommended)
4. Ecosystem Function
5. Fire
6. Methods
7. Monitoring
8. Nature metrics
9. to sort
```
(Numbering and folder names will vary; always regenerate from the Glob result.)

**Line 3 — Reply prompt:**

> Reply with: a number, a folder name, `recommended` / `yes` / blank to accept the suggestion, or `to sort`.

**Parse rules (apply in order):**
1. **Integer:** use the folder at that 1-based index in the printed list.
2. **Exact folder name (case-insensitive):** use that folder.
3. **Empty reply, `yes`, or `recommended`:** use the recommended folder.
4. **Unrecognised input:** re-print the numbered list once with the same reply prompt, then wait. If the second reply is also unrecognised, ask AG to type the exact folder name.

Wait for AG's reply before proceeding to Step 4.

---

## Step 4 — Generate note content

Construct the note using this exact structure. The whole note should fit on one screen (~1 page).

```markdown
---
type: atomic-note
added: YYYY-MM-DD
summary: "One-line summary of the key finding (see field rules below)"
subtopic: "kebab-case-theme"
citekey: bbtCitekey
aliases:
  - bbtCitekey
title: "Full paper title"
authors: "Author A, Author B"
year: YYYY
journal: "Journal Name"
doi: "10.xxxx/xxxxx"
zotero_note: "[[Zotero_import/bbtCitekey]]"
applicable_to_au: unclear
changed_my_thinking: no
content_source: full-text
tags:
  - atomic-note
  - topic-tag
---

# bbtCitekey — Short descriptive title

> **Zotero note:** [[Zotero_import/bbtCitekey]] · [DOI link](https://doi.org/xxxxx)

## Main findings
- 
- 
- 

## Methods
- **Design:** 
- **Country/Region:** 
- **Ecosystem:** 
- **Data:** 
- **Analysis:** 

## What this changes for me
- 
- **Transferability to AU:** 

## Gaps & limitations
- 
- 

## Connections
- **Related notes:** 
- **Related papers:** 
- **Key concepts:** 
- **Counter-claims:** 

## Follow-up
- 
```

**Content rules:**

- **Short title (H1):** 5–8 words capturing the key finding or topic. Not the full paper title.
- **Main findings:** Maximum 4 bullets. One sentence each. Prioritise ecological significance. Use the following priority order for source material:
  1. **Zotero annotations** (user's own highlights) — highest priority; these show what AG found most important in the paper. If annotations exist, lead with those findings.
  2. **Full PDF content** — when annotations are absent or sparse, draw findings from the full text (introduction framing, results, discussion). Never base the note on abstract alone if the PDF was successfully read.
  3. **Abstract only** — last resort, used only when the PDF could not be read. Note this limitation briefly in the Gaps & limitations section.
- **Methods:** One line per field. Plain language — write so a non-specialist understands the study design at a glance.
- **What this changes for me:** Your own reaction — did this paper shift your mental model, open a new question, or confirm something you suspected? One or two sentences; empty is fine. Forces a judgement at note-creation time even if you leave it blank. Populate based on the abstract, annotations, and how the paper fits with what you already know.
- **Transferability to AU (body line):** Expand the `applicable_to_au` frontmatter value into one plain-English sentence explaining *why* it is or isn't applicable — e.g. "Findings from boreal forest; fire-return intervals unlikely to match Australian eucalypt systems." Leave as a single dash if truly unclear.
- **Gaps & limitations:** Focus on what the study cannot tell us and what the next logical study would be. Include both author-stated limitations and any gaps apparent from the design.
- **Tags:** Always include `atomic-note`. Add 1–3 topic tags chosen **only** from the controlled vocabulary in `Vocabulary.md` (vault root). Do not invent new tags — pick the closest match. Do not add the year (already in `year` frontmatter). Do not use author wikilinks anywhere in the note. The canonical topic tags are:
  - *Disturbance/fire:* `wildfire`, `megafire`, `drought`
  - *Monitoring:* `acoustic-monitoring`, `monitoring`
  - *Community & methods:* `community-ecology`, `multivariate-methods`, `methods`
  - *Ecological concepts:* `functional-traits`, `niche-ecology`, `vegetation-structure`, `reference-states`, `climate-change`, `ecosystem-function`
  - *Conservation:* `conservation`, `threatened-species`, `invasive-species`
  - *Geographic/ecosystem:* `australia`, `marine`
  - *Taxonomic (when paper is specifically about that group):* `mammals`, `birds`, `reptiles`, `frogs`, `invertebrates`, `plants`

  > If the user has set `VOCABULARY_PATH: none`, skip Vocabulary.md validation and use `topic_tags_suggested` values as-is (still include `atomic-note` as a base tag).

- **DOI:** Always wrap in quotes in the frontmatter (e.g. `doi: "10.1111/geb.70241"`). Omit the DOI frontmatter field and the DOI link in the callout if no DOI is found.
- **zotero_note / Zotero body line — conditional on import-note existence (checked in Step 6):**
  - **Import note exists** (`Zotero_import/bbtCitekey.md` present): set `zotero_note: "[[Zotero_import/bbtCitekey]]"` and emit body callout `> **Zotero note:** [[Zotero_import/bbtCitekey]] · [DOI link](https://doi.org/xxxxx)`.
  - **Import note absent**: set `zotero_note: "add when imported"` (sentinel) and emit `> **Zotero note:** *not yet imported* · [DOI link](https://doi.org/xxxxx)`. This prevents a dangling Obsidian link; if the import note is created later, the cleanup script upgrades the sentinel to a live link.
  - PDF-only notes (no Zotero record) always use the absent form regardless of the Glob result.
- **No abstract available:** Note "Abstract not available" and rely on annotations or PDF content.
- **Counter-claims (Connections section):** If this paper contradicts or challenges another note already in the vault, record it as: `Counter-claims: [[folder/citekey — title]] argues X; this paper argues Y`. Surfaces intellectual tensions over time. Leave the `- **Counter-claims:**` bullet blank if no contradiction is identified — do not delete the bullet.
- **applicable_to_au:** Your quick judgement on how well the paper's findings transfer to Australian ecosystems. Set at note-creation time. Values: `yes` (directly applicable), `partial` (some findings apply), `no` (different biome/context), `unclear` (can't tell yet). Default: `unclear`. Use abstract, country/region, and ecosystem type to inform the choice. Also write one explanatory sentence in the `## What this changes for me` section's Transferability to AU line.
- **content_source:** Record what source material was used to build the note. Set in frontmatter. Values: `full-text` (get_content succeeded, no annotations), `full-text+annotations` (get_content succeeded and Zotero annotations exist), `abstract-only` (get_content failed — also add a sentence in Gaps & limitations: "Note built from abstract only; full text not retrieved."), `ecology-review-staged` (note built from staged .md file produced by /ecology-literature-review skill). Default: `full-text`.
- **changed_my_thinking:** Did this paper shift how you think about the topic? `yes` or `no`. Set at note-creation time — a one-shot judgement based on how novel the paper is relative to the other literature you know. If uncertain, leave as `no`. This field powers the "Changed my thinking" view in Base.base.
- **added:** The date the note is created, ISO `YYYY-MM-DD` (today). Drives the cumulative timeline on `Dashboard.md` — never omit it.
- **summary:** A single-line, plain-language précis (≤ ~30 words) of the paper's key finding or argument. This is the **single source** for both the per-folder MOC tables and Claude's on-demand catalog, so make it self-contained and specific (name the system, result, or number) rather than generic. Do not start with "This paper…".
- **subtopic:** Single-valued, kebab-case theme that groups the note **within its folder** (drives per-folder MOC grouping and the Dashboard). Choose from the folder's *existing* vocabulary — do not invent freely. **Before writing (Step 6):** run the Grep tool with pattern `^subtopic:` on the chosen folder (glob `[Folder]/**/*.md`, output mode `content`) to list the subtopic values already in use there, and reuse the one that best fits the paper's dominant theme. Only coin a new kebab-case value if none genuinely fit — and when you do, tell AG you introduced a new subtopic and why. If the note spans two themes, pick the dominant one. (For concept, hypothesis and idea notes the three `Ideas/` subfolders share **one** taxonomy — scan the whole `Ideas/` tree, not a single subfolder.)
- **Author wikilinks:** Never use `[[Author Name]]` wikilinks anywhere in the note. Authors belong in Zotero; use the plain `authors:` frontmatter field only.

---

## Step 5 — Scan vault for related content (bounded)

This step builds the Connections section. It is deliberately **bounded** so its cost does not grow with the vault — never run a whole-vault `^tags:` content grep here. In batch mode this step runs inside each paper's subagent (see Batch workflow); in single-paper mode it runs in the main thread. The procedure is identical in both.

**Scope rule:** search only the paper's **target folder** plus `Ideas/concept-notes/`. Never read `_<Folder> MOC.md`, `Dashboard.md`, `index.md`, or `Base.base` during this step (and never during a batch) — they are large aggregations that duplicate what the per-note `summary:` lines already give you.

**Phase A — Scoped summary scan**

Use the **Grep tool** with pattern `^summary:`, output mode `content`, `head_limit: 60`, over the target folder (glob `[Folder]/**/*.md`) and `Ideas/concept-notes/**/*.md`. This returns one short summary line per note — enough to judge relatedness without pulling whole tag blocks. Record: filepath → summary.

**Phase B — Concept-term scan (capped)**

From the abstract and main findings, pick **at most 3** distinctive ecological terms (e.g. `niche truncation`, `fire severity`, `functional diversity`). For each, use the **Grep tool** (pattern = term, output mode `files_with_matches`, `head_limit: 10`) scoped to the same target folder + `Ideas/concept-notes/`. Add hits to the candidate pool. A term appearing in 3+ vault notes is a potential future concept note — note it as a "Key concepts" bullet without creating a note now.

**Phase C — Read top candidates and compose links**

Use the **Read tool** (first **12 lines only**) on the **top 3** scored candidates to confirm their H1 title and citekey, then compose `[[folder/citekey — Short title]]` wikilinks for the Connections section.

**Batch same-batch links:** in batch mode, also cross-link against the other papers in the **batch manifest** passed into the prompt (citekey + tags) — add a same-batch link where tags overlap, even though that note may not be written yet. (The orchestrator's Phase D Pass-2 stitch catches any across-round links a subagent could not yet see.)

If the target folder has fewer than 5 atomic notes, note "Vault still growing — connections will strengthen over time" and skip to Step 6.

---

## Step 6 — Check for duplicates and write the note

**Duplicate check**

Use the **Glob tool** (pattern `**/*bbtCitekey*`, path = vault base) to check whether a note with this citekey already exists. If found, show the existing file path and ask: "A note for this citekey already exists. Overwrite, rename, or cancel?"

**Zotero import-note existence check**

Use the **Glob tool** (pattern `Zotero_import/<bbtCitekey>.md`, vault base path) to confirm whether the import note exists, then set `zotero_note` and body callout accordingly:

| Import note | `zotero_note` frontmatter value | Body callout line |
|-------------|--------------------------------|--------------------|
| **Exists** | `"[[Zotero_import/bbtCitekey]]"` | `> **Zotero note:** [[Zotero_import/bbtCitekey]] · [DOI link](...)` |
| **Absent** | `"add when imported"` | `> **Zotero note:** *not yet imported* · [DOI link](...)` |

PDF-only notes (no Zotero record) always use the absent form. Skip this Glob if Step 2 (PDF path) already set the absent form.

**Write the note**

> **Batch mode:** in a batch, this Write — together with the duplicate check above and the Step 7 import-note patch — is performed by the paper's **own subagent**, not the orchestrator. The subagent writes the finished note to disk and returns only a receipt; the orchestrator never holds or writes note bodies in a batch. In single-paper mode the main thread performs the Write as below.

Use the **Write tool** to save the completed note to:
`C:\Users\agre6595\OneDrive - The University of Sydney (Staff)\Obsidian\Ecology\[SelectedFolder]\[bbtCitekey] — [Short title].md`

Confirm to the user: "Saved to `[SelectedFolder]/[bbtCitekey] — [Short title].md`"

**After writing — MOC check (ingest fork):** if the target folder has a `_<Folder> MOC.md`, its Dataview block lists the new note automatically — nothing to do. If it does **not**, and adding this note brings the folder to ≥ 40 atomic notes, tell AG the folder has crossed the MOC shard threshold and offer to create `_<Folder> MOC.md`.

**After writing — concept-home suggestion (follow-up only):** do **not** try to suggest concept-note homes for this paper now — a brand-new note is not yet embedded by Smart Connections, so its vector does not exist this session (embedding lag). Instead tell AG: *"Once Obsidian has re-embedded, I can suggest which concept notes should list this paper — say 'run the concept-home pass'."* See the **Concept-home follow-up pass** below.

---

## Step 7 — Patch the Zotero import note

If a Zotero import note exists (`Zotero_import/[bbtCitekey].md`), check its current content using the **Read tool**:
- **Path:** `C:\Users\agre6595\OneDrive - The University of Sydney (Staff)\Obsidian\Ecology\Zotero_import\[bbtCitekey].md`

If the file exists and contains `atomic_note:` in its frontmatter with an empty or placeholder value, use the **Edit tool** to set:
```
atomic_note: "[[SelectedFolder/bbtCitekey — Short title]]"
```

This completes the two-way link between the atomic note and the Zotero import note.

If the Zotero import note does not exist, remind the user: "Run the Zotero Integration plugin in Obsidian to import highlights for this paper — the `atomic_note` field will need to be patched afterwards."

---

## Concept Note workflow

Triggered by: *"create a concept note for [term]"*, *"make a concept note"*, or *"add [concept] as a concept note"*.

Concept notes live in `Ideas/concept-notes/` and are named `Concept name.md` (no citekey prefix). They must **argue a position**, not just list papers — a concept note without a "Current position" and a "Tensions / unresolved" section is incomplete.

**CN-1 — Identify the concept**

Confirm the concept name with the user (e.g. "niche truncation"). If ambiguous, ask for a brief definition in their own words.

**CN-2 — Scan vault for papers using this concept**

Use the **Grep tool** (pattern = concept term, glob `**/*.md`, output mode `content`, context 2) on the vault to find all notes mentioning this concept. Read the first 20 lines of each matching note to confirm relevance and to capture its citekey, folder, and H1 title for wikilinking. Collect citekeys.

**CN-3 — Generate concept note content**

Construct the note using this exact structure. The whole note should fit on about half a page.

```markdown
---
type: concept-note
added: YYYY-MM-DD
summary: "One-line summary of the concept's current position (see field rules below)"
subtopic: "kebab-case-theme"
tags:
  - concept-note
  - topic-tag
---

# Concept name

## Definition
[One short paragraph: what the concept means and why it matters for this work.]

## Current position
[One or two sentences stating the defensible claim AG would make today — specific enough that
someone could argue for or against it. Never leave this as a placeholder dash.]

## Papers using this concept
- [[folder/citekey — Short title]]
- [[folder/citekey — Short title]]

## Tensions / unresolved
- [Where papers disagree, or evidence is thin. Each bullet is raw material for a future
  hypothesis note — be concrete about what is actually in tension.]
- 

## Open questions
- [Broader unknowns not yet captured as a tension above.]
- 

## See also
- [[Related concept or idea note]]
```

**Content rules:**

- **Definition:** Plain-language, one paragraph. State what the concept means in this vault's context, not a textbook definition copied from elsewhere.
- **Current position:** Required — this is the section that makes the note argue something rather than just summarise. Draw on the papers found in CN-2: where do they converge, and what would AG say today given that evidence?
- **Papers using this concept:** Wikilink every relevant paper found in CN-2, in the form `[[folder/citekey — Short title]]`. If none were found, write "No vault papers yet use this concept directly" rather than omitting the section.
- **Tensions / unresolved:** Required — at least one bullet, even if tentative. If the papers found genuinely agree on everything, write a tension about scope, generalisability, or an untested boundary condition rather than leaving this empty; it is the section `hypothesis-forge` scans to generate candidate hypotheses.
- **Open questions:** Optional but encouraged — broader unknowns the Tensions section didn't capture.
- **See also:** Optional. Wikilink other concept notes or idea notes (`Ideas/concept-notes/`, `Ideas/ideas/`) that this concept relates to. Omit the section entirely if there are no clear links yet.
- **summary:** ≤ ~30 words, states the *current position* in plain language (not a generic "this concept is about X" line) — same role as on atomic notes: the single source for MOC tables and on-demand catalog.
- **subtopic:** kebab-case, single-valued. The three `Ideas/` subfolders (`concept-notes/`, `hypotheses/`, `ideas/`) share **one** subtopic taxonomy — before writing, run Grep with pattern `^subtopic:` across `Ideas/**/*.md` to reuse an existing value; only coin a new one if nothing fits, and tell AG when you do.
- **Tags:** Always include `concept-note` as the first tag. Add 1–3 topic tags from `Vocabulary.md`, same rules as atomic notes (no invented tags, no year tag).
- **added:** ISO `YYYY-MM-DD`, today's date. Never omit.

**CN-4 — Check for duplicates and write**

Use the **Glob tool** (pattern `Ideas/concept-notes/*.md`, vault base path) to check whether a concept note with this name already exists (case-insensitive match on the filename). If found, show the existing file path and ask: "A concept note for [term] already exists at [path]. Overwrite, rename, or cancel?" Never overwrite silently.

Use the **Write tool** to save the completed note to:
`C:\Users\agre6595\OneDrive - The University of Sydney (Staff)\Obsidian\Ecology\Ideas\concept-notes\Concept name.md`

Confirm to the user: "Saved to `Ideas/concept-notes/Concept name.md`"

**After writing:** if `Ideas/` qualifies for a MOC under the threshold in the vault's `CLAUDE.md` (≥ 40 notes across the `Ideas/` tree) and one does not yet exist, flag it to AG the same way the atomic-note MOC check does in Step 6 — do not create one unprompted.

---

## Concept-home follow-up pass

Triggered by: *"suggest concept homes for [note]"*, *"which concept notes does this paper belong under"*, *"run the concept-home pass"*, or *"find concept homes for recent notes"*.

**What it does.** For one or more **already-embedded** atomic notes, it proposes which existing concept notes should list the paper under *"Papers using this concept"*, using a semantic (Smart Connections vector) lookup — the cheap substitute for the whole-vault `^tags:` / literal-term grep this skill forbids at filing time (the CN-2 cost boundary). **Concept-note scope only:** it does **not** suggest a topic folder — folder choice stays with Step 3 / Phase C. (The topic-folder half of the original feature #2 was deliberately dropped at AG's request, 2026-07-02.)

**Follow-up only — never at filing time.** The lookup seeds from the atomic note's own stored vector. A brand-new note is not embedded by Smart Connections until Obsidian has processed it, so it has no vector in the session it is written (embedding lag). Per AG's decision (2026-07-02) this pass runs **only as a follow-up** — in a later session, or after a vault sync, once the note is embedded. Never attempt it in the same session a note is created; offer it as a follow-up instead (see Step 6). Notes not yet embedded are reported, not treated as an error — re-run once they are embedded.

**CH-1 — Determine which notes to check**
- If AG named a specific note (path, citekey, or "this paper"), resolve it to its vault-relative path with the Glob tool (`**/*<citekey>*`).
- If AG said "recent notes", collect atomic notes whose `added:` frontmatter is within the last 7 days (or a window AG gives). Use Grep on `^added:` across the topic folders, or reuse the recent-notes list a weekly-synthesis run already built.

**CH-2 — Run the driver**

From the vault root, run the shared driver (a thin wrapper over `scripts/semantic_retrieve.py`):

```
python3 scripts/concept_home_suggest.py --notes "<folder>/<citekey> — <title>.md" ["<second note>" ...]
```

Pass every target note in one call (dedup is handled internally). Defaults: `--min-score 0.80`, `--k 3`. The driver returns JSON: one entry per note with `suggestions` (each carries `concept_note`, `concept_name`, `score`, `matched_section`, `already_listed`) plus a top-level `not_embedded` list. It is read-only — it never writes.

**CH-3 — Present suggestions (human-confirm)**

For each note, print its actionable suggestions as chat text — ranked by score, showing the concept name, score, and the section that matched. **Skip any suggestion with `already_listed: true`** (the concept note already references this paper — nothing to do); if all of a note's suggestions are already listed, say so and move on. Report any `not_embedded` notes as: *"not embedded yet — re-run the concept-home pass after Obsidian has re-embedded."* A paper can legitimately have more than one home (e.g. a PAM + megafire paper) — present all that clear the floor; do not force a single choice.

Example:

```
> liDecoupling…2026a — NDVI and NPP recovery diverge after fire
>   1. Post-fire recovery        (0.81, matched: Tensions / unresolved)
> fox…2006 — Price equation partitions biodiversity-loss effects
>   1. Biodiversity–ecosystem functioning (BEF) relationship  (0.84, matched: Papers using this concept)
>
> Reply with the paper→concept pairs to link (e.g. `1, 2a`), `all` to link every suggestion, or `none`.
```

Do **not** use `AskUserQuestion` — plain chat text. Wait for AG's reply. Never auto-write.

**CH-4 — Write confirmed links (both ends)**

For each confirmed paper→concept pair:

1. **Concept note** — add `[[<folder>/<citekey> — Short title>]]` as a new bullet under the concept note's **## Papers using this concept** section (Read that section first; do not duplicate an existing entry; if it currently reads "No vault papers yet use this concept directly", replace that line with the wikilink).
2. **Atomic note** — add `[[Ideas/concept-notes/<Concept name>]]` to the atomic note's **## Connections → Related notes** line if not already present.

Both ends must be set — a one-sided link is a broken graph edge (same rule as hypothesis↔project wiring). Confirm each write to AG: *"Linked <citekey> ↔ [[<Concept name>]] (both ends)."*

**Caveats (always surface):**

- **Currency.** Results are only as fresh as the last Smart Connections embed in Obsidian. If a note returns no suggestions where you expected one, it may simply not be embedded yet — say so rather than concluding it has no concept home.
- **Firewall.** The driver inherits the helper's hard `_Grant drafts/` + `_exemplars/` exclusion on all results — never weaken it.
- **Calibration.** `min_score 0.80` was measured on live vectors 2026-07-02 (whole atomic-note seed → concept note: correct home 0.78–0.89, generic below ~0.77). Re-check if the embedding model or note style changes.
