kiokuko-dsh 0.2.26 → 0.2.28

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.
Files changed (99) hide show
  1. package/dist/context/replay-model-memory.d.ts +2 -2
  2. package/dist/context/replay-model-memory.d.ts.map +1 -1
  3. package/dist/context/replay-model-memory.js +70 -16
  4. package/dist/context/replay-model-memory.js.map +1 -1
  5. package/dist/dsh/agenticreplay-host.d.ts.map +1 -1
  6. package/dist/dsh/agenticreplay-host.js +5 -1
  7. package/dist/dsh/agenticreplay-host.js.map +1 -1
  8. package/dist/dsh/agenticreplay-libraries.d.ts +1 -0
  9. package/dist/dsh/agenticreplay-libraries.d.ts.map +1 -1
  10. package/dist/dsh/agenticreplay-libraries.js.map +1 -1
  11. package/dist/dsh/agenticreplay-recorder.d.ts.map +1 -1
  12. package/dist/dsh/agenticreplay-recorder.js +22 -10
  13. package/dist/dsh/agenticreplay-recorder.js.map +1 -1
  14. package/dist/dsh/agenticreplay-security.d.ts.map +1 -1
  15. package/dist/dsh/agenticreplay-security.js +40 -6
  16. package/dist/dsh/agenticreplay-security.js.map +1 -1
  17. package/dist/dsh/agenticreplay-types.d.ts +3 -0
  18. package/dist/dsh/agenticreplay-types.d.ts.map +1 -1
  19. package/dist/dsh/agenticreplay-types.js.map +1 -1
  20. package/dist/dsh/coding-workflow/host.d.ts +1 -0
  21. package/dist/dsh/coding-workflow/host.d.ts.map +1 -1
  22. package/dist/dsh/coding-workflow/host.js +10 -0
  23. package/dist/dsh/coding-workflow/host.js.map +1 -1
  24. package/dist/dsh/coding-workflow/service.d.ts +6 -2
  25. package/dist/dsh/coding-workflow/service.d.ts.map +1 -1
  26. package/dist/dsh/coding-workflow/service.js +6 -5
  27. package/dist/dsh/coding-workflow/service.js.map +1 -1
  28. package/dist/dsh/core/host.d.ts.map +1 -1
  29. package/dist/dsh/core/host.js +10 -1
  30. package/dist/dsh/core/host.js.map +1 -1
  31. package/dist/dsh/execution-support.d.ts.map +1 -1
  32. package/dist/dsh/execution-support.js +2 -0
  33. package/dist/dsh/execution-support.js.map +1 -1
  34. package/dist/dsh/host-adapter/lifecycle.d.ts +20 -18
  35. package/dist/dsh/host-adapter/lifecycle.d.ts.map +1 -1
  36. package/dist/dsh/host-adapter/lifecycle.js +298 -102
  37. package/dist/dsh/host-adapter/lifecycle.js.map +1 -1
  38. package/dist/dsh/host-adapter.d.ts +47 -47
  39. package/dist/dsh/host-adapter.d.ts.map +1 -1
  40. package/dist/dsh/host-adapter.js +1213 -592
  41. package/dist/dsh/host-adapter.js.map +1 -1
  42. package/dist/dsh/index.d.ts +42 -41
  43. package/dist/dsh/index.d.ts.map +1 -1
  44. package/dist/dsh/index.js +166 -92
  45. package/dist/dsh/index.js.map +1 -1
  46. package/dist/dsh/lifecycle-memory.d.ts +12 -7
  47. package/dist/dsh/lifecycle-memory.d.ts.map +1 -1
  48. package/dist/dsh/lifecycle-memory.js +606 -172
  49. package/dist/dsh/lifecycle-memory.js.map +1 -1
  50. package/dist/dsh/memory-application.d.ts +9 -9
  51. package/dist/dsh/memory-application.d.ts.map +1 -1
  52. package/dist/dsh/memory-application.js +448 -147
  53. package/dist/dsh/memory-application.js.map +1 -1
  54. package/dist/dsh/on-demand-intake.d.ts +13 -0
  55. package/dist/dsh/on-demand-intake.d.ts.map +1 -1
  56. package/dist/dsh/on-demand-intake.js +30 -7
  57. package/dist/dsh/on-demand-intake.js.map +1 -1
  58. package/dist/dsh/repository-learning-reflector.d.ts +58 -0
  59. package/dist/dsh/repository-learning-reflector.d.ts.map +1 -0
  60. package/dist/dsh/repository-learning-reflector.js +230 -0
  61. package/dist/dsh/repository-learning-reflector.js.map +1 -0
  62. package/dist/dsh/repository-learning.d.ts +34 -0
  63. package/dist/dsh/repository-learning.d.ts.map +1 -0
  64. package/dist/dsh/repository-learning.js +512 -0
  65. package/dist/dsh/repository-learning.js.map +1 -0
  66. package/dist/dsh/task-completion.d.ts +7 -7
  67. package/dist/dsh/task-completion.d.ts.map +1 -1
  68. package/dist/dsh/task-completion.js +554 -194
  69. package/dist/dsh/task-completion.js.map +1 -1
  70. package/dist/dsh/task-state-host.d.ts +10 -10
  71. package/dist/dsh/task-state-host.d.ts.map +1 -1
  72. package/dist/dsh/task-state-host.js +337 -145
  73. package/dist/dsh/task-state-host.js.map +1 -1
  74. package/dist/index.js +1 -0
  75. package/dist/locale/en.json +1 -1
  76. package/dist/locale/ja.json +1 -1
  77. package/dist/locale/ko.json +1 -1
  78. package/dist/locale/zh-CN.json +1 -1
  79. package/dist/memory/forget.d.ts +2 -2
  80. package/dist/memory/forget.d.ts.map +1 -1
  81. package/dist/memory/forget.js +175 -74
  82. package/dist/memory/forget.js.map +1 -1
  83. package/dist/memory/replay-reflection.d.ts +94 -0
  84. package/dist/memory/replay-reflection.d.ts.map +1 -0
  85. package/dist/memory/replay-reflection.js +149 -0
  86. package/dist/memory/replay-reflection.js.map +1 -0
  87. package/dist/memory/replay-review.d.ts +18 -12
  88. package/dist/memory/replay-review.d.ts.map +1 -1
  89. package/dist/memory/replay-review.js +107 -46
  90. package/dist/memory/replay-review.js.map +1 -1
  91. package/dist/memory/repository-learning.d.ts +106 -0
  92. package/dist/memory/repository-learning.d.ts.map +1 -0
  93. package/dist/memory/repository-learning.js +348 -0
  94. package/dist/memory/repository-learning.js.map +1 -0
  95. package/docs/agenticreplay-recording.md +20 -2
  96. package/docs/on-demand-intake.md +8 -2
  97. package/docs/repository-learning.md +109 -0
  98. package/migrations/048_repository_learning.sql +65 -0
  99. package/package.json +6 -1
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/dsh/host-adapter/lifecycle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAyB,MAAM,0BAA0B,CAAA;AAC1F,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AAE/F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAE9E,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAUhF,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAoB,MAAM,sBAAsB,CAAA;AAE7F,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;IAChC,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAA;IAC7C,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAA;IAC3C,QAAQ,CAAC,eAAe,EAAE,kBAAkB,CAAA;IAC5C,QAAQ,CAAC,UAAU,EAAE,2BAA2B,CAAA;IAChD,QAAQ,CAAC,YAAY,EAAE,uBAAuB,CAAA;IAC9C,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAA;IAC1C,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAA;IACzC,QAAQ,CAAC,gBAAgB,EAAE,mBAAmB,CAAA;IAC9C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;IACtD,QAAQ,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,wBAAwB,GAAG,SAAS,CAAA;IAC9E,QAAQ,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAA;IACtE,QAAQ,CAAC,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAA;IAC3J,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,KAAK,cAAc,CAAA;IACzE,QAAQ,CAAC,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChF,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,mBAAmB,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IACnJ,QAAQ,CAAC,eAAe,EAAE,OAAO,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;IAC7E,QAAQ,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,QAAQ,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,qBAAqB,CAAA;IACnF,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAA;IAChE,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAClF;AAYD,wBAAgB,eAAe,CAAC,IAAI,EAAE,qBAAqB;;gCAwBhB,MAAM,cAAc,MAAM,kBAAkB,MAAM,gBAAgB,MAAM,KAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;mCA4BjH;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,KAAG,MAAM,GAAG,SAAS;qCAK3B,MAAM,iBAAiB,MAAM,KAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;gCAwFxE,UAAU,UAAU,WAAW,GAAG,QAAQ,GAAG,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC;yCAkB/D,WAAW,CAAC,MAAM,CAAC,KAAG,OAAO,CAAC,OAAO,EAAE,CAAC;EA+C3F"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/dsh/host-adapter/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -1,33 +1,39 @@
1
- import { readTaskSnapshot } from '../task-state.js';
2
- import { dshTurnBoundarySeq } from '../session-memory-finalizer.js';
3
- import { withImmediateTransaction } from '../../db/transaction.js';
4
- import { LedgerStore } from '../../ledger/store.js';
5
- import { terminalizeLedgerRunInTransaction } from '../../enno-oduno/store.js';
6
- import { KiokukoError } from '../../errors.js';
7
- import { saveTaskCompletionReceipt, taskCompletionBlocksClose } from '../task-completion.js';
8
- import { readCodingWorkflow } from '../coding-workflow/store.js';
9
- import { stopCodingWorkflow, synchronizeCodingWorkflow } from '../coding-workflow/service.js';
10
- import { saveSessionNotice } from '../plugin-records.js';
11
- import { canonicalContentHash } from '../../serialization/validate.js';
12
- import { DshRunLifecycle } from '../session-bridge.js';
1
+ import { readTaskSnapshot, } from "../task-state.js";
2
+ import { dshTurnBoundarySeq } from "../session-memory-finalizer.js";
3
+ import { withImmediateTransaction } from "../../db/transaction.js";
4
+ import { LedgerStore } from "../../ledger/store.js";
5
+ import { terminalizeLedgerRunInTransaction } from "../../enno-oduno/store.js";
6
+ import { KiokukoError } from "../../errors.js";
7
+ import { saveTaskCompletionReceipt, taskCompletionBlocksClose, } from "../task-completion.js";
8
+ import { readCodingWorkflow } from "../coding-workflow/store.js";
9
+ import { stopCodingWorkflow, synchronizeCodingWorkflow, } from "../coding-workflow/service.js";
10
+ import { saveSessionNotice } from "../plugin-records.js";
11
+ import { canonicalContentHash } from "../../serialization/validate.js";
12
+ import { DshRunLifecycle, } from "../session-bridge.js";
13
13
  function currentCloseAuthority(database, runId, authority) {
14
14
  if (!authority)
15
- return database.prepare('SELECT task_managed FROM ledger_runs WHERE run_id=?').get(runId)?.task_managed !== 1;
15
+ return (database
16
+ .prepare("SELECT task_managed FROM ledger_runs WHERE run_id=?")
17
+ .get(runId)?.task_managed !== 1);
16
18
  if (authority.taskId !== runId)
17
19
  return false;
18
20
  try {
19
21
  const current = readTaskSnapshot(database, authority);
20
- return current.revision === authority.revision && current.generation === authority.generation && !current.pendingStop;
22
+ return (current.revision === authority.revision &&
23
+ current.generation === authority.generation &&
24
+ !current.pendingStop);
21
25
  }
22
26
  catch {
23
27
  return false;
24
28
  }
25
29
  }
26
- function closeAuthority(item) { return item.authority ? { authority: item.authority } : {}; }
30
+ function closeAuthority(item) {
31
+ return item.authority ? { authority: item.authority } : {};
32
+ }
27
33
  export function createLifecycle(deps) {
28
- const { runtime, sessions, sessionMirror, autoReview, answerReview, ennoController, ennoMemory, executionSupport, gate, turnState, currentSession, currentForAgentEvent, stateForRun, deliverCompletionReport, reviewBinding, clearToolRun, sessionEventSource } = deps;
34
+ const { runtime, sessions, sessionMirror, autoReview, answerReview, ennoController, ennoMemory, executionSupport, gate, turnState, currentSession, currentForAgentEvent, stateForRun, deliverCompletionReport, reviewBinding, clearToolRun, sessionEventSource, } = deps;
29
35
  const getSelection = deps.getSelection;
30
- const completionReady = async (item) => runtime.withDatabase(database => {
36
+ const completionReady = async (item) => runtime.withDatabase((database) => {
31
37
  if (!currentCloseAuthority(database, item.runId, item.authority))
32
38
  return false;
33
39
  try {
@@ -35,17 +41,28 @@ export function createLifecycle(deps) {
35
41
  const assessment = saveTaskCompletionReceipt(database, item.runId);
36
42
  if (!taskCompletionBlocksClose(assessment))
37
43
  return true;
38
- const unresolved = assessment.criteria.filter(criterion => criterion.state !== 'satisfied');
39
- const text = `完了条件の検証待ちです。未確認: ${unresolved.map(criterion => criterion.description).join(' / ').slice(0, 4000)}。task_completion status で根拠を確認し、検証方法を登録してください。`;
40
- saveSessionNotice(database, { id: `completion-wait:${canonicalContentHash({ runId: item.runId, unresolved })}`,
41
- runId: item.runId, sessionId: item.sessionId, rootPath: item.cwd, kind: 'status', text, anchorSeq: 0 });
44
+ const unresolved = assessment.criteria.filter((criterion) => criterion.state !== "satisfied");
45
+ const text = `完了条件の検証待ちです。未確認: ${unresolved
46
+ .map((criterion) => criterion.description)
47
+ .join(" / ")
48
+ .slice(0, 4000)}。task_completion status で根拠を確認し、検証方法を登録してください。`;
49
+ saveSessionNotice(database, {
50
+ id: `completion-wait:${canonicalContentHash({ runId: item.runId, unresolved })}`,
51
+ runId: item.runId,
52
+ sessionId: item.sessionId,
53
+ rootPath: item.cwd,
54
+ kind: "status",
55
+ text,
56
+ anchorSeq: 0,
57
+ });
42
58
  return false;
43
59
  }
44
60
  catch {
45
61
  // A missing or corrupt new completion assessment never grants an opted-in
46
62
  // enforce run a verified terminal state. Legacy/shadow close as before.
47
- return database.prepare('SELECT mode FROM dsh_completion_runs WHERE run_id = ?')
48
- .get(item.runId)?.mode !== 'enforce';
63
+ return (database
64
+ .prepare("SELECT mode FROM dsh_completion_runs WHERE run_id = ?")
65
+ .get(item.runId)?.mode !== "enforce");
49
66
  }
50
67
  });
51
68
  const resolveIdleClose = async (agentId, sessionId, nativeSession, nativeAgent) => {
@@ -53,34 +70,58 @@ export function createLifecycle(deps) {
53
70
  return undefined;
54
71
  await deliverCompletionReport(nativeSession);
55
72
  const item = currentForAgentEvent(agentId, sessionId, undefined, nativeSession, nativeAgent);
56
- if (item === undefined || item.closed || executionSupport.paused(item.sessionId))
73
+ if (item === undefined ||
74
+ item.closed ||
75
+ executionSupport.paused(item.sessionId))
57
76
  return undefined;
58
77
  if (nativeAgent && answerReview.hold(nativeAgent))
59
78
  return undefined;
60
79
  const selection = getSelection(item.runId)?.value;
61
80
  if (selection?.discussion)
62
81
  return undefined;
63
- if (selection && (selection.status !== 'ready' && item.prepared.intake.profile.taskType !== 'chat' || item.failed && selection.mode === 'normal'))
82
+ if (selection &&
83
+ ((selection.status !== "ready" &&
84
+ item.prepared.intake.profile.taskType !== "chat") ||
85
+ (item.failed && selection.mode === "normal")))
64
86
  return undefined;
65
87
  const state = await runtime.withDatabase((database) => stateForRun(database, item));
66
- const coding = await runtime.withDatabase(db => readCodingWorkflow(db, item.runId));
67
- if (coding?.state === 'cancelled' || coding?.state === 'superseded')
68
- return { ...closeAuthority(item), runId: item.runId, status: 'cancelled', terminalTurn: item.turn };
69
- if (state.status === 'cancelled')
70
- return { ...closeAuthority(item), runId: item.runId, status: 'cancelled' };
71
- if (state.status === 'blocked' || state.nextAction === 'report_blocker')
72
- return { ...closeAuthority(item), runId: item.runId, status: 'failed', terminalTurn: item.turn };
88
+ const coding = await runtime.withDatabase((db) => readCodingWorkflow(db, item.runId));
89
+ if (coding?.state === "cancelled" || coding?.state === "superseded")
90
+ return {
91
+ ...closeAuthority(item),
92
+ runId: item.runId,
93
+ status: "cancelled",
94
+ terminalTurn: item.turn,
95
+ };
96
+ if (state.status === "cancelled")
97
+ return {
98
+ ...closeAuthority(item),
99
+ runId: item.runId,
100
+ status: "cancelled",
101
+ };
102
+ if (state.status === "blocked" || state.nextAction === "report_blocker")
103
+ return {
104
+ ...closeAuthority(item),
105
+ runId: item.runId,
106
+ status: "failed",
107
+ terminalTurn: item.turn,
108
+ };
73
109
  // A chat run spans the quiet time between user messages. Enno's
74
110
  // inapplicable `complete` means that no orchestration is required for this
75
111
  // turn; it does not mean that the persistent conversation has ended.
76
- if (item.prepared.intake.profile.taskType === 'chat')
112
+ if (item.prepared.intake.profile.taskType === "chat")
77
113
  return undefined;
78
- if (state.status === 'completed' || state.nextAction === 'complete') {
79
- if (!await completionReady(item))
114
+ if (state.status === "completed" || state.nextAction === "complete") {
115
+ if (!(await completionReady(item)))
80
116
  return undefined;
81
117
  // A provider failure while wording the final response cannot undo
82
118
  // already verified completion. The durable host report covers it.
83
- return { ...closeAuthority(item), runId: item.runId, status: 'completed', terminalTurn: item.turn };
119
+ return {
120
+ ...closeAuthority(item),
121
+ runId: item.runId,
122
+ status: "completed",
123
+ terminalTurn: item.turn,
124
+ };
84
125
  }
85
126
  // Idle means the driver has no active work, not that Enno reached a
86
127
  // terminal state. Keep only genuinely resumable active states open.
@@ -95,65 +136,102 @@ export function createLifecycle(deps) {
95
136
  const resolveSessionClose = async (sessionId, nativeSession) => {
96
137
  answerReview.cancel(sessionId);
97
138
  const item = currentSession(sessionId);
98
- if (item === undefined || item.closed || item.nativeSession !== nativeSession)
139
+ if (item === undefined ||
140
+ item.closed ||
141
+ item.nativeSession !== nativeSession)
99
142
  return undefined;
100
- if (executionSupport.paused(item.sessionId) || getSelection(item.runId)?.value.status !== undefined && getSelection(item.runId)?.value.status !== 'ready') {
101
- const end = await sessionMirror.latestEvent(sessionId, 'turn/end', Number.MAX_SAFE_INTEGER);
143
+ if (executionSupport.paused(item.sessionId) ||
144
+ (getSelection(item.runId)?.value.status !== undefined &&
145
+ getSelection(item.runId)?.value.status !== "ready")) {
146
+ const end = await sessionMirror.latestEvent(sessionId, "turn/end", Number.MAX_SAFE_INTEGER);
102
147
  if (end)
103
- autoReview.notify(reviewBinding(item, nativeSession), end.seq, 'boundary');
148
+ autoReview.notify(reviewBinding(item, nativeSession), end.seq, "boundary");
104
149
  return undefined;
105
150
  }
106
151
  const state = await runtime.withDatabase((database) => stateForRun(database, item));
107
- if (state.status === 'completed') {
108
- if (!await completionReady(item))
152
+ if (state.status === "completed") {
153
+ if (!(await completionReady(item)))
109
154
  return undefined;
110
155
  await deliverCompletionReport(nativeSession);
111
- return { ...closeAuthority(item), runId: item.runId, status: 'completed', terminalTurn: item.turn };
156
+ return {
157
+ ...closeAuthority(item),
158
+ runId: item.runId,
159
+ status: "completed",
160
+ terminalTurn: item.turn,
161
+ };
112
162
  }
113
163
  if (item.failed)
114
- return { ...closeAuthority(item), runId: item.runId, status: 'failed', terminalTurn: item.turn };
115
- if (state.status === 'cancelled')
116
- return { ...closeAuthority(item), runId: item.runId, status: 'cancelled' };
117
- if (state.status === 'blocked' || state.nextAction === 'report_blocker')
118
- return { ...closeAuthority(item), runId: item.runId, status: 'failed', terminalTurn: item.turn };
119
- if (item.prepared.intake.profile.taskType === 'chat' || state.nextAction === 'complete') {
120
- if (item.prepared.intake.profile.taskType !== 'chat' && !await completionReady(item))
164
+ return {
165
+ ...closeAuthority(item),
166
+ runId: item.runId,
167
+ status: "failed",
168
+ terminalTurn: item.turn,
169
+ };
170
+ if (state.status === "cancelled")
171
+ return {
172
+ ...closeAuthority(item),
173
+ runId: item.runId,
174
+ status: "cancelled",
175
+ };
176
+ if (state.status === "blocked" || state.nextAction === "report_blocker")
177
+ return {
178
+ ...closeAuthority(item),
179
+ runId: item.runId,
180
+ status: "failed",
181
+ terminalTurn: item.turn,
182
+ };
183
+ if (item.prepared.intake.profile.taskType === "chat" ||
184
+ state.nextAction === "complete") {
185
+ if (item.prepared.intake.profile.taskType !== "chat" &&
186
+ !(await completionReady(item)))
121
187
  return undefined;
122
- return { ...closeAuthority(item), runId: item.runId, status: 'completed', terminalTurn: item.turn };
188
+ return {
189
+ ...closeAuthority(item),
190
+ runId: item.runId,
191
+ status: "completed",
192
+ terminalTurn: item.turn,
193
+ };
123
194
  }
124
- return { ...closeAuthority(item), runId: item.runId, status: 'cancelled' };
195
+ return { ...closeAuthority(item), runId: item.runId, status: "cancelled" };
125
196
  };
126
197
  const closeRun = async (input) => {
127
198
  let committedAuthority;
128
199
  const committed = await runtime.withDatabase((database) => withImmediateTransaction(database, () => {
129
200
  if (!currentCloseAuthority(database, input.runId, input.authority))
130
201
  return false;
131
- if (input.status === 'cancelled')
132
- stopCodingWorkflow(database, input.runId, 'cancelled');
202
+ if (input.status === "cancelled")
203
+ stopCodingWorkflow(database, input.runId, "cancelled");
133
204
  let completionBlocked;
134
205
  try {
135
206
  completionBlocked = taskCompletionBlocksClose(saveTaskCompletionReceipt(database, input.runId));
136
207
  }
137
208
  catch {
138
- completionBlocked = database.prepare('SELECT mode FROM dsh_completion_runs WHERE run_id=?').get(input.runId)?.mode === 'enforce';
209
+ completionBlocked =
210
+ database
211
+ .prepare("SELECT mode FROM dsh_completion_runs WHERE run_id=?")
212
+ .get(input.runId)?.mode === "enforce";
139
213
  }
140
- if (input.status === 'completed' && completionBlocked)
141
- throw new KiokukoError('CONFLICT', 'Required task completion evidence is unresolved');
214
+ if (input.status === "completed" && completionBlocked)
215
+ throw new KiokukoError("CONFLICT", "Required task completion evidence is unresolved");
142
216
  const store = new LedgerStore(database);
143
217
  const before = store.readRun(input.runId);
144
218
  if (before === undefined)
145
- throw new KiokukoError('INTEGRITY_ERROR', 'Run close target does not exist');
146
- if (before.status === 'intake' || before.status === 'active') {
219
+ throw new KiokukoError("INTEGRITY_ERROR", "Run close target does not exist");
220
+ if (before.status === "intake" || before.status === "active") {
147
221
  terminalizeLedgerRunInTransaction(database, input.runId, input.status);
148
222
  }
149
223
  else if (before.status !== input.status) {
150
- throw new KiokukoError('CONFLICT', 'Run close status is immutable');
224
+ throw new KiokukoError("CONFLICT", "Run close status is immutable");
151
225
  }
152
226
  // Native completion and authority have been checked independently.
153
227
  // A missing optional memory range cannot change the observed task outcome.
154
228
  if (input.authority) {
155
229
  const closed = readTaskSnapshot(database, input.authority);
156
- committedAuthority = { ...input.authority, revision: closed.revision, generation: closed.generation };
230
+ committedAuthority = {
231
+ ...input.authority,
232
+ revision: closed.revision,
233
+ generation: closed.generation,
234
+ };
157
235
  }
158
236
  return true;
159
237
  }));
@@ -162,31 +240,50 @@ export function createLifecycle(deps) {
162
240
  const reviewFinishes = [];
163
241
  // The DB callback may resume after another client reopened this same run.
164
242
  // Run-wide caches must be retired atomically with a fresh generation check.
165
- await runtime.withDatabase(database => {
243
+ await runtime.withDatabase((database) => {
166
244
  if (!currentCloseAuthority(database, input.runId, committedAuthority))
167
245
  return;
168
246
  try {
169
247
  autoReview.worker.abort(input.runId);
170
248
  }
171
- catch { /* Optional memory cleanup cannot retain a task owner. */ }
172
- const items = turnState.allTurns().filter(candidate => candidate.runId === input.runId
173
- && (!input.authority || candidate.authority?.sessionId === input.authority.sessionId && candidate.authority.generation === input.authority.generation));
249
+ catch {
250
+ /* Optional memory cleanup cannot retain a task owner. */
251
+ }
252
+ const items = turnState
253
+ .allTurns()
254
+ .filter((candidate) => candidate.runId === input.runId &&
255
+ (!input.authority ||
256
+ (candidate.authority?.sessionId === input.authority.sessionId &&
257
+ candidate.authority.generation === input.authority.generation)));
174
258
  const committedSessionId = items[0]?.sessionId;
175
259
  if (committedSessionId)
176
260
  try {
177
- deps.onRunClosed?.(input.runId, input.status, committedSessionId);
261
+ deps.onRunClosed?.(input.runId, input.status, committedSessionId, committedAuthority &&
262
+ readTaskSnapshot(database, committedAuthority).state === "Done"
263
+ ? committedAuthority
264
+ : undefined);
265
+ }
266
+ catch {
267
+ /* optional memory observation */
178
268
  }
179
- catch { /* optional memory observation */ }
180
269
  for (const item of items) {
181
- ennoController.retire({ ...(item.nativeAgent === undefined ? {} : { nativeAgent: item.nativeAgent }),
182
- ...(item.nativeSession === undefined ? {} : { nativeSession: item.nativeSession }) });
270
+ ennoController.retire({
271
+ ...(item.nativeAgent === undefined
272
+ ? {}
273
+ : { nativeAgent: item.nativeAgent }),
274
+ ...(item.nativeSession === undefined
275
+ ? {}
276
+ : { nativeSession: item.nativeSession }),
277
+ });
183
278
  if (item.nativeAgent)
184
279
  reviewFinishes.push(answerReview.finish(item.nativeAgent));
185
280
  item.closed = true;
186
281
  try {
187
282
  ennoMemory.clear(item.runId);
188
283
  }
189
- catch { /* Optional memory cleanup cannot retain a task owner. */ }
284
+ catch {
285
+ /* Optional memory cleanup cannot retain a task owner. */
286
+ }
190
287
  executionSupport.clear(item.sessionId);
191
288
  gate.clearTurn(item.sessionId, item.turn);
192
289
  }
@@ -196,9 +293,72 @@ export function createLifecycle(deps) {
196
293
  await Promise.all(reviewFinishes);
197
294
  };
198
295
  const runLifecycle = new DshRunLifecycle({ closeRun });
296
+ const completeTask = async (task) => {
297
+ const authority = await runtime.withDatabase((database) => {
298
+ const current = readTaskSnapshot(database, task);
299
+ if (current.state !== "Done" ||
300
+ task.state !== "Done" ||
301
+ current.pendingStop ||
302
+ current.revision !== task.revision ||
303
+ current.generation !== task.generation)
304
+ return undefined;
305
+ const item = currentSession(task.sessionId);
306
+ const agent = item?.nativeAgent;
307
+ if (!item ||
308
+ item.closed ||
309
+ item.runId !== task.taskId ||
310
+ item.sessionId !== task.sessionId ||
311
+ item.repositoryRoot !== task.repositoryRoot ||
312
+ !agent ||
313
+ agent.status !== "idle" ||
314
+ agent.session !== item.nativeSession ||
315
+ sessions?.get(task.sessionId) !== item.nativeSession ||
316
+ currentForAgentEvent(item.agentId, item.sessionId, undefined, item.nativeSession, agent) !== item)
317
+ return undefined;
318
+ const matches = (candidate) => {
319
+ const prior = candidate.authority;
320
+ return (candidate.runId === task.taskId &&
321
+ candidate.sessionId === task.sessionId &&
322
+ candidate.repositoryRoot === task.repositoryRoot &&
323
+ candidate.nativeAgent === agent &&
324
+ candidate.nativeSession === item.nativeSession &&
325
+ !!prior &&
326
+ prior.taskId === task.taskId &&
327
+ prior.sessionId === task.sessionId &&
328
+ prior.repositoryRoot === task.repositoryRoot &&
329
+ ((prior.revision === task.revision &&
330
+ prior.generation === task.generation) ||
331
+ (prior.revision + 1 === task.revision &&
332
+ prior.generation + 1 === task.generation)));
333
+ };
334
+ if (!matches(item))
335
+ return undefined;
336
+ const next = {
337
+ taskId: task.taskId,
338
+ sessionId: task.sessionId,
339
+ repositoryRoot: task.repositoryRoot,
340
+ revision: task.revision,
341
+ generation: task.generation,
342
+ };
343
+ // Explicit completion advances the task lease before the final native answer.
344
+ // Reconcile only its exact projection; closeRun independently rechecks it.
345
+ for (const candidate of turnState.allTurns())
346
+ if (matches(candidate))
347
+ candidate.authority = next;
348
+ return next;
349
+ });
350
+ if (authority)
351
+ await runLifecycle.closeTurn({
352
+ runId: task.taskId,
353
+ status: "completed",
354
+ authority,
355
+ });
356
+ };
199
357
  const optionalSourceBoundary = (item) => {
200
358
  try {
201
- return { sourceEndSeq: dshTurnBoundarySeq(sessionEventSource(item.nativeSession), item.turn, 'end') };
359
+ return {
360
+ sourceEndSeq: dshTurnBoundarySeq(sessionEventSource(item.nativeSession), item.turn, "end"),
361
+ };
202
362
  }
203
363
  catch {
204
364
  return {}; /* Incomplete source evidence stays unavailable to memory. */
@@ -212,7 +372,9 @@ export function createLifecycle(deps) {
212
372
  try {
213
373
  await sessionMirror.checkpointAfterNativeFlush(item.nativeSession);
214
374
  }
215
- catch { /* Optional mirror cannot veto native task closure. */ }
375
+ catch {
376
+ /* Optional mirror cannot veto native task closure. */
377
+ }
216
378
  return optionalSourceBoundary(item);
217
379
  }
218
380
  catch {
@@ -220,71 +382,97 @@ export function createLifecycle(deps) {
220
382
  }
221
383
  };
222
384
  const retireSupersededRun = async (item, status) => {
223
- if (status === 'completed' && !await completionReady(item))
224
- status = 'cancelled';
225
- if (status !== 'completed') {
226
- await runLifecycle.closeTurn({ ...closeAuthority(item), runId: item.runId, status, ...(status === 'failed' ? await failedBoundary(item) : {}) });
385
+ if (status === "completed" && !(await completionReady(item)))
386
+ status = "cancelled";
387
+ if (status !== "completed") {
388
+ await runLifecycle.closeTurn({
389
+ ...closeAuthority(item),
390
+ runId: item.runId,
391
+ status,
392
+ ...(status === "failed" ? await failedBoundary(item) : {}),
393
+ });
227
394
  return;
228
395
  }
229
396
  if (item.nativeSession === undefined || sessions?.flush === undefined) {
230
- throw new KiokukoError('CONFLICT', 'Completed DSH run requires its exact native session checkpoint');
397
+ throw new KiokukoError("CONFLICT", "Completed DSH run requires its exact native session checkpoint");
231
398
  }
232
399
  await sessions.flush(item.nativeSession);
233
400
  try {
234
401
  await sessionMirror.checkpointAfterNativeFlush(item.nativeSession);
235
402
  }
236
- catch { /* Optional mirror cannot veto native task closure. */ }
403
+ catch {
404
+ /* Optional mirror cannot veto native task closure. */
405
+ }
237
406
  await runLifecycle.closeTurn({
238
- ...closeAuthority(item), runId: item.runId,
407
+ ...closeAuthority(item),
408
+ runId: item.runId,
239
409
  status,
240
410
  ...optionalSourceBoundary(item),
241
411
  });
242
412
  };
243
413
  const closeRemainingRuns = async (pausedSessions) => {
244
414
  const failures = [];
245
- const remainingRuns = [...new Map(turnState.allTurns()
415
+ const remainingRuns = [
416
+ ...new Map(turnState
417
+ .allTurns()
246
418
  .filter((item) => !item.closed && !pausedSessions.has(item.sessionId))
247
- .map((item) => [item.runId, item])).values()];
419
+ .map((item) => [item.runId, item])).values(),
420
+ ];
248
421
  for (const item of remainingRuns) {
249
422
  try {
250
423
  const selected = getSelection(item.runId)?.value;
251
424
  if (selected) {
252
- const state = await runtime.withDatabase(db => stateForRun(db, item));
253
- if (selected.status !== 'ready'
254
- || selected.mode === 'enno' && !['completed', 'blocked', 'cancelled'].includes(state.status ?? '')
255
- || selected.mode === 'normal' && (item.failed || item.nativeAgent?.status === 'running'))
425
+ const state = await runtime.withDatabase((db) => stateForRun(db, item));
426
+ if (selected.status !== "ready" ||
427
+ (selected.mode === "enno" &&
428
+ !["completed", "blocked", "cancelled"].includes(state.status ?? "")) ||
429
+ (selected.mode === "normal" &&
430
+ (item.failed ||
431
+ item.nativeAgent?.status ===
432
+ "running")))
256
433
  continue;
257
434
  }
258
435
  let status;
259
- if (item.prepared.intake.profile.taskType === 'chat')
260
- status = item.failed ? 'failed' : 'cancelled';
436
+ if (item.prepared.intake.profile.taskType === "chat")
437
+ status = item.failed ? "failed" : "cancelled";
261
438
  else {
262
439
  const state = await runtime.withDatabase((database) => stateForRun(database, item));
263
- status = state.status === 'completed' || state.nextAction === 'complete'
264
- ? 'completed'
265
- : item.failed || state.status === 'blocked' || state.nextAction === 'report_blocker'
266
- ? 'failed'
267
- : 'cancelled';
440
+ status =
441
+ state.status === "completed" || state.nextAction === "complete"
442
+ ? "completed"
443
+ : item.failed ||
444
+ state.status === "blocked" ||
445
+ state.nextAction === "report_blocker"
446
+ ? "failed"
447
+ : "cancelled";
268
448
  }
269
- if (status === 'completed') {
270
- if (!await completionReady(item))
449
+ if (status === "completed") {
450
+ if (!(await completionReady(item)))
271
451
  continue;
272
452
  await deliverCompletionReport(item.nativeSession);
273
- if (item.nativeSession === undefined || sessions?.flush === undefined) {
274
- throw new KiokukoError('CONFLICT', 'Completed DSH run requires its exact native session checkpoint');
453
+ if (item.nativeSession === undefined ||
454
+ sessions?.flush === undefined) {
455
+ throw new KiokukoError("CONFLICT", "Completed DSH run requires its exact native session checkpoint");
275
456
  }
276
457
  await sessions.flush(item.nativeSession);
277
458
  try {
278
459
  await sessionMirror.checkpointAfterNativeFlush(item.nativeSession);
279
460
  }
280
- catch { /* Optional mirror cannot veto native task closure. */ }
461
+ catch {
462
+ /* Optional mirror cannot veto native task closure. */
463
+ }
281
464
  }
282
465
  await runLifecycle.closeTurn({
283
- ...closeAuthority(item), runId: item.runId,
466
+ ...closeAuthority(item),
467
+ runId: item.runId,
284
468
  status,
285
- ...(status !== 'completed' ? status === 'failed' ? await failedBoundary(item) : {} : {
286
- ...optionalSourceBoundary(item),
287
- }),
469
+ ...(status !== "completed"
470
+ ? status === "failed"
471
+ ? await failedBoundary(item)
472
+ : {}
473
+ : {
474
+ ...optionalSourceBoundary(item),
475
+ }),
288
476
  });
289
477
  }
290
478
  catch (error) {
@@ -293,6 +481,14 @@ export function createLifecycle(deps) {
293
481
  }
294
482
  return failures;
295
483
  };
296
- return { runLifecycle, resolveIdleClose, resolveSessionRunId, resolveSessionClose, retireSupersededRun, closeRemainingRuns };
484
+ return {
485
+ runLifecycle,
486
+ completeTask,
487
+ resolveIdleClose,
488
+ resolveSessionRunId,
489
+ resolveSessionClose,
490
+ retireSupersededRun,
491
+ closeRemainingRuns,
492
+ };
297
493
  }
298
494
  //# sourceMappingURL=lifecycle.js.map