instar 0.28.83 → 0.28.84

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 (83) hide show
  1. package/dashboard/index.html +239 -0
  2. package/dist/cli.js +10 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/memoryBackfillEvidence.d.ts +69 -0
  5. package/dist/commands/memoryBackfillEvidence.d.ts.map +1 -0
  6. package/dist/commands/memoryBackfillEvidence.js +220 -0
  7. package/dist/commands/memoryBackfillEvidence.js.map +1 -0
  8. package/dist/commands/server.d.ts.map +1 -1
  9. package/dist/commands/server.js +72 -1
  10. package/dist/commands/server.js.map +1 -1
  11. package/dist/core/EvolutionManager.d.ts +73 -0
  12. package/dist/core/EvolutionManager.d.ts.map +1 -1
  13. package/dist/core/EvolutionManager.js +376 -0
  14. package/dist/core/EvolutionManager.js.map +1 -1
  15. package/dist/core/SharedStateLedger.d.ts.map +1 -1
  16. package/dist/core/SharedStateLedger.js +4 -0
  17. package/dist/core/SharedStateLedger.js.map +1 -1
  18. package/dist/core/types.d.ts +90 -1
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/core/types.js +8 -0
  21. package/dist/core/types.js.map +1 -1
  22. package/dist/memory/EvidenceRenderer.d.ts +64 -0
  23. package/dist/memory/EvidenceRenderer.d.ts.map +1 -0
  24. package/dist/memory/EvidenceRenderer.js +119 -0
  25. package/dist/memory/EvidenceRenderer.js.map +1 -0
  26. package/dist/memory/SemanticMemory.d.ts +61 -1
  27. package/dist/memory/SemanticMemory.d.ts.map +1 -1
  28. package/dist/memory/SemanticMemory.js +381 -11
  29. package/dist/memory/SemanticMemory.js.map +1 -1
  30. package/dist/server/AgentServer.d.ts +4 -0
  31. package/dist/server/AgentServer.d.ts.map +1 -1
  32. package/dist/server/AgentServer.js +2 -0
  33. package/dist/server/AgentServer.js.map +1 -1
  34. package/dist/server/routes.d.ts +8 -0
  35. package/dist/server/routes.d.ts.map +1 -1
  36. package/dist/server/routes.js +369 -0
  37. package/dist/server/routes.js.map +1 -1
  38. package/dist/tasks/DivergenceChecker.d.ts +89 -0
  39. package/dist/tasks/DivergenceChecker.d.ts.map +1 -0
  40. package/dist/tasks/DivergenceChecker.js +255 -0
  41. package/dist/tasks/DivergenceChecker.js.map +1 -0
  42. package/dist/tasks/LruCache.d.ts +33 -0
  43. package/dist/tasks/LruCache.d.ts.map +1 -0
  44. package/dist/tasks/LruCache.js +88 -0
  45. package/dist/tasks/LruCache.js.map +1 -0
  46. package/dist/tasks/RateLimiter.d.ts +61 -0
  47. package/dist/tasks/RateLimiter.d.ts.map +1 -0
  48. package/dist/tasks/RateLimiter.js +108 -0
  49. package/dist/tasks/RateLimiter.js.map +1 -0
  50. package/dist/tasks/TaskFlowDueWaker.d.ts +29 -0
  51. package/dist/tasks/TaskFlowDueWaker.d.ts.map +1 -0
  52. package/dist/tasks/TaskFlowDueWaker.js +73 -0
  53. package/dist/tasks/TaskFlowDueWaker.js.map +1 -0
  54. package/dist/tasks/TaskFlowMaintenanceSweeper.d.ts +40 -0
  55. package/dist/tasks/TaskFlowMaintenanceSweeper.d.ts.map +1 -0
  56. package/dist/tasks/TaskFlowMaintenanceSweeper.js +131 -0
  57. package/dist/tasks/TaskFlowMaintenanceSweeper.js.map +1 -0
  58. package/dist/tasks/TaskFlowRegistry.d.ts +180 -0
  59. package/dist/tasks/TaskFlowRegistry.d.ts.map +1 -0
  60. package/dist/tasks/TaskFlowRegistry.js +791 -0
  61. package/dist/tasks/TaskFlowRegistry.js.map +1 -0
  62. package/dist/tasks/ThreadlineFlowBridge.d.ts +54 -0
  63. package/dist/tasks/ThreadlineFlowBridge.d.ts.map +1 -0
  64. package/dist/tasks/ThreadlineFlowBridge.js +129 -0
  65. package/dist/tasks/ThreadlineFlowBridge.js.map +1 -0
  66. package/dist/tasks/task-flow-registry.store.sqlite.d.ts +77 -0
  67. package/dist/tasks/task-flow-registry.store.sqlite.d.ts.map +1 -0
  68. package/dist/tasks/task-flow-registry.store.sqlite.js +350 -0
  69. package/dist/tasks/task-flow-registry.store.sqlite.js.map +1 -0
  70. package/dist/tasks/task-flow-types.d.ts +229 -0
  71. package/dist/tasks/task-flow-types.d.ts.map +1 -0
  72. package/dist/tasks/task-flow-types.js +128 -0
  73. package/dist/tasks/task-flow-types.js.map +1 -0
  74. package/package.json +1 -1
  75. package/src/data/builtin-manifest.json +78 -78
  76. package/upgrades/0.28.84.md +89 -0
  77. package/upgrades/side-effects/taskflow-phase1.md +130 -0
  78. package/upgrades/side-effects/taskflow-phase2.md +110 -0
  79. package/upgrades/side-effects/taskflow-phase3a.md +138 -0
  80. package/upgrades/side-effects/taskflow-phase5.md +234 -0
  81. package/upgrades/side-effects/wikiclaim-evidence-phase1.md +138 -0
  82. package/upgrades/side-effects/wikiclaim-evidence-phase4.md +129 -0
  83. package/upgrades/side-effects/wikiclaim-evidence-phase5.md +285 -0
@@ -18,6 +18,7 @@ import type { EvolutionProposal, EvolutionType, EvolutionStatus, LearningEntry,
18
18
  import type { TrustElevationTracker } from './TrustElevationTracker.js';
19
19
  import type { AutonomousEvolution, ReviewResult } from './AutonomousEvolution.js';
20
20
  import type { AutonomyProfileManager } from './AutonomyProfileManager.js';
21
+ import type { TaskFlowRegistry } from '../tasks/TaskFlowRegistry.js';
21
22
  interface EvolutionState {
22
23
  proposals: EvolutionProposal[];
23
24
  stats: {
@@ -63,7 +64,79 @@ export declare class EvolutionManager {
63
64
  private trustElevationTracker;
64
65
  private autonomousEvolution;
65
66
  private autonomyManager;
67
+ /** Registry handle (set when TaskFlow is enabled). */
68
+ private taskFlowRegistry;
69
+ /** Per-process controller-instance id (server uuid). */
70
+ private taskFlowControllerInstanceId;
71
+ /**
72
+ * Set to true by DivergenceChecker when state-divergence is detected.
73
+ * When true, EvolutionManager continues JSON-only writes and DOES NOT
74
+ * dual-write to TaskFlow. The signal is reset on next divergence pass that
75
+ * reports zero divergence. This is a signal-emitted brake, not a hard gate.
76
+ */
77
+ private taskFlowShadowWritesHalted;
78
+ /** Most recent reason for halting; surfaced in /health and tests. */
79
+ private taskFlowShadowWritesHaltReason;
80
+ /**
81
+ * Source of the most recent halt. DivergenceChecker uses this to ensure it
82
+ * only auto-clears halts that DivergenceChecker itself imposed — an operator
83
+ * or sibling system's manual halt stays in place until that source clears it.
84
+ */
85
+ private taskFlowShadowWritesHaltSource;
66
86
  constructor(config: EvolutionManagerConfig);
87
+ /**
88
+ * Wire a TaskFlow registry for Phase 3a dual-write. After this call:
89
+ * - addProposal / updateProposalStatus shadow-write to TaskFlow
90
+ * - migrateExistingToTaskFlow() backfills any in-flight clusters
91
+ * - DivergenceChecker can call setShadowWritesHalted() to brake writes
92
+ *
93
+ * Idempotent — safe to call multiple times; subsequent calls overwrite.
94
+ */
95
+ setTaskFlowRegistry(registry: TaskFlowRegistry, controllerInstanceId: string): void;
96
+ getTaskFlowRegistry(): TaskFlowRegistry | null;
97
+ /**
98
+ * Halt or resume TaskFlow shadow-writes. Called by DivergenceChecker on a
99
+ * mismatch. Signal-vs-authority compliance: this is a signal-consumed brake,
100
+ * not a brittle blocker — the divergence checker decides, EvolutionManager
101
+ * obeys. JSON writes continue regardless (read-authoritative TaskFlow is
102
+ * shadow-mode in Phase 3a).
103
+ *
104
+ * The optional `source` parameter tags the halt with its origin so an
105
+ * automatic clearer (DivergenceChecker) only cancels halts it caused.
106
+ * Defaults to `'manual'` when omitted.
107
+ */
108
+ setShadowWritesHalted(halted: boolean, reason?: string, source?: string): void;
109
+ isShadowWritesHalted(): {
110
+ halted: boolean;
111
+ reason: string | null;
112
+ source: string | null;
113
+ };
114
+ private taskFlowPrincipal;
115
+ /**
116
+ * Best-effort dual-write to TaskFlow. NEVER throws to the caller — JSON
117
+ * remains the local durability path; TaskFlow is shadow until Phase 3b
118
+ * cutover. All TaskFlow errors land in console and the divergence checker
119
+ * picks up via state comparison.
120
+ */
121
+ private dualWriteCreate;
122
+ private dualWriteTransition;
123
+ private logTaskFlowError;
124
+ /**
125
+ * Backfill all in-flight proposals (status !== 'implemented' && !== 'rejected')
126
+ * into TaskFlow. Idempotent via `findIdempotent` on
127
+ * `evolution:cluster:<proposalId>` ownerKey. Safe to call multiple times.
128
+ *
129
+ * Returns counts: created, alreadyExisted, advanced (transitioned beyond
130
+ * 'queued' to match the proposal's current status).
131
+ */
132
+ migrateExistingToTaskFlow(): Promise<{
133
+ created: number;
134
+ alreadyExisted: number;
135
+ advanced: number;
136
+ skipped: number;
137
+ }>;
138
+ /** Catch a flow record up to the proposal's current status. */
139
+ private catchUpFlowToStatus;
67
140
  /**
68
141
  * Wire adaptive autonomy modules for runtime integration.
69
142
  * - TrustElevationTracker: receives proposal approval/rejection events
@@ -1 +1 @@
1
- {"version":3,"file":"EvolutionManager.d.ts","sourceRoot":"","sources":["../../src/core/EvolutionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EvolutionManager.d.ts","sourceRoot":"","sources":["../../src/core/EvolutionManager.ts"],"names":[],"mappings":"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"}
@@ -17,16 +17,386 @@
17
17
  import fs from 'node:fs';
18
18
  import path from 'node:path';
19
19
  import { SafeFsExecutor } from './SafeFsExecutor.js';
20
+ import { TaskFlowError } from '../tasks/task-flow-types.js';
21
+ /**
22
+ * TaskFlow controller identity for EvolutionManager (Phase 3a dual-write).
23
+ * Every proposal's flow is owned by this controllerId; the registry uses it
24
+ * for OCC scope checks. Single-instance per server process.
25
+ */
26
+ const EVOLUTION_TASKFLOW_CONTROLLER_ID = 'EvolutionManager';
27
+ function statusToFlowAction(prev, next, resolution) {
28
+ // Initial create-from-proposed is handled in addProposal directly.
29
+ if (prev === null && next === 'proposed')
30
+ return { kind: 'create' };
31
+ if (prev === next)
32
+ return { kind: 'noop' };
33
+ switch (next) {
34
+ case 'approved':
35
+ return { kind: 'start', step: 'approved' };
36
+ case 'in_progress':
37
+ return { kind: 'start', step: 'in_progress' };
38
+ case 'implemented':
39
+ return { kind: 'finish' };
40
+ case 'rejected':
41
+ return { kind: 'fail', reason: resolution ?? 'rejected' };
42
+ case 'deferred':
43
+ return { kind: 'cancel', reason: resolution ?? 'deferred' };
44
+ case 'proposed':
45
+ // Re-opening is not a legal transition; treat as no-op for v1.
46
+ return { kind: 'noop' };
47
+ default:
48
+ return { kind: 'noop' };
49
+ }
50
+ }
51
+ /**
52
+ * Owner-key for a proposal-flow. Deterministic — used as both the TaskFlow
53
+ * `ownerKey` and the basis of the `idempotencyKey`. Phase 3b's cutover
54
+ * gate relies on `evolution:cluster:<id>` being a stable bidirectional join.
55
+ */
56
+ function ownerKeyForProposal(proposalId) {
57
+ return `evolution:cluster:${proposalId}`;
58
+ }
20
59
  export class EvolutionManager {
21
60
  stateDir;
22
61
  config;
23
62
  trustElevationTracker = null;
24
63
  autonomousEvolution = null;
25
64
  autonomyManager = null;
65
+ // ── TaskFlow Phase 3a dual-write fields ──────────────────────────
66
+ /** Registry handle (set when TaskFlow is enabled). */
67
+ taskFlowRegistry = null;
68
+ /** Per-process controller-instance id (server uuid). */
69
+ taskFlowControllerInstanceId = null;
70
+ /**
71
+ * Set to true by DivergenceChecker when state-divergence is detected.
72
+ * When true, EvolutionManager continues JSON-only writes and DOES NOT
73
+ * dual-write to TaskFlow. The signal is reset on next divergence pass that
74
+ * reports zero divergence. This is a signal-emitted brake, not a hard gate.
75
+ */
76
+ taskFlowShadowWritesHalted = false;
77
+ /** Most recent reason for halting; surfaced in /health and tests. */
78
+ taskFlowShadowWritesHaltReason = null;
79
+ /**
80
+ * Source of the most recent halt. DivergenceChecker uses this to ensure it
81
+ * only auto-clears halts that DivergenceChecker itself imposed — an operator
82
+ * or sibling system's manual halt stays in place until that source clears it.
83
+ */
84
+ taskFlowShadowWritesHaltSource = null;
26
85
  constructor(config) {
27
86
  this.config = config;
28
87
  this.stateDir = config.stateDir;
29
88
  }
89
+ // ── TaskFlow wiring ─────────────────────────────────────────────
90
+ /**
91
+ * Wire a TaskFlow registry for Phase 3a dual-write. After this call:
92
+ * - addProposal / updateProposalStatus shadow-write to TaskFlow
93
+ * - migrateExistingToTaskFlow() backfills any in-flight clusters
94
+ * - DivergenceChecker can call setShadowWritesHalted() to brake writes
95
+ *
96
+ * Idempotent — safe to call multiple times; subsequent calls overwrite.
97
+ */
98
+ setTaskFlowRegistry(registry, controllerInstanceId) {
99
+ this.taskFlowRegistry = registry;
100
+ this.taskFlowControllerInstanceId = controllerInstanceId;
101
+ }
102
+ getTaskFlowRegistry() {
103
+ return this.taskFlowRegistry;
104
+ }
105
+ /**
106
+ * Halt or resume TaskFlow shadow-writes. Called by DivergenceChecker on a
107
+ * mismatch. Signal-vs-authority compliance: this is a signal-consumed brake,
108
+ * not a brittle blocker — the divergence checker decides, EvolutionManager
109
+ * obeys. JSON writes continue regardless (read-authoritative TaskFlow is
110
+ * shadow-mode in Phase 3a).
111
+ *
112
+ * The optional `source` parameter tags the halt with its origin so an
113
+ * automatic clearer (DivergenceChecker) only cancels halts it caused.
114
+ * Defaults to `'manual'` when omitted.
115
+ */
116
+ setShadowWritesHalted(halted, reason, source) {
117
+ this.taskFlowShadowWritesHalted = halted;
118
+ this.taskFlowShadowWritesHaltReason = halted ? (reason ?? 'divergence-detected') : null;
119
+ this.taskFlowShadowWritesHaltSource = halted ? (source ?? 'manual') : null;
120
+ }
121
+ isShadowWritesHalted() {
122
+ return {
123
+ halted: this.taskFlowShadowWritesHalted,
124
+ reason: this.taskFlowShadowWritesHaltReason,
125
+ source: this.taskFlowShadowWritesHaltSource,
126
+ };
127
+ }
128
+ taskFlowPrincipal() {
129
+ if (!this.taskFlowRegistry || !this.taskFlowControllerInstanceId)
130
+ return null;
131
+ return {
132
+ scope: 'controller',
133
+ controllerId: EVOLUTION_TASKFLOW_CONTROLLER_ID,
134
+ controllerInstanceId: this.taskFlowControllerInstanceId,
135
+ };
136
+ }
137
+ /**
138
+ * Best-effort dual-write to TaskFlow. NEVER throws to the caller — JSON
139
+ * remains the local durability path; TaskFlow is shadow until Phase 3b
140
+ * cutover. All TaskFlow errors land in console and the divergence checker
141
+ * picks up via state comparison.
142
+ */
143
+ async dualWriteCreate(p) {
144
+ if (!this.taskFlowRegistry || this.taskFlowShadowWritesHalted)
145
+ return;
146
+ const principal = this.taskFlowPrincipal();
147
+ if (!principal || principal.scope !== 'controller')
148
+ return;
149
+ try {
150
+ await this.taskFlowRegistry.createFlow({
151
+ controllerId: EVOLUTION_TASKFLOW_CONTROLLER_ID,
152
+ controllerInstanceId: principal.controllerInstanceId,
153
+ ownerKey: ownerKeyForProposal(p.id),
154
+ idempotencyKey: `evolution-cluster-create-${p.id}`,
155
+ goal: p.title.slice(0, 1024),
156
+ currentStep: 'proposed',
157
+ stateJson: { proposalId: p.id, type: p.type, source: p.source },
158
+ });
159
+ }
160
+ catch (err) {
161
+ // Swallow — JSON is the source of truth in Phase 3a.
162
+ this.logTaskFlowError('createFlow', p.id, err);
163
+ }
164
+ }
165
+ async dualWriteTransition(proposalId, action) {
166
+ if (!this.taskFlowRegistry || this.taskFlowShadowWritesHalted)
167
+ return;
168
+ if (action.kind === 'noop' || action.kind === 'create')
169
+ return;
170
+ const principal = this.taskFlowPrincipal();
171
+ if (!principal)
172
+ return;
173
+ const registry = this.taskFlowRegistry;
174
+ try {
175
+ // Look up current flow by owner key + deterministic idempotency key.
176
+ const existing = registry.findByIdempotency(EVOLUTION_TASKFLOW_CONTROLLER_ID, ownerKeyForProposal(proposalId), `evolution-cluster-create-${proposalId}`);
177
+ if (!existing) {
178
+ // No backfill yet — proposal exists in JSON but not TaskFlow. Skip
179
+ // the transition silently; the next migrate-existing pass will pick
180
+ // it up at its terminal state.
181
+ return;
182
+ }
183
+ const flow = registry.getFlow(existing.flowId, { bypassCache: true });
184
+ if (!flow)
185
+ return;
186
+ const expectedRevision = flow.revision;
187
+ switch (action.kind) {
188
+ case 'start': {
189
+ if (flow.status !== 'queued' && flow.status !== 'running')
190
+ return;
191
+ await registry.startStep({
192
+ flowId: flow.flowId,
193
+ expectedRevision,
194
+ principal,
195
+ currentStep: action.step,
196
+ });
197
+ break;
198
+ }
199
+ case 'finish': {
200
+ // Need flow in `running` state for finishFlow. If currently queued,
201
+ // promote first.
202
+ let rev = expectedRevision;
203
+ let cur = flow;
204
+ if (cur.status === 'queued') {
205
+ const r = await registry.startStep({
206
+ flowId: flow.flowId,
207
+ expectedRevision: rev,
208
+ principal,
209
+ currentStep: 'implementing',
210
+ });
211
+ cur = r.flow;
212
+ rev = r.flow.revision;
213
+ }
214
+ if (cur.status !== 'running')
215
+ return;
216
+ await registry.finishFlow({
217
+ flowId: flow.flowId,
218
+ expectedRevision: rev,
219
+ principal,
220
+ });
221
+ break;
222
+ }
223
+ case 'fail': {
224
+ let rev = expectedRevision;
225
+ let cur = flow;
226
+ // failFlow requires running|waiting. Promote queued → running.
227
+ if (cur.status === 'queued') {
228
+ const r = await registry.startStep({
229
+ flowId: flow.flowId,
230
+ expectedRevision: rev,
231
+ principal,
232
+ currentStep: 'reject-transition',
233
+ });
234
+ cur = r.flow;
235
+ rev = r.flow.revision;
236
+ }
237
+ if (cur.status !== 'running' && cur.status !== 'waiting')
238
+ return;
239
+ await registry.failFlow({
240
+ flowId: flow.flowId,
241
+ expectedRevision: rev,
242
+ principal,
243
+ failureReason: action.reason,
244
+ });
245
+ break;
246
+ }
247
+ case 'cancel': {
248
+ if (flow.status === 'succeeded' || flow.status === 'failed' ||
249
+ flow.status === 'cancelled' || flow.status === 'lost')
250
+ return;
251
+ // Two-phase: request, then cancel.
252
+ const r = await registry.requestFlowCancel({
253
+ flowId: flow.flowId,
254
+ expectedRevision,
255
+ requesterOrigin: { kind: 'system', id: 'EvolutionManager' },
256
+ });
257
+ await registry.cancelFlow({
258
+ flowId: flow.flowId,
259
+ expectedRevision: r.flow.revision,
260
+ principal,
261
+ });
262
+ break;
263
+ }
264
+ }
265
+ }
266
+ catch (err) {
267
+ this.logTaskFlowError(`transition:${action.kind}`, proposalId, err);
268
+ }
269
+ }
270
+ logTaskFlowError(op, proposalId, err) {
271
+ if (err instanceof TaskFlowError) {
272
+ // OCC conflicts and invalid-transition errors are expected during
273
+ // races and concurrent updates — log at debug level only.
274
+ console.warn(`[EvolutionManager] taskflow ${op} for ${proposalId} skipped: ${err.code} (${err.message})`);
275
+ }
276
+ else {
277
+ console.warn(`[EvolutionManager] taskflow ${op} for ${proposalId} unexpected error:`, err instanceof Error ? err.message : err);
278
+ }
279
+ }
280
+ /**
281
+ * Backfill all in-flight proposals (status !== 'implemented' && !== 'rejected')
282
+ * into TaskFlow. Idempotent via `findIdempotent` on
283
+ * `evolution:cluster:<proposalId>` ownerKey. Safe to call multiple times.
284
+ *
285
+ * Returns counts: created, alreadyExisted, advanced (transitioned beyond
286
+ * 'queued' to match the proposal's current status).
287
+ */
288
+ async migrateExistingToTaskFlow() {
289
+ if (!this.taskFlowRegistry) {
290
+ return { created: 0, alreadyExisted: 0, advanced: 0, skipped: 0 };
291
+ }
292
+ const principal = this.taskFlowPrincipal();
293
+ if (!principal || principal.scope !== 'controller') {
294
+ return { created: 0, alreadyExisted: 0, advanced: 0, skipped: 0 };
295
+ }
296
+ const registry = this.taskFlowRegistry;
297
+ const state = this.loadEvolution();
298
+ let created = 0;
299
+ let alreadyExisted = 0;
300
+ let advanced = 0;
301
+ let skipped = 0;
302
+ for (const p of state.proposals) {
303
+ try {
304
+ const existing = registry.findByIdempotency(EVOLUTION_TASKFLOW_CONTROLLER_ID, ownerKeyForProposal(p.id), `evolution-cluster-create-${p.id}`);
305
+ let flow;
306
+ if (existing) {
307
+ alreadyExisted++;
308
+ flow = existing;
309
+ }
310
+ else {
311
+ const r = await registry.createFlow({
312
+ controllerId: EVOLUTION_TASKFLOW_CONTROLLER_ID,
313
+ controllerInstanceId: principal.controllerInstanceId,
314
+ ownerKey: ownerKeyForProposal(p.id),
315
+ idempotencyKey: `evolution-cluster-create-${p.id}`,
316
+ goal: p.title.slice(0, 1024),
317
+ currentStep: 'proposed',
318
+ stateJson: { proposalId: p.id, type: p.type, source: p.source },
319
+ });
320
+ if (r.created)
321
+ created++;
322
+ else
323
+ alreadyExisted++;
324
+ flow = r.flow;
325
+ }
326
+ // Catch the flow up to the proposal's current status.
327
+ const advancedThis = await this.catchUpFlowToStatus(flow, p, principal);
328
+ if (advancedThis)
329
+ advanced++;
330
+ }
331
+ catch (err) {
332
+ skipped++;
333
+ this.logTaskFlowError('migrate', p.id, err);
334
+ }
335
+ }
336
+ return { created, alreadyExisted, advanced, skipped };
337
+ }
338
+ /** Catch a flow record up to the proposal's current status. */
339
+ async catchUpFlowToStatus(flow, p, principal) {
340
+ if (!this.taskFlowRegistry)
341
+ return false;
342
+ const registry = this.taskFlowRegistry;
343
+ let cur = registry.getFlow(flow.flowId, { bypassCache: true }) ?? flow;
344
+ let mutated = false;
345
+ const target = p.status;
346
+ // Already terminal — leave alone.
347
+ if (cur.status === 'succeeded' || cur.status === 'failed' ||
348
+ cur.status === 'cancelled' || cur.status === 'lost') {
349
+ return false;
350
+ }
351
+ // Promote queued → running if target is running/terminal-success/failed.
352
+ if (cur.status === 'queued' && (target === 'approved' || target === 'in_progress' ||
353
+ target === 'implemented' || target === 'rejected' || target === 'deferred')) {
354
+ const step = target === 'in_progress' ? 'in_progress'
355
+ : target === 'approved' ? 'approved' : 'catch-up';
356
+ const r = await registry.startStep({
357
+ flowId: cur.flowId,
358
+ expectedRevision: cur.revision,
359
+ principal,
360
+ currentStep: step,
361
+ });
362
+ cur = r.flow;
363
+ mutated = true;
364
+ }
365
+ // Finalize.
366
+ if (target === 'implemented' && cur.status === 'running') {
367
+ await registry.finishFlow({
368
+ flowId: cur.flowId,
369
+ expectedRevision: cur.revision,
370
+ principal,
371
+ });
372
+ mutated = true;
373
+ }
374
+ else if (target === 'rejected' &&
375
+ (cur.status === 'running' || cur.status === 'waiting')) {
376
+ await registry.failFlow({
377
+ flowId: cur.flowId,
378
+ expectedRevision: cur.revision,
379
+ principal,
380
+ failureReason: p.resolution ?? 'rejected',
381
+ });
382
+ mutated = true;
383
+ }
384
+ else if (target === 'deferred' &&
385
+ (cur.status === 'running' || cur.status === 'waiting' || cur.status === 'queued')) {
386
+ const r = await registry.requestFlowCancel({
387
+ flowId: cur.flowId,
388
+ expectedRevision: cur.revision,
389
+ requesterOrigin: { kind: 'system', id: 'EvolutionManager' },
390
+ });
391
+ await registry.cancelFlow({
392
+ flowId: cur.flowId,
393
+ expectedRevision: r.flow.revision,
394
+ principal,
395
+ });
396
+ mutated = true;
397
+ }
398
+ return mutated;
399
+ }
30
400
  /**
31
401
  * Wire adaptive autonomy modules for runtime integration.
32
402
  * - TrustElevationTracker: receives proposal approval/rejection events
@@ -143,6 +513,8 @@ export class EvolutionManager {
143
513
  };
144
514
  state.proposals.push(proposal);
145
515
  this.saveEvolution(state);
516
+ // TaskFlow Phase 3a shadow-write — best-effort, JSON remains source of truth.
517
+ void this.dualWriteCreate(proposal);
146
518
  return proposal;
147
519
  }
148
520
  updateProposalStatus(id, status, resolution) {
@@ -150,6 +522,7 @@ export class EvolutionManager {
150
522
  const proposal = state.proposals.find(p => p.id === id);
151
523
  if (!proposal)
152
524
  return false;
525
+ const prevStatus = proposal.status;
153
526
  proposal.status = status;
154
527
  if (resolution)
155
528
  proposal.resolution = resolution;
@@ -161,6 +534,9 @@ export class EvolutionManager {
161
534
  const decision = status === 'approved' ? 'approved' : 'rejected';
162
535
  this.trustElevationTracker.recordProposalDecision(proposal, decision, false);
163
536
  }
537
+ // TaskFlow Phase 3a shadow-write — best-effort, JSON remains source of truth.
538
+ const action = statusToFlowAction(prevStatus, status, resolution);
539
+ void this.dualWriteTransition(id, action);
164
540
  return true;
165
541
  }
166
542
  /**