@quolu/lattice 0.36.0 → 0.36.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.
@@ -0,0 +1,312 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.phase_todo_revision.v3.schema.json",
4
+ "title": "lattice.phase_todo_revision.v3",
5
+ "description": "`lattice todo revise-phase`が受理する最新契約。v1/v2のphase-audited desired state・task/phase migrationへ、runtime task migration・source inventory・per-ToDo source cutover batchを加えた12 keyの完全契約。",
6
+ "$comment": "Runtime validation (src/todo-revision.mjs validatePhaseTodoRevision) additionally enforces: canonical JSON+LF bytes; strict sort order on task_migration (by from_task_id), runtime_task_migration.entries (by predecessor_task_id), runtime_task_migration.entries[].successor_task_ids/evidence_digests, and source_inventory.excluded_tombstones/source_cutover_batch.operations (by source_ref); uniqueness constraints across all of those; desired_plan.plan_version === phaseTodoRevisionPlanVersion(...); runtime_task_migration projects onto task_migration exactly (validRuntimeTodoProjection) and its successor_task_ids cover exactly desired_plan.tasks; phase_migration's target phase set equals desired_plan.phases exactly; every reconciliation.*_digest field against its own recomputation; and revision_digest as the canonical self-digest over every other top-level field.",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": [
10
+ "schema", "project_id", "plan_key", "predecessor", "desired_plan",
11
+ "runtime_task_migration", "task_migration", "phase_migration", "source_inventory",
12
+ "reconciliation", "source_cutover_batch", "revision_digest"
13
+ ],
14
+ "properties": {
15
+ "schema": { "const": "lattice.phase_todo_revision.v3" },
16
+ "project_id": { "$ref": "#/$defs/identifier" },
17
+ "plan_key": { "$ref": "#/$defs/identifier" },
18
+ "predecessor": { "$ref": "#/$defs/predecessor" },
19
+ "desired_plan": { "$ref": "#/$defs/desiredPlanV5" },
20
+ "runtime_task_migration": { "$ref": "#/$defs/runtimeTaskMigration" },
21
+ "task_migration": {
22
+ "type": "array", "minItems": 1, "maxItems": 512,
23
+ "items": { "$ref": "#/$defs/taskMigrationEntry" }
24
+ },
25
+ "phase_migration": {
26
+ "type": "array", "minItems": 1, "maxItems": 512,
27
+ "items": { "$ref": "#/$defs/phaseMigrationEntry" }
28
+ },
29
+ "source_inventory": { "$ref": "#/$defs/sourceInventory" },
30
+ "reconciliation": {
31
+ "type": "object", "additionalProperties": false,
32
+ "required": [
33
+ "predecessor_reconciliation_digest", "source_inventory_digest", "desired_plan_digest",
34
+ "runtime_task_migration_digest", "task_migration_digest", "phase_migration_digest",
35
+ "source_cutover_batch_digest", "reconciliation_digest"
36
+ ],
37
+ "properties": {
38
+ "predecessor_reconciliation_digest": { "$ref": "#/$defs/digest" },
39
+ "source_inventory_digest": { "$ref": "#/$defs/digest" },
40
+ "desired_plan_digest": { "$ref": "#/$defs/digest" },
41
+ "runtime_task_migration_digest": { "$ref": "#/$defs/digest" },
42
+ "task_migration_digest": { "$ref": "#/$defs/digest" },
43
+ "phase_migration_digest": { "$ref": "#/$defs/digest" },
44
+ "source_cutover_batch_digest": { "$ref": "#/$defs/digest" },
45
+ "reconciliation_digest": { "$ref": "#/$defs/digest" }
46
+ }
47
+ },
48
+ "source_cutover_batch": { "$ref": "#/$defs/sourceCutoverBatch" },
49
+ "revision_digest": { "$ref": "#/$defs/digest" }
50
+ },
51
+ "$defs": {
52
+ "identifier": { "type": "string", "pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$" },
53
+ "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
54
+ "nullableDigest": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/digest" }] },
55
+ "gitSha": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
56
+ "repoRef": {
57
+ "type": "string",
58
+ "minLength": 1,
59
+ "maxLength": 1024,
60
+ "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*$"
61
+ },
62
+ "sourceLineRef": {
63
+ "type": "string",
64
+ "minLength": 1,
65
+ "maxLength": 1024,
66
+ "$comment": "repoRefと同じ形に加え#L<line>を必須にする。実際の判定はparseTodoSourceRef(src/todo-revision.mjs)。",
67
+ "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*#L[1-9][0-9]*$"
68
+ },
69
+ "nullableRepoRef": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/repoRef" }] },
70
+ "text": { "type": "string", "minLength": 1, "maxLength": 16384 },
71
+ "nullableText": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/text" }] },
72
+ "nodeRef": {
73
+ "type": "object", "additionalProperties": false,
74
+ "required": ["project_id", "plan_key", "task_id"],
75
+ "properties": {
76
+ "project_id": { "$ref": "#/$defs/identifier" },
77
+ "plan_key": { "$ref": "#/$defs/identifier" },
78
+ "task_id": { "$ref": "#/$defs/identifier" },
79
+ "expected_topology_digest": { "$ref": "#/$defs/digest" }
80
+ }
81
+ },
82
+ "phaseRef": {
83
+ "type": "object", "additionalProperties": false,
84
+ "required": ["project_id", "plan_key", "phase_id"],
85
+ "properties": {
86
+ "project_id": { "$ref": "#/$defs/identifier" },
87
+ "plan_key": { "$ref": "#/$defs/identifier" },
88
+ "phase_id": { "$ref": "#/$defs/identifier" },
89
+ "expected_topology_digest": { "$ref": "#/$defs/digest" }
90
+ }
91
+ },
92
+ "edge": {
93
+ "type": "object", "additionalProperties": false, "required": ["from", "to"],
94
+ "properties": { "from": { "$ref": "#/$defs/nodeRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
95
+ },
96
+ "phaseAcceptDependency": {
97
+ "type": "object", "additionalProperties": false, "required": ["from", "to"],
98
+ "properties": { "from": { "$ref": "#/$defs/phaseRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
99
+ },
100
+ "join": {
101
+ "type": "object", "additionalProperties": false, "required": ["id", "after", "before"],
102
+ "properties": {
103
+ "id": { "$ref": "#/$defs/identifier" },
104
+ "after": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/nodeRef" } },
105
+ "before": { "$ref": "#/$defs/nodeRef" }
106
+ }
107
+ },
108
+ "narrativeAnchor": {
109
+ "type": "object", "additionalProperties": false,
110
+ "required": ["origin_plan_ref", "origin_line", "source_commit", "source_line_digest"],
111
+ "properties": {
112
+ "origin_plan_ref": { "$ref": "#/$defs/repoRef" },
113
+ "origin_line": { "type": "integer", "minimum": 1 },
114
+ "source_commit": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
115
+ "source_line_digest": { "$ref": "#/$defs/digest" }
116
+ }
117
+ },
118
+ "compileBinding": {
119
+ "oneOf": [
120
+ { "type": "null" },
121
+ {
122
+ "type": "object", "additionalProperties": false,
123
+ "required": ["boundary_manifest_digest", "compiled_plan_digest", "topology_digest", "base_sha"],
124
+ "properties": {
125
+ "boundary_manifest_digest": { "$ref": "#/$defs/digest" },
126
+ "compiled_plan_digest": { "$ref": "#/$defs/digest" },
127
+ "topology_digest": { "$ref": "#/$defs/digest" },
128
+ "base_sha": { "$ref": "#/$defs/gitSha" }
129
+ }
130
+ }
131
+ ]
132
+ },
133
+ "predecessor": {
134
+ "type": "object", "additionalProperties": false,
135
+ "required": ["plan_digest", "journal_head_digest", "plan_version"],
136
+ "properties": {
137
+ "plan_digest": { "$ref": "#/$defs/digest" },
138
+ "journal_head_digest": { "$ref": "#/$defs/digest" },
139
+ "plan_version": { "$ref": "#/$defs/identifier" }
140
+ }
141
+ },
142
+ "taskV4": {
143
+ "type": "object", "additionalProperties": false,
144
+ "required": [
145
+ "task_id", "title", "lane", "narrative_ref", "narrative_anchor", "compile_binding",
146
+ "parent_task_id", "phase_id"
147
+ ],
148
+ "properties": {
149
+ "task_id": { "$ref": "#/$defs/identifier" },
150
+ "title": { "$ref": "#/$defs/nullableText" },
151
+ "lane": { "$ref": "#/$defs/identifier" },
152
+ "narrative_ref": { "$ref": "#/$defs/nullableRepoRef" },
153
+ "narrative_anchor": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/narrativeAnchor" }] },
154
+ "compile_binding": { "$ref": "#/$defs/compileBinding" },
155
+ "parent_task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
156
+ "phase_id": { "$ref": "#/$defs/identifier" }
157
+ }
158
+ },
159
+ "phase": {
160
+ "type": "object", "additionalProperties": false,
161
+ "required": ["phase_id", "title", "gate_policy", "predecessor_phase_ids", "required_evidence_slots"],
162
+ "properties": {
163
+ "phase_id": { "$ref": "#/$defs/identifier" },
164
+ "title": { "$ref": "#/$defs/nullableText" },
165
+ "gate_policy": { "$ref": "#/$defs/identifier" },
166
+ "predecessor_phase_ids": {
167
+ "type": "array", "items": { "$ref": "#/$defs/identifier" }, "uniqueItems": true
168
+ },
169
+ "required_evidence_slots": {
170
+ "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" }, "uniqueItems": true
171
+ }
172
+ }
173
+ },
174
+ "desiredPlanV5": {
175
+ "type": "object", "additionalProperties": false,
176
+ "required": [
177
+ "schema", "project_id", "plan_key", "plan_version", "predecessor_plan_digest",
178
+ "tasks", "hard_dependencies", "joins", "phases", "phase_accept_dependencies",
179
+ "topology_digest", "plan_digest"
180
+ ],
181
+ "properties": {
182
+ "schema": { "const": "lattice.todo_plan.v5" },
183
+ "project_id": { "$ref": "#/$defs/identifier" },
184
+ "plan_key": { "$ref": "#/$defs/identifier" },
185
+ "plan_version": { "$ref": "#/$defs/identifier" },
186
+ "predecessor_plan_digest": { "$ref": "#/$defs/nullableDigest" },
187
+ "tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskV4" } },
188
+ "hard_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/edge" } },
189
+ "joins": { "type": "array", "maxItems": 128, "items": { "$ref": "#/$defs/join" } },
190
+ "phases": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/phase" } },
191
+ "phase_accept_dependencies": {
192
+ "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/phaseAcceptDependency" }
193
+ },
194
+ "topology_digest": { "$ref": "#/$defs/digest" },
195
+ "plan_digest": { "$ref": "#/$defs/digest" }
196
+ }
197
+ },
198
+ "taskMigrationEntry": {
199
+ "type": "object", "additionalProperties": false,
200
+ "required": ["from_task_id", "to_task_id", "state_policy"],
201
+ "properties": {
202
+ "from_task_id": { "$ref": "#/$defs/identifier" },
203
+ "to_task_id": { "oneOf": [{ "const": "removed" }, { "$ref": "#/$defs/identifier" }] },
204
+ "state_policy": {
205
+ "enum": ["carry", "carry_reconciled_metadata", "reset_pending", "removed"],
206
+ "$comment": "'removed'はto_task_id==='removed'の時だけ、他の3値はto_task_idがidentifierの時だけ許される(runtime cross-check)。runtime_task_migrationのdisposition投影とも一致していなければならない(validRuntimeTodoProjection)。"
207
+ }
208
+ }
209
+ },
210
+ "phaseMigrationEntry": {
211
+ "type": "object", "additionalProperties": false,
212
+ "required": ["from_phase_id", "to_phase_id", "state_policy"],
213
+ "properties": {
214
+ "from_phase_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
215
+ "to_phase_id": { "oneOf": [{ "const": "removed" }, { "$ref": "#/$defs/identifier" }] },
216
+ "state_policy": {
217
+ "enum": ["carry", "reset", "removed"],
218
+ "$comment": "carryはfrom_phase_id!=null かつ to_phase_id!=='removed'の時だけ、removedはfrom_phase_id!=null かつ to_phase_id==='removed'の時だけ、resetはto_phase_id!=='removed'の時だけ許される(runtime cross-check)。"
219
+ }
220
+ }
221
+ },
222
+ "runtimeTaskMigrationEntry": {
223
+ "type": "object", "additionalProperties": false,
224
+ "required": ["predecessor_task_id", "disposition", "successor_task_ids", "reason", "evidence_digests"],
225
+ "properties": {
226
+ "predecessor_task_id": { "$ref": "#/$defs/identifier" },
227
+ "disposition": { "enum": ["carry", "stay", "replace", "split", "retire"] },
228
+ "successor_task_ids": {
229
+ "type": "array", "maxItems": 512, "items": { "$ref": "#/$defs/identifier" }, "uniqueItems": true,
230
+ "$comment": "carry/stayは要素1つでpredecessor_task_idと同一、retireは空、replace/splitは1つ以上(runtime cross-check)。全entry合算で重複禁止。"
231
+ },
232
+ "reason": { "$ref": "#/$defs/text" },
233
+ "evidence_digests": {
234
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/digest" },
235
+ "uniqueItems": true
236
+ }
237
+ }
238
+ },
239
+ "runtimeTaskMigration": {
240
+ "type": "object", "additionalProperties": false,
241
+ "required": ["schema", "entries", "migration_digest"],
242
+ "properties": {
243
+ "schema": { "const": "lattice.runtime_task_migration.v1" },
244
+ "entries": {
245
+ "type": "array", "minItems": 1, "maxItems": 512,
246
+ "items": { "$ref": "#/$defs/runtimeTaskMigrationEntry" }
247
+ },
248
+ "migration_digest": { "$ref": "#/$defs/digest" }
249
+ }
250
+ },
251
+ "sourceInventoryActiveEntry": {
252
+ "type": "object", "additionalProperties": false,
253
+ "required": ["task_id", "source_ref", "source_digest"],
254
+ "properties": {
255
+ "task_id": { "$ref": "#/$defs/identifier" },
256
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
257
+ "source_digest": { "$ref": "#/$defs/digest" }
258
+ }
259
+ },
260
+ "sourceInventoryTombstone": {
261
+ "type": "object", "additionalProperties": false,
262
+ "required": ["source_ref", "source_digest", "exclusion_reason"],
263
+ "properties": {
264
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
265
+ "source_digest": { "$ref": "#/$defs/digest" },
266
+ "exclusion_reason": { "$ref": "#/$defs/text" }
267
+ }
268
+ },
269
+ "sourceInventory": {
270
+ "type": "object", "additionalProperties": false,
271
+ "required": ["active", "excluded_tombstones"],
272
+ "$comment": "activeはdesired_plan.tasksと同じ順序・同じtask_id集合でなければならず、各entryのsource_refはそのtaskのnarrative_refと一致する必要がある(revise-phase v3固有のrequireNarrativeRef、runtime cross-check)。",
273
+ "properties": {
274
+ "active": {
275
+ "type": "array", "maxItems": 512, "items": { "$ref": "#/$defs/sourceInventoryActiveEntry" }
276
+ },
277
+ "excluded_tombstones": {
278
+ "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/sourceInventoryTombstone" }
279
+ }
280
+ }
281
+ },
282
+ "sourceCutoverOperation": {
283
+ "type": "object", "additionalProperties": false,
284
+ "required": ["task_id", "disposition", "source_ref", "source_digest", "live_replacement"],
285
+ "properties": {
286
+ "task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
287
+ "disposition": { "enum": ["active", "excluded"] },
288
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
289
+ "source_digest": { "$ref": "#/$defs/digest" },
290
+ "live_replacement": {
291
+ "type": "string", "minLength": 1, "maxLength": 4096,
292
+ "$comment": "改行・制御文字禁止に加え、Markdownチェックボックス行に見える文字列は拒否される(validLiveReplacement)。"
293
+ }
294
+ }
295
+ },
296
+ "sourceCutoverBatch": {
297
+ "type": "object", "additionalProperties": false,
298
+ "required": ["batch_id", "archive_ref", "operations", "batch_digest"],
299
+ "properties": {
300
+ "batch_id": { "$ref": "#/$defs/identifier" },
301
+ "archive_ref": {
302
+ "allOf": [{ "$ref": "#/$defs/repoRef" }, { "pattern": "\\.md$" }],
303
+ "$comment": "#L<line>付きのsourceLineRef形にはなり得ない(runtime cross-check)。"
304
+ },
305
+ "operations": {
306
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/sourceCutoverOperation" }
307
+ },
308
+ "batch_digest": { "$ref": "#/$defs/digest" }
309
+ }
310
+ }
311
+ }
312
+ }
@@ -0,0 +1,298 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.todo_extraction.v2.schema.json",
4
+ "title": "lattice.todo_extraction.v2",
5
+ "description": "G4 migration-wave-only intermediate artifact authored by AI. Version 2 adds fail-closed historical in-progress registration without changing v1.",
6
+ "$comment": "Runtime validation additionally enforces UTF-8 byte bounds, strict sort order, unique and resolvable task ids, and extraction_digest as the canonical self-digest. Registration separately rejects an extraction with no register_* task.",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": [
10
+ "schema",
11
+ "project_id",
12
+ "plan_key",
13
+ "plan_version",
14
+ "actor",
15
+ "recorded_at",
16
+ "tasks",
17
+ "hard_dependencies",
18
+ "joins",
19
+ "extraction_digest"
20
+ ],
21
+ "properties": {
22
+ "schema": { "const": "lattice.todo_extraction.v2" },
23
+ "project_id": { "$ref": "#/$defs/identifier" },
24
+ "plan_key": { "$ref": "#/$defs/identifier" },
25
+ "plan_version": { "$ref": "#/$defs/identifier" },
26
+ "actor": { "$ref": "#/$defs/actor" },
27
+ "recorded_at": { "$ref": "#/$defs/strictTimestamp" },
28
+ "tasks": {
29
+ "type": "array",
30
+ "minItems": 1,
31
+ "maxItems": 512,
32
+ "items": { "$ref": "#/$defs/task" }
33
+ },
34
+ "hard_dependencies": {
35
+ "type": "array",
36
+ "maxItems": 2048,
37
+ "items": {
38
+ "type": "object",
39
+ "additionalProperties": false,
40
+ "required": ["from", "to"],
41
+ "properties": {
42
+ "from": { "$ref": "#/$defs/nodeRef" },
43
+ "to": { "$ref": "#/$defs/nodeRef" }
44
+ }
45
+ }
46
+ },
47
+ "joins": {
48
+ "type": "array",
49
+ "maxItems": 128,
50
+ "items": {
51
+ "type": "object",
52
+ "additionalProperties": false,
53
+ "required": ["id", "after", "before"],
54
+ "properties": {
55
+ "id": { "$ref": "#/$defs/identifier" },
56
+ "after": {
57
+ "type": "array",
58
+ "minItems": 1,
59
+ "maxItems": 512,
60
+ "items": { "$ref": "#/$defs/nodeRef" }
61
+ },
62
+ "before": { "$ref": "#/$defs/nodeRef" }
63
+ }
64
+ }
65
+ },
66
+ "extraction_digest": { "$ref": "#/$defs/digest" }
67
+ },
68
+ "$defs": {
69
+ "identifier": {
70
+ "type": "string",
71
+ "pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$"
72
+ },
73
+ "digest": {
74
+ "type": "string",
75
+ "pattern": "^[0-9a-f]{64}$"
76
+ },
77
+ "repoRef": {
78
+ "type": "string",
79
+ "minLength": 1,
80
+ "maxLength": 1024,
81
+ "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*$"
82
+ },
83
+ "text": {
84
+ "type": "string",
85
+ "minLength": 1,
86
+ "maxLength": 16384
87
+ },
88
+ "nullableText": {
89
+ "oneOf": [
90
+ { "type": "null" },
91
+ { "$ref": "#/$defs/text" }
92
+ ]
93
+ },
94
+ "strictTimestamp": {
95
+ "type": "string",
96
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$",
97
+ "$comment": "Runtime validation also requires Date.parse(value).toISOString() byte equality."
98
+ },
99
+ "actor": {
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "required": ["host", "session", "agent"],
103
+ "properties": {
104
+ "host": { "$ref": "#/$defs/identifier" },
105
+ "session": { "$ref": "#/$defs/identifier" },
106
+ "agent": { "$ref": "#/$defs/identifier" }
107
+ }
108
+ },
109
+ "nodeRef": {
110
+ "type": "object",
111
+ "additionalProperties": false,
112
+ "required": ["project_id", "plan_key", "task_id"],
113
+ "properties": {
114
+ "project_id": { "$ref": "#/$defs/identifier" },
115
+ "plan_key": { "$ref": "#/$defs/identifier" },
116
+ "task_id": { "$ref": "#/$defs/identifier" },
117
+ "expected_topology_digest": { "$ref": "#/$defs/digest" }
118
+ }
119
+ },
120
+ "sourceLocation": {
121
+ "type": "object",
122
+ "additionalProperties": false,
123
+ "required": [
124
+ "origin_plan_ref",
125
+ "origin_line",
126
+ "source_commit",
127
+ "heading_path",
128
+ "markdown_depth",
129
+ "parent_task_id",
130
+ "checkbox_state"
131
+ ],
132
+ "properties": {
133
+ "origin_plan_ref": { "$ref": "#/$defs/repoRef" },
134
+ "origin_line": { "type": "integer", "minimum": 1 },
135
+ "source_commit": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
136
+ "heading_path": {
137
+ "type": "array",
138
+ "maxItems": 32,
139
+ "items": { "type": "string", "minLength": 1, "maxLength": 1024 }
140
+ },
141
+ "markdown_depth": { "type": "integer", "minimum": 0, "maximum": 64 },
142
+ "parent_task_id": {
143
+ "oneOf": [
144
+ { "type": "null" },
145
+ { "$ref": "#/$defs/identifier" }
146
+ ]
147
+ },
148
+ "checkbox_state": {
149
+ "enum": ["checked", "unchecked", "absent", "ambiguous"]
150
+ }
151
+ }
152
+ },
153
+ "migrationContext": {
154
+ "type": "object",
155
+ "additionalProperties": false,
156
+ "required": [
157
+ "external_canonical_ref",
158
+ "carry_over_ref",
159
+ "h_required",
160
+ "condition",
161
+ "evidence_refs",
162
+ "notes"
163
+ ],
164
+ "properties": {
165
+ "external_canonical_ref": { "$ref": "#/$defs/nullableText" },
166
+ "carry_over_ref": { "$ref": "#/$defs/nullableText" },
167
+ "h_required": { "type": "boolean" },
168
+ "condition": { "$ref": "#/$defs/nullableText" },
169
+ "evidence_refs": {
170
+ "type": "array",
171
+ "maxItems": 64,
172
+ "items": { "type": "string", "minLength": 1, "maxLength": 4096 }
173
+ },
174
+ "notes": {
175
+ "type": "array",
176
+ "maxItems": 64,
177
+ "items": { "type": "string", "minLength": 1, "maxLength": 4096 }
178
+ }
179
+ }
180
+ },
181
+ "historicalStart": {
182
+ "type": "object",
183
+ "additionalProperties": false,
184
+ "required": ["start_mode", "status", "started_at"],
185
+ "properties": {
186
+ "start_mode": { "const": "historical_import" },
187
+ "status": { "const": "in-progress" },
188
+ "started_at": {
189
+ "oneOf": [
190
+ { "const": "unknown_requires_evidence" },
191
+ { "$ref": "#/$defs/strictTimestamp" }
192
+ ]
193
+ }
194
+ }
195
+ },
196
+ "historicalCompletion": {
197
+ "type": "object",
198
+ "additionalProperties": false,
199
+ "required": ["done_mode", "completed_at"],
200
+ "properties": {
201
+ "done_mode": { "const": "historical_import" },
202
+ "completed_at": {
203
+ "oneOf": [
204
+ { "const": "unknown_requires_evidence" },
205
+ { "$ref": "#/$defs/strictTimestamp" }
206
+ ]
207
+ }
208
+ }
209
+ },
210
+ "taskBase": {
211
+ "type": "object",
212
+ "additionalProperties": false,
213
+ "required": [
214
+ "task_id",
215
+ "title",
216
+ "lane",
217
+ "narrative_ref",
218
+ "compile_binding",
219
+ "disposition",
220
+ "start",
221
+ "completion",
222
+ "source",
223
+ "migration_context"
224
+ ],
225
+ "properties": {
226
+ "task_id": { "$ref": "#/$defs/identifier" },
227
+ "title": { "$ref": "#/$defs/text" },
228
+ "lane": { "$ref": "#/$defs/identifier" },
229
+ "narrative_ref": {
230
+ "oneOf": [
231
+ { "type": "null" },
232
+ { "$ref": "#/$defs/repoRef" }
233
+ ]
234
+ },
235
+ "compile_binding": { "type": "null" },
236
+ "disposition": {
237
+ "enum": [
238
+ "register_pending",
239
+ "register_in_progress",
240
+ "register_done",
241
+ "exclude_superseded",
242
+ "exclude_compatibility_record",
243
+ "unknown_requires_evidence"
244
+ ]
245
+ },
246
+ "start": {
247
+ "oneOf": [
248
+ { "type": "null" },
249
+ { "$ref": "#/$defs/historicalStart" }
250
+ ]
251
+ },
252
+ "completion": {
253
+ "oneOf": [
254
+ { "type": "null" },
255
+ { "$ref": "#/$defs/historicalCompletion" }
256
+ ]
257
+ },
258
+ "source": { "$ref": "#/$defs/sourceLocation" },
259
+ "migration_context": { "$ref": "#/$defs/migrationContext" }
260
+ }
261
+ },
262
+ "task": {
263
+ "allOf": [
264
+ { "$ref": "#/$defs/taskBase" },
265
+ {
266
+ "if": {
267
+ "properties": { "disposition": { "const": "register_in_progress" } },
268
+ "required": ["disposition"]
269
+ },
270
+ "then": {
271
+ "properties": {
272
+ "start": { "$ref": "#/$defs/historicalStart" },
273
+ "completion": { "type": "null" }
274
+ }
275
+ },
276
+ "else": {
277
+ "if": {
278
+ "properties": { "disposition": { "const": "register_done" } },
279
+ "required": ["disposition"]
280
+ },
281
+ "then": {
282
+ "properties": {
283
+ "start": { "type": "null" },
284
+ "completion": { "$ref": "#/$defs/historicalCompletion" }
285
+ }
286
+ },
287
+ "else": {
288
+ "properties": {
289
+ "start": { "type": "null" },
290
+ "completion": { "type": "null" }
291
+ }
292
+ }
293
+ }
294
+ }
295
+ ]
296
+ }
297
+ }
298
+ }
@@ -0,0 +1,220 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.todo_revision.v2.schema.json",
4
+ "title": "lattice.todo_revision.v2",
5
+ "description": "`lattice todo revise`が受理する最新契約。v1のdesired state・source inventory・reconciliationへ、per-ToDoのsource cutover batch(Markdown置換の証跡)を加える。",
6
+ "$comment": "Runtime validation (src/todo-revision.mjs validateTodoRevision) additionally enforces: canonical JSON+LF bytes; strict sort order on task_migration (by from_task_id) and source_inventory.excluded_tombstones/source_cutover_batch.operations (by source_ref); uniqueness of from_task_id/to_task_id/source_ref across those collections; desired_plan.plan_version === todoRevisionPlanVersion(...); reconciliation.reconciliation_digest === todoReconciliationDigest(...); revision_digest as the canonical self-digest over every other top-level field; and that every task_migration.to_task_id (other than 'removed') resolves to a desired_plan task.",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": [
10
+ "schema", "project_id", "plan_key", "predecessor", "desired_plan", "task_migration",
11
+ "source_inventory", "reconciliation", "source_cutover_batch", "revision_digest"
12
+ ],
13
+ "properties": {
14
+ "schema": { "const": "lattice.todo_revision.v2" },
15
+ "project_id": { "$ref": "#/$defs/identifier" },
16
+ "plan_key": { "$ref": "#/$defs/identifier" },
17
+ "predecessor": { "$ref": "#/$defs/predecessor" },
18
+ "desired_plan": { "$ref": "#/$defs/desiredPlanV3" },
19
+ "task_migration": {
20
+ "type": "array", "minItems": 1, "maxItems": 512,
21
+ "items": { "$ref": "#/$defs/taskMigrationEntry" }
22
+ },
23
+ "source_inventory": { "$ref": "#/$defs/sourceInventory" },
24
+ "reconciliation": {
25
+ "type": "object", "additionalProperties": false,
26
+ "required": ["predecessor_reconciliation_digest", "source_inventory_digest", "reconciliation_digest"],
27
+ "properties": {
28
+ "predecessor_reconciliation_digest": { "$ref": "#/$defs/digest" },
29
+ "source_inventory_digest": { "$ref": "#/$defs/digest" },
30
+ "reconciliation_digest": { "$ref": "#/$defs/digest" }
31
+ }
32
+ },
33
+ "source_cutover_batch": { "$ref": "#/$defs/sourceCutoverBatch" },
34
+ "revision_digest": { "$ref": "#/$defs/digest" }
35
+ },
36
+ "$defs": {
37
+ "identifier": { "type": "string", "pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$" },
38
+ "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
39
+ "nullableDigest": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/digest" }] },
40
+ "gitSha": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
41
+ "repoRef": {
42
+ "type": "string",
43
+ "minLength": 1,
44
+ "maxLength": 1024,
45
+ "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*$"
46
+ },
47
+ "sourceLineRef": {
48
+ "type": "string",
49
+ "minLength": 1,
50
+ "maxLength": 1024,
51
+ "$comment": "repoRefと同じ形に加え#L<line>を必須にする。実際の判定はparseTodoSourceRef(src/todo-revision.mjs)。",
52
+ "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*#L[1-9][0-9]*$"
53
+ },
54
+ "nullableRepoRef": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/repoRef" }] },
55
+ "text": { "type": "string", "minLength": 1, "maxLength": 16384 },
56
+ "nullableText": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/text" }] },
57
+ "nodeRef": {
58
+ "type": "object", "additionalProperties": false,
59
+ "required": ["project_id", "plan_key", "task_id"],
60
+ "properties": {
61
+ "project_id": { "$ref": "#/$defs/identifier" },
62
+ "plan_key": { "$ref": "#/$defs/identifier" },
63
+ "task_id": { "$ref": "#/$defs/identifier" },
64
+ "expected_topology_digest": { "$ref": "#/$defs/digest" }
65
+ }
66
+ },
67
+ "edge": {
68
+ "type": "object", "additionalProperties": false, "required": ["from", "to"],
69
+ "properties": { "from": { "$ref": "#/$defs/nodeRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
70
+ },
71
+ "join": {
72
+ "type": "object", "additionalProperties": false, "required": ["id", "after", "before"],
73
+ "properties": {
74
+ "id": { "$ref": "#/$defs/identifier" },
75
+ "after": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/nodeRef" } },
76
+ "before": { "$ref": "#/$defs/nodeRef" }
77
+ }
78
+ },
79
+ "narrativeAnchor": {
80
+ "type": "object", "additionalProperties": false,
81
+ "required": ["origin_plan_ref", "origin_line", "source_commit", "source_line_digest"],
82
+ "properties": {
83
+ "origin_plan_ref": { "$ref": "#/$defs/repoRef" },
84
+ "origin_line": { "type": "integer", "minimum": 1 },
85
+ "source_commit": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
86
+ "source_line_digest": { "$ref": "#/$defs/digest" }
87
+ }
88
+ },
89
+ "compileBinding": {
90
+ "oneOf": [
91
+ { "type": "null" },
92
+ {
93
+ "type": "object", "additionalProperties": false,
94
+ "required": ["boundary_manifest_digest", "compiled_plan_digest", "topology_digest", "base_sha"],
95
+ "properties": {
96
+ "boundary_manifest_digest": { "$ref": "#/$defs/digest" },
97
+ "compiled_plan_digest": { "$ref": "#/$defs/digest" },
98
+ "topology_digest": { "$ref": "#/$defs/digest" },
99
+ "base_sha": { "$ref": "#/$defs/gitSha" }
100
+ }
101
+ }
102
+ ]
103
+ },
104
+ "predecessor": {
105
+ "type": "object", "additionalProperties": false,
106
+ "required": ["plan_digest", "journal_head_digest", "plan_version"],
107
+ "properties": {
108
+ "plan_digest": { "$ref": "#/$defs/digest" },
109
+ "journal_head_digest": { "$ref": "#/$defs/digest" },
110
+ "plan_version": { "$ref": "#/$defs/identifier" }
111
+ }
112
+ },
113
+ "taskV3": {
114
+ "type": "object", "additionalProperties": false,
115
+ "required": [
116
+ "task_id", "title", "lane", "narrative_ref", "narrative_anchor", "compile_binding", "parent_task_id"
117
+ ],
118
+ "properties": {
119
+ "task_id": { "$ref": "#/$defs/identifier" },
120
+ "title": { "$ref": "#/$defs/nullableText" },
121
+ "lane": { "$ref": "#/$defs/identifier" },
122
+ "narrative_ref": { "$ref": "#/$defs/nullableRepoRef" },
123
+ "narrative_anchor": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/narrativeAnchor" }] },
124
+ "compile_binding": { "$ref": "#/$defs/compileBinding" },
125
+ "parent_task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] }
126
+ }
127
+ },
128
+ "desiredPlanV3": {
129
+ "type": "object", "additionalProperties": false,
130
+ "required": [
131
+ "schema", "project_id", "plan_key", "plan_version", "predecessor_plan_digest",
132
+ "tasks", "hard_dependencies", "joins", "topology_digest", "plan_digest"
133
+ ],
134
+ "properties": {
135
+ "schema": { "const": "lattice.todo_plan.v3" },
136
+ "project_id": { "$ref": "#/$defs/identifier" },
137
+ "plan_key": { "$ref": "#/$defs/identifier" },
138
+ "plan_version": { "$ref": "#/$defs/identifier" },
139
+ "predecessor_plan_digest": { "$ref": "#/$defs/nullableDigest" },
140
+ "tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskV3" } },
141
+ "hard_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/edge" } },
142
+ "joins": { "type": "array", "maxItems": 128, "items": { "$ref": "#/$defs/join" } },
143
+ "topology_digest": { "$ref": "#/$defs/digest" },
144
+ "plan_digest": { "$ref": "#/$defs/digest" }
145
+ }
146
+ },
147
+ "taskMigrationEntry": {
148
+ "type": "object", "additionalProperties": false,
149
+ "required": ["from_task_id", "to_task_id", "state_policy"],
150
+ "properties": {
151
+ "from_task_id": { "$ref": "#/$defs/identifier" },
152
+ "to_task_id": { "oneOf": [{ "const": "removed" }, { "$ref": "#/$defs/identifier" }] },
153
+ "state_policy": {
154
+ "enum": ["carry", "carry_reconciled_metadata", "reset_pending", "removed"],
155
+ "$comment": "'removed'はto_task_id==='removed'の時だけ、他の3値はto_task_idがidentifierの時だけ許される(runtime cross-check)。"
156
+ }
157
+ }
158
+ },
159
+ "sourceInventoryActiveEntry": {
160
+ "type": "object", "additionalProperties": false,
161
+ "required": ["task_id", "source_ref", "source_digest"],
162
+ "properties": {
163
+ "task_id": { "$ref": "#/$defs/identifier" },
164
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
165
+ "source_digest": { "$ref": "#/$defs/digest" }
166
+ }
167
+ },
168
+ "sourceInventoryTombstone": {
169
+ "type": "object", "additionalProperties": false,
170
+ "required": ["source_ref", "source_digest", "exclusion_reason"],
171
+ "properties": {
172
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
173
+ "source_digest": { "$ref": "#/$defs/digest" },
174
+ "exclusion_reason": { "$ref": "#/$defs/text" }
175
+ }
176
+ },
177
+ "sourceInventory": {
178
+ "type": "object", "additionalProperties": false,
179
+ "required": ["active", "excluded_tombstones"],
180
+ "$comment": "activeはdesired_plan.tasksと同じ順序・同じtask_id集合でなければならない(runtime cross-check)。",
181
+ "properties": {
182
+ "active": {
183
+ "type": "array", "maxItems": 512, "items": { "$ref": "#/$defs/sourceInventoryActiveEntry" }
184
+ },
185
+ "excluded_tombstones": {
186
+ "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/sourceInventoryTombstone" }
187
+ }
188
+ }
189
+ },
190
+ "sourceCutoverOperation": {
191
+ "type": "object", "additionalProperties": false,
192
+ "required": ["task_id", "disposition", "source_ref", "source_digest", "live_replacement"],
193
+ "properties": {
194
+ "task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
195
+ "disposition": { "enum": ["active", "excluded"] },
196
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
197
+ "source_digest": { "$ref": "#/$defs/digest" },
198
+ "live_replacement": {
199
+ "type": "string", "minLength": 1, "maxLength": 4096,
200
+ "$comment": "改行・制御文字禁止に加え、Markdownチェックボックス行に見える文字列は拒否される(validLiveReplacement)。"
201
+ }
202
+ }
203
+ },
204
+ "sourceCutoverBatch": {
205
+ "type": "object", "additionalProperties": false,
206
+ "required": ["batch_id", "archive_ref", "operations", "batch_digest"],
207
+ "properties": {
208
+ "batch_id": { "$ref": "#/$defs/identifier" },
209
+ "archive_ref": {
210
+ "allOf": [{ "$ref": "#/$defs/repoRef" }, { "pattern": "\\.md$" }],
211
+ "$comment": "#L<line>付きのsourceLineRef形にはなり得ない(runtime cross-check)。"
212
+ },
213
+ "operations": {
214
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/sourceCutoverOperation" }
215
+ },
216
+ "batch_digest": { "$ref": "#/$defs/digest" }
217
+ }
218
+ }
219
+ }
220
+ }
@@ -0,0 +1,363 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.todo_revision_set.v3.schema.json",
4
+ "title": "lattice.todo_revision_set.v3",
5
+ "description": "`lattice todo revise-set`が受理する最新契約。複数planへ跨がるrevisionを1つのatomic書込みへ束ねる。v3のmemberは`lattice.todo_revision.v1/v2`(非phase plan)と`lattice.phase_todo_revision.v1/v2`(phase-audited plan)のいずれかであり、`lattice.phase_todo_revision.v3`はmemberとして受理されない——v3固有のruntime_task_migration/source_cutover_batchはrevise-setの外で単独revise-phaseとして扱う契約になっている。",
6
+ "$comment": "Runtime validation (src/todo-revision.mjs validateTodoRevisionSet) additionally enforces: canonical JSON+LF bytes; revisions.length in [2, 64]; each member's own digest chain (validateTodoRevision / validatePhaseTodoRevision); every member.project_id === project_id; v3はrevisions内に最低1つphase_todo_revision memberを含む必要がある; revisionsが厳密にplan_key昇順でソートされている(重複plan_key禁止); revision_set_digestは他の全top-level fieldへの正準self-digest。",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": ["schema", "project_id", "revisions", "revision_set_digest"],
10
+ "properties": {
11
+ "schema": { "const": "lattice.todo_revision_set.v3" },
12
+ "project_id": { "$ref": "#/$defs/identifier" },
13
+ "revisions": {
14
+ "type": "array", "minItems": 2, "maxItems": 64,
15
+ "items": {
16
+ "oneOf": [
17
+ { "$ref": "#/$defs/todoRevisionMember" },
18
+ { "$ref": "#/$defs/phaseTodoRevisionMember" }
19
+ ]
20
+ }
21
+ },
22
+ "revision_set_digest": { "$ref": "#/$defs/digest" }
23
+ },
24
+ "$defs": {
25
+ "identifier": { "type": "string", "pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$" },
26
+ "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
27
+ "nullableDigest": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/digest" }] },
28
+ "gitSha": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
29
+ "repoRef": {
30
+ "type": "string",
31
+ "minLength": 1,
32
+ "maxLength": 1024,
33
+ "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*$"
34
+ },
35
+ "sourceLineRef": {
36
+ "type": "string",
37
+ "minLength": 1,
38
+ "maxLength": 1024,
39
+ "pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*#L[1-9][0-9]*$"
40
+ },
41
+ "nullableRepoRef": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/repoRef" }] },
42
+ "text": { "type": "string", "minLength": 1, "maxLength": 16384 },
43
+ "nullableText": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/text" }] },
44
+ "nodeRef": {
45
+ "type": "object", "additionalProperties": false,
46
+ "required": ["project_id", "plan_key", "task_id"],
47
+ "properties": {
48
+ "project_id": { "$ref": "#/$defs/identifier" },
49
+ "plan_key": { "$ref": "#/$defs/identifier" },
50
+ "task_id": { "$ref": "#/$defs/identifier" },
51
+ "expected_topology_digest": { "$ref": "#/$defs/digest" }
52
+ }
53
+ },
54
+ "phaseRef": {
55
+ "type": "object", "additionalProperties": false,
56
+ "required": ["project_id", "plan_key", "phase_id"],
57
+ "properties": {
58
+ "project_id": { "$ref": "#/$defs/identifier" },
59
+ "plan_key": { "$ref": "#/$defs/identifier" },
60
+ "phase_id": { "$ref": "#/$defs/identifier" },
61
+ "expected_topology_digest": { "$ref": "#/$defs/digest" }
62
+ }
63
+ },
64
+ "edge": {
65
+ "type": "object", "additionalProperties": false, "required": ["from", "to"],
66
+ "properties": { "from": { "$ref": "#/$defs/nodeRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
67
+ },
68
+ "phaseAcceptDependency": {
69
+ "type": "object", "additionalProperties": false, "required": ["from", "to"],
70
+ "properties": { "from": { "$ref": "#/$defs/phaseRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
71
+ },
72
+ "join": {
73
+ "type": "object", "additionalProperties": false, "required": ["id", "after", "before"],
74
+ "properties": {
75
+ "id": { "$ref": "#/$defs/identifier" },
76
+ "after": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/nodeRef" } },
77
+ "before": { "$ref": "#/$defs/nodeRef" }
78
+ }
79
+ },
80
+ "narrativeAnchor": {
81
+ "type": "object", "additionalProperties": false,
82
+ "required": ["origin_plan_ref", "origin_line", "source_commit", "source_line_digest"],
83
+ "properties": {
84
+ "origin_plan_ref": { "$ref": "#/$defs/repoRef" },
85
+ "origin_line": { "type": "integer", "minimum": 1 },
86
+ "source_commit": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
87
+ "source_line_digest": { "$ref": "#/$defs/digest" }
88
+ }
89
+ },
90
+ "compileBinding": {
91
+ "oneOf": [
92
+ { "type": "null" },
93
+ {
94
+ "type": "object", "additionalProperties": false,
95
+ "required": ["boundary_manifest_digest", "compiled_plan_digest", "topology_digest", "base_sha"],
96
+ "properties": {
97
+ "boundary_manifest_digest": { "$ref": "#/$defs/digest" },
98
+ "compiled_plan_digest": { "$ref": "#/$defs/digest" },
99
+ "topology_digest": { "$ref": "#/$defs/digest" },
100
+ "base_sha": { "$ref": "#/$defs/gitSha" }
101
+ }
102
+ }
103
+ ]
104
+ },
105
+ "predecessor": {
106
+ "type": "object", "additionalProperties": false,
107
+ "required": ["plan_digest", "journal_head_digest", "plan_version"],
108
+ "properties": {
109
+ "plan_digest": { "$ref": "#/$defs/digest" },
110
+ "journal_head_digest": { "$ref": "#/$defs/digest" },
111
+ "plan_version": { "$ref": "#/$defs/identifier" }
112
+ }
113
+ },
114
+ "taskV3": {
115
+ "type": "object", "additionalProperties": false,
116
+ "required": [
117
+ "task_id", "title", "lane", "narrative_ref", "narrative_anchor", "compile_binding", "parent_task_id"
118
+ ],
119
+ "properties": {
120
+ "task_id": { "$ref": "#/$defs/identifier" },
121
+ "title": { "$ref": "#/$defs/nullableText" },
122
+ "lane": { "$ref": "#/$defs/identifier" },
123
+ "narrative_ref": { "$ref": "#/$defs/nullableRepoRef" },
124
+ "narrative_anchor": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/narrativeAnchor" }] },
125
+ "compile_binding": { "$ref": "#/$defs/compileBinding" },
126
+ "parent_task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] }
127
+ }
128
+ },
129
+ "taskV4": {
130
+ "type": "object", "additionalProperties": false,
131
+ "required": [
132
+ "task_id", "title", "lane", "narrative_ref", "narrative_anchor", "compile_binding",
133
+ "parent_task_id", "phase_id"
134
+ ],
135
+ "properties": {
136
+ "task_id": { "$ref": "#/$defs/identifier" },
137
+ "title": { "$ref": "#/$defs/nullableText" },
138
+ "lane": { "$ref": "#/$defs/identifier" },
139
+ "narrative_ref": { "$ref": "#/$defs/nullableRepoRef" },
140
+ "narrative_anchor": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/narrativeAnchor" }] },
141
+ "compile_binding": { "$ref": "#/$defs/compileBinding" },
142
+ "parent_task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
143
+ "phase_id": { "$ref": "#/$defs/identifier" }
144
+ }
145
+ },
146
+ "phase": {
147
+ "type": "object", "additionalProperties": false,
148
+ "required": ["phase_id", "title", "gate_policy", "predecessor_phase_ids", "required_evidence_slots"],
149
+ "properties": {
150
+ "phase_id": { "$ref": "#/$defs/identifier" },
151
+ "title": { "$ref": "#/$defs/nullableText" },
152
+ "gate_policy": { "$ref": "#/$defs/identifier" },
153
+ "predecessor_phase_ids": {
154
+ "type": "array", "items": { "$ref": "#/$defs/identifier" }, "uniqueItems": true
155
+ },
156
+ "required_evidence_slots": {
157
+ "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" }, "uniqueItems": true
158
+ }
159
+ }
160
+ },
161
+ "desiredPlanV3": {
162
+ "type": "object", "additionalProperties": false,
163
+ "required": [
164
+ "schema", "project_id", "plan_key", "plan_version", "predecessor_plan_digest",
165
+ "tasks", "hard_dependencies", "joins", "topology_digest", "plan_digest"
166
+ ],
167
+ "properties": {
168
+ "schema": { "const": "lattice.todo_plan.v3" },
169
+ "project_id": { "$ref": "#/$defs/identifier" },
170
+ "plan_key": { "$ref": "#/$defs/identifier" },
171
+ "plan_version": { "$ref": "#/$defs/identifier" },
172
+ "predecessor_plan_digest": { "$ref": "#/$defs/nullableDigest" },
173
+ "tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskV3" } },
174
+ "hard_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/edge" } },
175
+ "joins": { "type": "array", "maxItems": 128, "items": { "$ref": "#/$defs/join" } },
176
+ "topology_digest": { "$ref": "#/$defs/digest" },
177
+ "plan_digest": { "$ref": "#/$defs/digest" }
178
+ }
179
+ },
180
+ "desiredPlanV4orV5": {
181
+ "type": "object", "additionalProperties": false,
182
+ "required": [
183
+ "schema", "project_id", "plan_key", "plan_version", "predecessor_plan_digest",
184
+ "tasks", "hard_dependencies", "joins", "phases", "topology_digest", "plan_digest"
185
+ ],
186
+ "$comment": "schemaがv5の時だけphase_accept_dependenciesも必須keyに加わる(runtime-only cross-check、oneOfでは表現しない)。",
187
+ "properties": {
188
+ "schema": { "enum": ["lattice.todo_plan.v4", "lattice.todo_plan.v5"] },
189
+ "project_id": { "$ref": "#/$defs/identifier" },
190
+ "plan_key": { "$ref": "#/$defs/identifier" },
191
+ "plan_version": { "$ref": "#/$defs/identifier" },
192
+ "predecessor_plan_digest": { "$ref": "#/$defs/nullableDigest" },
193
+ "tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskV4" } },
194
+ "hard_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/edge" } },
195
+ "joins": { "type": "array", "maxItems": 128, "items": { "$ref": "#/$defs/join" } },
196
+ "phases": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/phase" } },
197
+ "phase_accept_dependencies": {
198
+ "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/phaseAcceptDependency" }
199
+ },
200
+ "topology_digest": { "$ref": "#/$defs/digest" },
201
+ "plan_digest": { "$ref": "#/$defs/digest" }
202
+ },
203
+ "if": { "properties": { "schema": { "const": "lattice.todo_plan.v5" } }, "required": ["schema"] },
204
+ "then": { "required": ["phase_accept_dependencies"] }
205
+ },
206
+ "taskMigrationEntry": {
207
+ "type": "object", "additionalProperties": false,
208
+ "required": ["from_task_id", "to_task_id", "state_policy"],
209
+ "properties": {
210
+ "from_task_id": { "$ref": "#/$defs/identifier" },
211
+ "to_task_id": { "oneOf": [{ "const": "removed" }, { "$ref": "#/$defs/identifier" }] },
212
+ "state_policy": { "enum": ["carry", "carry_reconciled_metadata", "reset_pending", "removed"] }
213
+ }
214
+ },
215
+ "phaseMigrationEntry": {
216
+ "type": "object", "additionalProperties": false,
217
+ "required": ["from_phase_id", "to_phase_id", "state_policy"],
218
+ "properties": {
219
+ "from_phase_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
220
+ "to_phase_id": { "oneOf": [{ "const": "removed" }, { "$ref": "#/$defs/identifier" }] },
221
+ "state_policy": { "enum": ["carry", "reset", "removed"] }
222
+ }
223
+ },
224
+ "sourceInventoryActiveEntry": {
225
+ "type": "object", "additionalProperties": false,
226
+ "required": ["task_id", "source_ref", "source_digest"],
227
+ "properties": {
228
+ "task_id": { "$ref": "#/$defs/identifier" },
229
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
230
+ "source_digest": { "$ref": "#/$defs/digest" }
231
+ }
232
+ },
233
+ "sourceInventoryTombstone": {
234
+ "type": "object", "additionalProperties": false,
235
+ "required": ["source_ref", "source_digest", "exclusion_reason"],
236
+ "properties": {
237
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
238
+ "source_digest": { "$ref": "#/$defs/digest" },
239
+ "exclusion_reason": { "$ref": "#/$defs/text" }
240
+ }
241
+ },
242
+ "sourceInventory": {
243
+ "type": "object", "additionalProperties": false,
244
+ "required": ["active", "excluded_tombstones"],
245
+ "properties": {
246
+ "active": {
247
+ "type": "array", "maxItems": 512, "items": { "$ref": "#/$defs/sourceInventoryActiveEntry" }
248
+ },
249
+ "excluded_tombstones": {
250
+ "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/sourceInventoryTombstone" }
251
+ }
252
+ }
253
+ },
254
+ "sourceCutoverOperation": {
255
+ "type": "object", "additionalProperties": false,
256
+ "required": ["task_id", "disposition", "source_ref", "source_digest", "live_replacement"],
257
+ "properties": {
258
+ "task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
259
+ "disposition": { "enum": ["active", "excluded"] },
260
+ "source_ref": { "$ref": "#/$defs/sourceLineRef" },
261
+ "source_digest": { "$ref": "#/$defs/digest" },
262
+ "live_replacement": { "type": "string", "minLength": 1, "maxLength": 4096 }
263
+ }
264
+ },
265
+ "sourceCutoverBatch": {
266
+ "type": "object", "additionalProperties": false,
267
+ "required": ["batch_id", "archive_ref", "operations", "batch_digest"],
268
+ "properties": {
269
+ "batch_id": { "$ref": "#/$defs/identifier" },
270
+ "archive_ref": { "allOf": [{ "$ref": "#/$defs/repoRef" }, { "pattern": "\\.md$" }] },
271
+ "operations": {
272
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/sourceCutoverOperation" }
273
+ },
274
+ "batch_digest": { "$ref": "#/$defs/digest" }
275
+ }
276
+ },
277
+ "todoRevisionMember": {
278
+ "description": "非phase planのrevision member。'lattice.todo_revision.v1'(source_cutover_batchなし)と'lattice.todo_revision.v2'(source_cutover_batchあり)のいずれか。",
279
+ "type": "object",
280
+ "if": { "properties": { "schema": { "const": "lattice.todo_revision.v2" } }, "required": ["schema"] },
281
+ "then": {
282
+ "additionalProperties": false,
283
+ "required": [
284
+ "schema", "project_id", "plan_key", "predecessor", "desired_plan", "task_migration",
285
+ "source_inventory", "reconciliation", "source_cutover_batch", "revision_digest"
286
+ ],
287
+ "properties": {
288
+ "schema": { "const": "lattice.todo_revision.v2" },
289
+ "project_id": { "$ref": "#/$defs/identifier" },
290
+ "plan_key": { "$ref": "#/$defs/identifier" },
291
+ "predecessor": { "$ref": "#/$defs/predecessor" },
292
+ "desired_plan": { "$ref": "#/$defs/desiredPlanV3" },
293
+ "task_migration": {
294
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskMigrationEntry" }
295
+ },
296
+ "source_inventory": { "$ref": "#/$defs/sourceInventory" },
297
+ "reconciliation": {
298
+ "type": "object", "additionalProperties": false,
299
+ "required": ["predecessor_reconciliation_digest", "source_inventory_digest", "reconciliation_digest"],
300
+ "properties": {
301
+ "predecessor_reconciliation_digest": { "$ref": "#/$defs/digest" },
302
+ "source_inventory_digest": { "$ref": "#/$defs/digest" },
303
+ "reconciliation_digest": { "$ref": "#/$defs/digest" }
304
+ }
305
+ },
306
+ "source_cutover_batch": { "$ref": "#/$defs/sourceCutoverBatch" },
307
+ "revision_digest": { "$ref": "#/$defs/digest" }
308
+ }
309
+ },
310
+ "else": {
311
+ "additionalProperties": false,
312
+ "required": [
313
+ "schema", "project_id", "plan_key", "predecessor", "desired_plan", "task_migration",
314
+ "source_inventory", "reconciliation", "revision_digest"
315
+ ],
316
+ "properties": {
317
+ "schema": { "const": "lattice.todo_revision.v1" },
318
+ "project_id": { "$ref": "#/$defs/identifier" },
319
+ "plan_key": { "$ref": "#/$defs/identifier" },
320
+ "predecessor": { "$ref": "#/$defs/predecessor" },
321
+ "desired_plan": { "$ref": "#/$defs/desiredPlanV3" },
322
+ "task_migration": {
323
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskMigrationEntry" }
324
+ },
325
+ "source_inventory": { "$ref": "#/$defs/sourceInventory" },
326
+ "reconciliation": {
327
+ "type": "object", "additionalProperties": false,
328
+ "required": ["predecessor_reconciliation_digest", "source_inventory_digest", "reconciliation_digest"],
329
+ "properties": {
330
+ "predecessor_reconciliation_digest": { "$ref": "#/$defs/digest" },
331
+ "source_inventory_digest": { "$ref": "#/$defs/digest" },
332
+ "reconciliation_digest": { "$ref": "#/$defs/digest" }
333
+ }
334
+ },
335
+ "revision_digest": { "$ref": "#/$defs/digest" }
336
+ }
337
+ }
338
+ },
339
+ "phaseTodoRevisionMember": {
340
+ "description": "phase-audited planのrevision member。'lattice.phase_todo_revision.v1'(desired_planはv4)と'v2'(desired_planはv5)のいずれかだけを受理する——'v3'(runtime_task_migration・source_cutover_batch付き)はrevise-set memberとしては受理されない。",
341
+ "type": "object", "additionalProperties": false,
342
+ "required": [
343
+ "schema", "project_id", "plan_key", "predecessor", "desired_plan",
344
+ "task_migration", "phase_migration", "revision_digest"
345
+ ],
346
+ "properties": {
347
+ "schema": { "enum": ["lattice.phase_todo_revision.v1", "lattice.phase_todo_revision.v2"] },
348
+ "project_id": { "$ref": "#/$defs/identifier" },
349
+ "plan_key": { "$ref": "#/$defs/identifier" },
350
+ "predecessor": { "$ref": "#/$defs/predecessor" },
351
+ "desired_plan": { "$ref": "#/$defs/desiredPlanV4orV5" },
352
+ "task_migration": {
353
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskMigrationEntry" }
354
+ },
355
+ "phase_migration": {
356
+ "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/phaseMigrationEntry" }
357
+ },
358
+ "revision_digest": { "$ref": "#/$defs/digest" }
359
+ },
360
+ "$comment": "schemaが'lattice.phase_todo_revision.v1'ならdesired_plan.schemaは'lattice.todo_plan.v4'、'v2'なら'lattice.todo_plan.v5'(runtime cross-check)。"
361
+ }
362
+ }
363
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quolu/lattice",
3
- "version": "0.36.0",
3
+ "version": "0.36.1",
4
4
  "description": "Schedulability compiler for multi-agent development: observe real code boundaries, refactor the conflicting seam, recompile the plan for parallel execution",
5
5
  "author": {
6
6
  "name": "Quo / クオ at kitepon.dev",
@@ -27,6 +27,10 @@
27
27
  "docs/schemas/lattice.plan_create_input.v1.schema.json",
28
28
  "docs/schemas/lattice.plan_create_input.v2.schema.json",
29
29
  "docs/schemas/lattice.plan_create_input.v3.schema.json",
30
+ "docs/schemas/lattice.todo_revision.v2.schema.json",
31
+ "docs/schemas/lattice.todo_revision_set.v3.schema.json",
32
+ "docs/schemas/lattice.phase_todo_revision.v3.schema.json",
33
+ "docs/schemas/lattice.todo_extraction.v2.schema.json",
30
34
  "docs/schemas/lattice.run_request.v1.schema.json",
31
35
  "docs/schemas/lattice.executor_packet.v1.schema.json",
32
36
  "docs/schemas/lattice.executor_receipt.v1.schema.json",