tasknotes-spec 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/00-overview.md +172 -0
  2. package/01-terminology.md +156 -0
  3. package/02-model-and-mapping.md +288 -0
  4. package/03-temporal-semantics.md +290 -0
  5. package/04-recurrence.md +398 -0
  6. package/05-operations.md +968 -0
  7. package/06-validation.md +267 -0
  8. package/07-conformance.md +292 -0
  9. package/08-compatibility-and-migrations.md +188 -0
  10. package/09-configuration.md +837 -0
  11. package/10-dependencies-and-reminders.md +266 -0
  12. package/11-links.md +373 -0
  13. package/CHANGELOG.md +25 -0
  14. package/README.md +80 -0
  15. package/conformance/README.md +31 -0
  16. package/conformance/adapters/mdbase-tasknotes.adapter.mjs +141 -0
  17. package/conformance/adapters/tasknotes-core/conformance.ts +2498 -0
  18. package/conformance/adapters/tasknotes-core/create-compat.ts +1 -0
  19. package/conformance/adapters/tasknotes-core/date.ts +12 -0
  20. package/conformance/adapters/tasknotes-core/field-mapping.ts +14 -0
  21. package/conformance/adapters/tasknotes-core/recurrence.ts +10 -0
  22. package/conformance/adapters/tasknotes-date-bridge.ts +20 -0
  23. package/conformance/adapters/tasknotes-runtime-bridge.ts +1107 -0
  24. package/conformance/adapters/tasknotes-runtime-obsidian-shim.ts +84 -0
  25. package/conformance/adapters/tasknotes-templating-bridge.ts +13 -0
  26. package/conformance/adapters/tasknotes.adapter.mjs +485 -0
  27. package/conformance/docs/ADAPTER_CONTRACT.md +245 -0
  28. package/conformance/docs/FIXTURE_FORMAT.md +247 -0
  29. package/conformance/docs/RUNNER_GUIDE.md +393 -0
  30. package/conformance/fixtures/config-schema.json +634 -0
  31. package/conformance/fixtures/config.json +18984 -0
  32. package/conformance/fixtures/conformance.json +444 -0
  33. package/conformance/fixtures/create-compat.json +18639 -0
  34. package/conformance/fixtures/date.json +25612 -0
  35. package/conformance/fixtures/dependencies.json +8647 -0
  36. package/conformance/fixtures/field-mapping.json +5406 -0
  37. package/conformance/fixtures/links.json +1127 -0
  38. package/conformance/fixtures/migrations.json +668 -0
  39. package/conformance/fixtures/operations.json +2761 -0
  40. package/conformance/fixtures/recurrence.json +22958 -0
  41. package/conformance/fixtures/reminders.json +13333 -0
  42. package/conformance/fixtures/templating.json +497 -0
  43. package/conformance/fixtures/validation.json +5308 -0
  44. package/conformance/lib/adapter-loader.mjs +23 -0
  45. package/conformance/lib/load-fixtures.mjs +43 -0
  46. package/conformance/lib/matchers.mjs +200 -0
  47. package/conformance/manifest.json +232 -0
  48. package/conformance/scripts/generate-fixtures.mjs +5239 -0
  49. package/conformance/scripts/package-fixtures.mjs +101 -0
  50. package/conformance/tests/coverage.test.mjs +213 -0
  51. package/conformance/tests/runner.test.mjs +102 -0
  52. package/conformance/tests/tasknotes-runtime-routing.test.mjs +64 -0
  53. package/package.json +49 -0
@@ -0,0 +1,267 @@
1
+ # 6. Validation
2
+
3
+ ## 6.1 Purpose
4
+
5
+ Validation ensures persisted task records conform to this specification and collection configuration.
6
+
7
+ ## 6.2 Validation phases
8
+
9
+ Implementations SHOULD validate in these phases:
10
+
11
+ 1. Parse validation (YAML/frontmatter structure)
12
+ 2. Schema validation (types and role constraints)
13
+ 3. Semantic validation (cross-field invariants)
14
+
15
+ ## 6.3 Validation modes
16
+
17
+ Conforming implementations MUST support:
18
+
19
+ - `strict`: errors block writes.
20
+
21
+ Implementations MAY additionally support:
22
+
23
+ - `permissive`: writes may continue with warnings.
24
+
25
+ Current mode MUST be discoverable.
26
+
27
+ ## 6.4 Required checks
28
+
29
+ A conforming validator MUST implement checks required by the claimed profile(s):
30
+
31
+ | Check ID | Requirement | Required for |
32
+ |---|---|---|
33
+ | 1 | Unconditionally required semantic roles are present (`status`, `date_created`, `date_modified`). | `core-lite` and above |
34
+ | 1a | `completed_date` conditional requiredness is enforced per §2.2.1. | `core-lite` and above |
35
+ | 1b | `title` resolves via active title policy (§2.2.2 and §9.13): storage-mode-aware precedence and fallback. | `core-lite` and above |
36
+ | 2 | Field values match role type requirements. | `core-lite` and above |
37
+ | 3 | Temporal values conform to §3. | `core-lite` and above |
38
+ | 4 | Recurrence values conform to §4 (including tasknotes recurrence-string syntax and anchor-seed resolution rules). | `recurrence` and above |
39
+ | 5 | Per-instance lists contain valid dates with no overlap. | `recurrence` and above |
40
+ | 6 | `date_modified` is not earlier than `date_created` when both exist. | `core-lite` and above |
41
+ | 7 | `time_estimate` is non-negative when present. | any profile that supports `time_estimate` |
42
+ | 8 | `time_entries` entries include required `startTime`, ranges are valid when `endTime` exists, and at most one active entry exists per task. | any profile that supports `time_entries` |
43
+ | 9 | `blocked_by` entries conform to §10.2 (shape, enum, duplicates, self-reference). | `extended` |
44
+ | 10 | `reminders` entries conform to §10.3 (shape, type-specific fields, unique ids). | `extended` |
45
+ | 11 | relative reminders have resolvable base fields or produce configured error/warning behavior. | `extended` |
46
+ | 12 | link-bearing fields (`projects`, `blocked_by.uid`) conform to §11 parsing/resolution and traversal safety. | `extended` |
47
+ | 13 | templating configuration is valid when provided (`templating` schema and enums). | `templating` |
48
+ | 14 | create-time template failures obey configured failure mode (`error` vs fallback). | `templating` |
49
+ | 15 | semantic `id` (when present) is a non-empty string; duplicate collection-level IDs SHOULD be reported when detectable. | any profile that supports semantic `id` |
50
+ | 16 | materialized occurrence notes contain valid `recurrence_parent` and `occurrence_date` roles. | `materialized-occurrences` |
51
+ | 17 | no duplicate materialized occurrence notes exist for the same resolved `(recurrence_parent, occurrence_date)` pair. | `materialized-occurrences` |
52
+ | 18 | materialization policy values and rolling horizons conform to §4.18 and §9.17. | `materialized-occurrences` |
53
+
54
+ ## 6.5 Unknown field policy
55
+
56
+ Unknown fields:
57
+
58
+ - MUST NOT fail validation by default unless collection is configured for strict schema closure.
59
+ - SHOULD generate informational warnings when strict schema closure is desired but not enabled.
60
+
61
+ ## 6.6 Issue structure
62
+
63
+ Validation issues MUST include:
64
+
65
+ - `code` (machine-readable)
66
+ - `severity` (`error`, `warning`, or `info`)
67
+ - `message` (human-readable)
68
+
69
+ Issues SHOULD include:
70
+
71
+ - `field` or path
72
+ - `expected` and `actual` details where useful
73
+
74
+ ## 6.7 Recommended issue codes
75
+
76
+ | Code | Severity (default) | Meaning |
77
+ |---|---|---|
78
+ | `missing_required` | error | required role missing |
79
+ | `invalid_type` | error | value type mismatch |
80
+ | `invalid_enum_value` | error | value not in configured set |
81
+ | `invalid_date_value` | error | malformed or impossible date |
82
+ | `invalid_datetime_value` | error | malformed datetime |
83
+ | `invalid_recurrence_rule` | error | recurrence not valid tasknotes recurrence syntax |
84
+ | `missing_recurrence_seed` | error | recurrence has no resolvable seed/start date |
85
+ | `invalid_recurrence_anchor` | error | anchor not allowed |
86
+ | `instance_state_overlap` | error | same date in complete and skipped lists |
87
+ | `invalid_time_range` | error | end before start in time entry |
88
+ | `missing_time_entry_start` | error | time entry is missing required startTime |
89
+ | `multiple_active_time_entries` | error | more than one active time entry exists in one task |
90
+ | `invalid_dependency_entry` | error | dependency object missing required fields |
91
+ | `invalid_dependency_reltype` | error | dependency reltype not allowed |
92
+ | `invalid_dependency_gap` | error | dependency gap not valid ISO 8601 duration |
93
+ | `duplicate_dependency_uid` | error in strict mode when `dependencies.enforce_unique_uid=true`; warning otherwise by policy | repeated dependency uid in task |
94
+ | `self_dependency` | error | task depends on itself |
95
+ | `unresolved_dependency_target` | warning | dependency target not resolvable |
96
+ | `invalid_reminder_entry` | error | reminder object missing required fields |
97
+ | `duplicate_reminder_id` | error | repeated reminder id in task |
98
+ | `invalid_reminder_type` | error | reminder type not allowed |
99
+ | `invalid_reminder_offset` | error | relative reminder offset not valid duration |
100
+ | `invalid_reminder_related_to` | error | relatedTo must be due or scheduled |
101
+ | `invalid_reminder_absolute_time` | error | absoluteTime invalid datetime |
102
+ | `unresolvable_reminder_base` | error | relative reminder base field missing/unusable |
103
+ | `invalid_link_format` | error | link value cannot be parsed as supported format |
104
+ | `ambiguous_link` | warning | link resolves to multiple candidates |
105
+ | `path_traversal` | error | resolved path escapes collection root |
106
+ | `unresolved_link_target` | warning | link target cannot be resolved |
107
+ | `invalid_task_id` | error | semantic `id` is empty or invalid type |
108
+ | `duplicate_task_id` | warning | duplicate semantic `id` detected in collection scope |
109
+ | `alias_conflict_ignored` | warning | alias key ignored due to canonical conflict |
110
+ | `unresolvable_title` | error | title cannot be resolved from title resolution policy |
111
+ | `title_source_conflict` | warning | mapped title and filename title differ; active title-storage policy selected authoritative source |
112
+ | `template_missing` | warning | configured template file cannot be read/found |
113
+ | `template_parse_failed` | warning | template frontmatter/body parsing or expansion failed |
114
+ | `missing_recurrence_parent` | error | materialized occurrence note omits recurrence_parent |
115
+ | `invalid_recurrence_parent` | warning | occurrence note parent reference cannot be resolved or does not reference a recurring task |
116
+ | `missing_occurrence_date` | error | materialized occurrence note omits occurrence_date |
117
+ | `duplicate_occurrence_note` | warning | more than one materialized occurrence note exists for the same parent/date |
118
+ | `occurrence_state_conflict` | warning | materialized occurrence state disagrees with parent instance lists |
119
+ | `materialization_target_not_generated` | warning | occurrence date is not generated by current parent recurrence rule |
120
+ | `missing_skipped_status` | error | skip of materialized occurrence requires configured skipped status |
121
+ | `next_occurrence_materialization_failed` | warning | triggering operation succeeded but next occurrence note could not be created |
122
+ | `orphan_occurrence_note` | warning | materialized occurrence note has no resolvable recurring parent or parent state references a deleted occurrence note |
123
+ | `unknown_field` | info | unmapped field encountered |
124
+
125
+ Implementations MAY extend this code set but SHOULD preserve existing meanings.
126
+
127
+ ## 6.8 Write-time validation behavior
128
+
129
+ In strict mode, mutating operations MUST fail if any error-severity issue is present after applying intended changes.
130
+
131
+ Warnings SHOULD NOT block writes unless explicitly configured.
132
+
133
+ Datetime/date acceptance and rejection in validation MUST follow the normative matrix in §3.4.4.
134
+
135
+ ## 6.9 Validation examples
136
+
137
+ ### 6.9.1 Missing required role
138
+
139
+ Input:
140
+
141
+ ```yaml
142
+ title: Plan workshop
143
+ status: open
144
+ dateCreated: 2026-02-20T09:00:00Z
145
+ ```
146
+
147
+ Issue:
148
+
149
+ ```yaml
150
+ code: missing_required
151
+ severity: error
152
+ field: dateModified
153
+ message: Required field 'dateModified' is missing.
154
+ ```
155
+
156
+ ### 6.9.2 Invalid recurrence anchor
157
+
158
+ Input:
159
+
160
+ ```yaml
161
+ recurrence: FREQ=DAILY
162
+ recurrenceAnchor: due
163
+ ```
164
+
165
+ Issue:
166
+
167
+ ```yaml
168
+ code: invalid_recurrence_anchor
169
+ severity: error
170
+ field: recurrenceAnchor
171
+ message: recurrence anchor must be 'scheduled' or 'completion'.
172
+ ```
173
+
174
+ ### 6.9.3 Overlap in instance state
175
+
176
+ Input:
177
+
178
+ ```yaml
179
+ completeInstances: [2026-02-20]
180
+ skippedInstances: [2026-02-20]
181
+ ```
182
+
183
+ Issue:
184
+
185
+ ```yaml
186
+ code: instance_state_overlap
187
+ severity: error
188
+ message: same date exists in complete and skipped instance lists.
189
+ ```
190
+
191
+ ### 6.9.4 Invalid dependency reltype
192
+
193
+ Input:
194
+
195
+ ```yaml
196
+ blockedBy:
197
+ - uid: "[[task-a]]"
198
+ reltype: BLOCKS
199
+ ```
200
+
201
+ Issue:
202
+
203
+ ```yaml
204
+ code: invalid_dependency_reltype
205
+ severity: error
206
+ field: blockedBy[0].reltype
207
+ message: reltype must be one of FINISHTOSTART, STARTTOSTART, FINISHTOFINISH, STARTTOFINISH.
208
+ ```
209
+
210
+ ### 6.9.5 Unresolvable reminder base
211
+
212
+ Input:
213
+
214
+ ```yaml
215
+ reminders:
216
+ - id: due_minus_1d
217
+ type: relative
218
+ relatedTo: due
219
+ offset: -P1D
220
+ ```
221
+
222
+ Issue when `due` missing:
223
+
224
+ ```yaml
225
+ code: unresolvable_reminder_base
226
+ severity: error
227
+ field: reminders[0]
228
+ message: relative reminder references due but no due value exists.
229
+ ```
230
+
231
+ ### 6.9.6 Unknown field in permissive mode
232
+
233
+ Input:
234
+
235
+ ```yaml
236
+ title: Plan workshop
237
+ status: open
238
+ vendorPriority: p1
239
+ ```
240
+
241
+ Issue example:
242
+
243
+ ```yaml
244
+ code: unknown_field
245
+ severity: info
246
+ field: vendorPriority
247
+ message: field is not mapped to a known semantic role.
248
+ ```
249
+
250
+ ### 6.9.7 Multiple active time entries
251
+
252
+ Input:
253
+
254
+ ```yaml
255
+ timeEntries:
256
+ - startTime: 2026-02-20T10:00:00Z
257
+ - startTime: 2026-02-20T11:00:00Z
258
+ ```
259
+
260
+ Issue:
261
+
262
+ ```yaml
263
+ code: multiple_active_time_entries
264
+ severity: error
265
+ field: timeEntries
266
+ message: task contains more than one active time entry.
267
+ ```
@@ -0,0 +1,292 @@
1
+ # 7. Conformance
2
+
3
+ ## 7.1 Purpose
4
+
5
+ This section defines conformance profiles and claim requirements for implementations.
6
+
7
+ ## 7.2 Conformance principles
8
+
9
+ An implementation MUST NOT claim conformance to a profile unless all required capabilities of that profile are implemented.
10
+
11
+ Implementations MAY implement additional behavior beyond a profile, but extra behavior MUST NOT violate profile requirements.
12
+
13
+ ## 7.3 Profile model
14
+
15
+ Profiles are cumulative unless explicitly marked otherwise.
16
+
17
+ ### 7.3.1 Profile: `core-lite`
18
+
19
+ Required capabilities:
20
+
21
+ - task identification and loading
22
+ - semantic-role mapping and canonical writes (§2)
23
+ - required role support (`title`, `status`, `completed_date`, `date_created`, `date_modified`)
24
+ - create, update, delete operations (§5)
25
+ - non-recurring complete/uncomplete (§5)
26
+ - temporal parsing/canonical serialization basics (§3)
27
+ - strict validation mode support (§6.3)
28
+ - validation core checks (§6.4 items 1,1a,1b,2,3,6)
29
+
30
+ ### 7.3.2 Profile: `recurrence`
31
+
32
+ Additional required capabilities:
33
+
34
+ - tasknotes recurrence-string parsing/validation, including RRULE parameter syntax and inline `DTSTART` handling
35
+ - recurrence anchor semantics, including seed precedence and completion-anchor progression
36
+ - complete/uncomplete instance
37
+ - skip/unskip instance
38
+ - instance-list invariants and effective state resolution
39
+ - validation checks for recurrence and instance overlap
40
+
41
+ ### 7.3.3 Profile: `templating` (non-cumulative extension)
42
+
43
+ This profile is not cumulative; it MAY be claimed alongside `core-lite`, `recurrence`, `materialized-occurrences`, and/or `extended`.
44
+ `templating` MUST NOT be claimed alone.
45
+
46
+ Required capabilities:
47
+
48
+ - create-time template processing semantics per §5.3.5
49
+ - `templating` configuration support per §9.14
50
+ - deterministic template/frontmatter/body merge behavior
51
+ - deterministic failure-mode behavior for template read/parse failures
52
+ - support for portable double-brace template variables defined in §5.3.5
53
+
54
+ ### 7.3.4 Profile: `materialized-occurrences` (non-cumulative extension)
55
+
56
+ This profile is not cumulative; it MUST be claimed alongside `recurrence`.
57
+ It MAY be claimed alongside `extended` and/or `templating`, but it does not require either.
58
+
59
+ Required capabilities:
60
+
61
+ - materialized occurrence roles and identity semantics (§2.6.6)
62
+ - recurrence materialization semantics (§4.18)
63
+ - materialize/complete/skip/uncomplete/unskip materialized occurrence operations (§5.20)
64
+ - `occurrences` configuration defaults (§9.17)
65
+ - parent-reference link parsing/resolution for `recurrence_parent` (§11), without requiring full `extended`
66
+ - validation checks for materialized occurrence identity, duplicates, and state conflicts (§6.4 items 16-18)
67
+
68
+ Claiming `materialized-occurrences` also has required capability-token implications:
69
+
70
+ - `meta.claim.capabilities` MUST include `materialized-occurrences`.
71
+ - `meta.claim.profiles` MUST also include `recurrence`.
72
+ - Omitting either token while claiming `materialized-occurrences` is a non-conformant claim.
73
+
74
+ ### 7.3.5 Profile: `extended`
75
+
76
+ Additional required capabilities:
77
+
78
+ - dependency schema support (`blocked_by`)
79
+ - reminder schema support (`reminders`)
80
+ - link parsing/resolution semantics for link-bearing fields (§11)
81
+ - time-tracking management semantics for `time_entries` (§5.19), including per-task active-session constraints
82
+ - dependency operations and validation per §10.2
83
+ - reminder operations and validation per §10.3
84
+
85
+ If `extended` is claimed, all of the above baseline capabilities MUST conform to documented semantics.
86
+
87
+ Claiming `extended` also has required capability-token implications:
88
+
89
+ - `meta.claim.capabilities` MUST include `dependencies`, `reminders`, `links`, and `time-tracking`.
90
+ - Omitting any of these tokens while claiming `extended` is a non-conformant claim (even if capability-gated fixtures are skipped by a runner).
91
+
92
+ Optional capability extensions within `extended`:
93
+
94
+ - `rename` capability: reference-aware rename behavior (including dependency UID references)
95
+ - `archive` capability: archive semantics (§5.12)
96
+ - `batch` capability: batch operations with per-item outcomes (§5.15)
97
+ - `concurrency` capability: write-conflict detection semantics (§5.16)
98
+ - `dry-run` capability: dry-run semantics (§5.17)
99
+
100
+ When an optional capability token is claimed, corresponding behavior MUST conform to documented semantics.
101
+
102
+ ## 7.4 Conformance claim format
103
+
104
+ A conformance claim MUST include:
105
+
106
+ - implementation name and version,
107
+ - `tasknotes-spec` version,
108
+ - claimed profile list,
109
+ - validation mode support (`strict` required; `permissive` optional),
110
+ - known deviations,
111
+ - compatibility mode status (if any),
112
+ - configuration provider status (active provider chain, precedence policy, and fallback state).
113
+
114
+ Example:
115
+
116
+ ```text
117
+ Implementation: example-task-cli v1.4.0
118
+ Spec: tasknotes-spec 0.2.0-draft
119
+ Profiles: core-lite, recurrence, templating
120
+ Validation modes: strict, permissive
121
+ Known deviations: none
122
+ Compatibility mode: disabled
123
+ Configuration providers: tasknotes_plugin_data_json > built_in_defaults
124
+ Configuration fallback: none
125
+ ```
126
+
127
+ ## 7.5 Deviation disclosure
128
+
129
+ Any known deviation from normative text MUST be explicitly disclosed in conformance output/documentation.
130
+
131
+ A deviation entry SHOULD include:
132
+
133
+ - affected section,
134
+ - deviation summary,
135
+ - impact,
136
+ - planned resolution version.
137
+
138
+ ## 7.6 Feature detection
139
+
140
+ Implementations SHOULD expose machine-readable capability metadata, including:
141
+
142
+ - profiles
143
+ - effective runtime timezone
144
+ - active configuration providers and precedence chain
145
+ - enabled compatibility modes
146
+ - configurable status sets
147
+ - supported mapping aliases
148
+ - templating support flags and effective templating failure mode
149
+ - dependency and reminder support flags
150
+ - time-tracking support flags, including active-session policy and auto-stop-on-complete behavior
151
+ - materialized occurrence support flags, including materialization mode, next trigger, and rolling bounds
152
+
153
+ ## 7.7 Strictness disclosure
154
+
155
+ Conformance requires `strict` validation mode support (§6.3).
156
+
157
+ Conformance claims MUST indicate whether `permissive` mode is also supported.
158
+
159
+ ## 7.8 Example profile matrix
160
+
161
+ | Capability | core-lite | recurrence | templating | materialized-occurrences | extended |
162
+ |---|---:|---:|---:|---:|---:|
163
+ | create/update/delete | required | required | companion-profile required | companion-profile required | required |
164
+ | non-recurring complete | required | required | companion-profile required | companion-profile required | required |
165
+ | recurring instance complete/skip | - | required | optional | required via companion `recurrence` claim | required |
166
+ | materialize occurrence notes (§4.18, §5.20) | - | - | optional | required | optional |
167
+ | recurrence parent link resolution | - | - | optional | required for `recurrence_parent` only | required |
168
+ | template expansion/merge (§5.3.5) | - | - | required | optional | optional |
169
+ | double-brace portable variable support | - | - | required | optional | optional |
170
+ | recurrence-string validation | - | required | optional | required via companion `recurrence` claim | required |
171
+ | link parsing/resolution (§11) | - | - | optional | required for `recurrence_parent` only | required |
172
+ | dependency schema and ops | - | - | optional | optional | required |
173
+ | reminder schema and ops | - | - | optional | optional | required |
174
+ | time tracking start/stop/edit semantics (§5.19) | - | - | optional | optional | required |
175
+ | rename updates dependency/project links | - | - | optional | optional | optional via `rename` capability |
176
+ | archive semantics (§5.12) | - | - | optional | optional | optional via `archive` capability |
177
+ | batch per-item outcomes (§5.15) | - | - | optional | optional | optional via `batch` capability |
178
+ | write-conflict detection (§5.16) | - | - | optional | optional | optional via `concurrency` capability |
179
+ | dry-run reporting (§5.17) | - | - | optional | optional | optional via `dry-run` capability |
180
+
181
+ ## 7.9 Executable fixture suite
182
+
183
+ This specification includes an executable fixture suite in `conformance/`.
184
+
185
+ - language-neutral fixtures are stored in `conformance/fixtures/*.json`
186
+ - section/profile/operation coverage is tracked in `conformance/manifest.json`
187
+ - coverage guard tests MUST enforce both section representation and minimum-depth thresholds for key sections/operations.
188
+ - adapters execute fixture operations per `conformance/docs/ADAPTER_CONTRACT.md`
189
+ - runners MUST execute fixtures only when both conditions hold:
190
+ - fixture `profile` is satisfied by claimed adapter profiles under cumulative profile rules (§7.3),
191
+ - all fixture `requires` capability tokens are present.
192
+
193
+ Fixture expectations MUST be profile-modular: they MUST NOT assume capability values or profile memberships beyond what the fixture's own `profile`/`requires` gating guarantees.
194
+ Fixtures for optional extension capabilities (`rename`, `archive`, `batch`, `concurrency`, `dry-run`) MUST be capability-gated via `requires` and MUST NOT rely on `extended` profile membership alone.
195
+
196
+ Conformance claims SHOULD report fixture pass/fail results against the claimed profiles.
197
+
198
+ ## 7.10 Meta operations
199
+
200
+ The following operations are part of the conformance interface and MUST be supported by any adapter that participates in the conformance suite, regardless of claimed profile. These meta operations MUST be callable without requiring any capability token.
201
+
202
+ ### `meta.claim`
203
+
204
+ Returns the adapter's self-reported metadata.
205
+
206
+ Input: `{}` (empty object)
207
+
208
+ Output:
209
+ ```json
210
+ {
211
+ "ok": true,
212
+ "result": {
213
+ "implementation": "my-tool",
214
+ "version": "1.0.0",
215
+ "spec_version": "0.2.0-draft",
216
+ "validation_modes": ["strict"],
217
+ "profiles": ["core-lite", "recurrence"],
218
+ "capabilities": ["dependencies", "links"]
219
+ }
220
+ }
221
+ ```
222
+
223
+ Fields:
224
+
225
+ | Field | Type | Required | Description |
226
+ |---|---|---|---|
227
+ | `implementation` | string | yes | Human-readable implementation name |
228
+ | `version` | string | yes | Implementation version string |
229
+ | `spec_version` | string | yes | `tasknotes-spec` version targeted by this adapter |
230
+ | `validation_modes` | string[] | yes | Supported validation modes; MUST include `strict` |
231
+ | `profiles` | string[] | yes | Claimed conformance profiles; valid values: `core-lite`, `recurrence`, `extended`, `templating`, `materialized-occurrences` |
232
+ | `capabilities` | string[] | yes | Optional capability tokens; known tokens listed in §7.11 |
233
+
234
+ `profiles` lists explicitly claimed profiles. Cumulative profile expansion is applied by runners for fixture selection (§7.3, §7.9), but does not change literal membership semantics of `meta.has_profile`.
235
+
236
+ Profile-token consistency rules:
237
+
238
+ - If `profiles` contains `extended`, `capabilities` MUST include `dependencies`, `reminders`, `links`, and `time-tracking`.
239
+ - If `profiles` contains `templating`, `capabilities` MUST include `templating`.
240
+ - If `profiles` contains `materialized-occurrences`, `profiles` MUST also contain `recurrence` and `capabilities` MUST include `materialized-occurrences`.
241
+ - Runners and fixture suites SHOULD validate these claim-consistency rules directly from `meta.claim`, not only by capability-gating feature fixtures.
242
+
243
+ ### `meta.has_capability`
244
+
245
+ Tests whether the adapter claims a specific capability.
246
+
247
+ Input:
248
+ ```json
249
+ { "capability": "dependencies" }
250
+ ```
251
+
252
+ Output:
253
+ ```json
254
+ { "ok": true, "result": { "value": true } }
255
+ ```
256
+
257
+ `result.value` MUST be `true` if the capability is in the `capabilities` array returned by `meta.claim`, and `false` otherwise.
258
+
259
+ ### `meta.has_profile`
260
+
261
+ Tests whether the adapter claims a specific conformance profile.
262
+
263
+ Input:
264
+ ```json
265
+ { "profile": "recurrence" }
266
+ ```
267
+
268
+ Output:
269
+ ```json
270
+ { "ok": true, "result": { "value": true } }
271
+ ```
272
+
273
+ `result.value` MUST be `true` if the profile is in the `profiles` array returned by `meta.claim`, and `false` otherwise.
274
+
275
+ ## 7.11 Known capability tokens
276
+
277
+ The following capability tokens are defined by this specification. Implementations MAY define additional tokens.
278
+
279
+ | Token | Required by profile | Meaning |
280
+ |---|---|---|
281
+ | `dependencies` | `extended` | Supports `blocked_by`, dependency operations, and dependency validation |
282
+ | `reminders` | `extended` | Supports `reminders`, reminder operations, and reminder validation |
283
+ | `links` | `extended` | Supports link parsing and resolution (§11) |
284
+ | `time-tracking` | `extended` | Supports time-tracking management operations (§5.19) |
285
+ | `materialized-occurrences` | `materialized-occurrences` | Supports recurrence materialization and materialized occurrence operations (§4.18, §5.20) |
286
+ | `rename` | optional extension under `extended` | Supports file rename with reference updates |
287
+ | `archive` | optional extension under `extended` | Supports archive semantics (§5.12) |
288
+ | `batch` | optional extension under `extended` | Supports batch operations with per-item outcomes (§5.15) |
289
+ | `concurrency` | optional extension under `extended` | Supports write-conflict detection (§5.16) |
290
+ | `dry-run` | optional extension under `extended` | Supports dry-run mode (§5.17) |
291
+ | `migration` | — | Supports migration operations (§8) |
292
+ | `templating` | `templating` | Supports create-time templating (§5.3.5) |