@zerwiz/ymir 0.1.16 → 0.1.18

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 (171) hide show
  1. package/.agents/config/app-repos.yaml +38 -0
  2. package/.claude/settings.json +31 -0
  3. package/.codex/hooks.json +43 -0
  4. package/.cursor/hooks.json +33 -0
  5. package/.pi/extensions/README.md +39 -0
  6. package/.pi/extensions/gna-pi-watch.ts +15 -0
  7. package/.pi/extensions/lib/ro-assistant-layout.ts +96 -0
  8. package/.pi/extensions/lib/ro-operational-user-layout.ts +145 -0
  9. package/.pi/extensions/lib/ro-visibility.ts +99 -0
  10. package/.pi/extensions/lib/ro-working-ship.ts +243 -0
  11. package/.pi/extensions/lib/rodd-operational-input.ts +62 -0
  12. package/.pi/extensions/lib/skuld-branch-dispatch.ts +252 -0
  13. package/.pi/extensions/lib/skuld-branch-model-picker.ts +77 -0
  14. package/.pi/extensions/lib/vordr-sessionstart-supervisor.mjs +48 -0
  15. package/.pi/extensions/ro.ts +11 -0
  16. package/.pi/extensions/skuld-branch-supervision.ts +11 -0
  17. package/.pi/extensions/syn-turnend-guard.ts +11 -0
  18. package/.pi/mcp.json +16 -0
  19. package/.pi/mcp.json.example +11 -0
  20. package/.pi/npm/.gitignore +2 -0
  21. package/.pi/settings.json +8 -0
  22. package/.pi/shared/extensions/gna-pi-watch.ts +750 -0
  23. package/.pi/shared/extensions/herdr-agent-state.ts +257 -0
  24. package/.pi/shared/extensions/open-editor.ts +509 -0
  25. package/.pi/shared/extensions/ro.ts +504 -0
  26. package/.pi/shared/extensions/skuld-branch-supervision.ts +1535 -0
  27. package/.pi/shared/extensions/syn-turnend-guard.ts +683 -0
  28. package/.pi/shared/extensions/todo.ts +133 -0
  29. package/.pi/shared/extensions/ymir-subagents.ts +287 -0
  30. package/.pi/shared/extensions/ymir-well.ts +130 -0
  31. package/CHANGELOG.md +23 -0
  32. package/assets/Ymir.md +4654 -0
  33. package/assets/healer.html +717 -0
  34. package/assets/icon-family/family-sheet.png +0 -0
  35. package/assets/icon-family/hlidskjalf.svg +1 -0
  36. package/assets/icon-family/sessrumnir.svg +1 -0
  37. package/assets/icon-family/smidja.svg +1 -0
  38. package/assets/icon-family/ymir.svg +1 -0
  39. package/assets/mimirswell.html +880 -0
  40. package/assets/mock/README.md +16 -0
  41. package/assets/mock/feeds.ts +175 -0
  42. package/assets/mock/mock.ts +408 -0
  43. package/assets/reference/docs/agent-control.md +122 -0
  44. package/assets/reference/docs/apodex/Appdex_as_Orchestrator_Planner_Reviewer_Assessment.md +176 -0
  45. package/assets/reference/docs/apodex/Final Report(1).md +198 -0
  46. package/assets/reference/docs/apodex/Final Report(2).md +54 -0
  47. package/assets/reference/docs/apodex/Final Report(3).md +40 -0
  48. package/assets/reference/docs/apodex/Final Report(4).md +234 -0
  49. package/assets/reference/docs/apodex/Final Report(5).md +13 -0
  50. package/assets/reference/docs/apodex/Final Report.md +82 -0
  51. package/assets/reference/docs/architecture.md +392 -0
  52. package/assets/reference/docs/arm-pretool-check.md +247 -0
  53. package/assets/reference/docs/calm-mode-feasibility.md +541 -0
  54. package/assets/reference/docs/calm.md +59 -0
  55. package/assets/reference/docs/captain-hold-lifecycle.md +96 -0
  56. package/assets/reference/docs/cd-guard.md +165 -0
  57. package/assets/reference/docs/cmux-backend.md +133 -0
  58. package/assets/reference/docs/codex-app-backend.md +57 -0
  59. package/assets/reference/docs/configuration.md +924 -0
  60. package/assets/reference/docs/documentation-audiences.json +468 -0
  61. package/assets/reference/docs/documentation-audiences.md +28 -0
  62. package/assets/reference/docs/examples/crew-dispatch.json +26 -0
  63. package/assets/reference/docs/examples/process-event-extension/file-signal.mjs +96 -0
  64. package/assets/reference/docs/examples/process-event-extension/firstmate-extension.json +15 -0
  65. package/assets/reference/docs/examples/watched-tools.json +24 -0
  66. package/assets/reference/docs/examples/wedge-alarm +22 -0
  67. package/assets/reference/docs/extension-bindings.md +237 -0
  68. package/assets/reference/docs/fm-test-isolation-proof.json +37 -0
  69. package/assets/reference/docs/fm-test-isolation-proof.md +149 -0
  70. package/assets/reference/docs/fm-test-portable-shards.md +118 -0
  71. package/assets/reference/docs/gitlab-merge-watch.md +275 -0
  72. package/assets/reference/docs/herdr-backend.md +346 -0
  73. package/assets/reference/docs/orca-backend.md +84 -0
  74. package/assets/reference/docs/pi-supervision-branch-poster.svg +125 -0
  75. package/assets/reference/docs/pi-supervision-branch.md +96 -0
  76. package/assets/reference/docs/plans/agentic-engineering-workflow.md +395 -0
  77. package/assets/reference/docs/plans/agentic-factory-implementation-plan.md +615 -0
  78. package/assets/reference/docs/plans/command-factory-enhancement-plan.md +420 -0
  79. package/assets/reference/docs/plans/phase-1-layer3-program-design.md +134 -0
  80. package/assets/reference/docs/plans/phase-2-vertical-slices.md +100 -0
  81. package/assets/reference/docs/plans/phase-3-measurable-goals.md +106 -0
  82. package/assets/reference/docs/plans/phase-4-context-budget.md +106 -0
  83. package/assets/reference/docs/plans/phase-5-pre-mortem-confidence.md +100 -0
  84. package/assets/reference/docs/plans/phase-6-incident-to-agent.md +109 -0
  85. package/assets/reference/docs/remote-secondmates.md +268 -0
  86. package/assets/reference/docs/scripts.md +146 -0
  87. package/assets/reference/docs/sessionstart-nudge.md +115 -0
  88. package/assets/reference/docs/subagent-guard.md +383 -0
  89. package/assets/reference/docs/supervision-protocols/claude.md +27 -0
  90. package/assets/reference/docs/supervision-protocols/codex.md +16 -0
  91. package/assets/reference/docs/supervision-protocols/cursor.md +31 -0
  92. package/assets/reference/docs/supervision-protocols/grok.md +39 -0
  93. package/assets/reference/docs/supervision-protocols/opencode.md +17 -0
  94. package/assets/reference/docs/supervision-protocols/pi.md +33 -0
  95. package/assets/reference/docs/supervision-protocols/unknown.md +13 -0
  96. package/assets/reference/docs/tmux-backend.md +115 -0
  97. package/assets/reference/docs/trace-context.md +117 -0
  98. package/assets/reference/docs/turnend-guard.md +170 -0
  99. package/assets/reference/docs/verification/dispatch-auth.md +204 -0
  100. package/assets/reference/docs/verification/muse.md +221 -0
  101. package/assets/reference/docs/verification/process-event-sources.md +208 -0
  102. package/assets/reference/docs/verification/public-followup.md +119 -0
  103. package/assets/reference/docs/verification/runtime-backends.md +1022 -0
  104. package/assets/reference/docs/verification/stow-memory.md +53 -0
  105. package/assets/reference/docs/verification/supervision.md +534 -0
  106. package/assets/reference/docs/verification/trace-context.md +31 -0
  107. package/assets/reference/docs/voice-relay.md +295 -0
  108. package/assets/reference/docs/watcher-continuity.md +119 -0
  109. package/assets/reference/docs/wedge-alarm.md +39 -0
  110. package/assets/reference/docs/zellij-backend.md +114 -0
  111. package/assets/reference/index.html +1172 -0
  112. package/assets/reference/skills/afk/SKILL.md +241 -0
  113. package/assets/reference/skills/ahoy/SKILL.md +56 -0
  114. package/assets/reference/skills/ask-user-authority/SKILL.md +56 -0
  115. package/assets/reference/skills/bearings/SKILL.md +161 -0
  116. package/assets/reference/skills/bearings/assets/board-template.html +731 -0
  117. package/assets/reference/skills/bootstrap-diagnostics/SKILL.md +68 -0
  118. package/assets/reference/skills/captain-hold-lifecycle/SKILL.md +54 -0
  119. package/assets/reference/skills/decision-hold-lifecycle/SKILL.md +15 -0
  120. package/assets/reference/skills/diagnostic-reasoning/SKILL.md +53 -0
  121. package/assets/reference/skills/firstmate-codexapp/SKILL.md +110 -0
  122. package/assets/reference/skills/firstmate-codexapp/agents/openai.yaml +4 -0
  123. package/assets/reference/skills/firstmate-coding-guidelines/SKILL.md +127 -0
  124. package/assets/reference/skills/firstmate-orca/SKILL.md +92 -0
  125. package/assets/reference/skills/fmx-respond/SKILL.md +283 -0
  126. package/assets/reference/skills/harness-adapters/SKILL.md +95 -0
  127. package/assets/reference/skills/harness-adapters/references/common/control-and-recovery.md +37 -0
  128. package/assets/reference/skills/harness-adapters/references/common/dispatch.md +32 -0
  129. package/assets/reference/skills/harness-adapters/references/common/model-and-effort.md +42 -0
  130. package/assets/reference/skills/harness-adapters/references/common/primary-hooks.md +40 -0
  131. package/assets/reference/skills/harness-adapters/references/harness/claude.md +55 -0
  132. package/assets/reference/skills/harness-adapters/references/harness/codex.md +43 -0
  133. package/assets/reference/skills/harness-adapters/references/harness/cursor.md +75 -0
  134. package/assets/reference/skills/harness-adapters/references/harness/grok.md +69 -0
  135. package/assets/reference/skills/harness-adapters/references/harness/kimi.md +51 -0
  136. package/assets/reference/skills/harness-adapters/references/harness/muse.md +70 -0
  137. package/assets/reference/skills/harness-adapters/references/harness/opencode.md +42 -0
  138. package/assets/reference/skills/harness-adapters/references/harness/pi.md +56 -0
  139. package/assets/reference/skills/process-event-sources/SKILL.md +137 -0
  140. package/assets/reference/skills/project-management/SKILL.md +92 -0
  141. package/assets/reference/skills/quota-array-dispatch/SKILL.md +131 -0
  142. package/assets/reference/skills/secondmate-provisioning/SKILL.md +254 -0
  143. package/assets/reference/skills/stow/SKILL.md +309 -0
  144. package/assets/reference/skills/stuck-crewmate-recovery/SKILL.md +54 -0
  145. package/assets/reference/skills/updatefirstmate/SKILL.md +64 -0
  146. package/assets/skills/README.md +5 -0
  147. package/assets/yggdrasil.html +649 -0
  148. package/assets/ymir-banner-01.png +0 -0
  149. package/assets/ymir-banner-02.png +0 -0
  150. package/assets/ymir-banner-03.png +0 -0
  151. package/assets/ymir-banner-04.png +0 -0
  152. package/assets/ymir-banner-05.png +0 -0
  153. package/assets/ymir-banner-06.png +0 -0
  154. package/assets/ymir-emblem-darksteel.svg +63 -0
  155. package/assets/ymir-emblem-forged.svg +55 -0
  156. package/assets/ymir-emblem-slate.svg +55 -0
  157. package/assets/ymir-mark-algiz-anvil.svg +9 -0
  158. package/assets/ymir-stave.svg +53 -0
  159. package/assets/ymir.html +563 -0
  160. package/bin/ymir-install.sh +6 -1
  161. package/data/learnings.md +33 -0
  162. package/data/local-models.md +34 -0
  163. package/data/operator.md +15 -0
  164. package/data/projects.md +28 -0
  165. package/data/realm.md +1 -0
  166. package/deploy/Containerfile +27 -0
  167. package/deploy/README.md +104 -0
  168. package/deploy/compose/compose.yaml +45 -0
  169. package/deploy/env.example +30 -0
  170. package/deploy/quadlet/ymir.container +57 -0
  171. package/package.json +10 -8
@@ -0,0 +1,16 @@
1
+ # assets/mock — archived UI seed data
2
+
3
+ Preserved copies of the Hlidskjalf mock/seed sources, kept for possible later use.
4
+ They are **not** imported by the shipped UI.
5
+
6
+ | File | Was | Purpose |
7
+ |---|---|---|
8
+ | `mock.ts` | `apps/hlidskjalf/src/data/mock.ts` | seed agents/tasks/runes/stream/recall/processes/reviews/files/skills/chat |
9
+ | `feeds.ts` | `apps/hlidskjalf/src/data/feeds.ts` | hardcoded per-page stream narration (`feedEvent` / `seedGateFeed`) |
10
+
11
+ Context: the Allfather directed the UI to carry no mock data in live mode; the
12
+ synthetic stream feed and seeded live paths were removed. A **hidden demo** may
13
+ still seed from `src/data/mock.ts`.
14
+
15
+ Law: `AGENTS.md` §Operational laws — *"No mocks, no examples, no placeholders in
16
+ shipped runtime or deliverables."* This directory is the archive, not the runtime.
@@ -0,0 +1,175 @@
1
+ import type { GateId, StreamEvent } from '../types';
2
+
3
+ /**
4
+ * Per-page domain feeds. Every gate gets its own rolling window of hardcoded,
5
+ * domain-appropriate messages so each page always shows a hot feed about what
6
+ * that page is about. These are UI narration, not memory — the well itself
7
+ * stays strictly real.
8
+ */
9
+ interface FeedLine {
10
+ from: string;
11
+ module: string;
12
+ kind: 'ratatoskr' | 'rune';
13
+ message: string;
14
+ }
15
+
16
+ const FEED: Record<string, FeedLine[]> = {
17
+ fleet: [
18
+ { from: 'Brokk', module: 'fleet', kind: 'ratatoskr', message: 'agent card re-signed · A2A 1.0' },
19
+ { from: 'Kaia', module: 'fleet', kind: 'ratatoskr', message: 'capability query fanned to 9 agents' },
20
+ { from: 'Eindri-01', module: 'utgard', kind: 'rune', message: 'worker heartbeat nominal' },
21
+ { from: 'Eindri-02', module: 'yggdrasil', kind: 'rune', message: 'worktree branch advanced' },
22
+ { from: 'Heimdall', module: 'fleet', kind: 'rune', message: 'rune of introduction verified' },
23
+ { from: 'Ratatoskr', module: 'ratatoskr', kind: 'ratatoskr', message: 'peer discovery refreshed' },
24
+ { from: 'Brokk', module: 'fleet', kind: 'rune', message: 'traceability index at 0.984' },
25
+ { from: 'Sindri', module: 'utgard', kind: 'ratatoskr', message: 'specialist lane attached' },
26
+ ],
27
+ tasks: [
28
+ { from: 'Kaia', module: 'ratatoskr', kind: 'ratatoskr', message: 'task state announced to peers' },
29
+ { from: 'Brokk', module: 'tasks', kind: 'rune', message: 'BACKLOG order claimed' },
30
+ { from: 'Eindri-01', module: 'tasks', kind: 'ratatoskr', message: 'SUBMITTED → WORKING' },
31
+ { from: 'Kaia', module: 'tasks', kind: 'ratatoskr', message: 'INPUT_REQUIRED raised for approval' },
32
+ { from: 'Brokk', module: 'tasks', kind: 'rune', message: 'artifact attached to order' },
33
+ { from: 'Ratatoskr', module: 'ratatoskr', kind: 'ratatoskr', message: 'redis queue drained ratatoskr:inbox' },
34
+ { from: 'Kaia', module: 'tasks', kind: 'ratatoskr', message: 'task lifecycle checkpoint written' },
35
+ ],
36
+ well: [
37
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'recall hybrid — episodes merged' },
38
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'observe episode carved into the engram' },
39
+ { from: 'Mimir', module: 'mimirsbrunn', kind: 'rune', message: 'cache-hit ratio rising' },
40
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'cache read served from context' },
41
+ { from: 'Brokk', module: 'mimirsbrunn', kind: 'rune', message: 'well watered after the dispatch' },
42
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'dry well — fired cold, never a blocker' },
43
+ { from: 'Mimir', module: 'mimirsbrunn', kind: 'rune', message: 'spreading recall walked the entity graph' },
44
+ ],
45
+ runes: [
46
+ { from: 'Brokk', module: 'runes', kind: 'rune', message: 'checksum chain extended' },
47
+ { from: 'Muninn', module: 'runes', kind: 'rune', message: 'ledger line appended, never rewritten' },
48
+ { from: 'Brokk', module: 'runes', kind: 'rune', message: 'audit entry sealed' },
49
+ { from: 'Nornir', module: 'runes', kind: 'rune', message: 'daily brief carved to memory' },
50
+ { from: 'Muninn', module: 'runes', kind: 'rune', message: 'chain verified end to end' },
51
+ { from: 'Brokk', module: 'runes', kind: 'rune', message: 'rune export rendered' },
52
+ ],
53
+ reviews: [
54
+ { from: 'Forseti', module: 'glitnir', kind: 'rune', message: 'PR diff opened for judgment' },
55
+ { from: 'Forseti', module: 'glitnir', kind: 'rune', message: 'changes requested — blocking item noted' },
56
+ { from: 'Mjollnir', module: 'glitnir', kind: 'rune', message: 'PR opened from issue' },
57
+ { from: 'Brokk', module: 'glitnir', kind: 'rune', message: 'human approval required — never force-merge' },
58
+ { from: 'Forseti', module: 'glitnir', kind: 'rune', message: 'seal granted after review' },
59
+ ],
60
+ processes: [
61
+ { from: 'Valhalla', module: 'processes', kind: 'rune', message: 'daemon heartbeat nominal' },
62
+ { from: 'Valhalla', module: 'processes', kind: 'rune', message: 'dead process detected — bring-back scheduled' },
63
+ { from: 'Valhalla', module: 'processes', kind: 'rune', message: 'systemd unit restarted and counted' },
64
+ { from: 'Valhalla', module: 'processes', kind: 'rune', message: 'docker container healthy' },
65
+ { from: 'Valhalla', module: 'processes', kind: 'rune', message: 'pm2 watch restored' },
66
+ { from: 'Valhalla', module: 'processes', kind: 'rune', message: 'restart budget within cap' },
67
+ ],
68
+ files: [
69
+ { from: 'Skrymir', module: 'files', kind: 'rune', message: 'realm tree indexed' },
70
+ { from: 'Skrymir', module: 'files', kind: 'rune', message: 'file checksum verified' },
71
+ { from: 'Brokk', module: 'files', kind: 'rune', message: 'artifact written to workspace' },
72
+ { from: 'Skrymir', module: 'files', kind: 'rune', message: 'realm boundary respected — no cross-tenant read' },
73
+ { from: 'Brokk', module: 'files', kind: 'rune', message: 'upload staged for review' },
74
+ ],
75
+ chat: [
76
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'drinks from the well before every dispatch' },
77
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'recall hybrid — the Allfather’s question grounded' },
78
+ { from: 'Kaia', module: 'chat', kind: 'ratatoskr', message: 'dispatch planned — Eindri chosen for the craft' },
79
+ { from: 'Kaia', module: 'chat', kind: 'rune', message: 'reply spoken from the well, never dry' },
80
+ { from: 'Brokk', module: 'chat', kind: 'rune', message: 'thread kept to the last 40 messages' },
81
+ { from: 'Kaia', module: 'chat', kind: 'rune', message: 'answered from the local llama.cpp router' },
82
+ { from: 'Kaia', module: 'chat', kind: 'rune', message: 'watered the well with what this turn taught' },
83
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'spreading recall walked the entity graph' },
84
+ { from: 'Kaia', module: 'chat', kind: 'ratatoskr', message: 'addressing the Allfather — never zero direct address' },
85
+ { from: 'Kaia', module: 'chat', kind: 'rune', message: 'conversation stored under state/chat/ for recall' },
86
+ { from: 'Kaia', module: 'chat', kind: 'rune', message: 'faithful counsel — an outcome, not preamble' },
87
+ { from: 'Kaia', module: 'mimirsbrunn', kind: 'rune', message: 'cache read served from prior context' },
88
+ { from: 'Mimir', module: 'mimirsbrunn', kind: 'rune', message: 'the well is warm — drink before you act' },
89
+ { from: 'Kaia', module: 'chat', kind: 'ratatoskr', message: 'sub-agent briefed and tracked to its lane' },
90
+ ],
91
+ forge: [
92
+ { from: 'Gungnir', module: 'gungnir', kind: 'rune', message: 'skill synthesized and awaiting Utgard validation' },
93
+ { from: 'Brokk', module: 'gungnir', kind: 'rune', message: 'agent forged — mythic name matched to craft' },
94
+ { from: 'Gungnir', module: 'gungnir', kind: 'rune', message: 'prompt anvil struck — user.md re-set' },
95
+ { from: 'Völundr', module: 'smidja', kind: 'rune', message: 'roster validated before spawn' },
96
+ { from: 'Gungnir', module: 'gungnir', kind: 'rune', message: 'skill registered in the index' },
97
+ ],
98
+ runtime: [
99
+ { from: 'Sága', module: 'runtime', kind: 'rune', message: 'session digest recited' },
100
+ { from: 'Gleipnir', module: 'runtime', kind: 'rune', message: 'session lock bound to the live pid' },
101
+ { from: 'Bifrost', module: 'runtime', kind: 'rune', message: 'model bridge raised' },
102
+ { from: 'Sága', module: 'runtime', kind: 'rune', message: 'wake queue drained' },
103
+ { from: 'Sýn', module: 'runtime', kind: 'rune', message: 'watch armed for the turn end' },
104
+ ],
105
+ cron: [
106
+ { from: 'Nornir', module: 'nornir', kind: 'rune', message: 'daily briefing job completed' },
107
+ { from: 'Nornir', module: 'nornir', kind: 'rune', message: 'observer job ran Huginn across the fleet' },
108
+ { from: 'Nornir', module: 'nornir', kind: 'rune', message: 'memory housekeeping swept the well' },
109
+ { from: 'Nornir', module: 'nornir', kind: 'rune', message: 'git sync advanced the world tree' },
110
+ { from: 'Nornir', module: 'nornir', kind: 'rune', message: 'schedule ticked — 4 jobs healthy' },
111
+ ],
112
+ sessions: [
113
+ { from: 'Völundr', module: 'smidja', kind: 'rune', message: 'run opened — phases planned' },
114
+ { from: 'Smiðja', module: 'smidja', kind: 'rune', message: 'builder phase committed its work' },
115
+ { from: 'Smiðja', module: 'smidja', kind: 'rune', message: 'quality gate passed — tests green' },
116
+ { from: 'Smiðja', module: 'smidja', kind: 'rune', message: 'reviewer confirmed the ask' },
117
+ { from: 'Smiðja', module: 'smidja', kind: 'rune', message: 'token and cost tallied into the run' },
118
+ ],
119
+ trace: [
120
+ { from: 'Sýn', module: 'smidja', kind: 'rune', message: 'lane opened for a sub-agent dispatch' },
121
+ { from: 'Sýn', module: 'smidja', kind: 'rune', message: 'span nested under the dispatcher' },
122
+ { from: 'Sýn', module: 'smidja', kind: 'rune', message: 'tool call observed and timed' },
123
+ { from: 'Sýn', module: 'smidja', kind: 'rune', message: 'context occupancy measured' },
124
+ { from: 'Sýn', module: 'smidja', kind: 'rune', message: 'lane closed at acceptance' },
125
+ ],
126
+ decisions: [
127
+ { from: 'Forseti', module: 'smidja', kind: 'rune', message: 'failure clustered by phase and model' },
128
+ { from: 'Brokk', module: 'smidja', kind: 'rune', message: 'fix surfaced — strongest model advised' },
129
+ { from: 'Forseti', module: 'smidja', kind: 'rune', message: 'JSON contract violation recorded' },
130
+ { from: 'Brokk', module: 'smidja', kind: 'rune', message: 'repeated failure grouped — one fix, many runs' },
131
+ { from: 'Forseti', module: 'smidja', kind: 'rune', message: 'no blocking failures — the forge holds' },
132
+ ],
133
+ stats: [
134
+ { from: 'Brokk', module: 'smidja', kind: 'rune', message: 'run tallied — tokens and cost reconciled' },
135
+ { from: 'Mimir', module: 'smidja', kind: 'rune', message: 'cache-hit ratio recomputed' },
136
+ { from: 'Brokk', module: 'smidja', kind: 'rune', message: 'local vs online provider split updated' },
137
+ { from: 'Mimir', module: 'smidja', kind: 'rune', message: 'commercial comparison priced against vendors' },
138
+ { from: 'Brokk', module: 'smidja', kind: 'rune', message: 'by-chain rollup refreshed' },
139
+ ],
140
+ profile: [
141
+ { from: 'Snotra', module: 'profile', kind: 'rune', message: 'tenant colour override applied' },
142
+ { from: 'Snotra', module: 'profile', kind: 'rune', message: 'company house recorded' },
143
+ { from: 'Snotra', module: 'profile', kind: 'rune', message: 'personal settings saved to the realm' },
144
+ { from: 'Snotra', module: 'profile', kind: 'rune', message: 'realm default restored on reset' },
145
+ ],
146
+ };
147
+
148
+ let counter = 0;
149
+
150
+ /** One page-appropriate event for the given gate. */
151
+ export function feedEvent(gate: GateId | string): StreamEvent {
152
+ const pool = FEED[gate] ?? FEED.fleet;
153
+ const line = pool[Math.floor(Math.random() * pool.length)];
154
+ counter += 1;
155
+ return {
156
+ id: `feed-${Date.now()}-${counter}`,
157
+ ts: new Date().toISOString(),
158
+ kind: line.kind,
159
+ from: line.from,
160
+ to: line.kind === 'ratatoskr' ? 'Kaia' : undefined,
161
+ state: line.kind === 'ratatoskr' ? 'WORKING' : undefined,
162
+ module: line.module,
163
+ message: line.message,
164
+ checksum: Math.random().toString(16).slice(2, 8),
165
+ gate: gate as GateId,
166
+ };
167
+ }
168
+
169
+ /** Fill a page's feed with a handful of domain messages so it is never cold. */
170
+ export function seedGateFeed(gate: GateId | string, n = 12): StreamEvent[] {
171
+ return Array.from({ length: n }, () => feedEvent(gate)).map((e, i) => ({
172
+ ...e,
173
+ ts: new Date(Date.now() - (n - i) * 2400).toISOString(),
174
+ }));
175
+ }
@@ -0,0 +1,408 @@
1
+ import type {
2
+ AgentCard,
3
+ ChatMessage,
4
+ FileNode,
5
+ ProcessInfo,
6
+ PullRequest,
7
+ RecallEpisode,
8
+ RealmId,
9
+ RuneEntry,
10
+ SkillDef,
11
+ StreamEvent,
12
+ Task,
13
+ } from '../types';
14
+
15
+ const now = Date.now();
16
+ const iso = (offsetMs: number) => new Date(now - offsetMs).toISOString();
17
+ const min = 60_000;
18
+
19
+ export function seedAgents(realm: RealmId): AgentCard[] {
20
+ const base: AgentCard[] = [
21
+ {
22
+ id: 'brokk',
23
+ name: 'Brokk',
24
+ role: 'Primary — the bellows',
25
+ realm: 'way-of',
26
+ house: 'ymirlabs',
27
+ status: 'nominal',
28
+ capabilities: ['orchestration', 'code', 'marketing', 'strategy', 'life'],
29
+ skills: ['brokk-craft', 'galdr', 'a2a-bridge', 'workspace_rag'],
30
+ interface: { protocol: 'A2A 1.0', endpoint: 'local://brokk', signed: true },
31
+ model: 'hermes-3-8b',
32
+ uptime: 41 * 60 * min,
33
+ tasksDone: 128,
34
+ traceability: 0.984,
35
+ },
36
+ {
37
+ id: 'kaia',
38
+ name: 'Kaia',
39
+ role: 'Orchestrator — the eye by the well',
40
+ realm: 'way-of',
41
+ house: 'muninn',
42
+ status: 'nominal',
43
+ capabilities: ['recall', 'dispatch', 'veil', 'memory'],
44
+ skills: ['a2a-bridge', 'tyr-check', 'workspace_rag'],
45
+ interface: { protocol: 'A2A 1.0', endpoint: 'local://kaia', signed: true },
46
+ model: 'hermes-3-8b',
47
+ uptime: 41 * 60 * min,
48
+ tasksDone: 96,
49
+ traceability: 0.981,
50
+ },
51
+ {
52
+ id: 'eindri-01',
53
+ name: 'Eindri-01',
54
+ role: 'Smith — frontend',
55
+ realm: 'way-of',
56
+ house: 'brokkforge',
57
+ status: 'nominal',
58
+ capabilities: ['react', 'vite', 'design-system', 'a11y'],
59
+ skills: ['galdr-crafter', 'galdr-compliance'],
60
+ interface: { protocol: 'A2A 1.0', endpoint: 'utgard://eindri-01', signed: true },
61
+ model: 'hermes-3-8b',
62
+ uptime: 22 * min,
63
+ tasksDone: 7,
64
+ traceability: 0.972,
65
+ },
66
+ {
67
+ id: 'eindri-02',
68
+ name: 'Eindri-02',
69
+ role: 'Smith — backend',
70
+ realm: 'way-of',
71
+ house: 'runestone',
72
+ status: 'degraded',
73
+ capabilities: ['fastify', 'zod', 'sqlite', 'a2a'],
74
+ skills: ['tyr-check'],
75
+ interface: { protocol: 'A2A 1.0', endpoint: 'utgard://eindri-02', signed: true },
76
+ model: 'hermes-3-8b',
77
+ uptime: 18 * min,
78
+ tasksDone: 5,
79
+ traceability: 0.964,
80
+ },
81
+ {
82
+ id: 'eindri-03',
83
+ name: 'Eindri-03',
84
+ role: 'Smith — memory',
85
+ realm: 'way-of',
86
+ house: 'muninn',
87
+ status: 'nominal',
88
+ capabilities: ['engram', 'embeddings', 'rag', 'fts5'],
89
+ skills: ['workspace_rag'],
90
+ interface: { protocol: 'A2A 1.0', endpoint: 'utgard://eindri-03', signed: true },
91
+ model: 'hermes-3-8b',
92
+ uptime: 9 * min,
93
+ tasksDone: 3,
94
+ traceability: 0.978,
95
+ },
96
+ {
97
+ id: 'eindri-04',
98
+ name: 'Eindri-04',
99
+ role: 'Smith — isolation',
100
+ realm: 'way-of',
101
+ house: 'utgard',
102
+ status: 'down',
103
+ capabilities: ['docker', 'cgroups', 'yggdrasil', 'seccomp'],
104
+ skills: ['a2a-bridge'],
105
+ interface: { protocol: 'A2A 1.0', endpoint: 'utgard://eindri-04', signed: false },
106
+ model: 'hermes-3-8b',
107
+ uptime: 0,
108
+ tasksDone: 11,
109
+ traceability: 0.941,
110
+ },
111
+ ];
112
+
113
+ // Re-scope the platform Eindri to the active realm, and swap the primary house.
114
+ return base.map((a) =>
115
+ a.id === 'brokk' || a.id === 'kaia'
116
+ ? { ...a, realm, house: realm === 'zerwiz' ? 'muninn' : realm === 'craig' ? 'brokkforge' : a.house }
117
+ : { ...a, realm },
118
+ );
119
+ }
120
+
121
+ export function seedTasks(realm: RealmId): Task[] {
122
+ const t: Task[] = [
123
+ {
124
+ id: 'tsk-7f1a',
125
+ title: 'Port the reference shell — rail, topbar, stream',
126
+ state: 'WORKING',
127
+ realm,
128
+ agent: 'Eindri-01',
129
+ agentId: 'eindri-01',
130
+ order: 'W0026',
131
+ progress: 62,
132
+ startedAt: iso(34 * min),
133
+ updatedAt: iso(40_000),
134
+ artifacts: ['src/app/Shell.tsx', 'src/styles/shell.css'],
135
+ log: [
136
+ 'claimed task from Redis queue ratatoskr:inbox:eindri-01',
137
+ 'yggdrasil worktree .yggdrasil/eindri-01 created (branch agent/eindri-01/shell)',
138
+ 'ported .shell grid 236px | 1fr · rows 56px · 1fr · 192px',
139
+ 'wired data-realm tint binding',
140
+ ],
141
+ },
142
+ {
143
+ id: 'tsk-3c9d',
144
+ title: 'Heimdall GitHub OAuth — code flow + JWT session',
145
+ state: 'INPUT_REQUIRED',
146
+ realm,
147
+ agent: 'Eindri-02',
148
+ agentId: 'eindri-02',
149
+ order: 'W0028',
150
+ progress: 41,
151
+ startedAt: iso(2 * 60 * min),
152
+ updatedAt: iso(6 * min),
153
+ artifacts: ['services/heimdall/oauth.ts'],
154
+ log: [
155
+ 'GitHub App client id resolved from .env.local',
156
+ 'awaiting: callback URL from the Allfather',
157
+ 'well recall: 3 prior auth episodes found (hybrid, 0.81)',
158
+ ],
159
+ },
160
+ {
161
+ id: 'tsk-91b0',
162
+ title: 'Workspace provisioner — idempotent first-login bootstrap',
163
+ state: 'SUBMITTED',
164
+ realm,
165
+ agent: 'Kaia',
166
+ agentId: 'kaia',
167
+ order: 'W0029',
168
+ progress: 0,
169
+ startedAt: iso(3 * min),
170
+ updatedAt: iso(3 * min),
171
+ artifacts: [],
172
+ log: ['submitted by Kaia', 'veil verdict: grounded (0.88) — dispatch approved'],
173
+ },
174
+ {
175
+ id: 'tsk-2ae4',
176
+ title: 'engram recall loop — hybrid + cosine modes',
177
+ state: 'COMPLETED',
178
+ realm,
179
+ agent: 'Eindri-03',
180
+ agentId: 'eindri-03',
181
+ order: 'W0004',
182
+ progress: 100,
183
+ startedAt: iso(3 * 60 * min),
184
+ updatedAt: iso(48 * min),
185
+ artifacts: ['skills/workspace_rag.ts', 'memory/engram.jsonl'],
186
+ log: ['observe + recall wired to 127.0.0.1:4602', 'drinking before dispatch — dry well fires cold'],
187
+ },
188
+ {
189
+ id: 'tsk-6d12',
190
+ title: 'Utgard sandbox — network-none enforcement',
191
+ state: 'FAILED',
192
+ realm,
193
+ agent: 'Eindri-04',
194
+ agentId: 'eindri-04',
195
+ order: 'W0002',
196
+ progress: 73,
197
+ startedAt: iso(5 * 60 * min),
198
+ updatedAt: iso(22 * min),
199
+ artifacts: [],
200
+ log: [
201
+ 'docker run --network none --cap-drop ALL',
202
+ 'FAILED: cgroup v2 write denied (no root)',
203
+ 'no trace on main — sandbox destroyed',
204
+ ],
205
+ },
206
+ {
207
+ id: 'tsk-88f5',
208
+ title: 'Runes ledger — append-strict JSONL carver',
209
+ state: 'WORKING',
210
+ realm,
211
+ agent: 'Kaia',
212
+ agentId: 'kaia',
213
+ order: 'W0005',
214
+ progress: 88,
215
+ startedAt: iso(70 * min),
216
+ updatedAt: iso(90_000),
217
+ artifacts: ['memory/runes_audit.md'],
218
+ log: ['checksum chain verified', 'a rune stays carved'],
219
+ },
220
+ {
221
+ id: 'tsk-04ce',
222
+ title: 'Skrymir Vue sub-app mount in Files gate',
223
+ state: 'SUBMITTED',
224
+ realm,
225
+ agent: 'Eindri-01',
226
+ agentId: 'eindri-01',
227
+ order: 'W0032',
228
+ progress: 0,
229
+ startedAt: iso(12 * min),
230
+ updatedAt: iso(12 * min),
231
+ artifacts: [],
232
+ log: ['queued behind tsk-7f1a'],
233
+ },
234
+ {
235
+ id: 'tsk-b731',
236
+ title: 'A2A Agent Card JWS signing via Heimdall',
237
+ state: 'WORKING',
238
+ realm,
239
+ agent: 'Eindri-02',
240
+ agentId: 'eindri-02',
241
+ order: 'W0008',
242
+ progress: 35,
243
+ startedAt: iso(26 * min),
244
+ updatedAt: iso(2 * min),
245
+ artifacts: [],
246
+ log: ['/.well-known/agent-card.json published', 'signing key rotated', 'tampered cards rejected'],
247
+ },
248
+ ];
249
+ return t.map((x) => ({ ...x, realm }));
250
+ }
251
+
252
+ export function seedRunes(realm: RealmId): RuneEntry[] {
253
+ const rows: Omit<RuneEntry, 'realm'>[] = [
254
+ { id: 'run-001', ts: iso(20_000), agent: 'Eindri-01', module: 'hlidskjalf', event: 'shell.grid.ported', checksum: 'a91f3c', order: 'W0026', level: 'ok' },
255
+ { id: 'run-002', ts: iso(45_000), agent: 'Kaia', module: 'mimirsbrunn', event: 'recall.hybrid 3 hits', checksum: '7c0d22', order: 'W0004', level: 'info' },
256
+ { id: 'run-003', ts: iso(70_000), agent: 'Eindri-02', module: 'ratatoskr', event: 'card.published eindri-02', checksum: 'b4e881', order: 'W0008', level: 'ok' },
257
+ { id: 'run-004', ts: iso(120_000), agent: 'Eindri-04', module: 'utgard', event: 'cgroup.denied', checksum: 'ff19aa', order: 'W0002', level: 'danger' },
258
+ { id: 'run-005', ts: iso(160_000), agent: 'Brokk', module: 'yggdrasil', event: 'worktree.merge agent/eindri-03', checksum: '2019d7', order: 'W0001', level: 'ok' },
259
+ { id: 'run-006', ts: iso(200_000), agent: 'Kaia', module: 'runes', event: 'ledger.append strict', checksum: '6ea4b0', order: 'W0005', level: 'info' },
260
+ { id: 'run-007', ts: iso(260_000), agent: 'Eindri-02', module: 'heimdall', event: 'jwt.session issued', checksum: '93bf55', order: 'W0028', level: 'info' },
261
+ { id: 'run-008', ts: iso(320_000), agent: 'Brokk', module: 'valhalla', event: 'pm2 reload ymir-gate', checksum: 'd07c13', order: 'W0019', level: 'warn' },
262
+ { id: 'run-009', ts: iso(400_000), agent: 'Eindri-03', module: 'mimirsbrunn', event: 'observe episode 128', checksum: '1ab9ef', order: 'W0004', level: 'ok' },
263
+ { id: 'run-010', ts: iso(520_000), agent: 'Kaia', module: 'veil', event: 'verdict grounded 0.88', checksum: '5dd201', order: 'W0006', level: 'ok' },
264
+ { id: 'run-011', ts: iso(640_000), agent: 'Eindri-01', module: 'gungnir', event: 'skill forged tyr-check', checksum: 'e3c790', order: 'W0007', level: 'ok' },
265
+ { id: 'run-012', ts: iso(760_000), agent: 'Brokk', module: 'bifrost', event: 'route /files → skrymir', checksum: '88aa12', order: 'W0017', level: 'info' },
266
+ ];
267
+ return rows.map((r) => ({ ...r, realm }));
268
+ }
269
+
270
+ export function seedStream(realm: RealmId): StreamEvent[] {
271
+ const s: Omit<StreamEvent, 'realm' | 'id'>[] = [
272
+ { ts: iso(8_000), kind: 'ratatoskr', from: 'Eindri-01', to: 'Kaia', taskId: 'tsk-7f1a', state: 'WORKING', message: 'shell grid ported — 236px rail, 56px topbar', checksum: 'a91f3c' },
273
+ { ts: iso(12_000), kind: 'rune', from: 'Eindri-01', module: 'hlidskjalf', message: 'shell.grid.ported', checksum: 'a91f3c' },
274
+ { ts: iso(30_000), kind: 'ratatoskr', from: 'Eindri-02', to: 'Brokk', taskId: 'tsk-b731', state: 'WORKING', message: 'agent-card.json published, JWS signed', checksum: 'b4e881' },
275
+ { ts: iso(55_000), kind: 'ratatoskr', from: 'Kaia', to: 'Eindri-03', taskId: 'tsk-2ae4', state: 'COMPLETED', message: 'recall loop complete — 3 episodes', checksum: '7c0d22' },
276
+ { ts: iso(90_000), kind: 'rune', from: 'Eindri-04', module: 'utgard', message: 'cgroup.denied', checksum: 'ff19aa' },
277
+ { ts: iso(140_000), kind: 'ratatoskr', from: 'Kaia', to: 'Brokk', taskId: 'tsk-91b0', state: 'SUBMITTED', message: 'dispatch approved — veil 0.88', checksum: '1c9f44' },
278
+ { ts: iso(210_000), kind: 'rune', from: 'Brokk', module: 'valhalla', message: 'pm2 reload ymir-gate', checksum: 'd07c13' },
279
+ { ts: iso(300_000), kind: 'ratatoskr', from: 'Eindri-04', to: 'Kaia', taskId: 'tsk-6d12', state: 'FAILED', message: 'cgroup write denied — sandbox destroyed', checksum: 'ff19aa' },
280
+ ];
281
+ return s.map((x, i) => ({ ...x, id: `evt-${i}`, realm }));
282
+ }
283
+
284
+ export function seedProcesses(realm: RealmId): ProcessInfo[] {
285
+ const p: ProcessInfo[] = [
286
+ { id: 'p1', name: 'ymir-gate', daemon: 'Fastify · API', manager: 'pm2', status: 'nominal', cpu: 3.4, mem: 182, restarts: 0, uptime: 41 * 60, realm: 'platform' },
287
+ { id: 'p2', name: 'heimdall', daemon: 'OAuth · JWS', manager: 'pm2', status: 'nominal', cpu: 1.1, mem: 96, restarts: 0, uptime: 41 * 60, realm: 'platform' },
288
+ { id: 'p3', name: 'mimirsbrunn', daemon: 'engram bridge :4602', manager: 'pm2', status: 'nominal', cpu: 2.2, mem: 240, restarts: 1, uptime: 39 * 60, realm: 'platform' },
289
+ { id: 'p4', name: 'ratatoskr', daemon: 'Redis queue', manager: 'docker', status: 'nominal', cpu: 0.6, mem: 42, restarts: 0, uptime: 41 * 60, realm: 'platform' },
290
+ { id: 'p5', name: 'hermes-runtime', daemon: 'worker controller', manager: 'pm2', status: 'degraded', cpu: 12.8, mem: 512, restarts: 3, uptime: 18 * 60, realm },
291
+ { id: 'p6', name: 'utgard-04', daemon: 'ephemeral sandbox', manager: 'docker', status: 'down', cpu: 0, mem: 0, restarts: 5, uptime: 0, realm },
292
+ { id: 'p7', name: 'bifrost', daemon: 'Traefik ingress', manager: 'docker', status: 'nominal', cpu: 0.9, mem: 64, restarts: 0, uptime: 41 * 60, realm: 'platform' },
293
+ { id: 'p8', name: 'gjallarhorn', daemon: 'cloudflared tunnel', manager: 'systemd', status: 'nominal', cpu: 0.3, mem: 28, restarts: 0, uptime: 41 * 60, realm: 'platform' },
294
+ ];
295
+ return p.map((x) => ({ ...x, realm: x.realm === 'platform' ? 'platform' : realm }));
296
+ }
297
+
298
+ export function seedReviews(realm: RealmId): PullRequest[] {
299
+ const r: PullRequest[] = [
300
+ {
301
+ id: 'pr-42', number: 42, title: 'feat(hlidskjalf): port reference shell + realm tints', repo: 'ymir', author: 'eindri-01',
302
+ realm, state: 'open', additions: 1284, deletions: 96, updatedAt: iso(9 * min), issue: '#28',
303
+ checks: [
304
+ { name: 'lint', state: 'nominal' },
305
+ { name: 'typecheck', state: 'nominal' },
306
+ { name: 'unit', state: 'nominal' },
307
+ { name: 'e2e', state: 'degraded' },
308
+ ],
309
+ checklist: [
310
+ { label: 'Shell grid matches design.md §5.1', done: true },
311
+ { label: 'data-realm tint on switch', done: true },
312
+ { label: 'Bottom stream pausable', done: true },
313
+ { label: 'A11y axe-core ≥ 95', done: false },
314
+ ],
315
+ },
316
+ {
317
+ id: 'pr-39', number: 39, title: 'fix(utgard): cgroup v2 write denied on rootless', repo: 'ymir', author: 'eindri-04',
318
+ realm, state: 'changes', additions: 212, deletions: 40, updatedAt: iso(34 * min), issue: '#31',
319
+ checks: [
320
+ { name: 'lint', state: 'nominal' },
321
+ { name: 'typecheck', state: 'nominal' },
322
+ { name: 'integration', state: 'down' },
323
+ ],
324
+ checklist: [
325
+ { label: 'Reproduce cgroup denial', done: true },
326
+ { label: 'delegate cgroup to rootless driver', done: false },
327
+ { label: 'No trace on main on failure', done: true },
328
+ ],
329
+ },
330
+ {
331
+ id: 'pr-37', number: 37, title: 'feat(mimirsbrunn): hybrid recall + observe loop', repo: 'ymir', author: 'eindri-03',
332
+ realm, state: 'approved', additions: 640, deletions: 12, updatedAt: iso(48 * min),
333
+ checks: [
334
+ { name: 'lint', state: 'nominal' },
335
+ { name: 'typecheck', state: 'nominal' },
336
+ { name: 'unit', state: 'nominal' },
337
+ ],
338
+ checklist: [
339
+ { label: 'Dry well fires cold', done: true },
340
+ { label: 'agent-scoped keys', done: true },
341
+ ],
342
+ },
343
+ ];
344
+ return r.map((x) => ({ ...x, realm }));
345
+ }
346
+
347
+ export function seedRecall(realm: RealmId): RecallEpisode[] {
348
+ const e: RecallEpisode[] = [
349
+ { id: 'ep-1', title: 'Reference shell is the visual contract', body: 'The plan forbids re-drawing the CSS. tokens.css is the single source; port the shell verbatim and bind data-realm at runtime.', score: 0.91, mode: 'hybrid', agentScope: 'agent://way-of/brokk', ts: iso(2 * 60 * min), tags: ['hlidskjalf', 'design-system'] },
350
+ { id: 'ep-2', title: 'Memory is a boost, never a blocker', body: 'A dry well fires cold but must never stop the forge. Recall before dispatch, observe after; never gate work on the well.', score: 0.87, mode: 'hybrid', agentScope: 'agent://way-of/kaia', ts: iso(6 * 60 * min), tags: ['mimirsbrunn', 'doctrine'] },
351
+ { id: 'ep-3', title: 'Terminal A2A states never restart', body: 'COMPLETED/FAILED/REJECTED/CANCELED are terminal. Retry and idempotency are the orchestrator\'s duty, not the worker\'s.', score: 0.78, mode: 'cosine', agentScope: 'agent://way-of/kaia', ts: iso(24 * 60 * min), tags: ['ratatoskr', 'a2a'] },
352
+ { id: 'ep-4', title: 'Failed sandbox never touches main', body: 'Utgard runs network-none with strict caps. On failure the container is destroyed and the worktree is discarded.', score: 0.71, mode: 'spreading', agentScope: 'agent://way-of/eindri-04', ts: iso(5 * 60 * min), tags: ['utgard', 'isolation'] },
353
+ ];
354
+ void realm;
355
+ return e;
356
+ }
357
+
358
+ export function seedFiles(realm: RealmId): FileNode {
359
+ return {
360
+ name: realm,
361
+ type: 'dir',
362
+ path: `/svartalfaheim/${realm}`,
363
+ children: [
364
+ {
365
+ name: 'workspace', type: 'dir', path: `/svartalfaheim/${realm}/workspace`, children: [
366
+ { name: 'company', type: 'dir', path: `/svartalfaheim/${realm}/workspace/company`, children: [
367
+ { name: 'offer.md', type: 'file', path: '/company/offer.md', size: 4210, updated: iso(2 * 60 * min) },
368
+ { name: 'brand.md', type: 'file', path: '/company/brand.md', size: 2880, updated: iso(9 * 60 * min) },
369
+ ] },
370
+ { name: 'development', type: 'dir', path: `/svartalfaheim/${realm}/workspace/development`, children: [
371
+ { name: 'specs', type: 'dir', path: '/development/specs', children: [
372
+ { name: 'hlidskjalf.md', type: 'file', path: '/development/specs/hlidskjalf.md', size: 15420, updated: iso(40_000) },
373
+ ] },
374
+ ] },
375
+ { name: 'memory', type: 'dir', path: `/svartalfaheim/${realm}/workspace/memory`, children: [
376
+ { name: 'daily', type: 'dir', path: '/memory/daily', children: [
377
+ { name: '2026-09-11.md', type: 'file', path: '/memory/daily/2026-09-11.md', size: 3120, updated: iso(3 * 60 * min) },
378
+ ] },
379
+ { name: 'entity_graph', type: 'dir', path: '/memory/entity_graph', children: [] },
380
+ ] },
381
+ { name: 'life', type: 'dir', path: `/svartalfaheim/${realm}/workspace/life`, children: [] },
382
+ { name: 'marketing', type: 'dir', path: `/svartalfaheim/${realm}/workspace/marketing`, children: [] },
383
+ ],
384
+ },
385
+ { name: '.env.realm', type: 'file', path: '/.env.realm', size: 0, updated: iso(60 * 60 * min) },
386
+ { name: 'Brokk.md', type: 'file', path: '/Brokk.md', size: 5120, updated: iso(60 * 60 * min) },
387
+ { name: 'projects', type: 'dir', path: `/svartalfaheim/${realm}/projects`, children: [] },
388
+ ],
389
+ };
390
+ }
391
+
392
+ export function seedSkills(): SkillDef[] {
393
+ return [
394
+ { id: 'skl-galdr', name: 'galdr', aett: 'galdr', description: 'Agent experience incantation standards — TOON output, 10 principles.', capabilities: ['cli', 'toon', 'ergonomics'], validated: true, house: 'ymirlabs', createdAt: iso(48 * 60 * min) },
395
+ { id: 'skl-tyr', name: 'tyr-check', aett: 'galdr', description: 'The judge — validates tools, skills, and docs against Galdr.', capabilities: ['validation', 'compliance'], validated: true, house: 'runestone', createdAt: iso(40 * 60 * min) },
396
+ { id: 'skl-brokk', name: 'brokk-craft', aett: 'galdr', description: 'The forger — generates Galdr-compliant skills in TOON.', capabilities: ['synthesis', 'skills'], validated: true, house: 'brokkforge', createdAt: iso(36 * 60 * min) },
397
+ { id: 'skl-a2a', name: 'a2a-bridge', aett: 'rat', description: 'Canonical collaboration skill — inbox per turn, complete tasks, FYI peers.', capabilities: ['a2a', 'collaboration'], validated: true, house: 'ymirlabs', createdAt: iso(30 * 60 * min) },
398
+ { id: 'skl-rag', name: 'workspace_rag', aett: 'mimir', description: 'Hybrid Markdown + vector recall across the workspace.', capabilities: ['rag', 'memory'], validated: false, house: 'muninn', createdAt: iso(20 * 60 * min) },
399
+ ];
400
+ }
401
+
402
+ export function seedChat(): ChatMessage[] {
403
+ return [
404
+ { id: 'm1', from: 'kaia', body: 'Well is warm. 128 episodes observed. What are we forging?', ts: iso(4 * 60 * min) },
405
+ { id: 'm2', from: 'user', body: 'Build out the Hlidskjalf frontend so I can see it on localhost.', ts: iso(3 * 60 * min) },
406
+ { id: 'm3', from: 'kaia', body: 'Recalled 4 episodes (hybrid, top 0.91). Dispatching Eindri-01 on the shell port under W0026. Veil verdict: grounded.', ts: iso(3 * 60 * min), recalling: true },
407
+ ];
408
+ }