@quolu/lattice 0.25.0 → 0.26.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quolu/lattice",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "Lattice — phase-aware TODO graph compiler and conflict-aware orchestration runtime",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -59,10 +59,8 @@
59
59
  "prepublishOnly": "npm run verify:release-commit",
60
60
  "test": "node scripts/run-product-tests.mjs",
61
61
  "test:sensor": "npm --prefix sensor test",
62
- "precheck": "node --check src/bridge-launch-agent.mjs",
63
- "check": "node --check bin/lattice.mjs && node --check bin/lattice-mcp.mjs && node --check bin/lattice-dashboard.mjs && node --check bin/lattice-bridge.mjs && node --check bin/lattice-scripted-adapter.mjs && node --check src/cli-stdio.mjs && node --check src/bridge-address.mjs && node --check src/bridge-registrar.mjs && node --check src/todo-independence-guidance.mjs && node --check src/todo-independence.mjs && node --check src/todo-independence-contracts.mjs && node --check src/seam-proposal-contracts.mjs && node --check src/seam-proposal-queries.mjs && node --check src/seam-proposal.mjs && node --check src/todo-gantt-layout.mjs && node --check src/todo-gantt-scope.mjs && node --check src/bridge-config.mjs && node --check src/bridge-server.mjs && node --check src/bridge-daemon.mjs && node --check src/bridge-cli.mjs && node --check src/project-cli.mjs && node --check src/sensor-cli.mjs && node --check src/sensor-runtime.mjs && node --check src/sensor-adapter.mjs && node --check src/factory-diagnostics.mjs && node --check src/runtime-errors.mjs && node --check src/runtime-contracts.mjs && node --check src/runtime-event-store.mjs && node --check src/runtime-adapter-registry.mjs && node --check src/runtime-scripted-adapter-controller.mjs && node --check src/hash-chain.mjs && node --check src/dag-chain.mjs && node --check src/todo-contracts.mjs && node --check src/todo-chain.mjs && node --check src/todo-store.mjs && node --check src/todo-migration.mjs && node --check src/todo-revision.mjs && node --check src/todo-status.mjs && node --check src/todo-cli.mjs && node --check src/todo-dashboard-registry.mjs && node --check src/todo-gantt-presentation.mjs && node --check src/todo-gantt-live.mjs && node --check src/bounded-seam.mjs && node --check src/todo-narrative-anchor.mjs && node --check src/todo-markdown-renderer.mjs && node --check src/todo-gantt-svg.mjs && node --check src/todo-gantt-html.mjs && node --check src/runtime-projection.mjs && node --check src/runtime-decision-verifier.mjs && node --check src/runtime-front-end.mjs && node --check src/runtime-cli.mjs && node --check src/rc3-dogfood-scaffold.mjs && node --check src/runtime-engine.mjs && node --check src/runtime-scripted-executor.mjs && node --check src/runtime-diff-observer.mjs && node --check src/runtime-worktree-executor.mjs && node --check src/runtime-hold-recompile.mjs && node --check src/rc3-scripted-campaign.mjs && node --check src/rc3-actual-dogfood.mjs && node --check src/rc4-stage1-dogfood.mjs && node --check research/fixtures/dispatch-record/src/dispatch-record.mjs && node --check test/research-dispatch-record.test.mjs",
64
- "check:project-identity": "node --check src/project-identity.mjs",
65
- "ci": "npm run test && npm run test:sensor && npm run check && npm run check:project-identity && npm run verify:todo-store",
62
+ "check": "node scripts/check-syntax.mjs",
63
+ "ci": "npm run test && npm run test:sensor && npm run check && npm run verify:todo-store",
66
64
  "verify:todo-store": "node bin/lattice.mjs todo verify --json"
67
65
  }
68
66
  }
@@ -65,6 +65,7 @@ function sha16(value) {
65
65
 
66
66
  const WITNESS_KINDS = Object.freeze(['state', 'schema', 'invariant', 'effect', 'external_effect']);
67
67
  const HEX_DIGEST = /^[0-9a-f]{64}$/u;
68
+ const HEX_SHA1 = /^[0-9a-f]{40}$/u;
68
69
  const IDENTIFIER = /^[0-9A-Za-z](?:[0-9A-Za-z._-]{0,127})$/u;
69
70
  const compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
70
71
 
@@ -620,12 +621,19 @@ export function recompileNextEpochPlan(options = {}) {
620
621
  if (!exactRecord(options, [
621
622
  'runId', 'request', 'plan', 'manifests', 'packets', 'events', 'holdDecision',
622
623
  'additionalConflicts', 'recordedAt',
624
+ ]) && !exactRecord(options, [
625
+ 'runId', 'request', 'plan', 'manifests', 'packets', 'events', 'holdDecision',
626
+ 'additionalConflicts', 'recordedAt', 'successorBaseSha',
623
627
  ])) {
624
628
  fail('recompileNextEpochPlan optionsがexact shapeでない');
625
629
  }
626
630
  const {
627
631
  runId, request, plan, manifests, packets, events, holdDecision, additionalConflicts, recordedAt,
632
+ successorBaseSha = null,
628
633
  } = options;
634
+ if (successorBaseSha !== null && !HEX_SHA1.test(successorBaseSha)) {
635
+ fail('successorBaseShaがgit shaでない');
636
+ }
629
637
  if (!validateRuntimePlan(plan)) fail('planがruntime_plan.v1 contractを満たさない');
630
638
  if (!validateHoldDecision(holdDecision)) fail('holdDecisionがcontractを満たさない');
631
639
  if (!Array.isArray(additionalConflicts)) fail('additionalConflictsがarrayではない');
@@ -673,7 +681,11 @@ export function recompileNextEpochPlan(options = {}) {
673
681
  plan_ref: newPlanRef,
674
682
  plan_epoch: newEpoch,
675
683
  request_digest: request.request_digest,
676
- base_sha: plan.base_sha,
684
+ // 変換でsourceの構造が変わったなら、再開先は変換を含むbaseでなければならない。
685
+ // 旧baseのまま再開させると、splitが所有を宣言した新pathがworktreeに存在しない(ADR 0141)。
686
+ // carry-over側のrebind packetはcontent不変が要件なので、そちらは触らない——
687
+ // 継続する作業は自分のworktreeで走り続けており、baseを付け替える対象ではない。
688
+ base_sha: successorBaseSha ?? plan.base_sha,
677
689
  nodes: structuredClone(plan.nodes),
678
690
  precedence: structuredClone(plan.precedence),
679
691
  conflicts: mergedConflicts,
@@ -98,7 +98,8 @@ export function buildRuntimeSeamSplit({
98
98
  export async function resolveRuntimeSeamTreatment(options = {}) {
99
99
  const {
100
100
  finding, witnessSet, pathNames = {}, predeclaredTreatments = [],
101
- applyConflict, baseSha, manifestDigest, affectedTests = [], taskMigrationDigest,
101
+ applyConflict, commitTransform, baseSha, manifestDigest, affectedTests = [],
102
+ taskMigrationDigest,
102
103
  } = options;
103
104
 
104
105
  if (finding?.kind === 'observed_write_conflict' && typeof finding.path === 'string') {
@@ -122,6 +123,13 @@ export async function resolveRuntimeSeamTreatment(options = {}) {
122
123
  }
123
124
 
124
125
  const applied = await applyConflict({ conflict });
126
+ if (applied?.outcome?.decision === 'accepted' && typeof commitTransform !== 'function') {
127
+ // 確定する手段が無いまま採用すると、splitは所有を宣言するのに再開先へその成果が無い。
128
+ // 「変換した」と言いながら再開できない状態を作らない(ADR 0141)。
129
+ return {
130
+ lane: 'intentional_serial', treatment: null, split: null, reasons: ['committer_absent'],
131
+ };
132
+ }
125
133
  if (applied?.outcome?.decision !== 'accepted') {
126
134
  return {
127
135
  lane: 'intentional_serial',
@@ -140,6 +148,15 @@ export async function resolveRuntimeSeamTreatment(options = {}) {
140
148
  if (built.split === null) {
141
149
  return { lane: 'intentional_serial', treatment: null, split: null, reasons: built.reasons };
142
150
  }
151
+ // 再開先が実在するbaseを要る。branchを動かさずcommitとして確定し、そのshaを後継planへ渡す。
152
+ const committed = await commitTransform({
153
+ conflict, files: applied.files ?? {}, candidateId: conflict.candidateId,
154
+ });
155
+ if (!/^[0-9a-f]{40}$/u.test(committed?.commitSha ?? '')) {
156
+ return {
157
+ lane: 'intentional_serial', treatment: null, split: null, reasons: ['transform_not_committed'],
158
+ };
159
+ }
143
160
  return {
144
161
  lane: 'seam_transform',
145
162
  treatment: {
@@ -148,6 +165,8 @@ export async function resolveRuntimeSeamTreatment(options = {}) {
148
165
  },
149
166
  split: built.split,
150
167
  files: applied.files ?? null,
168
+ successor_base_sha: committed.commitSha,
169
+ successor_base_ref: committed.ref ?? null,
151
170
  reasons: [],
152
171
  };
153
172
  }
Binary file