@quolu/lattice 0.62.2 → 0.62.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quolu/lattice",
3
- "version": "0.62.2",
3
+ "version": "0.62.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",
@@ -990,9 +990,24 @@ export async function attachPullWorker({ runDir, taskId, input, environment = pr
990
990
  const occupied = state.intakes.find((entry) => (
991
991
  entry.task_id !== taskId && entry.accepted === null && entry.worker?.pid === input.pid
992
992
  ));
993
- if (occupied) {
993
+ if (occupied && occupied.intervention.state !== 'hold') {
994
994
  fail('WORKER_ALREADY_ATTACHED', `同じworkerは複数active intakeへattachできない: ${occupied.task_id}`);
995
995
  }
996
+ if (occupied && occupied.intervention.state === 'hold') {
997
+ if (occupied.worker.stopped) {
998
+ await signalAttachedWorker(occupied, 'SIGCONT');
999
+ current = await appendEvent(runDir, current, buildEvent({
1000
+ events: current.events, meta: current.meta, kind: 'worker_resumed',
1001
+ taskId: occupied.task_id, payload: { released_by: 'stale_hold_reattach' },
1002
+ }));
1003
+ }
1004
+ current = await appendEvent(runDir, current, buildEvent({
1005
+ events: current.events, meta: current.meta, kind: 'worker_detached',
1006
+ taskId: occupied.task_id,
1007
+ payload: { detached_by: actor, pid: occupied.worker.pid, resumed: occupied.worker.stopped },
1008
+ }));
1009
+ state = project(current.events, current.meta);
1010
+ }
996
1011
  if (intake.worker !== null) {
997
1012
  if (digestArtifact(binding) !== digestArtifact({
998
1013
  pid: intake.worker.pid, process_group_id: intake.worker.process_group_id,
@@ -1082,6 +1097,11 @@ export async function detachPullWorker({ runDir, taskId, environment = process.e
1082
1097
  } finally { await lock.release(); }
1083
1098
  }
1084
1099
 
1100
+ export function concurrentAttachBlocked(occupied) {
1101
+ if (!occupied) return false;
1102
+ return occupied.intervention?.state !== 'hold';
1103
+ }
1104
+
1085
1105
  export function remainingRuntimeConflictFindings(findings, acceptedTaskId) {
1086
1106
  if (!Array.isArray(findings)) return [];
1087
1107
  return findings.filter((finding) => !(finding.todo_ids ?? []).includes(acceptedTaskId));