iriai-build 0.4.2 → 0.4.4
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 +1 -1
- package/v3/orchestrator.js +20 -9
- package/v3/recovery.js +8 -2
package/package.json
CHANGED
package/v3/orchestrator.js
CHANGED
|
@@ -2132,12 +2132,12 @@ export class Orchestrator {
|
|
|
2132
2132
|
}
|
|
2133
2133
|
|
|
2134
2134
|
// Handle [DECISION] blocks — render as separate decision prompts.
|
|
2135
|
-
// Skip
|
|
2135
|
+
// Skip ALL Operator-emitted decisions when a deferred decision exists for this feature.
|
|
2136
|
+
// The orchestrator already manages phase review / plan-approval decisions via
|
|
2137
|
+
// _requestPhaseReview → _postDeferredDecision. Operator [DECISION] blocks would
|
|
2138
|
+
// duplicate those, even if the IDs don't match exactly.
|
|
2136
2139
|
for (const decision of parsed.decisions) {
|
|
2137
|
-
if (this._deferredDecisions[feature.id])
|
|
2138
|
-
const deferred = this._deferredDecisions[feature.id].decision;
|
|
2139
|
-
if (deferred.id === decision.id) continue;
|
|
2140
|
-
}
|
|
2140
|
+
if (this._deferredDecisions[feature.id]) continue;
|
|
2141
2141
|
const options = decision.options.map(o => ({
|
|
2142
2142
|
id: o.id,
|
|
2143
2143
|
label: o.label,
|
|
@@ -2649,11 +2649,16 @@ export class Orchestrator {
|
|
|
2649
2649
|
return;
|
|
2650
2650
|
}
|
|
2651
2651
|
|
|
2652
|
+
// Re-read feature from DB — the file watcher's _handlePlanningDone may have
|
|
2653
|
+
// updated phase/role between the time the exit event was queued and now.
|
|
2654
|
+
const freshFeature = queries.getFeatureById(feature.id);
|
|
2655
|
+
if (!freshFeature) return;
|
|
2656
|
+
|
|
2652
2657
|
// Check if the file watcher already processed .done (it deletes the file).
|
|
2653
2658
|
// If review gate is posted or agent already marked done, don't retry.
|
|
2654
2659
|
const meta = queries.getFeatureMetadata(feature.id);
|
|
2655
2660
|
const agent = queries.getAgentById(agentId);
|
|
2656
|
-
if (meta.awaiting_phase_review
|
|
2661
|
+
if (meta.awaiting_phase_review) {
|
|
2657
2662
|
console.log(`[orchestrator] ${roleName} exit: review gate already posted, skipping retry`);
|
|
2658
2663
|
queries.updateAgentStatus(agentId, "done");
|
|
2659
2664
|
return;
|
|
@@ -2662,9 +2667,15 @@ export class Orchestrator {
|
|
|
2662
2667
|
console.log(`[orchestrator] ${roleName} exit: already marked done, skipping retry`);
|
|
2663
2668
|
return;
|
|
2664
2669
|
}
|
|
2665
|
-
//
|
|
2666
|
-
if (
|
|
2667
|
-
console.log(`[orchestrator] ${roleName} exit: phase
|
|
2670
|
+
// Skip if feature has left planning phase (e.g. plan-compiler PASS → plan-approval)
|
|
2671
|
+
if (freshFeature.phase !== "planning") {
|
|
2672
|
+
console.log(`[orchestrator] ${roleName} exit: feature phase is ${freshFeature.phase}, not planning — skipping retry`);
|
|
2673
|
+
queries.updateAgentStatus(agentId, "done");
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
// Skip if phase has already advanced past this role (null means role was cleared)
|
|
2677
|
+
if (freshFeature.active_planning_role !== roleName) {
|
|
2678
|
+
console.log(`[orchestrator] ${roleName} exit: active role is now ${freshFeature.active_planning_role || "none"}, skipping retry`);
|
|
2668
2679
|
queries.updateAgentStatus(agentId, "done");
|
|
2669
2680
|
return;
|
|
2670
2681
|
}
|
package/v3/recovery.js
CHANGED
|
@@ -100,8 +100,10 @@ export class Recovery {
|
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
// Emit stale signals
|
|
103
|
+
// Emit stale signals — only for the active planning role
|
|
104
|
+
const activeRole = feature.active_planning_role;
|
|
104
105
|
for (const [role, dir] of Object.entries(planningTree)) {
|
|
106
|
+
if (role !== activeRole) continue;
|
|
105
107
|
for (const [sig, eventType] of [
|
|
106
108
|
[SIGNAL.DONE, "planning:done"],
|
|
107
109
|
[SIGNAL.AGENT_RESPONSE, "planning:response"],
|
|
@@ -281,8 +283,12 @@ export class Recovery {
|
|
|
281
283
|
};
|
|
282
284
|
}
|
|
283
285
|
|
|
284
|
-
// Emit stale signals
|
|
286
|
+
// Emit stale signals — only for the active planning role to avoid
|
|
287
|
+
// re-processing signals from already-completed roles (which would cause
|
|
288
|
+
// duplicate artifact uploads and decision re-posts).
|
|
289
|
+
const activeRole = feature.active_planning_role;
|
|
285
290
|
for (const [role, dir] of Object.entries(planningTree)) {
|
|
291
|
+
if (role !== activeRole) continue;
|
|
286
292
|
for (const [sig, eventType] of [
|
|
287
293
|
[SIGNAL.DONE, "planning:done"],
|
|
288
294
|
[SIGNAL.AGENT_RESPONSE, "planning:response"],
|