@quolu/lattice 0.57.2 → 0.57.3
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/package.json +1 -1
- package/src/runtime-pull-intake.mjs +8 -4
- package/src/todo-cli.mjs +3 -0
- package/src/todo-store.mjs +37 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quolu/lattice",
|
|
3
|
-
"version": "0.57.
|
|
3
|
+
"version": "0.57.3",
|
|
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",
|
|
@@ -681,8 +681,10 @@ export async function intakePullTask({ repoRoot, runDir, taskId, environment = p
|
|
|
681
681
|
affected_tests: [], graph_evidence: [], witness_provenance: {}, manifest_digest: '',
|
|
682
682
|
};
|
|
683
683
|
manifest.manifest_digest = selfDigest(manifest, 'manifest_digest');
|
|
684
|
-
verdict.state
|
|
685
|
-
|
|
684
|
+
if (verdict.state !== 'hold') {
|
|
685
|
+
verdict.state = 'hold'; verdict.reason = 'boundary_unverified';
|
|
686
|
+
verdict.next_action = 'declare_and_recompile'; verdict.detail = { cause: error.code };
|
|
687
|
+
}
|
|
686
688
|
}
|
|
687
689
|
const constraint = verdict.state === 'none'
|
|
688
690
|
? planningConstraint(verdict.artifact, taskId, state, member) : null;
|
|
@@ -760,8 +762,10 @@ export async function intakePullTask({ repoRoot, runDir, taskId, environment = p
|
|
|
760
762
|
affected_tests: [], graph_evidence: [], witness_provenance: {}, manifest_digest: '',
|
|
761
763
|
};
|
|
762
764
|
manifest.manifest_digest = selfDigest(manifest, 'manifest_digest');
|
|
763
|
-
verdict.state
|
|
764
|
-
|
|
765
|
+
if (verdict.state !== 'hold') {
|
|
766
|
+
verdict.state = 'hold'; verdict.reason = 'boundary_unverified';
|
|
767
|
+
verdict.next_action = 'declare_and_recompile'; verdict.detail = { cause: error.code };
|
|
768
|
+
}
|
|
765
769
|
}
|
|
766
770
|
const packet = packetFor({ meta: current.meta, taskId, baseSha, manifest });
|
|
767
771
|
const worktreePath = await ensureScriptedWorktree({ repoRoot, runDir, packet });
|
package/src/todo-cli.mjs
CHANGED
|
@@ -1759,6 +1759,9 @@ async function independenceCompile({ repoRoot, planKey, inputRef }) {
|
|
|
1759
1759
|
previousArtifact,
|
|
1760
1760
|
});
|
|
1761
1761
|
const { ref } = await writeTodoIndependenceArtifact({ repoRoot, artifact });
|
|
1762
|
+
// compile成功後にだけ、受理した宣言をruntime readerが要求するcanonical bytesで固定する。
|
|
1763
|
+
// inputがstore自身でも外部draftでも、唯一の正規writerを通して同じ契約へ収束させる。
|
|
1764
|
+
await writeTodoWitnessSet({ repoRoot, witnessSet });
|
|
1762
1765
|
|
|
1763
1766
|
const result = {
|
|
1764
1767
|
schema: 'lattice.todo_independence_compile_result.v2',
|
package/src/todo-store.mjs
CHANGED
|
@@ -2286,8 +2286,19 @@ function localTaskRef(ref, plan, taskId) {
|
|
|
2286
2286
|
&& ref.task_id === taskId;
|
|
2287
2287
|
}
|
|
2288
2288
|
|
|
2289
|
+
function removedTaskIdsFor(revision) {
|
|
2290
|
+
return new Set(revision.task_migration
|
|
2291
|
+
.filter(({ to_task_id, state_policy }) => to_task_id === 'removed' && state_policy === 'removed')
|
|
2292
|
+
.map(({ from_task_id }) => from_task_id));
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
function removedTaskRef(ref, plan, removedTaskIds) {
|
|
2296
|
+
return ref.project_id === plan.project_id && ref.plan_key === plan.plan_key
|
|
2297
|
+
&& removedTaskIds.has(ref.task_id);
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2289
2300
|
function taskSemantics(plan, taskId, idMap, {
|
|
2290
|
-
reconciliationMetadata = false, includeDesignMemo = false,
|
|
2301
|
+
reconciliationMetadata = false, includeDesignMemo = false, removedTaskIds = new Set(),
|
|
2291
2302
|
} = {}) {
|
|
2292
2303
|
const task = plan.tasks.find(({ task_id }) => task_id === taskId);
|
|
2293
2304
|
if (!task) return null;
|
|
@@ -2302,17 +2313,23 @@ function taskSemantics(plan, taskId, idMap, {
|
|
|
2302
2313
|
compile_binding: task.compile_binding, parent_task_id: mapId(task.parent_task_id ?? null),
|
|
2303
2314
|
};
|
|
2304
2315
|
const edges = plan.hard_dependencies
|
|
2305
|
-
.filter(({ from, to }) =>
|
|
2316
|
+
.filter(({ from, to }) => !removedTaskRef(from, plan, removedTaskIds)
|
|
2317
|
+
&& !removedTaskRef(to, plan, removedTaskIds)
|
|
2318
|
+
&& (localTaskRef(from, plan, taskId) || localTaskRef(to, plan, taskId)))
|
|
2306
2319
|
.map(({ from, to }) => ({ from: mappedNodeRef(from, plan, idMap), to: mappedNodeRef(to, plan, idMap) }))
|
|
2307
2320
|
.sort((left, right) => canonicalizeTodoArtifact(left) < canonicalizeTodoArtifact(right) ? -1 : 1);
|
|
2308
2321
|
const joins = plan.joins
|
|
2309
|
-
.
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2322
|
+
.flatMap((join) => {
|
|
2323
|
+
if (removedTaskRef(join.before, plan, removedTaskIds)) return [];
|
|
2324
|
+
const after = join.after.filter((ref) => !removedTaskRef(ref, plan, removedTaskIds));
|
|
2325
|
+
if (after.length === 0 || (!localTaskRef(join.before, plan, taskId)
|
|
2326
|
+
&& !after.some((ref) => localTaskRef(ref, plan, taskId)))) return [];
|
|
2327
|
+
return [{ ...join,
|
|
2328
|
+
after: after.map((ref) => mappedNodeRef(ref, plan, idMap))
|
|
2313
2329
|
.sort((left, right) => canonicalizeTodoArtifact(left) < canonicalizeTodoArtifact(right) ? -1 : 1),
|
|
2314
|
-
|
|
2315
|
-
|
|
2330
|
+
before: mappedNodeRef(join.before, plan, idMap),
|
|
2331
|
+
}];
|
|
2332
|
+
}).sort((left, right) => left.id < right.id ? -1 : 1);
|
|
2316
2333
|
const phaseAcceptDependencies = isDecoupledPhaseTodoPlanSchema(plan.schema)
|
|
2317
2334
|
? plan.phase_accept_dependencies
|
|
2318
2335
|
.filter(({ to }) => localTaskRef(to, plan, taskId))
|
|
@@ -2323,7 +2340,7 @@ function taskSemantics(plan, taskId, idMap, {
|
|
|
2323
2340
|
}
|
|
2324
2341
|
|
|
2325
2342
|
function phaseV3CarrySemantics(plan, taskId, taskIdMap, phaseIdMap,
|
|
2326
|
-
{ reconciliationMetadata = false, includeDesignMemo = false } = {}) {
|
|
2343
|
+
{ reconciliationMetadata = false, includeDesignMemo = false, removedTaskIds = new Set() } = {}) {
|
|
2327
2344
|
const task = plan.tasks.find(({ task_id: id }) => id === taskId);
|
|
2328
2345
|
if (task === undefined) return null;
|
|
2329
2346
|
const mapTaskRef = (ref) => ref.project_id === plan.project_id && ref.plan_key === plan.plan_key
|
|
@@ -2351,13 +2368,17 @@ function phaseV3CarrySemantics(plan, taskId, taskIdMap, phaseIdMap,
|
|
|
2351
2368
|
const incoming = [];
|
|
2352
2369
|
const outgoing = [];
|
|
2353
2370
|
for (const edge of plan.hard_dependencies) {
|
|
2371
|
+
if (removedTaskRef(edge.from, plan, removedTaskIds)
|
|
2372
|
+
|| removedTaskRef(edge.to, plan, removedTaskIds)) continue;
|
|
2354
2373
|
const mapped = { kind: 'hard', from: mapTaskRef(edge.from), to: mapTaskRef(edge.to) };
|
|
2355
2374
|
if (localTaskRef(edge.to, plan, taskId)) incoming.push(mapped);
|
|
2356
2375
|
if (localTaskRef(edge.from, plan, taskId)) outgoing.push(mapped);
|
|
2357
2376
|
}
|
|
2358
2377
|
for (const join of plan.joins) {
|
|
2378
|
+
if (removedTaskRef(join.before, plan, removedTaskIds)) continue;
|
|
2359
2379
|
const to = mapTaskRef(join.before);
|
|
2360
2380
|
for (const after of join.after) {
|
|
2381
|
+
if (removedTaskRef(after, plan, removedTaskIds)) continue;
|
|
2361
2382
|
const tuple = { kind: 'join', join_id: join.id, from: mapTaskRef(after), to };
|
|
2362
2383
|
if (localTaskRef(join.before, plan, taskId)) incoming.push(tuple);
|
|
2363
2384
|
if (localTaskRef(after, plan, taskId)) outgoing.push(tuple);
|
|
@@ -2375,11 +2396,12 @@ function validatePhaseV3Carry(previous, revision, migration, idMap, state) {
|
|
|
2375
2396
|
const reconciliationMetadata = migration.state_policy === 'carry_reconciled_metadata';
|
|
2376
2397
|
const predecessorTask = previous.plan.tasks.find(({ task_id }) => task_id === migration.from_task_id);
|
|
2377
2398
|
const includeDesignMemo = !reconciliationMetadata && typeof predecessorTask?.design_memo === 'string';
|
|
2399
|
+
const removedTaskIds = removedTaskIdsFor(revision);
|
|
2378
2400
|
const phaseIdMap = new Map(revision.phase_migration
|
|
2379
2401
|
.filter(({ from_phase_id, to_phase_id }) => from_phase_id !== null && to_phase_id !== 'removed')
|
|
2380
2402
|
.map(({ from_phase_id, to_phase_id }) => [from_phase_id, to_phase_id]));
|
|
2381
2403
|
const before = phaseV3CarrySemantics(previous.plan, migration.from_task_id, idMap, phaseIdMap,
|
|
2382
|
-
{ reconciliationMetadata, includeDesignMemo });
|
|
2404
|
+
{ reconciliationMetadata, includeDesignMemo, removedTaskIds });
|
|
2383
2405
|
const after = phaseV3CarrySemantics(revision.desired_plan, migration.to_task_id,
|
|
2384
2406
|
new Map(), new Map(),
|
|
2385
2407
|
{ reconciliationMetadata, includeDesignMemo });
|
|
@@ -2412,8 +2434,9 @@ function validateAcquirePhaseCarry(previous, revision, migration, idMap) {
|
|
|
2412
2434
|
.map(({ from_phase_id, to_phase_id }) => [from_phase_id, to_phase_id]));
|
|
2413
2435
|
const predecessorTask = previous.plan.tasks.find(({ task_id }) => task_id === migration.from_task_id);
|
|
2414
2436
|
const includeDesignMemo = typeof predecessorTask?.design_memo === 'string';
|
|
2437
|
+
const removedTaskIds = removedTaskIdsFor(revision);
|
|
2415
2438
|
const before = phaseV3CarrySemantics(previous.plan, migration.from_task_id, idMap, phaseIdMap,
|
|
2416
|
-
{ includeDesignMemo });
|
|
2439
|
+
{ includeDesignMemo, removedTaskIds });
|
|
2417
2440
|
const after = phaseV3CarrySemantics(revision.desired_plan, migration.to_task_id, new Map(), new Map(),
|
|
2418
2441
|
{ includeDesignMemo });
|
|
2419
2442
|
if (before.task.phase_id !== null) {
|
|
@@ -2448,6 +2471,7 @@ function stateMigrationFor(previous, revision) {
|
|
|
2448
2471
|
const idMap = new Map(revision.task_migration
|
|
2449
2472
|
.filter(({ to_task_id }) => to_task_id !== 'removed')
|
|
2450
2473
|
.map(({ from_task_id, to_task_id }) => [from_task_id, to_task_id]));
|
|
2474
|
+
const removedTaskIds = removedTaskIdsFor(revision);
|
|
2451
2475
|
const states = new Map(previous.tasks.map((state) => [state.task_id, state]));
|
|
2452
2476
|
return revision.task_migration.map((migration) => {
|
|
2453
2477
|
const carriesState = ['carry', 'carry_reconciled_metadata', 'acquire_phase'].includes(migration.state_policy);
|
|
@@ -2467,7 +2491,7 @@ function stateMigrationFor(previous, revision) {
|
|
|
2467
2491
|
.find(({ task_id }) => task_id === migration.from_task_id);
|
|
2468
2492
|
const includeDesignMemo = typeof predecessorTask?.design_memo === 'string';
|
|
2469
2493
|
const before = taskSemantics(previous.plan, migration.from_task_id, idMap,
|
|
2470
|
-
{ includeDesignMemo });
|
|
2494
|
+
{ includeDesignMemo, removedTaskIds });
|
|
2471
2495
|
const after = taskSemantics(revision.desired_plan, migration.to_task_id, new Map(),
|
|
2472
2496
|
{ includeDesignMemo });
|
|
2473
2497
|
if (canonicalizeTodoArtifact(before) !== canonicalizeTodoArtifact(after)) {
|
|
@@ -2482,7 +2506,7 @@ function stateMigrationFor(previous, revision) {
|
|
|
2482
2506
|
const includeDesignMemo = !reconciliationMetadata
|
|
2483
2507
|
&& typeof predecessorTask?.design_memo === 'string';
|
|
2484
2508
|
const before = taskSemantics(previous.plan, migration.from_task_id, idMap,
|
|
2485
|
-
{ reconciliationMetadata, includeDesignMemo });
|
|
2509
|
+
{ reconciliationMetadata, includeDesignMemo, removedTaskIds });
|
|
2486
2510
|
const after = taskSemantics(revision.desired_plan, migration.to_task_id, new Map(),
|
|
2487
2511
|
{ reconciliationMetadata, includeDesignMemo });
|
|
2488
2512
|
if (canonicalizeTodoArtifact(before) !== canonicalizeTodoArtifact(after)) {
|