@davidorex/pi-context 0.26.0 → 0.28.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 (123) hide show
  1. package/CHANGELOG.md +69 -15
  2. package/README.md +71 -18
  3. package/dist/block-api.d.ts +165 -18
  4. package/dist/block-api.d.ts.map +1 -1
  5. package/dist/block-api.js +800 -57
  6. package/dist/block-api.js.map +1 -1
  7. package/dist/citation-rot-scanner.d.ts +80 -0
  8. package/dist/citation-rot-scanner.d.ts.map +1 -0
  9. package/dist/citation-rot-scanner.js +421 -0
  10. package/dist/citation-rot-scanner.js.map +1 -0
  11. package/dist/content-hash.d.ts +25 -0
  12. package/dist/content-hash.d.ts.map +1 -0
  13. package/dist/content-hash.js +62 -0
  14. package/dist/content-hash.js.map +1 -0
  15. package/dist/context-dir.d.ts +126 -1
  16. package/dist/context-dir.d.ts.map +1 -1
  17. package/dist/context-dir.js +208 -4
  18. package/dist/context-dir.js.map +1 -1
  19. package/dist/context-registry.d.ts +122 -0
  20. package/dist/context-registry.d.ts.map +1 -0
  21. package/dist/context-registry.js +189 -0
  22. package/dist/context-registry.js.map +1 -0
  23. package/dist/context-sdk.d.ts +179 -12
  24. package/dist/context-sdk.d.ts.map +1 -1
  25. package/dist/context-sdk.js +536 -101
  26. package/dist/context-sdk.js.map +1 -1
  27. package/dist/context.d.ts +222 -4
  28. package/dist/context.d.ts.map +1 -1
  29. package/dist/context.js +244 -56
  30. package/dist/context.js.map +1 -1
  31. package/dist/git-env.d.ts +2 -0
  32. package/dist/git-env.d.ts.map +1 -0
  33. package/dist/git-env.js +29 -0
  34. package/dist/git-env.js.map +1 -0
  35. package/dist/index.d.ts +124 -2
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +440 -1125
  38. package/dist/index.js.map +1 -1
  39. package/dist/lens-view.d.ts.map +1 -1
  40. package/dist/lens-view.js +5 -3
  41. package/dist/lens-view.js.map +1 -1
  42. package/dist/migration-registry-loader.d.ts +121 -0
  43. package/dist/migration-registry-loader.d.ts.map +1 -0
  44. package/dist/migration-registry-loader.js +309 -0
  45. package/dist/migration-registry-loader.js.map +1 -0
  46. package/dist/migrations-store.d.ts +141 -0
  47. package/dist/migrations-store.d.ts.map +1 -0
  48. package/dist/migrations-store.js +206 -0
  49. package/dist/migrations-store.js.map +1 -0
  50. package/dist/object-store.d.ts +26 -0
  51. package/dist/object-store.d.ts.map +1 -0
  52. package/dist/object-store.js +104 -0
  53. package/dist/object-store.js.map +1 -0
  54. package/dist/ops-registry.d.ts +44 -0
  55. package/dist/ops-registry.d.ts.map +1 -0
  56. package/dist/ops-registry.js +1223 -0
  57. package/dist/ops-registry.js.map +1 -0
  58. package/dist/orientation.d.ts +16 -0
  59. package/dist/orientation.d.ts.map +1 -0
  60. package/dist/orientation.js +49 -0
  61. package/dist/orientation.js.map +1 -0
  62. package/dist/promote-item.d.ts +28 -0
  63. package/dist/promote-item.d.ts.map +1 -0
  64. package/dist/promote-item.js +257 -0
  65. package/dist/promote-item.js.map +1 -0
  66. package/dist/read-element.d.ts +129 -0
  67. package/dist/read-element.d.ts.map +1 -0
  68. package/dist/read-element.js +296 -0
  69. package/dist/read-element.js.map +1 -0
  70. package/dist/rename-canonical-id.d.ts.map +1 -1
  71. package/dist/rename-canonical-id.js +22 -13
  72. package/dist/rename-canonical-id.js.map +1 -1
  73. package/dist/roadmap-plan.d.ts.map +1 -1
  74. package/dist/roadmap-plan.js +23 -13
  75. package/dist/roadmap-plan.js.map +1 -1
  76. package/dist/schema-validator.d.ts +1 -0
  77. package/dist/schema-validator.d.ts.map +1 -1
  78. package/dist/schema-validator.js +7 -3
  79. package/dist/schema-validator.js.map +1 -1
  80. package/dist/schema-write.d.ts +78 -4
  81. package/dist/schema-write.d.ts.map +1 -1
  82. package/dist/schema-write.js +297 -34
  83. package/dist/schema-write.js.map +1 -1
  84. package/dist/status-vocab.d.ts +1 -0
  85. package/dist/status-vocab.d.ts.map +1 -1
  86. package/dist/status-vocab.js +4 -0
  87. package/dist/status-vocab.js.map +1 -1
  88. package/dist/truncate.d.ts +34 -0
  89. package/dist/truncate.d.ts.map +1 -0
  90. package/dist/truncate.js +85 -0
  91. package/dist/truncate.js.map +1 -0
  92. package/dist/write-schema-migration-tool.d.ts +46 -0
  93. package/dist/write-schema-migration-tool.d.ts.map +1 -0
  94. package/dist/write-schema-migration-tool.js +115 -0
  95. package/dist/write-schema-migration-tool.js.map +1 -0
  96. package/package.json +35 -2
  97. package/samples/blocks/work-orders.json +3 -0
  98. package/samples/conception.json +22 -3
  99. package/samples/migrations.json +133 -0
  100. package/samples/schemas/context-contracts.schema.json +19 -4
  101. package/samples/schemas/conventions.schema.json +68 -12
  102. package/samples/schemas/decisions.schema.json +125 -28
  103. package/samples/schemas/features.schema.json +140 -26
  104. package/samples/schemas/framework-gaps.schema.json +171 -26
  105. package/samples/schemas/issues.schema.json +86 -13
  106. package/samples/schemas/layer-plans.schema.json +195 -35
  107. package/samples/schemas/phase.schema.json +18 -3
  108. package/samples/schemas/rationale.schema.json +37 -7
  109. package/samples/schemas/requirements.schema.json +77 -10
  110. package/samples/schemas/research.schema.json +169 -36
  111. package/samples/schemas/spec-reviews.schema.json +88 -18
  112. package/samples/schemas/story.schema.json +18 -3
  113. package/samples/schemas/tasks.schema.json +66 -10
  114. package/samples/schemas/verification.schema.json +70 -12
  115. package/samples/schemas/work-orders.schema.json +195 -0
  116. package/schemas/bootstrap.schema.json +18 -6
  117. package/schemas/config.schema.json +58 -26
  118. package/schemas/context-registry.schema.json +46 -0
  119. package/schemas/migrations.schema.json +123 -0
  120. package/schemas/relations.schema.json +41 -10
  121. package/skill-narrative.md +42 -21
  122. package/skills/pi-context/SKILL.md +159 -65
  123. package/skills/pi-context/references/bundled-resources.md +7 -2
@@ -1,55 +1,106 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "pi-context://schemas/research",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "title": "Research",
6
6
  "description": "Factual and analytical substrate under decisions — each entry captures what was investigated, how, what was found, what grounds the findings, and what stale conditions invalidate them.",
7
7
  "type": "object",
8
- "required": ["research"],
8
+ "required": [
9
+ "research"
10
+ ],
9
11
  "properties": {
10
12
  "research": {
11
13
  "type": "array",
12
14
  "items": {
13
15
  "type": "object",
14
16
  "additionalProperties": false,
15
- "required": ["id", "title", "status", "layer", "type", "question", "method", "findings_summary", "created_by", "created_at"],
17
+ "required": [
18
+ "id",
19
+ "title",
20
+ "status",
21
+ "layer",
22
+ "type",
23
+ "question",
24
+ "method",
25
+ "findings_summary",
26
+ "created_by",
27
+ "created_at"
28
+ ],
16
29
  "properties": {
17
- "id": { "type": "string", "pattern": "^R-\\d{4}$" },
18
- "title": { "type": "string" },
30
+ "id": {
31
+ "type": "string",
32
+ "pattern": "^R-\\d{4}$"
33
+ },
34
+ "title": {
35
+ "type": "string"
36
+ },
19
37
  "status": {
20
38
  "type": "string",
21
- "enum": ["planned", "in-progress", "complete", "stale", "superseded", "revised"],
39
+ "enum": [
40
+ "planned",
41
+ "in-progress",
42
+ "complete",
43
+ "stale",
44
+ "superseded",
45
+ "revised"
46
+ ],
22
47
  "description": "planned = question framed, method chosen, no work started. in-progress = investigation underway. complete = findings_summary and citations finalized. stale = a stale_condition fired; findings may still be correct but grounding is no longer authoritative. superseded = a newer research entry replaces this one. revised = transient state during re-investigation against updated grounding."
23
48
  },
24
49
  "layer": {
25
50
  "type": "string",
26
- "enum": ["L1", "L2", "L3", "L4", "L5"],
51
+ "enum": [
52
+ "L1",
53
+ "L2",
54
+ "L3",
55
+ "L4",
56
+ "L5"
57
+ ],
27
58
  "description": "Which Muni layer the research informs. L1 identity/domain; L2 specification; L3 work; L4 execution; L5 memory."
28
59
  },
29
60
  "type": {
30
61
  "type": "string",
31
- "enum": ["investigative", "comparative", "empirical", "historical", "audit", "landscape", "feasibility", "curation"],
62
+ "enum": [
63
+ "investigative",
64
+ "comparative",
65
+ "empirical",
66
+ "historical",
67
+ "audit",
68
+ "landscape",
69
+ "feasibility",
70
+ "curation"
71
+ ],
32
72
  "description": "Kind of research, per the research:* skill taxonomy. Affects reliability characteristics and staleness behavior."
33
73
  },
34
74
  "question": {
35
75
  "type": "string",
36
76
  "description": "The question being investigated.",
37
- "x-prompt-budget": { "tokens": 1000, "words": 800 }
77
+ "x-prompt-budget": {
78
+ "tokens": 1000,
79
+ "words": 800
80
+ }
38
81
  },
39
82
  "method": {
40
83
  "type": "string",
41
84
  "description": "How the investigation was conducted — e.g. 'code-inspection', 'empirical-test', 'web-fetch', 'curation of external document', or a combination.",
42
- "x-prompt-budget": { "tokens": 1000, "words": 800 }
85
+ "x-prompt-budget": {
86
+ "tokens": 1000,
87
+ "words": 800
88
+ }
43
89
  },
44
90
  "scope": {
45
91
  "type": "array",
46
- "items": { "type": "string" },
92
+ "items": {
93
+ "type": "string"
94
+ },
47
95
  "description": "What was in scope — versions, branches, revisions, URLs, documents examined."
48
96
  },
49
97
  "findings_summary": {
50
98
  "type": "string",
51
99
  "description": "Self-contained, prompt-injectable summary of what was found. Target ~300-800 words. Must stand alone without the full findings_document.",
52
- "x-prompt-budget": { "tokens": 1000, "words": 800 }
100
+ "x-prompt-budget": {
101
+ "tokens": 1000,
102
+ "words": 800
103
+ }
53
104
  },
54
105
  "findings_document": {
55
106
  "type": "string",
@@ -61,17 +112,23 @@
61
112
  "properties": {
62
113
  "dependencies": {
63
114
  "type": "array",
64
- "items": { "type": "string" },
115
+ "items": {
116
+ "type": "string"
117
+ },
65
118
  "description": "Version-pinned dependency strings (e.g. '@mariozechner/pi-ai@0.63.1') whose behavior is load-bearing for the findings."
66
119
  },
67
120
  "revisions": {
68
121
  "type": "array",
69
- "items": { "type": "string" },
122
+ "items": {
123
+ "type": "string"
124
+ },
70
125
  "description": "Git SHAs, branch snapshots, or repo-at-date references."
71
126
  },
72
127
  "external_refs": {
73
128
  "type": "array",
74
- "items": { "type": "string" },
129
+ "items": {
130
+ "type": "string"
131
+ },
75
132
  "description": "Dated external references — URLs with retrieval timestamps, academic papers, external spec documents."
76
133
  }
77
134
  }
@@ -82,8 +139,10 @@
82
139
  },
83
140
  "stale_conditions": {
84
141
  "type": "array",
85
- "items": { "type": "string" },
86
- "description": "Explicit list of conditions under which the research is no longer authoritative. The future staleness engine (FGAP-007) will read this to transition status from complete to stale automatically."
142
+ "items": {
143
+ "type": "string"
144
+ },
145
+ "description": "Explicit list of conditions under which the research is no longer authoritative. A future staleness engine will read this to transition status from complete to stale automatically."
87
146
  },
88
147
  "citations": {
89
148
  "type": "array",
@@ -91,13 +150,25 @@
91
150
  "items": {
92
151
  "type": "object",
93
152
  "additionalProperties": false,
94
- "required": ["label"],
153
+ "required": [
154
+ "label"
155
+ ],
95
156
  "properties": {
96
- "label": { "type": "string" },
97
- "path": { "type": "string" },
98
- "lines": { "type": "string" },
99
- "url": { "type": "string" },
100
- "retrieved_at": { "type": "string" }
157
+ "label": {
158
+ "type": "string"
159
+ },
160
+ "path": {
161
+ "type": "string"
162
+ },
163
+ "lines": {
164
+ "type": "string"
165
+ },
166
+ "url": {
167
+ "type": "string"
168
+ },
169
+ "retrieved_at": {
170
+ "type": "string"
171
+ }
101
172
  }
102
173
  }
103
174
  },
@@ -109,26 +180,88 @@
109
180
  "type": "string",
110
181
  "description": "Alias for created_at."
111
182
  },
112
- "created_by": { "type": "string" },
113
- "created_at": { "type": "string" },
114
- "modified_by": { "type": "string" },
115
- "modified_at": { "type": "string" }
183
+ "created_by": {
184
+ "type": "string"
185
+ },
186
+ "created_at": {
187
+ "type": "string"
188
+ },
189
+ "modified_by": {
190
+ "type": "string"
191
+ },
192
+ "modified_at": {
193
+ "type": "string"
194
+ },
195
+ "oid": {
196
+ "type": "string",
197
+ "pattern": "^[0-9a-f]{32}$",
198
+ "description": "Content-independent substrate-stable item identity (content-addressed substrate identity, Cycle 3). Minted once at item birth via mintOid(substrate_id); immutable across content versions. Optional in the schema so pre-Cycle-3 items validate; stamped on next write."
199
+ },
200
+ "content_hash": {
201
+ "type": "string",
202
+ "pattern": "^[0-9a-f]{64}$",
203
+ "description": "SHA-256 (hex) of the RFC-8785-canonical content projection of this item (metadata fields excluded). Recomputed on every stamping write; moves with content, stable across metadata-only churn."
204
+ },
205
+ "content_parent": {
206
+ "type": "string",
207
+ "pattern": "^[0-9a-f]{64}$",
208
+ "description": "content_hash of the immediately-prior version of this item; set on a content-changing update, absent on the first (v1) version. Forms the per-item content version chain."
209
+ }
116
210
  }
117
211
  }
118
212
  }
119
213
  },
120
214
  "x-lifecycle": {
121
215
  "field": "status",
122
- "states": ["planned", "in-progress", "complete", "stale", "superseded", "revised"],
216
+ "states": [
217
+ "planned",
218
+ "in-progress",
219
+ "complete",
220
+ "stale",
221
+ "superseded",
222
+ "revised"
223
+ ],
123
224
  "transitions": [
124
- { "from": "planned", "to": "in-progress", "required_authority": "any" },
125
- { "from": "in-progress", "to": "complete", "required_authority": "any", "note": "Agent may mark own research complete when findings_summary and citations are finalized." },
126
- { "from": "complete", "to": "stale", "required_authority": "any", "note": "Any party marks stale when a stale_condition fires. Future staleness engine (FGAP-007) fires this automatically." },
127
- { "from": "stale", "to": "in-progress", "required_authority": "user", "note": "Reopening for revision; requires user authority if the research is currently cited by an enacted decision because revising may invalidate the decision's grounding." },
128
- { "from": "complete", "to": "superseded", "required_authority": "any", "precondition": "superseding entry exists and points to this one via a research_supersedes_research edge" },
129
- { "from": "in-progress", "to": "revised", "required_authority": "any" },
130
- { "from": "revised", "to": "complete", "required_authority": "any" }
225
+ {
226
+ "from": "planned",
227
+ "to": "in-progress",
228
+ "required_authority": "any"
229
+ },
230
+ {
231
+ "from": "in-progress",
232
+ "to": "complete",
233
+ "required_authority": "any",
234
+ "note": "Agent may mark own research complete when findings_summary and citations are finalized."
235
+ },
236
+ {
237
+ "from": "complete",
238
+ "to": "stale",
239
+ "required_authority": "any",
240
+ "note": "Any party marks stale when a stale_condition fires. A future staleness engine fires this automatically."
241
+ },
242
+ {
243
+ "from": "stale",
244
+ "to": "in-progress",
245
+ "required_authority": "user",
246
+ "note": "Reopening for revision; requires user authority if the research is currently cited by an enacted decision because revising may invalidate the decision's grounding."
247
+ },
248
+ {
249
+ "from": "complete",
250
+ "to": "superseded",
251
+ "required_authority": "any",
252
+ "precondition": "superseding entry exists and points to this one via a research_supersedes_research edge"
253
+ },
254
+ {
255
+ "from": "in-progress",
256
+ "to": "revised",
257
+ "required_authority": "any"
258
+ },
259
+ {
260
+ "from": "revised",
261
+ "to": "complete",
262
+ "required_authority": "any"
263
+ }
131
264
  ],
132
- "note": "AJV draft-07 cannot enforce transition validity or required_authority; this block is metadata for future framework-level state-machine validation (FGAP-005) and authorship attestation (FGAP-004). The staleness engine (FGAP-007) reads stale_conditions and fires the complete→stale transition automatically when conditions are met."
265
+ "note": "AJV draft-07 cannot enforce transition validity or required_authority; this block is metadata reserved for future framework-level state-machine validation and authorship attestation. A future staleness engine reads stale_conditions and fires the complete→stale transition automatically when conditions are met."
133
266
  }
134
267
  }
@@ -1,47 +1,95 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "pi-context://schemas/spec-reviews",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "title": "Spec Reviews",
6
6
  "description": "Design reviews of specification documents. Each review targets one spec, runs a pre-implementation review pass (ideally via independent fresh-context reviewer), and carries scope/method/status. A spec-review blocks implementation-spec drafting until 'clean'.",
7
7
  "type": "object",
8
- "required": ["reviews"],
8
+ "required": [
9
+ "reviews"
10
+ ],
9
11
  "properties": {
10
12
  "reviews": {
11
13
  "type": "array",
12
14
  "items": {
13
15
  "type": "object",
14
16
  "additionalProperties": false,
15
- "required": ["id", "target", "status", "created_by", "created_at"],
17
+ "required": [
18
+ "id",
19
+ "target",
20
+ "status",
21
+ "created_by",
22
+ "created_at"
23
+ ],
16
24
  "properties": {
17
- "id": { "type": "string", "pattern": "^REVIEW-\\d{3}$" },
25
+ "id": {
26
+ "type": "string",
27
+ "pattern": "^REVIEW-\\d{3}$"
28
+ },
18
29
  "target": {
19
30
  "type": "string",
20
31
  "description": "Path to the spec doc being reviewed"
21
32
  },
22
- "target_revision": { "type": "string", "description": "Git SHA or version at which the review was conducted" },
23
- "reviewer": { "type": "string", "description": "Agent name or role performing the review" },
33
+ "target_revision": {
34
+ "type": "string",
35
+ "description": "Git SHA or version at which the review was conducted"
36
+ },
37
+ "reviewer": {
38
+ "type": "string",
39
+ "description": "Agent name or role performing the review"
40
+ },
24
41
  "status": {
25
42
  "type": "string",
26
- "enum": ["not-started", "in-progress", "complete", "abandoned"]
43
+ "enum": [
44
+ "not-started",
45
+ "in-progress",
46
+ "complete",
47
+ "abandoned"
48
+ ]
27
49
  },
28
50
  "scope": {
29
51
  "type": "array",
30
- "items": { "type": "string" },
52
+ "items": {
53
+ "type": "string"
54
+ },
31
55
  "description": "Sections or concerns of the target in scope for this review"
32
56
  },
33
57
  "method": {
34
58
  "type": "string",
35
59
  "description": "How the review is conducted — e.g. 'fresh-context independent reviewer', 'adversarial pre-mortem', 'self-review'",
36
- "x-prompt-budget": { "tokens": 1000, "words": 800 }
60
+ "x-prompt-budget": {
61
+ "tokens": 1000,
62
+ "words": 800
63
+ }
37
64
  },
38
65
  "clean": {
39
66
  "type": "boolean",
40
67
  "description": "True when every finding has a terminal state (resolved/wontfix/duplicate)"
41
68
  },
42
- "created_by": { "type": "string" },
43
- "created_at": { "type": "string" },
44
- "completed_at": { "type": "string" }
69
+ "created_by": {
70
+ "type": "string"
71
+ },
72
+ "created_at": {
73
+ "type": "string"
74
+ },
75
+ "completed_at": {
76
+ "type": "string"
77
+ },
78
+ "oid": {
79
+ "type": "string",
80
+ "pattern": "^[0-9a-f]{32}$",
81
+ "description": "Content-independent substrate-stable item identity (content-addressed substrate identity, Cycle 3). Minted once at item birth via mintOid(substrate_id); immutable across content versions. Optional in the schema so pre-Cycle-3 items validate; stamped on next write."
82
+ },
83
+ "content_hash": {
84
+ "type": "string",
85
+ "pattern": "^[0-9a-f]{64}$",
86
+ "description": "SHA-256 (hex) of the RFC-8785-canonical content projection of this item (metadata fields excluded). Recomputed on every stamping write; moves with content, stable across metadata-only churn."
87
+ },
88
+ "content_parent": {
89
+ "type": "string",
90
+ "pattern": "^[0-9a-f]{64}$",
91
+ "description": "content_hash of the immediately-prior version of this item; set on a content-changing update, absent on the first (v1) version. Forms the per-item content version chain."
92
+ }
45
93
  }
46
94
  }
47
95
  }
@@ -49,14 +97,36 @@
49
97
  "x-lifecycle": {
50
98
  "review": {
51
99
  "field": "status",
52
- "states": ["not-started", "in-progress", "complete", "abandoned"],
100
+ "states": [
101
+ "not-started",
102
+ "in-progress",
103
+ "complete",
104
+ "abandoned"
105
+ ],
53
106
  "transitions": [
54
- { "from": "not-started", "to": "in-progress", "required_authority": "any" },
55
- { "from": "in-progress", "to": "complete", "required_authority": "any" },
56
- { "from": "in-progress", "to": "abandoned", "required_authority": "user" },
57
- { "from": "complete", "to": "in-progress", "required_authority": "user", "note": "reopen for follow-up review" }
107
+ {
108
+ "from": "not-started",
109
+ "to": "in-progress",
110
+ "required_authority": "any"
111
+ },
112
+ {
113
+ "from": "in-progress",
114
+ "to": "complete",
115
+ "required_authority": "any"
116
+ },
117
+ {
118
+ "from": "in-progress",
119
+ "to": "abandoned",
120
+ "required_authority": "user"
121
+ },
122
+ {
123
+ "from": "complete",
124
+ "to": "in-progress",
125
+ "required_authority": "user",
126
+ "note": "reopen for follow-up review"
127
+ }
58
128
  ]
59
129
  },
60
- "note": "AJV draft-07 cannot enforce transition validity; this block is metadata for future framework-level state-machine validation (FGAP-005)."
130
+ "note": "AJV draft-07 cannot enforce transition validity; this block is metadata reserved for future framework-level state-machine validation."
61
131
  }
62
132
  }
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "pi-context://schemas/story",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "title": "Stories",
6
- "description": "Top-level user-story / story array-block (FGAP-064 elevation). Stories are a work-altitude between feature and task: a feature decomposes into stories, a story decomposes into tasks. Cross-altitude relationships (feature→story, story→task, story→story dependency, story→gating-item, story→milestone/phase/project-goal) live in relations.json closure-table edges per DEC-0013 — NOT as inline arrays on the story. Sub-shape is structural (id/title/status/description/acceptance_criteria); the Agile user-story form (role/want/benefit) is a future optional enrichment, not imposed (DEC-deferred per FGAP-064 — no role/want/benefit present in current data, none fabricated).",
6
+ "description": "Top-level user-story / story array-block. Stories are a work-altitude between feature and task: a feature decomposes into stories, a story decomposes into tasks. Cross-altitude relationships (feature→story, story→task, story→story dependency, story→gating-item, story→milestone/phase/project-goal) live in relations.json closure-table edges — NOT as inline arrays on the story. Sub-shape is structural (id/title/status/description/acceptance_criteria); the Agile user-story form (role/want/benefit) is a future optional enrichment, not imposed (no role/want/benefit present in current shape, none fabricated).",
7
7
  "type": "object",
8
8
  "required": [
9
9
  "stories"
@@ -39,7 +39,7 @@
39
39
  "complete",
40
40
  "blocked"
41
41
  ],
42
- "description": "Story lifecycle. Intentionally divergent from pi-context://schemas/status; reconciliation tracked in FGAP-021."
42
+ "description": "Story lifecycle. Intentionally divergent from pi-context://schemas/status; reconciliation deferred to a future status-schema unification."
43
43
  },
44
44
  "description": {
45
45
  "type": "string",
@@ -65,6 +65,21 @@
65
65
  },
66
66
  "modified_at": {
67
67
  "type": "string"
68
+ },
69
+ "oid": {
70
+ "type": "string",
71
+ "pattern": "^[0-9a-f]{32}$",
72
+ "description": "Content-independent substrate-stable item identity (content-addressed substrate identity, Cycle 3). Minted once at item birth via mintOid(substrate_id); immutable across content versions. Optional in the schema so pre-Cycle-3 items validate; stamped on next write."
73
+ },
74
+ "content_hash": {
75
+ "type": "string",
76
+ "pattern": "^[0-9a-f]{64}$",
77
+ "description": "SHA-256 (hex) of the RFC-8785-canonical content projection of this item (metadata fields excluded). Recomputed on every stamping write; moves with content, stable across metadata-only churn."
78
+ },
79
+ "content_parent": {
80
+ "type": "string",
81
+ "pattern": "^[0-9a-f]{64}$",
82
+ "description": "content_hash of the immediately-prior version of this item; set on a content-changing update, absent on the first (v1) version. Forms the per-item content version chain."
68
83
  }
69
84
  }
70
85
  }
@@ -1,32 +1,88 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "pi-context://schemas/tasks",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "title": "Tasks",
6
6
  "description": "Discrete units of work with status lifecycle (planned, in-progress, completed, blocked, cancelled). The operational layer between gaps/requirements and code changes.",
7
7
  "type": "object",
8
- "required": ["tasks"],
8
+ "required": [
9
+ "tasks"
10
+ ],
9
11
  "properties": {
10
12
  "tasks": {
11
13
  "type": "array",
12
14
  "items": {
13
15
  "type": "object",
14
- "required": ["id", "description", "status"],
16
+ "required": [
17
+ "id",
18
+ "description",
19
+ "status"
20
+ ],
15
21
  "properties": {
16
- "id": { "type": "string", "pattern": "^TASK-\\d{3,}$" },
17
- "description": { "type": "string", "x-prompt-budget": { "tokens": 1000, "words": 800 } },
18
- "status": { "type": "string", "enum": ["planned", "in-progress", "completed", "blocked", "cancelled"] },
22
+ "id": {
23
+ "type": "string",
24
+ "pattern": "^TASK-\\d{3,}$"
25
+ },
26
+ "description": {
27
+ "type": "string",
28
+ "x-prompt-budget": {
29
+ "tokens": 1000,
30
+ "words": 800
31
+ }
32
+ },
33
+ "status": {
34
+ "type": "string",
35
+ "enum": [
36
+ "planned",
37
+ "in-progress",
38
+ "completed",
39
+ "blocked",
40
+ "cancelled"
41
+ ]
42
+ },
19
43
  "files": {
20
44
  "type": "array",
21
- "items": { "type": "string" },
45
+ "items": {
46
+ "type": "string"
47
+ },
22
48
  "description": "Files this task creates or modifies"
23
49
  },
24
50
  "acceptance_criteria": {
25
51
  "type": "array",
26
- "items": { "type": "string", "x-prompt-budget": { "tokens": 1000, "words": 800 } }
52
+ "items": {
53
+ "type": "string",
54
+ "x-prompt-budget": {
55
+ "tokens": 1000,
56
+ "words": 800
57
+ }
58
+ }
59
+ },
60
+ "assigned_agent": {
61
+ "type": "string",
62
+ "description": "Agent name if assigned"
63
+ },
64
+ "notes": {
65
+ "type": "string",
66
+ "x-prompt-budget": {
67
+ "tokens": 1000,
68
+ "words": 800
69
+ }
70
+ },
71
+ "oid": {
72
+ "type": "string",
73
+ "pattern": "^[0-9a-f]{32}$",
74
+ "description": "Content-independent substrate-stable item identity (content-addressed substrate identity, Cycle 3). Minted once at item birth via mintOid(substrate_id); immutable across content versions. Optional in the schema so pre-Cycle-3 items validate; stamped on next write."
75
+ },
76
+ "content_hash": {
77
+ "type": "string",
78
+ "pattern": "^[0-9a-f]{64}$",
79
+ "description": "SHA-256 (hex) of the RFC-8785-canonical content projection of this item (metadata fields excluded). Recomputed on every stamping write; moves with content, stable across metadata-only churn."
27
80
  },
28
- "assigned_agent": { "type": "string", "description": "Agent name if assigned" },
29
- "notes": { "type": "string", "x-prompt-budget": { "tokens": 1000, "words": 800 } }
81
+ "content_parent": {
82
+ "type": "string",
83
+ "pattern": "^[0-9a-f]{64}$",
84
+ "description": "content_hash of the immediately-prior version of this item; set on a content-changing update, absent on the first (v1) version. Forms the per-item content version chain."
85
+ }
30
86
  }
31
87
  }
32
88
  }