diff --git a/.gitignore b/.gitignore
index 4ae580f..7005519 100644
--- a/.gitignore
+++ b/.gitignore
@@ -328,3 +328,4 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
+*.stackdump
diff --git a/docs/advanced-filemaker-scripting-syntax.md b/docs/advanced-filemaker-scripting-syntax.md
index 17686fc..8d1ba93 100644
--- a/docs/advanced-filemaker-scripting-syntax.md
+++ b/docs/advanced-filemaker-scripting-syntax.md
@@ -59,8 +59,9 @@ the same flag:
- `Exit after last: On` on found-set iterators.
- `With dialog: Off` on steps that can suppress their confirmation UI.
-- `Restore: On|Off` — **reserved**. Not currently emitted by any POCO;
- see "What to drop vs. surface" below for the rationale.
+- `Restore: On|Off` — emitted by steps whose XML carries a meaningful
+ stored-state flag (e.g. Enter Find Mode); see "What to drop vs.
+ surface" below for the fixed-value cases that stay XML-only.
### Form 3 — trailing `; Kind: [...]` blocks
@@ -125,16 +126,16 @@ Pro never alters it, never emits it in clipboard output, and no user
workflow produces a different value. Round-tripping such state adds
visual noise for zero information.
-### Canonical drop: `` on `If`
+### Canonical hidden state: `` on `If`
-Upstream `agentic-fm` snippets include the element; FM Pro's own
-clipboard output never does; no FM Pro user interaction produces
-`state="True"`. `IfStep` drops it on both read and write. The audit
-entry documents the drop:
-
-> <Restore state="False"/> — intentionally dropped. FM Pro never
-> changes the value and never emits the element in clipboard output; it
-> carries no information worth round-tripping.
+The vendored canonical reference (`docs/filemaker-xml-canonical/`,
+round-trip verified against FM Pro 2025/2026) shows FM Pro *does* write
+the element, so `IfStep` emits it in XML — but the value is fixed (no FM
+Pro user interaction produces `state="True"`), so it stays hidden from
+the display line: the shape declares it `Display = DisplayMode.Hidden`
+and it round-trips in XML only. The same treatment applies to Loop's
+``/`` pair. See the divergence review log in
+`docs/filemaker-xml-canonical/divergence-review.md`.
### Canonical surface: field `id` via `(#id)` suffix
diff --git a/docs/filemaker-xml-canonical/LICENSE.md b/docs/filemaker-xml-canonical/LICENSE.md
new file mode 100644
index 0000000..9a5bc01
--- /dev/null
+++ b/docs/filemaker-xml-canonical/LICENSE.md
@@ -0,0 +1,40 @@
+# License — Vendored canonical FileMaker XML references
+
+The reference material in this directory is **not** original to SharpFM. It is
+vendored, unmodified except where noted, from two open-source projects by
+**Andrew Kear** of **Clockwork Creative Technology** (https://www.clockworkct.co.uk),
+and is redistributed here under its original licence.
+
+## License: CC BY 4.0
+
+Both sources are licensed under the
+[Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/).
+
+You are free to share and adapt the material for any purpose, provided you give
+appropriate credit. SharpFM gives that credit here and in the `README.md`
+alongside this file.
+
+## Attribution
+
+- **FileMaker XML Snippet Claude Skill** — reverse-engineered specification of
+ FileMaker's `fmxmlsnippet` clipboard format.
+ Source: https://github.com/andykear/FileMaker-XMLsnippet-Claude-Skill
+ Vendored version: **v1.12** (FileMaker Pro 2026 / FM 26 support).
+ Vendored under `skill/`.
+
+- **Clockwork Inspector** — open-source FileMaker DDR / database-design XML
+ analyzer. SharpFM vendors only two extracts: the `FM_STEP_IDS` step catalog
+ and the `extractStepText` display renderer, used as a cross-check catalog and
+ a reference for SharpFM's own step-display convention.
+ Source: https://github.com/andykear/FileMaker-XML-inspector-open-source
+ Vendored version: **v2.0**.
+ Vendored under `inspector/`.
+
+## What SharpFM uses this for
+
+SharpFM is an XML-faithful FileMaker clipboard editor. These references are the
+authoritative description of the exact native XML FileMaker's Script Workspace
+paste handler accepts cleanly, including the documented silent-failure modes.
+SharpFM's step model is validated against them. No SharpFM source code is
+derived from Clockwork's code; the vendored files are reference data and are
+parsed at test time only.
diff --git a/docs/filemaker-xml-canonical/README.md b/docs/filemaker-xml-canonical/README.md
new file mode 100644
index 0000000..b659300
--- /dev/null
+++ b/docs/filemaker-xml-canonical/README.md
@@ -0,0 +1,45 @@
+# Canonical FileMaker XML references (vendored)
+
+This directory vendors the authoritative, reverse-engineered description of the
+native XML FileMaker Pro's Script Workspace paste handler accepts. SharpFM's
+script-step model (`src/SharpFM.Model/Scripting/`) is validated against it so
+that XML written back to the clipboard round-trips through FileMaker with no
+silently-dropped elements.
+
+See [`LICENSE.md`](LICENSE.md) for attribution. Both sources are CC BY 4.0,
+authored by Andrew Kear / Clockwork Creative Technology.
+
+## Layout
+
+| Path | Source | Used for |
+|------|--------|----------|
+| `skill/SKILL.md`, `skill/references/*.md` | FileMaker XML Snippet Skill **v1.12** | Canonical clip-XML skeletons per step. The refresh step extracts these fenced blocks into checked-in test fixtures (under `tests/SharpFM.Tests/CanonicalSkill/fixtures/`) that the round-trip suite reads — the markdown is not parsed live at test time. **Sole source of truth for clip-XML emission.** |
+| `skill/README.upstream.md` | same | The upstream project's own README, kept for provenance. |
+| `inspector/FM_STEP_IDS.js` | Clockwork Inspector **v2.0** | Verbatim 217-entry `stepId → {name, category}` catalog. Used as the **working list** to align SharpFM's POCO `StepMetadata` (Id/Name/Category) and find the steps we don't yet model. Once the POCOs match it, **SharpFM's `StepMetadata` is the authoritative catalog** — this file stays only as the upstream reference for spotting drift on future FM releases. |
+| `inspector/extractStepText.js` | Clockwork Inspector **v2.0** | Verbatim reference renderer for human-readable step text. Seeds SharpFM's `StepDisplayRenderer` convention. The Inspector's DDR parser is **not** reused — it targets a different XML dialect (database-design XML, not clip XML). |
+
+## Silent-failure modes (from `skill/references/core.md`)
+
+The paste handler is lenient as an XML parser but strict as a paste handler.
+Structurally valid XML can paste with data silently dropped. The verified modes
+SharpFM's renderer must respect:
+
+- **Set Variable** — the variable name must be in a `` child, present and
+ last. A bare `` or misplaced name pastes with no variable name.
+- **Perform JavaScript in Web Viewer** — parameters use `…
`; a `` element is silently dropped.
+- **Install OnTimer Script** — the interval must be wrapped in `…`; a bare top-level `` binds to the wrong slot and the timer never fires.
+
+## Refreshing
+
+Run [`refresh-canonical.ps1`](refresh-canonical.ps1) to re-sync both sources
+from upstream. Review the diff before committing — upstream version bumps (new
+FM releases) may add steps or change canonical shapes, which is exactly the
+signal the audit tests are meant to surface. After refreshing, regenerate the
+test fixtures from the updated skill markdown:
+
+```
+dotnet run --file docs/filemaker-xml-canonical/extract-fixtures.cs
+```
+
+This rewrites `tests/SharpFM.Tests/CanonicalSkill/fixtures/` and reports any
+catalog ids left without a fixture.
diff --git a/docs/filemaker-xml-canonical/divergence-review.md b/docs/filemaker-xml-canonical/divergence-review.md
new file mode 100644
index 0000000..3d01718
--- /dev/null
+++ b/docs/filemaker-xml-canonical/divergence-review.md
@@ -0,0 +1,158 @@
+# Divergence review log
+
+Every place SharpFM's emitted XML **changed** to match the vendored skill's
+canonical form during the canonicalization audit. The policy is *trust the
+skill*: where our output differed, we adopt the skill's form and record the
+change here for a second review.
+
+Each entry: the step, what we emitted **before**, what we emit **now**, the
+skill section that mandates it, and a review box. Tick the box once a human has
+confirmed the change is correct.
+
+> Status legend: `[ ]` awaiting review · `[x]` reviewed & accepted · `[!]` flagged for discussion
+
+## Phase 5 — worst offenders
+
+### Set Variable (141) — no behavioral change
+- [ ] Already canonical (skill §3). Refactored to the shape-driven renderer;
+ emitted XML is byte-for-byte unchanged. Listed for completeness only.
+
+### If (68), Else If (125), Else (69) — added ``
+- **Before:** `` was dropped on read and never emitted.
+- **Now:** emit `` as the first child (before
+ `` where present).
+- **Skill:** §8.1. Round-trip tested against FM Pro 2025/2026 — FileMaker *does*
+ write it. Supersedes the earlier `docs/advanced-filemaker-scripting-syntax.md`
+ note that claimed FM never emits it.
+- [ ] Reviewed
+
+### Loop (71) — added `` and ``
+- **Before:** emitted no children.
+- **Now:** emit `` then ``.
+- **Skill:** §8.1.
+- [ ] Reviewed
+
+> Both values are fixed (FileMaker never varies them), so they are hidden from
+> the display line and round-tripped in XML only.
+
+### Install OnTimer Script (148) — element order Interval → Script
+- **Before:** emitted `