@quolu/lattice 0.38.1 → 0.39.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.
- package/README.ja.md +22 -16
- package/README.md +11 -7
- package/bin/lattice-mcp.mjs +0 -0
- package/bin/lattice.mjs +1 -1
- package/docs/schemas/lattice.phase_todo_revision.v3.schema.json +49 -1
- package/docs/schemas/lattice.plan_create_input.v4.schema.json +85 -0
- package/docs/schemas/lattice.todo_extraction.v3.schema.json +146 -0
- package/docs/schemas/lattice.todo_revision.v2.schema.json +41 -1
- package/package.json +3 -1
- package/src/cli-help.mjs +7 -7
- package/src/project-cli.mjs +32 -15
- package/src/todo-cli.mjs +360 -218
- package/src/todo-contracts.mjs +46 -8
- package/src/todo-dashboard-registry.mjs +17 -3
- package/src/todo-gantt-html-independence.mjs +14 -3
- package/src/todo-gantt-html-shared.mjs +5 -2
- package/src/todo-gantt-layout.mjs +1 -1
- package/src/todo-gantt-scope.mjs +1 -1
- package/src/todo-migration.mjs +46 -9
- package/src/todo-revision.mjs +10 -8
- package/src/todo-status.mjs +3 -3
- package/src/todo-store.mjs +74 -31
package/README.ja.md
CHANGED
|
@@ -43,20 +43,26 @@ planを再コンパイルします。共有面が共有でなくなるので、
|
|
|
43
43
|
|
|
44
44
|
人が手で切ったのではありません。**工程を並列化するために製品が切りました。**
|
|
45
45
|
|
|
46
|
-
###
|
|
46
|
+
### 設計メモと作業記憶はToDoと一緒に渡る
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
新しいToDoは、実装方針・調査結果・採用/棄却理由・注意・未解決事項をMarkdownで書いた
|
|
49
|
+
`design_memo`を必ず持ちます。空欄やファイル参照だけでは登録できません。本当に何も考えていない場合だけ、
|
|
50
|
+
正確なsentinel `NO_PLAN`を本文にします。Latticeはauthoring時に次の問いを返し、空欄のまま通しません。
|
|
51
|
+
|
|
52
|
+
> If you have not thought through this ToDo, write exactly `NO_PLAN` in its design memo.
|
|
53
|
+
|
|
54
|
+
通常の`lattice todo show`と、成功するすべての`lattice todo start`は、この初期設計メモを自動で返します。
|
|
55
|
+
作業開始後に増えた方針、棄却案、調査結果、注意、未解決事項は、別のappend-only note chainへ追記できます。
|
|
56
|
+
同じ通常読取は元version/元task、訂正状態、note chain head、overflow、全履歴コマンドを含む最新の
|
|
57
|
+
bounded `note_context`も自動で返します。次のAIが別のnote読取コマンドを知っている必要はありません。
|
|
52
58
|
|
|
53
59
|
```bash
|
|
54
60
|
lattice todo note --plan <key> --task <id> --message "既存parserを使い、fallbackは追加しない"
|
|
55
61
|
lattice todo show --plan <key> --task <id> --json
|
|
56
62
|
```
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
ローカル/公開の動的工程表は、選択したToDoの右ペインへ初期設計メモを表示します。追記note本文は
|
|
65
|
+
ローカルだけに表示し、公開dashboardには含めません。project別HTMLの生成や再生成は不要です。
|
|
60
66
|
|
|
61
67
|
### 変換の受入五条件
|
|
62
68
|
|
|
@@ -128,11 +134,11 @@ lattice status --json
|
|
|
128
134
|
|
|
129
135
|
`state`は`uninitialized | ready | active_run | invalid`のいずれかです。`uninitialized`は
|
|
130
136
|
正常な未初期化状態で、`next_action`が正規の初期authoring入口を返します。初回planは
|
|
131
|
-
新規planはPhase監査とToDo scheduling
|
|
137
|
+
新規planはPhase監査とToDo schedulingを分離し、全ToDoに設計メモを持つ`lattice.plan_create_input.v4`のcanonical
|
|
132
138
|
JSON+LFを用意し、次で作成します。既存v2/v4は互換契約として維持されます。
|
|
133
139
|
|
|
134
140
|
```bash
|
|
135
|
-
lattice plan create --schema-version
|
|
141
|
+
lattice plan create --schema-version 4 --json
|
|
136
142
|
```
|
|
137
143
|
|
|
138
144
|
```bash
|
|
@@ -166,8 +172,8 @@ digestは手で計算しません。binary・config・capabilities・自己diges
|
|
|
166
172
|
作業ツリーをcleanにすると同じrequestがそのまま通ります。
|
|
167
173
|
|
|
168
174
|
TODO工程storeの読取は`lattice todo status`、`compile_binding`付きTaskの投影は
|
|
169
|
-
`lattice todo bindings`、検証は`lattice todo verify
|
|
170
|
-
|
|
175
|
+
`lattice todo bindings`、検証は`lattice todo verify`、表示は動的dashboardを使います。
|
|
176
|
+
個別HTMLの生成や再生成は不要です。topology/source reconciliationは
|
|
171
177
|
`lattice todo revise --plan <key> --input <canonical-revision.json>`、Phase付きplanは
|
|
172
178
|
`lattice todo revise-phase --plan <key> --input <canonical-phase-revision.json>`でsuccessor発行します。
|
|
173
179
|
cross-plan topologyを同時に切り替える場合は
|
|
@@ -250,7 +256,7 @@ lattice todo phase baseline --reason <text> --except <監査したいplan_key>
|
|
|
250
256
|
error detailの`violation_path`へ載ります(配列のソート違反は`/tasks/1`のようにindexまで名指しします)。
|
|
251
257
|
|
|
252
258
|
```bash
|
|
253
|
-
lattice plan create --schema --json # 既定は最新
|
|
259
|
+
lattice plan create --schema --json # 既定は最新v4
|
|
254
260
|
lattice todo revise-phase --schema --json
|
|
255
261
|
lattice plan show <plan_key> --json # planのtask・依存・phase・状態を1コマンドで読む
|
|
256
262
|
```Phase状態は
|
|
@@ -271,8 +277,8 @@ LANや外部reverse proxyから閲覧するoptional bridgeは既定で無効で
|
|
|
271
277
|
工程図の既定表示は、後続に作業中・未着手が残っていない完了工程を図から除きます。まとめnodeも置かないため、
|
|
272
278
|
完走したplanは図の場所を取りません。除いた工程は凡例の件数、右ペインの「全工程」一覧、各工程の詳細から
|
|
273
279
|
辿れ、詳細の前提・後続は除外前の依存関係を示します。総数・進捗・最長依存鎖は除外前の全工程で数えます。
|
|
274
|
-
|
|
275
|
-
|
|
280
|
+
凡例の件数バッジを押すと全工程を描いた図へ切り替わります。表示規約は
|
|
281
|
+
[ADR 0066](docs/adr/0066-gantt-live-scope-drops-finished-work.md)が正です。
|
|
276
282
|
|
|
277
283
|
右ペインは概要・選択工程・全工程の3面で、いずれもToDo storeを表示します(元plan Markdown本文は
|
|
278
284
|
再表示しません。元文書へは各工程の詳細が持つ行対応から辿ります)。全工程一覧は動いているplanを
|
|
@@ -280,8 +286,8 @@ LANや外部reverse proxyから閲覧するoptional bridgeは既定で無効で
|
|
|
280
286
|
決着済みPhaseと図から外した工程は既定で畳み、開けば読めます。規約は
|
|
281
287
|
[ADR 0067](docs/adr/0067-right-pane-shows-the-store-and-orders-by-activity.md)が正です。
|
|
282
288
|
|
|
283
|
-
|
|
284
|
-
|
|
289
|
+
`lattice todo gantt`と`lattice todo gantt status`による静的工程表は廃止済みで、呼ぶと
|
|
290
|
+
`STATIC_GANTT_RETIRED`が動的dashboardを案内します。
|
|
285
291
|
dashboard daemonは起動時に読み込んだ版数をhealthで名乗り、installされた版と食い違えば`lattice status`の
|
|
286
292
|
たびに新版daemonへ置き換わります。publishしただけで配信面が古いまま残ることはありません。
|
|
287
293
|
入れ替えは新daemonが登録済み全projectのstoreを読み終えるまで待つため、`lattice status`の応答が
|
package/README.md
CHANGED
|
@@ -60,19 +60,23 @@ Nobody hand-refactored that file. The product cut it so the work could paralleli
|
|
|
60
60
|
|
|
61
61
|
### Task memory travels with the task
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
Every newly authored ToDo carries an initial Markdown design memo. Empty text and a file reference are
|
|
64
|
+
not accepted; an agent with no plan must explicitly write `NO_PLAN`. Lattice asks:
|
|
65
|
+
“あなたがこのToDoに対して、何も考えていないならば、設計メモに `NO_PLAN` と書いてください”.
|
|
66
|
+
A normal `lattice todo show` and every successful `lattice todo start` return that memo automatically.
|
|
67
|
+
|
|
68
|
+
After work begins, an agent can append decisions, rejected approaches, findings, cautions, and open
|
|
69
|
+
questions. These remain a separate, append-only `note_context`, with origin, correction state, chain
|
|
70
|
+
head, overflow, and the full-history command.
|
|
68
71
|
|
|
69
72
|
```bash
|
|
70
73
|
lattice todo note --plan <key> --task <id> --message "Use the existing parser; do not add a fallback"
|
|
71
74
|
lattice todo show --plan <key> --task <id> --json
|
|
72
75
|
```
|
|
73
76
|
|
|
74
|
-
The
|
|
75
|
-
|
|
77
|
+
The initial design memo appears in the selected ToDo's detail pane on both local and public dynamic
|
|
78
|
+
dashboards. Public rendering excludes append-only note bodies by contract. Static per-project HTML is
|
|
79
|
+
not generated; `lattice todo gantt serve` and the shared dashboard read the store dynamically.
|
|
76
80
|
|
|
77
81
|
### The five acceptance conditions
|
|
78
82
|
|
package/bin/lattice-mcp.mjs
CHANGED
|
File without changes
|
package/bin/lattice.mjs
CHANGED
|
@@ -50,7 +50,7 @@ if (help !== null) {
|
|
|
50
50
|
process.exitCode = projectCliFailure(process.stderr, error);
|
|
51
51
|
}
|
|
52
52
|
} else if (args.length === 5 && args[0] === 'plan' && args[1] === 'create'
|
|
53
|
-
&& args[2] === '--schema-version' && ['1', '2', '3'].includes(args[3]) && args[4] === '--json') {
|
|
53
|
+
&& args[2] === '--schema-version' && ['1', '2', '3', '4'].includes(args[3]) && args[4] === '--json') {
|
|
54
54
|
const { projectCliFailure, runPlanCreateSchema } = await import('../src/project-cli.mjs');
|
|
55
55
|
try {
|
|
56
56
|
process.exitCode = await runPlanCreateSchema({ stdout: process.stdout, version: Number(args[3]) });
|
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
"project_id": { "$ref": "#/$defs/identifier" },
|
|
17
17
|
"plan_key": { "$ref": "#/$defs/identifier" },
|
|
18
18
|
"predecessor": { "$ref": "#/$defs/predecessor" },
|
|
19
|
-
"desired_plan": { "
|
|
19
|
+
"desired_plan": { "oneOf": [
|
|
20
|
+
{ "$ref": "#/$defs/desiredPlanV5" },
|
|
21
|
+
{ "$ref": "#/$defs/desiredPlanV7" }
|
|
22
|
+
] },
|
|
20
23
|
"runtime_task_migration": { "$ref": "#/$defs/runtimeTaskMigration" },
|
|
21
24
|
"task_migration": {
|
|
22
25
|
"type": "array", "minItems": 1, "maxItems": 512,
|
|
@@ -156,6 +159,27 @@
|
|
|
156
159
|
"phase_id": { "$ref": "#/$defs/identifier" }
|
|
157
160
|
}
|
|
158
161
|
},
|
|
162
|
+
"taskV6": {
|
|
163
|
+
"type": "object", "additionalProperties": false,
|
|
164
|
+
"required": [
|
|
165
|
+
"task_id", "title", "lane", "design_memo", "narrative_ref", "narrative_anchor",
|
|
166
|
+
"compile_binding", "parent_task_id", "phase_id"
|
|
167
|
+
],
|
|
168
|
+
"properties": {
|
|
169
|
+
"task_id": { "$ref": "#/$defs/identifier" },
|
|
170
|
+
"title": { "$ref": "#/$defs/nullableText" },
|
|
171
|
+
"lane": { "$ref": "#/$defs/identifier" },
|
|
172
|
+
"design_memo": {
|
|
173
|
+
"$ref": "#/$defs/text",
|
|
174
|
+
"description": "Markdown design memo. あなたがこのToDoに対して、何も考えていないならば、設計メモに `NO_PLAN` と書いてください"
|
|
175
|
+
},
|
|
176
|
+
"narrative_ref": { "$ref": "#/$defs/nullableRepoRef" },
|
|
177
|
+
"narrative_anchor": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/narrativeAnchor" }] },
|
|
178
|
+
"compile_binding": { "$ref": "#/$defs/compileBinding" },
|
|
179
|
+
"parent_task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
|
|
180
|
+
"phase_id": { "$ref": "#/$defs/identifier" }
|
|
181
|
+
}
|
|
182
|
+
},
|
|
159
183
|
"phase": {
|
|
160
184
|
"type": "object", "additionalProperties": false,
|
|
161
185
|
"required": ["phase_id", "title", "gate_policy", "predecessor_phase_ids", "required_evidence_slots"],
|
|
@@ -195,6 +219,30 @@
|
|
|
195
219
|
"plan_digest": { "$ref": "#/$defs/digest" }
|
|
196
220
|
}
|
|
197
221
|
},
|
|
222
|
+
"desiredPlanV7": {
|
|
223
|
+
"type": "object", "additionalProperties": false,
|
|
224
|
+
"required": [
|
|
225
|
+
"schema", "project_id", "plan_key", "plan_version", "predecessor_plan_digest",
|
|
226
|
+
"tasks", "hard_dependencies", "joins", "phases", "phase_accept_dependencies",
|
|
227
|
+
"topology_digest", "plan_digest"
|
|
228
|
+
],
|
|
229
|
+
"properties": {
|
|
230
|
+
"schema": { "const": "lattice.todo_plan.v7" },
|
|
231
|
+
"project_id": { "$ref": "#/$defs/identifier" },
|
|
232
|
+
"plan_key": { "$ref": "#/$defs/identifier" },
|
|
233
|
+
"plan_version": { "$ref": "#/$defs/identifier" },
|
|
234
|
+
"predecessor_plan_digest": { "$ref": "#/$defs/nullableDigest" },
|
|
235
|
+
"tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskV6" } },
|
|
236
|
+
"hard_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/edge" } },
|
|
237
|
+
"joins": { "type": "array", "maxItems": 128, "items": { "$ref": "#/$defs/join" } },
|
|
238
|
+
"phases": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/phase" } },
|
|
239
|
+
"phase_accept_dependencies": {
|
|
240
|
+
"type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/phaseAcceptDependency" }
|
|
241
|
+
},
|
|
242
|
+
"topology_digest": { "$ref": "#/$defs/digest" },
|
|
243
|
+
"plan_digest": { "$ref": "#/$defs/digest" }
|
|
244
|
+
}
|
|
245
|
+
},
|
|
198
246
|
"taskMigrationEntry": {
|
|
199
247
|
"type": "object", "additionalProperties": false,
|
|
200
248
|
"required": ["from_task_id", "to_task_id", "state_policy"],
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/kitepon-rgb/Lattice/blob/main/docs/schemas/lattice.plan_create_input.v4.schema.json",
|
|
4
|
+
"title": "lattice.plan_create_input.v4",
|
|
5
|
+
"description": "Canonical initial authoring input for a phase-audited plan. Every task requires a design memo. あなたがこのToDoに対して、何も考えていないならば、設計メモに `NO_PLAN` と書いてください",
|
|
6
|
+
"$comment": "Runtime validation additionally enforces canonical JSON+LF bytes, sorted identifiers and edges, unique ids, combined task/phase acyclicity, byte bounds, non-empty design_memo, and input_digest.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": ["schema", "project_id", "plan_key", "plan_version", "actor", "recorded_at", "tasks", "phases", "hard_dependencies", "joins", "phase_accept_dependencies", "input_digest"],
|
|
10
|
+
"properties": {
|
|
11
|
+
"schema": { "const": "lattice.plan_create_input.v4" },
|
|
12
|
+
"project_id": { "$ref": "#/$defs/identifier" },
|
|
13
|
+
"plan_key": { "$ref": "#/$defs/identifier" },
|
|
14
|
+
"plan_version": { "$ref": "#/$defs/identifier" },
|
|
15
|
+
"actor": { "$ref": "#/$defs/actor" },
|
|
16
|
+
"recorded_at": { "$ref": "#/$defs/strictTimestamp" },
|
|
17
|
+
"tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/task" } },
|
|
18
|
+
"phases": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/phase" } },
|
|
19
|
+
"hard_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/edge" } },
|
|
20
|
+
"joins": { "type": "array", "maxItems": 128, "items": { "$ref": "#/$defs/join" } },
|
|
21
|
+
"phase_accept_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/phaseAcceptDependency" } },
|
|
22
|
+
"input_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
|
+
"repoRef": { "type": "string", "minLength": 1, "maxLength": 1024 },
|
|
28
|
+
"strictTimestamp": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$" },
|
|
29
|
+
"nullableRepoRef": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/repoRef" }] },
|
|
30
|
+
"nullableIdentifier": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
|
|
31
|
+
"actor": {
|
|
32
|
+
"type": "object", "additionalProperties": false, "required": ["host", "session", "agent"],
|
|
33
|
+
"properties": { "host": { "$ref": "#/$defs/identifier" }, "session": { "$ref": "#/$defs/identifier" }, "agent": { "$ref": "#/$defs/identifier" } }
|
|
34
|
+
},
|
|
35
|
+
"task": {
|
|
36
|
+
"type": "object", "additionalProperties": false,
|
|
37
|
+
"required": ["task_id", "title", "lane", "design_memo", "narrative_ref", "narrative_anchor", "compile_binding", "parent_task_id", "phase_id"],
|
|
38
|
+
"properties": {
|
|
39
|
+
"task_id": { "$ref": "#/$defs/identifier" },
|
|
40
|
+
"title": { "oneOf": [{ "type": "null" }, { "type": "string", "minLength": 1, "maxLength": 16384 }] },
|
|
41
|
+
"lane": { "$ref": "#/$defs/identifier" },
|
|
42
|
+
"design_memo": {
|
|
43
|
+
"type": "string", "minLength": 1, "maxLength": 16384,
|
|
44
|
+
"description": "Markdown design memo. あなたがこのToDoに対して、何も考えていないならば、設計メモに `NO_PLAN` と書いてください"
|
|
45
|
+
},
|
|
46
|
+
"narrative_ref": { "$ref": "#/$defs/nullableRepoRef" },
|
|
47
|
+
"narrative_anchor": { "type": "null" },
|
|
48
|
+
"compile_binding": { "type": "null" },
|
|
49
|
+
"parent_task_id": { "$ref": "#/$defs/nullableIdentifier" },
|
|
50
|
+
"phase_id": { "$ref": "#/$defs/identifier" }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"phase": {
|
|
54
|
+
"type": "object", "additionalProperties": false,
|
|
55
|
+
"required": ["phase_id", "title", "gate_policy", "predecessor_phase_ids", "required_evidence_slots"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"phase_id": { "$ref": "#/$defs/identifier" },
|
|
58
|
+
"title": { "oneOf": [{ "type": "null" }, { "type": "string", "minLength": 1, "maxLength": 16384 }] },
|
|
59
|
+
"gate_policy": { "$ref": "#/$defs/identifier" },
|
|
60
|
+
"predecessor_phase_ids": { "type": "array", "items": { "$ref": "#/$defs/identifier" }, "uniqueItems": true },
|
|
61
|
+
"required_evidence_slots": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" }, "uniqueItems": true }
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"nodeRef": {
|
|
65
|
+
"type": "object", "additionalProperties": false, "required": ["project_id", "plan_key", "task_id"],
|
|
66
|
+
"properties": { "project_id": { "$ref": "#/$defs/identifier" }, "plan_key": { "$ref": "#/$defs/identifier" }, "task_id": { "$ref": "#/$defs/identifier" }, "expected_topology_digest": { "$ref": "#/$defs/digest" } }
|
|
67
|
+
},
|
|
68
|
+
"phaseRef": {
|
|
69
|
+
"type": "object", "additionalProperties": false, "required": ["project_id", "plan_key", "phase_id"],
|
|
70
|
+
"properties": { "project_id": { "$ref": "#/$defs/identifier" }, "plan_key": { "$ref": "#/$defs/identifier" }, "phase_id": { "$ref": "#/$defs/identifier" }, "expected_topology_digest": { "$ref": "#/$defs/digest" } }
|
|
71
|
+
},
|
|
72
|
+
"edge": {
|
|
73
|
+
"type": "object", "additionalProperties": false, "required": ["from", "to"],
|
|
74
|
+
"properties": { "from": { "$ref": "#/$defs/nodeRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
|
|
75
|
+
},
|
|
76
|
+
"phaseAcceptDependency": {
|
|
77
|
+
"type": "object", "additionalProperties": false, "required": ["from", "to"],
|
|
78
|
+
"properties": { "from": { "$ref": "#/$defs/phaseRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
|
|
79
|
+
},
|
|
80
|
+
"join": {
|
|
81
|
+
"type": "object", "additionalProperties": false, "required": ["id", "after", "before"],
|
|
82
|
+
"properties": { "id": { "$ref": "#/$defs/identifier" }, "after": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/nodeRef" } }, "before": { "$ref": "#/$defs/nodeRef" } }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
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.v3.schema.json",
|
|
4
|
+
"title": "lattice.todo_extraction.v3",
|
|
5
|
+
"description": "AI-authored ToDo migration artifact. Every task carries a non-blank Markdown design_memo. If no plan exists, write NO_PLAN explicitly.",
|
|
6
|
+
"$comment": "あなたがこのToDoに対して、何も考えていないならば、設計メモに `NO_PLAN` と書いてください。Runtime validation also enforces UTF-8 byte bounds, exact keys, strict sort order, referential integrity, disposition consistency, and the canonical self-digest.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"required": [
|
|
10
|
+
"schema", "project_id", "plan_key", "plan_version", "actor", "recorded_at",
|
|
11
|
+
"tasks", "hard_dependencies", "joins", "extraction_digest"
|
|
12
|
+
],
|
|
13
|
+
"properties": {
|
|
14
|
+
"schema": { "const": "lattice.todo_extraction.v3" },
|
|
15
|
+
"project_id": { "$ref": "#/$defs/identifier" },
|
|
16
|
+
"plan_key": { "$ref": "#/$defs/identifier" },
|
|
17
|
+
"plan_version": { "$ref": "#/$defs/identifier" },
|
|
18
|
+
"actor": { "$ref": "#/$defs/actor" },
|
|
19
|
+
"recorded_at": { "$ref": "#/$defs/strictTimestamp" },
|
|
20
|
+
"tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/task" } },
|
|
21
|
+
"hard_dependencies": {
|
|
22
|
+
"type": "array", "maxItems": 2048,
|
|
23
|
+
"items": {
|
|
24
|
+
"type": "object", "additionalProperties": false, "required": ["from", "to"],
|
|
25
|
+
"properties": { "from": { "$ref": "#/$defs/nodeRef" }, "to": { "$ref": "#/$defs/nodeRef" } }
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"joins": {
|
|
29
|
+
"type": "array", "maxItems": 128,
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "object", "additionalProperties": false, "required": ["id", "after", "before"],
|
|
32
|
+
"properties": {
|
|
33
|
+
"id": { "$ref": "#/$defs/identifier" },
|
|
34
|
+
"after": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/nodeRef" } },
|
|
35
|
+
"before": { "$ref": "#/$defs/nodeRef" }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"extraction_digest": { "$ref": "#/$defs/digest" }
|
|
40
|
+
},
|
|
41
|
+
"$defs": {
|
|
42
|
+
"identifier": { "type": "string", "pattern": "^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$" },
|
|
43
|
+
"digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
|
44
|
+
"repoRef": {
|
|
45
|
+
"type": "string", "minLength": 1, "maxLength": 1024,
|
|
46
|
+
"pattern": "^(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\\\)(?!.*[\\u0000-\\u001f\\u007f])[^/]+(?:/[^/]+)*$"
|
|
47
|
+
},
|
|
48
|
+
"text": { "type": "string", "minLength": 1, "maxLength": 16384 },
|
|
49
|
+
"designMemo": {
|
|
50
|
+
"type": "string", "minLength": 1, "maxLength": 262144, "pattern": "\\S",
|
|
51
|
+
"description": "Markdown design memo. Use the literal NO_PLAN only when no plan exists."
|
|
52
|
+
},
|
|
53
|
+
"nullableText": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/text" }] },
|
|
54
|
+
"strictTimestamp": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$"
|
|
57
|
+
},
|
|
58
|
+
"actor": {
|
|
59
|
+
"type": "object", "additionalProperties": false, "required": ["host", "session", "agent"],
|
|
60
|
+
"properties": {
|
|
61
|
+
"host": { "$ref": "#/$defs/identifier" },
|
|
62
|
+
"session": { "$ref": "#/$defs/identifier" },
|
|
63
|
+
"agent": { "$ref": "#/$defs/identifier" }
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"nodeRef": {
|
|
67
|
+
"type": "object", "additionalProperties": false, "required": ["project_id", "plan_key", "task_id"],
|
|
68
|
+
"properties": {
|
|
69
|
+
"project_id": { "$ref": "#/$defs/identifier" },
|
|
70
|
+
"plan_key": { "$ref": "#/$defs/identifier" },
|
|
71
|
+
"task_id": { "$ref": "#/$defs/identifier" },
|
|
72
|
+
"expected_topology_digest": { "$ref": "#/$defs/digest" }
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"sourceLocation": {
|
|
76
|
+
"type": "object", "additionalProperties": false,
|
|
77
|
+
"required": ["origin_plan_ref", "origin_line", "source_commit", "heading_path", "markdown_depth", "parent_task_id", "checkbox_state"],
|
|
78
|
+
"properties": {
|
|
79
|
+
"origin_plan_ref": { "$ref": "#/$defs/repoRef" },
|
|
80
|
+
"origin_line": { "type": "integer", "minimum": 1 },
|
|
81
|
+
"source_commit": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
|
|
82
|
+
"heading_path": { "type": "array", "maxItems": 32, "items": { "type": "string", "minLength": 1, "maxLength": 1024 } },
|
|
83
|
+
"markdown_depth": { "type": "integer", "minimum": 0, "maximum": 64 },
|
|
84
|
+
"parent_task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] },
|
|
85
|
+
"checkbox_state": { "enum": ["checked", "unchecked", "absent", "ambiguous"] }
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"migrationContext": {
|
|
89
|
+
"type": "object", "additionalProperties": false,
|
|
90
|
+
"required": ["external_canonical_ref", "carry_over_ref", "h_required", "condition", "evidence_refs", "notes"],
|
|
91
|
+
"properties": {
|
|
92
|
+
"external_canonical_ref": { "$ref": "#/$defs/nullableText" },
|
|
93
|
+
"carry_over_ref": { "$ref": "#/$defs/nullableText" },
|
|
94
|
+
"h_required": { "type": "boolean" },
|
|
95
|
+
"condition": { "$ref": "#/$defs/nullableText" },
|
|
96
|
+
"evidence_refs": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1, "maxLength": 4096 } },
|
|
97
|
+
"notes": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1, "maxLength": 4096 } }
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"historicalStart": {
|
|
101
|
+
"type": "object", "additionalProperties": false, "required": ["start_mode", "status", "started_at"],
|
|
102
|
+
"properties": {
|
|
103
|
+
"start_mode": { "const": "historical_import" }, "status": { "const": "in-progress" },
|
|
104
|
+
"started_at": { "oneOf": [{ "const": "unknown_requires_evidence" }, { "$ref": "#/$defs/strictTimestamp" }] }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"historicalCompletion": {
|
|
108
|
+
"type": "object", "additionalProperties": false, "required": ["done_mode", "completed_at"],
|
|
109
|
+
"properties": {
|
|
110
|
+
"done_mode": { "const": "historical_import" },
|
|
111
|
+
"completed_at": { "oneOf": [{ "const": "unknown_requires_evidence" }, { "$ref": "#/$defs/strictTimestamp" }] }
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"task": {
|
|
115
|
+
"type": "object", "additionalProperties": false,
|
|
116
|
+
"required": [
|
|
117
|
+
"task_id", "title", "lane", "design_memo", "narrative_ref", "compile_binding",
|
|
118
|
+
"disposition", "start", "completion", "source", "migration_context"
|
|
119
|
+
],
|
|
120
|
+
"properties": {
|
|
121
|
+
"task_id": { "$ref": "#/$defs/identifier" },
|
|
122
|
+
"title": { "$ref": "#/$defs/text" },
|
|
123
|
+
"lane": { "$ref": "#/$defs/identifier" },
|
|
124
|
+
"design_memo": { "$ref": "#/$defs/designMemo" },
|
|
125
|
+
"narrative_ref": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/repoRef" }] },
|
|
126
|
+
"compile_binding": { "type": "null" },
|
|
127
|
+
"disposition": { "enum": ["register_pending", "register_in_progress", "register_done", "exclude_superseded", "exclude_compatibility_record", "unknown_requires_evidence"] },
|
|
128
|
+
"start": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/historicalStart" }] },
|
|
129
|
+
"completion": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/historicalCompletion" }] },
|
|
130
|
+
"source": { "$ref": "#/$defs/sourceLocation" },
|
|
131
|
+
"migration_context": { "$ref": "#/$defs/migrationContext" }
|
|
132
|
+
},
|
|
133
|
+
"allOf": [
|
|
134
|
+
{
|
|
135
|
+
"if": { "properties": { "disposition": { "const": "register_in_progress" } }, "required": ["disposition"] },
|
|
136
|
+
"then": { "properties": { "start": { "$ref": "#/$defs/historicalStart" }, "completion": { "type": "null" } } },
|
|
137
|
+
"else": {
|
|
138
|
+
"if": { "properties": { "disposition": { "const": "register_done" } }, "required": ["disposition"] },
|
|
139
|
+
"then": { "properties": { "start": { "type": "null" }, "completion": { "$ref": "#/$defs/historicalCompletion" } } },
|
|
140
|
+
"else": { "properties": { "start": { "type": "null" }, "completion": { "type": "null" } } }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -15,7 +15,12 @@
|
|
|
15
15
|
"project_id": { "$ref": "#/$defs/identifier" },
|
|
16
16
|
"plan_key": { "$ref": "#/$defs/identifier" },
|
|
17
17
|
"predecessor": { "$ref": "#/$defs/predecessor" },
|
|
18
|
-
"desired_plan": {
|
|
18
|
+
"desired_plan": {
|
|
19
|
+
"oneOf": [
|
|
20
|
+
{ "$ref": "#/$defs/desiredPlanV3" },
|
|
21
|
+
{ "$ref": "#/$defs/desiredPlanV6" }
|
|
22
|
+
]
|
|
23
|
+
},
|
|
19
24
|
"task_migration": {
|
|
20
25
|
"type": "array", "minItems": 1, "maxItems": 512,
|
|
21
26
|
"items": { "$ref": "#/$defs/taskMigrationEntry" }
|
|
@@ -144,6 +149,41 @@
|
|
|
144
149
|
"plan_digest": { "$ref": "#/$defs/digest" }
|
|
145
150
|
}
|
|
146
151
|
},
|
|
152
|
+
"taskV6": {
|
|
153
|
+
"type": "object", "additionalProperties": false,
|
|
154
|
+
"required": [
|
|
155
|
+
"task_id", "title", "lane", "design_memo", "narrative_ref", "narrative_anchor", "compile_binding", "parent_task_id"
|
|
156
|
+
],
|
|
157
|
+
"properties": {
|
|
158
|
+
"task_id": { "$ref": "#/$defs/identifier" },
|
|
159
|
+
"title": { "$ref": "#/$defs/nullableText" },
|
|
160
|
+
"lane": { "$ref": "#/$defs/identifier" },
|
|
161
|
+
"design_memo": { "type": "string", "minLength": 1, "maxLength": 262144, "pattern": "\\S" },
|
|
162
|
+
"narrative_ref": { "$ref": "#/$defs/nullableRepoRef" },
|
|
163
|
+
"narrative_anchor": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/narrativeAnchor" }] },
|
|
164
|
+
"compile_binding": { "$ref": "#/$defs/compileBinding" },
|
|
165
|
+
"parent_task_id": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/identifier" }] }
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"desiredPlanV6": {
|
|
169
|
+
"type": "object", "additionalProperties": false,
|
|
170
|
+
"required": [
|
|
171
|
+
"schema", "project_id", "plan_key", "plan_version", "predecessor_plan_digest",
|
|
172
|
+
"tasks", "hard_dependencies", "joins", "topology_digest", "plan_digest"
|
|
173
|
+
],
|
|
174
|
+
"properties": {
|
|
175
|
+
"schema": { "const": "lattice.todo_plan.v6" },
|
|
176
|
+
"project_id": { "$ref": "#/$defs/identifier" },
|
|
177
|
+
"plan_key": { "$ref": "#/$defs/identifier" },
|
|
178
|
+
"plan_version": { "$ref": "#/$defs/identifier" },
|
|
179
|
+
"predecessor_plan_digest": { "$ref": "#/$defs/nullableDigest" },
|
|
180
|
+
"tasks": { "type": "array", "minItems": 1, "maxItems": 512, "items": { "$ref": "#/$defs/taskV6" } },
|
|
181
|
+
"hard_dependencies": { "type": "array", "maxItems": 2048, "items": { "$ref": "#/$defs/edge" } },
|
|
182
|
+
"joins": { "type": "array", "maxItems": 128, "items": { "$ref": "#/$defs/join" } },
|
|
183
|
+
"topology_digest": { "$ref": "#/$defs/digest" },
|
|
184
|
+
"plan_digest": { "$ref": "#/$defs/digest" }
|
|
185
|
+
}
|
|
186
|
+
},
|
|
147
187
|
"taskMigrationEntry": {
|
|
148
188
|
"type": "object", "additionalProperties": false,
|
|
149
189
|
"required": ["from_task_id", "to_task_id", "state_policy"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quolu/lattice",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
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,10 +27,12 @@
|
|
|
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.plan_create_input.v4.schema.json",
|
|
30
31
|
"docs/schemas/lattice.todo_revision.v2.schema.json",
|
|
31
32
|
"docs/schemas/lattice.todo_revision_set.v3.schema.json",
|
|
32
33
|
"docs/schemas/lattice.phase_todo_revision.v3.schema.json",
|
|
33
34
|
"docs/schemas/lattice.todo_extraction.v2.schema.json",
|
|
35
|
+
"docs/schemas/lattice.todo_extraction.v3.schema.json",
|
|
34
36
|
"docs/schemas/lattice.run_request.v1.schema.json",
|
|
35
37
|
"docs/schemas/lattice.executor_packet.v1.schema.json",
|
|
36
38
|
"docs/schemas/lattice.executor_receipt.v1.schema.json",
|
package/src/cli-help.mjs
CHANGED
|
@@ -27,7 +27,7 @@ Commands:
|
|
|
27
27
|
# 依存グラフがほぼ一直線(serialization_ratioが閾値超)なら一度突き返す。
|
|
28
28
|
# 再考した上でなお直列でよいなら --serialization-reviewed を付けて再実行する
|
|
29
29
|
create --schema --json # 既定は最新版(v3)のJSON Schemaを返す
|
|
30
|
-
create --schema-version <1|2|3> --json
|
|
30
|
+
create --schema-version <1|2|3|4> --json
|
|
31
31
|
show <plan_key> --json # task・依存・phase・状態をplan本体から1コマンドで投影する
|
|
32
32
|
compile --request <request.json>
|
|
33
33
|
compile --schema --json # lattice.run_request.v1 の JSON Schema を出す
|
|
@@ -69,15 +69,15 @@ Read commands:
|
|
|
69
69
|
seam-proposal [--plan <key>] [--json] # 記録済みseam提案をsensor無しで投影する
|
|
70
70
|
verify [--plan <key>] [--json]
|
|
71
71
|
snapshot --rebuild --plan <key>
|
|
72
|
-
gantt
|
|
73
|
-
gantt status [--out <file>]
|
|
74
|
-
gantt serve --port <port> [--scope live|all] # /projects/<project_id>/ をforeground配信
|
|
72
|
+
gantt serve --port <port> [--scope live|all] # 動的表示。静的HTML生成とstatusは廃止
|
|
75
73
|
phase status --plan <key>
|
|
76
74
|
|
|
77
75
|
Write commands:
|
|
76
|
+
dashboard adopt --json # 衝突したproject_idの配信元rootを現在repoへ明示的に移す
|
|
78
77
|
note --plan <key> --task <id> (--message <text>|--input <file>)
|
|
79
78
|
# ToDoへ作業継続に必要な方針・調査結果・注意をappend-onlyで追記する
|
|
80
79
|
migrate --input <extraction.json> [--serialization-reviewed]
|
|
80
|
+
migrate --input <extraction.json> --dry-run --json [--serialization-reviewed]
|
|
81
81
|
# 既存storeへplanを追加する(plan createは空store初期化専用)。
|
|
82
82
|
# 依存グラフがほぼ一直線なら一度突き返し、再考後の --serialization-reviewed で通す
|
|
83
83
|
start --plan <key> --task <id> [--parallel-frontier|--override-reason <text> [--serial-confirmed]]
|
|
@@ -149,7 +149,7 @@ registerはLATTICE_BRIDGE_REGISTRAR_SSH_HOSTとLATTICE_BRIDGE_REGISTRAR_SCRIPT
|
|
|
149
149
|
const SUBCOMMAND_USAGE = Object.freeze({
|
|
150
150
|
status: 'status --json',
|
|
151
151
|
'session-context': 'session-context --json',
|
|
152
|
-
'plan create': 'plan create --input <file> [--serialization-reviewed] | --schema --json | --schema-version <1|2|3> --json',
|
|
152
|
+
'plan create': 'plan create --input <file> [--serialization-reviewed] | --schema --json | --schema-version <1|2|3|4> --json',
|
|
153
153
|
'plan show': 'plan show <plan_key> --json',
|
|
154
154
|
'plan compile': 'plan compile --request <request.json> | --schema --json',
|
|
155
155
|
'plan verify': 'plan verify --request <request.json> --plan <plan.json>',
|
|
@@ -181,7 +181,7 @@ const SUBCOMMAND_USAGE = Object.freeze({
|
|
|
181
181
|
'todo seam-proposal': 'todo seam-proposal [--plan <key>] [--json] | compile --plan <key>',
|
|
182
182
|
'todo verify': 'todo verify [--plan <key>] [--json]',
|
|
183
183
|
'todo snapshot': 'todo snapshot --rebuild --plan <key>',
|
|
184
|
-
'todo gantt': 'todo gantt
|
|
184
|
+
'todo gantt': 'todo gantt serve --port <port> [--scope live|all] # 動的表示のみ。静的HTML生成は廃止',
|
|
185
185
|
'todo phase': 'todo phase <status|review|accept|reject|reopen|close-unaudited> --plan <key> [options]'
|
|
186
186
|
+ ' | baseline --reason <text> [--except <plan_key>]...',
|
|
187
187
|
'todo phase status': 'todo phase status --plan <key>',
|
|
@@ -201,7 +201,7 @@ const SUBCOMMAND_USAGE = Object.freeze({
|
|
|
201
201
|
'todo revise': 'todo revise --plan <key> --input <file> | --schema --json',
|
|
202
202
|
'todo revise-phase': 'todo revise-phase --plan <key> --input <file> | --schema --json',
|
|
203
203
|
'todo revise-set': 'todo revise-set --input <file> | --schema --json',
|
|
204
|
-
'todo migrate': 'todo migrate --input <extraction.json> [--serialization-reviewed] | --schema --json',
|
|
204
|
+
'todo migrate': 'todo migrate --input <extraction.json> [--serialization-reviewed] | --input <extraction.json> --dry-run --json [--serialization-reviewed] | --schema --json',
|
|
205
205
|
'sensor init': 'sensor init [path] --json',
|
|
206
206
|
'sensor sync': 'sensor sync [path] --json',
|
|
207
207
|
'runtime-errors snapshot': 'runtime-errors snapshot [--after-cursor <n>] [--limit <n>] --json',
|