@davidorex/pi-context 0.30.0 → 0.32.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 (90) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +27 -11
  3. package/dist/block-api.d.ts +13 -0
  4. package/dist/block-api.d.ts.map +1 -1
  5. package/dist/block-api.js +28 -3
  6. package/dist/block-api.js.map +1 -1
  7. package/dist/content-hash.d.ts +13 -0
  8. package/dist/content-hash.d.ts.map +1 -1
  9. package/dist/content-hash.js +16 -0
  10. package/dist/content-hash.js.map +1 -1
  11. package/dist/context-dir.d.ts +12 -0
  12. package/dist/context-dir.d.ts.map +1 -1
  13. package/dist/context-dir.js +14 -0
  14. package/dist/context-dir.js.map +1 -1
  15. package/dist/context-sdk.d.ts +71 -33
  16. package/dist/context-sdk.d.ts.map +1 -1
  17. package/dist/context-sdk.js +547 -149
  18. package/dist/context-sdk.js.map +1 -1
  19. package/dist/context.d.ts +213 -2
  20. package/dist/context.d.ts.map +1 -1
  21. package/dist/context.js +119 -5
  22. package/dist/context.js.map +1 -1
  23. package/dist/index.d.ts +595 -9
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2225 -55
  26. package/dist/index.js.map +1 -1
  27. package/dist/lens-view.d.ts +0 -5
  28. package/dist/lens-view.d.ts.map +1 -1
  29. package/dist/lens-view.js +43 -1
  30. package/dist/lens-view.js.map +1 -1
  31. package/dist/migration-registry-loader.d.ts +36 -12
  32. package/dist/migration-registry-loader.d.ts.map +1 -1
  33. package/dist/migration-registry-loader.js +79 -17
  34. package/dist/migration-registry-loader.js.map +1 -1
  35. package/dist/migrations-store.d.ts +45 -18
  36. package/dist/migrations-store.d.ts.map +1 -1
  37. package/dist/migrations-store.js +56 -22
  38. package/dist/migrations-store.js.map +1 -1
  39. package/dist/ops-registry.d.ts +16 -0
  40. package/dist/ops-registry.d.ts.map +1 -1
  41. package/dist/ops-registry.js +352 -117
  42. package/dist/ops-registry.js.map +1 -1
  43. package/dist/pending-blocked-store.d.ts +83 -0
  44. package/dist/pending-blocked-store.d.ts.map +1 -0
  45. package/dist/pending-blocked-store.js +93 -0
  46. package/dist/pending-blocked-store.js.map +1 -0
  47. package/dist/promote-item.d.ts.map +1 -1
  48. package/dist/promote-item.js +41 -12
  49. package/dist/promote-item.js.map +1 -1
  50. package/dist/roadmap-plan.d.ts +121 -99
  51. package/dist/roadmap-plan.d.ts.map +1 -1
  52. package/dist/roadmap-plan.js +281 -345
  53. package/dist/roadmap-plan.js.map +1 -1
  54. package/dist/schema-merge.d.ts +26 -0
  55. package/dist/schema-merge.d.ts.map +1 -0
  56. package/dist/schema-merge.js +176 -0
  57. package/dist/schema-merge.js.map +1 -0
  58. package/dist/status-vocab.d.ts +12 -2
  59. package/dist/status-vocab.d.ts.map +1 -1
  60. package/dist/status-vocab.js +14 -1
  61. package/dist/status-vocab.js.map +1 -1
  62. package/package.json +2 -1
  63. package/samples/blocks/milestone.json +3 -0
  64. package/samples/blocks/session-notes.json +1 -0
  65. package/samples/conception.json +358 -15
  66. package/samples/migrations.json +8 -0
  67. package/samples/schemas/context-contracts.schema.json +4 -0
  68. package/samples/schemas/conventions.schema.json +4 -0
  69. package/samples/schemas/decisions.schema.json +4 -0
  70. package/samples/schemas/features.schema.json +4 -0
  71. package/samples/schemas/framework-gaps.schema.json +5 -1
  72. package/samples/schemas/issues.schema.json +30 -2
  73. package/samples/schemas/layer-plans.schema.json +6 -2
  74. package/samples/schemas/milestone.schema.json +79 -0
  75. package/samples/schemas/phase.schema.json +4 -0
  76. package/samples/schemas/rationale.schema.json +4 -0
  77. package/samples/schemas/requirements.schema.json +4 -0
  78. package/samples/schemas/research.schema.json +5 -1
  79. package/samples/schemas/session-notes.schema.json +89 -0
  80. package/samples/schemas/spec-reviews.schema.json +4 -0
  81. package/samples/schemas/story.schema.json +8 -0
  82. package/samples/schemas/tasks.schema.json +4 -0
  83. package/samples/schemas/verification.schema.json +4 -0
  84. package/samples/schemas/work-orders.schema.json +6 -2
  85. package/schemas/config.schema.json +101 -3
  86. package/schemas/migrations.schema.json +25 -0
  87. package/schemas/pending-blocked.schema.json +190 -0
  88. package/skill-narrative.md +14 -10
  89. package/skills/pi-context/SKILL.md +127 -49
  90. package/skills/pi-context/references/bundled-resources.md +7 -2
@@ -121,6 +121,14 @@
121
121
  "array_key": "stories",
122
122
  "data_path": "story.json"
123
123
  },
124
+ {
125
+ "canonical_id": "milestone",
126
+ "display_name": "Milestones",
127
+ "prefix": "MILE-",
128
+ "schema_path": "schemas/milestone.schema.json",
129
+ "array_key": "milestones",
130
+ "data_path": "milestone.json"
131
+ },
124
132
  {
125
133
  "canonical_id": "work-orders",
126
134
  "display_name": "Work Orders",
@@ -128,6 +136,14 @@
128
136
  "schema_path": "schemas/work-orders.schema.json",
129
137
  "array_key": "work_orders",
130
138
  "data_path": "work-orders.json"
139
+ },
140
+ {
141
+ "canonical_id": "session-notes",
142
+ "display_name": "Session Notes",
143
+ "prefix": "SESSION-",
144
+ "schema_path": "schemas/session-notes.schema.json",
145
+ "array_key": "sessions",
146
+ "data_path": "session-notes.json"
131
147
  }
132
148
  ],
133
149
  "relation_types": [
@@ -136,7 +152,8 @@
136
152
  "display_name": "supersedes",
137
153
  "category": "ordering",
138
154
  "source_kinds": ["decisions"],
139
- "target_kinds": ["decisions"]
155
+ "target_kinds": ["decisions"],
156
+ "role_direction": "as_parent"
140
157
  },
141
158
  {
142
159
  "canonical_id": "decision_relates_to_decision",
@@ -187,19 +204,35 @@
187
204
  "source_kinds": ["framework-gaps"],
188
205
  "target_kinds": ["issues"]
189
206
  },
207
+ {
208
+ "canonical_id": "task_addresses_issue",
209
+ "display_name": "addresses issue",
210
+ "category": "data_flow",
211
+ "source_kinds": ["tasks"],
212
+ "target_kinds": ["issues"]
213
+ },
214
+ {
215
+ "canonical_id": "issue_relates_to_issue",
216
+ "display_name": "relates to issue",
217
+ "category": "data_flow",
218
+ "source_kinds": ["issues"],
219
+ "target_kinds": ["issues"]
220
+ },
190
221
  {
191
222
  "canonical_id": "feature_depends_on_item",
192
223
  "display_name": "depends on item",
193
224
  "category": "ordering",
194
225
  "source_kinds": ["features"],
195
- "target_kinds": ["*"]
226
+ "target_kinds": ["*"],
227
+ "role_direction": "as_parent"
196
228
  },
197
229
  {
198
230
  "canonical_id": "feature_gated_by_item",
199
231
  "display_name": "gated by",
200
232
  "category": "ordering",
201
233
  "source_kinds": ["features"],
202
- "target_kinds": ["*"]
234
+ "target_kinds": ["*"],
235
+ "role_direction": "as_child"
203
236
  },
204
237
  {
205
238
  "canonical_id": "feature_resolves_issue",
@@ -220,35 +253,40 @@
220
253
  "display_name": "story depends on story",
221
254
  "category": "ordering",
222
255
  "source_kinds": ["story"],
223
- "target_kinds": ["story"]
256
+ "target_kinds": ["story"],
257
+ "role_direction": "as_parent"
224
258
  },
225
259
  {
226
260
  "canonical_id": "story_gated_by_item",
227
261
  "display_name": "story gated by",
228
262
  "category": "ordering",
229
263
  "source_kinds": ["story"],
230
- "target_kinds": ["*"]
264
+ "target_kinds": ["*"],
265
+ "role_direction": "as_child"
231
266
  },
232
267
  {
233
268
  "canonical_id": "task_depends_on_task",
234
269
  "display_name": "depends on task",
235
270
  "category": "ordering",
236
271
  "source_kinds": ["tasks"],
237
- "target_kinds": ["tasks"]
272
+ "target_kinds": ["tasks"],
273
+ "role_direction": "as_parent"
238
274
  },
239
275
  {
240
276
  "canonical_id": "requirement_depends_on_requirement",
241
277
  "display_name": "depends on requirement",
242
278
  "category": "ordering",
243
279
  "source_kinds": ["requirements"],
244
- "target_kinds": ["requirements"]
280
+ "target_kinds": ["requirements"],
281
+ "role_direction": "as_parent"
245
282
  },
246
283
  {
247
284
  "canonical_id": "research_supersedes_research",
248
285
  "display_name": "research supersedes research",
249
286
  "category": "ordering",
250
287
  "source_kinds": ["research"],
251
- "target_kinds": ["research"]
288
+ "target_kinds": ["research"],
289
+ "role_direction": "as_parent"
252
290
  },
253
291
  {
254
292
  "canonical_id": "research_informs_item",
@@ -283,21 +321,40 @@
283
321
  "display_name": "positioned in phase",
284
322
  "category": "membership",
285
323
  "source_kinds": ["tasks"],
286
- "target_kinds": ["phase"]
324
+ "target_kinds": ["phase"],
325
+ "role_direction": "as_child"
326
+ },
327
+ {
328
+ "canonical_id": "phase_positioned_in_milestone",
329
+ "display_name": "positioned in milestone",
330
+ "category": "membership",
331
+ "source_kinds": ["phase"],
332
+ "target_kinds": ["milestone"],
333
+ "role_direction": "as_child"
334
+ },
335
+ {
336
+ "canonical_id": "milestone_precedes_milestone",
337
+ "display_name": "precedes",
338
+ "category": "ordering",
339
+ "source_kinds": ["milestone"],
340
+ "target_kinds": ["milestone"],
341
+ "role_direction": "as_parent"
287
342
  },
288
343
  {
289
344
  "canonical_id": "feature_contains_story",
290
345
  "display_name": "contains story",
291
346
  "category": "membership",
292
347
  "source_kinds": ["features"],
293
- "target_kinds": ["story"]
348
+ "target_kinds": ["story"],
349
+ "role_direction": "as_parent"
294
350
  },
295
351
  {
296
- "canonical_id": "story_contains_task",
297
- "display_name": "contains task",
352
+ "canonical_id": "story_includes_item",
353
+ "display_name": "includes item",
298
354
  "category": "membership",
299
355
  "source_kinds": ["story"],
300
- "target_kinds": ["tasks"]
356
+ "target_kinds": ["*"],
357
+ "role_direction": "as_parent"
301
358
  },
302
359
  {
303
360
  "canonical_id": "rationale_supports_decision",
@@ -327,12 +384,93 @@
327
384
  "source_kinds": ["tasks"],
328
385
  "target_kinds": ["decisions"]
329
386
  },
387
+ {
388
+ "canonical_id": "item_governed_by_convention",
389
+ "display_name": "governed by convention",
390
+ "category": "data_flow",
391
+ "source_kinds": ["decisions", "features", "tasks"],
392
+ "target_kinds": ["conventions"]
393
+ },
394
+ {
395
+ "canonical_id": "item_acknowledges_missing_convention",
396
+ "display_name": "acknowledges missing convention",
397
+ "category": "data_flow",
398
+ "source_kinds": ["decisions", "features", "tasks"],
399
+ "target_kinds": ["framework-gaps"]
400
+ },
330
401
  {
331
402
  "canonical_id": "item_derived_from_item",
332
403
  "display_name": "derived from",
333
404
  "category": "data_flow",
334
405
  "source_kinds": ["*"],
406
+ "target_kinds": ["*"],
407
+ "role_direction": "as_child"
408
+ },
409
+ {
410
+ "canonical_id": "decision_raises_gap",
411
+ "display_name": "raises gap",
412
+ "category": "data_flow",
413
+ "source_kinds": ["decisions"],
414
+ "target_kinds": ["framework-gaps"]
415
+ },
416
+ {
417
+ "canonical_id": "decision_gated_by_item",
418
+ "display_name": "gated by",
419
+ "category": "ordering",
420
+ "source_kinds": ["decisions"],
421
+ "target_kinds": ["*"],
422
+ "role_direction": "as_child"
423
+ },
424
+ {
425
+ "canonical_id": "gap_relates_to_gap",
426
+ "display_name": "relates to gap",
427
+ "category": "data_flow",
428
+ "source_kinds": ["framework-gaps"],
429
+ "target_kinds": ["framework-gaps"]
430
+ },
431
+ {
432
+ "canonical_id": "task_gated_by_item",
433
+ "display_name": "gated by",
434
+ "category": "ordering",
435
+ "source_kinds": ["tasks"],
436
+ "target_kinds": ["*"],
437
+ "role_direction": "as_child"
438
+ },
439
+ {
440
+ "canonical_id": "session_touches_item",
441
+ "display_name": "touches item",
442
+ "category": "membership",
443
+ "source_kinds": ["session-notes"],
335
444
  "target_kinds": ["*"]
445
+ },
446
+ {
447
+ "canonical_id": "decision_derived_from_item",
448
+ "display_name": "derived from",
449
+ "category": "data_flow",
450
+ "source_kinds": ["decisions"],
451
+ "target_kinds": ["*"],
452
+ "role_direction": "as_child"
453
+ },
454
+ {
455
+ "canonical_id": "decision_escalates_underdetermined",
456
+ "display_name": "escalates underdetermined choice",
457
+ "category": "data_flow",
458
+ "source_kinds": ["decisions"],
459
+ "target_kinds": ["framework-gaps"]
460
+ },
461
+ {
462
+ "canonical_id": "task_advances_story",
463
+ "display_name": "advances story",
464
+ "category": "data_flow",
465
+ "source_kinds": ["tasks"],
466
+ "target_kinds": ["story"]
467
+ },
468
+ {
469
+ "canonical_id": "feature_advances_story",
470
+ "display_name": "advances story",
471
+ "category": "data_flow",
472
+ "source_kinds": ["features"],
473
+ "target_kinds": ["story"]
336
474
  }
337
475
  ],
338
476
  "lenses": [
@@ -361,10 +499,137 @@
361
499
  "closed",
362
500
  "wontfix"
363
501
  ]
502
+ },
503
+ {
504
+ "id": "issues-by-status",
505
+ "kind": "target",
506
+ "target": "issues",
507
+ "derived_from_field": "status",
508
+ "bins": [
509
+ "open",
510
+ "resolved",
511
+ "deferred"
512
+ ]
513
+ },
514
+ {
515
+ "id": "issues-by-priority",
516
+ "kind": "target",
517
+ "target": "issues",
518
+ "derived_from_field": "priority",
519
+ "bins": [
520
+ "critical",
521
+ "high",
522
+ "medium",
523
+ "low"
524
+ ]
525
+ },
526
+ {
527
+ "id": "gaps-by-priority",
528
+ "kind": "target",
529
+ "target": "framework-gaps",
530
+ "derived_from_field": "priority",
531
+ "bins": [
532
+ "P0",
533
+ "P1",
534
+ "P2",
535
+ "P3"
536
+ ]
537
+ },
538
+ {
539
+ "id": "features-by-status",
540
+ "kind": "target",
541
+ "target": "features",
542
+ "derived_from_field": "status",
543
+ "bins": [
544
+ "proposed",
545
+ "approved",
546
+ "in-progress",
547
+ "in-review",
548
+ "complete",
549
+ "blocked",
550
+ "cancelled"
551
+ ]
552
+ },
553
+ {
554
+ "id": "story-advancers",
555
+ "kind": "target",
556
+ "target": "story",
557
+ "relation_type": "task_advances_story",
558
+ "derived_from_field": null,
559
+ "bins": []
560
+ },
561
+ {
562
+ "id": "story-advancers-features",
563
+ "kind": "target",
564
+ "target": "story",
565
+ "relation_type": "feature_advances_story",
566
+ "derived_from_field": null,
567
+ "bins": []
364
568
  }
365
569
  ],
366
570
  "layers": [],
367
571
  "status_buckets": {},
572
+ "state_derivation": {
573
+ "in_flight": {
574
+ "kinds": [
575
+ "tasks"
576
+ ],
577
+ "bucket": "in_progress"
578
+ },
579
+ "focus_fallback": {
580
+ "kind": "phase",
581
+ "bucket": "in_progress"
582
+ },
583
+ "next_ranked": [
584
+ {
585
+ "kind": "tasks",
586
+ "label": "task",
587
+ "bucket": "todo",
588
+ "reason_template": "unblocked planned task"
589
+ },
590
+ {
591
+ "kind": "issues",
592
+ "label": "issue",
593
+ "bucket": "todo",
594
+ "rank_field": "priority",
595
+ "rank_order": [
596
+ "critical",
597
+ "high",
598
+ "medium",
599
+ "low"
600
+ ],
601
+ "reason_template": "open issue (priority {rank_value})"
602
+ },
603
+ {
604
+ "kind": "framework-gaps",
605
+ "label": "framework-gap",
606
+ "bucket": "todo",
607
+ "rank_field": "priority",
608
+ "rank_order": [
609
+ "P0",
610
+ "P1",
611
+ "P2",
612
+ "P3"
613
+ ],
614
+ "reason_template": "open gap (priority {rank_value})"
615
+ }
616
+ ],
617
+ "blocked_by": {
618
+ "relation_types": [
619
+ "task_depends_on_task",
620
+ "task_gated_by_item"
621
+ ]
622
+ },
623
+ "rollups": [
624
+ {
625
+ "kind": "milestone",
626
+ "membership_relation": "phase_positioned_in_milestone",
627
+ "complete_status": "reached",
628
+ "incomplete_status": "planned"
629
+ }
630
+ ],
631
+ "head_size": 15
632
+ },
368
633
  "installed_schemas": [
369
634
  "decisions",
370
635
  "framework-gaps",
@@ -381,7 +646,9 @@
381
646
  "context-contracts",
382
647
  "phase",
383
648
  "story",
384
- "work-orders"
649
+ "milestone",
650
+ "work-orders",
651
+ "session-notes"
385
652
  ],
386
653
  "installed_blocks": [
387
654
  "decisions",
@@ -399,7 +666,9 @@
399
666
  "context-contracts",
400
667
  "phase",
401
668
  "story",
402
- "work-orders"
669
+ "milestone",
670
+ "work-orders",
671
+ "session-notes"
403
672
  ],
404
673
  "invariants": [
405
674
  {
@@ -442,6 +711,19 @@
442
711
  "severity": "warning",
443
712
  "message": "Completed task '{id}' addresses a gap that is not closed"
444
713
  },
714
+ {
715
+ "id": "task-completed-issue-resolved",
716
+ "class": "status-consistency",
717
+ "block": "tasks",
718
+ "relation_types": [
719
+ "task_addresses_issue"
720
+ ],
721
+ "direction": "as_parent",
722
+ "when_bucket": "complete",
723
+ "require_target_bucket": "complete",
724
+ "severity": "warning",
725
+ "message": "Completed task '{id}' addresses an issue that is not resolved"
726
+ },
445
727
  {
446
728
  "id": "task-completed-feature-complete",
447
729
  "class": "status-consistency",
@@ -479,6 +761,67 @@
479
761
  "forbid_target_bucket": "unknown",
480
762
  "severity": "warning",
481
763
  "message": "Task '{id}' is governed by a superseded or cancelled decision"
764
+ },
765
+ {
766
+ "id": "decision-articulates-convention",
767
+ "class": "requires-edge",
768
+ "block": "decisions",
769
+ "relation_types": [
770
+ "item_governed_by_convention",
771
+ "item_acknowledges_missing_convention"
772
+ ],
773
+ "direction": "as_parent",
774
+ "severity": "warning",
775
+ "message": "Decision '{id}' articulates no governing convention — add an item_governed_by_convention edge to a convention, or an item_acknowledges_missing_convention edge to a missing-convention gap"
776
+ },
777
+ {
778
+ "id": "feature-articulates-convention",
779
+ "class": "requires-edge",
780
+ "block": "features",
781
+ "relation_types": [
782
+ "item_governed_by_convention",
783
+ "item_acknowledges_missing_convention"
784
+ ],
785
+ "direction": "as_parent",
786
+ "severity": "warning",
787
+ "message": "Feature '{id}' articulates no governing convention — add an item_governed_by_convention edge to a convention, or an item_acknowledges_missing_convention edge to a missing-convention gap"
788
+ },
789
+ {
790
+ "id": "task-articulates-convention",
791
+ "class": "requires-edge",
792
+ "block": "tasks",
793
+ "relation_types": [
794
+ "item_governed_by_convention",
795
+ "item_acknowledges_missing_convention"
796
+ ],
797
+ "direction": "as_parent",
798
+ "severity": "warning",
799
+ "message": "Task '{id}' articulates no governing convention — add an item_governed_by_convention edge to a convention, or an item_acknowledges_missing_convention edge to a missing-convention gap"
800
+ },
801
+ {
802
+ "id": "reached-milestone-phases-complete",
803
+ "class": "status-consistency",
804
+ "block": "milestone",
805
+ "relation_types": [
806
+ "phase_positioned_in_milestone"
807
+ ],
808
+ "direction": "as_child",
809
+ "when_bucket": "complete",
810
+ "require_target_bucket": "complete",
811
+ "severity": "error",
812
+ "message": "Reached milestone '{id}' has a positioned phase that is not complete — milestone.reached is a pure phase-rollup; a reached milestone requires the parent phase of every phase_positioned_in_milestone edge to be complete"
813
+ },
814
+ {
815
+ "id": "decision-shows-derivation",
816
+ "class": "requires-edge",
817
+ "block": "decisions",
818
+ "relation_types": [
819
+ "decision_derived_from_item",
820
+ "decision_escalates_underdetermined"
821
+ ],
822
+ "direction": "as_parent",
823
+ "severity": "warning",
824
+ "message": "Decision '{id}' shows no derivation basis — add a decision_derived_from_item edge to the fact its resolution derives from, or a decision_escalates_underdetermined edge to the framework-gap capturing a genuinely-underdetermined escalated choice (derive-decisions-from-facts)"
482
825
  }
483
826
  ],
484
827
  "tool_operations": [],
@@ -128,6 +128,14 @@
128
128
  "kind": "identity",
129
129
  "created_by": "human/davidryan@gmail.com",
130
130
  "created_at": "2026-05-31T07:48:18.893Z"
131
+ },
132
+ {
133
+ "schemaName": "config",
134
+ "fromVersion": "1.0.0",
135
+ "toVersion": "1.8.0",
136
+ "kind": "identity",
137
+ "created_by": "human/davidryan@gmail.com",
138
+ "created_at": "2026-07-02T00:00:00.000Z"
131
139
  }
132
140
  ]
133
141
  }
@@ -10,6 +10,10 @@
10
10
  ],
11
11
  "additionalProperties": false,
12
12
  "properties": {
13
+ "schema_version": {
14
+ "type": "string",
15
+ "description": "Semver of the block schema this envelope was last written against. Stamped by the write path to the schema's current version; when it differs from the installed schema's version, the read/write gates walk the block through the registered migration chain (or fail loud when no chain reaches the current version). Absent on blocks not yet written by a stamping write path."
16
+ },
13
17
  "contracts": {
14
18
  "type": "array",
15
19
  "items": {
@@ -9,6 +9,10 @@
9
9
  "rules"
10
10
  ],
11
11
  "properties": {
12
+ "schema_version": {
13
+ "type": "string",
14
+ "description": "Semver of the block schema this envelope was last written against. Stamped by the write path to the schema's current version; when it differs from the installed schema's version, the read/write gates walk the block through the registered migration chain (or fail loud when no chain reaches the current version). Absent on blocks not yet written by a stamping write path."
15
+ },
12
16
  "rules": {
13
17
  "type": "array",
14
18
  "items": {
@@ -9,6 +9,10 @@
9
9
  "decisions"
10
10
  ],
11
11
  "properties": {
12
+ "schema_version": {
13
+ "type": "string",
14
+ "description": "Semver of the block schema this envelope was last written against. Stamped by the write path to the schema's current version; when it differs from the installed schema's version, the read/write gates walk the block through the registered migration chain (or fail loud when no chain reaches the current version). Absent on blocks not yet written by a stamping write path."
15
+ },
12
16
  "decisions": {
13
17
  "type": "array",
14
18
  "items": {
@@ -9,6 +9,10 @@
9
9
  "features"
10
10
  ],
11
11
  "properties": {
12
+ "schema_version": {
13
+ "type": "string",
14
+ "description": "Semver of the block schema this envelope was last written against. Stamped by the write path to the schema's current version; when it differs from the installed schema's version, the read/write gates walk the block through the registered migration chain (or fail loud when no chain reaches the current version). Absent on blocks not yet written by a stamping write path."
15
+ },
12
16
  "features": {
13
17
  "type": "array",
14
18
  "items": {
@@ -3,12 +3,16 @@
3
3
  "$id": "pi-context://schemas/framework-gaps",
4
4
  "version": "1.1.1",
5
5
  "title": "Framework Gaps",
6
- "description": "Capability gaps in the pi-project-workflows framework — pieces that must exist natively for the target artifact-ownership model to be expressible as configuration rather than hand-enactment. Each gap carries evidence (file + line references), impact, canonical engineering vocabulary for the missing capability, proposed resolution, and lifecycle state. Framework gaps are distinct from feature-level defects: they describe what the framework cannot yet express at all, not bugs in expressible functionality.",
6
+ "description": "Capability gaps in the framework — pieces that must exist natively for the target artifact-ownership model to be expressible as configuration rather than hand-enactment. Each gap carries evidence (file + line references), impact, canonical engineering vocabulary for the missing capability, proposed resolution, and lifecycle state. Framework gaps are distinct from feature-level defects: they describe what the framework cannot yet express at all, not bugs in expressible functionality.",
7
7
  "type": "object",
8
8
  "required": [
9
9
  "gaps"
10
10
  ],
11
11
  "properties": {
12
+ "schema_version": {
13
+ "type": "string",
14
+ "description": "Semver of the block schema this envelope was last written against. Stamped by the write path to the schema's current version; when it differs from the installed schema's version, the read/write gates walk the block through the registered migration chain (or fail loud when no chain reaches the current version). Absent on blocks not yet written by a stamping write path."
15
+ },
12
16
  "gaps": {
13
17
  "type": "array",
14
18
  "items": {
@@ -9,6 +9,10 @@
9
9
  "issues"
10
10
  ],
11
11
  "properties": {
12
+ "schema_version": {
13
+ "type": "string",
14
+ "description": "Semver of the block schema this envelope was last written against. Stamped by the write path to the schema's current version; when it differs from the installed schema's version, the read/write gates walk the block through the registered migration chain (or fail loud when no chain reaches the current version). Absent on blocks not yet written by a stamping write path."
15
+ },
12
16
  "issues": {
13
17
  "type": "array",
14
18
  "items": {
@@ -43,7 +47,7 @@
43
47
  },
44
48
  "location": {
45
49
  "type": "string",
46
- "description": "File path + line number, e.g. packages/pi-workflows/src/dag.ts:219"
50
+ "description": "File path + line number, e.g. src/module/file.ts:NNN"
47
51
  },
48
52
  "status": {
49
53
  "type": "string",
@@ -74,7 +78,7 @@
74
78
  },
75
79
  "package": {
76
80
  "type": "string",
77
- "description": "Which monorepo package this issue touches (e.g. pi-workflows, pi-project, pi-behavior-monitors)"
81
+ "description": "Which package/module this issue touches (e.g. package-a, package-b)"
78
82
  },
79
83
  "source": {
80
84
  "type": "string",
@@ -90,6 +94,10 @@
90
94
  "type": "string",
91
95
  "description": "Commit message or reference if resolved"
92
96
  },
97
+ "resolved_at": {
98
+ "type": "string",
99
+ "description": "ISO-8601 timestamp when the issue was resolved"
100
+ },
93
101
  "oid": {
94
102
  "type": "string",
95
103
  "pattern": "^[0-9a-f]{32}$",
@@ -108,5 +116,25 @@
108
116
  }
109
117
  }
110
118
  }
119
+ },
120
+ "x-lifecycle": {
121
+ "field": "status",
122
+ "states": [
123
+ "open",
124
+ "resolved",
125
+ "deferred"
126
+ ],
127
+ "transitions": [
128
+ {
129
+ "from": "open",
130
+ "to": "resolved",
131
+ "required_authority": "any"
132
+ },
133
+ {
134
+ "from": "open",
135
+ "to": "deferred",
136
+ "required_authority": "user"
137
+ }
138
+ ]
111
139
  }
112
140
  }