@syntesseraai/opencode-feature-factory 0.10.7 → 0.10.8

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.
@@ -18,6 +18,7 @@ export declare function evaluatePlanningGate(consensus: ConsensusPlan): GateResu
18
18
  * Evaluate the review approval gate.
19
19
  *
20
20
  * - confidence >=95 AND unresolvedIssues == 0 → APPROVED
21
+ * - vacuous review (0 issues, 0 action items) → APPROVED (nothing to fix)
21
22
  * - iteration >= maxIterations → ESCALATE
22
23
  * - otherwise → REWORK
23
24
  */
@@ -26,6 +27,7 @@ export declare function evaluateReviewGate(synthesis: ReviewSynthesis, iteration
26
27
  * Evaluate the documentation approval gate.
27
28
  *
28
29
  * - confidence >95, no change requested, 0 unresolved → APPROVED
30
+ * - vacuous review (0 issues, 0 action items) → APPROVED (nothing to fix)
29
31
  * - iteration >= maxIterations → ESCALATE
30
32
  * - otherwise → REWORK
31
33
  */
@@ -34,6 +36,7 @@ export declare function evaluateDocGate(review: DocReview, iteration: number, ma
34
36
  * Evaluate the mini-loop implementation gate.
35
37
  *
36
38
  * - confidence >95, no change requested, 0 blocking issues → APPROVED
39
+ * - vacuous review (0 issues, 0 action items) → APPROVED (nothing to fix)
37
40
  * - iteration >= maxIterations → ESCALATE
38
41
  * - otherwise → REWORK
39
42
  */
@@ -12,6 +12,23 @@ function formatActionItems(actionItems) {
12
12
  return actionItems.map((item, index) => `${index + 1}. ${item}`).join('\n');
13
13
  }
14
14
  // ---------------------------------------------------------------------------
15
+ // Vacuous review detection
16
+ // ---------------------------------------------------------------------------
17
+ /**
18
+ * Detect whether a review is "vacuous" — the reviewer produced no
19
+ * substantive feedback. This happens when the LLM returns no
20
+ * structured fields or an empty review: confidence falls back to 0,
21
+ * unresolvedIssues is 0, and there are no real action items.
22
+ *
23
+ * When a review is vacuous the gate should auto-approve rather than
24
+ * triggering an infinite rework loop with no actionable feedback.
25
+ */
26
+ function isVacuousReview(unresolvedIssues, stageOutput) {
27
+ return (unresolvedIssues === 0 &&
28
+ stageOutput.actionItems.length === 0 &&
29
+ stageOutput.issues.length === 0);
30
+ }
31
+ // ---------------------------------------------------------------------------
15
32
  // Planning gate
16
33
  // ---------------------------------------------------------------------------
17
34
  /**
@@ -43,6 +60,7 @@ export function evaluatePlanningGate(consensus) {
43
60
  * Evaluate the review approval gate.
44
61
  *
45
62
  * - confidence >=95 AND unresolvedIssues == 0 → APPROVED
63
+ * - vacuous review (0 issues, 0 action items) → APPROVED (nothing to fix)
46
64
  * - iteration >= maxIterations → ESCALATE
47
65
  * - otherwise → REWORK
48
66
  */
@@ -50,6 +68,9 @@ export function evaluateReviewGate(synthesis, iteration, maxIterations = 10) {
50
68
  if (synthesis.overallConfidence >= 95 && synthesis.unresolvedIssues === 0) {
51
69
  return { decision: 'APPROVED' };
52
70
  }
71
+ if (isVacuousReview(synthesis.unresolvedIssues, synthesis.stageOutput)) {
72
+ return { decision: 'APPROVED' };
73
+ }
53
74
  if (iteration >= maxIterations) {
54
75
  return {
55
76
  decision: 'ESCALATE',
@@ -73,6 +94,7 @@ export function evaluateReviewGate(synthesis, iteration, maxIterations = 10) {
73
94
  * Evaluate the documentation approval gate.
74
95
  *
75
96
  * - confidence >95, no change requested, 0 unresolved → APPROVED
97
+ * - vacuous review (0 issues, 0 action items) → APPROVED (nothing to fix)
76
98
  * - iteration >= maxIterations → ESCALATE
77
99
  * - otherwise → REWORK
78
100
  */
@@ -80,6 +102,9 @@ export function evaluateDocGate(review, iteration, maxIterations = 5) {
80
102
  if (review.verdict === 'APPROVED' && review.unresolvedIssues === 0 && review.confidence > 95) {
81
103
  return { decision: 'APPROVED' };
82
104
  }
105
+ if (isVacuousReview(review.unresolvedIssues, review.stageOutput)) {
106
+ return { decision: 'APPROVED' };
107
+ }
83
108
  if (iteration >= maxIterations) {
84
109
  return {
85
110
  decision: 'ESCALATE',
@@ -103,6 +128,7 @@ export function evaluateDocGate(review, iteration, maxIterations = 5) {
103
128
  * Evaluate the mini-loop implementation gate.
104
129
  *
105
130
  * - confidence >95, no change requested, 0 blocking issues → APPROVED
131
+ * - vacuous review (0 issues, 0 action items) → APPROVED (nothing to fix)
106
132
  * - iteration >= maxIterations → ESCALATE
107
133
  * - otherwise → REWORK
108
134
  */
@@ -110,6 +136,9 @@ export function evaluateMiniLoopImplGate(review, iteration, maxIterations = 10)
110
136
  if (review.confidence > 95 && !review.changeRequested && review.unresolvedIssues === 0) {
111
137
  return { decision: 'APPROVED' };
112
138
  }
139
+ if (isVacuousReview(review.unresolvedIssues, review.stageOutput)) {
140
+ return { decision: 'APPROVED' };
141
+ }
113
142
  if (iteration >= maxIterations) {
114
143
  return {
115
144
  decision: 'ESCALATE',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@syntesseraai/opencode-feature-factory",
4
- "version": "0.10.7",
4
+ "version": "0.10.8",
5
5
  "type": "module",
6
6
  "description": "OpenCode plugin for Feature Factory agents - provides sub-agents and skills for validation, review, security, and architecture assessment",
7
7
  "license": "MIT",