@zerwiz/ymir 0.1.26 → 0.1.28

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 (143) hide show
  1. package/.agents/skills/groa-update/SKILL.md +30 -0
  2. package/CHANGELOG.md +44 -0
  3. package/README.md +47 -8
  4. package/bin/fixes-guard.sh +112 -0
  5. package/bin/fixes.sh +157 -0
  6. package/bin/ymir.js +35 -0
  7. package/docs/fixes/agents/unversioned-2026-09-11-chat-uses-the-root-pi-model-catalog.md +15 -0
  8. package/docs/fixes/agents/unversioned-2026-09-11-shared-well-for-every-harness-no-mock-clickable-memories.md +26 -0
  9. package/docs/fixes/agents/unversioned-2026-09-13-gleipnir-sees-when-an-agent-is-turned-off.md +26 -0
  10. package/docs/fixes/agents/unversioned-2026-09-14-the-eindri-brokk-wake-bridge-they-can-talk-back-now.md +23 -0
  11. package/docs/fixes/agents/unversioned-2026-09-16-a-sandboxed-worker-cannot-think-auto-stops-killing-agent.md +18 -0
  12. package/docs/fixes/agents/unversioned-2026-09-17-agents-md-states-the-one-law-no-private-data-in-the-publ.md +25 -0
  13. package/docs/fixes/agents/unversioned-2026-09-17-every-figure-loads-the-agent-directory-was-never-read.md +25 -0
  14. package/docs/fixes/agents/unversioned-2026-09-17-pi-gets-its-agents-and-a-dead-extension-comes-back.md +26 -0
  15. package/docs/fixes/agents/unversioned-2026-09-17-the-well-as-tools-ymir-s-first-custom-pi-extension.md +20 -0
  16. package/docs/fixes/gate/0.1.28-fixes-guard-replaces-the-changelog-gate.md +7 -0
  17. package/docs/fixes/gate/0.1.28-the-changelog-system-is-replaced-by-fix-notes.md +8 -0
  18. package/docs/fixes/gate/0.1.28-the-frozen-changelog-becomes-per-component-notes.md +9 -0
  19. package/docs/fixes/hlidskjalf/unversioned-2026-09-11-automate-the-install-consent-gate-self-healing-prereqs-v.md +21 -0
  20. package/docs/fixes/hlidskjalf/unversioned-2026-09-11-single-tenant-workspaces-shipped.md +15 -0
  21. package/docs/fixes/hlidskjalf/unversioned-2026-09-13-the-cloth-reaches-all-three-halls-hlidskjalf-sm-ja-the-s.md +25 -0
  22. package/docs/fixes/hlidskjalf/unversioned-2026-09-16-one-login-for-every-app-on-the-web-the-gate-fronts-them-.md +24 -0
  23. package/docs/fixes/hlidskjalf/unversioned-2026-09-16-the-credential-reaches-the-gate-and-the-hall-stops-leaki.md +23 -0
  24. package/docs/fixes/hlidskjalf/unversioned-2026-09-16-the-delivery-gates-install-themselves-rename-drift-mende.md +22 -0
  25. package/docs/fixes/hlidskjalf/unversioned-2026-09-16-the-panels-that-crashed-the-gate-that-lied-and-the-well-.md +25 -0
  26. package/docs/fixes/hlidskjalf/unversioned-2026-09-17-0-1-14-the-panels-reach-the-gate-and-the-fourth-window-s.md +9 -0
  27. package/docs/fixes/hlidskjalf/unversioned-2026-09-17-models-providers-and-paths-are-the-user-s-and-the-gate-s.md +26 -0
  28. package/docs/fixes/hlidskjalf/unversioned-2026-09-17-the-northstar-gate-runs-nightly-the-platform-door-it-cau.md +16 -0
  29. package/docs/fixes/hoard/unversioned-2026-09-16-every-app-wears-its-own-rune.md +27 -0
  30. package/docs/fixes/hoard/unversioned-2026-09-16-hodd-lives-outside-the-repo-and-the-installer-makes-it-s.md +24 -0
  31. package/docs/fixes/hoard/unversioned-2026-09-16-the-icons-are-real-runes-now-eight-of-them-were-drawings.md +33 -0
  32. package/docs/fixes/hoard/unversioned-2026-09-17-0-1-26-published-and-the-vault-door-named.md +8 -0
  33. package/docs/fixes/hoard/unversioned-2026-09-17-one-well-in-the-hoard-every-reader-of-kaia-s-memory-reso.md +23 -0
  34. package/docs/fixes/hoard/unversioned-2026-09-17-skrymir-opens-the-hoard-not-the-checkout.md +18 -0
  35. package/docs/fixes/hoard/unversioned-2026-09-17-the-hoard-encrypts-its-secrets-at-rest.md +20 -0
  36. package/docs/fixes/hoard/unversioned-2026-09-17-the-hoard-gets-a-guard-and-rule-04-stops-contradicting-t.md +19 -0
  37. package/docs/fixes/hoard/unversioned-2026-09-17-the-home-s-re-laid-layout-taught-to-the-system.md +17 -0
  38. package/docs/fixes/hoard/unversioned-2026-09-17-the-private-home-gets-the-ward-it-never-had.md +25 -0
  39. package/docs/fixes/hoard/unversioned-2026-09-17-the-schedule-is-the-user-s-cron-leaves-the-tree-lives-in.md +27 -0
  40. package/docs/fixes/install/0.1.28-a-stale-install-can-no-longer-hide.md +8 -0
  41. package/docs/fixes/install/unversioned-2026-09-11-desktop-shell-tunnel-and-temporary-auth.md +14 -0
  42. package/docs/fixes/install/unversioned-2026-09-11-smooth-install-provider-choice-no-forced-key-real-prereq.md +22 -0
  43. package/docs/fixes/install/unversioned-2026-09-16-apodex-joins-the-weave-research-planning-provider.md +27 -0
  44. package/docs/fixes/install/unversioned-2026-09-16-icons-the-operator-can-pin-and-one-pair-of-hands-for-the.md +29 -0
  45. package/docs/fixes/install/unversioned-2026-09-16-the-desktop-never-dials-out-cloudflare-stays-outside-ele.md +25 -0
  46. package/docs/fixes/install/unversioned-2026-09-17-0-1-12-the-icons-reach-the-live-tree-and-a-missing-surfa.md +10 -0
  47. package/docs/fixes/install/unversioned-2026-09-17-0-1-8-the-day-s-work-reaches-npm.md +25 -0
  48. package/docs/fixes/install/unversioned-2026-09-17-a-stale-install-cannot-hide-and-the-one-liner-cannot-be-.md +9 -0
  49. package/docs/fixes/install/unversioned-2026-09-17-both-shapes-a-clone-and-an-npm-install-and-the-patience-.md +26 -0
  50. package/docs/fixes/install/unversioned-2026-09-17-gr-a-knows-the-npm-half-how-to-renew-the-published-packa.md +9 -0
  51. package/docs/fixes/install/unversioned-2026-09-17-npm-only-the-hall-answers-on-its-own-port-and-the-marks-.md +27 -0
  52. package/docs/fixes/install/unversioned-2026-09-17-the-apps-leave-the-monorepo-installation-pulls-them-from.md +23 -0
  53. package/docs/fixes/install/unversioned-2026-09-17-the-doors-the-cloth-and-the-icons-that-were-not-there.md +27 -0
  54. package/docs/fixes/install/unversioned-2026-09-17-the-editor-stops-being-banished-to-its-own-desktop.md +18 -0
  55. package/docs/fixes/install/unversioned-2026-09-17-the-four-surfaces-arrive-by-npm-and-an-old-tree-gives-up.md +24 -0
  56. package/docs/fixes/install/unversioned-2026-09-17-the-house-gains-an-unpublish-door.md +19 -0
  57. package/docs/fixes/install/unversioned-2026-09-17-the-icons-reach-the-live-tree-and-a-missing-surface-is-a.md +26 -0
  58. package/docs/fixes/install/unversioned-2026-09-17-the-install-asks-with-a-plan-and-the-operator-s-things-l.md +24 -0
  59. package/docs/fixes/install/unversioned-2026-09-17-the-installer-actually-installs-the-whole-platform-then-.md +9 -0
  60. package/docs/fixes/install/unversioned-2026-09-17-the-installer-has-a-design-of-its-own.md +9 -0
  61. package/docs/fixes/install/unversioned-2026-09-17-the-npm-door-stands-the-surfaces.md +13 -0
  62. package/docs/fixes/install/unversioned-2026-09-17-the-one-liner-the-readme-promised-and-it-sets-the-path.md +9 -0
  63. package/docs/fixes/install/unversioned-2026-09-17-ymir-command-not-found-is-a-path-fault-and-here-is-the-c.md +8 -0
  64. package/docs/fixes/install/unversioned-2026-09-18-the-readme-leads-with-the-doors-that-work.md +13 -0
  65. package/docs/fixes/odrerir/unversioned-2026-09-14-rerir-forged-eindri-odrerir-pane-w3-p7.md +12 -0
  66. package/docs/fixes/odrerir/unversioned-2026-09-17-the-live-hall-s-board-becomes-true-the-snapshot-lands-on.md +18 -0
  67. package/docs/fixes/runtime/unversioned-2026-09-11-gleipnir-lock-pid-binding-fix.md +17 -0
  68. package/docs/fixes/runtime/unversioned-2026-09-11-hardcoded-per-page-feeds-header-stream.md +19 -0
  69. package/docs/fixes/runtime/unversioned-2026-09-11-per-page-rolling-40-message-feeds.md +13 -0
  70. package/docs/fixes/runtime/unversioned-2026-09-11-smi-ja-views-are-repo-local.md +17 -0
  71. package/docs/fixes/runtime/unversioned-2026-09-11-stats-1-1-kaia-chat-forge-prompts.md +23 -0
  72. package/docs/fixes/runtime/unversioned-2026-09-11-the-well-is-real-mimirsbrunn-engram.md +21 -0
  73. package/docs/fixes/runtime/unversioned-2026-09-12-fleet-preferences.md +11 -0
  74. package/docs/fixes/runtime/unversioned-2026-09-12-house-law-rules-and-the-grein-naming.md +11 -0
  75. package/docs/fixes/runtime/unversioned-2026-09-12-r-preference-moved-out-of-the-tracked-tree.md +10 -0
  76. package/docs/fixes/runtime/unversioned-2026-09-12-the-dashboards-stop-crash-looping-on-the-igpu.md +20 -0
  77. package/docs/fixes/runtime/unversioned-2026-09-12-the-well-actually-installs-it-never-did.md +23 -0
  78. package/docs/fixes/runtime/unversioned-2026-09-12-updater-forged-credential-moved-to-env.md +12 -0
  79. package/docs/fixes/runtime/unversioned-2026-09-14-a-vacant-helm-is-entered-not-punted-watcher-wake-repair.md +24 -0
  80. package/docs/fixes/runtime/unversioned-2026-09-14-the-echo-guard-no-wake-flood-through-gn-s-door.md +18 -0
  81. package/docs/fixes/runtime/unversioned-2026-09-16-app-packaging-prepared-under-the-ymir-scope-amendment-c-.md +23 -0
  82. package/docs/fixes/runtime/unversioned-2026-09-16-four-readers-that-still-pointed-at-the-pre-split-world.md +26 -0
  83. package/docs/fixes/runtime/unversioned-2026-09-16-no-blue-the-forge-language-replaces-the-old-blue.md +26 -0
  84. package/docs/fixes/runtime/unversioned-2026-09-16-omarchy-first-host-aware-windows-and-macos-get-a-door.md +25 -0
  85. package/docs/fixes/runtime/unversioned-2026-09-16-smi-ja-moves-into-the-app-tree.md +17 -0
  86. package/docs/fixes/runtime/unversioned-2026-09-16-the-changelog-guard-no-push-ships-untold.md +19 -0
  87. package/docs/fixes/runtime/unversioned-2026-09-16-the-core-senses-the-real-host-not-omarchy-s-shadow.md +23 -0
  88. package/docs/fixes/runtime/unversioned-2026-09-16-the-hearth-spreads-one-fire-three-more-surfaces.md +25 -0
  89. package/docs/fixes/runtime/unversioned-2026-09-16-the-loader-stops-deleting-merge-never-overwrite.md +27 -0
  90. package/docs/fixes/runtime/unversioned-2026-09-16-the-mesh-reaches-teams-and-anchor-and-show-stops-guessin.md +24 -0
  91. package/docs/fixes/runtime/unversioned-2026-09-17-0-1-10-the-hall-answers-on-its-port-and-the-marks-land.md +15 -0
  92. package/docs/fixes/runtime/unversioned-2026-09-17-0-1-11-four-surfaces-their-marks-and-a-door-that-mends.md +18 -0
  93. package/docs/fixes/runtime/unversioned-2026-09-17-glitnir-stops-hanging-and-one-process-is-one-row.md +15 -0
  94. package/docs/fixes/runtime/unversioned-2026-09-17-main-is-repaired-and-the-report-wears-the-cloth.md +25 -0
  95. package/docs/fixes/runtime/unversioned-2026-09-17-not-again-and-four-surfaces-in-one-raise.md +26 -0
  96. package/docs/fixes/runtime/unversioned-2026-09-17-smoke-test-all-ui-two-checks-that-lied-about-their-own-s.md +20 -0
  97. package/docs/fixes/runtime/unversioned-2026-09-17-the-changelog-stops-conflicting-fragments-folded-by-a-sc.md +25 -0
  98. package/docs/fixes/runtime/unversioned-2026-09-17-the-doors-written-down-where-a-user-will-find-them.md +20 -0
  99. package/docs/fixes/runtime/unversioned-2026-09-17-the-duplicate-extensions-removed-from-the-project-tree.md +17 -0
  100. package/docs/fixes/runtime/unversioned-2026-09-17-the-extensions-deployed-without-their-modules.md +23 -0
  101. package/docs/fixes/runtime/unversioned-2026-09-17-the-feed-follows-brokk-s-thinking-past-the-composer.md +17 -0
  102. package/docs/fixes/runtime/unversioned-2026-09-17-the-fleet-stops-colliding-a-grid-fan-and-each-smith-s-ow.md +21 -0
  103. package/docs/fixes/runtime/unversioned-2026-09-17-the-fork-stands-the-machine.md +12 -0
  104. package/docs/fixes/runtime/unversioned-2026-09-17-the-fragment-convention-is-enforced-where-github-runs-it.md +26 -0
  105. package/docs/fixes/runtime/unversioned-2026-09-17-the-layout-swept-every-reader-taught-the-new-doors.md +24 -0
  106. package/docs/fixes/runtime/unversioned-2026-09-17-the-model-that-raised-itself-and-the-workhorse-that-repl.md +26 -0
  107. package/docs/fixes/runtime/unversioned-2026-09-17-the-package-shipped-the-memory-well-one-version-now-excl.md +26 -0
  108. package/docs/fixes/runtime/unversioned-2026-09-17-the-phantom-optional-pins-cut.md +9 -0
  109. package/docs/fixes/runtime/unversioned-2026-09-17-the-sweep-and-the-door-that-mends-itself.md +26 -0
  110. package/docs/fixes/sessrumnir/unversioned-2026-09-12-the-editor-keeps-its-own-seat.md +16 -0
  111. package/docs/fixes/sessrumnir/unversioned-2026-09-13-sessr-mnir-the-seat-hall.md +28 -0
  112. package/docs/fixes/sessrumnir/unversioned-2026-09-13-the-carved-cloth-reaches-the-seat-hall-sessr-mnir.md +27 -0
  113. package/docs/fixes/sessrumnir/unversioned-2026-09-13-the-new-tree-the-mesh-the-seat-hall.md +25 -0
  114. package/docs/fixes/sessrumnir/unversioned-2026-09-13-the-realm-seat-carved-wayof.md +24 -0
  115. package/docs/fixes/sessrumnir/unversioned-2026-09-16-apodex-seat-verified-the-weave-mended.md +27 -0
  116. package/docs/fixes/sessrumnir/unversioned-2026-09-16-the-visualizer-finds-its-db-and-the-seat-hall-actually-b.md +22 -0
  117. package/docs/fixes/sessrumnir/unversioned-2026-09-17-0-1-13-the-re-voiced-seat-arrives-and-the-packages-are-l.md +8 -0
  118. package/docs/fixes/sessrumnir/unversioned-2026-09-17-sessr-mnir-stops-wearing-pi-s-clothes.md +23 -0
  119. package/docs/fixes/sessrumnir/unversioned-2026-09-17-the-hearth-re-seeds-on-its-container-sessr-mnir-s-chat-f.md +23 -0
  120. package/docs/fixes/sessrumnir/unversioned-2026-09-17-the-packaged-seat-carries-the-watch.md +11 -0
  121. package/docs/fixes/sessrumnir/unversioned-2026-09-17-the-readme-lists-the-packages-and-the-pin-moves-to-the-r.md +16 -0
  122. package/docs/fixes/sessrumnir/unversioned-2026-09-17-the-seat-s-name-and-the-visualizer-s-home.md +12 -0
  123. package/docs/fixes/skills/unversioned-2026-09-11-galdr-tyr-assets-symlink-not-copies.md +11 -0
  124. package/docs/fixes/skills/unversioned-2026-09-11-load-the-owning-asset-before-editing-a-governed-path-5-l.md +21 -0
  125. package/docs/fixes/skills/unversioned-2026-09-11-omarchy-first-host-skills-machine-learning-native-fixes.md +27 -0
  126. package/docs/fixes/skills/unversioned-2026-09-13-the-imported-names-leave-the-halls-norse-naming-purge.md +26 -0
  127. package/docs/fixes/skills/unversioned-2026-09-16-gunnl-joins-the-hall-skillopt-integration.md +17 -0
  128. package/docs/fixes/skills/unversioned-2026-09-16-one-skills-tree-every-harness-the-config-stomp-mended.md +25 -0
  129. package/docs/fixes/skills/unversioned-2026-09-16-the-skill-loading-audit-wrong-skills-unloaded-the-index-.md +26 -0
  130. package/docs/fixes/skills/unversioned-2026-09-17-0-1-9-both-shapes-reach-the-registry.md +17 -0
  131. package/docs/fixes/skills/unversioned-2026-09-17-midgard-holds-public-assets-only-the-company-wiki-is-gon.md +23 -0
  132. package/docs/fixes/skills/unversioned-2026-09-17-the-forge-speaks-each-skill-s-own-text-in-the-index.md +16 -0
  133. package/docs/fixes/skills/unversioned-2026-09-17-the-local-git-round-joins-the-loom-the-stack-s-doors-are.md +19 -0
  134. package/docs/fixes/skills/unversioned-2026-09-17-the-registry-says-where-a-repo-lives-and-what-it-is-for.md +20 -0
  135. package/docs/fixes/smidja/unversioned-2026-09-16-the-pane-bridge-keeps-its-quoting-phase-3-verified.md +22 -0
  136. package/docs/fixes/smidja/unversioned-2026-09-16-the-roster-can-finally-run-an-agent-on-pi.md +23 -0
  137. package/docs/fixes/smidja/unversioned-2026-09-16-the-roster-s-effect-lands-and-the-backend-pin-stops-bein.md +19 -0
  138. package/docs/fixes/smidja/unversioned-2026-09-16-the-validator-stops-calling-a-dead-visualizer-healthy.md +20 -0
  139. package/docs/fixes/smidja/unversioned-2026-09-17-the-fleet-was-a-rack-of-terminals-now-it-is-the-roster.md +18 -0
  140. package/docs/fixes/smidja/unversioned-2026-09-17-the-plan-learns-the-smithy-s-package-name-and-the-instal.md +25 -0
  141. package/docs/fixes/smidja/unversioned-2026-09-17-the-smithy-can-see-the-well.md +20 -0
  142. package/docs/fixes/smidja/unversioned-2026-09-17-the-smithy-s-dependency-names-the-package-npm-will-actua.md +20 -0
  143. package/package.json +1 -1
@@ -0,0 +1,25 @@
1
+ ## agents · unversioned · 2026-09-17 — every figure loads: the agent directory was never read
2
+
3
+ ### Why
4
+ - **The bug, stated plainly.** Twenty agent profiles existed, twenty symlinks
5
+ pointed at them, and every gate was green — yet OpenCode loaded **three**
6
+ agents. The symlinks lived in `.opencode/agent/` (SINGULAR). OpenCode reads
7
+ `.opencode/agents/` (PLURAL). Twenty correct links sat in a directory no loader
8
+ opened, so only `brokk` and `hnoss` — the two declared by hand in
9
+ `opencode.json` — ever appeared.
10
+ - **The directory is fixed and migrated.** `.opencode/agent/` → `.opencode/agents/`
11
+ (20 links, all resolving). `bin/valknut-load.sh` now writes the plural path and
12
+ **migrates a legacy singular dir forward**, so an old home heals instead of
13
+ silently keeping its agents invisible.
14
+ - **The roster now declares what it names.** `bin/agents-config.sh apply` only
15
+ touched an agent already present in `opencode.json` (`if a in ablock`), so a
16
+ figure the roster knew but the config had never seen stayed undeclared. The
17
+ roster is the source of truth; a name in it now reaches the harness config.
18
+ - **A new gate catches the class.** `compliance-check.sh` gains **`roster`**: the
19
+ roster (`config/agents.yaml.example`) and the canonical tree
20
+ (`.agents/agents/*.md`) must name the same figures. A figure in the tree but not
21
+ the roster falls to `default_model` and is never declared; a figure in the
22
+ roster with no profile is a phantom. This is the check that would have caught
23
+
24
+ ### Files
25
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,26 @@
1
+ ## agents · unversioned · 2026-09-17 — Pi gets its agents, and a dead extension comes back
2
+
3
+ ### Why
4
+ - **Pi has no agent loader.** Agent loading in Pi is a *package* (`pi-agents`,
5
+ `pi-agent-mode`, `pi-simple-agents`), never a core feature — and Ymir installs
6
+ none. So `.pi/agents/` held twenty correct profile links that **nothing in Pi
7
+ ever read**. The same failure as OpenCode's singular `.opencode/agent/`,
8
+ arrived at from the other side.
9
+ - **The fix ships in this repo, not a root-pi package.**
10
+ `.pi/shared/extensions/ymir-subagents.ts` discovers the canonical
11
+ `.agents/agents/*.md` tree itself and registers a `subagent` tool. A call runs
12
+ the chosen figure as a nested model call in the current session: the figure's
13
+ markdown body is its system prompt, its frontmatter `model:` picks the model
14
+ where the machine serves it. `subagent({})` and `/subagents` list the roster.
15
+ - **It imports nothing.** `@earendil-works/pi-coding-agent` is not installed as a
16
+ package, so an extension importing its types cannot load at all. This one takes
17
+ `pi` as `any` and declares `parameters` as a plain JSON schema — the pattern
18
+ every working extension in the tree already uses.
19
+ - **A rename that left a reader behind.** `skuld-branch-supervision.ts` imported
20
+ `calmTranscriptClassIsVisible` / `CalmPresentationState` from
21
+ `./lib/ro-visibility.ts`, but that module exports `roTranscriptClassIsVisible` /
22
+ `RoPresentationState`. Pi refuses the **whole extension** at load, so Skuld's
23
+ s
24
+
25
+ ### Files
26
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,20 @@
1
+ ## agents · unversioned · 2026-09-17 — the well as tools: Ymir's first custom pi extension
2
+
3
+ ### Why
4
+ - **Why the extension tree was failing, from the upstream law:** pi auto-discovers
5
+ extensions from BOTH the global home and the project-local tree. The same extension
6
+ in both loads twice and pi refuses the duplicate tool —
7
+ `Tool "gna_watch_arm" conflicts with …`. Ymir's own loader already says the shared
8
+ extensions have **one** home; the tree contradicted it by carrying the extension
9
+ files project-locally as well.
10
+ - **Built: `ymir-well`** — the well, as tools inside every pi session.
11
+ `well_recall(query, k)` reads Kaia's memory before work begins;
12
+ `well_observe(content, tags, actors, salience)` writes the lesson after. Written in
13
+ the house voice, honest about failure (a failed write says the lesson was NOT
14
+ written), and it sends tags as LISTS — a comma-string is stored as an array of
15
+ characters, which is exactly how a recall once returned `['r','u','n']`.
16
+ - Authored in the SHARED source and deployed to the global home — one home, never a
17
+ project copy. That is the pattern every future Ymir extension follows.
18
+
19
+ ### Files
20
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,7 @@
1
+ ## gate · 0.1.28 · 2026-09-18 — fixes-guard replaces the changelog gate
2
+
3
+ ### Why
4
+ changelog-guard passed if a range merely touched CHANGELOG.md, and the hook folded fragments mid-push. The new gate only reads: a push must carry a note under docs/fixes/<component>/. It refused its own first push, which is the proof it has teeth.
5
+
6
+ ### Files
7
+ - `bin/fixes-guard.sh`
@@ -0,0 +1,8 @@
1
+ ## gate · 0.1.28 · 2026-09-18 — the changelog system is replaced by fix notes
2
+
3
+ ### Why
4
+ Both failed us: a monolith fed by fragments, folded at push time, guarded by a check that a stray line satisfied.
5
+
6
+ ### Files
7
+ - `bin/fixes.sh`
8
+ - `CHANGELOG.d/`
@@ -0,0 +1,9 @@
1
+ ## gate · 0.1.28 · 2026-09-18 — the frozen changelog becomes per-component notes
2
+
3
+ ### Why
4
+ 142 entries of history, one file per fix now, in the component each belongs to. The old file stays frozen — Rule 06 — with a line saying so.
5
+
6
+ ### Files
7
+ - `docs/fixes/`
8
+ - `CHANGELOG.md`
9
+ - `bin/fixes-guard.sh`
@@ -0,0 +1,21 @@
1
+ ## hlidskjalf · unversioned · 2026-09-11 — Automate the install: consent gate, self-healing prereqs, visualizer-ready
2
+
3
+ ### Why
4
+ - **Consent gate:** a real install now prints its plan and waits for the operator
5
+ to accept (`[y/N]`). Declining changes nothing (exit 3). `--check` still previews
6
+ without asking; non-interactive callers must pass `--yes`.
7
+ - **New `bin/prereq-ensure.sh`:** self-healing prerequisites in USER SPACE —
8
+ installs `bun` and `uv` via their official installers, `mcp<2>` via pip, and can
9
+ fetch a specific Python (e.g. `3.12`) with uv for packages that need one.
10
+ - **New `bin/smidja-bootstrap.sh`:** creates `smidja/smidja_data/smidja.db` from
11
+ the tracer's own schema and seeds a bootstrap session, so the Smíðja visualizer
12
+ has data from the first install. Fixed: it now bootstraps on a bare call
13
+ instead of printing help, and reports failure honestly when the DB is absent.
14
+ - **`bin/ymir-install.sh`:** new `smidja` step; prerequisites delegated to the
15
+ self-healing helper; `engram` reported as an honest optional `SKIP` with the
16
+ exact next command; docker-group-permission and build-failure distinguished.
17
+ - **Verified:** consent refuse/accept/decline paths; smidja db created and read
18
+ back (8 tables, bootstrap session); compliance 8/8.
19
+
20
+ ### Files
21
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,15 @@
1
+ ## hlidskjalf · unversioned · 2026-09-11 — Single-tenant workspaces shipped
2
+
3
+ ### Why
4
+ - **First setup:** `bin/ymir-install.sh` (8 steps) + `bin/workspace-provision.sh`.
5
+ - **Model:** single tenant; workspaces (personal|work) over domains; houses = brands.
6
+ - **UI:** Login onboarding (name/kind/domains), Topbar workspace chip, AccountMenu/Profile relabelled.
7
+ - **Engines:** treehouse → `yggdrasil.sh pool`; sandcastle → `utgard.sh sandcastle`; no-mistakes → Mjollnir gate.
8
+ - **GitHub:** `bin/project-git.sh` reads `workspace/projects.yaml` `git{}`.
9
+ - **Verified:** build green, compliance 8/8, smoke 8/8, lint 4/4.
10
+
11
+ All significant runtime, policy, and architectural changes for the Ymir platform.
12
+ Entries are appended chronologically; never rewritten.
13
+
14
+ ### Files
15
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,25 @@
1
+ ## hlidskjalf · unversioned · 2026-09-13 — the cloth reaches all three halls (Hlidskjalf · Smíðja · the seat)
2
+
3
+ ### Why
4
+ - **One look, one source.** The carved cloth (the landing page's `:root`) now
5
+ dresses every hall, each through its own thin adapter, and `docs/design.md`
6
+ gained §0 *The cloth* plus the re-cut §4.1/§4.2 tables — the contract, not a
7
+ wish. `midgard/design-system/tokens.css` keeps every `--ymir-*` **name** and
8
+ changes only the values: stone `#0e0c09`/`#151209`/`#1a1610`/`#221d14`, bone
9
+ text `#cfc3a9`/`#9a8f75`/`#6b6250`, bronze `#c9973f` accent with `#7d5f2a` as
10
+ the brass rule, blood `#c2584a` danger, steel `#96a0a8` ok, brass bevel
11
+ `inset 0 0 0 1px rgba(201,151,79,.12)`.
12
+ - **Type.** Cormorant (display), Newsreader (body), IBM Plex Mono (data) — the
13
+ landing's three faces — with Noto Sans Runic appended to every stack so runes
14
+ fall through to the rune family. Hlidskjalf loads them from Google Fonts; the
15
+ visualizer bundles them from `@fontsource` (its `@fontsource/play` is gone).
16
+ - **Hlidskjalf:** 24 old-palette `rgba()` literals and every role hex in the
17
+ stylesheets now read tokens (`color-mix(… var(--ymir-ok) …)`); workspace tints
18
+ are cloth (work bronze, personal steel); the `HallsChooser` cards no longer name
19
+ two tokens that never existed (`--ymir-line`/`--ymir-panel`); the login's GitHub
20
+ button is a bone plate; the realm-tint fallbacks in `global.css` follow.
21
+ - **Smíðja's eye:** the default theme is **fensalir** (the titlebar toggle cycles
22
+ fensalir →
23
+
24
+ ### Files
25
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,24 @@
1
+ ## hlidskjalf · unversioned · 2026-09-16 — one login for every app on the web; the gate fronts them all
2
+
3
+ ### Why
4
+ - **Every app host is gated**, not just Smíðja. The gate now routes by host from
5
+ an `APP_HOSTS` table and fronts each one: unauthenticated visitors get that
6
+ app's own sign-in page, an API path gets 401, and the desktop seat (loopback +
7
+ marker) walks straight in. Verified: `smidjadell…` → *Smíðja — Sign in*,
8
+ `odrerirdell…` → *Óðrerir — Sign in*, API 401, desktop seat 200 (the hall).
9
+ - **Every public hostname points at the gate (:3889)** — never at an app's own
10
+ port. That was a hole straight past the login: `gjallarhorn-expose.sh` had been
11
+ exposing each app on its own port, so the app answered the world directly.
12
+ - **The gate learns the host map at start** (`state/gjallarhorn-hosts.env`,
13
+ written by the expose script and sourced by `scripts/start.sh`), so routing is
14
+ not an accident of whoever launched it last.
15
+ - **No guessed credentials.** The generated tunnel config wrote
16
+ `credentials-file: …/ymir.json`; cloudflared names that file for the tunnel's
17
+ UUID, so it refused to start and the world got 530. The line is gone —
18
+ cloudflared resolves a named tunnel's own credentials.
19
+ - Verified through the tunnel: `https://ymirdell.zerwiz.org/` → 200. The app
20
+ hostnames still answer 530: their DNS routes were made against an earlier
21
+ tunnel and need re-creating (`cloudflared tunnel route dns ymir <host>`).
22
+
23
+ ### Files
24
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,23 @@
1
+ ## hlidskjalf · unversioned · 2026-09-16 — the credential reaches the gate, and the hall stops leaking an IP
2
+
3
+ ### Why
4
+ Setting the operator password had **no effect**. This is the bug that made that
5
+ true, and the runtime state that leaked a private address.
6
+
7
+ - **`scripts/start.sh` never loaded the platform env for the gate.** The gate is
8
+ `bun run apps/hlidskjalf/server/index.ts`, and the server reads
9
+ `process.env.HLIDSKJALF_AUTH` — but the launcher passed only `PORT`, and nothing
10
+ sourced `.env.local`. So a credential written by `bin/ymir-setup-auth.sh`
11
+ (correctly: `0600`, gitignored) never arrived, and because the gate treats an
12
+ empty `GATE_AUTH` as authenticated (`authed: GATE_AUTH ? … : true`) the gate
13
+ stayed **open**. `start.sh` now loads `.env.local` once, before the ports, for
14
+ every service it raises — the gate, Bifrost and Mimir.
15
+ - **`apps/odrerir/.astro/dev.json` was tracked.** Astro rewrites it on every
16
+ start with the live `pid` and the host's own addresses (LAN + tailnet) — a
17
+ private-IP leak into a public tree. It is now untracked and gitignored; the
18
+ generated types beside it stay tracked.
19
+ - `galdr-reread`: `assets/hlidskjalf-ui.md` (the gate must receive the credential)
20
+ and `assets/odrerir-hall.md` (`.astro/dev.json` is runtime state).
21
+
22
+ ### Files
23
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,22 @@
1
+ ## hlidskjalf · unversioned · 2026-09-16 — the delivery gates install themselves; rename drift mended
2
+
3
+ ### Why
4
+ - **Install seam.** `bin/ymir-install.sh` gains step **`gates`** (after
5
+ `loaders`): `bin/secret-guard.sh --install` seats the pre-commit guard and
6
+ `bin/changelog-guard.sh --install` the pre-push (branch + changelog). A fresh
7
+ clone now gets the delivery gate without a manual step — `--check` reports it
8
+ as `gates OK|WARN`, the consent preamble names it, and
9
+ `assets/installation.md` carries the row in the same change.
10
+ - **Drift mended — found by the compliance gate, not by me.** Two symlinks
11
+ still pointed at the retired `galdr-cli` skill, so the last rename was not in
12
+ fact complete: `.agents/agents/galdr.md` (Galdr's agent surface was a **dead
13
+ link**) and `.agents/skills/tyr-check/assets`. Both repointed at
14
+ `galdr-ymirsystem`, which is where the skill and its assets live.
15
+ - **`AGENTS.md` TOON mend.** The `security[4]` block carried a rule wrapped
16
+ across two lines, which the checker counted as a fifth row. Joined to one
17
+ line; the block now declares and holds exactly four.
18
+ - **Compliance.** All ten Galdr gates green: toon · naming · mocks · syntax ·
19
+ json · sync · surfaces · assets · duplicates · governed.
20
+
21
+ ### Files
22
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,25 @@
1
+ ## hlidskjalf · unversioned · 2026-09-16 — the panels that crashed, the gate that lied, and the well that would not open
2
+
3
+ ### Why
4
+ - **Statistics now reports the HARNESSES** (pi + opencode), not the smithy's runs.
5
+ `bin/hlidskjalf-usage.sh` aggregates opencode's SQLite token store and both pi
6
+ stores, and emits the numbers under the names the gate renders (`gate{}`):
7
+ totals, usage, providers local/online with per_model, by_chain, by_model.
8
+ Verified: 21,497 runs (opencode 21,422 · pi 75) · 331.5M tokens ·
9
+ local 239,623 / online 331,289,420 · cache-hit 91.5%.
10
+ - **A failed fetch no longer takes the hall down.** Endpoints answering `{error}`
11
+ were handed to panels as data — Rail read `.filter` on an object, Stats read
12
+ `.totals` on a string, and both crashed. The store now runs every bootstrap
13
+ answer through `ok()`: an error keeps the last good value.
14
+ - **`/api/usage` was answering with a traceback** while the script passed by hand:
15
+ the gate process had been started before the fix and caches a failure for 60s.
16
+ Restarted; the endpoint serves the harness numbers.
17
+ - **The engram MCP (`-32000: Connection closed`) is mended.** Not config, not the
18
+ engram package: `python3.12 -c "import mcp"` failed because the system
19
+ `python3-rpds-py` ships without its compiled `rpds.rpds` module, which
20
+ `jsonschema` (inside `mcp` 1.x) imports. Mended with
21
+ `python3.12 -m pip install --user --break-system-packages --force-reinstall rpds-py`
22
+ (plus `mcp<2` under python3.12). The server now starts and waits on s
23
+
24
+ ### Files
25
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,9 @@
1
+ ## hlidskjalf · unversioned · 2026-09-17 — 0.1.14: the panels reach the gate, and the fourth window ships
2
+
3
+ ### Why
4
+ - **`@zerwiz/hlidskjalf` 0.1.1** — the package now declares its own `name`, `files` and the absence of `private`, and ships **`vite.config.ts`**. Without that config a packaged SPA is served by `vite preview` with **no `/api` proxy**, so every panel answered `index.html` and died on `Unexpected token '<'<`. That was the whole panel fault.
5
+ - **`@zerwiz/odrerir` 0.1.1** — ships its **`electron/`** half, so the fourth hall can have a window; its name is `@zerwiz/odrerir` and it is no longer marked private (npm refuses those, EPRIVATE).
6
+ - Both apps declared what ships **in their own repos**, instead of a manifest rewritten at publish time — which is how the wrong things shipped in the first place.
7
+
8
+ ### Files
9
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,26 @@
1
+ ## hlidskjalf · unversioned · 2026-09-17 — models, providers, and paths are the user's — and the gate says so
2
+
3
+ ### Why
4
+ - **The law, amended (Rule 07).** Two clauses appended, the rule itself untouched:
5
+ - **A. Models and providers live in the hoard, per user, read from YAML.**
6
+ Every operator's differ, so there is **no global model or provider** — a
7
+ shipped default naming a model is a claim about someone else's machine. The
8
+ user's own live in `$YMIR_HOME/hodd/`, read from a YAML file there; the repo
9
+ ships a template.
10
+ - **B. No hardcoded absolute file paths.** No `$HOME<user>/…`, no
11
+ `/Users/<user>/…`, no `C:\Users\…`. A path is relative to a resolved root or
12
+ comes from env/config with one documented default.
13
+ - **The gate, `config`.** `compliance-check.sh` gains a check that fails on a
14
+ model id or provider name used as a **value** in shipped code or a tracked
15
+ config, and on an absolute path naming a user. Comments, `*.example` templates,
16
+ `CHANGELOG*`, and `assets/reference/` are exempt by intent — they document,
17
+ they do not configure. **192 files clean.**
18
+ - **Three real violations found and fixed:**
19
+ - `.agents/config/eindri-dispatch.json` — three dispatch rules named
20
+ `opencode-go/deepseek-v4.1-flash`. Now a template with `<your-model-id>`.
21
+ - `.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml` — the PI boot
22
+ profile named `lmstudio/qwen3.6-35b-a3b`. Now a placeholder.
23
+ - `bin/bootstrap-macos.sh` — `$HOME/Documents/Ymir`. Now resolve
24
+
25
+ ### Files
26
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,16 @@
1
+ ## hlidskjalf · unversioned · 2026-09-17 — the NorthStar gate runs nightly; the platform door it caught is mended
2
+
3
+ ### Why
4
+ - **`bin/nornir-job-nsr-compliance.sh` (02:30)** runs every
5
+ `.compliance/gates/check_*.sh` (danger · env · paths · platform · wiring)
6
+ and carves the verdict — `nsr.compliance` clean, or `nsr.compliance.failed`
7
+ (exit 1) naming the broken gate, so the 07:00 briefing reads it at sunrise.
8
+ - **The gate it caught, mended:** `scripts/electron.sh` used `kill -9`, which
9
+ the platform gate rightly refuses as non-portable. It now uses `kill -KILL`
10
+ (the house idiom already in `scripts/stop.sh`) — the NSR round is 5/5 green.
11
+
12
+ galdr-reread: `.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md` — new
13
+ §3.5 (hall snapshot) and §3.6 (NSR round) rows.
14
+
15
+ ### Files
16
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,27 @@
1
+ ## hoard · unversioned · 2026-09-16 — every app wears its own rune
2
+
3
+ ### Why
4
+ The icon set is runecoded (`midgard/design-system/icons.md`): an Elder Futhark
5
+ rune, stroked at the chisel bevel, tinted by the app's house colour. The apps were
6
+ wearing the generic Ymir mark — or, worse, the old **blue** logo.
7
+
8
+ - **`bin/design-icon.sh`** mints an app's icon from a glyph plus a house tint: a
9
+ stone tile with the rune stroked in bronze. `list` shows the mapping.
10
+ - Minted and wired: **Hlidskjalf** `ehwaz` ᛖ (the seat), **Óðrerir** `valhalla` ᚹ
11
+ (the hall), **Sessrúmnir** `sowilo` ᛊ (the sun), **Smíðja** `ansuz` ᚨ (Odin's
12
+ breath — the forge). Óðrerir already carried a forge-coloured favicon set.
13
+ - **The blue logo is retired**: `public/logo.svg` removed, and Smíðja's *inline*
14
+ copy in `App.vue` — the mark in its own header, still `#0f172a`/`#1e293b` —
15
+ replaced with the ansuz rune in bronze. Rebuilt; no blue in the bundle.
16
+
17
+ ### The hearth stays, and spreads
18
+
19
+ Sessrúmnir's background fire is **`EmberBackground`** — 26 embers rising with a
20
+ gentle sway on a canvas, *"the hearth of the landing page, carried into the
21
+ chat"* — used by its home screen and chat panel. It stays. Next: one shared
22
+ ember (a framework-neutral `midgard/design-system/ember.js` with a
23
+ `prefers-reduced-motion` guard) so Hlidskjalf's shell, the login screen,
24
+ Óðrerir's hall and the Smíðja chrome can warm the same fire.
25
+
26
+ ### Files
27
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,24 @@
1
+ ## hoard · unversioned · 2026-09-16 — Hodd lives outside the repo, and the installer makes it so
2
+
3
+ ### Why
4
+ - **One resolver.** `bin/hoard-lib.sh` (`hoard_root`) is now the single answer to
5
+ *where private data lives*: `$YMIR_HOARD`, else `$YMIR_HOME`, else
6
+ `$HOME/Documents/Ymir` — never the checkout. Rule 07's one documented default,
7
+ in one place.
8
+ - **The inward default is gone.** `bin/mimir-ingest.sh`, `bin/project-git.sh` and
9
+ `bin/workspace-provision.sh` each fell back to `$ROOT/hodd`, so on a machine
10
+ with neither `YMIR_HOARD` nor `YMIR_HOME` exported, memory ingest, the project
11
+ registry and workspace provisioning wrote private data **inside the repo**.
12
+ All three (plus `bin/hodd.sh` and the installer) now resolve through the lib.
13
+ - **The misplaced document is out.** `0003-private-data-separation.md`, which had
14
+ come to rest in the repo at `hodd/docs/plans/`, now lives in the hoard at
15
+ `$YMIR_HOME/docs/plans/`. The repo's `hodd/` holds exactly the guard, the
16
+ README and `AGENTS.example.md` — Rule 04's scaffold set, and nothing else.
17
+ - **Installed, not assumed.** `bin/ymir-install.sh` step `tree` now raises the
18
+ hoard layout *outside* the repo (`bin/hodd.sh init`) and seeds an empty
19
+ `secrets/platform.env` (mode 0600), so `bin/hodd.sh emit secrets/platform.env`
20
+ resolves on a fresh machine instead of failing with "not readable".
21
+ `assets/installation.md` and `assets/memory-well.md` updated in the same change.
22
+
23
+ ### Files
24
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,33 @@
1
+ ## hoard · unversioned · 2026-09-16 — the icons are real runes now (eight of them were drawings)
2
+
3
+ ### Why
4
+ The Allfather looked at the icons and said what no check had: *"the icons must be
5
+ based on real runes."* He was right, and the fault was in the **glyph set**, not
6
+ just in the two icons I had minted.
7
+
8
+ `midgard/design-system/icons.md` claims every glyph is an Elder Futhark rune and
9
+ gives each its unicode. **Eight of the twenty-one files were drawings** — a hall
10
+ (`valhalla`, which Óðrerir was wearing), a horn, a shield, a spear, a well, a
11
+ squirrel, a gate, a world-tree. Replaced with the real runes their own rows
12
+ declare:
13
+
14
+ ```
15
+ gjallarhorn ᚷ Gebo · gungnir ᚦ Thurisaz · heimdall ᚺ Hagall · mimirsbrunn ᛜ Ingwaz
16
+ ratatoskr ᛒ Berkanan · utgard ᚢ Uruz · valhalla ᚹ Wunjo · yggdrasil ᛃ Jera
17
+ ```
18
+
19
+ Gungnir was claiming Gebo, which Gjallarhorn already holds, so it takes
20
+ **Thurisaz** (the thorn — the spear) and `icons.md` is corrected to match.
21
+
22
+ **Five apps, five different runes:** Hlidskjalf `ehwaz`, mobile `raidho` (the
23
+ road), Óðrerir `valhalla`→ now genuinely `ᚹ Wunjo`, Sessrúmnir `sowilo`, Smíðja
24
+ `kaunan` (the torch). The install table drives both mint and install now — it had
25
+ been guessing paths, which is why the Smíðja visualizer had been given
26
+ Hlidskjalf's icon.
27
+
28
+ Also this pass: the visualizer gained its furniture (description, canonical,
29
+ manifest, OG + Twitter), Óðrerir's Electron shell asks for a window icon, and the
30
+ apple-touch PNGs are rasterised (ImageMagick is present).
31
+
32
+ ### Files
33
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,8 @@
1
+ ## hoard · unversioned · 2026-09-17 — 0.1.26: published, and the vault door named
2
+
3
+ ### Why
4
+ - **@zerwiz/ymir@0.1.26 is on the registry** — the latest main, published as `zerwiz`. The token was in the encrypted vault all along; `age` was missing from this machine, and `bin/hodd.sh emit` returns empty, so every reader reported the token absent. The door is the fix, not the key.
5
+ - **The bump clears the registry**: main carried 0.1.18 while the registry served 0.1.25 (other sessions published past main).
6
+
7
+ ### Files
8
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,23 @@
1
+ ## hoard · unversioned · 2026-09-17 — one well, in the hoard: every reader of Kaia's memory resolves the hoard store
2
+
3
+ ### Why
4
+ - **The memory is ONE store and it lives in the hoard** —
5
+ `$YMIR_HOME/hodd/memory/kaia.engram` — never in the tree, never in a
6
+ migrated copy. `bin/hoard-lib.sh` gains `hoard_memory_store` (the one
7
+ resolver); every reader honors it or an explicit `ENGRAM_DB`:
8
+ `mimir-bridge.sh`/`mimir-bridge.py`, `mimir-reflect.sh`, `a2a-mcp.sh`,
9
+ `ymir-install.sh` step_memory, and the rendered `.pi/mcp.json.example`
10
+ (`__YMIR_HOME__/hodd/memory/kaia.engram`).
11
+ - **The duplicate is dead.** The old store (`$YMIR_HOME/memory/kaia.engram`,
12
+ plus the migration seed copy) is struck from this machine and the vault;
13
+ its 8 episodes were seeded into the hoard store first. The public ymir
14
+ repo's `.agents/memory/kaia.engram*` leftovers are deleted (already guarded
15
+ by `.gitignore`) and the 0003 migration now copies INTO the hoard.
16
+ - The Allfather's decision, accepted and recorded everywhere: the well must
17
+ travel between his computers, so it rides the private vault as one store.
18
+
19
+ galdr-reread: `.agents/skills/galdr-ymirsystem/assets/memory-well.md` — the
20
+ Store row, MCP command, law #4, and the Python recipe now name the hoard path.
21
+
22
+ ### Files
23
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,18 @@
1
+ ## hoard · unversioned · 2026-09-17 — Skrymir opens the hoard, not the checkout
2
+
3
+ ### Why
4
+ - **The file browser was rooted in the wrong tree.** `workspaceRoot()` built every
5
+ realm path under `ROOT` — the checkout — so `work` resolved to a directory that does
6
+ not exist and the walk fell back to the repo's `docs/`. That is why Skrymir showed
7
+ `lore.md`, `Architecture.md`, `research/`, `runbooks/`, and why a file it had just
8
+ listed answered **"not found"**: the listing came from one tree and the read from
9
+ another.
10
+ - **The hoard first now (Rule 04):** `$YMIR_HOME/svartalfaheim/<realm>` → company
11
+ container → `$YMIR_HOME/workspace/<realm>` → the checkout only as legacy. An empty
12
+ realm shows the hoard's home, never the repo's docs. Verified: `work` lists
13
+ `memory/daily/2026-09-13.md` and `workspace/`, and a read returns its body.
14
+ - Note for the next hand: the gate runs **without** `--watch` — a server edit is on
15
+ disk and not in the process until `scripts/start.sh` raises it again.
16
+
17
+ ### Files
18
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,20 @@
1
+ ## hoard · unversioned · 2026-09-17 — the hoard encrypts its secrets at rest
2
+
3
+ ### Why
4
+ - **`bin/hodd.sh` decrypts transparently.** `load`, `emit`, and `tenant` now
5
+ accept a plaintext file *or* an `.age` ciphertext with the sibling plaintext
6
+ absent. A shared `resolve_secret` finds the readable form; when it decrypts,
7
+ it uses a mode-600 temp and removes it afterward. An agent asks for the
8
+ resolved path and never handles ciphertext directly.
9
+ - **Secrets stay encrypted at rest.** `hodd/secrets/platform.env.age` is the
10
+ committed form; the plaintext is scratch and gitignored. Round-trip verified
11
+ byte-identical before the plaintext was untracked.
12
+ - **The vault invariant, written down.** The age key and the ciphertext travel
13
+ together in the private `ymirhome` repo, so a dead disk loses nothing — and
14
+ `ymirhome` **must never be made public**. Stated in `hodd/docs/secrets-vault.md`.
15
+ - **The honest limit.** This is encryption-at-rest, not encryption-against-yourself:
16
+ on a single-user machine, a process running as the operator can read what the
17
+ operator can read. What it buys is the *file* and the *repo*, not the *account*.
18
+
19
+ ### Files
20
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,19 @@
1
+ ## hoard · unversioned · 2026-09-17 — the hoard gets a guard, and Rule 04 stops contradicting the disk
2
+
3
+ ### Why
4
+ - **Eir gains a `hoard` surface.** Private data drifting outside the hoard is
5
+ now caught rather than discovered by asking "where did that go?". The check
6
+ fails on two things: a `.ymir-layout.yaml` entry naming a directory that does
7
+ not exist (a stale map is what lets private work land outside the hoard), and
8
+ a flat `$YMIR_HOME/{identity,data,docs,secrets,tenants}` sitting beside
9
+ `hodd/`. `fix` merges a flat duplicate into the hoard without clobbering, then
10
+ repoints any stale layout entry at the hoard.
11
+ - **Rule 04 corrected, append-only.** The rule's mapping table read as if
12
+ `hodd/x/` and `$YMIR_HOME/x/` were two locations; on a real home that produced
13
+ two parallel stores which drifted. The appended correction states the truth:
14
+ `$YMIR_HOME/hodd/` **is** the private data path, `bin/hoard-lib.sh` is the one
15
+ source of truth for it, and `.ymir-layout.yaml` must name only paths that
16
+ exist. Nothing above the correction was rewritten.
17
+
18
+ ### Files
19
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,17 @@
1
+ ## hoard · unversioned · 2026-09-17 — the home's re-laid layout taught to the system
2
+
3
+ ### Why
4
+ - **The layout changed (2026-09-17):** plans filed by domain under
5
+ `$YMIR_HOME/memory/plans/<domain>/`, live plans in `hodd/plans/`,
6
+ workspaces under `hodd/workspaces/`, dropped-from-git material in
7
+ `hodd/state/stale-*`. The hodd example (`hodd/AGENTS.example.md`) now
8
+ teaches the new shape.
9
+ - **AGENTS.md** — the private-home tree block, the outputs table
10
+ (`hodd/workspaces/work/`, `hodd/workspaces/personal/`), and the Ratatoskr
11
+ plan pointer updated to the new homes.
12
+ - **bin/nornir-job-daily-briefing.sh** — the morning brief's masterplan and
13
+ plan-status reads follow the new layout (`hodd/docs/masterplan.md`,
14
+ `memory/plans`) with `BROKK_MASTERPLAN`/`BROKK_PLANS_DIR` overrides.
15
+
16
+ ### Files
17
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,25 @@
1
+ ## hoard · unversioned · 2026-09-17 — the private home gets the ward it never had
2
+
3
+ ### Why
4
+ - **Six guards watched the public repo; the home had none — yet the home is where
5
+ every private byte lives.** The one real leak of this day (`platform.env.prev-fill`,
6
+ 44 credentials) happened *there*, in a scratch backup swept up by `git add -A`,
7
+ with nothing watching. `bin/hoard-guard.sh` closes that.
8
+ - **It is a hook, not a script.** Seated as `$YMIR_HOME/.git/hooks/pre-commit`,
9
+ **git runs it on every commit** — including one made in a hurry, by a loop, or by
10
+ an agent that has never heard of it. Verified by attempting a real `git commit`
11
+ with no guard invoked: git refused, exit 1.
12
+ - **It catches what actually leaked**, verified by planting each: a scratch-backup
13
+ name (`*.prev-*`, `*.bak`, `*.orig`), a plaintext secret filename, a secret shape,
14
+ and — the evasion that would have hidden a key — **a base64 blob whose decode
15
+ contains a PEM header**, under an innocent filename.
16
+ - **`bin/ymir-install.sh` seats it at both repos** (the `hoard-gate` step reports
17
+ the home separately, so a dormant vault is visible), on every install layer.
18
+ - **A bypass is logged, not silent.** `hoard-guard.sh --log-bypass` appends to the
19
+ Runes ledger when a `--no-verify` commit is detected.
20
+ - **Two stale flat paths fixed in the guards themselves.** `bin/docs-guard.sh` told
21
+ an operator to move private docs to `$YMIR_HOME/docs/` — a path that no longer
22
+ exists — and `bin/groa-updat
23
+
24
+ ### Files
25
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,27 @@
1
+ ## hoard · unversioned · 2026-09-17 — the schedule is the user's: cron leaves the tree, lives in the home
2
+
3
+ ### Why
4
+ - **The tracked tree no longer carries the live cron schedule.** The Nornir
5
+ scheduler now resolves the schedule in this order: `BROKK_CONFIG_OVERRIDE`
6
+ (explicit) → **the home's own `$YMIR_HOME/config/cron.yaml`** (users set
7
+ their jobs there) → the repo's `config/cron.yaml.example` (a template, never
8
+ the live list). `bin/nornir-cron-start.sh` resolves the home through
9
+ `bin/hoard-lib.sh`, the one answer the whole runtime shares.
10
+ - `config/cron.yaml` → `config/cron.yaml.example` (the tracked template stays;
11
+ the live schedule lives in the operator's home).
12
+ - **The marketing stack can be provisioned on any computer** —
13
+ `bin/ymir-marketing-stack.sh up|status|down|doors` stands Mautic + Postiz +
14
+ Activepieces (+ optionally Forgejo) from the same OSS engines the server
15
+ runs, env-driven, ports virtualized, secrets generated once into the home
16
+ (never inline); agents (Bragi · Sindri) provision it for any user.
17
+ - **Bragi's scrape round, honest to Firecrawl** — `bin/nornir-job-bragi-scrape.sh`
18
+ reads the operator's `config/scrape-sources.yaml` and scrapes with the real
19
+ Firecrawl SDK (scrape/search + markdown, BYOK key from the home's secrets),
20
+ landing clean markdown in the marketing workspace and carving a Rune.
21
+
22
+ galdr-reread: `.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md` — §2
23
+ rewritten (the schedule is the user's; example template; the four-inputs
24
+ contract
25
+
26
+ ### Files
27
+ - *(carried from the frozen CHANGELOG.md)*
@@ -0,0 +1,8 @@
1
+ ## install · 0.1.28 · 2026-09-18 — a stale install can no longer hide
2
+
3
+ ### Why
4
+ npm install -g reported 'changed 200 packages' while changing nothing: it resolved a cached latest.
5
+
6
+ ### Files
7
+ - `bin/ymir.js`
8
+ - `install.sh`
@@ -0,0 +1,14 @@
1
+ ## install · unversioned · 2026-09-11 — Desktop shell, tunnel, and temporary auth
2
+
3
+ ### Why
4
+ - **Electron:** `apps/hlidskjalf/electron` + `scripts/electron.sh` open Hlidskjalf
5
+ (and Smiðja) as a native window; raises the stack if down.
6
+ - **Tunnel:** `ymirdell.zerwiz.org` → `:3889` via `bin/gjallarhorn-tunnel.sh`
7
+ (cloudflared config in `midgard/infrastructure/ingress/cloudflared-ymir.yml`).
8
+ - **Auth:** hardcoded HTTP Basic (`zerwiz:allfather`, `HLIDSKJALF_AUTH`) on the
9
+ gate API, which now also serves the built SPA. Temporary — move to Heimdall +
10
+ `.env.local`.
11
+ - **Mobile:** PWA manifest added; recommended APK = Capacitor over the tunnel.
12
+
13
+ ### Files
14
+ - *(carried from the frozen CHANGELOG.md)*