--- name: convergence description: | Detects convergence, stalling, and oscillation in multi-cycle PDCA runs. Prevents wasted cycles by stopping early when findings are not being resolved or are bouncing between cycles. Automatically loaded during Act phase before exit decision User: "Is the run converging?" --- # Convergence Detection In multi-cycle PDCA runs, the Act phase must decide whether another cycle will help or just waste tokens. This skill provides the analysis: are findings being resolved (converging), staying the same (stalling), or bouncing back (oscillating)? ## When It Runs Convergence analysis runs **after the Check phase completes and before the Act phase exit decision**. It requires at least 2 cycles of data — on cycle 1, it is skipped (no comparison baseline). ``` Check phase → Convergence Analysis → Act phase exit decision ``` --- ## Step 1: Finding Comparison Extract findings from the current cycle and compare against the previous cycle. ### Data Sources - **Current cycle findings:** Parsed from `check-*.md` artifacts in `.archeflow/artifacts//` - **Previous cycle findings:** Parsed from `check-*.md` artifacts in `.archeflow/artifacts//cycle-/` Each finding is identified by a composite key: `source + category + file_location + description_keywords`. ### Finding Categories Every finding from the current cycle is classified into exactly one category: | Category | Definition | |----------|------------| | **NEW** | Finding not present in any previous cycle | | **RESOLVED** | Was present in the previous cycle, absent in the current cycle | | **PERSISTENT** | Present in both the current and previous cycle (same key) | | **REGRESSED** | Was RESOLVED in the previous cycle (was present in N-2, absent in N-1), but returned in the current cycle | ### Matching Algorithm Two findings match if: 1. Same `source` archetype (guardian, sage, etc.) 2. Same `category` (security, reliability, quality, etc.) 3. Same or overlapping file location (same file, line within 10 lines) 4. 50%+ keyword overlap in description (lowercase, strip punctuation) All four conditions must hold. This prevents false matches across unrelated findings. --- ## Step 2: Convergence Score Calculate a convergence score from the categorized findings: ``` convergence = resolved_count / (resolved_count + new_count + regressed_count) ``` If the denominator is 0 (no resolved, no new, no regressed — only persistent), the score is `0.0` (stalled, not converging). ### Score Interpretation | Score Range | Status | Meaning | |-------------|--------|---------| | > 0.8 | **Converging** | Most issues being resolved, few new ones introduced | | 0.5 - 0.8 | **Stalling** | Fixing roughly as many as introducing | | < 0.5 | **Diverging** | Making things worse — more new/regressed than resolved | | 0.0 (all persistent) | **Stuck** | No progress in either direction | --- ## Step 3: Oscillation Detection An oscillating finding is one that bounces between resolved and re-introduced across cycles: 1. Finding was present in cycle N-2 2. Finding was absent in cycle N-1 (resolved) 3. Finding is present again in cycle N (regressed) This indicates the fix in cycle N-1 was undone or invalidated by other changes in cycle N. ### Oscillation Rules - A single oscillating finding: **flag it** in the convergence report but continue. - Two or more oscillating findings: **STOP** and escalate to the user. - Message: `"Findings X and Y are oscillating between cycles. Manual intervention needed — the automated fixes are interfering with each other."` Oscillation tracking requires 3+ cycles of data. On cycles 1-2, oscillation detection is skipped. --- ## Step 4: Early Termination Rules The convergence analysis can override the normal Act phase exit decision. If any of these conditions hold, the recommendation is **STOP**: | Condition | Threshold | Recommendation | |-----------|-----------|----------------| | Diverging | Score < 0.5 for 2 consecutive cycles | STOP — changes are making things worse | | Stalled | 0 findings resolved between cycles | STOP — no progress, further cycles will not help | | Stuck | All findings are PERSISTENT for 2 consecutive cycles | STOP — automated fixes cannot resolve these | | Oscillating | 2+ findings oscillating | STOP — fixes are interfering with each other | When STOP is recommended, the Act phase should: 1. **Not** start another PDCA cycle 2. Report all unresolved findings to the user 3. Present the best implementation so far (on its branch, not merged) 4. Include the convergence report explaining why the run was stopped ### Override Behavior The convergence STOP recommendation overrides the normal cycle-back logic in the Act phase. Even if `CYCLE < MAX_CYCLES` and there are fixable-looking findings, if convergence says STOP, the run stops. The user can always override by explicitly requesting another cycle: `"Run one more cycle anyway"`. --- ## Step 5: Integration with Act Phase ### Event Data Convergence data is included in the `cycle.boundary` event emitted by the Act phase: ```json { "type": "cycle.boundary", "phase": "act", "data": { "cycle": 2, "max_cycles": 3, "exit_condition": "convergence_stop", "met": false, "fixes_applied": 2, "next_action": "stop", "convergence": { "score": 0.35, "status": "diverging", "resolved": 1, "new": 2, "regressed": 1, "persistent": 3, "oscillating": ["Timeline reference mismatch"], "recommendation": "stop", "reason": "Diverging for 2 consecutive cycles" } } } ``` ### Decision Tree Update The Act phase decision tree (from `act-phase` skill Step 4) gains a new first branch: ``` ┌─ Convergence analysis (cycle 2+) │ ├─ Convergence says STOP │ └─ STOP: Report to user with convergence report │ ├─ Convergence says CONTINUE │ └─ Fall through to normal exit decision logic │ └─ Cycle 1 (no convergence data) └─ Fall through to normal exit decision logic ``` ### Act Feedback Enhancement When the Act phase builds `act-feedback.md` for the next cycle, it includes the convergence summary at the top: ```markdown ## Convergence Analysis (Cycle 1 → 2) Score: 0.75 (converging) Resolved: 3 | New: 1 | Regressed: 0 | Persistent: 2 Recommendation: Continue — trend is positive ### Finding Status | Finding | Status | Cycles | |---------|--------|--------| | SQL injection in user input | RESOLVED | 1 | | Missing rate limit | RESOLVED | 1 | | Test names unclear | RESOLVED | 1 | | Null check missing in parser | PERSISTENT | 2 | | Error path not tested | PERSISTENT | 2 | | New: Unused import introduced | NEW | 1 | ``` --- ## Convergence Report Format The full convergence report is generated as part of the orchestration output: ```markdown ## Convergence Analysis (Cycle N-1 → N) **Score:** 0.75 (converging) **Resolved:** 3 | **New:** 1 | **Regressed:** 0 | **Persistent:** 2 | **Oscillating:** 0 ### Resolved This Cycle | Source | Category | Description | |--------|----------|-------------| | guardian | security | SQL injection in user input handler | | guardian | reliability | Missing rate limit on auth endpoint | | sage | quality | Test names don't describe behavior | ### New This Cycle | Source | Category | Description | |--------|----------|-------------| | sage | quality | Unused import introduced by fix | ### Persistent (unresolved across cycles) | Source | Category | Description | Cycles Open | |--------|----------|-------------|-------------| | trickster | reliability | Null check missing in parser | 2 | | sage | testing | Error path not tested | 2 | ### Oscillating (none) **Recommendation:** Continue — trend is positive ``` --- ## Integration with Memory Skill When convergence detects PERSISTENT findings (present for 2+ cycles), these are strong candidates for the `memory` skill's lesson extraction: - After a run that had persistent findings, `archeflow-memory.sh extract` will pick these up with higher confidence (they have been confirmed across multiple cycles within a single run). - Persistent findings that also appear in `lessons.jsonl` from prior runs get a double frequency boost (cross-cycle within run + cross-run pattern). --- ## Design Principles 1. **Conservative stopping.** Requires 2 consecutive data points before recommending STOP. A single bad cycle might be noise. 2. **User has final say.** STOP is a recommendation, not an enforced shutdown. The user can override. 3. **Cheap computation.** Keyword matching on finding descriptions, simple arithmetic on counts. No ML, no embeddings. 4. **Bounded scope.** Only compares adjacent cycles (N vs N-1, with N-2 for oscillation). Does not attempt to model long-term trends across many cycles. 5. **Observable.** All convergence data is included in the `cycle.boundary` event, making it available for post-hoc analysis via the process log.