@davidorex/pi-context 0.26.0 → 0.28.1

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 +71 -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
@@ -0,0 +1,133 @@
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "migrations": [
4
+ {
5
+ "schemaName": "context-contracts",
6
+ "fromVersion": "1.0.0",
7
+ "toVersion": "1.0.1",
8
+ "kind": "identity",
9
+ "created_by": "human/davidryan@gmail.com",
10
+ "created_at": "2026-05-31T07:48:18.891Z"
11
+ },
12
+ {
13
+ "schemaName": "conventions",
14
+ "fromVersion": "1.0.0",
15
+ "toVersion": "1.0.1",
16
+ "kind": "identity",
17
+ "created_by": "human/davidryan@gmail.com",
18
+ "created_at": "2026-05-31T07:48:18.891Z"
19
+ },
20
+ {
21
+ "schemaName": "decisions",
22
+ "fromVersion": "1.0.0",
23
+ "toVersion": "1.0.1",
24
+ "kind": "identity",
25
+ "created_by": "human/davidryan@gmail.com",
26
+ "created_at": "2026-05-31T07:48:18.891Z"
27
+ },
28
+ {
29
+ "schemaName": "features",
30
+ "fromVersion": "1.0.0",
31
+ "toVersion": "1.0.1",
32
+ "kind": "identity",
33
+ "created_by": "human/davidryan@gmail.com",
34
+ "created_at": "2026-05-31T07:48:18.892Z"
35
+ },
36
+ {
37
+ "schemaName": "framework-gaps",
38
+ "fromVersion": "1.1.0",
39
+ "toVersion": "1.1.1",
40
+ "kind": "identity",
41
+ "created_by": "human/davidryan@gmail.com",
42
+ "created_at": "2026-05-31T07:48:18.892Z"
43
+ },
44
+ {
45
+ "schemaName": "issues",
46
+ "fromVersion": "1.0.0",
47
+ "toVersion": "1.0.1",
48
+ "kind": "identity",
49
+ "created_by": "human/davidryan@gmail.com",
50
+ "created_at": "2026-05-31T07:48:18.892Z"
51
+ },
52
+ {
53
+ "schemaName": "layer-plans",
54
+ "fromVersion": "1.0.0",
55
+ "toVersion": "1.0.1",
56
+ "kind": "identity",
57
+ "created_by": "human/davidryan@gmail.com",
58
+ "created_at": "2026-05-31T07:48:18.892Z"
59
+ },
60
+ {
61
+ "schemaName": "phase",
62
+ "fromVersion": "2.0.0",
63
+ "toVersion": "2.0.1",
64
+ "kind": "identity",
65
+ "created_by": "human/davidryan@gmail.com",
66
+ "created_at": "2026-05-31T07:48:18.892Z"
67
+ },
68
+ {
69
+ "schemaName": "rationale",
70
+ "fromVersion": "1.0.0",
71
+ "toVersion": "1.0.1",
72
+ "kind": "identity",
73
+ "created_by": "human/davidryan@gmail.com",
74
+ "created_at": "2026-05-31T07:48:18.893Z"
75
+ },
76
+ {
77
+ "schemaName": "requirements",
78
+ "fromVersion": "1.0.0",
79
+ "toVersion": "1.0.1",
80
+ "kind": "identity",
81
+ "created_by": "human/davidryan@gmail.com",
82
+ "created_at": "2026-05-31T07:48:18.893Z"
83
+ },
84
+ {
85
+ "schemaName": "research",
86
+ "fromVersion": "1.0.0",
87
+ "toVersion": "1.0.1",
88
+ "kind": "identity",
89
+ "created_by": "human/davidryan@gmail.com",
90
+ "created_at": "2026-05-31T07:48:18.893Z"
91
+ },
92
+ {
93
+ "schemaName": "spec-reviews",
94
+ "fromVersion": "1.0.0",
95
+ "toVersion": "1.0.1",
96
+ "kind": "identity",
97
+ "created_by": "human/davidryan@gmail.com",
98
+ "created_at": "2026-05-31T07:48:18.893Z"
99
+ },
100
+ {
101
+ "schemaName": "story",
102
+ "fromVersion": "1.0.0",
103
+ "toVersion": "1.0.1",
104
+ "kind": "identity",
105
+ "created_by": "human/davidryan@gmail.com",
106
+ "created_at": "2026-05-31T07:48:18.893Z"
107
+ },
108
+ {
109
+ "schemaName": "tasks",
110
+ "fromVersion": "1.0.0",
111
+ "toVersion": "1.0.1",
112
+ "kind": "identity",
113
+ "created_by": "human/davidryan@gmail.com",
114
+ "created_at": "2026-05-31T07:48:18.893Z"
115
+ },
116
+ {
117
+ "schemaName": "verification",
118
+ "fromVersion": "1.0.0",
119
+ "toVersion": "1.0.1",
120
+ "kind": "identity",
121
+ "created_by": "human/davidryan@gmail.com",
122
+ "created_at": "2026-05-31T07:48:18.893Z"
123
+ },
124
+ {
125
+ "schemaName": "work-orders",
126
+ "fromVersion": "1.0.0",
127
+ "toVersion": "1.0.1",
128
+ "kind": "identity",
129
+ "created_by": "human/davidryan@gmail.com",
130
+ "created_at": "2026-05-31T07:48:18.893Z"
131
+ }
132
+ ]
133
+ }
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "pi-context://schemas/context-contracts",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "title": "Context contracts",
6
- "description": "Per-work-unit-kind context contracts declaring which relation_types compose the execution bundle (DEC-0017 surface; FGAP-030 closure). Each contract is keyed by a plain-string unit_kind type tag (carve-out from DEC-0013's edges-only constraint — unit_kind is a type marker, not a reference to a substrate item).",
6
+ "description": "Per-work-unit-kind context contracts declaring which relation_types compose the execution bundle. Each contract is keyed by a plain-string unit_kind type tag (carve-out from the edges-only constraint on inter-item relationships — unit_kind is a type marker, not a reference to a substrate item).",
7
7
  "type": "object",
8
8
  "required": [
9
9
  "contracts"
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "unit_kind": {
31
31
  "type": "string",
32
- "description": "Type tag for the unit kind this contract composes context for (e.g. 'task', 'decision', 'verification'). Plain-string keyed lookup — NOT a substrate-block-item reference (DEC-0013 carve-out for type tags)."
32
+ "description": "Type tag for the unit kind this contract composes context for (e.g. 'task', 'decision', 'verification'). Plain-string keyed lookup — NOT a substrate-block-item reference (type tags are a carve-out from the edges-only constraint on inter-item relationships)."
33
33
  },
34
34
  "bundle_relation_types": {
35
35
  "type": "array",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "applicability_predicate": {
61
61
  "type": "string",
62
- "description": "Optional FGAP-010 territory; reserved for relevance-scoping language."
62
+ "description": "Optional relevance-scoping predicate; reserved for a future scoping language."
63
63
  }
64
64
  }
65
65
  }
@@ -81,6 +81,21 @@
81
81
  },
82
82
  "modified_at": {
83
83
  "type": "string"
84
+ },
85
+ "oid": {
86
+ "type": "string",
87
+ "pattern": "^[0-9a-f]{32}$",
88
+ "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."
89
+ },
90
+ "content_hash": {
91
+ "type": "string",
92
+ "pattern": "^[0-9a-f]{64}$",
93
+ "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."
94
+ },
95
+ "content_parent": {
96
+ "type": "string",
97
+ "pattern": "^[0-9a-f]{64}$",
98
+ "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."
84
99
  }
85
100
  }
86
101
  }
@@ -1,34 +1,90 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "pi-context://schemas/conventions",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "title": "Conventions",
6
6
  "description": "Code and process conventions the project follows. Rules with enforcement methods (lint, review, test) that agents must comply with when writing code. Injected into agent prompts as constraints.",
7
7
  "type": "object",
8
- "required": ["rules"],
8
+ "required": [
9
+ "rules"
10
+ ],
9
11
  "properties": {
10
12
  "rules": {
11
13
  "type": "array",
12
14
  "items": {
13
15
  "type": "object",
14
- "required": ["id", "description", "enforcement", "severity"],
16
+ "required": [
17
+ "id",
18
+ "description",
19
+ "enforcement",
20
+ "severity"
21
+ ],
15
22
  "properties": {
16
- "id": { "type": "string" },
17
- "description": { "type": "string", "x-prompt-budget": { "tokens": 1000, "words": 800 } },
18
- "enforcement": { "type": "string", "enum": ["lint", "test", "review", "manual"] },
19
- "severity": { "type": "string", "enum": ["error", "warning", "info"] }
23
+ "id": {
24
+ "type": "string"
25
+ },
26
+ "description": {
27
+ "type": "string",
28
+ "x-prompt-budget": {
29
+ "tokens": 1000,
30
+ "words": 800
31
+ }
32
+ },
33
+ "enforcement": {
34
+ "type": "string",
35
+ "enum": [
36
+ "lint",
37
+ "test",
38
+ "review",
39
+ "manual"
40
+ ]
41
+ },
42
+ "severity": {
43
+ "type": "string",
44
+ "enum": [
45
+ "error",
46
+ "warning",
47
+ "info"
48
+ ]
49
+ },
50
+ "oid": {
51
+ "type": "string",
52
+ "pattern": "^[0-9a-f]{32}$",
53
+ "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."
54
+ },
55
+ "content_hash": {
56
+ "type": "string",
57
+ "pattern": "^[0-9a-f]{64}$",
58
+ "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."
59
+ },
60
+ "content_parent": {
61
+ "type": "string",
62
+ "pattern": "^[0-9a-f]{64}$",
63
+ "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."
64
+ }
20
65
  }
21
66
  }
22
67
  },
23
68
  "test_conventions": {
24
69
  "type": "object",
25
- "required": ["runner_command", "file_pattern"],
70
+ "required": [
71
+ "runner_command",
72
+ "file_pattern"
73
+ ],
26
74
  "properties": {
27
- "runner_command": { "type": "string" },
28
- "file_pattern": { "type": "string" }
75
+ "runner_command": {
76
+ "type": "string"
77
+ },
78
+ "file_pattern": {
79
+ "type": "string"
80
+ }
29
81
  }
30
82
  },
31
- "lint_command": { "type": "string" },
32
- "lint_scope": { "type": "string" }
83
+ "lint_command": {
84
+ "type": "string"
85
+ },
86
+ "lint_scope": {
87
+ "type": "string"
88
+ }
33
89
  }
34
90
  }
@@ -1,35 +1,61 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "pi-context://schemas/decisions",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "title": "Decisions",
6
6
  "description": "Live decision log; each entry is open, enacted, or superseded, with supporting references and intra-item options.",
7
7
  "type": "object",
8
- "required": ["decisions"],
8
+ "required": [
9
+ "decisions"
10
+ ],
9
11
  "properties": {
10
12
  "decisions": {
11
13
  "type": "array",
12
14
  "items": {
13
15
  "type": "object",
14
16
  "additionalProperties": false,
15
- "required": ["id", "title", "status", "context", "decision", "consequences", "created_by", "created_at"],
17
+ "required": [
18
+ "id",
19
+ "title",
20
+ "status",
21
+ "context",
22
+ "decision",
23
+ "consequences",
24
+ "created_by",
25
+ "created_at"
26
+ ],
16
27
  "properties": {
17
- "id": { "type": "string", "pattern": "^DEC-\\d{4}$" },
18
- "title": { "type": "string" },
28
+ "id": {
29
+ "type": "string",
30
+ "pattern": "^DEC-\\d{4}$"
31
+ },
32
+ "title": {
33
+ "type": "string"
34
+ },
19
35
  "status": {
20
36
  "type": "string",
21
- "enum": ["open", "enacted", "superseded"],
37
+ "enum": [
38
+ "open",
39
+ "enacted",
40
+ "superseded"
41
+ ],
22
42
  "description": "open = decision needs to be made; gates work. enacted = ratified by user authority; new constraint is in code and forward-looking constraint blocks. superseded = withdrawn without enactment; the entry was filed under proliferation pressure or on incorrect framing and is acknowledged as not-a-real-decision. Reasoning for supersession lives in consequences. Entry is preserved; not deleted."
23
43
  },
24
44
  "context": {
25
45
  "type": "string",
26
46
  "description": "Forces at play; what must be resolved and why. Grounded in citations to the forcing artifact and supporting research.",
27
- "x-prompt-budget": { "tokens": 1000, "words": 800 }
47
+ "x-prompt-budget": {
48
+ "tokens": 1000,
49
+ "words": 800
50
+ }
28
51
  },
29
52
  "decision": {
30
53
  "type": "string",
31
54
  "description": "The chosen direction. Populated at creation as the proposed direction and edited if needed at the moment of enactment. Only mandate-compliant, structurally-correct candidates appear here.",
32
- "x-prompt-budget": { "tokens": 1000, "words": 800 }
55
+ "x-prompt-budget": {
56
+ "tokens": 1000,
57
+ "words": 800
58
+ }
33
59
  },
34
60
  "options_considered": {
35
61
  "type": "array",
@@ -37,18 +63,36 @@
37
63
  "items": {
38
64
  "type": "object",
39
65
  "additionalProperties": false,
40
- "required": ["label", "description"],
66
+ "required": [
67
+ "label",
68
+ "description"
69
+ ],
41
70
  "properties": {
42
- "label": { "type": "string" },
43
- "description": { "type": "string" },
44
- "tradeoffs": { "type": "string" },
45
- "rejected_reason": { "type": "string", "description": "Populated only post-enactment for the non-chosen options." }
71
+ "label": {
72
+ "type": "string"
73
+ },
74
+ "description": {
75
+ "type": "string"
76
+ },
77
+ "tradeoffs": {
78
+ "type": "string"
79
+ },
80
+ "rejected_reason": {
81
+ "type": "string",
82
+ "description": "Populated only post-enactment for the non-chosen options."
83
+ }
46
84
  }
47
85
  }
48
86
  },
49
87
  "consequences": {
50
88
  "type": "array",
51
- "items": { "type": "string", "x-prompt-budget": { "tokens": 1000, "words": 800 } },
89
+ "items": {
90
+ "type": "string",
91
+ "x-prompt-budget": {
92
+ "tokens": 1000,
93
+ "words": 800
94
+ }
95
+ },
52
96
  "description": "What follows from the decision if enacted — what becomes easier, harder, or impossible; which constraint blocks or code files change."
53
97
  },
54
98
  "references": {
@@ -57,31 +101,84 @@
57
101
  "items": {
58
102
  "type": "object",
59
103
  "additionalProperties": false,
60
- "required": ["label"],
104
+ "required": [
105
+ "label"
106
+ ],
61
107
  "properties": {
62
- "label": { "type": "string" },
63
- "path": { "type": "string" },
64
- "lines": { "type": "string" },
65
- "commit": { "type": "string" }
108
+ "label": {
109
+ "type": "string"
110
+ },
111
+ "path": {
112
+ "type": "string"
113
+ },
114
+ "lines": {
115
+ "type": "string"
116
+ },
117
+ "commit": {
118
+ "type": "string"
119
+ }
66
120
  }
67
121
  }
68
122
  },
69
- "created_by": { "type": "string" },
70
- "created_at": { "type": "string" },
71
- "enacted_by": { "type": "string", "description": "User identifier; populated on status transition to enacted. Requires user authority." },
72
- "enacted_at": { "type": "string" }
123
+ "created_by": {
124
+ "type": "string"
125
+ },
126
+ "created_at": {
127
+ "type": "string"
128
+ },
129
+ "enacted_by": {
130
+ "type": "string",
131
+ "description": "User identifier; populated on status transition to enacted. Requires user authority."
132
+ },
133
+ "enacted_at": {
134
+ "type": "string"
135
+ },
136
+ "oid": {
137
+ "type": "string",
138
+ "pattern": "^[0-9a-f]{32}$",
139
+ "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."
140
+ },
141
+ "content_hash": {
142
+ "type": "string",
143
+ "pattern": "^[0-9a-f]{64}$",
144
+ "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."
145
+ },
146
+ "content_parent": {
147
+ "type": "string",
148
+ "pattern": "^[0-9a-f]{64}$",
149
+ "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."
150
+ }
73
151
  }
74
152
  }
75
153
  }
76
154
  },
77
155
  "x-lifecycle": {
78
156
  "field": "status",
79
- "states": ["open", "enacted", "superseded"],
157
+ "states": [
158
+ "open",
159
+ "enacted",
160
+ "superseded"
161
+ ],
80
162
  "transitions": [
81
- { "from": "open", "to": "enacted", "required_authority": "user", "note": "Enactment updates forward-looking constraint blocks and lands code change; entry is NOT removed on enactment." },
82
- { "from": "enacted", "to": "open", "required_authority": "user", "note": "Reopening for revision; creates a new open state on the existing entry rather than a new entry. Alternative pattern: create a new decision entry with a decision_supersedes_decision edge referencing this one." },
83
- { "from": "open", "to": "superseded", "required_authority": "user", "note": "Withdrawal of an entry that was filed under proliferation pressure or on incorrect framing. Reasoning lives in consequences. Used when the entry is acknowledged as not-a-real-decision rather than enacted." }
163
+ {
164
+ "from": "open",
165
+ "to": "enacted",
166
+ "required_authority": "user",
167
+ "note": "Enactment updates forward-looking constraint blocks and lands code change; entry is NOT removed on enactment."
168
+ },
169
+ {
170
+ "from": "enacted",
171
+ "to": "open",
172
+ "required_authority": "user",
173
+ "note": "Reopening for revision; creates a new open state on the existing entry rather than a new entry. Alternative pattern: create a new decision entry with a decision_supersedes_decision edge referencing this one."
174
+ },
175
+ {
176
+ "from": "open",
177
+ "to": "superseded",
178
+ "required_authority": "user",
179
+ "note": "Withdrawal of an entry that was filed under proliferation pressure or on incorrect framing. Reasoning lives in consequences. Used when the entry is acknowledged as not-a-real-decision rather than enacted."
180
+ }
84
181
  ],
85
- "note": "Three-state lifecycle. 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)."
182
+ "note": "Three-state lifecycle. 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."
86
183
  }
87
184
  }