Use when Obsidian vault notes need their `status` and `type` frontmatter properties set or audited. Trigger phrases - "set note types", "check status", "classify notes", "status audit", "type audit", "lifecycle check", "draft notes", "assign types". Also trigger when notes have `type: TBD` or no status field, or when the user wants to know which notes need attention based on completeness.
How this skill is triggered — by the user, by Claude, or both
Slash command
/obsidian-vault-autopilot:property-classifyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Assign `status` (lifecycle) and `type` (category) in one pass. Rule-based, no AI, cheap to run.
Assign status (lifecycle) and type (category) in one pass. Rule-based, no AI, cheap to run.
status and type from content, metadata, and pathStatus → status)| Parameter | Default | Description |
|---|---|---|
cooldown_days | 3 | Skip notes created within the last N days. Grace period so the user can review recent captures before automation touches them. Date source: YAML created field in frontmatter. If missing, evaluate via the Source Hierarchy (filename date > Git first-commit > filesystem birthtime, gated by the clone-cluster check) — read-only for cooldown purposes; classify does not write created (that is property-enrich's job). Never use modification date. |
clone_cluster_skip | true | When true (default), Step 2b DEFERs classification for files whose only available date source is filesystem birthtime AND whose birthtime falls in a detected clone-cluster window (cooldown undecidable). See references/clone-cluster-detection.md. Set to false to fall through to filesystem birthtime for cooldown evaluation. |
scope | inbox | Which folder to scan. inbox = inbox only. vault = entire vault. User confirms before execution. |
Never process or modify these files (see references/vault-autopilot-note.md):
_vault-autopilot.md in vault root_ in vault root (reserved for plugin management)| Status | Rule |
|---|---|
permanent / evergreen | Protected — never changed, skip entirely |
archived | Any folder-path segment contains archive (case-insensitive — e.g. 099_Archive/, Archive/). Same matching semantics as the Layer-2 type rule below — the two rules must agree on the same folder. |
reviewed | All checkboxes [x], at least one exists |
polished | Has real description (not TBD) + 3+ aliases + no placeholder fields |
draft | Default — anything not matching above |
Layer 1 — Content signals (checked first, more specific):
| Signal | Type |
|---|---|
ISBN or Author: in frontmatter/body | book |
Agenda: heading or field | meeting |
Layer 2 — Path fallback (if no content signal):
| Path contains | Type |
|---|---|
inbox | inbox |
project | project |
people or contact | person |
meeting | meeting |
resource | resource |
archive | archive |
template | template |
Path semantics: "Path contains" means the folder path relative to the vault root, excluding the filename. A note named Meeting with Bob.md inside notes/ must NOT become type: meeting via its own filename — only folder names carry Layer-2 intent.
No match: type: TBD. Content signals override path signals.
Existing type (not TBD/inbox) + different proposed value = conflict, do not overwrite. Notes with TBD, inbox, or no type can always be set.
Before every invocation of this skill — including resumed sessions and re-triggers within the same conversation:
references/clone-preflight.md. It detects clone-induced birthtime clusters and emits a WARN before any date-derivation runs. Cross-platform — applies on macOS, Linux, and Windows. WARN-flow only; skill execution continues.references/windows-preflight.md end-to-end (registry check, trailing-dot folder detection, Windows-aware file-enumeration pattern). The enumeration pattern in Step 6 of that preflight applies to every subsequent file-listing call this skill makes — Scan (step 2 below) included. On macOS or Linux, this preflight is a no-op.Run the checks freshly each time. Do not assume a previous turn's pass result still holds — registry state, folder topology, and birthtime clustering can change between invocations and previous results are not authoritative.
${OBSIDIAN_VAULT_PATH}. Ask for scope. Confirm if 50+ notes.references/yaml-sanity.md. Verdict-routing per references/yaml-sanity.md § "Per-skill policy" — classify is additive-only on YAML health: it never repairs, it defers to the repair-capable skills:
BROKEN_KEYS_INSIDE_COLON (shape β — F26): SKIP + Class-C finding "broken-yaml: inside-colon shape detected — run property-enrich first" (NOT repair).DUPLICATE_KEYS_DIVERGENT_VALUES (F7 family): skip + Class-A finding "duplicate-key-divergent-values" (route to user / note-rename for resolution).DUPLICATE_KEYS_IDENTICAL_VALUES: SKIP + Class-C finding "duplicate-keys-identical: run property-enrich first to dedup".MULTIPLE_FRONTMATTER_BLOCKS or UNCLOSED_FRONTMATTER: skip + Class-A finding (route to note-rename for handling).OK_QUOTED (shape α): proceed normally; classification regexes accept both plain and standard-quoted forms.OK / OK_NO_FRONTMATTER: proceed normally.cooldown_days, for each candidate note where YAML created is absent: detect the scope-wide clone-cluster window per references/clone-cluster-detection.md § "Cluster Window Detection" once per invocation, then walk the Source Hierarchy Prio 1-3 read-only (filename date > Git first-commit). If Prio 1-3 yields no value, invoke recipe (a) is_birthtime_in_clone_cluster_window. If recipe (a) returns 0 (in cluster) AND recipe (b) has_alternate_date_source returns 1 (no alt source), DEFER: treat the file as cooldown unknown, SKIP classification for it, and log Class-C "clone-cluster birthtime, no alt source — cooldown undecidable" in the findings file. The note is reported in the Skipped section (not silently dropped). Otherwise, evaluate cooldown_days against the available date source. Behavior gated by config clone_cluster_skip (default true); when false, cooldown falls through to filesystem birthtime.references/yaml-sanity.md again as defense-in-depth (idempotent). Set status and type via line-by-line YAML edits per references/yaml-edits.md only — recipe (b) to replace an existing field value, recipe (c) to add a missing field. Never str.replace, never multi-line regex. Preserve all other fields. Casing Nahbereich (Status → status) is a recipe-(b)-style single-line replacement of the key, value untouched.VaultAutopilot tag and append skill log callout row (see references/skill-log.md). YAML tag-list edits and skill-log callout edits MUST follow references/yaml-edits.md (recipes d + e).references/findings-file.md), append a section to <VAULT>/_vault-autopilot/findings/<YYYY-MM-DD>-property-classify.md. Create the folder chain if missing. Never edit prior findings — append-only ledger.logs/run-history.md.status and type (plus the casing Nahbereich on those two keys) — no other property modifiedcreated — cooldown derivation is read-only (property-enrich owns created)## Property Classify Report — [Date]
### Done
- Classified: X notes | Status set: X | Type set: X
- Conflicts flagged: X (not overwritten)
### Skipped
- Cooldown: X | Cooldown undecidable (clone-cluster): X | Broken YAML (deferred): X | Protected: X
### Distribution
- Status: draft X | polished X | reviewed X | archived X | protected X
- Type: inbox X | project X | meeting X | book X | TBD X
### Findings
- [Status downgrades, type conflicts, observations for other skills]
permanent/evergreen) were not modifiedreferences/yaml-sanity.mdcreated / Source Hierarchy with clone-cluster gate — never raw birthtime on a clustered vault (Step 2b)archived and type archive agreed on every archive-folder note (same path semantics)references/yaml-edits.md recipes (b/c for fields, d/e for tag + skill log)references/findings-file.md for any non-trivial findingsGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub neckarshore-skills/obsidian-vault-autopilot --plugin obsidian-vault-autopilot