Anthirayas79 downloadsDrive property autocomplete, option pickers, validation and migration from YAML note schemas kept in your vault.
An Obsidian plugin for desktop (macOS and Windows) and mobile (iOS and Android) that reads note schemas from plain YAML files in your vault and uses them for property autocomplete, option pickers, validation, readable IDs, timestamps and schema migration, and, where you ask for it, the shape of a note's body.
Schemas are text files in a folder (_schema by default). Each note type is a list of reusable modules plus its own fields. Add a type, a status value or a tag by editing a file: no code change, no restart.
It is described as governance-ready, not as a compliance system: locks are advisory, and real audit history needs git or backups.
type property, then the first segment of breadcrumb, then the folder name, otherwise it asks once and remembers. Include and exclude rules decide which notes are managed; the schema folder is always excluded.KB-2026-0143: type prefix, creation year, running number. No counter file; the next number is worked out from your notes.created and modified are real frontmatter fields, always last, local time YYYY-MM-DDTHH:mm. modified follows any change to the note (including changes that arrive through sync) and ignores moves, breadcrumb rewrites and the plugin's own writes. By default it is the only thing written without asking; optional settings can fill new notes, keep name in step with the file name, and write breadcrumb from the folder.archived_fields (nothing is ever deleted)._schema/preview/<type>.yaml shows, read-only and always current, what a new note of each type starts with and what each property allows. Where a domain changes a type, _schema/preview/<type>/<domain>.yaml shows it for that domain.domain, timestamps, folder case clashes, schema problems). Every fix shows exactly what it will write and waits for you.{{time:HH:mm}} template variables and Bases-style formulas ({{ now().format('ddd HH:mm') }}). A journal can make every new line - 14:09 (off until you allow body edits).domain removed when it repeats the breadcrumb; anything that would be lost goes to archived_fields.main.js, manifest.json and styles.css from the latest release (or build them: see Development).<your vault>/.obsidian/plugins/rubric/ and enable Rubric in Settings → Community plugins._schema/ with the starter types (it never overwrites existing files).Rubric starts off on a fresh install, so you can write and change your schema without it touching a note. When the schema is ready, turn it on from the status bar, the settings page or the command Toggle automation on or off.
Requires Obsidian 1.13.7 or later. Full features on macOS and Windows; a lighter mobile-lite set on iOS and Android (no Properties-area hold key; pick values with the command Choose a property to edit; the body module works on a phone too). On Android it has been tested in an emulator, not yet on a real phone, and not on iOS. Update by copying the three files over the old ones and restarting Obsidian; a schema that needs a newer plugin (its registry says so) is refused by an older one with a clear message. See docs/user-guide.md for details.
| Command | What it does |
|---|---|
| Choose a property to edit | Pick a property of the open note from a list, then its value; works without a focused property, so it is the way to do it on a phone |
| Show all options for this property | Latches the option list for the focused property (assign a hotkey in Obsidian's Hotkeys settings); opens a picker window if the Properties-area features are off |
| Toggle automation on or off | The master switch. Rubric is off on a fresh install so you can write your schema first; the status bar item does the same |
| Check vault | Runs the eleven checks and opens the report |
| Reload schemas | Reads the schema files again (use after editing a hidden .schema folder) |
| Open schema folder | Shows the schema folder in Finder or Explorer |
| Choose schema for this note | Asks which schema a note should use |
| Convert this note to another type | Preview, then convert; old values are kept in archived_fields |
| Create note from schema | Creates a note with an ID, created and every default |
| Install starter schema pack | Creates the starter schema files that are missing |
| Save schema as preset | Keeps a named copy of the schema folder |
| Apply schema preset | Picks a preset, shows what will change, saves a backup preset, then applies it |
| Export schema as zip | Writes the schema folder to one zip file in the vault's top folder |
No command has a default hotkey.
The starter pack has 11 types in three groups, and _schema/REFERENCE.md (installed with it) is the full reference to every file, attribute, domain and error code.
| Group | Types |
|---|---|
Knowledge and learning (placed in a domain and a reading path, with unique_id and verification) |
kb, exercise (a question to attempt), scenario (a decision to make), example (a worked example) |
| Everyday | note, resource, project, task |
| Personal | journal, person, workout |
Five example domains show what the override files can do, each in a few lines you can copy or delete: general (the default, no files), maths and physics (subject domains: their own kinds and fields), pcb and embedded (engineering domains: standards, target, toolchain, their own decision types). There is no breadcrumb property, so the pack works without a breadcrumb plugin.
Properties are described in YAML; the body of a note can be too. A body module is a module file (like base) that lists a note's sections by heading and says what Enter, Tab and Shift-Tab do, under a heading or everywhere. A type pulls it in with uses.
# _schema/modules/body.yaml (register it under `modules:` in registry/types.yaml, add `body` to a type's `uses`)
module: body
sections:
- heading: Captures
level: 2
starter: "- {{time:HH:mm}} " # what a new note has under the heading
- heading: Gratitude
keys:
Enter: { insert: "- " } # plain bullets under this heading
default:
keys:
Enter: { insert: "- {{time:HH:mm}} " } # every new line is a timed entry: - 14:09
Tab: { insert: "{{ now().format('ddd') }} ", newline: false }
insert (text), newline and pass. A section's rule applies under its heading; default applies everywhere else; a type's own body: block can change a module's rules.{{ ... }} are either Obsidian's core Templates variables ({{time:HH:mm}}, {{date:FORMAT}}, {{title}}) or Bases-style formulas (now().format("HH:mm"), file.basename, if(mood >= 4, ":)", ""), text, list and date methods, note properties). Formulas run in a small engine written for Rubric; it never runs JavaScript.Every part, the full list of formula functions and the cases for Enter are in _schema/REFERENCE.md (The body module) and in docs/user-guide.md.
A new domain (maths, physics, biology…) can change the defaults without forking the schema. Next to a default file, an optional folder named after it holds one override file per domain, named by the domain slug:
_schema/types/kb.yaml default
_schema/types/kb/maths.yaml override for kb notes whose domain is maths
_schema/modules/verification/maths.yaml override for a module
_schema/vocabularies/tags/maths.yaml extra tags for maths
_schema/vocabularies/tracks/maths.yaml extra tracks for maths
The effective schema for a note is the default plus the override file for the note's domain property. No override file means the default applies, so a vault without override folders behaves exactly as before. The domains are registered in registry/domains.yaml (a prefix, a folder name and a description each, and the default; a pack without that file takes them from the domain property's own values); a file for a domain that is not registered is an error. The file name is the slug, and the file must say domain: <slug> too.
Type and module files have three verbs, nothing else (no inheritance, no archetypes):
domain: maths
override: # change values, default or description of an existing property
kind:
values: [definition, theorem, proof]
default: definition
add: # properties allowed only for this domain (full property definitions)
prerequisite_theorems: {type: list, items: link}
remove: [standards] # properties not allowed for this domain
sections: [maths-algebra, maths-analysis] # module files only: added to the module's `section` values
override replaces values (the domain's list, not an addition); only values, default and description can change, and values only on an enum. Changing type is an error, as is any other key.add puts the property after the type's own properties and before created and modified. A name the type already has is an error.remove of a name the type does not have is an error. One property cannot appear under two verbs in one file.type, schema, id, name, status, domain, section, level, order, created, modified.sections extends the default section list with the domain's own. Every section value and every track term for a domain starts with <domain>-.domain: plus terms:, in the same shape as the default vocabulary. The domain's terms are added to the default ones. A term or synonym that equals a default term or synonym is an error and the default wins. The "Add to vocabulary" fix writes into the domain's file when it has one.A note is checked against its domain's effective schema: values, required properties, options and autocomplete, tag synonyms. The vault check also reports a section or track that does not start with the note's domain, and a property the domain removed that is still present (reported only, never deleted).
The existing overrides: key in a type file is a different thing and is unchanged: it adjusts a module property for that type in every domain (values, default, required). Domain overrides live in their own files so a type file never has to name a domain.
The same rules are enforced by the vault's tools/validate.py (--domain <slug> prints a domain's overrides and the effective properties per type). Tests: npm test (the engine) and npm run test:validator (the validator, against tests/fixtures/domain-vault).
None. The plugin makes no network requests, collects no telemetry, needs no account, and reads and writes only files inside your vault. It stores its settings and a small index of known IDs in its own data.json.
breadcrumb and never moves files; those belong to your breadcrumb plugin.npm install
npm test # unit tests
npm run lint # ESLint with the Obsidian rules, and stylelint on styles.css
npm run build # production build: main.js
npm run e2e # real Obsidian, isolated profile (needs Obsidian installed)
Documentation for contributors is in docs/README.md. Licence: MIT.