| 1 | # Skill: Retro Enforcement |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | Ensure retrospectives happen on schedule and that their action items are tracked in GitHub Issues — not markdown checklists. |
| 6 | |
| 7 | This skill addresses a specific, measured failure mode: **0% completion rate on markdown retro action items across 6 consecutive retrospectives**. GitHub Issues have an 85%+ completion rate in the same squad. The format was the problem, not the people. |
| 8 | |
| 9 | ## Core Function: Test-RetroOverdue |
| 10 | |
| 11 | ```powershell |
| 12 | function Test-RetroOverdue { |
| 13 | param( |
| 14 | [string]$LogDir = ".squad/log", |
| 15 | [int]$WindowDays = 7, |
| 16 | [string]$Pattern = "*retrospective*" |
| 17 | ) |
| 18 | |
| 19 | $cutoff = (Get-Date).AddDays(-$WindowDays) |
| 20 | |
| 21 | $retroLogs = Get-ChildItem -Path $LogDir -Filter $Pattern -ErrorAction SilentlyContinue | |
| 22 | Where-Object { $_.LastWriteTime -ge $cutoff } |
| 23 | |
| 24 | return ($retroLogs.Count -eq 0) |
| 25 | } |
| 26 | ``` |
| 27 | |
| 28 | ### Returns |
| 29 | - `$true` — No retro log found within the window. **Retro is overdue. Block other work.** |
| 30 | - `$false` — At least one retro log found within the window. Proceed normally. |
| 31 | |
| 32 | ### Detection Logic |
| 33 | |
| 34 | The function checks `.squad/log/` for any file matching `*retrospective*` dated within the last `$WindowDays` days (default: 7). If none is found, the retro is overdue. |
| 35 | |
| 36 | **File naming convention:** `.squad/log/{ISO8601-timestamp}-retrospective.md` |
| 37 | |
| 38 | Example: `.squad/log/2026-03-24T14-45-00Z-retrospective.md` |
| 39 | |
| 40 | ## Coordinator Integration |
| 41 | |
| 42 | Call `Test-RetroOverdue` **at the start of every round**, before building the work queue. |
| 43 | |
| 44 | ```powershell |
| 45 | # At round start — before any work queue construction |
| 46 | if (Test-RetroOverdue -LogDir ".squad/log" -WindowDays 7) { |
| 47 | Write-Host "[RETRO] Retrospective overdue. Running before other work." |
| 48 | |
| 49 | # Spawn retro facilitator |
| 50 | Invoke-RetroSession -Mode "catch-up" |
| 51 | |
| 52 | # Wait for retro log to be written |
| 53 | # Then resume normal round |
| 54 | } |
| 55 | |
| 56 | # Proceed with normal work queue |
| 57 | $workQueue = Get-PendingIssues | Sort-Object -Property Priority |
| 58 | ``` |
| 59 | |
| 60 | ### Blocking Semantics |
| 61 | |
| 62 | When `Test-RetroOverdue` returns `$true`: |
| 63 | |
| 64 | 1. **Do not start any other work** until the retro completes |
| 65 | 2. **Spawn the facilitator agent** (Scribe or designated) with retro mode |
| 66 | 3. **Wait for the log file** to be written to `.squad/log/` |
| 67 | 4. **Verify action items** were created as GitHub Issues (not markdown) |
| 68 | 5. **Resume normal round** after retro log confirmed |
| 69 | |
| 70 | ## Action Item Enforcement |
| 71 | |
| 72 | Every retro action item MUST become a GitHub Issue. The facilitator agent is responsible for this. The coordinator verifies. |
| 73 | |
| 74 | ### Verification Check |
| 75 | |
| 76 | ```powershell |
| 77 | function Test-RetroActionItemsCreated { |
| 78 | param([string]$RetroLogPath) |
| 79 | |
| 80 | $content = Get-Content $RetroLogPath -Raw |
| 81 | |
| 82 | # Check for Issue references (e.g., #1478, https://github.com/.../issues/1478) |
| 83 | $issueRefs = [regex]::Matches($content, '(?:#\d{3,}|issues/\d{3,})') |
| 84 | |
| 85 | # Check for unclosed markdown checkboxes (bad pattern) |
| 86 | $openCheckboxes = [regex]::Matches($content, '- \[ \]') |
| 87 | |
| 88 | if ($openCheckboxes.Count -gt 0) { |
| 89 | Write-Warning "[RETRO] Found $($openCheckboxes.Count) markdown checkboxes — convert to Issues" |
| 90 | return $false |
| 91 | } |
| 92 | |
| 93 | return ($issueRefs.Count -gt 0) |
| 94 | } |
| 95 | ``` |
| 96 | |
| 97 | ### Why Not Markdown Checklists |
| 98 | |
| 99 | From production data in tamirdresher/tamresearch1: |
| 100 | |
| 101 | | Retro | Action Items Format | Completion | |
| 102 | |-------|---------------------|------------| |
| 103 | | 2025-12-05 | Markdown `- [ ]` | 0/4 = **0%** | |
| 104 | | 2025-12-19 | Markdown `- [ ]` | 0/3 = **0%** | |
| 105 | | 2026-01-09 | Markdown `- [ ]` | 0/5 = **0%** | |
| 106 | | 2026-01-23 | Markdown `- [ ]` | 0/4 = **0%** | |
| 107 | | 2026-02-07 | Markdown `- [ ]` | 0/3 = **0%** | |
| 108 | | 2026-02-21 | Markdown `- [ ]` | 0/4 = **0%** | |
| 109 | | 2026-03-24 | GitHub Issues | 4/4 = **100%** (after enforcement) | |
| 110 | |
| 111 | **Root cause:** Markdown checklists have no assignee, no notifications, no close event, and no query surface. They are invisible to every workflow that drives completion. |
| 112 | |
| 113 | ## Cadence Enforcement |
| 114 | |
| 115 | ### Recommended schedule |
| 116 | - Weekly squads: window = 7 days |
| 117 | - Bi-weekly squads: window = 14 days |
| 118 | |
| 119 | ### Ralph integration example |
| 120 | |
| 121 | ```powershell |
| 122 | # ralph-watch.ps1 — round start hook |
| 123 | function Invoke-RoundStart { |
| 124 | # 1. Always check retro first |
| 125 | if (Test-RetroOverdue -LogDir "$RepoRoot/.squad/log" -WindowDays 7) { |
| 126 | Write-Host "[RALPH] Retro overdue — enforcing before work queue" |
| 127 | Invoke-RetroSession |
| 128 | return # Re-enter round after retro completes |
| 129 | } |
| 130 | |
| 131 | # 2. Normal work queue |
| 132 | $issues = Get-ReadyIssues |
| 133 | foreach ($issue in $issues) { |
| 134 | Invoke-WorkItem -Issue $issue |
| 135 | } |
| 136 | } |
| 137 | ``` |
| 138 | |
| 139 | ## Skill Metadata |
| 140 | |
| 141 | | Field | Value | |
| 142 | |-------|-------| |
| 143 | | **Skill ID** | `retro-enforcement` | |
| 144 | | **Category** | Ceremonies / Process | |
| 145 | | **Trigger** | Coordinator round start | |
| 146 | | **Dependencies** | `.squad/log/` directory, GitHub Issues API | |
| 147 | | **Tested in** | tamirdresher/tamresearch1 (production, March 2026) | |
| 148 | | **Outcome** | Retro cadence restored; action item completion 0% → 100% | |