@tekyzinc/gsd-t 2.50.12 → 2.53.10

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.
Files changed (99) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +379 -372
  3. package/bin/component-registry.js +250 -0
  4. package/bin/graph-cgc.js +510 -510
  5. package/bin/graph-indexer.js +147 -147
  6. package/bin/graph-overlay.js +195 -195
  7. package/bin/graph-parsers.js +327 -327
  8. package/bin/graph-query.js +453 -452
  9. package/bin/graph-store.js +154 -154
  10. package/bin/qa-calibrator.js +194 -0
  11. package/bin/scan-data-collector.js +153 -153
  12. package/bin/scan-diagrams-generators.js +187 -187
  13. package/bin/scan-diagrams.js +79 -79
  14. package/bin/scan-renderer.js +92 -92
  15. package/bin/scan-report-sections.js +121 -121
  16. package/bin/scan-report.js +184 -184
  17. package/bin/scan-schema-parsers.js +199 -199
  18. package/bin/scan-schema.js +103 -103
  19. package/bin/token-budget.js +246 -0
  20. package/commands/Claude-md.md +10 -10
  21. package/commands/branch.md +15 -15
  22. package/commands/checkin.md +45 -45
  23. package/commands/global-change.md +209 -209
  24. package/commands/gsd-t-audit.md +199 -0
  25. package/commands/gsd-t-backlog-add.md +94 -94
  26. package/commands/gsd-t-backlog-edit.md +111 -111
  27. package/commands/gsd-t-backlog-list.md +63 -63
  28. package/commands/gsd-t-backlog-move.md +94 -94
  29. package/commands/gsd-t-backlog-promote.md +123 -123
  30. package/commands/gsd-t-backlog-remove.md +86 -86
  31. package/commands/gsd-t-backlog-settings.md +158 -158
  32. package/commands/gsd-t-complete-milestone.md +528 -515
  33. package/commands/gsd-t-debug.md +506 -399
  34. package/commands/gsd-t-discuss.md +174 -174
  35. package/commands/gsd-t-execute.md +758 -634
  36. package/commands/gsd-t-feature.md +276 -276
  37. package/commands/gsd-t-health.md +142 -142
  38. package/commands/gsd-t-help.md +465 -457
  39. package/commands/gsd-t-impact.md +302 -302
  40. package/commands/gsd-t-init.md +320 -280
  41. package/commands/gsd-t-integrate.md +365 -249
  42. package/commands/gsd-t-milestone.md +87 -87
  43. package/commands/gsd-t-partition.md +442 -361
  44. package/commands/gsd-t-pause.md +82 -82
  45. package/commands/gsd-t-plan.md +345 -344
  46. package/commands/gsd-t-populate.md +111 -111
  47. package/commands/gsd-t-prd.md +326 -326
  48. package/commands/gsd-t-project.md +211 -211
  49. package/commands/gsd-t-promote-debt.md +123 -123
  50. package/commands/gsd-t-prompt.md +137 -137
  51. package/commands/gsd-t-qa.md +266 -266
  52. package/commands/gsd-t-quick.md +357 -234
  53. package/commands/gsd-t-reflect.md +134 -134
  54. package/commands/gsd-t-resume.md +72 -72
  55. package/commands/gsd-t-scan.md +615 -615
  56. package/commands/gsd-t-setup.md +76 -0
  57. package/commands/gsd-t-status.md +192 -166
  58. package/commands/gsd-t-test-sync.md +381 -381
  59. package/commands/gsd-t-triage-and-merge.md +171 -171
  60. package/commands/gsd-t-verify.md +382 -382
  61. package/commands/gsd-t-visualize.md +118 -118
  62. package/commands/gsd-t-wave.md +401 -378
  63. package/docs/GSD-T-README.md +425 -422
  64. package/docs/architecture.md +385 -369
  65. package/docs/harness-design-analysis.md +371 -0
  66. package/docs/infrastructure.md +205 -205
  67. package/docs/prd-graph-engine.md +398 -398
  68. package/docs/prd-gsd2-hybrid.md +559 -559
  69. package/docs/prd-harness-evolution.md +583 -0
  70. package/docs/requirements.md +14 -0
  71. package/docs/workflows.md +226 -226
  72. package/examples/.gsd-t/domains/example-domain/scope.md +13 -13
  73. package/package.json +40 -40
  74. package/scripts/gsd-t-auto-route.js +39 -39
  75. package/scripts/gsd-t-dashboard-mockup.html +1143 -1143
  76. package/scripts/gsd-t-dashboard-server.js +171 -171
  77. package/scripts/gsd-t-dashboard.html +262 -262
  78. package/scripts/gsd-t-event-writer.js +128 -128
  79. package/scripts/gsd-t-statusline.js +94 -94
  80. package/scripts/gsd-t-tools.js +175 -175
  81. package/templates/CLAUDE-global.md +639 -614
  82. package/templates/CLAUDE-project.md +24 -0
  83. package/templates/backlog-settings.md +18 -18
  84. package/templates/backlog.md +1 -1
  85. package/templates/progress.md +40 -40
  86. package/templates/shared-services-contract.md +60 -60
  87. package/templates/stacks/desktop.ini +2 -2
  88. package/bin/desktop.ini +0 -2
  89. package/commands/desktop.ini +0 -2
  90. package/docs/ci-examples/desktop.ini +0 -2
  91. package/docs/desktop.ini +0 -2
  92. package/examples/.gsd-t/contracts/desktop.ini +0 -2
  93. package/examples/.gsd-t/desktop.ini +0 -2
  94. package/examples/.gsd-t/domains/desktop.ini +0 -2
  95. package/examples/.gsd-t/domains/example-domain/desktop.ini +0 -2
  96. package/examples/desktop.ini +0 -2
  97. package/examples/rules/desktop.ini +0 -2
  98. package/scripts/desktop.ini +0 -2
  99. package/templates/desktop.ini +0 -2
@@ -1,1143 +1,1143 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>GSD-T Dashboard — Mockup</title>
6
- <style>
7
- :root {
8
- --bg:#0d1117; --surface:#161b22; --surface2:#21262d; --border:#30363d;
9
- --text:#e6edf3; --muted:#7d8590; --dim:#484f58;
10
- --blue:#388bfd; --blue-bg:#1f3a5f;
11
- --green:#3fb950; --green-bg:#1a3a1e;
12
- --yellow:#d29922; --yellow-bg:#3a2c10;
13
- --red:#f85149; --red-bg:#3a1a1a;
14
- --purple:#bc8cff; --purple-bg:#2d1f5e;
15
- --cyan:#79c0ff; --orange:#d18616;
16
- --font:'SF Mono','Fira Code','Cascadia Code',monospace;
17
- }
18
- *{box-sizing:border-box;margin:0;padding:0;}
19
- body{background:var(--bg);color:var(--text);font-family:var(--font);font-size:12px;
20
- height:100vh;display:flex;flex-direction:column;overflow:hidden;}
21
-
22
- /* Header */
23
- .hdr{display:flex;align-items:center;gap:12px;padding:0 16px;
24
- background:var(--surface);border-bottom:1px solid var(--border);height:40px;flex-shrink:0;}
25
- .logo{color:var(--blue);font-weight:bold;font-size:13px;}
26
- .live{display:flex;align-items:center;gap:5px;background:var(--green-bg);
27
- border:1px solid var(--green);color:var(--green);padding:2px 8px;border-radius:10px;font-size:10px;}
28
- .ldot{width:6px;height:6px;border-radius:50%;background:var(--green);
29
- animation:pdot 1.5s ease-in-out infinite;}
30
- @keyframes pdot{0%,100%{opacity:1}50%{opacity:.3}}
31
- .hmeta{color:var(--muted);font-size:11px;}
32
- .hright{margin-left:auto;display:flex;gap:12px;align-items:center;}
33
- .tok{color:var(--cyan);font-size:11px;}
34
- .pbadge{background:var(--blue-bg);border:1px solid var(--blue);color:var(--blue);
35
- padding:2px 10px;border-radius:4px;font-size:11px;}
36
-
37
- /* Scenario bar */
38
- .scbar{display:flex;gap:4px;padding:8px 16px;background:var(--surface);
39
- border-bottom:1px solid var(--border);flex-shrink:0;overflow-x:auto;}
40
- .scbtn{padding:5px 14px;border-radius:5px;font-family:var(--font);font-size:11px;
41
- cursor:pointer;border:1px solid var(--border);background:transparent;color:var(--muted);
42
- white-space:nowrap;transition:all .15s;}
43
- .scbtn:hover{border-color:var(--blue);color:var(--blue);}
44
- .scbtn.active{background:var(--blue-bg);border-color:var(--blue);color:var(--blue);}
45
-
46
- /* Main */
47
- .main{display:flex;flex:1;overflow:hidden;}
48
-
49
- /* Graph */
50
- .garea{flex:1;position:relative;overflow:hidden;background:var(--bg);
51
- background-image:radial-gradient(circle at 1px 1px,var(--border) 1px,transparent 0);
52
- background-size:24px 24px;}
53
- svg.g{position:absolute;width:100%;height:100%;overflow:visible;}
54
-
55
- /* Nodes */
56
- .ng{cursor:pointer;}
57
- .ng:hover rect.nr{filter:brightness(1.25);}
58
- .nr{transition:filter .2s;}
59
- .n-session {fill:#1a1f2e;stroke:var(--blue);stroke-width:1.5;}
60
- .n-command {fill:#1e1a2e;stroke:var(--purple);stroke-width:1.5;}
61
- .n-domain {fill:#1a2e1a;stroke:var(--green);stroke-width:1.5;}
62
- .n-qa {fill:#2e2a1a;stroke:var(--yellow);stroke-width:1.5;}
63
- .n-scan {fill:#1a1e2e;stroke:var(--cyan);stroke-width:1.5;}
64
- .n-research{fill:#2e1a2e;stroke:var(--purple);stroke-width:1.5;}
65
- .n-error {fill:var(--red-bg);stroke:var(--red);stroke-width:1.5;}
66
- .n-done {fill:#1a2e1a;stroke:var(--green);stroke-width:1.5;}
67
- .n-pending {fill:#161b22;stroke:var(--dim);stroke-width:1;}
68
- .n-debug {fill:#2e2210;stroke:var(--orange);stroke-width:1.5;}
69
- .n-tool-active{fill:#1e1a2e;stroke:var(--purple);stroke-width:1.5;}
70
- .n-tool-done {fill:#1a2e1a;stroke:var(--green);stroke-width:1;}
71
-
72
- .running{animation:npulse 2s ease-in-out infinite;}
73
- @keyframes npulse{0%,100%{stroke-opacity:1;stroke-width:1.5}50%{stroke-opacity:.4;stroke-width:2.5}}
74
- .nerr{animation:nerror .4s ease-in-out 4;}
75
- @keyframes nerror{0%,100%{stroke-width:1.5}50%{stroke-width:3}}
76
-
77
- .nl{fill:var(--text);font-size:11px;font-family:var(--font);font-weight:500;}
78
- .ns{fill:var(--muted);font-size:9px;font-family:var(--font);}
79
- .nd{fill:var(--dim);font-size:11px;}
80
-
81
- /* Edges */
82
- .e{fill:none;stroke-width:1.5;}
83
- .e-spawn {stroke:var(--border);}
84
- .e-active{stroke:var(--blue);stroke-width:2;}
85
- .e-tool {stroke:var(--purple);stroke-dasharray:3,2;}
86
- .e-msg {stroke:var(--cyan);stroke-dasharray:4,3;}
87
- .e-pending{stroke:var(--dim);stroke-width:1;stroke-dasharray:2,3;}
88
-
89
- .ef{fill:none;stroke-width:2;stroke-dasharray:8,4;animation:flow 1.4s linear infinite;}
90
- .ef-spawn{stroke:var(--blue);}
91
- .ef-tool {stroke:var(--purple);}
92
- .ef-msg {stroke:var(--cyan);}
93
- .ef-scan {stroke:var(--cyan);}
94
- .ef-res {stroke:var(--purple);}
95
- @keyframes flow{to{stroke-dashoffset:-24}}
96
-
97
- .tpulse{fill:none;stroke:var(--purple);stroke-width:1;
98
- animation:texp 1.6s ease-out infinite;}
99
- @keyframes texp{0%{r:5;opacity:.9}100%{r:18;opacity:0}}
100
-
101
- /* Sidebar */
102
- .sb{width:280px;background:var(--surface);border-left:1px solid var(--border);
103
- display:flex;flex-direction:column;flex-shrink:0;overflow:hidden;}
104
- .sbtabs{display:flex;border-bottom:1px solid var(--border);flex-shrink:0;}
105
- .sbtab{flex:1;padding:8px;text-align:center;color:var(--muted);cursor:pointer;
106
- font-size:11px;border-bottom:2px solid transparent;transition:all .15s;}
107
- .sbtab.active{color:var(--blue);border-bottom-color:var(--blue);}
108
- .sbcont{flex:1;overflow-y:auto;padding:12px;}
109
- .sbcont::-webkit-scrollbar{width:4px;}
110
- .sbcont::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px;}
111
- .ssect{margin-bottom:14px;}
112
- .stitle{color:var(--muted);font-size:10px;text-transform:uppercase;
113
- letter-spacing:.8px;margin-bottom:7px;}
114
- .mrow{display:flex;justify-content:space-between;padding:4px 0;
115
- border-bottom:1px solid var(--surface2);font-size:11px;}
116
- .ml{color:var(--muted)}.mv{color:var(--text)}
117
- .mv.gr{color:var(--green)}.mv.bl{color:var(--blue)}
118
- .mv.yl{color:var(--yellow)}.mv.rd{color:var(--red)}
119
- .rbox{background:var(--surface2);border:1px solid var(--border);border-radius:6px;
120
- padding:8px;margin-top:6px;color:var(--muted);font-size:10px;line-height:1.5;
121
- border-left:3px solid var(--blue);}
122
- .xitem{background:var(--surface2);border-radius:4px;padding:6px 8px;
123
- margin-bottom:6px;border-left:3px solid var(--yellow);}
124
- .xitem.s{border-left-color:var(--green);}
125
- .xitem.f{border-left-color:var(--red);}
126
- .xtag{display:inline-block;font-size:9px;padding:1px 5px;border-radius:3px;
127
- margin-bottom:3px;font-weight:bold;}
128
- .t-f{background:var(--red-bg);color:var(--red);}
129
- .t-s{background:var(--green-bg);color:var(--green);}
130
- .t-l{background:var(--blue-bg);color:var(--blue);}
131
- .t-d{background:var(--surface2);color:var(--muted);}
132
- .xt{color:var(--muted);font-size:10px;line-height:1.4;}
133
- .xd{color:var(--dim);font-size:9px;margin-top:2px;}
134
- .pbw{height:3px;background:var(--surface2);border-radius:2px;margin:4px 0;}
135
- .pbf{height:100%;background:var(--green);border-radius:2px;transition:width .5s;}
136
- .spin{display:inline-block;width:9px;height:9px;border:1.5px solid var(--border);
137
- border-top-color:var(--blue);border-radius:50%;animation:sp .8s linear infinite;
138
- vertical-align:middle;margin-right:3px;}
139
- @keyframes sp{to{transform:rotate(360deg)}}
140
-
141
- /* Agent count badges */
142
- .abadge{display:inline-flex;align-items:center;justify-content:center;
143
- width:18px;height:18px;border-radius:50%;font-size:9px;font-weight:bold;
144
- background:var(--blue-bg);color:var(--blue);border:1px solid var(--blue);}
145
- .abadge.yl{background:var(--yellow-bg);color:var(--yellow);border-color:var(--yellow);}
146
- .abadge.gr{background:var(--green-bg);color:var(--green);border-color:var(--green);}
147
- .abadge.pu{background:var(--purple-bg);color:var(--purple);border-color:var(--purple);}
148
-
149
- /* Event log */
150
- .elog{border-top:1px solid var(--border);flex-shrink:0;height:130px;
151
- overflow-y:auto;padding:8px;}
152
- .elog::-webkit-scrollbar{width:4px;}
153
- .elog::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px;}
154
- .ee{display:flex;gap:6px;align-items:flex-start;padding:3px 0;
155
- border-bottom:1px solid var(--surface2);font-size:10px;line-height:1.3;}
156
- .ets{color:var(--dim);flex-shrink:0;}
157
- .et{flex-shrink:0;font-weight:bold;}
158
- .et.spawn{color:var(--blue)}.et.tool{color:var(--purple)}
159
- .et.trans{color:var(--cyan)}.et.dec{color:var(--yellow)}
160
- .et.err{color:var(--red)}.et.done{color:var(--green)}
161
- .et.res{color:var(--purple)}
162
- .em{color:var(--muted);}
163
- .enew{animation:fnew 1s ease-out;}
164
- @keyframes fnew{from{background:var(--blue-bg)}to{background:transparent}}
165
-
166
- /* Timeline */
167
- .tl{height:50px;background:var(--surface);border-top:1px solid var(--border);
168
- flex-shrink:0;display:flex;align-items:center;padding:0 16px;gap:0;overflow-x:auto;}
169
- .tlp{display:flex;align-items:center;gap:5px;padding:5px 10px;border-radius:4px;
170
- font-size:10px;flex-shrink:0;}
171
- .tlp.done{color:var(--green);background:var(--green-bg);}
172
- .tlp.act{color:var(--blue);background:var(--blue-bg);
173
- animation:tlpulse 2s ease-in-out infinite;}
174
- .tlp.fut{color:var(--dim);}
175
- @keyframes tlpulse{0%,100%{background:var(--blue-bg)}50%{background:#1a2f5e}}
176
- .tla{color:var(--border);padding:0 3px;font-size:13px;}
177
- .tla.act{color:var(--blue);animation:farr .8s ease-in-out infinite;}
178
- @keyframes farr{0%,100%{opacity:1}50%{opacity:.2}}
179
-
180
- /* Sync animation for parallel nodes */
181
- .parallel-bracket{fill:none;stroke:var(--dim);stroke-width:1;stroke-dasharray:3,2;}
182
- .parallel-label{fill:var(--dim);font-size:9px;font-family:var(--font);}
183
- </style>
184
- </head>
185
- <body>
186
-
187
- <div class="hdr">
188
- <div class="logo">◆ GSD-T</div>
189
- <div class="live"><div class="ldot"></div>LIVE</div>
190
- <div class="hmeta" id="hdr-meta">session: sess_8f3c2a · gsd-t-wave → M14</div>
191
- <div class="hright">
192
- <div class="tok" id="hdr-tok">⬡ 87,432 / 200,000 (43%)</div>
193
- <div class="pbadge" id="hdr-phase">▶ EXECUTE</div>
194
- </div>
195
- </div>
196
-
197
- <!-- Scenario selector -->
198
- <div class="scbar">
199
- <button class="scbtn active" onclick="showScene(0)">wave / execute (parallel domains)</button>
200
- <button class="scbtn" onclick="showScene(1)">execute: 3 domains × 3 QA agents</button>
201
- <button class="scbtn" onclick="showScene(2)">gsd-t-scan (5 parallel agents)</button>
202
- <button class="scbtn" onclick="showScene(3)">gsd-t-brainstorm (deep research)</button>
203
- <button class="scbtn" onclick="showScene(4)">gsd-t-debug (loop detection)</button>
204
- <button class="scbtn" onclick="showScene(5)">gsd-t-quick + error recovery</button>
205
- </div>
206
-
207
- <div class="main">
208
- <div class="garea">
209
- <svg class="g" id="graph-svg" viewBox="0 0 820 520">
210
- <defs>
211
- <marker id="ar-sp" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#30363d"/></marker>
212
- <marker id="ar-bl" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#388bfd"/></marker>
213
- <marker id="ar-pu" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#bc8cff"/></marker>
214
- <marker id="ar-cy" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#79c0ff"/></marker>
215
- <marker id="ar-gr" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#3fb950"/></marker>
216
- <marker id="ar-or" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#d18616"/></marker>
217
- </defs>
218
- <g id="scene-content"></g>
219
- </svg>
220
- </div>
221
-
222
- <!-- Sidebar -->
223
- <div class="sb">
224
- <div class="sbtabs">
225
- <div class="sbtab active" onclick="stab('info')">Info</div>
226
- <div class="sbtab" onclick="stab('agents')">Agents</div>
227
- <div class="sbtab" onclick="stab('memory')">Memory</div>
228
- </div>
229
- <div class="sbcont" id="sp-info">
230
- <div class="ssect">
231
- <div class="stitle">Selected Node</div>
232
- <div id="node-name" style="font-size:13px;font-weight:bold;margin-bottom:4px;color:var(--text)">gsd-t-wave</div>
233
- <div id="node-type" style="font-size:10px;color:var(--muted);margin-bottom:10px">orchestrator · session root</div>
234
- <div class="mrow"><span class="ml">status</span><span class="mv bl" id="nv-status"><span class="spin"></span>running</span></div>
235
- <div class="mrow"><span class="ml">command</span><span class="mv" id="nv-cmd">gsd-t-wave</span></div>
236
- <div class="mrow"><span class="ml">phase</span><span class="mv" id="nv-phase">EXECUTE</span></div>
237
- <div class="mrow"><span class="ml">duration</span><span class="mv" id="nv-dur">2m 28s</span></div>
238
- <div class="mrow"><span class="ml">tokens</span><span class="mv" id="nv-tok">87,432</span></div>
239
- <div class="mrow"><span class="ml">model</span><span class="mv" id="nv-model">sonnet</span></div>
240
- <div class="pbw"><div class="pbf" id="nv-prog" style="width:43%"></div></div>
241
- <div style="font-size:9px;color:var(--muted);text-align:right;margin-top:2px" id="nv-tasks">7/19 tasks</div>
242
- </div>
243
- <div class="ssect">
244
- <div class="stitle">Current Reasoning</div>
245
- <div class="rbox" id="nv-reason">Orchestrating parallel domain execution — event-capture ✓, learning-loop running (task 3/7), visualization blocked pending event-capture contract.</div>
246
- </div>
247
- <div class="ssect" id="exp-section">
248
- <div class="stitle">Past Experience Surfaced</div>
249
- <div class="xitem f"><span class="xtag t-f">[failure]</span>
250
- <div class="xt" id="nv-exp1">Pre-task retrieval didn't apply to team mode spawn — domain subagents in parallel mode missed past experience context</div>
251
- <div class="xd">2026-02-19 · execute domain</div>
252
- </div>
253
- <div class="xitem s"><span class="xtag t-s">[success]</span>
254
- <div class="xt">Zero-dep chokidar watch pattern works reliably for JSONL file monitoring</div>
255
- <div class="xd">2026-02-22 · cli domain</div>
256
- </div>
257
- </div>
258
- </div>
259
- <div class="sbcont" id="sp-agents" style="display:none">
260
- <div class="ssect">
261
- <div class="stitle">Active Agents</div>
262
- <div id="agent-list"></div>
263
- </div>
264
- <div class="ssect">
265
- <div class="stitle">Spawn Tree</div>
266
- <div id="spawn-tree" style="font-size:10px;color:var(--muted);line-height:2;font-family:var(--font)"></div>
267
- </div>
268
- </div>
269
- <div class="sbcont" id="sp-memory" style="display:none">
270
- <div class="ssect">
271
- <div class="stitle">Session Stats</div>
272
- <div class="mrow"><span class="ml">events logged</span><span class="mv bl" id="mem-events">248</span></div>
273
- <div class="mrow"><span class="ml">agents spawned</span><span class="mv" id="mem-agents">8</span></div>
274
- <div class="mrow"><span class="ml">decisions captured</span><span class="mv" id="mem-dec">14</span></div>
275
- <div class="mrow"><span class="ml">failures surfaced</span><span class="mv yl" id="mem-fail">2</span></div>
276
- <div class="mrow"><span class="ml">lessons applied</span><span class="mv gr" id="mem-les">3</span></div>
277
- <div class="mrow"><span class="ml">errors</span><span class="mv rd" id="mem-err">0</span></div>
278
- </div>
279
- <div class="ssect">
280
- <div class="stitle">Outcome Log</div>
281
- <div id="outcome-log" style="font-size:10px;color:var(--muted);line-height:1.8;"></div>
282
- </div>
283
- </div>
284
- <div class="elog" id="evt-log"></div>
285
- </div>
286
- </div>
287
-
288
- <div class="tl" id="timeline-bar"></div>
289
-
290
- <script>
291
- // ═══════════════════════════════════════════════
292
- // SCENE DEFINITIONS
293
- // ═══════════════════════════════════════════════
294
-
295
- const SCENES = [
296
-
297
- // ─────────────────────────────────────────────
298
- // 0: wave / execute (parallel domains)
299
- // ─────────────────────────────────────────────
300
- {
301
- meta: { cmd:'gsd-t-wave → M14', tok:'87,432 / 200,000 (43%)', phase:'▶ EXECUTE' },
302
- timeline: [
303
- {l:'partition',s:'done'},{a:'›'},{l:'plan',s:'done'},{a:'›'},
304
- {l:'execute',s:'act'},{a:'›',act:true},{l:'test-sync',s:'fut'},{a:'›'},
305
- {l:'integrate',s:'fut'},{a:'›'},{l:'verify',s:'fut'},{a:'›'},{l:'complete',s:'fut'}
306
- ],
307
- agents:[
308
- {n:'gsd-t-wave', t:'orchestrator', s:'running', tok:'87k'},
309
- {n:'execute', t:'phase agent', s:'running', tok:'41k'},
310
- {n:'event-capture', t:'domain', s:'done', tok:'19k'},
311
- {n:'learning-loop', t:'domain', s:'running', tok:'47k'},
312
- {n:'visualization', t:'domain', s:'blocked', tok:'—'},
313
- {n:'qa-agent', t:'QA · haiku', s:'running', tok:'3k'},
314
- ],
315
- tree:'◆ gsd-t-wave\n└─ execute\n ├─ ✓ event-capture\n ├─ ◌ learning-loop\n │ └─ ⚑ qa-agent\n └─ ⏳ visualization (blocked)',
316
- outcomes:'[success] event-capture: 6/6 tasks done\n[running] learning-loop: task 3/7\n[blocked] visualization: waiting on event-capture contract',
317
- events:[
318
- {t:'tool', msg:'learning-loop → Bash: npm test'},
319
- {t:'spawn', msg:'learning-loop → qa-agent (haiku)'},
320
- {t:'dec', msg:'[learning] 2 past entries surfaced for learning-loop'},
321
- {t:'done', msg:'event-capture: 6/6 tasks ✓ 48s'},
322
- {t:'trans', msg:'plan → execute · 19 tasks, 3 domains'},
323
- {t:'spawn', msg:'execute → learning-loop, event-capture (parallel)'},
324
- ],
325
- svg: `
326
- <!-- ROOT -->
327
- <g class="ng" onclick="selNode('wave',0)">
328
- <rect class="nr n-session running" x="310" y="16" width="200" height="48" rx="8"/>
329
- <text class="nl" x="410" y="36" text-anchor="middle">gsd-t-wave</text>
330
- <text class="ns" x="410" y="52" text-anchor="middle">orchestrator · M14: Execution Intelligence</text>
331
- <text x="322" y="36" fill="#79c0ff" font-size="11">◆</text>
332
- </g>
333
- <!-- EXECUTE phase -->
334
- <g class="ng" onclick="selNode('execute',0)">
335
- <rect class="nr n-domain running" x="310" y="108" width="200" height="44" rx="8"/>
336
- <text class="nl" x="410" y="127" text-anchor="middle">execute</text>
337
- <text x="322" y="127" fill="#388bfd" font-size="11">◌</text>
338
- <text class="ns" x="410" y="141" text-anchor="middle">phase agent · 7/19 tasks · 2m14s</text>
339
- </g>
340
- <!-- PARTITION done -->
341
- <g class="ng" onclick="selNode('partition',0)">
342
- <rect class="nr n-done" x="30" y="108" width="130" height="44" rx="8"/>
343
- <text class="nl" x="95" y="127" text-anchor="middle">partition</text>
344
- <text class="ns" x="95" y="141" text-anchor="middle">✓ 3 domains · 12s</text>
345
- <text x="42" y="127" fill="#3fb950" font-size="11">✓</text>
346
- </g>
347
- <!-- PLAN done -->
348
- <g class="ng" onclick="selNode('plan',0)">
349
- <rect class="nr n-done" x="180" y="108" width="110" height="44" rx="8"/>
350
- <text class="nl" x="235" y="127" text-anchor="middle">plan</text>
351
- <text class="ns" x="235" y="141" text-anchor="middle">✓ 19 tasks · 28s</text>
352
- <text x="192" y="127" fill="#3fb950" font-size="11">✓</text>
353
- </g>
354
- <!-- VERIFY pending -->
355
- <g class="ng" onclick="selNode('verify',0)">
356
- <rect class="nr n-pending" x="530" y="108" width="120" height="44" rx="8"/>
357
- <text class="nd" x="590" y="127" text-anchor="middle">verify</text>
358
- <text class="ns" x="590" y="141" text-anchor="middle">pending</text>
359
- </g>
360
-
361
- <!-- PARALLEL bracket -->
362
- <line class="parallel-bracket" x1="80" y1="205" x2="80" y2="220"/>
363
- <line class="parallel-bracket" x1="80" y1="220" x2="700" y2="220"/>
364
- <line class="parallel-bracket" x1="700" y1="205" x2="700" y2="220"/>
365
- <text class="parallel-label" x="390" y="232" text-anchor="middle">── parallel domain subagents ──</text>
366
-
367
- <!-- DOMAINS -->
368
- <!-- event-capture done -->
369
- <g class="ng" onclick="selNode('event-capture',0)">
370
- <rect class="nr n-done" x="60" y="240" width="160" height="52" rx="8"/>
371
- <text class="nl" x="140" y="260" text-anchor="middle">event-capture</text>
372
- <text x="72" y="260" fill="#3fb950" font-size="11">✓</text>
373
- <text class="ns" x="140" y="276" text-anchor="middle">6/6 tasks · sonnet · 48s</text>
374
- </g>
375
- <!-- learning-loop running -->
376
- <g class="ng" onclick="selNode('learning-loop',0)">
377
- <rect class="nr n-domain running" x="330" y="240" width="160" height="52" rx="8"/>
378
- <text class="nl" x="410" y="260" text-anchor="middle">learning-loop</text>
379
- <text x="342" y="260" fill="#388bfd" font-size="11">◌</text>
380
- <text class="ns" x="410" y="276" text-anchor="middle">task 3/7 · sonnet · 1m02s</text>
381
- </g>
382
- <!-- visualization blocked -->
383
- <g class="ng" onclick="selNode('visualization',0)">
384
- <rect class="nr n-pending" x="600" y="240" width="160" height="52" rx="8"/>
385
- <text class="nd" x="680" y="260" text-anchor="middle">visualization</text>
386
- <text x="612" y="260" fill="#484f58" font-size="11">⏳</text>
387
- <text class="ns" x="680" y="276" text-anchor="middle">blocked · 7 tasks pending</text>
388
- </g>
389
-
390
- <!-- QA agent under learning-loop -->
391
- <g class="ng" onclick="selNode('qa',0)">
392
- <rect class="nr n-qa" x="340" y="348" width="140" height="44" rx="8"/>
393
- <text class="nl" x="410" y="367" text-anchor="middle">qa-agent</text>
394
- <text x="352" y="367" fill="#d29922" font-size="11">⚑</text>
395
- <text class="ns" x="410" y="381" text-anchor="middle">haiku · running tests</text>
396
- </g>
397
- <!-- Bash tool -->
398
- <g class="ng" onclick="selNode('bash',0)">
399
- <rect class="nr n-tool-active" x="280" y="448" width="120" height="36" rx="8"/>
400
- <text class="nl" x="340" y="464" text-anchor="middle" font-size="10">Bash</text>
401
- <text class="ns" x="340" y="478" text-anchor="middle">npm test</text>
402
- <text x="292" y="464" fill="#bc8cff" font-size="10">⬡</text>
403
- <circle class="tpulse" cx="292" cy="464" r="5"/>
404
- </g>
405
- <!-- Edit done -->
406
- <g class="ng" onclick="selNode('edit',0)">
407
- <rect class="nr n-tool-done" x="430" y="448" width="110" height="36" rx="8"/>
408
- <text class="nl" x="485" y="464" text-anchor="middle" font-size="10">Edit</text>
409
- <text class="ns" x="485" y="478" text-anchor="middle" fill="#3fb950">✓ 3 files</text>
410
- </g>
411
-
412
- <!-- Experience warning -->
413
- <rect x="30" y="318" width="170" height="44" fill="#3a2c10" stroke="#d29922" stroke-width="1" rx="5" opacity=".92"/>
414
- <text x="115" y="334" text-anchor="middle" fill="#d29922" font-size="9" font-family="monospace">⚠ past experience surfaced</text>
415
- <text x="115" y="347" text-anchor="middle" fill="#d29922" font-size="9" font-family="monospace">[failure] team mode missed retrieval</text>
416
- <text x="115" y="359" text-anchor="middle" fill="#d29922" font-size="8" font-family="monospace" opacity=".7">→ applying fix to parallel spawn</text>
417
- <path d="M200,340 L330,268" stroke="#d29922" stroke-width="1" stroke-dasharray="3,2" opacity=".6" marker-end="url(#ar-or)"/>
418
-
419
- <!-- EDGES -->
420
- <path class="e e-spawn" d="M360,64 L95,108" marker-end="url(#ar-sp)"/>
421
- <path class="e e-spawn" d="M370,64 L235,108" marker-end="url(#ar-sp)"/>
422
- <path class="e e-active" d="M410,64 L410,108" marker-end="url(#ar-bl)"/>
423
- <path class="ef ef-spawn" d="M410,64 L410,108"/>
424
- <path class="e e-pending" d="M450,64 L590,108" marker-end="url(#ar-sp)"/>
425
- <path class="e e-spawn" d="M370,152 L140,240" marker-end="url(#ar-sp)"/>
426
- <path class="e e-active" d="M410,152 L410,240" marker-end="url(#ar-bl)"/>
427
- <path class="ef ef-spawn" d="M410,152 L410,240"/>
428
- <path class="e e-pending" d="M450,152 L680,240" marker-end="url(#ar-sp)" stroke-opacity=".4"/>
429
- <path class="e e-active" d="M410,292 L410,348" marker-end="url(#ar-bl)"/>
430
- <path class="ef ef-spawn" d="M410,292 L410,348"/>
431
- <path class="e e-tool" d="M390,292 C370,380 350,420 340,448" marker-end="url(#ar-pu)"/>
432
- <path class="ef ef-tool" d="M390,292 C370,380 350,420 340,448"/>
433
- <path class="e e-spawn" d="M430,292 C450,380 470,420 485,448" marker-end="url(#ar-sp)"/>
434
- `
435
- },
436
-
437
- // ─────────────────────────────────────────────
438
- // 1: 3 domains × 3 QA agents
439
- // ─────────────────────────────────────────────
440
- {
441
- meta: { cmd:'gsd-t-execute · M14 · 3 domains in parallel', tok:'142,100 / 200,000 (71%)', phase:'▶ EXECUTE' },
442
- timeline: [
443
- {l:'partition',s:'done'},{a:'›'},{l:'plan',s:'done'},{a:'›'},
444
- {l:'execute',s:'act'},{a:'›',act:true},{l:'test-sync',s:'fut'},{a:'›'},{l:'verify',s:'fut'}
445
- ],
446
- agents:[
447
- {n:'execute', t:'orchestrator', s:'running', tok:'18k'},
448
- {n:'backend', t:'domain · sonnet', s:'running', tok:'55k'},
449
- {n:'frontend', t:'domain · sonnet', s:'running', tok:'42k'},
450
- {n:'cli', t:'domain · sonnet', s:'done', tok:'27k'},
451
- {n:'qa-backend', t:'QA · haiku', s:'running', tok:'8k'},
452
- {n:'qa-frontend',t:'QA · haiku', s:'running', tok:'6k'},
453
- {n:'qa-cli', t:'QA · haiku', s:'done', tok:'4k'},
454
- ],
455
- tree:'◆ execute (orchestrator)\n├─ ◌ backend\n│ └─ ⚑ qa-backend (haiku)\n├─ ◌ frontend\n│ └─ ⚑ qa-frontend (haiku)\n└─ ✓ cli\n └─ ✓ qa-cli (haiku)',
456
- outcomes:'[running] backend: task 4/8, qa watching\n[running] frontend: task 2/6, qa watching\n[success] cli: 5/5 tasks, 127/127 tests pass',
457
- events:[
458
- {t:'tool', msg:'qa-backend → Bash: npm test -- auth'},
459
- {t:'tool', msg:'qa-frontend → Bash: playwright test'},
460
- {t:'done', msg:'cli domain: 5/5 tasks ✓ 127 tests pass'},
461
- {t:'spawn', msg:'execute → qa-frontend (haiku, parallel)'},
462
- {t:'spawn', msg:'execute → qa-backend (haiku, parallel)'},
463
- {t:'spawn', msg:'execute → backend, frontend, cli (parallel)'},
464
- ],
465
- svg: `
466
- <!-- Execute root -->
467
- <g class="ng" onclick="selNode('execute',1)">
468
- <rect class="nr n-command running" x="310" y="20" width="200" height="48" rx="8"/>
469
- <text class="nl" x="410" y="40" text-anchor="middle">execute</text>
470
- <text x="322" y="40" fill="#bc8cff" font-size="11">◌</text>
471
- <text class="ns" x="410" y="54" text-anchor="middle">orchestrator · 3 parallel domains</text>
472
- </g>
473
-
474
- <!-- Parallel bracket -->
475
- <line class="parallel-bracket" x1="100" y1="115" x2="100" y2="130"/>
476
- <line class="parallel-bracket" x1="100" y1="130" x2="720" y2="130"/>
477
- <line class="parallel-bracket" x1="720" y1="115" x2="720" y2="130"/>
478
- <text class="parallel-label" x="410" y="143" text-anchor="middle">── 3 domain subagents (parallel, each with own QA agent) ──</text>
479
-
480
- <!-- BACKEND domain running -->
481
- <g class="ng" onclick="selNode('backend',1)">
482
- <rect class="nr n-domain running" x="60" y="152" width="160" height="52" rx="8"/>
483
- <text class="nl" x="140" y="172" text-anchor="middle">backend</text>
484
- <text x="72" y="172" fill="#388bfd" font-size="11">◌</text>
485
- <text class="ns" x="140" y="188" text-anchor="middle">task 4/8 · sonnet · 3m12s</text>
486
- </g>
487
- <!-- FRONTEND domain running -->
488
- <g class="ng" onclick="selNode('frontend',1)">
489
- <rect class="nr n-domain running" x="330" y="152" width="160" height="52" rx="8"/>
490
- <text class="nl" x="410" y="172" text-anchor="middle">frontend</text>
491
- <text x="342" y="172" fill="#388bfd" font-size="11">◌</text>
492
- <text class="ns" x="410" y="188" text-anchor="middle">task 2/6 · sonnet · 2m44s</text>
493
- </g>
494
- <!-- CLI domain done -->
495
- <g class="ng" onclick="selNode('cli',1)">
496
- <rect class="nr n-done" x="600" y="152" width="160" height="52" rx="8"/>
497
- <text class="nl" x="680" y="172" text-anchor="middle">cli</text>
498
- <text x="612" y="172" fill="#3fb950" font-size="11">✓</text>
499
- <text class="ns" x="680" y="188" text-anchor="middle">5/5 tasks · sonnet · 1m18s</text>
500
- </g>
501
-
502
- <!-- QA AGENTS row — all three visible simultaneously -->
503
- <text class="parallel-label" x="410" y="267" text-anchor="middle">── QA agents (one per domain, spawned after each task) ──</text>
504
-
505
- <!-- qa-backend running -->
506
- <g class="ng" onclick="selNode('qa-backend',1)">
507
- <rect class="nr n-qa running" x="50" y="276" width="170" height="48" rx="8"/>
508
- <text class="nl" x="135" y="296" text-anchor="middle">qa-backend</text>
509
- <text x="62" y="296" fill="#d29922" font-size="11">⚑</text>
510
- <text class="ns" x="135" y="310" text-anchor="middle">haiku · npm test -- auth</text>
511
- </g>
512
- <!-- qa-frontend running -->
513
- <g class="ng" onclick="selNode('qa-frontend',1)">
514
- <rect class="nr n-qa running" x="320" y="276" width="180" height="48" rx="8"/>
515
- <text class="nl" x="410" y="296" text-anchor="middle">qa-frontend</text>
516
- <text x="332" y="296" fill="#d29922" font-size="11">⚑</text>
517
- <text class="ns" x="410" y="310" text-anchor="middle">haiku · playwright test</text>
518
- </g>
519
- <!-- qa-cli done -->
520
- <g class="ng" onclick="selNode('qa-cli',1)">
521
- <rect class="nr n-done" x="590" y="276" width="180" height="48" rx="8"/>
522
- <text class="nl" x="680" y="296" text-anchor="middle">qa-cli</text>
523
- <text x="602" y="296" fill="#3fb950" font-size="11">✓</text>
524
- <text class="ns" x="680" y="310" text-anchor="middle">haiku · 127/127 tests ✓</text>
525
- </g>
526
-
527
- <!-- TOOL CALLS under QA agents -->
528
- <!-- backend tool active -->
529
- <g class="ng" onclick="selNode('bash-be',1)">
530
- <rect class="nr n-tool-active" x="35" y="384" width="110" height="36" rx="8"/>
531
- <text class="nl" x="90" y="400" text-anchor="middle" font-size="10">Bash</text>
532
- <text class="ns" x="90" y="414" text-anchor="middle">npm test -- auth</text>
533
- <circle class="tpulse" cx="47" cy="400" r="4"/>
534
- </g>
535
- <!-- backend edit done -->
536
- <g class="ng" onclick="selNode('edit-be',1)">
537
- <rect class="nr n-tool-done" x="160" y="384" width="100" height="36" rx="8"/>
538
- <text class="nl" x="210" y="400" text-anchor="middle" font-size="10">Edit</text>
539
- <text class="ns" x="210" y="414" text-anchor="middle" fill="#3fb950">✓ routes.js</text>
540
- </g>
541
- <!-- frontend playwright active -->
542
- <g class="ng" onclick="selNode('pw-fe',1)">
543
- <rect class="nr n-tool-active" x="340" y="384" width="130" height="36" rx="8"/>
544
- <text class="nl" x="405" y="400" text-anchor="middle" font-size="10">Bash</text>
545
- <text class="ns" x="405" y="414" text-anchor="middle">playwright test</text>
546
- <circle class="tpulse" cx="352" cy="400" r="4"/>
547
- </g>
548
-
549
- <!-- Contract check annotation -->
550
- <rect x="500" y="370" width="180" height="52" fill="#1f3a5f" stroke="#388bfd" stroke-width="1" rx="5" opacity=".9"/>
551
- <text x="590" y="386" text-anchor="middle" fill="#79c0ff" font-size="9" font-family="monospace">◎ contract compliance</text>
552
- <text x="590" y="399" text-anchor="middle" fill="#79c0ff" font-size="9" font-family="monospace">qa-cli verified: api-contract.md ✓</text>
553
- <text x="590" y="412" text-anchor="middle" fill="#3fb950" font-size="9" font-family="monospace">schema-contract.md ✓</text>
554
-
555
- <!-- Agent count summary -->
556
- <rect x="20" y="450" width="220" height="42" fill="#161b22" stroke="#30363d" stroke-width="1" rx="6" opacity=".95"/>
557
- <text x="30" y="466" fill="#7d8590" font-size="9" font-family="monospace">ACTIVE AGENTS</text>
558
- <text x="30" y="481" fill="#388bfd" font-size="10" font-family="monospace">● 2 domain agents running</text>
559
- <text x="160" y="481" fill="#d29922" font-size="10" font-family="monospace">⚑ 2 QA agents running</text>
560
-
561
- <!-- EDGES -->
562
- <path class="e e-active" d="M370,68 L140,152" marker-end="url(#ar-bl)"/>
563
- <path class="ef ef-spawn" d="M370,68 L140,152"/>
564
- <path class="e e-active" d="M410,68 L410,152" marker-end="url(#ar-bl)"/>
565
- <path class="ef ef-spawn" d="M410,68 L410,152"/>
566
- <path class="e e-spawn" d="M450,68 L680,152" marker-end="url(#ar-sp)"/>
567
- <path class="ef ef-spawn" d="M450,68 L680,152"/>
568
- <!-- domain → qa -->
569
- <path class="e e-active" d="M140,204 L135,276" marker-end="url(#ar-bl)"/>
570
- <path class="ef ef-spawn" d="M140,204 L135,276"/>
571
- <path class="e e-active" d="M410,204 L410,276" marker-end="url(#ar-bl)"/>
572
- <path class="ef ef-spawn" d="M410,204 L410,276"/>
573
- <path class="e e-spawn" d="M680,204 L680,276" marker-end="url(#ar-sp)"/>
574
- <!-- qa → tools -->
575
- <path class="e e-tool" d="M100,324 L90,384" marker-end="url(#ar-pu)"/>
576
- <path class="ef ef-tool" d="M100,324 L90,384"/>
577
- <path class="e e-spawn" d="M150,324 L210,384" marker-end="url(#ar-sp)"/>
578
- <path class="e e-tool" d="M390,324 L405,384" marker-end="url(#ar-pu)"/>
579
- <path class="ef ef-tool" d="M390,324 L405,384"/>
580
- `
581
- },
582
-
583
- // ─────────────────────────────────────────────
584
- // 2: gsd-t-scan (5 parallel agents)
585
- // ─────────────────────────────────────────────
586
- {
587
- meta: { cmd:'gsd-t-scan · post-M14 analysis', tok:'62,300 / 200,000 (31%)', phase:'▶ SCAN' },
588
- timeline: [{l:'scan',s:'act'}],
589
- agents:[
590
- {n:'gsd-t-scan', t:'orchestrator · sonnet', s:'running', tok:'12k'},
591
- {n:'architecture', t:'scan agent · haiku', s:'done', tok:'9k'},
592
- {n:'business-rules',t:'scan agent · haiku', s:'done', tok:'11k'},
593
- {n:'security', t:'scan agent · sonnet', s:'running', tok:'14k'},
594
- {n:'quality', t:'scan agent · sonnet', s:'running', tok:'16k'},
595
- {n:'contracts', t:'scan agent · haiku', s:'done', tok:'8k'},
596
- ],
597
- tree:'◆ gsd-t-scan\n├─ ✓ architecture (haiku)\n├─ ✓ business-rules (haiku)\n├─ ◌ security (sonnet)\n├─ ◌ quality (sonnet)\n└─ ✓ contracts (haiku)',
598
- outcomes:'[success] architecture: 0 critical, 2 medium\n[success] business-rules: 3 patterns found\n[running] security: analyzing 6 dimensions\n[running] quality: checking 87 functions\n[success] contracts: 2 drift items found',
599
- events:[
600
- {t:'tool', msg:'security → Bash: grep -r "execSync" bin/'},
601
- {t:'tool', msg:'quality → Glob: **/*.js'},
602
- {t:'done', msg:'contracts: 2 drift items found'},
603
- {t:'done', msg:'business-rules: 3 patterns found'},
604
- {t:'done', msg:'architecture: 0 critical, 2 medium findings'},
605
- {t:'spawn', msg:'scan → 5 parallel agents spawned (sonnet×2, haiku×3)'},
606
- ],
607
- svg: `
608
- <!-- ROOT -->
609
- <g class="ng" onclick="selNode('scan',2)">
610
- <rect class="nr n-session running" x="310" y="20" width="200" height="48" rx="8"/>
611
- <text class="nl" x="410" y="40" text-anchor="middle">gsd-t-scan</text>
612
- <text x="322" y="40" fill="#79c0ff" font-size="11">◆</text>
613
- <text class="ns" x="410" y="54" text-anchor="middle">orchestrator · 5 parallel agents</text>
614
- </g>
615
-
616
- <!-- Parallel bracket -->
617
- <line class="parallel-bracket" x1="75" y1="115" x2="75" y2="132"/>
618
- <line class="parallel-bracket" x1="75" y1="132" x2="745" y2="132"/>
619
- <line class="parallel-bracket" x1="745" y1="115" x2="745" y2="132"/>
620
- <text class="parallel-label" x="410" y="144" text-anchor="middle">── 5 scan agents spawned simultaneously ──</text>
621
-
622
- <!-- architecture done -->
623
- <g class="ng" onclick="selNode('arch',2)">
624
- <rect class="nr n-done" x="20" y="154" width="140" height="52" rx="8"/>
625
- <text class="nl" x="90" y="174" text-anchor="middle">architecture</text>
626
- <text x="32" y="174" fill="#3fb950" font-size="11">✓</text>
627
- <text class="ns" x="90" y="190" text-anchor="middle">haiku · 0 crit, 2 med</text>
628
- </g>
629
- <!-- business-rules done -->
630
- <g class="ng" onclick="selNode('biz',2)">
631
- <rect class="nr n-done" x="180" y="154" width="140" height="52" rx="8"/>
632
- <text class="nl" x="250" y="174" text-anchor="middle">business-rules</text>
633
- <text x="192" y="174" fill="#3fb950" font-size="11">✓</text>
634
- <text class="ns" x="250" y="190" text-anchor="middle">haiku · 3 patterns</text>
635
- </g>
636
- <!-- security running -->
637
- <g class="ng" onclick="selNode('security',2)">
638
- <rect class="nr n-scan running" x="340" y="154" width="140" height="52" rx="8"/>
639
- <text class="nl" x="410" y="174" text-anchor="middle">security</text>
640
- <text x="352" y="174" fill="#79c0ff" font-size="11">◌</text>
641
- <text class="ns" x="410" y="190" text-anchor="middle">sonnet · 6 dimensions</text>
642
- </g>
643
- <!-- quality running -->
644
- <g class="ng" onclick="selNode('quality',2)">
645
- <rect class="nr n-scan running" x="500" y="154" width="140" height="52" rx="8"/>
646
- <text class="nl" x="570" y="174" text-anchor="middle">quality</text>
647
- <text x="512" y="174" fill="#79c0ff" font-size="11">◌</text>
648
- <text class="ns" x="570" y="190" text-anchor="middle">sonnet · 87 functions</text>
649
- </g>
650
- <!-- contracts done -->
651
- <g class="ng" onclick="selNode('contracts',2)">
652
- <rect class="nr n-done" x="660" y="154" width="140" height="52" rx="8"/>
653
- <text class="nl" x="730" y="174" text-anchor="middle">contracts</text>
654
- <text x="672" y="174" fill="#3fb950" font-size="11">✓</text>
655
- <text class="ns" x="730" y="190" text-anchor="middle">haiku · 2 drift items</text>
656
- </g>
657
-
658
- <!-- Tool calls for active agents -->
659
- <!-- security tools -->
660
- <g class="ng"><rect class="nr n-tool-active" x="280" y="270" width="130" height="36" rx="8"/>
661
- <text class="nl" x="345" y="286" text-anchor="middle" font-size="10">Bash</text>
662
- <text class="ns" x="345" y="300" text-anchor="middle">grep -r execSync</text>
663
- <circle class="tpulse" cx="292" cy="286" r="4"/>
664
- </g>
665
- <g class="ng"><rect class="nr n-tool-done" x="420" y="270" width="110" height="36" rx="8"/>
666
- <text class="nl" x="475" y="286" text-anchor="middle" font-size="10">Read</text>
667
- <text class="ns" x="475" y="300" text-anchor="middle" fill="#3fb950">✓ bin/gsd-t.js</text>
668
- </g>
669
- <!-- quality tools -->
670
- <g class="ng"><rect class="nr n-tool-active" x="490" y="270" width="130" height="36" rx="8"/>
671
- <text class="nl" x="555" y="286" text-anchor="middle" font-size="10">Glob</text>
672
- <text class="ns" x="555" y="300" text-anchor="middle">**/*.js (87 fns)</text>
673
- <circle class="tpulse" cx="502" cy="286" r="4"/>
674
- </g>
675
- <g class="ng"><rect class="nr n-tool-done" x="630" y="270" width="110" height="36" rx="8"/>
676
- <text class="nl" x="685" y="286" text-anchor="middle" font-size="10">Grep</text>
677
- <text class="ns" x="685" y="300" text-anchor="middle" fill="#3fb950">✓ 127 tests</text>
678
- </g>
679
-
680
- <!-- Synthesis node (pending) -->
681
- <rect x="300" y="372" width="220" height="52" fill="#161b22" stroke="#30363d" stroke-width="1" rx="8" stroke-dasharray="4,2"/>
682
- <text x="410" y="392" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">synthesis (pending)</text>
683
- <text x="410" y="408" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">merges all 5 reports → techdebt.md</text>
684
- <text x="312" y="392" fill="#484f58" font-size="11">⏳</text>
685
- <!-- dash edges to synthesis -->
686
- <path d="M90,206 C120,300 280,370 300,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
687
- <path d="M250,206 C270,290 310,370 330,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
688
- <path d="M410,206 L410,372" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
689
- <path d="M570,206 C560,290 500,370 490,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
690
- <path d="M730,206 C710,300 540,370 520,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
691
-
692
- <!-- Model label badges -->
693
- <rect x="22" y="215" width="45" height="16" fill="#1f3a5f" rx="3"/>
694
- <text x="45" y="226" text-anchor="middle" fill="#79c0ff" font-size="8" font-family="monospace">haiku</text>
695
- <rect x="182" y="215" width="45" height="16" fill="#1f3a5f" rx="3"/>
696
- <text x="205" y="226" text-anchor="middle" fill="#79c0ff" font-size="8" font-family="monospace">haiku</text>
697
- <rect x="342" y="215" width="50" height="16" fill="#2d1f5e" rx="3"/>
698
- <text x="367" y="226" text-anchor="middle" fill="#bc8cff" font-size="8" font-family="monospace">sonnet</text>
699
- <rect x="502" y="215" width="50" height="16" fill="#2d1f5e" rx="3"/>
700
- <text x="527" y="226" text-anchor="middle" fill="#bc8cff" font-size="8" font-family="monospace">sonnet</text>
701
- <rect x="662" y="215" width="45" height="16" fill="#1f3a5f" rx="3"/>
702
- <text x="685" y="226" text-anchor="middle" fill="#79c0ff" font-size="8" font-family="monospace">haiku</text>
703
-
704
- <!-- EDGES root → all 5 -->
705
- <path class="e e-spawn" d="M370,68 L90,154" marker-end="url(#ar-sp)"/>
706
- <path class="e e-spawn" d="M390,68 L250,154" marker-end="url(#ar-sp)"/>
707
- <path class="e e-active" d="M410,68 L410,154" marker-end="url(#ar-bl)"/>
708
- <path class="ef ef-scan" d="M410,68 L410,154"/>
709
- <path class="e e-active" d="M430,68 L570,154" marker-end="url(#ar-bl)"/>
710
- <path class="ef ef-scan" d="M430,68 L570,154"/>
711
- <path class="e e-spawn" d="M450,68 L730,154" marker-end="url(#ar-sp)"/>
712
- <!-- tool edges -->
713
- <path class="e e-tool" d="M380,206 L345,270" marker-end="url(#ar-pu)"/>
714
- <path class="ef ef-tool" d="M380,206 L345,270"/>
715
- <path class="e e-spawn" d="M430,206 L475,270" marker-end="url(#ar-sp)"/>
716
- <path class="e e-tool" d="M550,206 L555,270" marker-end="url(#ar-pu)"/>
717
- <path class="ef ef-tool" d="M550,206 L555,270"/>
718
- <path class="e e-spawn" d="M600,206 L685,270" marker-end="url(#ar-sp)"/>
719
- `
720
- },
721
-
722
- // ─────────────────────────────────────────────
723
- // 3: gsd-t-brainstorm (deep research)
724
- // ─────────────────────────────────────────────
725
- {
726
- meta: { cmd:'gsd-t-brainstorm · execution intelligence', tok:'48,700 / 200,000 (24%)', phase:'▶ DEEP RESEARCH' },
727
- timeline: [{l:'deep research',s:'act'},{a:'›',act:true},{l:'synthesis',s:'fut'},{a:'›'},{l:'brainstorm',s:'fut'}],
728
- agents:[
729
- {n:'gsd-t-brainstorm', t:'orchestrator · sonnet', s:'running', tok:'8k'},
730
- {n:'landscape', t:'research agent · sonnet', s:'done', tok:'18k'},
731
- {n:'alternatives',t:'research agent · sonnet', s:'running', tok:'14k'},
732
- {n:'analogies', t:'research agent · sonnet', s:'running', tok:'12k'},
733
- ],
734
- tree:'◆ gsd-t-brainstorm\n└─ Deep Research Phase (mandatory)\n ├─ ✓ landscape (sonnet)\n ├─ ◌ alternatives (sonnet)\n └─ ◌ analogies (sonnet)',
735
- outcomes:'[success] landscape: OTel, AgentOps, LangSmith patterns\n[running] alternatives: evaluating 5 approaches\n[running] analogies: git blame, VS Code timeline',
736
- events:[
737
- {t:'res', msg:'alternatives → WebSearch: agent learning frameworks 2026'},
738
- {t:'res', msg:'analogies → WebFetch: reflexion paper arxiv'},
739
- {t:'done', msg:'landscape: OTel GenAI conventions, 3 reference impls'},
740
- {t:'spawn', msg:'brainstorm → 3 parallel research agents (sonnet)'},
741
- {t:'dec', msg:'Deep Research Phase: mandatory before any conclusions'},
742
- ],
743
- svg: `
744
- <!-- ROOT -->
745
- <g class="ng" onclick="selNode('brainstorm',3)">
746
- <rect class="nr n-session running" x="285" y="20" width="250" height="48" rx="8"/>
747
- <text class="nl" x="410" y="40" text-anchor="middle">gsd-t-brainstorm</text>
748
- <text x="297" y="40" fill="#79c0ff" font-size="11">◆</text>
749
- <text class="ns" x="410" y="54" text-anchor="middle">execution intelligence & visualization</text>
750
- </g>
751
-
752
- <!-- Deep research mandatory label -->
753
- <rect x="250" y="110" width="320" height="28" fill="#2d1f5e" stroke="#bc8cff" stroke-width="1" rx="6"/>
754
- <text x="410" y="129" text-anchor="middle" fill="#bc8cff" font-size="10" font-family="monospace">MANDATORY: Deep Research Phase</text>
755
-
756
- <!-- Parallel bracket -->
757
- <line class="parallel-bracket" x1="120" y1="155" x2="120" y2="170"/>
758
- <line class="parallel-bracket" x1="120" y1="170" x2="700" y2="170"/>
759
- <line class="parallel-bracket" x1="700" y1="155" x2="700" y2="170"/>
760
- <text class="parallel-label" x="410" y="182" text-anchor="middle">── 3 parallel research agents (all sonnet, all blocking) ──</text>
761
-
762
- <!-- landscape done -->
763
- <g class="ng" onclick="selNode('landscape',3)">
764
- <rect class="nr n-done" x="60" y="192" width="185" height="52" rx="8"/>
765
- <text class="nl" x="152" y="212" text-anchor="middle">landscape</text>
766
- <text x="72" y="212" fill="#3fb950" font-size="11">✓</text>
767
- <text class="ns" x="152" y="228" text-anchor="middle">state of field · tools · patterns</text>
768
- </g>
769
- <!-- alternatives running -->
770
- <g class="ng" onclick="selNode('alternatives',3)">
771
- <rect class="nr n-research running" x="320" y="192" width="180" height="52" rx="8"/>
772
- <text class="nl" x="410" y="212" text-anchor="middle">alternatives</text>
773
- <text x="332" y="212" fill="#bc8cff" font-size="11">◌</text>
774
- <text class="ns" x="410" y="228" text-anchor="middle">design options · tradeoffs</text>
775
- </g>
776
- <!-- analogies running -->
777
- <g class="ng" onclick="selNode('analogies',3)">
778
- <rect class="nr n-research running" x="575" y="192" width="185" height="52" rx="8"/>
779
- <text class="nl" x="662" y="212" text-anchor="middle">analogies</text>
780
- <text x="587" y="212" fill="#bc8cff" font-size="11">◌</text>
781
- <text class="ns" x="662" y="228" text-anchor="middle">cross-domain patterns</text>
782
- </g>
783
-
784
- <!-- landscape findings -->
785
- <rect x="40" y="300" width="220" height="80" fill="#1a2e1a" stroke="#3fb950" stroke-width="1" rx="6"/>
786
- <text x="150" y="318" text-anchor="middle" fill="#3fb950" font-size="9" font-family="monospace">✓ landscape findings</text>
787
- <text x="150" y="333" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• OTel GenAI agent spans (dev)</text>
788
- <text x="150" y="347" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• AgentTrace 3-surface model</text>
789
- <text x="150" y="361" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• disler reference impl (Claude)</text>
790
- <text x="150" y="375" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• TRAIL error taxonomy</text>
791
-
792
- <!-- alternatives findings (partial) -->
793
- <rect x="305" y="300" width="210" height="80" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" stroke-dasharray="3,2" rx="6"/>
794
- <text x="410" y="318" text-anchor="middle" fill="#bc8cff" font-size="9" font-family="monospace">◌ alternatives (in progress)</text>
795
- <text x="410" y="333" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• Option A: extend existing files</text>
796
- <text x="410" y="347" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• Option B: JSONL event stream</text>
797
- <text x="410" y="361" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• Option C: intelligence-first</text>
798
- <text x="410" y="375" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">searching 2 more...</text>
799
-
800
- <!-- analogies searching -->
801
- <rect x="555" y="300" width="215" height="80" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" stroke-dasharray="3,2" rx="6"/>
802
- <text x="662" y="318" text-anchor="middle" fill="#bc8cff" font-size="9" font-family="monospace">◌ analogies (in progress)</text>
803
- <text x="662" y="333" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• git blame / git log UX</text>
804
- <text x="662" y="347" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">• VS Code timeline panel (fetch)</text>
805
- <text x="662" y="361" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">• Reflexion paper (reading)</text>
806
-
807
- <!-- Synthesis pending -->
808
- <rect x="280" y="438" width="260" height="52" fill="#161b22" stroke="#30363d" stroke-width="1" rx="8" stroke-dasharray="4,2"/>
809
- <text x="410" y="460" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">synthesis (blocked)</text>
810
- <text x="410" y="476" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">waits for all 3 research agents ✓</text>
811
-
812
- <!-- EDGES -->
813
- <path class="e e-active" d="M410,68 L410,110" marker-end="url(#ar-pu)"/>
814
- <path class="ef ef-res" d="M410,68 L410,110"/>
815
- <path class="e e-active" d="M340,138 L152,192" marker-end="url(#ar-pu)"/>
816
- <path class="ef ef-res" d="M340,138 L152,192"/>
817
- <path class="e e-active" d="M410,138 L410,192" marker-end="url(#ar-pu)"/>
818
- <path class="ef ef-res" d="M410,138 L410,192"/>
819
- <path class="e e-active" d="M480,138 L662,192" marker-end="url(#ar-pu)"/>
820
- <path class="ef ef-res" d="M480,138 L662,192"/>
821
- <!-- agents → findings -->
822
- <path class="e e-spawn" d="M152,244 L150,300" marker-end="url(#ar-sp)"/>
823
- <path class="e e-active" d="M410,244 L410,300" marker-end="url(#ar-pu)"/>
824
- <path class="ef ef-res" d="M410,244 L410,300"/>
825
- <path class="e e-active" d="M662,244 L662,300" marker-end="url(#ar-pu)"/>
826
- <path class="ef ef-res" d="M662,244 L662,300"/>
827
- `
828
- },
829
-
830
- // ─────────────────────────────────────────────
831
- // 4: gsd-t-debug (loop detection + research)
832
- // ─────────────────────────────────────────────
833
- {
834
- meta: { cmd:'gsd-t-debug · auth timeout bug (attempt 3)', tok:'156,400 / 200,000 (78%)', phase:'▶ DEBUG ESCALATION' },
835
- timeline: [{l:'reproduce',s:'done'},{a:'›'},{l:'fix × 2',s:'done'},{a:'›'},{l:'loop detected',s:'act'},{a:'›',act:true},{l:'deep research',s:'fut'}],
836
- agents:[
837
- {n:'gsd-t-debug', t:'orchestrator · sonnet', s:'running', tok:'38k'},
838
- {n:'root-cause', t:'research agent · sonnet', s:'fut', tok:'—'},
839
- {n:'alternatives',t:'research agent · sonnet', s:'fut', tok:'—'},
840
- {n:'prior-art', t:'research agent · sonnet', s:'fut', tok:'—'},
841
- ],
842
- tree:'◆ gsd-t-debug\n├─ ✓ reproduce (repro script)\n├─ ✗ fix attempt 1 (failed)\n├─ ✗ fix attempt 2 (failed)\n└─ ⚠ loop detection triggered\n └─ spawning deep research (3 agents)...',
843
- outcomes:'[failure] fix attempt 1: timeout still occurs\n[failure] fix attempt 2: different failure mode\n[warning] 3+ failed sessions detected in Decision Log\n[escalating] → mandatory deep research mode',
844
- events:[
845
- {t:'err', msg:'fix attempt 2: test still fails (different error)'},
846
- {t:'dec', msg:'[failure] 3+ debug sessions found in Decision Log'},
847
- {t:'trans', msg:'loop detection: escalating to deep research'},
848
- {t:'err', msg:'fix attempt 1: auth timeout unchanged'},
849
- {t:'done', msg:'reproduce: repro script confirms issue'},
850
- {t:'spawn', msg:'debug started · checking Decision Log for prior attempts'},
851
- ],
852
- svg: `
853
- <!-- ROOT -->
854
- <g class="ng" onclick="selNode('debug',4)">
855
- <rect class="nr n-debug running" x="285" y="16" width="250" height="48" rx="8"/>
856
- <text class="nl" x="410" y="36" text-anchor="middle">gsd-t-debug</text>
857
- <text x="297" y="36" fill="#d18616" font-size="11">◆</text>
858
- <text class="ns" x="410" y="50" text-anchor="middle">auth timeout bug · session 3 of 3</text>
859
- </g>
860
-
861
- <!-- History row: prior failed attempts from Decision Log -->
862
- <rect x="20" y="88" width="780" height="48" fill="#2e2210" stroke="#d18616" stroke-width="1" rx="6" opacity=".9"/>
863
- <text x="410" y="107" text-anchor="middle" fill="#d29922" font-size="10" font-family="monospace">⚠ Decision Log: 3 prior [debug] sessions found for "auth timeout"</text>
864
- <text x="410" y="122" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">2026-02-20 · 2026-02-21 · 2026-02-23 — all marked [failure] — loop detection triggered</text>
865
-
866
- <!-- Timeline of this session -->
867
- <!-- reproduce done -->
868
- <g class="ng" onclick="selNode('reproduce',4)">
869
- <rect class="nr n-done" x="40" y="174" width="150" height="52" rx="8"/>
870
- <text class="nl" x="115" y="194" text-anchor="middle">reproduce</text>
871
- <text x="52" y="194" fill="#3fb950" font-size="11">✓</text>
872
- <text class="ns" x="115" y="210" text-anchor="middle">repro script created</text>
873
- </g>
874
- <!-- fix 1 failed -->
875
- <g class="ng" onclick="selNode('fix1',4)">
876
- <rect class="nr n-error nerr" x="220" y="174" width="150" height="52" rx="8"/>
877
- <text class="nl" x="295" y="194" text-anchor="middle">fix attempt 1</text>
878
- <text x="232" y="194" fill="#f85149" font-size="11">✗</text>
879
- <text class="ns" x="295" y="210" text-anchor="middle">timeout unchanged</text>
880
- </g>
881
- <!-- fix 2 failed -->
882
- <g class="ng" onclick="selNode('fix2',4)">
883
- <rect class="nr n-error nerr" x="400" y="174" width="150" height="52" rx="8"/>
884
- <text class="nl" x="475" y="194" text-anchor="middle">fix attempt 2</text>
885
- <text x="412" y="194" fill="#f85149" font-size="11">✗</text>
886
- <text class="ns" x="475" y="210" text-anchor="middle">different failure mode</text>
887
- </g>
888
- <!-- loop detection warning -->
889
- <g class="ng" onclick="selNode('loop',4)">
890
- <rect x="580" y="174" width="200" height="52" fill="#2e2210" stroke="#d29922" stroke-width="2" rx="8" style="animation:npulse 1.5s ease-in-out infinite"/>
891
- <text x="680" y="194" text-anchor="middle" fill="#d29922" font-size="11" font-family="monospace">⚠ loop detected</text>
892
- <text x="680" y="210" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">3 attempts exhausted</text>
893
- </g>
894
-
895
- <!-- Escalation arrow -->
896
- <path d="M660,226 L660,274" stroke="#d29922" stroke-width="2" marker-end="url(#ar-or)" fill="none"/>
897
- <path class="ef" style="stroke:#d18616;stroke-dasharray:6,3;animation:flow 1.2s linear infinite;" d="M660,226 L660,274" fill="none"/>
898
-
899
- <!-- Deep research spawning -->
900
- <rect x="250" y="282" width="320" height="32" fill="#2d1f5e" stroke="#bc8cff" stroke-width="1.5" rx="6"/>
901
- <text x="410" y="303" text-anchor="middle" fill="#bc8cff" font-size="10" font-family="monospace">→ mandatory deep research escalation</text>
902
-
903
- <!-- Research agents spawning -->
904
- <line class="parallel-bracket" x1="130" y1="330" x2="130" y2="344"/>
905
- <line class="parallel-bracket" x1="130" y1="344" x2="690" y2="344"/>
906
- <line class="parallel-bracket" x1="690" y1="330" x2="690" y2="344"/>
907
- <text class="parallel-label" x="410" y="356" text-anchor="middle">── spawning 3 research agents ──</text>
908
-
909
- <!-- root-cause (spawning) -->
910
- <g class="ng" onclick="selNode('root-cause',4)">
911
- <rect x="80" y="364" width="175" height="52" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
912
- <text x="167" y="384" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">root-cause</text>
913
- <text x="92" y="384" fill="#bc8cff" font-size="11">◌</text>
914
- <text class="ns" x="167" y="400" text-anchor="middle">sonnet · spawning...</text>
915
- </g>
916
- <!-- alternatives (spawning) -->
917
- <g class="ng" onclick="selNode('alt-debug',4)">
918
- <rect x="322" y="364" width="175" height="52" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
919
- <text x="409" y="384" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">alternatives</text>
920
- <text x="334" y="384" fill="#bc8cff" font-size="11">◌</text>
921
- <text class="ns" x="409" y="400" text-anchor="middle">sonnet · spawning...</text>
922
- </g>
923
- <!-- prior-art (spawning) -->
924
- <g class="ng" onclick="selNode('prior-art',4)">
925
- <rect x="564" y="364" width="175" height="52" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
926
- <text x="651" y="384" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">prior-art</text>
927
- <text x="576" y="384" fill="#bc8cff" font-size="11">◌</text>
928
- <text class="ns" x="651" y="400" text-anchor="middle">sonnet · spawning...</text>
929
- </g>
930
-
931
- <!-- High context warning -->
932
- <rect x="20" y="450" width="260" height="42" fill="#3a1a1a" stroke="#f85149" stroke-width="1" rx="5"/>
933
- <text x="30" y="466" fill="#f85149" font-size="9" font-family="monospace">⚠ context: 78% (156k / 200k tokens)</text>
934
- <text x="30" y="481" fill="#7d8590" font-size="9" font-family="monospace">research agents get fresh context windows</text>
935
-
936
- <!-- EDGES -->
937
- <path class="e e-spawn" d="M360,64 L115,174" marker-end="url(#ar-sp)"/>
938
- <path class="e e-spawn" d="M380,64 L295,174" marker-end="url(#ar-sp)"/>
939
- <path class="e e-spawn" d="M430,64 L475,174" marker-end="url(#ar-sp)"/>
940
- <path class="e e-spawn" d="M450,64 L680,174" marker-end="url(#ar-sp)"/>
941
- <path class="e e-spawn" d="M115,226 L220,226 L220,174" stroke="#3fb950" marker-end="url(#ar-gr)"/>
942
- <path class="e e-active" d="M380,314 L167,364" marker-end="url(#ar-pu)"/>
943
- <path class="ef ef-res" d="M380,314 L167,364"/>
944
- <path class="e e-active" d="M410,314 L409,364" marker-end="url(#ar-pu)"/>
945
- <path class="ef ef-res" d="M410,314 L409,364"/>
946
- <path class="e e-active" d="M440,314 L651,364" marker-end="url(#ar-pu)"/>
947
- <path class="ef ef-res" d="M440,314 L651,364"/>
948
- `
949
- },
950
-
951
- // ─────────────────────────────────────────────
952
- // 5: gsd-t-quick + error recovery
953
- // ─────────────────────────────────────────────
954
- {
955
- meta: { cmd:'gsd-t-quick · fix checkin hook bug', tok:'28,100 / 200,000 (14%)', phase:'▶ QUICK' },
956
- timeline: [{l:'subagent spawn',s:'done'},{a:'›'},{l:'implement',s:'done'},{a:'›'},{l:'test',s:'act'},{a:'›',act:true},{l:'deviation',s:'fut'},{a:'›'},{l:'verify',s:'fut'}],
957
- agents:[
958
- {n:'gsd-t-quick', t:'orchestrator · sonnet', s:'running', tok:'8k'},
959
- {n:'quick-subagent',t:'subagent · sonnet', s:'running', tok:'20k'},
960
- ],
961
- tree:'◆ gsd-t-quick (Step 0: self-spawn)\n└─ ◌ quick-subagent (fresh context)\n ├─ ✓ implement fix\n ├─ ◌ running tests (4 fail)\n └─ ⏳ deviation rule check pending',
962
- outcomes:'[success] fix implemented: gsd-t-checkin.md line 47\n[running] test suite: 4 failures found\n[pending] deviation rule: auto-fix if possible',
963
- events:[
964
- {t:'err', msg:'quick-subagent → test run: 4 failures (hook timing)'},
965
- {t:'tool', msg:'quick-subagent → Bash: node --test test/'},
966
- {t:'done', msg:'quick-subagent → Edit: gsd-t-checkin.md ✓'},
967
- {t:'spawn', msg:'gsd-t-quick → quick-subagent (Step 0 self-spawn)'},
968
- ],
969
- svg: `
970
- <!-- Root orchestrator (small, stays lightweight) -->
971
- <g class="ng" onclick="selNode('quick',5)">
972
- <rect class="nr n-command" x="335" y="20" width="150" height="44" rx="8"/>
973
- <text class="nl" x="410" y="39" text-anchor="middle">gsd-t-quick</text>
974
- <text x="347" y="39" fill="#bc8cff" font-size="11">◌</text>
975
- <text class="ns" x="410" y="53" text-anchor="middle">orchestrator · Step 0 → subagent</text>
976
- </g>
977
-
978
- <!-- Self-spawn note -->
979
- <rect x="260" y="88" width="300" height="24" fill="#2d1f5e" stroke="#bc8cff" stroke-width="1" rx="5" opacity=".85"/>
980
- <text x="410" y="104" text-anchor="middle" fill="#bc8cff" font-size="9" font-family="monospace">Step 0: self-spawn for fresh context window</text>
981
-
982
- <!-- Quick subagent (main work) -->
983
- <g class="ng" onclick="selNode('quick-sub',5)">
984
- <rect class="nr n-domain running" x="260" y="130" width="300" height="56" rx="8"/>
985
- <text class="nl" x="410" y="153" text-anchor="middle">quick-subagent</text>
986
- <text x="272" y="153" fill="#388bfd" font-size="11">◌</text>
987
- <text class="ns" x="410" y="170" text-anchor="middle">sonnet · fix checkin hook bug · fresh context</text>
988
- </g>
989
-
990
- <!-- Work steps -->
991
- <!-- implement done -->
992
- <g class="ng" onclick="selNode('impl',5)">
993
- <rect class="nr n-done" x="100" y="238" width="160" height="48" rx="8"/>
994
- <text class="nl" x="180" y="258" text-anchor="middle">implement</text>
995
- <text x="112" y="258" fill="#3fb950" font-size="11">✓</text>
996
- <text class="ns" x="180" y="272" text-anchor="middle">Edit: gsd-t-checkin.md</text>
997
- </g>
998
- <!-- test suite running with failures -->
999
- <g class="ng" onclick="selNode('tests',5)">
1000
- <rect class="nr n-qa running" x="330" y="238" width="160" height="48" rx="8"/>
1001
- <text class="nl" x="410" y="258" text-anchor="middle">test suite</text>
1002
- <text x="342" y="258" fill="#d29922" font-size="11">⚑</text>
1003
- <text class="ns" x="410" y="272" text-anchor="middle">127 tests · 4 failing</text>
1004
- </g>
1005
-
1006
- <!-- Error node -->
1007
- <g class="ng" onclick="selNode('err',5)">
1008
- <rect class="nr n-error nerr" x="560" y="238" width="160" height="48" rx="8"/>
1009
- <text class="nl" x="640" y="258" text-anchor="middle">4 failures</text>
1010
- <text x="572" y="258" fill="#f85149" font-size="11">✗</text>
1011
- <text class="ns" x="640" y="272" text-anchor="middle">hook timing (recoverable)</text>
1012
- </g>
1013
-
1014
- <!-- Deviation rule check -->
1015
- <rect x="280" y="342" width="260" height="48" fill="#2e2210" stroke="#d29922" stroke-width="1.5" rx="8"/>
1016
- <text x="410" y="362" text-anchor="middle" fill="#d29922" font-size="10" font-family="monospace">⚑ deviation rule check</text>
1017
- <text x="410" y="378" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">auto-fix: yes (timing, not architecture)</text>
1018
-
1019
- <!-- Deviation rules legend -->
1020
- <rect x="20" y="330" width="230" height="88" fill="#161b22" stroke="#30363d" rx="5" opacity=".95"/>
1021
- <text x="30" y="346" fill="#7d8590" font-size="9" font-family="monospace">DEVIATION RULES</text>
1022
- <text x="30" y="361" fill="#3fb950" font-size="9" font-family="monospace">✓ Rule 1: auto-fix bugs</text>
1023
- <text x="30" y="376" fill="#3fb950" font-size="9" font-family="monospace">✓ Rule 2: add missing functionality</text>
1024
- <text x="30" y="391" fill="#3fb950" font-size="9" font-family="monospace">✓ Rule 3: fix blockers</text>
1025
- <text x="30" y="406" fill="#f85149" font-size="9" font-family="monospace">✗ Rule 4: STOP for arch changes</text>
1026
-
1027
- <!-- Fix attempt 2 (pending) -->
1028
- <rect x="280" y="450" width="260" height="44" fill="#161b22" stroke="#30363d" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
1029
- <text x="410" y="469" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">auto-fix attempt 2 (pending)</text>
1030
- <text x="410" y="483" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">max 3 attempts before escalation</text>
1031
-
1032
- <!-- Tools -->
1033
- <g class="ng"><rect class="nr n-tool-done" x="80" y="352" width="110" height="36" rx="8"/>
1034
- <text class="nl" x="135" y="368" text-anchor="middle" font-size="10">Edit</text>
1035
- <text class="ns" x="135" y="382" text-anchor="middle" fill="#3fb950">✓ line 47</text>
1036
- </g>
1037
- <g class="ng"><rect class="nr n-tool-active" x="210" y="352" width="50" height="36" rx="8"/>
1038
- <text class="nl" x="235" y="368" text-anchor="middle" font-size="10">Bash</text>
1039
- <text class="ns" x="235" y="382" text-anchor="middle">tests</text>
1040
- <circle class="tpulse" cx="222" cy="368" r="4"/>
1041
- </g>
1042
-
1043
- <!-- EDGES -->
1044
- <path class="e e-active" d="M410,64 L410,130" marker-end="url(#ar-bl)"/>
1045
- <path class="ef ef-spawn" d="M410,64 L410,130"/>
1046
- <path class="e e-spawn" d="M360,186 L180,238" marker-end="url(#ar-sp)"/>
1047
- <path class="e e-active" d="M410,186 L410,238" marker-end="url(#ar-bl)"/>
1048
- <path class="ef ef-spawn" d="M410,186 L410,238"/>
1049
- <path class="e e-active" d="M450,186 L640,238" marker-end="url(#ar-bl)"/>
1050
- <path class="ef ef-spawn" d="M450,186 L640,238"/>
1051
- <path class="e e-tool" d="M180,286 L135,352" marker-end="url(#ar-pu)"/>
1052
- <path class="e e-tool" d="M360,286 L235,352" marker-end="url(#ar-pu)"/>
1053
- <path class="ef ef-tool" d="M360,286 L235,352"/>
1054
- <!-- error → deviation -->
1055
- <path d="M620,286 C590,310 520,340 540,366" stroke="#d29922" stroke-width="1.5" marker-end="url(#ar-or)" fill="none"/>
1056
- <path class="e e-active" d="M410,286 L410,342" marker-end="url(#ar-bl)"/>
1057
- <path class="ef ef-spawn" d="M410,286 L410,342"/>
1058
- `
1059
- }
1060
- ];
1061
-
1062
- // ═══════════════════════════════════════════════
1063
- // RENDER ENGINE
1064
- // ═══════════════════════════════════════════════
1065
-
1066
- let currentScene = 0;
1067
- let eventTimer = null;
1068
-
1069
- function showScene(idx) {
1070
- currentScene = idx;
1071
- // Update buttons
1072
- document.querySelectorAll('.scbtn').forEach((b,i)=>b.classList.toggle('active',i===idx));
1073
- const s = SCENES[idx];
1074
- // Header
1075
- document.getElementById('hdr-meta').textContent = 'session: sess_8f3c2a · ' + s.meta.cmd;
1076
- document.getElementById('hdr-tok').textContent = '⬡ ' + s.meta.tok;
1077
- document.getElementById('hdr-phase').textContent = s.meta.phase;
1078
- // Graph
1079
- document.getElementById('scene-content').innerHTML = s.svg;
1080
- // Timeline
1081
- const tl = document.getElementById('timeline-bar');
1082
- tl.innerHTML = s.timeline.map(t =>
1083
- t.a ? `<div class="tla${t.act?' act':''}">›</div>`
1084
- : `<div class="tlp ${t.s}">${t.s==='done'?'✓ ':t.s==='act'?'▶ ':''}${t.l}</div>`
1085
- ).join('');
1086
- // Events
1087
- const el = document.getElementById('evt-log');
1088
- el.innerHTML = s.events.map(e => {
1089
- const now = new Date();
1090
- const ts = `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}`;
1091
- return `<div class="ee"><span class="ets">${ts}</span><span class="et ${e.t}">${e.t.toUpperCase()}</span><span class="em">${e.msg}</span></div>`;
1092
- }).join('');
1093
- // Agents tab
1094
- document.getElementById('agent-list').innerHTML = s.agents.map(a => {
1095
- const sc = {running:'bl',done:'gr',blocked:'',fut:''}[a.s]||'';
1096
- return `<div class="mrow"><span class="ml">${a.n}</span><span class="mv ${sc}">${a.t} · ${a.tok}</span></div>`;
1097
- }).join('');
1098
- document.getElementById('spawn-tree').textContent = s.tree;
1099
- document.getElementById('outcome-log').innerHTML = s.outcomes.split('\n').map(l=>l).join('<br>');
1100
- // Memory stats
1101
- document.getElementById('mem-events').textContent = [248,312,186,94,312,88][idx];
1102
- document.getElementById('mem-agents').textContent = [8,7,6,4,4,2][idx];
1103
- // Live events
1104
- if (eventTimer) clearInterval(eventTimer);
1105
- eventTimer = setInterval(() => addLiveEvent(idx), 4500);
1106
- }
1107
-
1108
- function selNode(id, sceneIdx) {
1109
- // Simple selection feedback — in production this would update sidebar
1110
- const el = document.getElementById('node-name');
1111
- if (el) {
1112
- el.textContent = id;
1113
- el.style.opacity='0';
1114
- setTimeout(()=>{el.style.opacity='1';el.style.transition='opacity .3s';},50);
1115
- }
1116
- }
1117
-
1118
- function stab(t) {
1119
- ['info','agents','memory'].forEach(x=>{
1120
- document.getElementById('sp-'+x).style.display = x===t?'block':'none';
1121
- document.querySelectorAll('.sbtab')[['info','agents','memory'].indexOf(x)].classList.toggle('active',x===t);
1122
- });
1123
- }
1124
-
1125
- function addLiveEvent(idx) {
1126
- const s = SCENES[idx];
1127
- if (!s) return;
1128
- const el = document.getElementById('evt-log');
1129
- const e = s.events[Math.floor(Math.random()*s.events.length)];
1130
- const now = new Date();
1131
- const ts = `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}`;
1132
- const div = document.createElement('div');
1133
- div.className = 'ee enew';
1134
- div.innerHTML = `<span class="ets">${ts}</span><span class="et ${e.t}">${e.t.toUpperCase()}</span><span class="em">${e.msg}</span>`;
1135
- el.insertBefore(div, el.firstChild);
1136
- if (el.children.length > 10) el.removeChild(el.lastChild);
1137
- }
1138
-
1139
- // Boot
1140
- showScene(0);
1141
- </script>
1142
- </body>
1143
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>GSD-T Dashboard — Mockup</title>
6
+ <style>
7
+ :root {
8
+ --bg:#0d1117; --surface:#161b22; --surface2:#21262d; --border:#30363d;
9
+ --text:#e6edf3; --muted:#7d8590; --dim:#484f58;
10
+ --blue:#388bfd; --blue-bg:#1f3a5f;
11
+ --green:#3fb950; --green-bg:#1a3a1e;
12
+ --yellow:#d29922; --yellow-bg:#3a2c10;
13
+ --red:#f85149; --red-bg:#3a1a1a;
14
+ --purple:#bc8cff; --purple-bg:#2d1f5e;
15
+ --cyan:#79c0ff; --orange:#d18616;
16
+ --font:'SF Mono','Fira Code','Cascadia Code',monospace;
17
+ }
18
+ *{box-sizing:border-box;margin:0;padding:0;}
19
+ body{background:var(--bg);color:var(--text);font-family:var(--font);font-size:12px;
20
+ height:100vh;display:flex;flex-direction:column;overflow:hidden;}
21
+
22
+ /* Header */
23
+ .hdr{display:flex;align-items:center;gap:12px;padding:0 16px;
24
+ background:var(--surface);border-bottom:1px solid var(--border);height:40px;flex-shrink:0;}
25
+ .logo{color:var(--blue);font-weight:bold;font-size:13px;}
26
+ .live{display:flex;align-items:center;gap:5px;background:var(--green-bg);
27
+ border:1px solid var(--green);color:var(--green);padding:2px 8px;border-radius:10px;font-size:10px;}
28
+ .ldot{width:6px;height:6px;border-radius:50%;background:var(--green);
29
+ animation:pdot 1.5s ease-in-out infinite;}
30
+ @keyframes pdot{0%,100%{opacity:1}50%{opacity:.3}}
31
+ .hmeta{color:var(--muted);font-size:11px;}
32
+ .hright{margin-left:auto;display:flex;gap:12px;align-items:center;}
33
+ .tok{color:var(--cyan);font-size:11px;}
34
+ .pbadge{background:var(--blue-bg);border:1px solid var(--blue);color:var(--blue);
35
+ padding:2px 10px;border-radius:4px;font-size:11px;}
36
+
37
+ /* Scenario bar */
38
+ .scbar{display:flex;gap:4px;padding:8px 16px;background:var(--surface);
39
+ border-bottom:1px solid var(--border);flex-shrink:0;overflow-x:auto;}
40
+ .scbtn{padding:5px 14px;border-radius:5px;font-family:var(--font);font-size:11px;
41
+ cursor:pointer;border:1px solid var(--border);background:transparent;color:var(--muted);
42
+ white-space:nowrap;transition:all .15s;}
43
+ .scbtn:hover{border-color:var(--blue);color:var(--blue);}
44
+ .scbtn.active{background:var(--blue-bg);border-color:var(--blue);color:var(--blue);}
45
+
46
+ /* Main */
47
+ .main{display:flex;flex:1;overflow:hidden;}
48
+
49
+ /* Graph */
50
+ .garea{flex:1;position:relative;overflow:hidden;background:var(--bg);
51
+ background-image:radial-gradient(circle at 1px 1px,var(--border) 1px,transparent 0);
52
+ background-size:24px 24px;}
53
+ svg.g{position:absolute;width:100%;height:100%;overflow:visible;}
54
+
55
+ /* Nodes */
56
+ .ng{cursor:pointer;}
57
+ .ng:hover rect.nr{filter:brightness(1.25);}
58
+ .nr{transition:filter .2s;}
59
+ .n-session {fill:#1a1f2e;stroke:var(--blue);stroke-width:1.5;}
60
+ .n-command {fill:#1e1a2e;stroke:var(--purple);stroke-width:1.5;}
61
+ .n-domain {fill:#1a2e1a;stroke:var(--green);stroke-width:1.5;}
62
+ .n-qa {fill:#2e2a1a;stroke:var(--yellow);stroke-width:1.5;}
63
+ .n-scan {fill:#1a1e2e;stroke:var(--cyan);stroke-width:1.5;}
64
+ .n-research{fill:#2e1a2e;stroke:var(--purple);stroke-width:1.5;}
65
+ .n-error {fill:var(--red-bg);stroke:var(--red);stroke-width:1.5;}
66
+ .n-done {fill:#1a2e1a;stroke:var(--green);stroke-width:1.5;}
67
+ .n-pending {fill:#161b22;stroke:var(--dim);stroke-width:1;}
68
+ .n-debug {fill:#2e2210;stroke:var(--orange);stroke-width:1.5;}
69
+ .n-tool-active{fill:#1e1a2e;stroke:var(--purple);stroke-width:1.5;}
70
+ .n-tool-done {fill:#1a2e1a;stroke:var(--green);stroke-width:1;}
71
+
72
+ .running{animation:npulse 2s ease-in-out infinite;}
73
+ @keyframes npulse{0%,100%{stroke-opacity:1;stroke-width:1.5}50%{stroke-opacity:.4;stroke-width:2.5}}
74
+ .nerr{animation:nerror .4s ease-in-out 4;}
75
+ @keyframes nerror{0%,100%{stroke-width:1.5}50%{stroke-width:3}}
76
+
77
+ .nl{fill:var(--text);font-size:11px;font-family:var(--font);font-weight:500;}
78
+ .ns{fill:var(--muted);font-size:9px;font-family:var(--font);}
79
+ .nd{fill:var(--dim);font-size:11px;}
80
+
81
+ /* Edges */
82
+ .e{fill:none;stroke-width:1.5;}
83
+ .e-spawn {stroke:var(--border);}
84
+ .e-active{stroke:var(--blue);stroke-width:2;}
85
+ .e-tool {stroke:var(--purple);stroke-dasharray:3,2;}
86
+ .e-msg {stroke:var(--cyan);stroke-dasharray:4,3;}
87
+ .e-pending{stroke:var(--dim);stroke-width:1;stroke-dasharray:2,3;}
88
+
89
+ .ef{fill:none;stroke-width:2;stroke-dasharray:8,4;animation:flow 1.4s linear infinite;}
90
+ .ef-spawn{stroke:var(--blue);}
91
+ .ef-tool {stroke:var(--purple);}
92
+ .ef-msg {stroke:var(--cyan);}
93
+ .ef-scan {stroke:var(--cyan);}
94
+ .ef-res {stroke:var(--purple);}
95
+ @keyframes flow{to{stroke-dashoffset:-24}}
96
+
97
+ .tpulse{fill:none;stroke:var(--purple);stroke-width:1;
98
+ animation:texp 1.6s ease-out infinite;}
99
+ @keyframes texp{0%{r:5;opacity:.9}100%{r:18;opacity:0}}
100
+
101
+ /* Sidebar */
102
+ .sb{width:280px;background:var(--surface);border-left:1px solid var(--border);
103
+ display:flex;flex-direction:column;flex-shrink:0;overflow:hidden;}
104
+ .sbtabs{display:flex;border-bottom:1px solid var(--border);flex-shrink:0;}
105
+ .sbtab{flex:1;padding:8px;text-align:center;color:var(--muted);cursor:pointer;
106
+ font-size:11px;border-bottom:2px solid transparent;transition:all .15s;}
107
+ .sbtab.active{color:var(--blue);border-bottom-color:var(--blue);}
108
+ .sbcont{flex:1;overflow-y:auto;padding:12px;}
109
+ .sbcont::-webkit-scrollbar{width:4px;}
110
+ .sbcont::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px;}
111
+ .ssect{margin-bottom:14px;}
112
+ .stitle{color:var(--muted);font-size:10px;text-transform:uppercase;
113
+ letter-spacing:.8px;margin-bottom:7px;}
114
+ .mrow{display:flex;justify-content:space-between;padding:4px 0;
115
+ border-bottom:1px solid var(--surface2);font-size:11px;}
116
+ .ml{color:var(--muted)}.mv{color:var(--text)}
117
+ .mv.gr{color:var(--green)}.mv.bl{color:var(--blue)}
118
+ .mv.yl{color:var(--yellow)}.mv.rd{color:var(--red)}
119
+ .rbox{background:var(--surface2);border:1px solid var(--border);border-radius:6px;
120
+ padding:8px;margin-top:6px;color:var(--muted);font-size:10px;line-height:1.5;
121
+ border-left:3px solid var(--blue);}
122
+ .xitem{background:var(--surface2);border-radius:4px;padding:6px 8px;
123
+ margin-bottom:6px;border-left:3px solid var(--yellow);}
124
+ .xitem.s{border-left-color:var(--green);}
125
+ .xitem.f{border-left-color:var(--red);}
126
+ .xtag{display:inline-block;font-size:9px;padding:1px 5px;border-radius:3px;
127
+ margin-bottom:3px;font-weight:bold;}
128
+ .t-f{background:var(--red-bg);color:var(--red);}
129
+ .t-s{background:var(--green-bg);color:var(--green);}
130
+ .t-l{background:var(--blue-bg);color:var(--blue);}
131
+ .t-d{background:var(--surface2);color:var(--muted);}
132
+ .xt{color:var(--muted);font-size:10px;line-height:1.4;}
133
+ .xd{color:var(--dim);font-size:9px;margin-top:2px;}
134
+ .pbw{height:3px;background:var(--surface2);border-radius:2px;margin:4px 0;}
135
+ .pbf{height:100%;background:var(--green);border-radius:2px;transition:width .5s;}
136
+ .spin{display:inline-block;width:9px;height:9px;border:1.5px solid var(--border);
137
+ border-top-color:var(--blue);border-radius:50%;animation:sp .8s linear infinite;
138
+ vertical-align:middle;margin-right:3px;}
139
+ @keyframes sp{to{transform:rotate(360deg)}}
140
+
141
+ /* Agent count badges */
142
+ .abadge{display:inline-flex;align-items:center;justify-content:center;
143
+ width:18px;height:18px;border-radius:50%;font-size:9px;font-weight:bold;
144
+ background:var(--blue-bg);color:var(--blue);border:1px solid var(--blue);}
145
+ .abadge.yl{background:var(--yellow-bg);color:var(--yellow);border-color:var(--yellow);}
146
+ .abadge.gr{background:var(--green-bg);color:var(--green);border-color:var(--green);}
147
+ .abadge.pu{background:var(--purple-bg);color:var(--purple);border-color:var(--purple);}
148
+
149
+ /* Event log */
150
+ .elog{border-top:1px solid var(--border);flex-shrink:0;height:130px;
151
+ overflow-y:auto;padding:8px;}
152
+ .elog::-webkit-scrollbar{width:4px;}
153
+ .elog::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px;}
154
+ .ee{display:flex;gap:6px;align-items:flex-start;padding:3px 0;
155
+ border-bottom:1px solid var(--surface2);font-size:10px;line-height:1.3;}
156
+ .ets{color:var(--dim);flex-shrink:0;}
157
+ .et{flex-shrink:0;font-weight:bold;}
158
+ .et.spawn{color:var(--blue)}.et.tool{color:var(--purple)}
159
+ .et.trans{color:var(--cyan)}.et.dec{color:var(--yellow)}
160
+ .et.err{color:var(--red)}.et.done{color:var(--green)}
161
+ .et.res{color:var(--purple)}
162
+ .em{color:var(--muted);}
163
+ .enew{animation:fnew 1s ease-out;}
164
+ @keyframes fnew{from{background:var(--blue-bg)}to{background:transparent}}
165
+
166
+ /* Timeline */
167
+ .tl{height:50px;background:var(--surface);border-top:1px solid var(--border);
168
+ flex-shrink:0;display:flex;align-items:center;padding:0 16px;gap:0;overflow-x:auto;}
169
+ .tlp{display:flex;align-items:center;gap:5px;padding:5px 10px;border-radius:4px;
170
+ font-size:10px;flex-shrink:0;}
171
+ .tlp.done{color:var(--green);background:var(--green-bg);}
172
+ .tlp.act{color:var(--blue);background:var(--blue-bg);
173
+ animation:tlpulse 2s ease-in-out infinite;}
174
+ .tlp.fut{color:var(--dim);}
175
+ @keyframes tlpulse{0%,100%{background:var(--blue-bg)}50%{background:#1a2f5e}}
176
+ .tla{color:var(--border);padding:0 3px;font-size:13px;}
177
+ .tla.act{color:var(--blue);animation:farr .8s ease-in-out infinite;}
178
+ @keyframes farr{0%,100%{opacity:1}50%{opacity:.2}}
179
+
180
+ /* Sync animation for parallel nodes */
181
+ .parallel-bracket{fill:none;stroke:var(--dim);stroke-width:1;stroke-dasharray:3,2;}
182
+ .parallel-label{fill:var(--dim);font-size:9px;font-family:var(--font);}
183
+ </style>
184
+ </head>
185
+ <body>
186
+
187
+ <div class="hdr">
188
+ <div class="logo">◆ GSD-T</div>
189
+ <div class="live"><div class="ldot"></div>LIVE</div>
190
+ <div class="hmeta" id="hdr-meta">session: sess_8f3c2a · gsd-t-wave → M14</div>
191
+ <div class="hright">
192
+ <div class="tok" id="hdr-tok">⬡ 87,432 / 200,000 (43%)</div>
193
+ <div class="pbadge" id="hdr-phase">▶ EXECUTE</div>
194
+ </div>
195
+ </div>
196
+
197
+ <!-- Scenario selector -->
198
+ <div class="scbar">
199
+ <button class="scbtn active" onclick="showScene(0)">wave / execute (parallel domains)</button>
200
+ <button class="scbtn" onclick="showScene(1)">execute: 3 domains × 3 QA agents</button>
201
+ <button class="scbtn" onclick="showScene(2)">gsd-t-scan (5 parallel agents)</button>
202
+ <button class="scbtn" onclick="showScene(3)">gsd-t-brainstorm (deep research)</button>
203
+ <button class="scbtn" onclick="showScene(4)">gsd-t-debug (loop detection)</button>
204
+ <button class="scbtn" onclick="showScene(5)">gsd-t-quick + error recovery</button>
205
+ </div>
206
+
207
+ <div class="main">
208
+ <div class="garea">
209
+ <svg class="g" id="graph-svg" viewBox="0 0 820 520">
210
+ <defs>
211
+ <marker id="ar-sp" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#30363d"/></marker>
212
+ <marker id="ar-bl" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#388bfd"/></marker>
213
+ <marker id="ar-pu" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#bc8cff"/></marker>
214
+ <marker id="ar-cy" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#79c0ff"/></marker>
215
+ <marker id="ar-gr" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#3fb950"/></marker>
216
+ <marker id="ar-or" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3z" fill="#d18616"/></marker>
217
+ </defs>
218
+ <g id="scene-content"></g>
219
+ </svg>
220
+ </div>
221
+
222
+ <!-- Sidebar -->
223
+ <div class="sb">
224
+ <div class="sbtabs">
225
+ <div class="sbtab active" onclick="stab('info')">Info</div>
226
+ <div class="sbtab" onclick="stab('agents')">Agents</div>
227
+ <div class="sbtab" onclick="stab('memory')">Memory</div>
228
+ </div>
229
+ <div class="sbcont" id="sp-info">
230
+ <div class="ssect">
231
+ <div class="stitle">Selected Node</div>
232
+ <div id="node-name" style="font-size:13px;font-weight:bold;margin-bottom:4px;color:var(--text)">gsd-t-wave</div>
233
+ <div id="node-type" style="font-size:10px;color:var(--muted);margin-bottom:10px">orchestrator · session root</div>
234
+ <div class="mrow"><span class="ml">status</span><span class="mv bl" id="nv-status"><span class="spin"></span>running</span></div>
235
+ <div class="mrow"><span class="ml">command</span><span class="mv" id="nv-cmd">gsd-t-wave</span></div>
236
+ <div class="mrow"><span class="ml">phase</span><span class="mv" id="nv-phase">EXECUTE</span></div>
237
+ <div class="mrow"><span class="ml">duration</span><span class="mv" id="nv-dur">2m 28s</span></div>
238
+ <div class="mrow"><span class="ml">tokens</span><span class="mv" id="nv-tok">87,432</span></div>
239
+ <div class="mrow"><span class="ml">model</span><span class="mv" id="nv-model">sonnet</span></div>
240
+ <div class="pbw"><div class="pbf" id="nv-prog" style="width:43%"></div></div>
241
+ <div style="font-size:9px;color:var(--muted);text-align:right;margin-top:2px" id="nv-tasks">7/19 tasks</div>
242
+ </div>
243
+ <div class="ssect">
244
+ <div class="stitle">Current Reasoning</div>
245
+ <div class="rbox" id="nv-reason">Orchestrating parallel domain execution — event-capture ✓, learning-loop running (task 3/7), visualization blocked pending event-capture contract.</div>
246
+ </div>
247
+ <div class="ssect" id="exp-section">
248
+ <div class="stitle">Past Experience Surfaced</div>
249
+ <div class="xitem f"><span class="xtag t-f">[failure]</span>
250
+ <div class="xt" id="nv-exp1">Pre-task retrieval didn't apply to team mode spawn — domain subagents in parallel mode missed past experience context</div>
251
+ <div class="xd">2026-02-19 · execute domain</div>
252
+ </div>
253
+ <div class="xitem s"><span class="xtag t-s">[success]</span>
254
+ <div class="xt">Zero-dep chokidar watch pattern works reliably for JSONL file monitoring</div>
255
+ <div class="xd">2026-02-22 · cli domain</div>
256
+ </div>
257
+ </div>
258
+ </div>
259
+ <div class="sbcont" id="sp-agents" style="display:none">
260
+ <div class="ssect">
261
+ <div class="stitle">Active Agents</div>
262
+ <div id="agent-list"></div>
263
+ </div>
264
+ <div class="ssect">
265
+ <div class="stitle">Spawn Tree</div>
266
+ <div id="spawn-tree" style="font-size:10px;color:var(--muted);line-height:2;font-family:var(--font)"></div>
267
+ </div>
268
+ </div>
269
+ <div class="sbcont" id="sp-memory" style="display:none">
270
+ <div class="ssect">
271
+ <div class="stitle">Session Stats</div>
272
+ <div class="mrow"><span class="ml">events logged</span><span class="mv bl" id="mem-events">248</span></div>
273
+ <div class="mrow"><span class="ml">agents spawned</span><span class="mv" id="mem-agents">8</span></div>
274
+ <div class="mrow"><span class="ml">decisions captured</span><span class="mv" id="mem-dec">14</span></div>
275
+ <div class="mrow"><span class="ml">failures surfaced</span><span class="mv yl" id="mem-fail">2</span></div>
276
+ <div class="mrow"><span class="ml">lessons applied</span><span class="mv gr" id="mem-les">3</span></div>
277
+ <div class="mrow"><span class="ml">errors</span><span class="mv rd" id="mem-err">0</span></div>
278
+ </div>
279
+ <div class="ssect">
280
+ <div class="stitle">Outcome Log</div>
281
+ <div id="outcome-log" style="font-size:10px;color:var(--muted);line-height:1.8;"></div>
282
+ </div>
283
+ </div>
284
+ <div class="elog" id="evt-log"></div>
285
+ </div>
286
+ </div>
287
+
288
+ <div class="tl" id="timeline-bar"></div>
289
+
290
+ <script>
291
+ // ═══════════════════════════════════════════════
292
+ // SCENE DEFINITIONS
293
+ // ═══════════════════════════════════════════════
294
+
295
+ const SCENES = [
296
+
297
+ // ─────────────────────────────────────────────
298
+ // 0: wave / execute (parallel domains)
299
+ // ─────────────────────────────────────────────
300
+ {
301
+ meta: { cmd:'gsd-t-wave → M14', tok:'87,432 / 200,000 (43%)', phase:'▶ EXECUTE' },
302
+ timeline: [
303
+ {l:'partition',s:'done'},{a:'›'},{l:'plan',s:'done'},{a:'›'},
304
+ {l:'execute',s:'act'},{a:'›',act:true},{l:'test-sync',s:'fut'},{a:'›'},
305
+ {l:'integrate',s:'fut'},{a:'›'},{l:'verify',s:'fut'},{a:'›'},{l:'complete',s:'fut'}
306
+ ],
307
+ agents:[
308
+ {n:'gsd-t-wave', t:'orchestrator', s:'running', tok:'87k'},
309
+ {n:'execute', t:'phase agent', s:'running', tok:'41k'},
310
+ {n:'event-capture', t:'domain', s:'done', tok:'19k'},
311
+ {n:'learning-loop', t:'domain', s:'running', tok:'47k'},
312
+ {n:'visualization', t:'domain', s:'blocked', tok:'—'},
313
+ {n:'qa-agent', t:'QA · haiku', s:'running', tok:'3k'},
314
+ ],
315
+ tree:'◆ gsd-t-wave\n└─ execute\n ├─ ✓ event-capture\n ├─ ◌ learning-loop\n │ └─ ⚑ qa-agent\n └─ ⏳ visualization (blocked)',
316
+ outcomes:'[success] event-capture: 6/6 tasks done\n[running] learning-loop: task 3/7\n[blocked] visualization: waiting on event-capture contract',
317
+ events:[
318
+ {t:'tool', msg:'learning-loop → Bash: npm test'},
319
+ {t:'spawn', msg:'learning-loop → qa-agent (haiku)'},
320
+ {t:'dec', msg:'[learning] 2 past entries surfaced for learning-loop'},
321
+ {t:'done', msg:'event-capture: 6/6 tasks ✓ 48s'},
322
+ {t:'trans', msg:'plan → execute · 19 tasks, 3 domains'},
323
+ {t:'spawn', msg:'execute → learning-loop, event-capture (parallel)'},
324
+ ],
325
+ svg: `
326
+ <!-- ROOT -->
327
+ <g class="ng" onclick="selNode('wave',0)">
328
+ <rect class="nr n-session running" x="310" y="16" width="200" height="48" rx="8"/>
329
+ <text class="nl" x="410" y="36" text-anchor="middle">gsd-t-wave</text>
330
+ <text class="ns" x="410" y="52" text-anchor="middle">orchestrator · M14: Execution Intelligence</text>
331
+ <text x="322" y="36" fill="#79c0ff" font-size="11">◆</text>
332
+ </g>
333
+ <!-- EXECUTE phase -->
334
+ <g class="ng" onclick="selNode('execute',0)">
335
+ <rect class="nr n-domain running" x="310" y="108" width="200" height="44" rx="8"/>
336
+ <text class="nl" x="410" y="127" text-anchor="middle">execute</text>
337
+ <text x="322" y="127" fill="#388bfd" font-size="11">◌</text>
338
+ <text class="ns" x="410" y="141" text-anchor="middle">phase agent · 7/19 tasks · 2m14s</text>
339
+ </g>
340
+ <!-- PARTITION done -->
341
+ <g class="ng" onclick="selNode('partition',0)">
342
+ <rect class="nr n-done" x="30" y="108" width="130" height="44" rx="8"/>
343
+ <text class="nl" x="95" y="127" text-anchor="middle">partition</text>
344
+ <text class="ns" x="95" y="141" text-anchor="middle">✓ 3 domains · 12s</text>
345
+ <text x="42" y="127" fill="#3fb950" font-size="11">✓</text>
346
+ </g>
347
+ <!-- PLAN done -->
348
+ <g class="ng" onclick="selNode('plan',0)">
349
+ <rect class="nr n-done" x="180" y="108" width="110" height="44" rx="8"/>
350
+ <text class="nl" x="235" y="127" text-anchor="middle">plan</text>
351
+ <text class="ns" x="235" y="141" text-anchor="middle">✓ 19 tasks · 28s</text>
352
+ <text x="192" y="127" fill="#3fb950" font-size="11">✓</text>
353
+ </g>
354
+ <!-- VERIFY pending -->
355
+ <g class="ng" onclick="selNode('verify',0)">
356
+ <rect class="nr n-pending" x="530" y="108" width="120" height="44" rx="8"/>
357
+ <text class="nd" x="590" y="127" text-anchor="middle">verify</text>
358
+ <text class="ns" x="590" y="141" text-anchor="middle">pending</text>
359
+ </g>
360
+
361
+ <!-- PARALLEL bracket -->
362
+ <line class="parallel-bracket" x1="80" y1="205" x2="80" y2="220"/>
363
+ <line class="parallel-bracket" x1="80" y1="220" x2="700" y2="220"/>
364
+ <line class="parallel-bracket" x1="700" y1="205" x2="700" y2="220"/>
365
+ <text class="parallel-label" x="390" y="232" text-anchor="middle">── parallel domain subagents ──</text>
366
+
367
+ <!-- DOMAINS -->
368
+ <!-- event-capture done -->
369
+ <g class="ng" onclick="selNode('event-capture',0)">
370
+ <rect class="nr n-done" x="60" y="240" width="160" height="52" rx="8"/>
371
+ <text class="nl" x="140" y="260" text-anchor="middle">event-capture</text>
372
+ <text x="72" y="260" fill="#3fb950" font-size="11">✓</text>
373
+ <text class="ns" x="140" y="276" text-anchor="middle">6/6 tasks · sonnet · 48s</text>
374
+ </g>
375
+ <!-- learning-loop running -->
376
+ <g class="ng" onclick="selNode('learning-loop',0)">
377
+ <rect class="nr n-domain running" x="330" y="240" width="160" height="52" rx="8"/>
378
+ <text class="nl" x="410" y="260" text-anchor="middle">learning-loop</text>
379
+ <text x="342" y="260" fill="#388bfd" font-size="11">◌</text>
380
+ <text class="ns" x="410" y="276" text-anchor="middle">task 3/7 · sonnet · 1m02s</text>
381
+ </g>
382
+ <!-- visualization blocked -->
383
+ <g class="ng" onclick="selNode('visualization',0)">
384
+ <rect class="nr n-pending" x="600" y="240" width="160" height="52" rx="8"/>
385
+ <text class="nd" x="680" y="260" text-anchor="middle">visualization</text>
386
+ <text x="612" y="260" fill="#484f58" font-size="11">⏳</text>
387
+ <text class="ns" x="680" y="276" text-anchor="middle">blocked · 7 tasks pending</text>
388
+ </g>
389
+
390
+ <!-- QA agent under learning-loop -->
391
+ <g class="ng" onclick="selNode('qa',0)">
392
+ <rect class="nr n-qa" x="340" y="348" width="140" height="44" rx="8"/>
393
+ <text class="nl" x="410" y="367" text-anchor="middle">qa-agent</text>
394
+ <text x="352" y="367" fill="#d29922" font-size="11">⚑</text>
395
+ <text class="ns" x="410" y="381" text-anchor="middle">haiku · running tests</text>
396
+ </g>
397
+ <!-- Bash tool -->
398
+ <g class="ng" onclick="selNode('bash',0)">
399
+ <rect class="nr n-tool-active" x="280" y="448" width="120" height="36" rx="8"/>
400
+ <text class="nl" x="340" y="464" text-anchor="middle" font-size="10">Bash</text>
401
+ <text class="ns" x="340" y="478" text-anchor="middle">npm test</text>
402
+ <text x="292" y="464" fill="#bc8cff" font-size="10">⬡</text>
403
+ <circle class="tpulse" cx="292" cy="464" r="5"/>
404
+ </g>
405
+ <!-- Edit done -->
406
+ <g class="ng" onclick="selNode('edit',0)">
407
+ <rect class="nr n-tool-done" x="430" y="448" width="110" height="36" rx="8"/>
408
+ <text class="nl" x="485" y="464" text-anchor="middle" font-size="10">Edit</text>
409
+ <text class="ns" x="485" y="478" text-anchor="middle" fill="#3fb950">✓ 3 files</text>
410
+ </g>
411
+
412
+ <!-- Experience warning -->
413
+ <rect x="30" y="318" width="170" height="44" fill="#3a2c10" stroke="#d29922" stroke-width="1" rx="5" opacity=".92"/>
414
+ <text x="115" y="334" text-anchor="middle" fill="#d29922" font-size="9" font-family="monospace">⚠ past experience surfaced</text>
415
+ <text x="115" y="347" text-anchor="middle" fill="#d29922" font-size="9" font-family="monospace">[failure] team mode missed retrieval</text>
416
+ <text x="115" y="359" text-anchor="middle" fill="#d29922" font-size="8" font-family="monospace" opacity=".7">→ applying fix to parallel spawn</text>
417
+ <path d="M200,340 L330,268" stroke="#d29922" stroke-width="1" stroke-dasharray="3,2" opacity=".6" marker-end="url(#ar-or)"/>
418
+
419
+ <!-- EDGES -->
420
+ <path class="e e-spawn" d="M360,64 L95,108" marker-end="url(#ar-sp)"/>
421
+ <path class="e e-spawn" d="M370,64 L235,108" marker-end="url(#ar-sp)"/>
422
+ <path class="e e-active" d="M410,64 L410,108" marker-end="url(#ar-bl)"/>
423
+ <path class="ef ef-spawn" d="M410,64 L410,108"/>
424
+ <path class="e e-pending" d="M450,64 L590,108" marker-end="url(#ar-sp)"/>
425
+ <path class="e e-spawn" d="M370,152 L140,240" marker-end="url(#ar-sp)"/>
426
+ <path class="e e-active" d="M410,152 L410,240" marker-end="url(#ar-bl)"/>
427
+ <path class="ef ef-spawn" d="M410,152 L410,240"/>
428
+ <path class="e e-pending" d="M450,152 L680,240" marker-end="url(#ar-sp)" stroke-opacity=".4"/>
429
+ <path class="e e-active" d="M410,292 L410,348" marker-end="url(#ar-bl)"/>
430
+ <path class="ef ef-spawn" d="M410,292 L410,348"/>
431
+ <path class="e e-tool" d="M390,292 C370,380 350,420 340,448" marker-end="url(#ar-pu)"/>
432
+ <path class="ef ef-tool" d="M390,292 C370,380 350,420 340,448"/>
433
+ <path class="e e-spawn" d="M430,292 C450,380 470,420 485,448" marker-end="url(#ar-sp)"/>
434
+ `
435
+ },
436
+
437
+ // ─────────────────────────────────────────────
438
+ // 1: 3 domains × 3 QA agents
439
+ // ─────────────────────────────────────────────
440
+ {
441
+ meta: { cmd:'gsd-t-execute · M14 · 3 domains in parallel', tok:'142,100 / 200,000 (71%)', phase:'▶ EXECUTE' },
442
+ timeline: [
443
+ {l:'partition',s:'done'},{a:'›'},{l:'plan',s:'done'},{a:'›'},
444
+ {l:'execute',s:'act'},{a:'›',act:true},{l:'test-sync',s:'fut'},{a:'›'},{l:'verify',s:'fut'}
445
+ ],
446
+ agents:[
447
+ {n:'execute', t:'orchestrator', s:'running', tok:'18k'},
448
+ {n:'backend', t:'domain · sonnet', s:'running', tok:'55k'},
449
+ {n:'frontend', t:'domain · sonnet', s:'running', tok:'42k'},
450
+ {n:'cli', t:'domain · sonnet', s:'done', tok:'27k'},
451
+ {n:'qa-backend', t:'QA · haiku', s:'running', tok:'8k'},
452
+ {n:'qa-frontend',t:'QA · haiku', s:'running', tok:'6k'},
453
+ {n:'qa-cli', t:'QA · haiku', s:'done', tok:'4k'},
454
+ ],
455
+ tree:'◆ execute (orchestrator)\n├─ ◌ backend\n│ └─ ⚑ qa-backend (haiku)\n├─ ◌ frontend\n│ └─ ⚑ qa-frontend (haiku)\n└─ ✓ cli\n └─ ✓ qa-cli (haiku)',
456
+ outcomes:'[running] backend: task 4/8, qa watching\n[running] frontend: task 2/6, qa watching\n[success] cli: 5/5 tasks, 127/127 tests pass',
457
+ events:[
458
+ {t:'tool', msg:'qa-backend → Bash: npm test -- auth'},
459
+ {t:'tool', msg:'qa-frontend → Bash: playwright test'},
460
+ {t:'done', msg:'cli domain: 5/5 tasks ✓ 127 tests pass'},
461
+ {t:'spawn', msg:'execute → qa-frontend (haiku, parallel)'},
462
+ {t:'spawn', msg:'execute → qa-backend (haiku, parallel)'},
463
+ {t:'spawn', msg:'execute → backend, frontend, cli (parallel)'},
464
+ ],
465
+ svg: `
466
+ <!-- Execute root -->
467
+ <g class="ng" onclick="selNode('execute',1)">
468
+ <rect class="nr n-command running" x="310" y="20" width="200" height="48" rx="8"/>
469
+ <text class="nl" x="410" y="40" text-anchor="middle">execute</text>
470
+ <text x="322" y="40" fill="#bc8cff" font-size="11">◌</text>
471
+ <text class="ns" x="410" y="54" text-anchor="middle">orchestrator · 3 parallel domains</text>
472
+ </g>
473
+
474
+ <!-- Parallel bracket -->
475
+ <line class="parallel-bracket" x1="100" y1="115" x2="100" y2="130"/>
476
+ <line class="parallel-bracket" x1="100" y1="130" x2="720" y2="130"/>
477
+ <line class="parallel-bracket" x1="720" y1="115" x2="720" y2="130"/>
478
+ <text class="parallel-label" x="410" y="143" text-anchor="middle">── 3 domain subagents (parallel, each with own QA agent) ──</text>
479
+
480
+ <!-- BACKEND domain running -->
481
+ <g class="ng" onclick="selNode('backend',1)">
482
+ <rect class="nr n-domain running" x="60" y="152" width="160" height="52" rx="8"/>
483
+ <text class="nl" x="140" y="172" text-anchor="middle">backend</text>
484
+ <text x="72" y="172" fill="#388bfd" font-size="11">◌</text>
485
+ <text class="ns" x="140" y="188" text-anchor="middle">task 4/8 · sonnet · 3m12s</text>
486
+ </g>
487
+ <!-- FRONTEND domain running -->
488
+ <g class="ng" onclick="selNode('frontend',1)">
489
+ <rect class="nr n-domain running" x="330" y="152" width="160" height="52" rx="8"/>
490
+ <text class="nl" x="410" y="172" text-anchor="middle">frontend</text>
491
+ <text x="342" y="172" fill="#388bfd" font-size="11">◌</text>
492
+ <text class="ns" x="410" y="188" text-anchor="middle">task 2/6 · sonnet · 2m44s</text>
493
+ </g>
494
+ <!-- CLI domain done -->
495
+ <g class="ng" onclick="selNode('cli',1)">
496
+ <rect class="nr n-done" x="600" y="152" width="160" height="52" rx="8"/>
497
+ <text class="nl" x="680" y="172" text-anchor="middle">cli</text>
498
+ <text x="612" y="172" fill="#3fb950" font-size="11">✓</text>
499
+ <text class="ns" x="680" y="188" text-anchor="middle">5/5 tasks · sonnet · 1m18s</text>
500
+ </g>
501
+
502
+ <!-- QA AGENTS row — all three visible simultaneously -->
503
+ <text class="parallel-label" x="410" y="267" text-anchor="middle">── QA agents (one per domain, spawned after each task) ──</text>
504
+
505
+ <!-- qa-backend running -->
506
+ <g class="ng" onclick="selNode('qa-backend',1)">
507
+ <rect class="nr n-qa running" x="50" y="276" width="170" height="48" rx="8"/>
508
+ <text class="nl" x="135" y="296" text-anchor="middle">qa-backend</text>
509
+ <text x="62" y="296" fill="#d29922" font-size="11">⚑</text>
510
+ <text class="ns" x="135" y="310" text-anchor="middle">haiku · npm test -- auth</text>
511
+ </g>
512
+ <!-- qa-frontend running -->
513
+ <g class="ng" onclick="selNode('qa-frontend',1)">
514
+ <rect class="nr n-qa running" x="320" y="276" width="180" height="48" rx="8"/>
515
+ <text class="nl" x="410" y="296" text-anchor="middle">qa-frontend</text>
516
+ <text x="332" y="296" fill="#d29922" font-size="11">⚑</text>
517
+ <text class="ns" x="410" y="310" text-anchor="middle">haiku · playwright test</text>
518
+ </g>
519
+ <!-- qa-cli done -->
520
+ <g class="ng" onclick="selNode('qa-cli',1)">
521
+ <rect class="nr n-done" x="590" y="276" width="180" height="48" rx="8"/>
522
+ <text class="nl" x="680" y="296" text-anchor="middle">qa-cli</text>
523
+ <text x="602" y="296" fill="#3fb950" font-size="11">✓</text>
524
+ <text class="ns" x="680" y="310" text-anchor="middle">haiku · 127/127 tests ✓</text>
525
+ </g>
526
+
527
+ <!-- TOOL CALLS under QA agents -->
528
+ <!-- backend tool active -->
529
+ <g class="ng" onclick="selNode('bash-be',1)">
530
+ <rect class="nr n-tool-active" x="35" y="384" width="110" height="36" rx="8"/>
531
+ <text class="nl" x="90" y="400" text-anchor="middle" font-size="10">Bash</text>
532
+ <text class="ns" x="90" y="414" text-anchor="middle">npm test -- auth</text>
533
+ <circle class="tpulse" cx="47" cy="400" r="4"/>
534
+ </g>
535
+ <!-- backend edit done -->
536
+ <g class="ng" onclick="selNode('edit-be',1)">
537
+ <rect class="nr n-tool-done" x="160" y="384" width="100" height="36" rx="8"/>
538
+ <text class="nl" x="210" y="400" text-anchor="middle" font-size="10">Edit</text>
539
+ <text class="ns" x="210" y="414" text-anchor="middle" fill="#3fb950">✓ routes.js</text>
540
+ </g>
541
+ <!-- frontend playwright active -->
542
+ <g class="ng" onclick="selNode('pw-fe',1)">
543
+ <rect class="nr n-tool-active" x="340" y="384" width="130" height="36" rx="8"/>
544
+ <text class="nl" x="405" y="400" text-anchor="middle" font-size="10">Bash</text>
545
+ <text class="ns" x="405" y="414" text-anchor="middle">playwright test</text>
546
+ <circle class="tpulse" cx="352" cy="400" r="4"/>
547
+ </g>
548
+
549
+ <!-- Contract check annotation -->
550
+ <rect x="500" y="370" width="180" height="52" fill="#1f3a5f" stroke="#388bfd" stroke-width="1" rx="5" opacity=".9"/>
551
+ <text x="590" y="386" text-anchor="middle" fill="#79c0ff" font-size="9" font-family="monospace">◎ contract compliance</text>
552
+ <text x="590" y="399" text-anchor="middle" fill="#79c0ff" font-size="9" font-family="monospace">qa-cli verified: api-contract.md ✓</text>
553
+ <text x="590" y="412" text-anchor="middle" fill="#3fb950" font-size="9" font-family="monospace">schema-contract.md ✓</text>
554
+
555
+ <!-- Agent count summary -->
556
+ <rect x="20" y="450" width="220" height="42" fill="#161b22" stroke="#30363d" stroke-width="1" rx="6" opacity=".95"/>
557
+ <text x="30" y="466" fill="#7d8590" font-size="9" font-family="monospace">ACTIVE AGENTS</text>
558
+ <text x="30" y="481" fill="#388bfd" font-size="10" font-family="monospace">● 2 domain agents running</text>
559
+ <text x="160" y="481" fill="#d29922" font-size="10" font-family="monospace">⚑ 2 QA agents running</text>
560
+
561
+ <!-- EDGES -->
562
+ <path class="e e-active" d="M370,68 L140,152" marker-end="url(#ar-bl)"/>
563
+ <path class="ef ef-spawn" d="M370,68 L140,152"/>
564
+ <path class="e e-active" d="M410,68 L410,152" marker-end="url(#ar-bl)"/>
565
+ <path class="ef ef-spawn" d="M410,68 L410,152"/>
566
+ <path class="e e-spawn" d="M450,68 L680,152" marker-end="url(#ar-sp)"/>
567
+ <path class="ef ef-spawn" d="M450,68 L680,152"/>
568
+ <!-- domain → qa -->
569
+ <path class="e e-active" d="M140,204 L135,276" marker-end="url(#ar-bl)"/>
570
+ <path class="ef ef-spawn" d="M140,204 L135,276"/>
571
+ <path class="e e-active" d="M410,204 L410,276" marker-end="url(#ar-bl)"/>
572
+ <path class="ef ef-spawn" d="M410,204 L410,276"/>
573
+ <path class="e e-spawn" d="M680,204 L680,276" marker-end="url(#ar-sp)"/>
574
+ <!-- qa → tools -->
575
+ <path class="e e-tool" d="M100,324 L90,384" marker-end="url(#ar-pu)"/>
576
+ <path class="ef ef-tool" d="M100,324 L90,384"/>
577
+ <path class="e e-spawn" d="M150,324 L210,384" marker-end="url(#ar-sp)"/>
578
+ <path class="e e-tool" d="M390,324 L405,384" marker-end="url(#ar-pu)"/>
579
+ <path class="ef ef-tool" d="M390,324 L405,384"/>
580
+ `
581
+ },
582
+
583
+ // ─────────────────────────────────────────────
584
+ // 2: gsd-t-scan (5 parallel agents)
585
+ // ─────────────────────────────────────────────
586
+ {
587
+ meta: { cmd:'gsd-t-scan · post-M14 analysis', tok:'62,300 / 200,000 (31%)', phase:'▶ SCAN' },
588
+ timeline: [{l:'scan',s:'act'}],
589
+ agents:[
590
+ {n:'gsd-t-scan', t:'orchestrator · sonnet', s:'running', tok:'12k'},
591
+ {n:'architecture', t:'scan agent · haiku', s:'done', tok:'9k'},
592
+ {n:'business-rules',t:'scan agent · haiku', s:'done', tok:'11k'},
593
+ {n:'security', t:'scan agent · sonnet', s:'running', tok:'14k'},
594
+ {n:'quality', t:'scan agent · sonnet', s:'running', tok:'16k'},
595
+ {n:'contracts', t:'scan agent · haiku', s:'done', tok:'8k'},
596
+ ],
597
+ tree:'◆ gsd-t-scan\n├─ ✓ architecture (haiku)\n├─ ✓ business-rules (haiku)\n├─ ◌ security (sonnet)\n├─ ◌ quality (sonnet)\n└─ ✓ contracts (haiku)',
598
+ outcomes:'[success] architecture: 0 critical, 2 medium\n[success] business-rules: 3 patterns found\n[running] security: analyzing 6 dimensions\n[running] quality: checking 87 functions\n[success] contracts: 2 drift items found',
599
+ events:[
600
+ {t:'tool', msg:'security → Bash: grep -r "execSync" bin/'},
601
+ {t:'tool', msg:'quality → Glob: **/*.js'},
602
+ {t:'done', msg:'contracts: 2 drift items found'},
603
+ {t:'done', msg:'business-rules: 3 patterns found'},
604
+ {t:'done', msg:'architecture: 0 critical, 2 medium findings'},
605
+ {t:'spawn', msg:'scan → 5 parallel agents spawned (sonnet×2, haiku×3)'},
606
+ ],
607
+ svg: `
608
+ <!-- ROOT -->
609
+ <g class="ng" onclick="selNode('scan',2)">
610
+ <rect class="nr n-session running" x="310" y="20" width="200" height="48" rx="8"/>
611
+ <text class="nl" x="410" y="40" text-anchor="middle">gsd-t-scan</text>
612
+ <text x="322" y="40" fill="#79c0ff" font-size="11">◆</text>
613
+ <text class="ns" x="410" y="54" text-anchor="middle">orchestrator · 5 parallel agents</text>
614
+ </g>
615
+
616
+ <!-- Parallel bracket -->
617
+ <line class="parallel-bracket" x1="75" y1="115" x2="75" y2="132"/>
618
+ <line class="parallel-bracket" x1="75" y1="132" x2="745" y2="132"/>
619
+ <line class="parallel-bracket" x1="745" y1="115" x2="745" y2="132"/>
620
+ <text class="parallel-label" x="410" y="144" text-anchor="middle">── 5 scan agents spawned simultaneously ──</text>
621
+
622
+ <!-- architecture done -->
623
+ <g class="ng" onclick="selNode('arch',2)">
624
+ <rect class="nr n-done" x="20" y="154" width="140" height="52" rx="8"/>
625
+ <text class="nl" x="90" y="174" text-anchor="middle">architecture</text>
626
+ <text x="32" y="174" fill="#3fb950" font-size="11">✓</text>
627
+ <text class="ns" x="90" y="190" text-anchor="middle">haiku · 0 crit, 2 med</text>
628
+ </g>
629
+ <!-- business-rules done -->
630
+ <g class="ng" onclick="selNode('biz',2)">
631
+ <rect class="nr n-done" x="180" y="154" width="140" height="52" rx="8"/>
632
+ <text class="nl" x="250" y="174" text-anchor="middle">business-rules</text>
633
+ <text x="192" y="174" fill="#3fb950" font-size="11">✓</text>
634
+ <text class="ns" x="250" y="190" text-anchor="middle">haiku · 3 patterns</text>
635
+ </g>
636
+ <!-- security running -->
637
+ <g class="ng" onclick="selNode('security',2)">
638
+ <rect class="nr n-scan running" x="340" y="154" width="140" height="52" rx="8"/>
639
+ <text class="nl" x="410" y="174" text-anchor="middle">security</text>
640
+ <text x="352" y="174" fill="#79c0ff" font-size="11">◌</text>
641
+ <text class="ns" x="410" y="190" text-anchor="middle">sonnet · 6 dimensions</text>
642
+ </g>
643
+ <!-- quality running -->
644
+ <g class="ng" onclick="selNode('quality',2)">
645
+ <rect class="nr n-scan running" x="500" y="154" width="140" height="52" rx="8"/>
646
+ <text class="nl" x="570" y="174" text-anchor="middle">quality</text>
647
+ <text x="512" y="174" fill="#79c0ff" font-size="11">◌</text>
648
+ <text class="ns" x="570" y="190" text-anchor="middle">sonnet · 87 functions</text>
649
+ </g>
650
+ <!-- contracts done -->
651
+ <g class="ng" onclick="selNode('contracts',2)">
652
+ <rect class="nr n-done" x="660" y="154" width="140" height="52" rx="8"/>
653
+ <text class="nl" x="730" y="174" text-anchor="middle">contracts</text>
654
+ <text x="672" y="174" fill="#3fb950" font-size="11">✓</text>
655
+ <text class="ns" x="730" y="190" text-anchor="middle">haiku · 2 drift items</text>
656
+ </g>
657
+
658
+ <!-- Tool calls for active agents -->
659
+ <!-- security tools -->
660
+ <g class="ng"><rect class="nr n-tool-active" x="280" y="270" width="130" height="36" rx="8"/>
661
+ <text class="nl" x="345" y="286" text-anchor="middle" font-size="10">Bash</text>
662
+ <text class="ns" x="345" y="300" text-anchor="middle">grep -r execSync</text>
663
+ <circle class="tpulse" cx="292" cy="286" r="4"/>
664
+ </g>
665
+ <g class="ng"><rect class="nr n-tool-done" x="420" y="270" width="110" height="36" rx="8"/>
666
+ <text class="nl" x="475" y="286" text-anchor="middle" font-size="10">Read</text>
667
+ <text class="ns" x="475" y="300" text-anchor="middle" fill="#3fb950">✓ bin/gsd-t.js</text>
668
+ </g>
669
+ <!-- quality tools -->
670
+ <g class="ng"><rect class="nr n-tool-active" x="490" y="270" width="130" height="36" rx="8"/>
671
+ <text class="nl" x="555" y="286" text-anchor="middle" font-size="10">Glob</text>
672
+ <text class="ns" x="555" y="300" text-anchor="middle">**/*.js (87 fns)</text>
673
+ <circle class="tpulse" cx="502" cy="286" r="4"/>
674
+ </g>
675
+ <g class="ng"><rect class="nr n-tool-done" x="630" y="270" width="110" height="36" rx="8"/>
676
+ <text class="nl" x="685" y="286" text-anchor="middle" font-size="10">Grep</text>
677
+ <text class="ns" x="685" y="300" text-anchor="middle" fill="#3fb950">✓ 127 tests</text>
678
+ </g>
679
+
680
+ <!-- Synthesis node (pending) -->
681
+ <rect x="300" y="372" width="220" height="52" fill="#161b22" stroke="#30363d" stroke-width="1" rx="8" stroke-dasharray="4,2"/>
682
+ <text x="410" y="392" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">synthesis (pending)</text>
683
+ <text x="410" y="408" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">merges all 5 reports → techdebt.md</text>
684
+ <text x="312" y="392" fill="#484f58" font-size="11">⏳</text>
685
+ <!-- dash edges to synthesis -->
686
+ <path d="M90,206 C120,300 280,370 300,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
687
+ <path d="M250,206 C270,290 310,370 330,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
688
+ <path d="M410,206 L410,372" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
689
+ <path d="M570,206 C560,290 500,370 490,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
690
+ <path d="M730,206 C710,300 540,370 520,398" stroke="#484f58" stroke-width="1" stroke-dasharray="2,3" fill="none"/>
691
+
692
+ <!-- Model label badges -->
693
+ <rect x="22" y="215" width="45" height="16" fill="#1f3a5f" rx="3"/>
694
+ <text x="45" y="226" text-anchor="middle" fill="#79c0ff" font-size="8" font-family="monospace">haiku</text>
695
+ <rect x="182" y="215" width="45" height="16" fill="#1f3a5f" rx="3"/>
696
+ <text x="205" y="226" text-anchor="middle" fill="#79c0ff" font-size="8" font-family="monospace">haiku</text>
697
+ <rect x="342" y="215" width="50" height="16" fill="#2d1f5e" rx="3"/>
698
+ <text x="367" y="226" text-anchor="middle" fill="#bc8cff" font-size="8" font-family="monospace">sonnet</text>
699
+ <rect x="502" y="215" width="50" height="16" fill="#2d1f5e" rx="3"/>
700
+ <text x="527" y="226" text-anchor="middle" fill="#bc8cff" font-size="8" font-family="monospace">sonnet</text>
701
+ <rect x="662" y="215" width="45" height="16" fill="#1f3a5f" rx="3"/>
702
+ <text x="685" y="226" text-anchor="middle" fill="#79c0ff" font-size="8" font-family="monospace">haiku</text>
703
+
704
+ <!-- EDGES root → all 5 -->
705
+ <path class="e e-spawn" d="M370,68 L90,154" marker-end="url(#ar-sp)"/>
706
+ <path class="e e-spawn" d="M390,68 L250,154" marker-end="url(#ar-sp)"/>
707
+ <path class="e e-active" d="M410,68 L410,154" marker-end="url(#ar-bl)"/>
708
+ <path class="ef ef-scan" d="M410,68 L410,154"/>
709
+ <path class="e e-active" d="M430,68 L570,154" marker-end="url(#ar-bl)"/>
710
+ <path class="ef ef-scan" d="M430,68 L570,154"/>
711
+ <path class="e e-spawn" d="M450,68 L730,154" marker-end="url(#ar-sp)"/>
712
+ <!-- tool edges -->
713
+ <path class="e e-tool" d="M380,206 L345,270" marker-end="url(#ar-pu)"/>
714
+ <path class="ef ef-tool" d="M380,206 L345,270"/>
715
+ <path class="e e-spawn" d="M430,206 L475,270" marker-end="url(#ar-sp)"/>
716
+ <path class="e e-tool" d="M550,206 L555,270" marker-end="url(#ar-pu)"/>
717
+ <path class="ef ef-tool" d="M550,206 L555,270"/>
718
+ <path class="e e-spawn" d="M600,206 L685,270" marker-end="url(#ar-sp)"/>
719
+ `
720
+ },
721
+
722
+ // ─────────────────────────────────────────────
723
+ // 3: gsd-t-brainstorm (deep research)
724
+ // ─────────────────────────────────────────────
725
+ {
726
+ meta: { cmd:'gsd-t-brainstorm · execution intelligence', tok:'48,700 / 200,000 (24%)', phase:'▶ DEEP RESEARCH' },
727
+ timeline: [{l:'deep research',s:'act'},{a:'›',act:true},{l:'synthesis',s:'fut'},{a:'›'},{l:'brainstorm',s:'fut'}],
728
+ agents:[
729
+ {n:'gsd-t-brainstorm', t:'orchestrator · sonnet', s:'running', tok:'8k'},
730
+ {n:'landscape', t:'research agent · sonnet', s:'done', tok:'18k'},
731
+ {n:'alternatives',t:'research agent · sonnet', s:'running', tok:'14k'},
732
+ {n:'analogies', t:'research agent · sonnet', s:'running', tok:'12k'},
733
+ ],
734
+ tree:'◆ gsd-t-brainstorm\n└─ Deep Research Phase (mandatory)\n ├─ ✓ landscape (sonnet)\n ├─ ◌ alternatives (sonnet)\n └─ ◌ analogies (sonnet)',
735
+ outcomes:'[success] landscape: OTel, AgentOps, LangSmith patterns\n[running] alternatives: evaluating 5 approaches\n[running] analogies: git blame, VS Code timeline',
736
+ events:[
737
+ {t:'res', msg:'alternatives → WebSearch: agent learning frameworks 2026'},
738
+ {t:'res', msg:'analogies → WebFetch: reflexion paper arxiv'},
739
+ {t:'done', msg:'landscape: OTel GenAI conventions, 3 reference impls'},
740
+ {t:'spawn', msg:'brainstorm → 3 parallel research agents (sonnet)'},
741
+ {t:'dec', msg:'Deep Research Phase: mandatory before any conclusions'},
742
+ ],
743
+ svg: `
744
+ <!-- ROOT -->
745
+ <g class="ng" onclick="selNode('brainstorm',3)">
746
+ <rect class="nr n-session running" x="285" y="20" width="250" height="48" rx="8"/>
747
+ <text class="nl" x="410" y="40" text-anchor="middle">gsd-t-brainstorm</text>
748
+ <text x="297" y="40" fill="#79c0ff" font-size="11">◆</text>
749
+ <text class="ns" x="410" y="54" text-anchor="middle">execution intelligence & visualization</text>
750
+ </g>
751
+
752
+ <!-- Deep research mandatory label -->
753
+ <rect x="250" y="110" width="320" height="28" fill="#2d1f5e" stroke="#bc8cff" stroke-width="1" rx="6"/>
754
+ <text x="410" y="129" text-anchor="middle" fill="#bc8cff" font-size="10" font-family="monospace">MANDATORY: Deep Research Phase</text>
755
+
756
+ <!-- Parallel bracket -->
757
+ <line class="parallel-bracket" x1="120" y1="155" x2="120" y2="170"/>
758
+ <line class="parallel-bracket" x1="120" y1="170" x2="700" y2="170"/>
759
+ <line class="parallel-bracket" x1="700" y1="155" x2="700" y2="170"/>
760
+ <text class="parallel-label" x="410" y="182" text-anchor="middle">── 3 parallel research agents (all sonnet, all blocking) ──</text>
761
+
762
+ <!-- landscape done -->
763
+ <g class="ng" onclick="selNode('landscape',3)">
764
+ <rect class="nr n-done" x="60" y="192" width="185" height="52" rx="8"/>
765
+ <text class="nl" x="152" y="212" text-anchor="middle">landscape</text>
766
+ <text x="72" y="212" fill="#3fb950" font-size="11">✓</text>
767
+ <text class="ns" x="152" y="228" text-anchor="middle">state of field · tools · patterns</text>
768
+ </g>
769
+ <!-- alternatives running -->
770
+ <g class="ng" onclick="selNode('alternatives',3)">
771
+ <rect class="nr n-research running" x="320" y="192" width="180" height="52" rx="8"/>
772
+ <text class="nl" x="410" y="212" text-anchor="middle">alternatives</text>
773
+ <text x="332" y="212" fill="#bc8cff" font-size="11">◌</text>
774
+ <text class="ns" x="410" y="228" text-anchor="middle">design options · tradeoffs</text>
775
+ </g>
776
+ <!-- analogies running -->
777
+ <g class="ng" onclick="selNode('analogies',3)">
778
+ <rect class="nr n-research running" x="575" y="192" width="185" height="52" rx="8"/>
779
+ <text class="nl" x="662" y="212" text-anchor="middle">analogies</text>
780
+ <text x="587" y="212" fill="#bc8cff" font-size="11">◌</text>
781
+ <text class="ns" x="662" y="228" text-anchor="middle">cross-domain patterns</text>
782
+ </g>
783
+
784
+ <!-- landscape findings -->
785
+ <rect x="40" y="300" width="220" height="80" fill="#1a2e1a" stroke="#3fb950" stroke-width="1" rx="6"/>
786
+ <text x="150" y="318" text-anchor="middle" fill="#3fb950" font-size="9" font-family="monospace">✓ landscape findings</text>
787
+ <text x="150" y="333" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• OTel GenAI agent spans (dev)</text>
788
+ <text x="150" y="347" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• AgentTrace 3-surface model</text>
789
+ <text x="150" y="361" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• disler reference impl (Claude)</text>
790
+ <text x="150" y="375" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• TRAIL error taxonomy</text>
791
+
792
+ <!-- alternatives findings (partial) -->
793
+ <rect x="305" y="300" width="210" height="80" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" stroke-dasharray="3,2" rx="6"/>
794
+ <text x="410" y="318" text-anchor="middle" fill="#bc8cff" font-size="9" font-family="monospace">◌ alternatives (in progress)</text>
795
+ <text x="410" y="333" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• Option A: extend existing files</text>
796
+ <text x="410" y="347" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• Option B: JSONL event stream</text>
797
+ <text x="410" y="361" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• Option C: intelligence-first</text>
798
+ <text x="410" y="375" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">searching 2 more...</text>
799
+
800
+ <!-- analogies searching -->
801
+ <rect x="555" y="300" width="215" height="80" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" stroke-dasharray="3,2" rx="6"/>
802
+ <text x="662" y="318" text-anchor="middle" fill="#bc8cff" font-size="9" font-family="monospace">◌ analogies (in progress)</text>
803
+ <text x="662" y="333" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">• git blame / git log UX</text>
804
+ <text x="662" y="347" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">• VS Code timeline panel (fetch)</text>
805
+ <text x="662" y="361" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">• Reflexion paper (reading)</text>
806
+
807
+ <!-- Synthesis pending -->
808
+ <rect x="280" y="438" width="260" height="52" fill="#161b22" stroke="#30363d" stroke-width="1" rx="8" stroke-dasharray="4,2"/>
809
+ <text x="410" y="460" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">synthesis (blocked)</text>
810
+ <text x="410" y="476" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">waits for all 3 research agents ✓</text>
811
+
812
+ <!-- EDGES -->
813
+ <path class="e e-active" d="M410,68 L410,110" marker-end="url(#ar-pu)"/>
814
+ <path class="ef ef-res" d="M410,68 L410,110"/>
815
+ <path class="e e-active" d="M340,138 L152,192" marker-end="url(#ar-pu)"/>
816
+ <path class="ef ef-res" d="M340,138 L152,192"/>
817
+ <path class="e e-active" d="M410,138 L410,192" marker-end="url(#ar-pu)"/>
818
+ <path class="ef ef-res" d="M410,138 L410,192"/>
819
+ <path class="e e-active" d="M480,138 L662,192" marker-end="url(#ar-pu)"/>
820
+ <path class="ef ef-res" d="M480,138 L662,192"/>
821
+ <!-- agents → findings -->
822
+ <path class="e e-spawn" d="M152,244 L150,300" marker-end="url(#ar-sp)"/>
823
+ <path class="e e-active" d="M410,244 L410,300" marker-end="url(#ar-pu)"/>
824
+ <path class="ef ef-res" d="M410,244 L410,300"/>
825
+ <path class="e e-active" d="M662,244 L662,300" marker-end="url(#ar-pu)"/>
826
+ <path class="ef ef-res" d="M662,244 L662,300"/>
827
+ `
828
+ },
829
+
830
+ // ─────────────────────────────────────────────
831
+ // 4: gsd-t-debug (loop detection + research)
832
+ // ─────────────────────────────────────────────
833
+ {
834
+ meta: { cmd:'gsd-t-debug · auth timeout bug (attempt 3)', tok:'156,400 / 200,000 (78%)', phase:'▶ DEBUG ESCALATION' },
835
+ timeline: [{l:'reproduce',s:'done'},{a:'›'},{l:'fix × 2',s:'done'},{a:'›'},{l:'loop detected',s:'act'},{a:'›',act:true},{l:'deep research',s:'fut'}],
836
+ agents:[
837
+ {n:'gsd-t-debug', t:'orchestrator · sonnet', s:'running', tok:'38k'},
838
+ {n:'root-cause', t:'research agent · sonnet', s:'fut', tok:'—'},
839
+ {n:'alternatives',t:'research agent · sonnet', s:'fut', tok:'—'},
840
+ {n:'prior-art', t:'research agent · sonnet', s:'fut', tok:'—'},
841
+ ],
842
+ tree:'◆ gsd-t-debug\n├─ ✓ reproduce (repro script)\n├─ ✗ fix attempt 1 (failed)\n├─ ✗ fix attempt 2 (failed)\n└─ ⚠ loop detection triggered\n └─ spawning deep research (3 agents)...',
843
+ outcomes:'[failure] fix attempt 1: timeout still occurs\n[failure] fix attempt 2: different failure mode\n[warning] 3+ failed sessions detected in Decision Log\n[escalating] → mandatory deep research mode',
844
+ events:[
845
+ {t:'err', msg:'fix attempt 2: test still fails (different error)'},
846
+ {t:'dec', msg:'[failure] 3+ debug sessions found in Decision Log'},
847
+ {t:'trans', msg:'loop detection: escalating to deep research'},
848
+ {t:'err', msg:'fix attempt 1: auth timeout unchanged'},
849
+ {t:'done', msg:'reproduce: repro script confirms issue'},
850
+ {t:'spawn', msg:'debug started · checking Decision Log for prior attempts'},
851
+ ],
852
+ svg: `
853
+ <!-- ROOT -->
854
+ <g class="ng" onclick="selNode('debug',4)">
855
+ <rect class="nr n-debug running" x="285" y="16" width="250" height="48" rx="8"/>
856
+ <text class="nl" x="410" y="36" text-anchor="middle">gsd-t-debug</text>
857
+ <text x="297" y="36" fill="#d18616" font-size="11">◆</text>
858
+ <text class="ns" x="410" y="50" text-anchor="middle">auth timeout bug · session 3 of 3</text>
859
+ </g>
860
+
861
+ <!-- History row: prior failed attempts from Decision Log -->
862
+ <rect x="20" y="88" width="780" height="48" fill="#2e2210" stroke="#d18616" stroke-width="1" rx="6" opacity=".9"/>
863
+ <text x="410" y="107" text-anchor="middle" fill="#d29922" font-size="10" font-family="monospace">⚠ Decision Log: 3 prior [debug] sessions found for "auth timeout"</text>
864
+ <text x="410" y="122" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">2026-02-20 · 2026-02-21 · 2026-02-23 — all marked [failure] — loop detection triggered</text>
865
+
866
+ <!-- Timeline of this session -->
867
+ <!-- reproduce done -->
868
+ <g class="ng" onclick="selNode('reproduce',4)">
869
+ <rect class="nr n-done" x="40" y="174" width="150" height="52" rx="8"/>
870
+ <text class="nl" x="115" y="194" text-anchor="middle">reproduce</text>
871
+ <text x="52" y="194" fill="#3fb950" font-size="11">✓</text>
872
+ <text class="ns" x="115" y="210" text-anchor="middle">repro script created</text>
873
+ </g>
874
+ <!-- fix 1 failed -->
875
+ <g class="ng" onclick="selNode('fix1',4)">
876
+ <rect class="nr n-error nerr" x="220" y="174" width="150" height="52" rx="8"/>
877
+ <text class="nl" x="295" y="194" text-anchor="middle">fix attempt 1</text>
878
+ <text x="232" y="194" fill="#f85149" font-size="11">✗</text>
879
+ <text class="ns" x="295" y="210" text-anchor="middle">timeout unchanged</text>
880
+ </g>
881
+ <!-- fix 2 failed -->
882
+ <g class="ng" onclick="selNode('fix2',4)">
883
+ <rect class="nr n-error nerr" x="400" y="174" width="150" height="52" rx="8"/>
884
+ <text class="nl" x="475" y="194" text-anchor="middle">fix attempt 2</text>
885
+ <text x="412" y="194" fill="#f85149" font-size="11">✗</text>
886
+ <text class="ns" x="475" y="210" text-anchor="middle">different failure mode</text>
887
+ </g>
888
+ <!-- loop detection warning -->
889
+ <g class="ng" onclick="selNode('loop',4)">
890
+ <rect x="580" y="174" width="200" height="52" fill="#2e2210" stroke="#d29922" stroke-width="2" rx="8" style="animation:npulse 1.5s ease-in-out infinite"/>
891
+ <text x="680" y="194" text-anchor="middle" fill="#d29922" font-size="11" font-family="monospace">⚠ loop detected</text>
892
+ <text x="680" y="210" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">3 attempts exhausted</text>
893
+ </g>
894
+
895
+ <!-- Escalation arrow -->
896
+ <path d="M660,226 L660,274" stroke="#d29922" stroke-width="2" marker-end="url(#ar-or)" fill="none"/>
897
+ <path class="ef" style="stroke:#d18616;stroke-dasharray:6,3;animation:flow 1.2s linear infinite;" d="M660,226 L660,274" fill="none"/>
898
+
899
+ <!-- Deep research spawning -->
900
+ <rect x="250" y="282" width="320" height="32" fill="#2d1f5e" stroke="#bc8cff" stroke-width="1.5" rx="6"/>
901
+ <text x="410" y="303" text-anchor="middle" fill="#bc8cff" font-size="10" font-family="monospace">→ mandatory deep research escalation</text>
902
+
903
+ <!-- Research agents spawning -->
904
+ <line class="parallel-bracket" x1="130" y1="330" x2="130" y2="344"/>
905
+ <line class="parallel-bracket" x1="130" y1="344" x2="690" y2="344"/>
906
+ <line class="parallel-bracket" x1="690" y1="330" x2="690" y2="344"/>
907
+ <text class="parallel-label" x="410" y="356" text-anchor="middle">── spawning 3 research agents ──</text>
908
+
909
+ <!-- root-cause (spawning) -->
910
+ <g class="ng" onclick="selNode('root-cause',4)">
911
+ <rect x="80" y="364" width="175" height="52" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
912
+ <text x="167" y="384" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">root-cause</text>
913
+ <text x="92" y="384" fill="#bc8cff" font-size="11">◌</text>
914
+ <text class="ns" x="167" y="400" text-anchor="middle">sonnet · spawning...</text>
915
+ </g>
916
+ <!-- alternatives (spawning) -->
917
+ <g class="ng" onclick="selNode('alt-debug',4)">
918
+ <rect x="322" y="364" width="175" height="52" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
919
+ <text x="409" y="384" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">alternatives</text>
920
+ <text x="334" y="384" fill="#bc8cff" font-size="11">◌</text>
921
+ <text class="ns" x="409" y="400" text-anchor="middle">sonnet · spawning...</text>
922
+ </g>
923
+ <!-- prior-art (spawning) -->
924
+ <g class="ng" onclick="selNode('prior-art',4)">
925
+ <rect x="564" y="364" width="175" height="52" fill="#1e1a2e" stroke="#bc8cff" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
926
+ <text x="651" y="384" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">prior-art</text>
927
+ <text x="576" y="384" fill="#bc8cff" font-size="11">◌</text>
928
+ <text class="ns" x="651" y="400" text-anchor="middle">sonnet · spawning...</text>
929
+ </g>
930
+
931
+ <!-- High context warning -->
932
+ <rect x="20" y="450" width="260" height="42" fill="#3a1a1a" stroke="#f85149" stroke-width="1" rx="5"/>
933
+ <text x="30" y="466" fill="#f85149" font-size="9" font-family="monospace">⚠ context: 78% (156k / 200k tokens)</text>
934
+ <text x="30" y="481" fill="#7d8590" font-size="9" font-family="monospace">research agents get fresh context windows</text>
935
+
936
+ <!-- EDGES -->
937
+ <path class="e e-spawn" d="M360,64 L115,174" marker-end="url(#ar-sp)"/>
938
+ <path class="e e-spawn" d="M380,64 L295,174" marker-end="url(#ar-sp)"/>
939
+ <path class="e e-spawn" d="M430,64 L475,174" marker-end="url(#ar-sp)"/>
940
+ <path class="e e-spawn" d="M450,64 L680,174" marker-end="url(#ar-sp)"/>
941
+ <path class="e e-spawn" d="M115,226 L220,226 L220,174" stroke="#3fb950" marker-end="url(#ar-gr)"/>
942
+ <path class="e e-active" d="M380,314 L167,364" marker-end="url(#ar-pu)"/>
943
+ <path class="ef ef-res" d="M380,314 L167,364"/>
944
+ <path class="e e-active" d="M410,314 L409,364" marker-end="url(#ar-pu)"/>
945
+ <path class="ef ef-res" d="M410,314 L409,364"/>
946
+ <path class="e e-active" d="M440,314 L651,364" marker-end="url(#ar-pu)"/>
947
+ <path class="ef ef-res" d="M440,314 L651,364"/>
948
+ `
949
+ },
950
+
951
+ // ─────────────────────────────────────────────
952
+ // 5: gsd-t-quick + error recovery
953
+ // ─────────────────────────────────────────────
954
+ {
955
+ meta: { cmd:'gsd-t-quick · fix checkin hook bug', tok:'28,100 / 200,000 (14%)', phase:'▶ QUICK' },
956
+ timeline: [{l:'subagent spawn',s:'done'},{a:'›'},{l:'implement',s:'done'},{a:'›'},{l:'test',s:'act'},{a:'›',act:true},{l:'deviation',s:'fut'},{a:'›'},{l:'verify',s:'fut'}],
957
+ agents:[
958
+ {n:'gsd-t-quick', t:'orchestrator · sonnet', s:'running', tok:'8k'},
959
+ {n:'quick-subagent',t:'subagent · sonnet', s:'running', tok:'20k'},
960
+ ],
961
+ tree:'◆ gsd-t-quick (Step 0: self-spawn)\n└─ ◌ quick-subagent (fresh context)\n ├─ ✓ implement fix\n ├─ ◌ running tests (4 fail)\n └─ ⏳ deviation rule check pending',
962
+ outcomes:'[success] fix implemented: gsd-t-checkin.md line 47\n[running] test suite: 4 failures found\n[pending] deviation rule: auto-fix if possible',
963
+ events:[
964
+ {t:'err', msg:'quick-subagent → test run: 4 failures (hook timing)'},
965
+ {t:'tool', msg:'quick-subagent → Bash: node --test test/'},
966
+ {t:'done', msg:'quick-subagent → Edit: gsd-t-checkin.md ✓'},
967
+ {t:'spawn', msg:'gsd-t-quick → quick-subagent (Step 0 self-spawn)'},
968
+ ],
969
+ svg: `
970
+ <!-- Root orchestrator (small, stays lightweight) -->
971
+ <g class="ng" onclick="selNode('quick',5)">
972
+ <rect class="nr n-command" x="335" y="20" width="150" height="44" rx="8"/>
973
+ <text class="nl" x="410" y="39" text-anchor="middle">gsd-t-quick</text>
974
+ <text x="347" y="39" fill="#bc8cff" font-size="11">◌</text>
975
+ <text class="ns" x="410" y="53" text-anchor="middle">orchestrator · Step 0 → subagent</text>
976
+ </g>
977
+
978
+ <!-- Self-spawn note -->
979
+ <rect x="260" y="88" width="300" height="24" fill="#2d1f5e" stroke="#bc8cff" stroke-width="1" rx="5" opacity=".85"/>
980
+ <text x="410" y="104" text-anchor="middle" fill="#bc8cff" font-size="9" font-family="monospace">Step 0: self-spawn for fresh context window</text>
981
+
982
+ <!-- Quick subagent (main work) -->
983
+ <g class="ng" onclick="selNode('quick-sub',5)">
984
+ <rect class="nr n-domain running" x="260" y="130" width="300" height="56" rx="8"/>
985
+ <text class="nl" x="410" y="153" text-anchor="middle">quick-subagent</text>
986
+ <text x="272" y="153" fill="#388bfd" font-size="11">◌</text>
987
+ <text class="ns" x="410" y="170" text-anchor="middle">sonnet · fix checkin hook bug · fresh context</text>
988
+ </g>
989
+
990
+ <!-- Work steps -->
991
+ <!-- implement done -->
992
+ <g class="ng" onclick="selNode('impl',5)">
993
+ <rect class="nr n-done" x="100" y="238" width="160" height="48" rx="8"/>
994
+ <text class="nl" x="180" y="258" text-anchor="middle">implement</text>
995
+ <text x="112" y="258" fill="#3fb950" font-size="11">✓</text>
996
+ <text class="ns" x="180" y="272" text-anchor="middle">Edit: gsd-t-checkin.md</text>
997
+ </g>
998
+ <!-- test suite running with failures -->
999
+ <g class="ng" onclick="selNode('tests',5)">
1000
+ <rect class="nr n-qa running" x="330" y="238" width="160" height="48" rx="8"/>
1001
+ <text class="nl" x="410" y="258" text-anchor="middle">test suite</text>
1002
+ <text x="342" y="258" fill="#d29922" font-size="11">⚑</text>
1003
+ <text class="ns" x="410" y="272" text-anchor="middle">127 tests · 4 failing</text>
1004
+ </g>
1005
+
1006
+ <!-- Error node -->
1007
+ <g class="ng" onclick="selNode('err',5)">
1008
+ <rect class="nr n-error nerr" x="560" y="238" width="160" height="48" rx="8"/>
1009
+ <text class="nl" x="640" y="258" text-anchor="middle">4 failures</text>
1010
+ <text x="572" y="258" fill="#f85149" font-size="11">✗</text>
1011
+ <text class="ns" x="640" y="272" text-anchor="middle">hook timing (recoverable)</text>
1012
+ </g>
1013
+
1014
+ <!-- Deviation rule check -->
1015
+ <rect x="280" y="342" width="260" height="48" fill="#2e2210" stroke="#d29922" stroke-width="1.5" rx="8"/>
1016
+ <text x="410" y="362" text-anchor="middle" fill="#d29922" font-size="10" font-family="monospace">⚑ deviation rule check</text>
1017
+ <text x="410" y="378" text-anchor="middle" fill="#7d8590" font-size="9" font-family="monospace">auto-fix: yes (timing, not architecture)</text>
1018
+
1019
+ <!-- Deviation rules legend -->
1020
+ <rect x="20" y="330" width="230" height="88" fill="#161b22" stroke="#30363d" rx="5" opacity=".95"/>
1021
+ <text x="30" y="346" fill="#7d8590" font-size="9" font-family="monospace">DEVIATION RULES</text>
1022
+ <text x="30" y="361" fill="#3fb950" font-size="9" font-family="monospace">✓ Rule 1: auto-fix bugs</text>
1023
+ <text x="30" y="376" fill="#3fb950" font-size="9" font-family="monospace">✓ Rule 2: add missing functionality</text>
1024
+ <text x="30" y="391" fill="#3fb950" font-size="9" font-family="monospace">✓ Rule 3: fix blockers</text>
1025
+ <text x="30" y="406" fill="#f85149" font-size="9" font-family="monospace">✗ Rule 4: STOP for arch changes</text>
1026
+
1027
+ <!-- Fix attempt 2 (pending) -->
1028
+ <rect x="280" y="450" width="260" height="44" fill="#161b22" stroke="#30363d" stroke-width="1" rx="8" stroke-dasharray="3,2"/>
1029
+ <text x="410" y="469" text-anchor="middle" fill="#7d8590" font-size="11" font-family="monospace">auto-fix attempt 2 (pending)</text>
1030
+ <text x="410" y="483" text-anchor="middle" fill="#484f58" font-size="9" font-family="monospace">max 3 attempts before escalation</text>
1031
+
1032
+ <!-- Tools -->
1033
+ <g class="ng"><rect class="nr n-tool-done" x="80" y="352" width="110" height="36" rx="8"/>
1034
+ <text class="nl" x="135" y="368" text-anchor="middle" font-size="10">Edit</text>
1035
+ <text class="ns" x="135" y="382" text-anchor="middle" fill="#3fb950">✓ line 47</text>
1036
+ </g>
1037
+ <g class="ng"><rect class="nr n-tool-active" x="210" y="352" width="50" height="36" rx="8"/>
1038
+ <text class="nl" x="235" y="368" text-anchor="middle" font-size="10">Bash</text>
1039
+ <text class="ns" x="235" y="382" text-anchor="middle">tests</text>
1040
+ <circle class="tpulse" cx="222" cy="368" r="4"/>
1041
+ </g>
1042
+
1043
+ <!-- EDGES -->
1044
+ <path class="e e-active" d="M410,64 L410,130" marker-end="url(#ar-bl)"/>
1045
+ <path class="ef ef-spawn" d="M410,64 L410,130"/>
1046
+ <path class="e e-spawn" d="M360,186 L180,238" marker-end="url(#ar-sp)"/>
1047
+ <path class="e e-active" d="M410,186 L410,238" marker-end="url(#ar-bl)"/>
1048
+ <path class="ef ef-spawn" d="M410,186 L410,238"/>
1049
+ <path class="e e-active" d="M450,186 L640,238" marker-end="url(#ar-bl)"/>
1050
+ <path class="ef ef-spawn" d="M450,186 L640,238"/>
1051
+ <path class="e e-tool" d="M180,286 L135,352" marker-end="url(#ar-pu)"/>
1052
+ <path class="e e-tool" d="M360,286 L235,352" marker-end="url(#ar-pu)"/>
1053
+ <path class="ef ef-tool" d="M360,286 L235,352"/>
1054
+ <!-- error → deviation -->
1055
+ <path d="M620,286 C590,310 520,340 540,366" stroke="#d29922" stroke-width="1.5" marker-end="url(#ar-or)" fill="none"/>
1056
+ <path class="e e-active" d="M410,286 L410,342" marker-end="url(#ar-bl)"/>
1057
+ <path class="ef ef-spawn" d="M410,286 L410,342"/>
1058
+ `
1059
+ }
1060
+ ];
1061
+
1062
+ // ═══════════════════════════════════════════════
1063
+ // RENDER ENGINE
1064
+ // ═══════════════════════════════════════════════
1065
+
1066
+ let currentScene = 0;
1067
+ let eventTimer = null;
1068
+
1069
+ function showScene(idx) {
1070
+ currentScene = idx;
1071
+ // Update buttons
1072
+ document.querySelectorAll('.scbtn').forEach((b,i)=>b.classList.toggle('active',i===idx));
1073
+ const s = SCENES[idx];
1074
+ // Header
1075
+ document.getElementById('hdr-meta').textContent = 'session: sess_8f3c2a · ' + s.meta.cmd;
1076
+ document.getElementById('hdr-tok').textContent = '⬡ ' + s.meta.tok;
1077
+ document.getElementById('hdr-phase').textContent = s.meta.phase;
1078
+ // Graph
1079
+ document.getElementById('scene-content').innerHTML = s.svg;
1080
+ // Timeline
1081
+ const tl = document.getElementById('timeline-bar');
1082
+ tl.innerHTML = s.timeline.map(t =>
1083
+ t.a ? `<div class="tla${t.act?' act':''}">›</div>`
1084
+ : `<div class="tlp ${t.s}">${t.s==='done'?'✓ ':t.s==='act'?'▶ ':''}${t.l}</div>`
1085
+ ).join('');
1086
+ // Events
1087
+ const el = document.getElementById('evt-log');
1088
+ el.innerHTML = s.events.map(e => {
1089
+ const now = new Date();
1090
+ const ts = `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}`;
1091
+ return `<div class="ee"><span class="ets">${ts}</span><span class="et ${e.t}">${e.t.toUpperCase()}</span><span class="em">${e.msg}</span></div>`;
1092
+ }).join('');
1093
+ // Agents tab
1094
+ document.getElementById('agent-list').innerHTML = s.agents.map(a => {
1095
+ const sc = {running:'bl',done:'gr',blocked:'',fut:''}[a.s]||'';
1096
+ return `<div class="mrow"><span class="ml">${a.n}</span><span class="mv ${sc}">${a.t} · ${a.tok}</span></div>`;
1097
+ }).join('');
1098
+ document.getElementById('spawn-tree').textContent = s.tree;
1099
+ document.getElementById('outcome-log').innerHTML = s.outcomes.split('\n').map(l=>l).join('<br>');
1100
+ // Memory stats
1101
+ document.getElementById('mem-events').textContent = [248,312,186,94,312,88][idx];
1102
+ document.getElementById('mem-agents').textContent = [8,7,6,4,4,2][idx];
1103
+ // Live events
1104
+ if (eventTimer) clearInterval(eventTimer);
1105
+ eventTimer = setInterval(() => addLiveEvent(idx), 4500);
1106
+ }
1107
+
1108
+ function selNode(id, sceneIdx) {
1109
+ // Simple selection feedback — in production this would update sidebar
1110
+ const el = document.getElementById('node-name');
1111
+ if (el) {
1112
+ el.textContent = id;
1113
+ el.style.opacity='0';
1114
+ setTimeout(()=>{el.style.opacity='1';el.style.transition='opacity .3s';},50);
1115
+ }
1116
+ }
1117
+
1118
+ function stab(t) {
1119
+ ['info','agents','memory'].forEach(x=>{
1120
+ document.getElementById('sp-'+x).style.display = x===t?'block':'none';
1121
+ document.querySelectorAll('.sbtab')[['info','agents','memory'].indexOf(x)].classList.toggle('active',x===t);
1122
+ });
1123
+ }
1124
+
1125
+ function addLiveEvent(idx) {
1126
+ const s = SCENES[idx];
1127
+ if (!s) return;
1128
+ const el = document.getElementById('evt-log');
1129
+ const e = s.events[Math.floor(Math.random()*s.events.length)];
1130
+ const now = new Date();
1131
+ const ts = `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}`;
1132
+ const div = document.createElement('div');
1133
+ div.className = 'ee enew';
1134
+ div.innerHTML = `<span class="ets">${ts}</span><span class="et ${e.t}">${e.t.toUpperCase()}</span><span class="em">${e.msg}</span>`;
1135
+ el.insertBefore(div, el.firstChild);
1136
+ if (el.children.length > 10) el.removeChild(el.lastChild);
1137
+ }
1138
+
1139
+ // Boot
1140
+ showScene(0);
1141
+ </script>
1142
+ </body>
1143
+ </html>