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,668 @@
1
+ [
2
+ {
3
+ "id": "migration.0001",
4
+ "section": "§8.2",
5
+ "profile": "core-lite",
6
+ "operation": "migration.compat_mode",
7
+ "assertion": "envelope_equals",
8
+ "requires": [
9
+ "migration"
10
+ ],
11
+ "input": {
12
+ "mode": "legacy-aliases",
13
+ "enabled": false,
14
+ "defaultsToEnabled": false
15
+ },
16
+ "expect": {
17
+ "ok": true,
18
+ "result": {
19
+ "discoverable": true,
20
+ "defaultsToEnabled": false
21
+ }
22
+ }
23
+ },
24
+ {
25
+ "id": "migration.0002",
26
+ "section": "§8.2",
27
+ "profile": "core-lite",
28
+ "operation": "migration.compat_mode",
29
+ "assertion": "envelope_equals",
30
+ "requires": [
31
+ "migration"
32
+ ],
33
+ "input": {
34
+ "mode": "legacy-aliases",
35
+ "enabled": true,
36
+ "defaultsToEnabled": false
37
+ },
38
+ "expect": {
39
+ "ok": true,
40
+ "result": {
41
+ "discoverable": true
42
+ }
43
+ }
44
+ },
45
+ {
46
+ "id": "migration.0003",
47
+ "section": "§8.3",
48
+ "profile": "core-lite",
49
+ "operation": "migration.plan",
50
+ "assertion": "envelope_equals",
51
+ "requires": [
52
+ "migration"
53
+ ],
54
+ "input": {
55
+ "dryRun": true,
56
+ "rollbackGuidance": true,
57
+ "deterministic": true
58
+ },
59
+ "expect": {
60
+ "ok": true,
61
+ "result": {
62
+ "deterministic": true,
63
+ "dryRunSupported": true,
64
+ "rollbackSafeGuidance": true
65
+ }
66
+ }
67
+ },
68
+ {
69
+ "id": "migration.0004",
70
+ "section": "§8.4",
71
+ "profile": "core-lite",
72
+ "operation": "migration.normalize_aliases",
73
+ "assertion": "envelope_equals",
74
+ "requires": [
75
+ "migration"
76
+ ],
77
+ "input": {
78
+ "frontmatter": {
79
+ "recurrenceAnchor": "scheduled",
80
+ "recurrence_anchor": "completion"
81
+ }
82
+ },
83
+ "expect": {
84
+ "ok": true,
85
+ "result": {
86
+ "frontmatter": {
87
+ "$contains": {
88
+ "recurrenceAnchor": "scheduled"
89
+ }
90
+ },
91
+ "issues": {
92
+ "$contains": [
93
+ {
94
+ "code": "alias_conflict_ignored"
95
+ }
96
+ ]
97
+ }
98
+ }
99
+ }
100
+ },
101
+ {
102
+ "id": "migration.0005",
103
+ "section": "§8.4",
104
+ "profile": "core-lite",
105
+ "operation": "migration.normalize_aliases",
106
+ "assertion": "envelope_equals",
107
+ "requires": [
108
+ "migration"
109
+ ],
110
+ "input": {
111
+ "frontmatter": {
112
+ "recurrence_anchor": "scheduled"
113
+ }
114
+ },
115
+ "expect": {
116
+ "ok": true,
117
+ "result": {
118
+ "frontmatter": {
119
+ "$contains": {
120
+ "recurrenceAnchor": "scheduled"
121
+ }
122
+ }
123
+ }
124
+ }
125
+ },
126
+ {
127
+ "id": "migration.0006",
128
+ "section": "§8.5",
129
+ "profile": "core-lite",
130
+ "operation": "migration.normalize_temporal",
131
+ "assertion": "envelope_equals",
132
+ "requires": [
133
+ "migration"
134
+ ],
135
+ "input": {
136
+ "frontmatter": {
137
+ "dateCreated": "2026-02-20 10:00:00+00:00"
138
+ }
139
+ },
140
+ "expect": {
141
+ "ok": true,
142
+ "result": {
143
+ "frontmatter": {
144
+ "$contains": {
145
+ "dateCreated": "2026-02-20T10:00:00Z"
146
+ }
147
+ }
148
+ }
149
+ }
150
+ },
151
+ {
152
+ "id": "migration.0007",
153
+ "section": "§8.5",
154
+ "profile": "core-lite",
155
+ "operation": "migration.normalize_temporal",
156
+ "assertion": "envelope_equals",
157
+ "requires": [
158
+ "migration"
159
+ ],
160
+ "input": {
161
+ "frontmatter": {
162
+ "dateCreated": "2026-02-20T10:00:00Z",
163
+ "dateModified": "2026-02-20T11:00:00Z"
164
+ }
165
+ },
166
+ "expect": {
167
+ "ok": true,
168
+ "result": {
169
+ "frontmatter": {
170
+ "$contains": {
171
+ "dateCreated": "2026-02-20T10:00:00Z",
172
+ "dateModified": "2026-02-20T11:00:00Z"
173
+ }
174
+ }
175
+ }
176
+ }
177
+ },
178
+ {
179
+ "id": "migration.0008",
180
+ "section": "§8.5",
181
+ "profile": "core-lite",
182
+ "operation": "migration.normalize_temporal",
183
+ "assertion": "envelope_equals",
184
+ "requires": [
185
+ "migration"
186
+ ],
187
+ "input": {
188
+ "frontmatter": {
189
+ "dateCreated": "2026-02-20 10:00:00+00:00",
190
+ "dateModified": "2026-02-20 11:00:00+00:00"
191
+ }
192
+ },
193
+ "expect": {
194
+ "ok": true,
195
+ "result": {
196
+ "frontmatter": {
197
+ "$contains": {
198
+ "dateCreated": "2026-02-20T10:00:00Z",
199
+ "dateModified": "2026-02-20T11:00:00Z"
200
+ }
201
+ }
202
+ }
203
+ }
204
+ },
205
+ {
206
+ "id": "migration.0009",
207
+ "section": "§8.6",
208
+ "profile": "recurrence",
209
+ "operation": "migration.resolve_instance_overlap",
210
+ "assertion": "envelope_equals",
211
+ "requires": [
212
+ "migration"
213
+ ],
214
+ "input": {
215
+ "completeInstances": [
216
+ "2026-02-20",
217
+ "2026-02-21"
218
+ ],
219
+ "skippedInstances": [
220
+ "2026-02-20"
221
+ ],
222
+ "policy": "prefer_complete"
223
+ },
224
+ "expect": {
225
+ "ok": true,
226
+ "result": {
227
+ "completeInstances": {
228
+ "$contains": [
229
+ "2026-02-20",
230
+ "2026-02-21"
231
+ ]
232
+ },
233
+ "skippedInstances": []
234
+ }
235
+ }
236
+ },
237
+ {
238
+ "id": "migration.0010",
239
+ "section": "§8.6",
240
+ "profile": "recurrence",
241
+ "operation": "migration.resolve_instance_overlap",
242
+ "assertion": "envelope_equals",
243
+ "requires": [
244
+ "migration"
245
+ ],
246
+ "input": {
247
+ "completeInstances": [
248
+ "2026-02-20",
249
+ "2026-02-21"
250
+ ],
251
+ "skippedInstances": [
252
+ "2026-02-20"
253
+ ],
254
+ "policy": "prefer_skip"
255
+ },
256
+ "expect": {
257
+ "ok": true,
258
+ "result": {
259
+ "completeInstances": {
260
+ "$contains": [
261
+ "2026-02-21"
262
+ ]
263
+ },
264
+ "skippedInstances": {
265
+ "$contains": [
266
+ "2026-02-20"
267
+ ]
268
+ }
269
+ }
270
+ }
271
+ },
272
+ {
273
+ "id": "migration.0011",
274
+ "section": "§8.6",
275
+ "profile": "recurrence",
276
+ "operation": "migration.resolve_instance_overlap",
277
+ "assertion": "envelope_equals",
278
+ "requires": [
279
+ "migration"
280
+ ],
281
+ "input": {
282
+ "completeInstances": [
283
+ "2026-02-20"
284
+ ],
285
+ "skippedInstances": [
286
+ "2026-02-21"
287
+ ],
288
+ "policy": "prefer_complete"
289
+ },
290
+ "expect": {
291
+ "ok": true,
292
+ "result": {
293
+ "completeInstances": {
294
+ "$contains": [
295
+ "2026-02-20"
296
+ ]
297
+ },
298
+ "skippedInstances": {
299
+ "$contains": [
300
+ "2026-02-21"
301
+ ]
302
+ }
303
+ }
304
+ }
305
+ },
306
+ {
307
+ "id": "migration.0012",
308
+ "section": "§8.7",
309
+ "profile": "extended",
310
+ "operation": "migration.normalize_dependencies",
311
+ "assertion": "envelope_equals",
312
+ "requires": [
313
+ "migration",
314
+ "dependencies"
315
+ ],
316
+ "input": {
317
+ "blockedBy": [
318
+ {
319
+ "uid": "[[a]]"
320
+ },
321
+ {
322
+ "uid": "[[a]]",
323
+ "reltype": "FINISHTOSTART"
324
+ },
325
+ {
326
+ "uid": "[[b]]",
327
+ "reltype": "STARTTOSTART"
328
+ }
329
+ ],
330
+ "defaultReltype": "FINISHTOSTART"
331
+ },
332
+ "expect": {
333
+ "ok": true,
334
+ "result": {
335
+ "blockedBy": {
336
+ "$contains": [
337
+ {
338
+ "uid": "[[a]]",
339
+ "reltype": "FINISHTOSTART"
340
+ },
341
+ {
342
+ "uid": "[[b]]",
343
+ "reltype": "STARTTOSTART"
344
+ }
345
+ ]
346
+ }
347
+ }
348
+ }
349
+ },
350
+ {
351
+ "id": "migration.0013",
352
+ "section": "§8.7",
353
+ "profile": "extended",
354
+ "operation": "migration.normalize_dependencies",
355
+ "assertion": "envelope_equals",
356
+ "requires": [
357
+ "migration",
358
+ "dependencies"
359
+ ],
360
+ "input": {
361
+ "blockedBy": [],
362
+ "defaultReltype": "FINISHTOSTART"
363
+ },
364
+ "expect": {
365
+ "ok": true,
366
+ "result": {
367
+ "blockedBy": []
368
+ }
369
+ }
370
+ },
371
+ {
372
+ "id": "migration.0014",
373
+ "section": "§8.7",
374
+ "profile": "extended",
375
+ "operation": "migration.normalize_dependencies",
376
+ "assertion": "envelope_equals",
377
+ "requires": [
378
+ "migration",
379
+ "dependencies"
380
+ ],
381
+ "input": {
382
+ "blockedBy": [
383
+ {
384
+ "uid": "[[a]]"
385
+ },
386
+ {
387
+ "uid": "[[b]]",
388
+ "reltype": "STARTTOSTART"
389
+ }
390
+ ],
391
+ "defaultReltype": "FINISHTOSTART"
392
+ },
393
+ "expect": {
394
+ "ok": true,
395
+ "result": {
396
+ "blockedBy": {
397
+ "$contains": [
398
+ {
399
+ "uid": "[[a]]",
400
+ "reltype": "FINISHTOSTART"
401
+ },
402
+ {
403
+ "uid": "[[b]]",
404
+ "reltype": "STARTTOSTART"
405
+ }
406
+ ]
407
+ }
408
+ }
409
+ }
410
+ },
411
+ {
412
+ "id": "migration.0015",
413
+ "section": "§8.8",
414
+ "profile": "extended",
415
+ "operation": "migration.normalize_reminders",
416
+ "assertion": "envelope_equals",
417
+ "requires": [
418
+ "migration",
419
+ "reminders"
420
+ ],
421
+ "input": {
422
+ "reminders": [
423
+ {
424
+ "type": "relative",
425
+ "relatedTo": "due",
426
+ "offset": "-P1D"
427
+ },
428
+ {
429
+ "id": "x",
430
+ "type": "absolute",
431
+ "absoluteTime": "2026-02-20 09:00:00+00:00"
432
+ }
433
+ ],
434
+ "generateIds": true
435
+ },
436
+ "expect": {
437
+ "ok": true,
438
+ "result": {
439
+ "generated_ids": {
440
+ "$regex": "^[0-9]+$"
441
+ }
442
+ }
443
+ }
444
+ },
445
+ {
446
+ "id": "migration.0016",
447
+ "section": "§8.8",
448
+ "profile": "extended",
449
+ "operation": "migration.normalize_reminders",
450
+ "assertion": "envelope_equals",
451
+ "requires": [
452
+ "migration",
453
+ "reminders"
454
+ ],
455
+ "input": {
456
+ "reminders": [
457
+ {
458
+ "id": "r1",
459
+ "type": "relative",
460
+ "relatedTo": "due",
461
+ "offset": "-P1D"
462
+ },
463
+ {
464
+ "id": "r2",
465
+ "type": "absolute",
466
+ "absoluteTime": "2026-02-20 09:00:00+00:00"
467
+ }
468
+ ],
469
+ "generateIds": false
470
+ },
471
+ "expect": {
472
+ "ok": true,
473
+ "result": {
474
+ "reminders": {
475
+ "$contains": [
476
+ {
477
+ "id": "r1"
478
+ },
479
+ {
480
+ "id": "r2",
481
+ "absoluteTime": "2026-02-20T09:00:00Z"
482
+ }
483
+ ]
484
+ }
485
+ }
486
+ }
487
+ },
488
+ {
489
+ "id": "migration.0017",
490
+ "section": "§8.9",
491
+ "profile": "extended",
492
+ "operation": "migration.normalize_links",
493
+ "assertion": "envelope_equals",
494
+ "requires": [
495
+ "migration",
496
+ "links"
497
+ ],
498
+ "input": {
499
+ "links": [
500
+ "[[task-001|Task]]",
501
+ "[Doc](docs/doc.md)",
502
+ "docs/doc.md"
503
+ ]
504
+ },
505
+ "expect": {
506
+ "ok": true,
507
+ "result": {
508
+ "normalized": {
509
+ "$contains": [
510
+ "[[task-001|Task]]"
511
+ ]
512
+ }
513
+ }
514
+ }
515
+ },
516
+ {
517
+ "id": "migration.0018",
518
+ "section": "§8.9",
519
+ "profile": "extended",
520
+ "operation": "migration.normalize_links",
521
+ "assertion": "envelope_equals",
522
+ "requires": [
523
+ "migration",
524
+ "links"
525
+ ],
526
+ "input": {
527
+ "links": [
528
+ "[[task-001]]",
529
+ "[[task-002|Alias]]"
530
+ ]
531
+ },
532
+ "expect": {
533
+ "ok": true,
534
+ "result": {
535
+ "normalized": {
536
+ "$contains": [
537
+ "[[task-001]]",
538
+ "[[task-002|Alias]]"
539
+ ]
540
+ }
541
+ }
542
+ }
543
+ },
544
+ {
545
+ "id": "migration.0019",
546
+ "section": "§8.13",
547
+ "profile": "core-lite",
548
+ "operation": "migration.report_summary",
549
+ "assertion": "envelope_equals",
550
+ "requires": [
551
+ "migration"
552
+ ],
553
+ "input": {
554
+ "files_scanned": 214,
555
+ "files_changed": 67,
556
+ "warnings": {
557
+ "alias_conflict_ignored": 3
558
+ },
559
+ "changes": {
560
+ "normalized_datetime_fields": 41
561
+ }
562
+ },
563
+ "expect": {
564
+ "ok": true,
565
+ "result": {
566
+ "spec_version_from": {
567
+ "$regex": ".+"
568
+ },
569
+ "spec_version_to": {
570
+ "$regex": ".+"
571
+ },
572
+ "files_scanned": 214,
573
+ "files_changed": 67
574
+ }
575
+ }
576
+ },
577
+ {
578
+ "id": "migration.0020",
579
+ "section": "§8.10",
580
+ "profile": "core-lite",
581
+ "operation": "migration.divergence_register",
582
+ "assertion": "envelope_equals",
583
+ "requires": [
584
+ "migration"
585
+ ],
586
+ "input": {},
587
+ "expect": {
588
+ "ok": true,
589
+ "result": {
590
+ "columns": {
591
+ "$contains": [
592
+ "section",
593
+ "current_behavior",
594
+ "target_behavior",
595
+ "migration_strategy",
596
+ "deprecation_timeline"
597
+ ]
598
+ }
599
+ }
600
+ }
601
+ },
602
+ {
603
+ "id": "migration.0021",
604
+ "section": "§8.11",
605
+ "profile": "core-lite",
606
+ "operation": "migration.deprecation_policy",
607
+ "assertion": "envelope_equals",
608
+ "requires": [
609
+ "migration"
610
+ ],
611
+ "input": {},
612
+ "expect": {
613
+ "ok": true,
614
+ "result": {
615
+ "includes": {
616
+ "$contains": [
617
+ "release_notes",
618
+ "warning_period",
619
+ "migration_tooling",
620
+ "versioned_removal"
621
+ ]
622
+ }
623
+ }
624
+ }
625
+ },
626
+ {
627
+ "id": "migration.0022",
628
+ "section": "§8.12",
629
+ "profile": "core-lite",
630
+ "operation": "migration.safety_guards",
631
+ "assertion": "envelope_equals",
632
+ "requires": [
633
+ "migration"
634
+ ],
635
+ "input": {},
636
+ "expect": {
637
+ "ok": true,
638
+ "result": {
639
+ "prevents": {
640
+ "$contains": [
641
+ "drop_unknown_fields",
642
+ "date_to_datetime_silent_conversion",
643
+ "silent_link_retarget"
644
+ ]
645
+ }
646
+ }
647
+ }
648
+ },
649
+ {
650
+ "id": "migration.0023",
651
+ "section": "§8.14",
652
+ "profile": "core-lite",
653
+ "operation": "migration.compat_statement",
654
+ "assertion": "envelope_equals",
655
+ "requires": [
656
+ "migration"
657
+ ],
658
+ "input": {},
659
+ "expect": {
660
+ "ok": true,
661
+ "result": {
662
+ "value": {
663
+ "$regex": "Compatibility mode|legacy|Migration command"
664
+ }
665
+ }
666
+ }
667
+ }
668
+ ]