| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "strings" |
| 6 | ) |
| 7 | |
| 8 | const timelineWidth = 48 |
| 9 | |
| 10 | // renderTimelines draws each checkpointed run's lifecycle as the argument- |
| 11 | // ending picture: start → first useful mutation → CORRECT → final, with the |
| 12 | // before/after-correct tallies underneath. |
| 13 | func renderTimelines(results []result) string { |
| 14 | var b strings.Builder |
| 15 | for _, r := range results { |
| 16 | if len(r.Checkpoints) == 0 || r.WallMs == 0 { |
| 17 | continue |
| 18 | } |
| 19 | if b.Len() == 0 { |
| 20 | b.WriteString("### Timelines\n\n") |
| 21 | } |
| 22 | fmt.Fprintf(&b, "`%s`\n\n```\n%s```\n\n", r.ID, taskTimeline(r)) |
| 23 | } |
| 24 | return b.String() |
| 25 | } |
| 26 | |
| 27 | func taskTimeline(r result) string { |
| 28 | pos := func(ms int64) int { |
| 29 | p := int(ms * timelineWidth / r.WallMs) |
| 30 | return min(max(p, 0), timelineWidth) |
| 31 | } |
| 32 | markers := []struct { |
| 33 | at int |
| 34 | label string |
| 35 | }{{0, "start"}} |
| 36 | if r.FirstUsefulMs > 0 { |
| 37 | markers = append(markers, struct { |
| 38 | at int |
| 39 | label string |
| 40 | }{pos(r.FirstUsefulMs), "useful mutation " + dur(r.FirstUsefulMs)}) |
| 41 | } |
| 42 | if r.FirstCorrectMs > 0 { |
| 43 | markers = append(markers, struct { |
| 44 | at int |
| 45 | label string |
| 46 | }{pos(r.FirstCorrectMs), "CORRECT " + dur(r.FirstCorrectMs)}) |
| 47 | } |
| 48 | markers = append(markers, struct { |
| 49 | at int |
| 50 | label string |
| 51 | }{timelineWidth, "final " + dur(r.WallMs)}) |
| 52 | |
| 53 | bar := []rune(strings.Repeat("─", timelineWidth+1)) |
| 54 | for _, m := range markers { |
| 55 | bar[m.at] = '│' |
| 56 | } |
| 57 | var out strings.Builder |
| 58 | out.WriteString(string(bar) + "\n") |
| 59 | for _, m := range markers { |
| 60 | out.WriteString(strings.Repeat(" ", m.at) + "^ " + m.label + "\n") |
| 61 | } |
| 62 | if r.Passed && r.PostSolveWasteMs > 0 { |
| 63 | fmt.Fprintf(&out, "post-solve waste %s (%s of wall)\n", dur(r.PostSolveWasteMs), pct(int(r.PostSolveWasteMs), int(r.WallMs))) |
| 64 | } |
| 65 | if r.FirstCorrectMs > 0 { |
| 66 | fmt.Fprintf(&out, "rounds %d→%d · calls %d→%d · after correct: verifications %d · reviews %d · mutations %d\n", |
| 67 | r.RoundsBeforeCorrect, r.RoundsAfterCorrect, |
| 68 | r.CallsBeforeCorrect, r.CallsAfterCorrect, |
| 69 | r.VerifyAfterCorrect, r.ReviewsAfterCorrect, r.MutationsAfterCorrect) |
| 70 | } |
| 71 | return out.String() |
| 72 | } |
| 73 | |
| 74 | // renderDiagnosis applies the decide-then-optimize tree to the measured |
| 75 | // signals and names the knife, in priority order: capability first (you |
| 76 | // cannot stop what never solves), damage second (safety bounds any stop |
| 77 | // policy), then the bigger of the termination tail and the exploration road. |
| 78 | func renderDiagnosis(results []result) string { |
| 79 | var wall, waste, ttfum int64 |
| 80 | checkpointed, neverCorrect, damaged, withCorrect := 0, 0, 0, 0 |
| 81 | for _, r := range results { |
| 82 | if len(r.Checkpoints) == 0 { |
| 83 | continue |
| 84 | } |
| 85 | checkpointed++ |
| 86 | wall += r.WallMs |
| 87 | if r.FirstCorrectMs == 0 && !r.Passed { |
| 88 | neverCorrect++ |
| 89 | continue |
| 90 | } |
| 91 | withCorrect++ |
| 92 | if r.RegressedAfterCorrect { |
| 93 | damaged++ |
| 94 | } |
| 95 | waste += r.PostSolveWasteMs |
| 96 | ttfum += r.FirstUsefulMs |
| 97 | } |
| 98 | if checkpointed == 0 || wall == 0 { |
| 99 | return "" |
| 100 | } |
| 101 | verdict := "" |
| 102 | switch { |
| 103 | case neverCorrect*100 >= checkpointed*30: |
| 104 | verdict = fmt.Sprintf("**never-correct dominates** (%s of runs) → reasoning quality: better verifier, subagent specialization, or a better model — latency work is premature", pct(neverCorrect, checkpointed)) |
| 105 | case withCorrect > 0 && damaged*100 >= withCorrect*10: |
| 106 | verdict = fmt.Sprintf("**correct→incorrect regressions** (%s) → conservative stop policy plus a mutation-after-pass guard before anything else", pct(damaged, withCorrect)) |
| 107 | case waste >= ttfum: |
| 108 | verdict = fmt.Sprintf("**post-solve waste dominates** (%s of wall vs TTFUM %s) → TaskContract + evidence graph + early termination", pct(int(waste), int(wall)), pct(int(ttfum), int(wall))) |
| 109 | default: |
| 110 | verdict = fmt.Sprintf("**exploration dominates** (TTFUM %s of wall vs waste %s) → fault localization, context retrieval, planner and tool choice", pct(int(ttfum), int(wall)), pct(int(waste), int(wall))) |
| 111 | } |
| 112 | return "**Diagnosis**: " + verdict + "\n\n" |
| 113 | } |
| 114 |