@quolu/lattice 0.61.2 → 0.62.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/LICENSE +147 -147
- package/README.ja.md +374 -374
- package/README.md +300 -300
- package/bin/lattice-mcp.mjs +0 -0
- package/bin/lattice-scripted-adapter.mjs +0 -0
- package/bin/lattice-scripted-worker.mjs +0 -0
- package/bin/lattice-work-order-adapter.mjs +0 -0
- package/bin/lattice.mjs +20 -9
- package/docs/bridge-setup.md +248 -248
- package/docs/schemas/lattice.executor_packet.v1.schema.json +57 -57
- package/docs/schemas/lattice.executor_receipt.v1.schema.json +66 -66
- package/docs/schemas/lattice.phase_todo_revision.v3.schema.json +360 -360
- package/docs/schemas/lattice.plan_create_input.v1.schema.json +56 -56
- package/docs/schemas/lattice.plan_create_input.v2.schema.json +72 -72
- package/docs/schemas/lattice.plan_create_input.v3.schema.json +81 -81
- package/docs/schemas/lattice.plan_create_input.v4.schema.json +85 -85
- package/docs/schemas/lattice.plan_scope_review.v1.schema.json +55 -55
- package/docs/schemas/lattice.run_request.v1.schema.json +238 -238
- package/docs/schemas/lattice.runtime_adapter_capabilities.v2.schema.json +55 -55
- package/docs/schemas/lattice.runtime_adapter_registration_input.v1.schema.json +78 -78
- package/docs/schemas/lattice.runtime_adapter_registration_input.v2.schema.json +86 -86
- package/docs/schemas/lattice.todo_extraction.v2.schema.json +298 -298
- package/docs/schemas/lattice.todo_extraction.v3.schema.json +150 -150
- package/docs/schemas/lattice.todo_extraction.v4.schema.json +161 -161
- package/docs/schemas/lattice.todo_revision.v2.schema.json +260 -260
- package/docs/schemas/lattice.todo_revision_set.v3.schema.json +363 -363
- package/docs/schemas/lattice.todo_structure_binding.v1.schema.json +47 -47
- package/docs/schemas/lattice.todo_structure_realization.v1.schema.json +55 -55
- package/docs/schemas/lattice.todo_structure_set.v1.schema.json +264 -264
- package/package.json +109 -109
- package/sensor/LICENSE +21 -21
- package/sensor/NOTICE +19 -19
- package/sensor/dist/bin/lattice-sensor.js +9 -9
- package/sensor/dist/db/index.js +24 -24
- package/sensor/dist/db/migrations.js +41 -41
- package/sensor/dist/db/queries.js +164 -164
- package/sensor/dist/db/schema.sql +205 -205
- package/sensor/dist/directory.js +5 -5
- package/sensor/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
- package/sensor/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/sensor/dist/mcp/liveness-watchdog.js +53 -53
- package/sensor/dist/mcp/server-instructions.js +95 -95
- package/sensor/package.json +56 -56
- package/src/cli-help.mjs +9 -5
- package/src/project-cli.mjs +22 -71
- package/src/runtime-diff-observer.mjs +34 -2
- package/src/runtime-pull-intake.mjs +15 -1
- package/src/todo-authoring-input.mjs +183 -0
- package/src/todo-cli.mjs +367 -382
- package/src/todo-independence-contracts.mjs +11 -4
- package/src/todo-independence-guidance.mjs +4 -4
- package/src/todo-store.mjs +6 -30
- package/src/witness-scaffold.mjs +11 -4
|
@@ -203,15 +203,20 @@ export function synthesizeWitnessRunRequest(witnessSet, { baseSha, requestId })
|
|
|
203
203
|
/**
|
|
204
204
|
* 1 taskのconcern anchor宣言を検査する。
|
|
205
205
|
*
|
|
206
|
-
* `within
|
|
207
|
-
*
|
|
206
|
+
* `within`は`owns`または`writes`が指す資源に限る。触ると宣言した面の内側に担当を書ける。
|
|
207
|
+
* 所有も書き込みも無い資源の内側には主張させない。
|
|
208
208
|
*/
|
|
209
|
-
function explainConcernAnchors(anchors, owns, at) {
|
|
209
|
+
function explainConcernAnchors(anchors, owns, writes, at) {
|
|
210
210
|
const reject = (reason, path) => ({ valid: false, reason, path });
|
|
211
211
|
if (!Array.isArray(anchors) || anchors.length > TODO_CONCERN_ANCHOR_LIMIT) {
|
|
212
212
|
return reject('bounded_collection_violation', at);
|
|
213
213
|
}
|
|
214
214
|
const ownedKeys = new Set(owns.map((own) => `${own.kind}\0${own.target}`));
|
|
215
|
+
if (Array.isArray(writes)) {
|
|
216
|
+
for (const write of writes) {
|
|
217
|
+
if (typeof write === 'string') ownedKeys.add(`path\0${write}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
215
220
|
for (const [index, entry] of anchors.entries()) {
|
|
216
221
|
const entryAt = `${at}/${index}`;
|
|
217
222
|
if (!exactRecord(entry, ['within', 'symbols'])) {
|
|
@@ -297,7 +302,9 @@ export function explainTodoWitnessSet(value) {
|
|
|
297
302
|
if (!CONCERN_ANCHOR_SCHEMAS.includes(value.schema)) {
|
|
298
303
|
return reject('concern_anchors_require_witness_set_v2', at);
|
|
299
304
|
}
|
|
300
|
-
const anchors = explainConcernAnchors(
|
|
305
|
+
const anchors = explainConcernAnchors(
|
|
306
|
+
witness.concern_anchors, witness.owns, witness.writes, at,
|
|
307
|
+
);
|
|
301
308
|
if (!anchors.valid) return reject(anchors.reason, anchors.path);
|
|
302
309
|
}
|
|
303
310
|
return { valid: true };
|
|
@@ -304,8 +304,8 @@ export function selectSeamProposalGuidance({ coverage, unknownKinds = [] }) {
|
|
|
304
304
|
*/
|
|
305
305
|
export const TODO_INDEPENDENCE_WORKFLOW = Object.freeze([
|
|
306
306
|
'1. 宣言する: .lattice/todo/witness/<plan_key>.json へ、ToDoごとのowns/reads/writes/affected_testsを書く',
|
|
307
|
-
' 係争資源しか所有していないToDo
|
|
308
|
-
'2. 判定する: lattice todo independence compile --plan <key> --input <ref>(実sensor
|
|
307
|
+
' 係争資源しか所有していないToDoは、ownsまたはwritesの内側で自分が触るsymbolをconcern_anchorsへ宣言できる(witness set v2)。並列可否の判定には写らず、切断候補の束縛だけに効く',
|
|
308
|
+
'2. 判定する: lattice todo independence compile --plan <key> --input <ref>(実sensorを引く。pretty-printやdigest未計算の下書きは機械が直す)',
|
|
309
309
|
'3. 読む: lattice todo independence --plan <key> --json(sensorを引かず、記録とHEAD照合だけで返る)',
|
|
310
310
|
'4. 追従する: plan改訂後は lattice todo independence witness migrate --plan <key> で宣言を写してから再compileする',
|
|
311
311
|
]);
|
|
@@ -319,8 +319,8 @@ export const TODO_INDEPENDENCE_WORKFLOW = Object.freeze([
|
|
|
319
319
|
*/
|
|
320
320
|
const SCAFFOLD_CATALOG = Object.freeze({
|
|
321
321
|
anchor_outside_owned: {
|
|
322
|
-
message: 'concern_anchorのwithin
|
|
323
|
-
next_action: '
|
|
322
|
+
message: 'concern_anchorのwithinが、ownsにもwritesにも無い。触ると宣言した面の内側にだけ担当を書ける。',
|
|
323
|
+
next_action: 'align_anchor_with_owns_or_writes',
|
|
324
324
|
},
|
|
325
325
|
draft_invalid: {
|
|
326
326
|
message: '下書きがlattice.todo_witness_draft契約を満たしていない。',
|
package/src/todo-store.mjs
CHANGED
|
@@ -1040,7 +1040,11 @@ function validateMergedTransition(store, member, event) {
|
|
|
1040
1040
|
if (event.kind === 'reopen' && event.payload.override_reason === null) {
|
|
1041
1041
|
const startedSuccessor = mergedSuccessorKeys(store, targetKey)
|
|
1042
1042
|
.some((key) => states.get(key) !== 'pending');
|
|
1043
|
-
if (startedSuccessor)
|
|
1043
|
+
if (startedSuccessor) {
|
|
1044
|
+
fail('STORE_INCONSISTENT', 'reopen_has_started_successor', {
|
|
1045
|
+
next_action: `lattice todo split --plan ${member.plan.plan_key} --input <file>`,
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1044
1048
|
}
|
|
1045
1049
|
if (event.kind === 'phase_reopen' && event.payload.override_reason === null) {
|
|
1046
1050
|
const startedSuccessor = member.plan.schema === 'lattice.todo_plan.v4'
|
|
@@ -1838,6 +1842,7 @@ function resolveCanonicalTaskId(plan, requestedTaskId) {
|
|
|
1838
1842
|
}
|
|
1839
1843
|
|
|
1840
1844
|
async function enforceTodoStructureLifecycleGate(repoRoot, member, eventInput) {
|
|
1845
|
+
if (eventInput.kind === 'done') return;
|
|
1841
1846
|
const binding = await readTodoStructureBinding({
|
|
1842
1847
|
repoRoot, planKey: member.plan.plan_key, planVersion: member.plan.plan_version,
|
|
1843
1848
|
});
|
|
@@ -1846,35 +1851,6 @@ async function enforceTodoStructureLifecycleGate(repoRoot, member, eventInput) {
|
|
|
1846
1851
|
if (source === null || source.structure_set_digest !== binding.structure_set_digest) {
|
|
1847
1852
|
fail('STRUCTURE_LIFECYCLE_GATE_FAILED', 'enabled_structure_source_unreadable');
|
|
1848
1853
|
}
|
|
1849
|
-
if (eventInput.kind === 'done') {
|
|
1850
|
-
const task = source.tasks.find(({ task_id: id }) => id === eventInput.task_id);
|
|
1851
|
-
if (task?.applicability !== 'graph') return;
|
|
1852
|
-
const chain = await readTodoStructureRealizationChain({
|
|
1853
|
-
repoRoot, structureSet: source, taskId: eventInput.task_id,
|
|
1854
|
-
});
|
|
1855
|
-
const latest = chain.at(-1);
|
|
1856
|
-
if (latest === undefined) {
|
|
1857
|
-
fail('STRUCTURE_REALIZATION_REQUIRED', 'fresh_realization_missing', {
|
|
1858
|
-
plan_key: member.plan.plan_key, task_id: eventInput.task_id,
|
|
1859
|
-
next_action: `lattice todo structure realize --plan ${member.plan.plan_key} --task ${eventInput.task_id} --realized <actual-structure.json>`,
|
|
1860
|
-
});
|
|
1861
|
-
}
|
|
1862
|
-
let currentHead;
|
|
1863
|
-
try {
|
|
1864
|
-
currentHead = gitSync(['rev-parse', '--verify', 'HEAD^{commit}'], {
|
|
1865
|
-
cwd: repoRoot, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'],
|
|
1866
|
-
}).trim();
|
|
1867
|
-
} catch {
|
|
1868
|
-
fail('STRUCTURE_GIT_HEAD_UNAVAILABLE', 'current_head_unavailable');
|
|
1869
|
-
}
|
|
1870
|
-
if (latest.head_sha !== currentHead) {
|
|
1871
|
-
fail('STRUCTURE_REALIZATION_REQUIRED', 'realization_head_stale', {
|
|
1872
|
-
plan_key: member.plan.plan_key, task_id: eventInput.task_id,
|
|
1873
|
-
realization_head_sha: latest.head_sha, current_head_sha: currentHead,
|
|
1874
|
-
next_action: `lattice todo structure realize --plan ${member.plan.plan_key} --task ${eventInput.task_id} --realized <actual-structure.json>`,
|
|
1875
|
-
});
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
1854
|
if (!['phase_accept', 'phase_close_unaudited'].includes(eventInput.kind)
|
|
1879
1855
|
|| member.tasks.some(({ status }) => status !== 'done')) return;
|
|
1880
1856
|
const finalization = await readTodoStructureFinalization({
|
package/src/witness-scaffold.mjs
CHANGED
|
@@ -65,6 +65,7 @@ export function validateWitnessDraft(value) {
|
|
|
65
65
|
&& task !== null && typeof task === 'object' && !Array.isArray(task)
|
|
66
66
|
&& draftOwnEntries(task, value.schema) !== null
|
|
67
67
|
&& (task.reads === undefined || (Array.isArray(task.reads) && task.reads.every(isTodoRef)))
|
|
68
|
+
&& (task.writes === undefined || (Array.isArray(task.writes) && task.writes.every(isTodoRef)))
|
|
68
69
|
&& (task.unknowns === undefined || (Array.isArray(task.unknowns)
|
|
69
70
|
&& task.unknowns.every((entry) => entry !== null && typeof entry === 'object'
|
|
70
71
|
&& isTodoIdentifier(entry.kind) && typeof entry.ref === 'string' && entry.ref.length > 0)))
|
|
@@ -113,20 +114,26 @@ export function buildWitnessSet({ draft, observationByPath } = {}) {
|
|
|
113
114
|
const entries = draftOwnEntries(task, draft.schema) ?? [];
|
|
114
115
|
const owns = [...new Map(entries.map((entry) => [entry.target, entry])).values()]
|
|
115
116
|
.sort((left, right) => compareText(left.target, right.target));
|
|
116
|
-
const
|
|
117
|
+
const writeTargets = sortedUnique([
|
|
118
|
+
...owns.map(({ target }) => target),
|
|
119
|
+
...(Array.isArray(task.writes) ? task.writes : []),
|
|
120
|
+
]);
|
|
121
|
+
const declaredTargets = new Set(writeTargets);
|
|
117
122
|
const affected = sortedUnique(owns.flatMap(({ target }) => (
|
|
118
123
|
observationByPath?.[target]?.affectedTests ?? []
|
|
119
124
|
)));
|
|
120
125
|
for (const anchor of task.concern_anchors ?? []) {
|
|
121
|
-
// `within
|
|
122
|
-
if (!
|
|
126
|
+
// `within`はownsまたはwritesが指す資源に限る。
|
|
127
|
+
if (!declaredTargets.has(anchor.within)) {
|
|
128
|
+
reasons.push(`anchor_outside_owned:${taskId}:${anchor.within}`);
|
|
129
|
+
}
|
|
123
130
|
}
|
|
124
131
|
manualWitness[taskId] = {
|
|
125
132
|
owns: owns.map(({ target, creates }) => (
|
|
126
133
|
creates ? { kind: 'path', target, creates: true } : { kind: 'path', target }
|
|
127
134
|
)),
|
|
128
135
|
reads: sortedUnique(task.reads ?? []),
|
|
129
|
-
writes:
|
|
136
|
+
writes: writeTargets,
|
|
130
137
|
resources: [],
|
|
131
138
|
state_effects: [],
|
|
132
139
|
sensor_provenance: {
|