9. Configuration
9.1 Purpose
This section defines the normative configuration model for collections using tasknotes-spec.
9.2 Configuration provider model
Implementations MUST derive an effective configuration from one or more configuration providers.
A provider is a source adapter that returns a partial configuration normalized to this section's schema.
Implementations MUST:
- support at least one provider,
- document supported providers,
- document provider precedence order,
- disclose active providers and fallback behavior in conformance output (§7).
9.2.1 Common provider types
Common providers include:
yaml_file: atasknotes.yamldocument at collection root,tasknotes_plugin_data_json:.obsidian/plugins/tasknotes/data.json,built_in_defaults: implementation defaults,- optional runtime/CLI/env overrides.
This list is not exhaustive.
9.2.2 Deterministic precedence and merge
Provider precedence MUST be deterministic.
Unless explicitly documented otherwise, implementations MUST resolve configuration per top-level key:
- for each key in §9.3/§9.4, the highest-precedence provider that supplies that key wins,
- winning object values replace lower-precedence object values as whole objects (no implicit deep merge),
- after top-level selection, implementations MUST apply documented schema defaults for missing nested keys before exposing effective configuration.
If an implementation supports deep-merge behavior, it MUST be explicitly documented and deterministic.
9.2.3 Strict vs permissive provider behavior
In strict mode:
- failure to resolve required effective keys (
spec_version,mapping) MUST be a configuration error.
If permissive mode is implemented, then in permissive mode:
- implementations MAY continue with defaults when providers are missing/unreadable,
- implementations MUST emit configuration warnings,
- implementations MUST disclose that effective configuration is partial/default-derived.
9.2.4 TaskNotes plugin provider (data.json)
The TaskNotes plugin stores settings in .obsidian/plugins/tasknotes/data.json within the vault root. When using this file as a configuration provider, normalization MUST apply the field mapping in the table below.
Key mapping table (data.json key → spec effective config):
data.json key |
Spec key | Notes |
|---|---|---|
fieldMapping |
mapping |
Normalize role names: dateCreated→date_created, completedDate→completed_date, recurrenceAnchor→recurrence_anchor, completeInstances→complete_instances, skippedInstances→skipped_instances, blockedBy→blocked_by, timeEntries→time_entries, timeEstimate→time_estimate |
storeTitleInFilename |
title.storage |
true → "filename", false → "frontmatter" |
taskFilenameFormat |
title.filename_format |
Values: "title", "zettel", "timestamp", "custom"; used only when title.storage=frontmatter for canonical writes, but preserved as compatibility input when present |
customFilenameTemplate |
title.custom_filename_template |
Template string, e.g. "{title}"; used only when title.storage=frontmatter and filename_format=custom |
taskCreationDefaults.useBodyTemplate |
templating.enabled |
boolean |
taskCreationDefaults.bodyTemplate |
templating.template_path |
Path to template file |
customStatuses[*].value |
status.values |
Ordered array of status value strings |
defaultTaskStatus |
status.default |
Default status string |
customStatuses[isCompleted=true][*].value |
status.completed_values |
Statuses where isCompleted: true |
defaultTaskPriority |
defaults.priority |
Default priority string |
autoStopTimeTrackingOnComplete |
time_tracking.auto_stop_on_complete |
boolean |
autoStopTimeTrackingNotification |
time_tracking.auto_stop_notification |
boolean |
taskIdentificationMethod |
task_detection.method |
"tag" or "property" |
taskTag |
task_detection.tag |
Tag string used when method="tag" |
taskPropertyName |
task_detection.property_name |
Frontmatter key used when method="property" |
taskPropertyValue |
task_detection.property_value |
Expected value; empty means key must exist |
tasksFolder |
task_detection.default_folder |
Default folder for new tasks |
excludedFolders |
task_detection.excluded_folders |
Comma-separated folder paths to exclude |
moveArchivedTasks |
archive.move_on_archive |
boolean |
archiveFolder |
archive.folder |
Archive destination folder |
useFrontmatterMarkdownLinks |
links.use_markdown_format |
boolean; see §11 |
Key data.json fields with defaults (for cold-start reading of a vault with no tasknotes.yaml):
| Field | Type | Default | Meaning |
|---|---|---|---|
tasksFolder |
string | "TaskNotes/Tasks" |
Default folder for new task files |
taskIdentificationMethod |
"tag" | "property" |
"tag" |
How task files are identified |
taskTag |
string | "task" |
Tag that identifies task files (when method="tag") |
taskPropertyName |
string | "" |
Frontmatter key for property-based identification |
taskPropertyValue |
string | "" |
Expected value for property-based identification (empty = key presence) |
storeTitleInFilename |
boolean | true |
Title storage mode |
taskFilenameFormat |
"title" | "zettel" | "timestamp" | "custom" |
"title" |
Filename generation format |
customFilenameTemplate |
string | "{title}" |
Template for "custom" filename format |
defaultTaskStatus |
string | "open" |
Default status on create |
defaultTaskPriority |
string | "normal" |
Default priority on create |
customStatuses |
StatusConfig[] | see §9.20 | Ordered status definitions |
autoStopTimeTrackingOnComplete |
boolean | true |
Auto-stop active session on completion |
autoStopTimeTrackingNotification |
boolean | false |
Show notification when auto-stopping |
useFrontmatterMarkdownLinks |
boolean | false |
Use markdown links in frontmatter (requires obsidian-frontmatter-markdown-links plugin) |
moveArchivedTasks |
boolean | false |
Move task file to archive folder on archive |
archiveFolder |
string | "TaskNotes/Archive" |
Archive destination folder |
excludedFolders |
string | "" |
Comma-separated folders to exclude from task indexing |
StatusConfig object shape:
{
"id": "done",
"value": "done",
"label": "Done",
"color": "#00aa00",
"isCompleted": true,
"order": 3,
"autoArchive": false,
"autoArchiveDelay": 5
}
spec_version is not present in data.json. Implementations MUST synthesize an effective spec_version as described in §9.5.
Provider keys not listed above MAY be ignored by tasknotes-spec consumers.
9.3 Required top-level keys
Required keys apply to the effective configuration after provider resolution.
| Key | Type | Required | Description |
|---|---|---|---|
spec_version |
string | yes | target spec version (provider-supplied or synthesized per §9.5) |
mapping |
object | yes | semantic role to storage key mapping |
9.4 Recommended top-level keys
| Key | Type | Description |
|---|---|---|
runtime_timezone |
string | IANA timezone for day-level semantics |
task_detection |
object | task file identification rules |
defaults |
object | role defaults used during create |
status |
object | status set and completed-value semantics |
validation |
object | validation behavior (strict required, permissive optional) |
links |
object | link parsing/resolution behavior |
title |
object | title source and filename behavior policy |
templating |
object | optional create-time templating behavior policy |
dependencies |
object | dependency behavior policy |
reminders |
object | reminder behavior policy |
time_tracking |
object | time-tracking management behavior policy |
compatibility |
object | legacy alias/behavior switches |
9.5 spec_version behavior
spec_version MUST be a semantic version string.
Pre-release identifiers are valid (for example 0.1.0-draft).
Implementations in strict mode MUST reject unsupported major versions.
If permissive mode is implemented, permissive mode MAY proceed with warning when major version differs.
If a provider does not supply spec_version (for example TaskNotes data.json), implementations MUST synthesize an effective spec_version matching their target tasknotes-spec version and SHOULD disclose that it was synthesized.
9.5.1 runtime_timezone behavior
If runtime_timezone is configured, it MUST be a valid IANA timezone identifier and MUST be used for day-level semantics.
If runtime_timezone is absent, implementations MUST use system local timezone.
The effective timezone MUST be discoverable.
9.6 mapping schema
mapping MUST map semantic roles (from §2) to string storage keys.
Minimum required roles in mapping:
titlestatuscompleted_datedate_createddate_modified
If semantic role id is supported (§2.6.5), mapping SHOULD include id.
Example:
mapping:
title: title
status: status
date_created: dateCreated
date_modified: dateModified
completed_date: completedDate
recurrence: recurrence
recurrence_anchor: recurrenceAnchor
complete_instances: completeInstances
skipped_instances: skippedInstances
time_entries: timeEntries
blocked_by: blockedBy
reminders: reminders
9.7 task_detection schema
task_detection controls how task files are identified within the vault.
Detection methods
The tasknotes plugin natively supports two identification methods, controlled by taskIdentificationMethod in data.json (mapped to task_detection.method):
tag (default) — A markdown file is a task if it contains the configured tag (default #task) in its frontmatter tags array or inline in the body. Configured by task_detection.tag.
property — A markdown file is a task if a specified frontmatter property has a specified value (or exists, if value is empty). Configured by task_detection.property_name and task_detection.property_value.
Schema and selection rules:
task_detectionMAY specify either:method(single-method form), ormethods(multi-method form; non-empty list).
- If both are present,
methodsMUST take precedence and implementations SHOULD emit a configuration warning. - If neither is present, effective detection method MUST default to
tag. methodMUST betagorproperty.methodsentries MUST be unique and MUST be from:tagpropertyfield_presencefield_match
- Method-specific required keys:
- when
tagis enabled, effectivetask_detection.tagMUST be non-empty (defaulttaskwhen absent); - when
propertyis enabled,task_detection.property_nameMUST be provided and non-empty;task_detection.property_valueMAY be empty (empty means key-exists semantics).
- when
- If
methodshas more than one entry,task_detection.combinecontrols combination semantics (§9.7.3). If omitted, it MUST default toor.
9.7.1 Tag matching semantics
When task_detection.method=tag, matching MUST follow these rules:
- Normalize configured
task_detection.tagby stripping one leading#when present. - Compare tag names case-insensitively after normalization.
- Frontmatter matching:
tagsMAY be a list of strings or a single string.- each tag value is normalized by trimming surrounding whitespace and stripping one leading
#. - match requires exact normalized equality (for example
taskmatches#task;taskdoes not matchtasking).
- Body matching:
- only markdown text outside fenced code blocks and inline code spans is considered,
- a match requires a hashtag token with exact normalized name (for example
#task), - partial-word matches MUST NOT count (for example
#taskingdoes not match configuredtask).
If either frontmatter or body matches, the file is identified as a task.
9.7.2 Property matching semantics
When property detection is enabled (method=property or methods includes property):
task_detection.property_nameMUST name the frontmatter key to inspect.- If
task_detection.property_valueis non-empty, match requires semantic equality with the configured value. - If
task_detection.property_valueis empty or absent, match requires key presence only.
9.7.3 Multi-method extension semantics
tasknotes.yaml-level providers MAY additionally support:
field_presence(example: required keystatus)field_match(example:type == "task")
Extension-key shape:
field_presence: string or listof required frontmatter keys. field_match: object map ofkey -> expected scalar valuefor exact semantic equality checks.
If multiple methods are configured in tasknotes.yaml, task_detection.combine MUST define combinator semantics:
or(default): file is a task if any enabled method matches.and: file is a task only if all enabled methods match.
If task_detection.combine is absent, implementations MUST default to or.
Implementations MUST exclude folders listed in task_detection.excluded_folders from task indexing.
Executable conformance: adapters participating in the fixture suite SHOULD expose config.detect_task_file to evaluate these detection semantics against fixture inputs.
Example (tasknotes.yaml, equivalent to tag-based default):
task_detection:
method: tag
tag: task
default_folder: TaskNotes/Tasks
Example (property-based):
task_detection:
method: property
property_name: type
property_value: task
9.8 defaults schema
defaults defines values used at create time when caller input omits a role.
Defaults MUST NOT override explicit user input.
Example:
defaults:
status: open
priority: normal
recurrence_anchor: scheduled
reminders:
- id: due_minus_1d
type: relative
relatedTo: due
offset: -P1D
defaults.reminders behavior is defined in §10.3.9.
9.9 status schema
status defines known status values and completion semantics.
Example:
status:
values: [open, in-progress, done, cancelled]
default: open
completed_values: [done, cancelled]
Rules:
defaultMUST be one ofvalues.completed_valuesMUST be a non-empty list.- Each
completed_valuesentry MUST be invalues. - Non-recurring completion MUST use this list, not hardcoded literals.
- When a complete operation does not provide an explicit target status, writers MUST use the first entry of
completed_values.
9.10 validation schema
Example:
validation:
mode: strict
reject_unknown_fields: false
Rules:
modeMUST bestrictorpermissivewhen present.- If
modeis absent, effective mode MUST default tostrict. - Conforming implementations MUST support
strict. - Implementations MAY support
permissive. - If
mode=permissiveis configured but not implemented, configuration MUST fail in strict mode and SHOULD emit warning/fallback in permissive mode. reject_unknown_fields=trueenforces closed-schema behavior for mapped roles.
9.11 dependencies schema
Example:
dependencies:
default_reltype: FINISHTOSTART
treat_missing_target_as_blocked: true
enforce_unique_uid: true
unresolved_target_severity: warning
require_resolved_uid_on_write: false
Rules:
default_reltypeMUST be one of the allowed reltype values in §10.2.treat_missing_target_as_blockedcontrols whether missing/unresolvable dependency targets contribute to blocked-state evaluation (§10.2.5).- If
treat_missing_target_as_blockedis absent, effective value MUST default totrue. enforce_unique_uid=trueenforces uniqueness at validation/write time.- If
enforce_unique_uidis absent, effective value MUST default totrue. unresolved_target_severityMUST bewarningorerror.require_resolved_uid_on_write=truerequires dependency UID resolution success for add/update operations.
9.12 links schema
Example:
links:
extensions: [".md"]
unresolved_default_severity: warning
update_references_on_rename: true
Rules:
extensionsdefines extension trial order for extensionless targets.unresolved_default_severityMUST bewarningorerror.update_references_on_rename=trueenables rename-time link rewrite behavior when supported.
9.13 title schema
Example (storage=frontmatter):
title:
storage: frontmatter
filename_format: custom
custom_filename_template: "{{date}} {{title}}"
Example (storage=filename):
title:
storage: filename
Rules:
storageMUST befrontmatterorfilename.- when
storage=frontmatter,filename_formatMUST betitle,zettel,timestamp, orcustom. - when
storage=frontmatterandfilename_format=custom,custom_filename_templateMUST be provided and non-empty. - when
storage=filename,filename_formatandcustom_filename_templateMAY be present for compatibility input but MUST be ignored for canonical write behavior. - Read precedence MUST be storage-mode-aware:
- when
storage=frontmatter, use mappedtitlekey when present and non-empty, then file basename fallback; - when
storage=filename, use file basename first, then mappedtitlefallback when basename is unavailable.
- when
- If frontmatter and basename titles both exist and differ, the source authoritative for active
storageMUST win. - If
storage=filename, canonical writes MUST treat filename as title source, MUST rename on title change, and MUST ignorefilename_formatandcustom_filename_template. - If
storage=frontmatter, canonical writes MUST persist mapped title key;filename_formatandcustom_filename_templategovern create-time filename generation.
Informative mapping to TaskNotes settings:
title.storage=filenamecorresponds tostoreTitleInFilename=true.title.filename_formatcorresponds totaskFilenameFormat.title.custom_filename_templatecorresponds tocustomFilenameTemplate.
9.14 templating schema
templating defines optional create-time template behavior.
This schema is required only for implementations claiming profile templating (§7.3.3).
Example:
templating:
enabled: true
template_path: Templates/Task.md
failure_mode: warning_fallback
unknown_variable_policy: preserve
Rules:
enabledMUST be boolean.- If
enabled=true,template_pathMUST be provided and non-empty. failure_modeMUST beerrororwarning_fallbackwhen present.unknown_variable_policyMUST bepreserveoremptywhen present.- If
failure_modeis absent, effective value MUST default towarning_fallback. - If
unknown_variable_policyis absent, effective value MUST default topreserve. - Implementations claiming
templatingMUST support portable double-brace variables from §5.3.5. - Implementations not claiming
templatingMAY ignoretemplatingsettings.
9.15 reminders schema
Example:
reminders:
date_only_anchor_time: "00:00"
apply_defaults_when_explicit: false
Rules:
date_only_anchor_timeMUST beHH:MM24-hour local time format.date_only_anchor_timeis used by §10.3.4 for relative reminders against date-only bases.apply_defaults_when_explicitMUST be boolean when present.- if
apply_defaults_when_explicitis absent, effective value MUST default tofalse. apply_defaults_when_explicit=falsemeans explicit input reminders replace default-reminder application at create time.apply_defaults_when_explicit=truemeans explicit create-time reminders are merged with defaults using §10.3.9 deterministic merge rules.
9.16 time_tracking schema
Example:
time_tracking:
auto_stop_on_complete: true
auto_stop_notification: false
Rules:
auto_stop_on_completeMUST be boolean when present.auto_stop_notificationMUST be boolean when present.- if
auto_stop_on_complete=true, completion-triggered stop behavior MUST follow §5.19.5. - if
auto_stop_notificationis absent, effective value MUST default tofalse.
9.17 compatibility schema
Example:
compatibility:
read_aliases: true
legacy_duration_field: true
legacy_local_datetime_input: false
Rules:
- Compatibility flags MUST default to conservative behavior in new collections.
legacy_local_datetime_input=trueMAY relax strict parsing for offset-less datetimes only in permissive mode; strict mode parsing rules in §3.4.2 still apply.- Enabled compatibility flags SHOULD be disclosed in conformance output (§7).
9.18 Complete configuration example (yaml_file provider)
spec_version: 0.1.0-draft
runtime_timezone: America/Los_Angeles
mapping:
title: title
status: status
priority: priority
due: due
scheduled: scheduled
completed_date: completedDate
date_created: dateCreated
date_modified: dateModified
recurrence: recurrence
recurrence_anchor: recurrenceAnchor
complete_instances: completeInstances
skipped_instances: skippedInstances
time_entries: timeEntries
blocked_by: blockedBy
reminders: reminders
task_detection:
method: tag
tag: task
default_folder: TaskNotes/Tasks
defaults:
status: open
priority: normal
recurrence_anchor: scheduled
reminders:
- id: due_minus_1d
type: relative
relatedTo: due
offset: -P1D
status:
values: [open, in-progress, done, cancelled]
default: open
completed_values: [done, cancelled]
validation:
mode: strict
reject_unknown_fields: false
dependencies:
default_reltype: FINISHTOSTART
treat_missing_target_as_blocked: true
enforce_unique_uid: true
unresolved_target_severity: warning
require_resolved_uid_on_write: false
links:
extensions: [".md"]
unresolved_default_severity: warning
update_references_on_rename: true
title:
storage: filename
templating:
enabled: false
failure_mode: warning_fallback
unknown_variable_policy: preserve
reminders:
date_only_anchor_time: "00:00"
apply_defaults_when_explicit: false
time_tracking:
auto_stop_on_complete: true
auto_stop_notification: false
compatibility:
read_aliases: true
legacy_duration_field: true
9.19 Configuration errors
Configuration validation MUST report structured errors with key path context.
Examples:
- no readable configuration provider available in strict mode
- required effective key unresolved after provider resolution (
spec_versionormapping) - missing
mapping.title status.defaultnot present instatus.values- unsupported
validation.mode validation.mode=permissivebut permissive mode is not implemented- invalid
task_detection.method - invalid
task_detection.methodsentry - empty
task_detection.tagwhentagmethod is enabled - missing
task_detection.property_namewhenpropertymethod is enabled - invalid
task_detection.combine - invalid
dependencies.default_reltype - invalid
dependencies.unresolved_target_severity - invalid
links.unresolved_default_severity - invalid
title.storage - invalid
title.filename_format - missing
title.filename_formatwhentitle.storage=frontmatter - missing
title.custom_filename_templatewhentitle.storage=frontmatterandtitle.filename_format=custom - missing
templating.template_pathwhentemplating.enabled=true - invalid
templating.failure_mode - invalid
templating.unknown_variable_policy - invalid
reminders.date_only_anchor_time - invalid
reminders.apply_defaults_when_explicit - invalid
time_tracking.auto_stop_on_complete - invalid
time_tracking.auto_stop_notification
9.20 Default collection state
This section describes what a fresh tasknotes vault looks like before any user customization. Implementations that read an existing tasknotes vault without a tasknotes.yaml SHOULD apply these defaults when data.json is absent or fields are missing.
Folder layout
MyVault/
├── TaskNotes/
│ ├── Tasks/ ← new tasks created here by default
│ └── Archive/ ← archived tasks moved here (if moveArchivedTasks=true)
└── .obsidian/
└── plugins/
└── tasknotes/
└── data.json
Task detection
Default method: tag. A file is a task if it contains the tag #task in its frontmatter tags array or inline in the body.
Default field mapping
| Semantic role | Default storage key |
|---|---|
title |
title |
status |
status |
priority |
priority |
due |
due |
scheduled |
scheduled |
contexts |
contexts |
projects |
projects |
time_estimate |
timeEstimate |
completed_date |
completedDate |
date_created |
dateCreated |
date_modified |
dateModified |
recurrence |
recurrence |
recurrence_anchor |
recurrence_anchor |
complete_instances |
complete_instances |
skipped_instances |
skipped_instances |
time_entries |
timeEntries |
blocked_by |
blockedBy |
reminders |
reminders |
Note: recurrenceAnchor, completeInstances, and skippedInstances are accepted as aliases on read (§2.5). The mixed camelCase/snake_case defaults are intentional for compatibility with historical TaskNotes frontmatter.
Default statuses
| Value | Label | isCompleted |
Order |
|---|---|---|---|
none |
None | false | 0 |
open |
Open | false | 1 |
in-progress |
In progress | false | 2 |
done |
Done | true | 3 |
Default status on create: open. Default completed status (first isCompleted=true): done.
Default priorities
| Value | Label | Weight |
|---|---|---|
none |
None | 0 |
low |
Low | 1 |
normal |
Normal | 2 |
high |
High | 3 |
Default priority on create: normal.
Title and filename defaults
title.storage:filename(filename/path is the authoritative title source)- default basename generation under
title.storage=filenamederives from semantic title using filename-safe sanitization - implementations MAY also keep mapped
titlein frontmatter as a synchronized compatibility mirror - TaskNotes
data.jsonmay still contain legacytaskFilenameFormatvalues such aszettel, but these are compatibility inputs rather than the forward default whentitle.storage=filename - title is read from filename first; frontmatter
titleis compatibility fallback when filename-derived title is unavailable (§2.2.2)
Time tracking defaults
auto_stop_on_complete:trueauto_stop_notification:false
Link format defaults
useFrontmatterMarkdownLinks:false— wikilinks used by default (e.g.[[task-name]])- To use markdown link format, the
obsidian-frontmatter-markdown-linksplugin must also be installed
Effective configuration for a minimal fresh vault
When neither data.json nor tasknotes.yaml is present, implementations MUST use the following effective configuration:
spec_version: 0.1.0-draft # synthesized
mapping:
title: title
status: status
priority: priority
due: due
scheduled: scheduled
contexts: contexts
projects: projects
time_estimate: timeEstimate
completed_date: completedDate
date_created: dateCreated
date_modified: dateModified
recurrence: recurrence
recurrence_anchor: recurrence_anchor
complete_instances: complete_instances
skipped_instances: skipped_instances
time_entries: timeEntries
blocked_by: blockedBy
reminders: reminders
task_detection:
method: tag
tag: task
default_folder: TaskNotes/Tasks
status:
values: [none, open, in-progress, done]
default: open
completed_values: [done]
title:
storage: filename
time_tracking:
auto_stop_on_complete: true
auto_stop_notification: false
links:
use_markdown_format: false
extensions: [".md"]
unresolved_default_severity: warning
update_references_on_rename: true