gsd-pi 2.47.0-dev.8cfe772 → 2.47.0-dev.f2e721d

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 (43) hide show
  1. package/dist/resources/extensions/gsd/forensics.js +292 -1
  2. package/dist/resources/extensions/gsd/guided-flow.js +7 -1
  3. package/dist/resources/extensions/gsd/prompts/forensics.md +37 -5
  4. package/dist/web/standalone/.next/BUILD_ID +1 -1
  5. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  6. package/dist/web/standalone/.next/build-manifest.json +2 -2
  7. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  8. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  9. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  10. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  13. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  17. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  21. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  25. package/dist/web/standalone/.next/server/app/index.html +1 -1
  26. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  33. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  34. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  35. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  36. package/package.json +1 -1
  37. package/src/resources/extensions/gsd/forensics.ts +329 -2
  38. package/src/resources/extensions/gsd/guided-flow.ts +9 -1
  39. package/src/resources/extensions/gsd/prompts/forensics.md +37 -5
  40. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +162 -0
  41. package/src/resources/extensions/gsd/tests/stale-milestone-id-reservation.test.ts +79 -0
  42. /package/dist/web/standalone/.next/static/{DyrX2zX_4v7KZDbUNxE2q → O3E7X3EJ2lEKs_0hIUzGd}/_buildManifest.js +0 -0
  43. /package/dist/web/standalone/.next/static/{DyrX2zX_4v7KZDbUNxE2q → O3E7X3EJ2lEKs_0hIUzGd}/_ssgManifest.js +0 -0
@@ -197,7 +197,11 @@ export async function buildForensicReport(basePath) {
197
197
  // Extensions run from ~/.gsd/agent/extensions/gsd/ at runtime, so path-traversal
198
198
  // from import.meta.url would resolve to ~/package.json (wrong on every system).
199
199
  const gsdVersion = process.env.GSD_VERSION || "unknown";
200
- // 9. Run anomaly detectors
200
+ // 9. Scan journal for flow timeline and structured events
201
+ const journalSummary = scanJournalForForensics(basePath);
202
+ // 10. Gather activity log directory metadata
203
+ const activityLogMeta = gatherActivityLogMeta(basePath, activeMilestone);
204
+ // 11. Run anomaly detectors
201
205
  if (metrics?.units)
202
206
  detectStuckLoops(metrics.units, anomalies);
203
207
  if (metrics?.units)
@@ -207,6 +211,7 @@ export async function buildForensicReport(basePath) {
207
211
  detectCrash(crashLock, anomalies);
208
212
  detectDoctorIssues(doctorIssues, anomalies);
209
213
  detectErrorTraces(unitTraces, anomalies);
214
+ detectJournalAnomalies(journalSummary, anomalies);
210
215
  return {
211
216
  gsdVersion,
212
217
  timestamp: new Date().toISOString(),
@@ -221,10 +226,14 @@ export async function buildForensicReport(basePath) {
221
226
  doctorIssues,
222
227
  anomalies,
223
228
  recentUnits,
229
+ journalSummary,
230
+ activityLogMeta,
224
231
  };
225
232
  }
226
233
  // ─── Activity Log Scanner ─────────────────────────────────────────────────────
227
234
  const ACTIVITY_FILENAME_RE = /^(\d+)-(.+?)-(.+)\.jsonl$/;
235
+ /** Threshold below which iteration cadence is considered rapid (thrashing). */
236
+ const RAPID_ITERATION_THRESHOLD_MS = 5000;
228
237
  function scanActivityLogs(basePath, activeMilestone) {
229
238
  const activityDirs = resolveActivityDirs(basePath, activeMilestone);
230
239
  const allTraces = [];
@@ -292,6 +301,152 @@ function resolveActivityDirs(basePath, activeMilestone) {
292
301
  dirs.push(rootActivityDir);
293
302
  return dirs;
294
303
  }
304
+ // ─── Journal Scanner ──────────────────────────────────────────────────────────
305
+ /**
306
+ * Max recent journal files to fully parse for event counts and recent events.
307
+ * Older files are line-counted only to avoid loading huge amounts of data.
308
+ */
309
+ const MAX_JOURNAL_RECENT_FILES = 3;
310
+ /** Max recent events to extract for the forensic report timeline. */
311
+ const MAX_JOURNAL_RECENT_EVENTS = 20;
312
+ /**
313
+ * Intelligently scan journal files for forensic summary.
314
+ *
315
+ * Journal files can be huge (thousands of JSONL entries over weeks of auto-mode).
316
+ * Instead of loading all entries into memory:
317
+ * - Only fully parse the most recent N daily files (event counts, flow tracking)
318
+ * - Line-count older files for approximate totals (no JSON parsing)
319
+ * - Extract only the last 20 events for the timeline
320
+ */
321
+ function scanJournalForForensics(basePath) {
322
+ try {
323
+ const journalDir = join(gsdRoot(basePath), "journal");
324
+ if (!existsSync(journalDir))
325
+ return null;
326
+ const files = readdirSync(journalDir).filter(f => f.endsWith(".jsonl")).sort();
327
+ if (files.length === 0)
328
+ return null;
329
+ // Split into recent (fully parsed) and older (line-counted only)
330
+ const recentFiles = files.slice(-MAX_JOURNAL_RECENT_FILES);
331
+ const olderFiles = files.slice(0, -MAX_JOURNAL_RECENT_FILES);
332
+ // Line-count older files without parsing — avoids loading megabytes of JSON
333
+ let olderEntryCount = 0;
334
+ let oldestEntry = null;
335
+ for (const file of olderFiles) {
336
+ try {
337
+ const raw = readFileSync(join(journalDir, file), "utf-8");
338
+ const lines = raw.split("\n");
339
+ for (const line of lines) {
340
+ if (!line.trim())
341
+ continue;
342
+ olderEntryCount++;
343
+ // Extract only the timestamp from the first non-empty line of the oldest file
344
+ if (!oldestEntry) {
345
+ try {
346
+ const parsed = JSON.parse(line);
347
+ if (parsed.ts)
348
+ oldestEntry = parsed.ts;
349
+ }
350
+ catch { /* skip malformed */ }
351
+ }
352
+ }
353
+ }
354
+ catch { /* skip unreadable files */ }
355
+ }
356
+ // Fully parse recent files for event counts and timeline
357
+ const eventCounts = {};
358
+ const flowIds = new Set();
359
+ const recentParsedEntries = [];
360
+ let recentEntryCount = 0;
361
+ for (const file of recentFiles) {
362
+ try {
363
+ const raw = readFileSync(join(journalDir, file), "utf-8");
364
+ for (const line of raw.split("\n")) {
365
+ if (!line.trim())
366
+ continue;
367
+ try {
368
+ const entry = JSON.parse(line);
369
+ recentEntryCount++;
370
+ eventCounts[entry.eventType] = (eventCounts[entry.eventType] ?? 0) + 1;
371
+ flowIds.add(entry.flowId);
372
+ if (!oldestEntry)
373
+ oldestEntry = entry.ts;
374
+ // Keep a rolling window of last N events — avoids accumulating unbounded arrays
375
+ recentParsedEntries.push({
376
+ ts: entry.ts,
377
+ flowId: entry.flowId,
378
+ eventType: entry.eventType,
379
+ rule: entry.rule,
380
+ unitId: entry.data?.unitId,
381
+ });
382
+ if (recentParsedEntries.length > MAX_JOURNAL_RECENT_EVENTS) {
383
+ recentParsedEntries.shift();
384
+ }
385
+ }
386
+ catch { /* skip malformed lines */ }
387
+ }
388
+ }
389
+ catch { /* skip unreadable files */ }
390
+ }
391
+ const totalEntries = olderEntryCount + recentEntryCount;
392
+ if (totalEntries === 0)
393
+ return null;
394
+ const newestEntry = recentParsedEntries.length > 0
395
+ ? recentParsedEntries[recentParsedEntries.length - 1].ts
396
+ : null;
397
+ return {
398
+ totalEntries,
399
+ flowCount: flowIds.size,
400
+ eventCounts,
401
+ recentEvents: recentParsedEntries,
402
+ oldestEntry,
403
+ newestEntry,
404
+ fileCount: files.length,
405
+ };
406
+ }
407
+ catch {
408
+ return null;
409
+ }
410
+ }
411
+ // ─── Activity Log Metadata ────────────────────────────────────────────────────
412
+ function gatherActivityLogMeta(basePath, activeMilestone) {
413
+ try {
414
+ const activityDirs = resolveActivityDirs(basePath, activeMilestone);
415
+ let fileCount = 0;
416
+ let totalSizeBytes = 0;
417
+ let oldestFile = null;
418
+ let newestFile = null;
419
+ let oldestMtime = Infinity;
420
+ let newestMtime = 0;
421
+ for (const activityDir of activityDirs) {
422
+ if (!existsSync(activityDir))
423
+ continue;
424
+ const files = readdirSync(activityDir).filter(f => f.endsWith(".jsonl"));
425
+ for (const file of files) {
426
+ const filePath = join(activityDir, file);
427
+ const stat = statSync(filePath, { throwIfNoEntry: false });
428
+ if (!stat)
429
+ continue;
430
+ fileCount++;
431
+ totalSizeBytes += stat.size;
432
+ if (stat.mtimeMs < oldestMtime) {
433
+ oldestMtime = stat.mtimeMs;
434
+ oldestFile = file;
435
+ }
436
+ if (stat.mtimeMs > newestMtime) {
437
+ newestMtime = stat.mtimeMs;
438
+ newestFile = file;
439
+ }
440
+ }
441
+ }
442
+ if (fileCount === 0)
443
+ return null;
444
+ return { fileCount, totalSizeBytes, oldestFile, newestFile };
445
+ }
446
+ catch {
447
+ return null;
448
+ }
449
+ }
295
450
  // ─── Completed Keys Loader ────────────────────────────────────────────────────
296
451
  function loadCompletedKeys(basePath) {
297
452
  const file = join(gsdRoot(basePath), "completed-units.json");
@@ -423,6 +578,64 @@ function detectErrorTraces(traces, anomalies) {
423
578
  }
424
579
  }
425
580
  }
581
+ function detectJournalAnomalies(journal, anomalies) {
582
+ if (!journal)
583
+ return;
584
+ // Detect stuck-detected events from the journal
585
+ const stuckCount = journal.eventCounts["stuck-detected"] ?? 0;
586
+ if (stuckCount > 0) {
587
+ anomalies.push({
588
+ type: "journal-stuck",
589
+ severity: stuckCount >= 3 ? "error" : "warning",
590
+ summary: `Journal recorded ${stuckCount} stuck-detected event(s)`,
591
+ details: `The auto-mode loop detected it was stuck ${stuckCount} time(s). Check journal events for flow IDs and causal chains to trace the root cause.`,
592
+ });
593
+ }
594
+ // Detect guard-block events (dispatch was blocked by a guard)
595
+ const guardCount = journal.eventCounts["guard-block"] ?? 0;
596
+ if (guardCount > 0) {
597
+ anomalies.push({
598
+ type: "journal-guard-block",
599
+ severity: guardCount >= 5 ? "warning" : "info",
600
+ summary: `Journal recorded ${guardCount} guard-block event(s)`,
601
+ details: `Dispatch was blocked by a guard condition ${guardCount} time(s). This may indicate a persistent blocking condition preventing progress.`,
602
+ });
603
+ }
604
+ // Detect rapid iterations (many flows in short time = likely thrashing)
605
+ if (journal.flowCount > 0 && journal.oldestEntry && journal.newestEntry) {
606
+ const oldest = new Date(journal.oldestEntry).getTime();
607
+ const newest = new Date(journal.newestEntry).getTime();
608
+ const spanMs = newest - oldest;
609
+ if (spanMs > 0 && journal.flowCount > 10) {
610
+ const avgMs = spanMs / journal.flowCount;
611
+ if (avgMs < RAPID_ITERATION_THRESHOLD_MS) {
612
+ anomalies.push({
613
+ type: "journal-rapid-iterations",
614
+ severity: "warning",
615
+ summary: `${journal.flowCount} iterations in ${formatDuration(spanMs)} (avg ${formatDuration(avgMs)}/iteration)`,
616
+ details: `Unusually rapid iteration cadence suggests the loop may be thrashing without making progress. Review recent journal events for dispatch-stop or terminal events.`,
617
+ });
618
+ }
619
+ }
620
+ }
621
+ // Detect worktree failures from journal events
622
+ const wtCreateFailed = journal.eventCounts["worktree-create-failed"] ?? 0;
623
+ const wtMergeFailed = journal.eventCounts["worktree-merge-failed"] ?? 0;
624
+ const wtFailures = wtCreateFailed + wtMergeFailed;
625
+ if (wtFailures > 0) {
626
+ const parts = [];
627
+ if (wtCreateFailed > 0)
628
+ parts.push(`${wtCreateFailed} create failure(s)`);
629
+ if (wtMergeFailed > 0)
630
+ parts.push(`${wtMergeFailed} merge failure(s)`);
631
+ anomalies.push({
632
+ type: "journal-worktree-failure",
633
+ severity: "warning",
634
+ summary: `Worktree failures: ${parts.join(", ")}`,
635
+ details: `Journal recorded worktree operation failures. These may indicate git state corruption or conflicting branches.`,
636
+ });
637
+ }
638
+ }
426
639
  // ─── Report Persistence ───────────────────────────────────────────────────────
427
640
  function saveForensicReport(basePath, report, problemDescription) {
428
641
  const dir = join(gsdRoot(basePath), "forensics");
@@ -491,6 +704,48 @@ function saveForensicReport(basePath, report, problemDescription) {
491
704
  sections.push(`## Crash Lock`, ``);
492
705
  sections.push(redact(formatCrashInfo(report.crashLock)), ``);
493
706
  }
707
+ // Activity log metadata
708
+ if (report.activityLogMeta) {
709
+ const meta = report.activityLogMeta;
710
+ sections.push(`## Activity Log Metadata`, ``);
711
+ sections.push(`- Files: ${meta.fileCount}`);
712
+ sections.push(`- Total size: ${(meta.totalSizeBytes / 1024).toFixed(1)} KB`);
713
+ if (meta.oldestFile)
714
+ sections.push(`- Oldest: ${meta.oldestFile}`);
715
+ if (meta.newestFile)
716
+ sections.push(`- Newest: ${meta.newestFile}`);
717
+ sections.push(``);
718
+ }
719
+ // Journal summary
720
+ if (report.journalSummary) {
721
+ const js = report.journalSummary;
722
+ sections.push(`## Journal Summary`, ``);
723
+ sections.push(`- Total entries: ${js.totalEntries}`);
724
+ sections.push(`- Distinct flows (iterations): ${js.flowCount}`);
725
+ sections.push(`- Daily files: ${js.fileCount}`);
726
+ if (js.oldestEntry)
727
+ sections.push(`- Date range: ${js.oldestEntry} — ${js.newestEntry}`);
728
+ sections.push(``);
729
+ sections.push(`### Event Type Distribution`, ``);
730
+ sections.push(`| Event Type | Count |`);
731
+ sections.push(`|------------|-------|`);
732
+ for (const [evType, count] of Object.entries(js.eventCounts).sort((a, b) => b[1] - a[1])) {
733
+ sections.push(`| ${evType} | ${count} |`);
734
+ }
735
+ sections.push(``);
736
+ if (js.recentEvents.length > 0) {
737
+ sections.push(`### Recent Journal Events (last ${js.recentEvents.length})`, ``);
738
+ for (const ev of js.recentEvents) {
739
+ const parts = [`${ev.ts} [${ev.eventType}] flow=${ev.flowId.slice(0, 8)}`];
740
+ if (ev.rule)
741
+ parts.push(`rule=${ev.rule}`);
742
+ if (ev.unitId)
743
+ parts.push(`unit=${ev.unitId}`);
744
+ sections.push(`- ${parts.join(" ")}`);
745
+ }
746
+ sections.push(``);
747
+ }
748
+ }
494
749
  writeFileSync(filePath, sections.join("\n"), "utf-8");
495
750
  return filePath;
496
751
  }
@@ -565,6 +820,42 @@ function formatReportForPrompt(report) {
565
820
  sections.push(`- Total duration: ${formatDuration(totals.duration)}`);
566
821
  sections.push("");
567
822
  }
823
+ // Activity log metadata
824
+ if (report.activityLogMeta) {
825
+ const meta = report.activityLogMeta;
826
+ sections.push("### Activity Log Overview");
827
+ sections.push(`- Files: ${meta.fileCount}, Total size: ${(meta.totalSizeBytes / 1024).toFixed(1)} KB`);
828
+ if (meta.oldestFile)
829
+ sections.push(`- Oldest: ${meta.oldestFile}`);
830
+ if (meta.newestFile)
831
+ sections.push(`- Newest: ${meta.newestFile}`);
832
+ sections.push("");
833
+ }
834
+ // Journal summary — structured event timeline
835
+ if (report.journalSummary) {
836
+ const js = report.journalSummary;
837
+ sections.push("### Journal Summary (Iteration Event Log)");
838
+ sections.push(`- Total entries: ${js.totalEntries}, Distinct flows: ${js.flowCount}, Daily files: ${js.fileCount}`);
839
+ if (js.oldestEntry)
840
+ sections.push(`- Date range: ${js.oldestEntry} — ${js.newestEntry}`);
841
+ // Event type distribution (compact)
842
+ const eventPairs = Object.entries(js.eventCounts).sort((a, b) => b[1] - a[1]);
843
+ sections.push(`- Events: ${eventPairs.map(([t, c]) => `${t}(${c})`).join(", ")}`);
844
+ // Recent events timeline (for tracing what just happened)
845
+ if (js.recentEvents.length > 0) {
846
+ sections.push("");
847
+ sections.push(`**Recent Journal Events (last ${js.recentEvents.length}):**`);
848
+ for (const ev of js.recentEvents) {
849
+ const parts = [`${ev.ts} [${ev.eventType}] flow=${ev.flowId.slice(0, 8)}`];
850
+ if (ev.rule)
851
+ parts.push(`rule=${ev.rule}`);
852
+ if (ev.unitId)
853
+ parts.push(`unit=${ev.unitId}`);
854
+ sections.push(`- ${parts.join(" ")}`);
855
+ }
856
+ }
857
+ sections.push("");
858
+ }
568
859
  // Completed keys count
569
860
  sections.push(`### Completed Keys: ${report.completedKeys.length}`);
570
861
  sections.push(`### GSD Version: ${report.gsdVersion}`);
@@ -29,7 +29,7 @@ import { showProjectInit, offerMigration } from "./init-wizard.js";
29
29
  import { validateDirectory } from "./validate-directory.js";
30
30
  import { showConfirm } from "../shared/tui.js";
31
31
  import { debugLog } from "./debug-logger.js";
32
- import { findMilestoneIds, nextMilestoneId, reserveMilestoneId, getReservedMilestoneIds } from "./milestone-ids.js";
32
+ import { findMilestoneIds, nextMilestoneId, reserveMilestoneId, getReservedMilestoneIds, clearReservedMilestoneIds } from "./milestone-ids.js";
33
33
  import { parkMilestone, discardMilestone } from "./milestone-actions.js";
34
34
  import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
35
35
  // ─── Re-exports (preserve public API for existing importers) ────────────────
@@ -296,6 +296,8 @@ function bootstrapGsdProject(basePath) {
296
296
  * and dispatches the headless discuss prompt (no Q&A rounds).
297
297
  */
298
298
  export async function showHeadlessMilestoneCreation(ctx, pi, basePath, seedContext) {
299
+ // Clear stale reservations from previous cancelled sessions (#2488)
300
+ clearReservedMilestoneIds();
299
301
  // Ensure .gsd/ is bootstrapped
300
302
  bootstrapGsdProject(basePath);
301
303
  // Generate next milestone ID
@@ -769,6 +771,10 @@ async function handleMilestoneActions(ctx, pi, basePath, milestoneId, milestoneT
769
771
  }
770
772
  export async function showSmartEntry(ctx, pi, basePath, options) {
771
773
  const stepMode = options?.step;
774
+ // ── Clear stale milestone ID reservations from previous cancelled sessions ──
775
+ // Reservations only need to survive within a single /gsd interaction.
776
+ // Without this, each cancelled session permanently bumps the next ID. (#2488)
777
+ clearReservedMilestoneIds();
772
778
  // ── Directory safety check — refuse to operate in system/home dirs ───
773
779
  const dirCheck = validateDirectory(basePath);
774
780
  if (dirCheck.severity === "blocked") {
@@ -36,6 +36,8 @@ GSD extension source code is at: `{{gsdSourceDir}}`
36
36
  ├── doctor-history.jsonl — doctor check history
37
37
  ├── activity/ — session activity logs (JSONL per unit)
38
38
  │ └── {seq}-{unitType}-{unitId}.jsonl
39
+ ├── journal/ — structured event journal (JSONL per day)
40
+ │ └── YYYY-MM-DD.jsonl
39
41
  ├── runtime/
40
42
  │ ├── paused-session.json — serialized session when auto pauses
41
43
  │ └── headless-context.md — headless resume context
@@ -60,6 +62,32 @@ GSD extension source code is at: `{{gsdSourceDir}}`
60
62
  - `usage` field on assistant messages: `input`, `output`, `cacheRead`, `cacheWrite`, `totalTokens`, `cost`
61
63
  - **To trace a failure**: find the last activity log, search for `isError: true` tool results, then read the agent's reasoning text preceding that error
62
64
 
65
+ ### Journal Format (`.gsd/journal/`)
66
+
67
+ The journal is a structured event log for auto-mode iterations. Each daily file contains JSONL entries:
68
+
69
+ ```
70
+ { ts: "ISO-8601", flowId: "UUID", seq: 0, eventType: "iteration-start", rule?: "rule-name", causedBy?: { flowId, seq }, data?: { unitId, status, ... } }
71
+ ```
72
+
73
+ **Key event types:**
74
+ - `iteration-start` / `iteration-end` — marks loop iteration boundaries
75
+ - `dispatch-match` / `dispatch-stop` — what the auto-mode decided to do (or not do)
76
+ - `unit-start` / `unit-end` — lifecycle of individual work units
77
+ - `terminal` — auto-mode reached a terminal state (all done, budget exceeded, etc.)
78
+ - `guard-block` — dispatch was blocked by a guard condition (e.g. needs user input)
79
+ - `stuck-detected` — the loop detected it was stuck (same unit repeatedly dispatched)
80
+ - `milestone-transition` — a milestone was promoted or completed
81
+ - `worktree-enter` / `worktree-create-failed` / `worktree-merge-start` / `worktree-merge-failed` — worktree operations
82
+
83
+ **Key concepts:**
84
+ - **flowId**: UUID grouping all events in one iteration. Use to reconstruct what happened in a single loop pass.
85
+ - **causedBy**: Cross-reference to a prior event (same or different flow). Enables causal chain tracing.
86
+ - **seq**: Monotonically increasing within a flow. Reconstruct event order within an iteration.
87
+
88
+ **To trace a stuck loop**: filter for `stuck-detected` events, then follow `flowId` to see the surrounding dispatch and unit events.
89
+ **To trace a guard block**: filter for `guard-block` events, check `data.reason` for why dispatch was blocked.
90
+
63
91
  ### Crash Lock Format (`auto.lock`)
64
92
 
65
93
  JSON with fields: `pid`, `startedAt`, `unitType`, `unitId`, `unitStartedAt`, `completedUnits`, `sessionFile`
@@ -78,20 +106,24 @@ A unit dispatched more than once (`type/id` appears multiple times) indicates a
78
106
 
79
107
  1. **Start with the pre-parsed forensic report** above. The anomaly section contains automated findings — treat these as leads, not conclusions.
80
108
 
81
- 2. **Form hypotheses** about which module and code path is responsible. Use the source map to identify candidate files.
109
+ 2. **Check the journal timeline** if present. The journal events show the auto-mode's decision sequence (dispatches, guards, stuck detection, worktree operations). Use flow IDs to group related events and trace causal chains.
110
+
111
+ 3. **Cross-reference activity logs and journal**. Activity logs show *what the LLM did* (tool calls, reasoning, errors). Journal events show *what auto-mode decided* (dispatch rules, iteration boundaries, state transitions). Together they reveal the full picture.
112
+
113
+ 4. **Form hypotheses** about which module and code path is responsible. Use the source map to identify candidate files.
82
114
 
83
- 3. **Read the actual GSD source code** at `{{gsdSourceDir}}` to confirm or deny each hypothesis. Do not guess what code does — read it.
115
+ 5. **Read the actual GSD source code** at `{{gsdSourceDir}}` to confirm or deny each hypothesis. Do not guess what code does — read it.
84
116
 
85
- 4. **Trace the code path** from the entry point (usually `auto-loop.ts` dispatch or `auto-dispatch.ts`) through to the failure point. Follow function calls across files.
117
+ 6. **Trace the code path** from the entry point (usually `auto-loop.ts` dispatch or `auto-dispatch.ts`) through to the failure point. Follow function calls across files.
86
118
 
87
- 5. **Identify the specific file and line** where the bug lives. Determine what kind of defect it is:
119
+ 7. **Identify the specific file and line** where the bug lives. Determine what kind of defect it is:
88
120
  - Missing edge case / unhandled condition
89
121
  - Wrong boolean logic or comparison
90
122
  - Race condition or ordering issue
91
123
  - State corruption (e.g. completed-units.json out of sync with artifacts)
92
124
  - Timeout / recovery logic not triggering correctly
93
125
 
94
- 6. **Clarify if needed.** Use ask_user_questions (max 2 questions) only if the report is genuinely insufficient. Do not ask questions you can answer from the data or source code.
126
+ 8. **Clarify if needed.** Use ask_user_questions (max 2 questions) only if the report is genuinely insufficient. Do not ask questions you can answer from the data or source code.
95
127
 
96
128
  ## Output
97
129
 
@@ -1 +1 @@
1
- DyrX2zX_4v7KZDbUNxE2q
1
+ O3E7X3EJ2lEKs_0hIUzGd
@@ -1,45 +1,45 @@
1
1
  {
2
2
  "/_not-found/page": "/_not-found",
3
3
  "/_global-error/page": "/_global-error",
4
- "/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
5
- "/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
6
4
  "/api/boot/route": "/api/boot",
5
+ "/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
6
+ "/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
7
7
  "/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
8
- "/api/cleanup/route": "/api/cleanup",
9
8
  "/api/dev-mode/route": "/api/dev-mode",
9
+ "/api/cleanup/route": "/api/cleanup",
10
10
  "/api/export-data/route": "/api/export-data",
11
11
  "/api/captures/route": "/api/captures",
12
- "/api/doctor/route": "/api/doctor",
13
12
  "/api/forensics/route": "/api/forensics",
14
- "/api/history/route": "/api/history",
15
- "/api/hooks/route": "/api/hooks",
13
+ "/api/doctor/route": "/api/doctor",
16
14
  "/api/git/route": "/api/git",
15
+ "/api/history/route": "/api/history",
17
16
  "/api/browse-directories/route": "/api/browse-directories",
18
- "/api/knowledge/route": "/api/knowledge",
17
+ "/api/hooks/route": "/api/hooks",
19
18
  "/api/inspect/route": "/api/inspect",
19
+ "/api/knowledge/route": "/api/knowledge",
20
20
  "/api/live-state/route": "/api/live-state",
21
- "/api/preferences/route": "/api/preferences",
22
- "/api/recovery/route": "/api/recovery",
23
21
  "/api/onboarding/route": "/api/onboarding",
24
22
  "/api/projects/route": "/api/projects",
23
+ "/api/preferences/route": "/api/preferences",
25
24
  "/api/session/browser/route": "/api/session/browser",
26
- "/api/session/command/route": "/api/session/command",
27
25
  "/api/session/events/route": "/api/session/events",
28
- "/api/settings-data/route": "/api/settings-data",
26
+ "/api/session/command/route": "/api/session/command",
29
27
  "/api/session/manage/route": "/api/session/manage",
30
- "/api/shutdown/route": "/api/shutdown",
28
+ "/api/settings-data/route": "/api/settings-data",
31
29
  "/api/skill-health/route": "/api/skill-health",
30
+ "/api/files/route": "/api/files",
32
31
  "/api/steer/route": "/api/steer",
33
- "/api/terminal/input/route": "/api/terminal/input",
32
+ "/api/terminal/resize/route": "/api/terminal/resize",
34
33
  "/api/switch-root/route": "/api/switch-root",
34
+ "/api/terminal/input/route": "/api/terminal/input",
35
35
  "/api/terminal/sessions/route": "/api/terminal/sessions",
36
- "/api/files/route": "/api/files",
37
- "/api/terminal/resize/route": "/api/terminal/resize",
38
36
  "/api/terminal/stream/route": "/api/terminal/stream",
39
- "/api/visualizer/route": "/api/visualizer",
37
+ "/api/recovery/route": "/api/recovery",
38
+ "/api/shutdown/route": "/api/shutdown",
40
39
  "/api/terminal/upload/route": "/api/terminal/upload",
41
- "/api/remote-questions/route": "/api/remote-questions",
42
40
  "/api/undo/route": "/api/undo",
41
+ "/api/remote-questions/route": "/api/remote-questions",
42
+ "/api/visualizer/route": "/api/visualizer",
43
43
  "/api/update/route": "/api/update",
44
44
  "/page": "/"
45
45
  }
@@ -4,8 +4,8 @@
4
4
  ],
5
5
  "devFiles": [],
6
6
  "lowPriorityFiles": [
7
- "static/DyrX2zX_4v7KZDbUNxE2q/_buildManifest.js",
8
- "static/DyrX2zX_4v7KZDbUNxE2q/_ssgManifest.js"
7
+ "static/O3E7X3EJ2lEKs_0hIUzGd/_buildManifest.js",
8
+ "static/O3E7X3EJ2lEKs_0hIUzGd/_ssgManifest.js"
9
9
  ],
10
10
  "rootMainFiles": [
11
11
  "static/chunks/webpack-0a4cd455ec4197d2.js",
@@ -78,8 +78,8 @@
78
78
  "dynamicRoutes": {},
79
79
  "notFoundRoutes": [],
80
80
  "preview": {
81
- "previewModeId": "a80a606752e17c880119d3545e1faa6e",
82
- "previewModeSigningKey": "3a511f8bd2204f2943d8e667be2c3c27601c67398e03927a25b52817ca86d602",
83
- "previewModeEncryptionKey": "8cedfc253133096267c2f0a203b07da60b22dbfe50406179325850ef9f335739"
81
+ "previewModeId": "446a6c648d2fc4a7e1c707dec447f29c",
82
+ "previewModeSigningKey": "1085d39489f5cf617079ccd48d7b083e0bdb1b2710355a0c1e3bd6185bc6c9a8",
83
+ "previewModeEncryptionKey": "1d3c307c105e142bd56433bcf66c8c7f24be7e0a373bcf8629c0277a9b8ec495"
84
84
  }
85
85
  }
@@ -1,2 +1,2 @@
1
- <!DOCTYPE html><!--DyrX2zX_4v7KZDbUNxE2q--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-0a4cd455ec4197d2.js"/><script src="/_next/static/chunks/4bd1b696-e5d7c65570c947b7.js" async=""></script><script src="/_next/static/chunks/3794-337d1ca25ad99a89.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
- @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-0a4cd455ec4197d2.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[90484,[],\"ViewportBoundary\"]\n9:I[90484,[],\"MetadataBoundary\"]\nb:I[27123,[],\"\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"DyrX2zX_4v7KZDbUNxE2q\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--O3E7X3EJ2lEKs_0hIUzGd--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-0a4cd455ec4197d2.js"/><script src="/_next/static/chunks/4bd1b696-e5d7c65570c947b7.js" async=""></script><script src="/_next/static/chunks/3794-337d1ca25ad99a89.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
+ @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-0a4cd455ec4197d2.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[90484,[],\"ViewportBoundary\"]\n9:I[90484,[],\"MetadataBoundary\"]\nb:I[27123,[],\"\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"O3E7X3EJ2lEKs_0hIUzGd\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
@@ -6,7 +6,7 @@
6
6
  7:I[90484,[],"ViewportBoundary"]
7
7
  9:I[90484,[],"MetadataBoundary"]
8
8
  b:I[27123,[],""]
9
- 0:{"P":null,"b":"DyrX2zX_4v7KZDbUNxE2q","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["_global-error",{"children":["__PAGE__",{}]}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b",[]],"S":true}
9
+ 0:{"P":null,"b":"O3E7X3EJ2lEKs_0hIUzGd","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["_global-error",{"children":["__PAGE__",{}]}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b",[]],"S":true}
10
10
  8:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
11
11
  6:null
12
12
  a:[]
@@ -6,7 +6,7 @@
6
6
  7:I[90484,[],"ViewportBoundary"]
7
7
  9:I[90484,[],"MetadataBoundary"]
8
8
  b:I[27123,[],""]
9
- 0:{"P":null,"b":"DyrX2zX_4v7KZDbUNxE2q","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["_global-error",{"children":["__PAGE__",{}]}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b",[]],"S":true}
9
+ 0:{"P":null,"b":"O3E7X3EJ2lEKs_0hIUzGd","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["_global-error",{"children":["__PAGE__",{}]}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b",[]],"S":true}
10
10
  8:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
11
11
  6:null
12
12
  a:[]