Skip to content

Knowledge patterns

A template describes a note's structure — its fields and body. A Knowledge Pattern adds behavior: an ordered list of actions that run when a note is created from it. Structure + behavior.

The shipped Permanent Note pattern isn't just Claim / Evidence / Connections / Questions fields — on creation it runs find related · find contradictions · suggest links · calculate maturity against your existing graph, writing each result into the note's frontmatter. (See A note on timing below for what a brand-new note receives on its very first pass.)

How it works

A step's zettelFlowSettings gains one optional, additive key:

zettelFlowSettings:
  root: true
  label: Permanent note
  actions:            # the interactive wizard steps (unchanged)
    - type: prompt
      ...
  onCreation:         # NEW (#170): headless actions run on note creation, in order
    - type: find-related
      hasUI: false
      key: related
      zone: frontmatter
      limit: 10
    - type: find-contradiction
      hasUI: false
      key: contradictions
      zone: frontmatter
    - type: suggest-link
      hasUI: false
      key: suggestedLinks
      zone: frontmatter
      limit: 5
    - type: calculate-maturity
      hasUI: false
      key: maturity
      zone: frontmatter

When the note is built, after its structure is assembled and before the file is written, the note-builder runs each onCreation action in order through the standard execute() pipeline, so their results land in the note's frontmatter. Each action is best-effort: a failure is logged and never aborts the build or the remaining actions. The onCreation list is collected from every walked step, so a multi-step flow composes its behavior.

Backward compatibility

onCreation is optional and additive, exactly like phase (#149), trigger (#150) and wait (#151). A legacy template with no onCreation key parses and behaves exactly as before — a plain static template. The step-builder preserves the field opaquely (there is no visual editor yet), so an unrelated edit never drops it.

Scope

This ships on-creation behavior only. General "on-event" triggers (run behavior on later edits, state changes, etc.) are a deliberate follow-up; launching a whole flow on a vault event is already the trigger field (#150).

A note on timing

On-creation actions run before the new note's own file exists, so the graph-based actions rank it against the already-indexed vault, and the new note is not yet a node in that graph. On that first pass a brand-new note's result properties (related, contradictions, maturity, …) are often empty — the note is not yet in the graph.

To close that gap, ZettelFlow re-runs the pattern once, automatically, after the note is indexed (#200). The re-run:

  • fires exactly once per note creation, only when the note becomes indexed with its links resolved — it waits up to ~5 seconds and then gives up silently (a debug log line, no notice) if indexing is slow;
  • is a strict one-shot from the create path — it is never wired to later edits, and a per-note guard means its own frontmatter write cannot re-trigger it (one create ⇒ at most one re-run);
  • writes only the pattern's own declared keys back into the note; every other frontmatter key you or another action set is preserved untouched;
  • is offline — it reads only the local knowledge index, makes no network call, and adds no new capability.

It is on by default. To disable it — for example if you object to a second automatic write to a just-created note — turn off Settings → ZettelFlow → Knowledge patterns → Re-run a pattern after the note is indexed; behaviour is then identical to the build-time-only pass.

Try it

Install the starter flows (Settings → ZettelFlow → Zettelkasten toolkit → Starter flows), then build a note from the Permanent note flow: its frontmatter will carry the pattern's result properties (related, contradictions, suggestedLinks, maturity), computed against your existing graph.