@zerwiz/ymir 0.1.4 → 0.1.7
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.
- package/.agents/README.md +291 -0
- package/.agents/agents/bragi-marketer.md +111 -0
- package/.agents/agents/brokk.md +352 -0
- package/.agents/agents/forseti-reviewer.md +93 -0
- package/.agents/agents/frigg-consent.md +77 -0
- package/.agents/agents/groa-update.md +77 -0
- package/.agents/agents/hnoss-designer.md +69 -0
- package/.agents/agents/huginn-researcher.md +99 -0
- package/.agents/agents/jord-projects.md +78 -0
- package/.agents/agents/kvasir-scout.md +91 -0
- package/.agents/agents/mimir-planner.md +92 -0
- package/.agents/agents/muninn-stow.md +77 -0
- package/.agents/agents/saga-bearings.md +78 -0
- package/.agents/agents/sindri-developer.md +114 -0
- package/.agents/agents/snotra-documenter.md +105 -0
- package/.agents/agents/syn-recovery.md +78 -0
- package/.agents/agents/tyr-check.md +78 -0
- package/.agents/agents/urdh-hold.md +77 -0
- package/.agents/agents/volundr-smith.md +80 -0
- package/.agents/agents/vor-diagnostics.md +77 -0
- package/.agents/assets/agents/naming.md +50 -0
- package/.agents/assets/agents/registry.md +93 -0
- package/.agents/assets/agents/runtime.md +36 -0
- package/.agents/assets/agents/toon-tasks-cli.md +42 -0
- package/.agents/assets/templates/company_entity.template.md +37 -0
- package/.agents/backend/README.md +74 -0
- package/.agents/backend/backends/cmux.sh +649 -0
- package/.agents/backend/backends/herdr-eventwait.py +157 -0
- package/.agents/backend/backends/herdr-workspace-move.py +114 -0
- package/.agents/backend/backends/herdr.sh +3386 -0
- package/.agents/backend/backends/orca.sh +290 -0
- package/.agents/backend/backends/tmux.sh +357 -0
- package/.agents/backend/backends/zellij.sh +700 -0
- package/.agents/backend/fm-afk-launch.sh +654 -0
- package/.agents/backend/fm-afk-return.sh +241 -0
- package/.agents/backend/fm-afk-start.sh +172 -0
- package/.agents/backend/fm-arm-command-policy.mjs +960 -0
- package/.agents/backend/fm-arm-pretool-check.sh +200 -0
- package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
- package/.agents/backend/fm-backend.sh +981 -0
- package/.agents/backend/fm-backlog-handoff.sh +909 -0
- package/.agents/backend/fm-backlog-receive.sh +187 -0
- package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
- package/.agents/backend/fm-bearings-board.sh +204 -0
- package/.agents/backend/fm-bearings-snapshot.sh +546 -0
- package/.agents/backend/fm-bootstrap.sh +1568 -0
- package/.agents/backend/fm-branch-outcome.sh +203 -0
- package/.agents/backend/fm-branch-prompt.sh +101 -0
- package/.agents/backend/fm-brief.sh +452 -0
- package/.agents/backend/fm-busy-event.sh +234 -0
- package/.agents/backend/fm-busy-lib.sh +986 -0
- package/.agents/backend/fm-captain-hold.sh +1001 -0
- package/.agents/backend/fm-cd-command-policy.mjs +153 -0
- package/.agents/backend/fm-cd-pretool-check.sh +190 -0
- package/.agents/backend/fm-check-lib.sh +74 -0
- package/.agents/backend/fm-check-register.sh +42 -0
- package/.agents/backend/fm-check-unregister.sh +52 -0
- package/.agents/backend/fm-classify-lib.sh +1770 -0
- package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
- package/.agents/backend/fm-composer-lib.sh +1416 -0
- package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
- package/.agents/backend/fm-config-push.sh +254 -0
- package/.agents/backend/fm-control-lib.sh +251 -0
- package/.agents/backend/fm-control.sh +878 -0
- package/.agents/backend/fm-crew-state.sh +625 -0
- package/.agents/backend/fm-cursor-lib.sh +243 -0
- package/.agents/backend/fm-decision-hold.sh +232 -0
- package/.agents/backend/fm-doc-audience-check.sh +269 -0
- package/.agents/backend/fm-dod-lib.sh +67 -0
- package/.agents/backend/fm-ensure-agents-md.sh +253 -0
- package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
- package/.agents/backend/fm-extension.mjs +2577 -0
- package/.agents/backend/fm-extension.sh +16 -0
- package/.agents/backend/fm-ff-lib.sh +420 -0
- package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
- package/.agents/backend/fm-fleet-sync.sh +458 -0
- package/.agents/backend/fm-fleet-view.sh +96 -0
- package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
- package/.agents/backend/fm-guard.sh +242 -0
- package/.agents/backend/fm-harness.sh +195 -0
- package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
- package/.agents/backend/fm-herdr-lab.sh +346 -0
- package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
- package/.agents/backend/fm-home-seed.sh +984 -0
- package/.agents/backend/fm-home-summary-refresh.sh +255 -0
- package/.agents/backend/fm-hook-host-lib.sh +36 -0
- package/.agents/backend/fm-inactive-reconcile.sh +531 -0
- package/.agents/backend/fm-inbox.sh +399 -0
- package/.agents/backend/fm-install-actionlint.sh +84 -0
- package/.agents/backend/fm-install-herdr.sh +96 -0
- package/.agents/backend/fm-install-shellcheck.sh +84 -0
- package/.agents/backend/fm-install-treehouse.sh +95 -0
- package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
- package/.agents/backend/fm-lease-lib.sh +218 -0
- package/.agents/backend/fm-lease.sh +189 -0
- package/.agents/backend/fm-line-cap-lib.sh +51 -0
- package/.agents/backend/fm-lint-workflows.sh +137 -0
- package/.agents/backend/fm-lint.sh +591 -0
- package/.agents/backend/fm-lock-lib.sh +104 -0
- package/.agents/backend/fm-lock.sh +107 -0
- package/.agents/backend/fm-marker-lib.sh +12 -0
- package/.agents/backend/fm-merge-local.sh +74 -0
- package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
- package/.agents/backend/fm-nm-run-lib.sh +124 -0
- package/.agents/backend/fm-on.sh +125 -0
- package/.agents/backend/fm-operational-input.sh +253 -0
- package/.agents/backend/fm-peek.sh +46 -0
- package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
- package/.agents/backend/fm-pr-check.sh +135 -0
- package/.agents/backend/fm-pr-lib.sh +1016 -0
- package/.agents/backend/fm-pr-merge.sh +707 -0
- package/.agents/backend/fm-pr-poll.sh +110 -0
- package/.agents/backend/fm-primary-scope-lib.sh +33 -0
- package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
- package/.agents/backend/fm-procevent-lavish.sh +628 -0
- package/.agents/backend/fm-procevent-lib.sh +892 -0
- package/.agents/backend/fm-procevent-quota.sh +290 -0
- package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
- package/.agents/backend/fm-procevent-when.sh +504 -0
- package/.agents/backend/fm-procevent.sh +1466 -0
- package/.agents/backend/fm-project-mode.sh +92 -0
- package/.agents/backend/fm-project-origin-lib.sh +180 -0
- package/.agents/backend/fm-promote.sh +282 -0
- package/.agents/backend/fm-public-followup-emit.sh +260 -0
- package/.agents/backend/fm-public-followup-lib.sh +398 -0
- package/.agents/backend/fm-public-followup.sh +1330 -0
- package/.agents/backend/fm-push-transition-lib.sh +168 -0
- package/.agents/backend/fm-quota-axi-lib.sh +93 -0
- package/.agents/backend/fm-quota-choose.sh +384 -0
- package/.agents/backend/fm-remote-delta-read.sh +189 -0
- package/.agents/backend/fm-remote-doctor.sh +800 -0
- package/.agents/backend/fm-remote-entrypoint.sh +193 -0
- package/.agents/backend/fm-remote-file.sh +234 -0
- package/.agents/backend/fm-remote-home-provision.sh +259 -0
- package/.agents/backend/fm-remote-home-seed.sh +259 -0
- package/.agents/backend/fm-remote-inherit-push.sh +90 -0
- package/.agents/backend/fm-remote-inherit.sh +179 -0
- package/.agents/backend/fm-remote-job-lib.sh +1241 -0
- package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
- package/.agents/backend/fm-remote-job-worker.sh +1124 -0
- package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
- package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
- package/.agents/backend/fm-review-diff.sh +158 -0
- package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
- package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
- package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
- package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
- package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
- package/.agents/backend/fm-secondmate-report.sh +88 -0
- package/.agents/backend/fm-send.sh +1059 -0
- package/.agents/backend/fm-session-lock-lib.sh +176 -0
- package/.agents/backend/fm-session-start.sh +970 -0
- package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
- package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
- package/.agents/backend/fm-sessionstart-run.sh +145 -0
- package/.agents/backend/fm-spawn.sh +3153 -0
- package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
- package/.agents/backend/fm-startup-memory-budget.sh +94 -0
- package/.agents/backend/fm-startup-network.sh +642 -0
- package/.agents/backend/fm-stow-cascade.sh +251 -0
- package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
- package/.agents/backend/fm-supervise-daemon.sh +1732 -0
- package/.agents/backend/fm-supervision-instructions.sh +215 -0
- package/.agents/backend/fm-supervision-lib.sh +90 -0
- package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
- package/.agents/backend/fm-tangle-lib.sh +53 -0
- package/.agents/backend/fm-task-inbox-lib.sh +402 -0
- package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
- package/.agents/backend/fm-teardown.sh +2922 -0
- package/.agents/backend/fm-test-isolation-proof.sh +588 -0
- package/.agents/backend/fm-test-run.sh +2191 -0
- package/.agents/backend/fm-timeout-lib.sh +141 -0
- package/.agents/backend/fm-timing-lib.sh +179 -0
- package/.agents/backend/fm-tmux-lib.sh +291 -0
- package/.agents/backend/fm-tool-update-check.sh +898 -0
- package/.agents/backend/fm-trace-context-lib.sh +227 -0
- package/.agents/backend/fm-transition-lib.sh +103 -0
- package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
- package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
- package/.agents/backend/fm-turnend-guard.sh +432 -0
- package/.agents/backend/fm-update.sh +110 -0
- package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
- package/.agents/backend/fm-voice-client.py +1373 -0
- package/.agents/backend/fm-voice-relay.py +1256 -0
- package/.agents/backend/fm-wake-drain.sh +592 -0
- package/.agents/backend/fm-wake-grant.sh +127 -0
- package/.agents/backend/fm-wake-lib.sh +1849 -0
- package/.agents/backend/fm-watch-arm.sh +602 -0
- package/.agents/backend/fm-watch-checkpoint.sh +109 -0
- package/.agents/backend/fm-watch.sh +1962 -0
- package/.agents/backend/fm-x-dismiss.sh +116 -0
- package/.agents/backend/fm-x-followup.sh +286 -0
- package/.agents/backend/fm-x-lib.sh +1000 -0
- package/.agents/backend/fm-x-link.sh +234 -0
- package/.agents/backend/fm-x-poll.sh +185 -0
- package/.agents/backend/fm-x-reply.sh +385 -0
- package/.agents/backend/fm_voice_frame.py +166 -0
- package/.agents/backend/fm_voice_records.py +574 -0
- package/.agents/backend/model-bridge.py +360 -0
- package/.agents/backend/opencode-go-bridge.py +30 -0
- package/.agents/bus/README.md +12 -0
- package/.agents/bus/messages.json +1 -0
- package/.agents/config/agents.machine.example.yaml +16 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +11 -0
- package/.agents/config/eindri-dispatch.json +67 -0
- package/.agents/config/eindri-harness +1 -0
- package/.agents/config/startup-memory-budget +1 -0
- package/.agents/filebrowser/.filebrowser.json +6 -0
- package/.agents/filebrowser/README.md +11 -0
- package/.agents/gateway/README.md +12 -0
- package/.agents/github/README.md +15 -0
- package/.agents/github/webhooks/.gitkeep +0 -0
- package/.agents/github/workflows/.gitkeep +0 -0
- package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
- package/.agents/harness/opencode/plugins/package.json +4 -0
- package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
- package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
- package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
- package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
- package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
- package/.agents/memory/README.md +46 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/migrations/0001-hodd-layout.sh +38 -0
- package/.agents/migrations/0002-a2a-mcp.sh +27 -0
- package/.agents/migrations/0003-private-data-separation.sh +121 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/migrations/0005-roots-out-of-tree.sh +158 -0
- package/.agents/sandbox/Dockerfile.utgard +19 -0
- package/.agents/sandbox/README.md +14 -0
- package/.agents/sandbox/utgard.config.json +14 -0
- package/.agents/skills/README.md +59 -0
- package/.agents/skills/bragi-marketing/README.md +3 -0
- package/.agents/skills/bragi-marketing/SKILL.md +82 -0
- package/.agents/skills/eindri-homes/README.md +3 -0
- package/.agents/skills/eindri-homes/SKILL.md +291 -0
- package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
- package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
- package/.agents/skills/frigg-consent/README.md +3 -0
- package/.agents/skills/frigg-consent/SKILL.md +56 -0
- package/.agents/skills/galdr-ymirsystem/README.md +3 -0
- package/.agents/skills/galdr-ymirsystem/SKILL.md +159 -0
- package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
- package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +736 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
- package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +539 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +763 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
- package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +415 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +133 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +101 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
- package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
- package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
- package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
- package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
- package/.agents/skills/galdr-ymirsystem/assets/smidja.md +180 -0
- package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
- package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
- package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
- package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +503 -0
- package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
- package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
- package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
- package/.agents/skills/gjallarhorn-relay/README.md +3 -0
- package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
- package/.agents/skills/groa-update/SKILL.md +90 -0
- package/.agents/skills/hamr-adapters/README.md +3 -0
- package/.agents/skills/hamr-adapters/SKILL.md +123 -0
- package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
- package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
- package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
- package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
- package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
- package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
- package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
- package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
- package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
- package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
- package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
- package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
- package/.agents/skills/herdr-panes/README.md +3 -0
- package/.agents/skills/herdr-panes/SKILL.md +92 -0
- package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
- package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
- package/.agents/skills/hnoss-design/DESIGN.md +19 -0
- package/.agents/skills/hnoss-design/README.md +3 -0
- package/.agents/skills/hnoss-design/SKILL.md +83 -0
- package/.agents/skills/hvild-afk/README.md +3 -0
- package/.agents/skills/hvild-afk/SKILL.md +241 -0
- package/.agents/skills/jord-projects/README.md +3 -0
- package/.agents/skills/jord-projects/SKILL.md +92 -0
- package/.agents/skills/lifecycle/SKILL.md +56 -0
- package/.agents/skills/lifecycle/smoke_test.sh +57 -0
- package/.agents/skills/lifecycle/start.sh +21 -0
- package/.agents/skills/lifecycle/status.sh +35 -0
- package/.agents/skills/lifecycle/stop.sh +16 -0
- package/.agents/skills/muninn-stow/README.md +3 -0
- package/.agents/skills/muninn-stow/SKILL.md +309 -0
- package/.agents/skills/no-mistakes/SKILL.md +379 -0
- package/.agents/skills/nornir-schedule/README.md +3 -0
- package/.agents/skills/nornir-schedule/SKILL.md +25 -0
- package/.agents/skills/nornir-schedule/assets/events.md +137 -0
- package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
- package/.agents/skills/nsr-compliance/README.md +3 -0
- package/.agents/skills/nsr-compliance/SKILL.md +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/pr-ops/README.md +3 -0
- package/.agents/skills/pr-ops/SKILL.md +109 -0
- package/.agents/skills/ratatoskr-a2a/README.md +3 -0
- package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
- package/.agents/skills/rules-check-drift/SKILL.md +81 -0
- package/.agents/skills/saga-bearings/README.md +3 -0
- package/.agents/skills/saga-bearings/SKILL.md +26 -0
- package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
- package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
- package/.agents/skills/saga-bearings/assets/recap.md +56 -0
- package/.agents/skills/syn-recovery/README.md +3 -0
- package/.agents/skills/syn-recovery/SKILL.md +54 -0
- package/.agents/skills/tyr-check/README.md +3 -0
- package/.agents/skills/tyr-check/SKILL.md +218 -0
- package/.agents/skills/urdh-hold/README.md +3 -0
- package/.agents/skills/urdh-hold/SKILL.md +25 -0
- package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
- package/.agents/skills/urdh-hold/assets/hold.md +54 -0
- package/.agents/skills/vor-diagnostics/README.md +3 -0
- package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
- package/.agents/skills/ymir-host/README.md +3 -0
- package/.agents/skills/ymir-host/SKILL.md +35 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/install.md +69 -0
- package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
- package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
- package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
- package/.agents/skills/ymir-host/assets/update.md +64 -0
- package/.agents/tests/assets/board-render-harness.mjs +117 -0
- package/.agents/tests/cmux-test-safety.sh +51 -0
- package/.agents/tests/fixtures.sh +291 -0
- package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
- package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
- package/.agents/tests/fm-afk-launch.test.sh +961 -0
- package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
- package/.agents/tests/fm-afk-return.test.sh +283 -0
- package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
- package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
- package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
- package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
- package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
- package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
- package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
- package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
- package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
- package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
- package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
- package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
- package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
- package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
- package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
- package/.agents/tests/fm-backend-orca.test.sh +1357 -0
- package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
- package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
- package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
- package/.agents/tests/fm-backend.test.sh +1142 -0
- package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
- package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
- package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
- package/.agents/tests/fm-bearings-board.test.sh +414 -0
- package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
- package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
- package/.agents/tests/fm-bootstrap.test.sh +1178 -0
- package/.agents/tests/fm-branch-supervision.test.sh +552 -0
- package/.agents/tests/fm-brief.test.sh +785 -0
- package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
- package/.agents/tests/fm-busy-state.test.sh +465 -0
- package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
- package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
- package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
- package/.agents/tests/fm-check-unregister.test.sh +198 -0
- package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
- package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
- package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
- package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
- package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
- package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
- package/.agents/tests/fm-composer-ghost.test.sh +716 -0
- package/.agents/tests/fm-composer-lib.test.sh +666 -0
- package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
- package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
- package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
- package/.agents/tests/fm-control.test.sh +910 -0
- package/.agents/tests/fm-crew-state.test.sh +1610 -0
- package/.agents/tests/fm-cursor-harness.test.sh +404 -0
- package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
- package/.agents/tests/fm-cursor-primary.test.sh +708 -0
- package/.agents/tests/fm-daemon.test.sh +2740 -0
- package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
- package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
- package/.agents/tests/fm-extension-binding.test.sh +2187 -0
- package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
- package/.agents/tests/fm-fleet-sync.test.sh +721 -0
- package/.agents/tests/fm-gate-refuse.test.sh +356 -0
- package/.agents/tests/fm-gitignore-config.test.sh +89 -0
- package/.agents/tests/fm-gotmp.test.sh +230 -0
- package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
- package/.agents/tests/fm-grok-harness.test.sh +117 -0
- package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
- package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
- package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
- package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
- package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
- package/.agents/tests/fm-herdr-lab.test.sh +243 -0
- package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
- package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
- package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
- package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
- package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
- package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
- package/.agents/tests/fm-kimi-harness.test.sh +687 -0
- package/.agents/tests/fm-lint-workflows.test.sh +532 -0
- package/.agents/tests/fm-lint.test.sh +1023 -0
- package/.agents/tests/fm-muse-harness.test.sh +932 -0
- package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
- package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
- package/.agents/tests/fm-on.test.sh +507 -0
- package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
- package/.agents/tests/fm-operational-input.test.sh +160 -0
- package/.agents/tests/fm-peek-remote.test.sh +110 -0
- package/.agents/tests/fm-pending-reply.test.sh +1288 -0
- package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
- package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
- package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
- package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
- package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
- package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
- package/.agents/tests/fm-pr-merge.test.sh +2135 -0
- package/.agents/tests/fm-procevent-quota.test.sh +225 -0
- package/.agents/tests/fm-procevent-when.test.sh +406 -0
- package/.agents/tests/fm-procevent.test.sh +1745 -0
- package/.agents/tests/fm-project-origin.test.sh +110 -0
- package/.agents/tests/fm-public-followup.test.sh +2272 -0
- package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
- package/.agents/tests/fm-quota-choose.test.sh +626 -0
- package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
- package/.agents/tests/fm-remote-doctor.test.sh +625 -0
- package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
- package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
- package/.agents/tests/fm-remote-job.test.sh +768 -0
- package/.agents/tests/fm-remote-reply.test.sh +520 -0
- package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
- package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
- package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
- package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
- package/.agents/tests/fm-review-diff.test.sh +176 -0
- package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
- package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
- package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
- package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
- package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
- package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
- package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
- package/.agents/tests/fm-send-inbox.test.sh +352 -0
- package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
- package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
- package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
- package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
- package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
- package/.agents/tests/fm-send-settle.test.sh +147 -0
- package/.agents/tests/fm-send-strict.test.sh +241 -0
- package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
- package/.agents/tests/fm-session-start.test.sh +2515 -0
- package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
- package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
- package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
- package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
- package/.agents/tests/fm-spawn-batch.test.sh +148 -0
- package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
- package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
- package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
- package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
- package/.agents/tests/fm-startup-network.test.sh +712 -0
- package/.agents/tests/fm-stow-cascade.test.sh +370 -0
- package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
- package/.agents/tests/fm-supervision-events.test.sh +156 -0
- package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
- package/.agents/tests/fm-tangle-guard.test.sh +277 -0
- package/.agents/tests/fm-task-delivery.test.sh +420 -0
- package/.agents/tests/fm-task-inbox.test.sh +513 -0
- package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
- package/.agents/tests/fm-teardown.test.sh +2665 -0
- package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
- package/.agents/tests/fm-test-fixtures.test.sh +132 -0
- package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
- package/.agents/tests/fm-test-run.test.sh +1196 -0
- package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
- package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
- package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
- package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
- package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
- package/.agents/tests/fm-transition-lib.test.sh +54 -0
- package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
- package/.agents/tests/fm-update.test.sh +304 -0
- package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
- package/.agents/tests/fm-voice-relay.test.sh +4741 -0
- package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
- package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
- package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
- package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
- package/.agents/tests/fm-wake-queue.test.sh +1224 -0
- package/.agents/tests/fm-watch-arm.test.sh +821 -0
- package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
- package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
- package/.agents/tests/fm-watch-triage.test.sh +3889 -0
- package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
- package/.agents/tests/fm-x-mode.test.sh +3042 -0
- package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
- package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
- package/.agents/tests/herdr-test-safety.sh +42 -0
- package/.agents/tests/lib.sh +315 -0
- package/.agents/tests/remote-herdr-fixture.sh +125 -0
- package/.agents/tests/secondmate-helpers.sh +193 -0
- package/.agents/tests/smoke.test.sh +93 -0
- package/.agents/tests/wake-helpers.sh +338 -0
- package/.agents/tests/zellij-test-safety.sh +60 -0
- package/.agents/tools/README.md +10 -0
- package/.agents/tools/bin/tasks-cli +267 -0
- package/.agents/tools/tasks-cli.ts +216 -0
- package/AGENTS.md +498 -0
- package/CHANGELOG.md +1913 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +114 -60
- package/RULES/01-domains.md +51 -0
- package/RULES/02-agents.md +78 -0
- package/RULES/03-houses.md +61 -0
- package/RULES/04-hoard.md +97 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +108 -0
- package/RULES/07-config.md +101 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/09-electron.md +58 -0
- package/RULES/README.md +22 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +133 -0
- package/bin/a2a-serve.py +103 -0
- package/bin/a2a-serve.sh +8 -0
- package/bin/a2a-talk.sh +50 -0
- package/bin/a2abridge-ensure.sh +108 -0
- package/bin/agent-run.sh +43 -0
- package/bin/agents-config.sh +256 -0
- package/bin/apodex-smoke-test.sh +105 -0
- package/bin/bifrost-bridge.sh +131 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +112 -0
- package/bin/bootstrap-windows.ps1 +112 -0
- package/bin/branch-guard.sh +64 -0
- package/bin/brokk +73 -0
- package/bin/brokk-classify-lib.sh +1770 -0
- package/bin/brokk-lease-lib.sh +222 -0
- package/bin/brokk-lease.sh +193 -0
- package/bin/brokk-lint.sh +65 -0
- package/bin/brokk-send.sh +51 -0
- package/bin/brokk-update.sh +9 -0
- package/bin/brokk-wake-grant.sh +127 -0
- package/bin/brokk-wake-lib.sh +1849 -0
- package/bin/changelog-assemble.sh +154 -0
- package/bin/changelog-guard.sh +197 -0
- package/bin/crash-sense.sh +173 -0
- package/bin/design-check.sh +80 -0
- package/bin/design-icon.sh +153 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +225 -0
- package/bin/eindri-acclaim.sh +47 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seat.sh +83 -0
- package/bin/eindri-seen.sh +54 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +98 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +158 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/feature-inventory.sh +73 -0
- package/bin/fleet-apply.sh +81 -0
- package/bin/github-deploy.sh +94 -0
- package/bin/gjallarhorn-expose.sh +136 -0
- package/bin/gjallarhorn-notify.sh +71 -0
- package/bin/gjallarhorn-purge.sh +67 -0
- package/bin/gjallarhorn-tunnel.sh +85 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +130 -0
- package/bin/hall-snapshot.sh +111 -0
- package/bin/hamr-harness.sh +246 -0
- package/bin/heimdall-ssh-keys.sh +374 -0
- package/bin/herdr-agents.py +44 -0
- package/bin/herdr-ensure.sh +104 -0
- package/bin/herdr-run.sh +452 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hlidskjalf-agents.sh +172 -0
- package/bin/hlidskjalf-usage.sh +196 -0
- package/bin/hoard-guard.sh +135 -0
- package/bin/hoard-lib.sh +105 -0
- package/bin/hodd.sh +102 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +121 -0
- package/bin/local-model-lock.sh +70 -0
- package/bin/mimir-bridge.py +259 -0
- package/bin/mimir-bridge.sh +100 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir-reflect.sh +27 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +72 -0
- package/bin/mjollnir.sh +104 -0
- package/bin/model-hardware.sh +96 -0
- package/bin/model-resolve.sh +160 -0
- package/bin/models-detect.sh +178 -0
- package/bin/nornir-cron-start.sh +162 -0
- package/bin/nornir-job-daily-briefing.sh +191 -0
- package/bin/nornir-job-git-sync.sh +152 -0
- package/bin/nornir-job-hall-snapshot.sh +28 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-nsr-compliance.sh +54 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/npm-publish.sh +136 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +161 -0
- package/bin/omarchy-plugins.sh +187 -0
- package/bin/omarchy-sense.sh +162 -0
- package/bin/perm-guard.sh +30 -0
- package/bin/pi-agent.sh +68 -0
- package/bin/pi-ensure.sh +77 -0
- package/bin/pi-local.sh +37 -0
- package/bin/pi-model-agnostic.sh +71 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +58 -0
- package/bin/project-git.sh +69 -0
- package/bin/public-guard.sh +71 -0
- package/bin/ratatoskr.sh +49 -0
- package/bin/realm-lib.sh +32 -0
- package/bin/repo-scrub.sh +62 -0
- package/bin/rodd-operational-input.sh +250 -0
- package/bin/runes-append.sh +198 -0
- package/bin/saga-session-start.sh +172 -0
- package/bin/saga-sessionstart-run.sh +79 -0
- package/bin/saga-wake-drain.sh +41 -0
- package/bin/secret-guard.sh +63 -0
- package/bin/sessrumnir-ensure.sh +100 -0
- package/bin/sessrumnir-sync.sh +237 -0
- package/bin/sessrumnir.sh +104 -0
- package/bin/skillopt-setup.sh +76 -0
- package/bin/skuld-branch-outcome.sh +203 -0
- package/bin/skuld-branch-prompt.sh +101 -0
- package/bin/smidja-bootstrap.sh +94 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +89 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-spawn-pretool-check.sh +58 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +203 -0
- package/bin/telegram-bot.sh +82 -0
- package/bin/toolchain.sh +74 -0
- package/bin/ui-truth-check.sh +75 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +298 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +60 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +163 -0
- package/bin/wyrd-db.sh +47 -0
- package/bin/yggdrasil.sh +152 -0
- package/bin/ymir-edit.sh +145 -0
- package/bin/ymir-install.sh +806 -0
- package/bin/ymir-invite.sh +93 -0
- package/bin/ymir-isolation.sh +88 -0
- package/bin/ymir-migrate.sh +61 -0
- package/bin/ymir-plan.sh +356 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +110 -0
- package/bin/ymir-setup-auth.sh +119 -0
- package/bin/ymir-validate.sh +193 -0
- package/bin/ymir.js +74 -16
- package/docs/Architecture.md +339 -0
- package/docs/design.md +351 -0
- package/docs/installations/README.md +63 -0
- package/docs/installations/ymir-home.md +93 -0
- package/docs/integration.md +105 -0
- package/docs/lore.md +1060 -0
- package/docs/research/agent-harnesses.md +290 -0
- package/docs/runbooks/README.md +19 -0
- package/docs/runbooks/a2a.md +91 -0
- package/docs/runbooks/agent-permissions.md +99 -0
- package/docs/runbooks/agents.md +57 -0
- package/docs/runbooks/models.md +69 -0
- package/docs/runbooks/realm-onboarding.md +60 -0
- package/docs/runbooks/secrets-and-hoard.md +60 -0
- package/docs/runbooks/updates-and-migrations.md +110 -0
- package/docs/runbooks/worktrees-isolation.md +72 -0
- package/docs/session-start.md +105 -0
- package/docs/skillopt-integration.md +321 -0
- package/docs/sync-system.md +66 -0
- package/docs/workspaces.md +104 -0
- package/docs/ymir-rut.md +260 -0
- package/package.json +54 -14
- package/packaging/build.sh +74 -0
- package/packaging/macos/Ymir Installer.command +43 -0
- package/packaging/windows/ymir-setup.nsi +74 -0
- package/scripts/README.md +22 -0
- package/scripts/electron.sh +269 -0
- package/scripts/lower.sh +34 -0
- package/scripts/raise.sh +42 -0
- package/scripts/start.sh +217 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1913 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
## 2026-09-17 — the house gains an unpublish door
|
|
4
|
+
|
|
5
|
+
- **`bin/npm-publish.sh --unpublish @scope/name@<version>`.** Publishing had a
|
|
6
|
+
door in this house and unpublishing had none, so the act was done by hand on a
|
|
7
|
+
machine whose `~/.npmrc` holds a stale token — the very reason the door exists.
|
|
8
|
+
The new mode resolves the token from the hoard exactly as publishing does,
|
|
9
|
+
demands a spec that names the version (a whole package is not a one-word act),
|
|
10
|
+
supports `--dry-run`, and says plainly that the registry's CDN may serve the
|
|
11
|
+
tarball for a while after the removal.
|
|
12
|
+
- **The window is 72 hours.** npm allows one version back within 72 hours of its
|
|
13
|
+
publication; past that only npm support can remove it. The help text says so,
|
|
14
|
+
because a door that does not name its own clock invites a late knock.
|
|
15
|
+
- **`@zerwiz/ymir@0.1.5` was unpublished** — the version that carried the memory
|
|
16
|
+
well. Publishing the clean 0.1.7 moves the `latest` tag off the tainted build at
|
|
17
|
+
once, which is the half of the repair that does not wait for propagation.
|
|
18
|
+
|
|
19
|
+
## 2026-09-17 — the package shipped the memory well (one version, now excluded)
|
|
20
|
+
|
|
21
|
+
- **The exposure.** `@zerwiz/ymir@0.1.5` carries five files that are nobody's but
|
|
22
|
+
the operator's: `.agents/memory/kaia.engram`, its `-shm` and `-wal` sidecars, and
|
|
23
|
+
`.agents/memory/well/{episodes,workspace}.jsonl`. A public npm tarball contained
|
|
24
|
+
the live memory well — the store and the episodes. Verified by fetching the
|
|
25
|
+
published artefact and listing it; `0.1.0`–`0.1.4` are clean, and this branch's
|
|
26
|
+
build is clean.
|
|
27
|
+
- **The cause, and it is a trap worth naming.** `.gitignore` excludes
|
|
28
|
+
`.agents/memory/kaia.engram*` and `.agents/memory/well/*.jsonl`, and the repo is
|
|
29
|
+
clean — but **npm does not consult `.gitignore` when `files[]` names a whole
|
|
30
|
+
directory.** `files: [".agents/"]` packs that subtree *including* the ignored
|
|
31
|
+
files. Nothing warned: the leak travelled in the artefact, not the repo.
|
|
32
|
+
- **The fix.** The manifest excludes them explicitly, because a `files[]` list
|
|
33
|
+
cannot rely on the ignore file it overrides:
|
|
34
|
+
`!.agents/memory/kaia.engram*`, `!.agents/memory/well/*.jsonl`,
|
|
35
|
+
`!.agents/memory/*.db`, plus `!**/__pycache__/` and `!**/*.pyc` for the compiled
|
|
36
|
+
junk that was travelling the same way. Verified: `npm pack --dry-run` carries
|
|
37
|
+
864 files and **no** memory store — the memory README and the ledger's scaffold
|
|
38
|
+
header are all that remain, as they should be.
|
|
39
|
+
- **The rule for every future package:** a `files[]` entry that names a directory
|
|
40
|
+
overrides `.gitignore` for everything beneath it. Name what ships, or exclude
|
|
41
|
+
what must not — and verify with a dry-run pack, never by assumption.
|
|
42
|
+
- **Remediation.** `@zerwiz/ymir@0.1.5` should be unpublished (it is inside npm's
|
|
43
|
+
window); the clean build publishes as 0.1.7 and supersedes it.
|
|
44
|
+
|
|
45
|
+
## 2026-09-17 — the smithy's dependency names the package npm will actually serve
|
|
46
|
+
|
|
47
|
+
- **`@zerwiz/smidja` is published and not served.** npm accepted it twice (0.1.0,
|
|
48
|
+
then 0.1.1): the tarball and the version document existed, the package document
|
|
49
|
+
never did, and a republish of 0.1.0 was refused as *"previously published"*. The
|
|
50
|
+
name answers `404`, the website `403`, while `@zerwiz/hlidskjalf`,
|
|
51
|
+
`@zerwiz/odrerir` and `@zerwiz/sessrumnir` resolve normally and always have.
|
|
52
|
+
- **A second free name failed identically.** `@zerwiz/smidja-factory` was published
|
|
53
|
+
and shows the same shape — version served, package document withheld. Two names,
|
|
54
|
+
one behaviour, while packages published yesterday serve fine: the withholding is
|
|
55
|
+
npm's, not the name's, and the CLI does not report it.
|
|
56
|
+
- **The distro depends on the name that can resolve.** `optionalDependencies` now
|
|
57
|
+
names `@zerwiz/smidja-factory`, so the moment npm serves that package the smithy
|
|
58
|
+
arrives with the rest. Being optional, it is skipped silently until then — the
|
|
59
|
+
plan's phase-5 row is what says so out loud.
|
|
60
|
+
- **`@zerwiz/ymir` 0.1.7** — the version published once this lands.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## 2026-09-17 — the four surfaces arrive by npm, and an old tree gives up what it holds
|
|
64
|
+
|
|
65
|
+
- **The app packages arrive with the distro.** `@zerwiz/ymir` now depends on the
|
|
66
|
+
surfaces as their own packages — `@zerwiz/hlidskjalf`, `@zerwiz/odrerir`,
|
|
67
|
+
`@zerwiz/sessrumnir` (live on the registry) and `@zerwiz/smiddja` (published at
|
|
68
|
+
0.1.0 today). They are **optionalDependencies**, deliberately: a broken app
|
|
69
|
+
package must never stop the core from installing, and a package not yet on the
|
|
70
|
+
registry is skipped by npm and starts arriving the moment it is published.
|
|
71
|
+
**Proven**: a global install from the packed tarball lands the core plus all
|
|
72
|
+
three live apps, 330 packages, and the bin answers `0.1.6`. A local install
|
|
73
|
+
hoists them to `node_modules/@zerwiz/<app>`; a global one nests them under the
|
|
74
|
+
distro's own `node_modules` — the plan checks both shapes.
|
|
75
|
+
- **The plan tells the shapes apart.** "Declared as a dependency but not fetched"
|
|
76
|
+
is a `DO`; "no package and no dependency" is a `BLOCKED`. All four surfaces read
|
|
77
|
+
`DO` on a machine that has the distro but not yet the apps.
|
|
78
|
+
- **Migration 0005 — the operator's things leave the code tree.** It carries this
|
|
79
|
+
machine's records, the runtime state (pids · logs · locks · the applied-marker),
|
|
80
|
+
the operator's credentials, and the settings git does not track. Run on the
|
|
81
|
+
Allfather's machine: **44 carried, 3 stale twins kept, 1 identical duplicate
|
|
82
|
+
removed, 0 refused** — the tree left holding `.gitkeep` and the distro's own
|
|
83
|
+
tracked defaults.
|
|
84
|
+
- **A collision is decided by evidence, never assumption.** Two files, one name:
|
|
85
|
+
identical content means the tree's copy goes (the content is provably at home);
|
|
86
|
+
different content means both are real, so the home's keeps the name and the
|
|
87
|
+
tree's is carried beside it as `<name>.stale-<UTC>`. Never merged, never
|
|
88
|
+
discarded. A template is not only `*.example` — `agents.machine.example.yaml`
|
|
89
|
+
matched none of the old guards and was carried off as if it were the operator's;
|
|
90
|
+
it is back, and the pattern now covers `*.example.*`.
|
|
91
|
+
- **The plan's `purity` row applies the same law.** A settings file git *tracks* is
|
|
92
|
+
the distro's shipped default, not the operator's — and the check asks git about
|
|
93
|
+
the real path, because the tree's `config` is a symlink into `.agents/config`
|
|
94
|
+
and the index holds the real name. Asking about the link reported "untracked" and
|
|
95
|
+
flagged the distro's own `cron.yaml`. It now reads: *nothing of the operator's is
|
|
96
|
+
written into the code tree*.
|
|
97
|
+
- **`bin/npm-publish.sh --all` learns the smithy** — the registry maps `smidja` to
|
|
98
|
+
`apps/smidja-factory`, so it is a publish target like any other app.
|
|
99
|
+
- **The smithy gets a front page.** `zerwiz/smidja`'s README was a three-line stub;
|
|
100
|
+
it now says what Smíðja is, how to install it, how to run the visualizer on
|
|
101
|
+
`:8437`, what the tree holds, and the shape of a run. The tarball also carries
|
|
102
|
+
`LICENSE` and `NOTICE` — npm attaches the licence and the readme on its own, but
|
|
103
|
+
**not the notice**.
|
|
104
|
+
|
|
105
|
+
## 2026-09-17 — the install asks with a plan, and the operator's things leave the code tree
|
|
106
|
+
|
|
107
|
+
- **The consent a real install asks for is now computed, not recited.** The old
|
|
108
|
+
prompt was a hardcoded paragraph, and a paragraph cannot know the host: it named
|
|
109
|
+
an Omarchy version on a Mac, promised a workspace tree that already stood, and
|
|
110
|
+
never mentioned that no application had been installed at all. `bin/ymir-plan.sh`
|
|
111
|
+
probes this machine and prints one row per step with its state and the reason —
|
|
112
|
+
`DO · SKIP · INFO · BLOCKED · CONSENT` — across nine phases (resolve · code ·
|
|
113
|
+
home · runtimes · engines · apps · wire · raise · verify). `ymir-install.sh`
|
|
114
|
+
prints it at the consent prompt; `--plan` / `--dry-run` prints it and writes
|
|
115
|
+
nothing; `--json`, `--phase N` and `--blocked` are there for automation and for
|
|
116
|
+
reading what is holding an install back.
|
|
117
|
+
- **The four app surfaces are named in the plan.** hlidskjalf, odrerir, sessrumnir
|
|
118
|
+
and smidja each get a row: whether the source is present, whether the web build
|
|
119
|
+
exists, and — when it is absent — the honest reason (`no apps/<name> and no
|
|
120
|
+
@zerwiz/<name> package`). The Electron shells are a `CONSENT` row, not a silent
|
|
121
|
+
download: three shells each pull a ~100 MB runtime the web surfaces do not need.
|
|
122
|
+
- **The home is the operator's to choose.** `step_home` asks once, records the
|
|
123
|
+
answer as machine state under `~/.config/ymir/home`, and every later script
|
|
124
|
+
resolves it through `bin/hoard-lib.sh` (`$YMIR_HOME` → the recorded choice → one
|
|
125
|
+
documented default). `--check` never writes; `--yes` takes what is recorded.
|
|
126
|
+
- **The roots law, applied across the tree.** The package is the **code that runs
|
|
127
|
+
the programs**; everything the operator owns lives in the home. Two resolvers
|
|
128
|
+
were added (`hoard_data_dir`, `hoard_state_dir`, `hoard_settings_dir`,
|
|
129
|
+
`hoard_local_env`) and **42 call sites** converted: `$ROOT/data` and
|
|
130
|
+
`$ROOT/state` (25 scripts), then `$ROOT/.env.local` and `$ROOT/config/*`
|
|
131
|
+
(17 scripts). A credential no longer sits in a tree that ships, and machine
|
|
132
|
+
records no longer sit where npm will erase them on upgrade.
|
|
133
|
+
- **The plan is the ward for that law.** Its phase-1 `purity` row names anything of
|
|
134
|
+
the operator's found in the code tree — `data/`, `state/`, `config/*.yaml`,
|
|
135
|
+
`.env.local` — so drift is reported on every run instead of discovered after an
|
|
136
|
+
upgrade.
|
|
137
|
+
- **The install no longer lectures about local models.** The `step_models` console
|
|
138
|
+
line told the operator to "load the modeltesting skill" — a skill that does not
|
|
139
|
+
exist anywhere in the tree — mid-install. It is gone; the real method is named in
|
|
140
|
+
the one place it belongs, the Galdr asset `assets/local-models.md`. `step_models`
|
|
141
|
+
still ensures the Pi harness and seeds `~/.pi/agent/models.json`.
|
|
142
|
+
- **The package no longer claims to ship `config/`.** `config` is a symlink to
|
|
143
|
+
`.agents/config`, which npm cannot carry; the tarball now declares what it
|
|
144
|
+
actually contains (147 bin scripts, the agent-set template under `.agents/`).
|
|
145
|
+
Settings are seeded into `$YMIR_HOME/config/agents.yaml` from the tracked
|
|
146
|
+
template, falling back to `.agents/config/` when the symlink is absent.
|
|
147
|
+
- **A corrupted TOON block in `AGENTS.md`** — `outputs[7]` carrying eight rows and
|
|
148
|
+
duplicate `midgard/` lines — is mended; the compliance gate reports 84 valid
|
|
149
|
+
blocks again.
|
|
150
|
+
## 2026-09-17 — the registry says where a repo lives and what it is for
|
|
151
|
+
|
|
152
|
+
- **A project entry can now name its machine.** `machine:` records the host
|
|
153
|
+
where a checkout lives; `data/machines.md` holds the fleet (omarchy-1,
|
|
154
|
+
zerwiz, zerwizserver live on the tailnet). A repo is no longer assumed to be
|
|
155
|
+
on the box you happen to be standing on.
|
|
156
|
+
- **A project entry can now say what it is for.** `about:` is one plain
|
|
157
|
+
sentence per repo. `bin/project-git.sh list --field about` prints the whole
|
|
158
|
+
inventory without opening the YAML.
|
|
159
|
+
- **`project-git.sh` resolves more of the block.** `--field` now accepts
|
|
160
|
+
`machine`, `company`, `workspace` and `about` alongside the git fields, and
|
|
161
|
+
non-git keys read from the project block rather than the `git:` line.
|
|
162
|
+
- **One registry, not two.** The live registry is `hodd/identity/projects.yaml`
|
|
163
|
+
(what the runtime reads). A stale duplicate at `Documents/Ymir/identity/` had
|
|
164
|
+
been drifting apart from it — different GitHub owners, different project sets
|
|
165
|
+
— and is retired, with a backup kept in `hodd/state/`.
|
|
166
|
+
|
|
167
|
+
## 2026-09-17 — the private home gets the ward it never had
|
|
168
|
+
|
|
169
|
+
- **Six guards watched the public repo; the home had none — yet the home is where
|
|
170
|
+
every private byte lives.** The one real leak of this day (`platform.env.prev-fill`,
|
|
171
|
+
44 credentials) happened *there*, in a scratch backup swept up by `git add -A`,
|
|
172
|
+
with nothing watching. `bin/hoard-guard.sh` closes that.
|
|
173
|
+
- **It is a hook, not a script.** Seated as `$YMIR_HOME/.git/hooks/pre-commit`,
|
|
174
|
+
**git runs it on every commit** — including one made in a hurry, by a loop, or by
|
|
175
|
+
an agent that has never heard of it. Verified by attempting a real `git commit`
|
|
176
|
+
with no guard invoked: git refused, exit 1.
|
|
177
|
+
- **It catches what actually leaked**, verified by planting each: a scratch-backup
|
|
178
|
+
name (`*.prev-*`, `*.bak`, `*.orig`), a plaintext secret filename, a secret shape,
|
|
179
|
+
and — the evasion that would have hidden a key — **a base64 blob whose decode
|
|
180
|
+
contains a PEM header**, under an innocent filename.
|
|
181
|
+
- **`bin/ymir-install.sh` seats it at both repos** (the `hoard-gate` step reports
|
|
182
|
+
the home separately, so a dormant vault is visible), on every install layer.
|
|
183
|
+
- **A bypass is logged, not silent.** `hoard-guard.sh --log-bypass` appends to the
|
|
184
|
+
Runes ledger when a `--no-verify` commit is detected.
|
|
185
|
+
- **Two stale flat paths fixed in the guards themselves.** `bin/docs-guard.sh` told
|
|
186
|
+
an operator to move private docs to `$YMIR_HOME/docs/` — a path that no longer
|
|
187
|
+
exists — and `bin/groa-update.sh` read `$YMIR_HOME/data/eindri-homes.md` instead of
|
|
188
|
+
the hoard's. A guard pointing at the wrong door teaches the drift it exists to stop;
|
|
189
|
+
`groa-update.sh` now resolves through `hoard_root`.
|
|
190
|
+
|
|
191
|
+
## 2026-09-17 — the NorthStar gate runs nightly; the platform door it caught is mended
|
|
192
|
+
|
|
193
|
+
- **`bin/nornir-job-nsr-compliance.sh` (02:30)** runs every
|
|
194
|
+
`.compliance/gates/check_*.sh` (danger · env · paths · platform · wiring)
|
|
195
|
+
and carves the verdict — `nsr.compliance` clean, or `nsr.compliance.failed`
|
|
196
|
+
(exit 1) naming the broken gate, so the 07:00 briefing reads it at sunrise.
|
|
197
|
+
- **The gate it caught, mended:** `scripts/electron.sh` used `kill -9`, which
|
|
198
|
+
the platform gate rightly refuses as non-portable. It now uses `kill -KILL`
|
|
199
|
+
(the house idiom already in `scripts/stop.sh`) — the NSR round is 5/5 green.
|
|
200
|
+
|
|
201
|
+
galdr-reread: `.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md` — new
|
|
202
|
+
§3.5 (hall snapshot) and §3.6 (NSR round) rows.
|
|
203
|
+
|
|
204
|
+
## 2026-09-17 — the Live Hall's board becomes true: the snapshot lands on the loom
|
|
205
|
+
|
|
206
|
+
- **The Hall was a glass with nothing behind it.** The Óðrerir page reads
|
|
207
|
+
`apps/odrerir/public/livehall.json` same-origin, but nothing wrote it on a
|
|
208
|
+
schedule — the board showed the saga's own static count and said so.
|
|
209
|
+
`bin/nornir-job-hall-snapshot.sh` (08:00, after the 06:00 observer and the
|
|
210
|
+
07:00 briefing) now drives `bin/hall-snapshot.sh` from real state — runes,
|
|
211
|
+
projects, the cron gauge, the wake queue, standing smiths, armed when-
|
|
212
|
+
sources, landed errands — and carves Rune `odrerir / hall.snapshot`.
|
|
213
|
+
- The snapshot is runtime, never repo: `apps/odrerir/public/livehall.json` is
|
|
214
|
+
gitignored, so the job never dirties a branch.
|
|
215
|
+
|
|
216
|
+
galdr-reread: `.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md` — new
|
|
217
|
+
§3.5 row (reads/writes table, idempotence note).
|
|
218
|
+
|
|
219
|
+
## 2026-09-17 — the hoard gets a guard, and Rule 04 stops contradicting the disk
|
|
220
|
+
|
|
221
|
+
- **Eir gains a `hoard` surface.** Private data drifting outside the hoard is
|
|
222
|
+
now caught rather than discovered by asking "where did that go?". The check
|
|
223
|
+
fails on two things: a `.ymir-layout.yaml` entry naming a directory that does
|
|
224
|
+
not exist (a stale map is what lets private work land outside the hoard), and
|
|
225
|
+
a flat `$YMIR_HOME/{identity,data,docs,secrets,tenants}` sitting beside
|
|
226
|
+
`hodd/`. `fix` merges a flat duplicate into the hoard without clobbering, then
|
|
227
|
+
repoints any stale layout entry at the hoard.
|
|
228
|
+
- **Rule 04 corrected, append-only.** The rule's mapping table read as if
|
|
229
|
+
`hodd/x/` and `$YMIR_HOME/x/` were two locations; on a real home that produced
|
|
230
|
+
two parallel stores which drifted. The appended correction states the truth:
|
|
231
|
+
`$YMIR_HOME/hodd/` **is** the private data path, `bin/hoard-lib.sh` is the one
|
|
232
|
+
source of truth for it, and `.ymir-layout.yaml` must name only paths that
|
|
233
|
+
exist. Nothing above the correction was rewritten.
|
|
234
|
+
|
|
235
|
+
## 2026-09-17 — the hoard encrypts its secrets at rest
|
|
236
|
+
|
|
237
|
+
- **`bin/hodd.sh` decrypts transparently.** `load`, `emit`, and `tenant` now
|
|
238
|
+
accept a plaintext file *or* an `.age` ciphertext with the sibling plaintext
|
|
239
|
+
absent. A shared `resolve_secret` finds the readable form; when it decrypts,
|
|
240
|
+
it uses a mode-600 temp and removes it afterward. An agent asks for the
|
|
241
|
+
resolved path and never handles ciphertext directly.
|
|
242
|
+
- **Secrets stay encrypted at rest.** `hodd/secrets/platform.env.age` is the
|
|
243
|
+
committed form; the plaintext is scratch and gitignored. Round-trip verified
|
|
244
|
+
byte-identical before the plaintext was untracked.
|
|
245
|
+
- **The vault invariant, written down.** The age key and the ciphertext travel
|
|
246
|
+
together in the private `ymirhome` repo, so a dead disk loses nothing — and
|
|
247
|
+
`ymirhome` **must never be made public**. Stated in `hodd/docs/secrets-vault.md`.
|
|
248
|
+
- **The honest limit.** This is encryption-at-rest, not encryption-against-yourself:
|
|
249
|
+
on a single-user machine, a process running as the operator can read what the
|
|
250
|
+
operator can read. What it buys is the *file* and the *repo*, not the *account*.
|
|
251
|
+
|
|
252
|
+
## 2026-09-17 — the Forge speaks: each skill's own text in the index
|
|
253
|
+
|
|
254
|
+
- **The Forge listed skills as bare names.** `Forge.tsx` rendered only
|
|
255
|
+
`{s.name}` + the aett rune, while the live `/api/skills` index carries every
|
|
256
|
+
skill's `description` (240-char truncation) — the data was there, the
|
|
257
|
+
surface never showed it. The skill list items are now two-line cards: name +
|
|
258
|
+
aett on the head row, the description beneath (`forge-item-desc`, dimmed
|
|
259
|
+
until hover), scoped to the skill variant so the Eindri rows keep their
|
|
260
|
+
side-by-side name+status shape.
|
|
261
|
+
|
|
262
|
+
galdr-reread: `.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md` — the
|
|
263
|
+
Forge gate bullet (skill list shows name + aett + description).
|
|
264
|
+
|
|
265
|
+
## 2026-09-17 — the feed follows Brokk's thinking past the composer
|
|
266
|
+
|
|
267
|
+
- **Sessrúmnir's auto-scroll never counted streamed THINKING as growth.**
|
|
268
|
+
`useChatScroll` watched `messages` and `streamingContent` only, so a
|
|
269
|
+
reasoning-heavy turn (thinking before any visible content) grew the feed
|
|
270
|
+
without moving it — the thinking block ended up below the floating composer,
|
|
271
|
+
behind it, and the Allfather had to scroll down to read it.
|
|
272
|
+
- **The growth signal now also includes `streamingThinking` and streaming tool
|
|
273
|
+
calls.** While Brokk reasons, the feed keeps the thinking tail in view above
|
|
274
|
+
the composer (still only when Auto Scroll is on and the reader is at the
|
|
275
|
+
bottom — scrolling up to re-read never gets yanked).
|
|
276
|
+
- Live hall updated: rebuilt renderer delivered to the running Sessrúmnir and
|
|
277
|
+
the app restarted via `bin/sessrumnir.sh` (window back on workspace 8).
|
|
278
|
+
|
|
279
|
+
## 2026-09-17 — the editor stops being banished to its own desktop
|
|
280
|
+
|
|
281
|
+
- **`bin/editor-place.sh` pinned the editor to its own desktop with
|
|
282
|
+
`no_focus = true`** — VS Code mapped onto a different workspace than the one
|
|
283
|
+
the Allfather worked on and never took focus, so nothing inside it was
|
|
284
|
+
clickable. The rule was written by Ymir itself into
|
|
285
|
+
`~/.config/hypr/ymir-desktops.lua`.
|
|
286
|
+
- **The editor is now UNMANAGED by default**: it opens on the active desktop,
|
|
287
|
+
focused and clickable, like any other app. The old pin remains reachable
|
|
288
|
+
explicitly with `YMIR_EDITOR_PIN=1 bin/editor-place.sh apply`.
|
|
289
|
+
- Live desk healed: the `code` windowrule was removed from
|
|
290
|
+
`~/.config/hypr/ymir-desktops.lua` (backup kept alongside), Hyprland reloaded
|
|
291
|
+
with no config errors, and the stranded VS Code windows were moved to the
|
|
292
|
+
active desktop and focused.
|
|
293
|
+
|
|
294
|
+
## 2026-09-17 — models, providers, and paths are the user's — and the gate says so
|
|
295
|
+
|
|
296
|
+
- **The law, amended (Rule 07).** Two clauses appended, the rule itself untouched:
|
|
297
|
+
- **A. Models and providers live in the hoard, per user, read from YAML.**
|
|
298
|
+
Every operator's differ, so there is **no global model or provider** — a
|
|
299
|
+
shipped default naming a model is a claim about someone else's machine. The
|
|
300
|
+
user's own live in `$YMIR_HOME/hodd/`, read from a YAML file there; the repo
|
|
301
|
+
ships a template.
|
|
302
|
+
- **B. No hardcoded absolute file paths.** No `/home/<user>/…`, no
|
|
303
|
+
`/Users/<user>/…`, no `C:\Users\…`. A path is relative to a resolved root or
|
|
304
|
+
comes from env/config with one documented default.
|
|
305
|
+
- **The gate, `config`.** `compliance-check.sh` gains a check that fails on a
|
|
306
|
+
model id or provider name used as a **value** in shipped code or a tracked
|
|
307
|
+
config, and on an absolute path naming a user. Comments, `*.example` templates,
|
|
308
|
+
`CHANGELOG*`, and `assets/reference/` are exempt by intent — they document,
|
|
309
|
+
they do not configure. **192 files clean.**
|
|
310
|
+
- **Three real violations found and fixed:**
|
|
311
|
+
- `.agents/config/eindri-dispatch.json` — three dispatch rules named
|
|
312
|
+
`opencode-go/deepseek-v4.1-flash`. Now a template with `<your-model-id>`.
|
|
313
|
+
- `.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml` — the PI boot
|
|
314
|
+
profile named `lmstudio/qwen3.6-35b-a3b`. Now a placeholder.
|
|
315
|
+
- `bin/bootstrap-macos.sh` — `/home/ubuntu/Documents/Ymir`. Now resolved from
|
|
316
|
+
`YMIR_VM_USER` with one documented default.
|
|
317
|
+
- **Two false positives found and fixed in the gates themselves.** The `mocks`
|
|
318
|
+
gate flagged a prose comment explaining why a guard exists; the new `config`
|
|
319
|
+
gate first flagged a sentence mentioning `llama.cpp/llama-swap`. Both now
|
|
320
|
+
exclude comments and require a value position — a gate that cries wolf is a
|
|
321
|
+
gate that gets ignored.
|
|
322
|
+
- **Four pre-existing failures on main mended** so the gate could be added to a
|
|
323
|
+
green tree: a duplicated `midgard/` row in `AGENTS.md` (a bad merge left three),
|
|
324
|
+
the `mocks` false positive, `smidja-factory` indexed but app-provided, and the
|
|
325
|
+
seat's cloth read from an app repo that is absent until `step_apps` runs
|
|
326
|
+
(`design-check` now skips cleanly rather than failing every worktree).
|
|
327
|
+
|
|
328
|
+
## 2026-09-17 — midgard holds public assets only; the company wiki is gone
|
|
329
|
+
|
|
330
|
+
- **`midgard/company_wiki/` did not belong in this repo.** It was an empty
|
|
331
|
+
placeholder (one `.gitkeep`), but a company wiki is *tenant data* — policies,
|
|
332
|
+
vision, specs, client names — and this repo is public. Removed, with every
|
|
333
|
+
reference to it corrected in `midgard/README.md`, `STRUCTURE.md`, `docs/lore.md`
|
|
334
|
+
and `assets/Ymir.md`.
|
|
335
|
+
- **`midgard/` is now described precisely.** It was called "shared company
|
|
336
|
+
assets" in one place and "cross-tenant" in another; a wiki is neither. The
|
|
337
|
+
contract says **public assets**, and `midgard/README.md` names what does *not*
|
|
338
|
+
belong: company knowledge, which lives at `$YMIR_HOME/hodd/identity/companies/`.
|
|
339
|
+
- **`bin/private-guard.sh` gains a tenant-document rule** so the shape cannot
|
|
340
|
+
return: a `company_wiki/`, `wiki/`, `policies/`, `handbook/` or `vision`/
|
|
341
|
+
`strategy`/`roadmap` document staged in the public tree is refused, with a
|
|
342
|
+
message naming where it belongs. Verified by planting `midgard/company_wiki/policies.md`.
|
|
343
|
+
- **Nothing had leaked.** A full sweep of every tracked midgard file for personal
|
|
344
|
+
handles, home paths, key shapes, tunnel UUIDs and LAN/tailnet addresses found
|
|
345
|
+
no hits — the ingress configs use `${VARS}` and `example.org` throughout, and
|
|
346
|
+
the DB schema is generic with row-level security on every tenant table.
|
|
347
|
+
|
|
348
|
+
## 2026-09-17 — AGENTS.md states the one law: no private data in the public repo
|
|
349
|
+
|
|
350
|
+
- **The law is now first.** A `first_law` block sits directly under the mandate
|
|
351
|
+
in `AGENTS.md`: never store personal or private data in this repo — not a
|
|
352
|
+
secret, a key, a name, a plan, a schedule, a client, a credential, or a note.
|
|
353
|
+
The repo is public; private data lives at `$YMIR_HOME`, under `hodd/`.
|
|
354
|
+
- **The private-data section was rebuilt against the disk.** It had duplicated
|
|
355
|
+
`secrets/` and `identity/` lines, no `hodd/` level, and a layout that no longer
|
|
356
|
+
matched the home. It now shows the real tree, names `$YMIR_HOME/hodd/` as *the*
|
|
357
|
+
private data path, and records that `bin/hoard-lib.sh` is the one source of
|
|
358
|
+
truth for it.
|
|
359
|
+
- **Every `$YMIR_HOME/...` path in the file was corrected** to `$YMIR_HOME/hodd/...`
|
|
360
|
+
— the directory rules table, the registry reference, the secrets reference, and
|
|
361
|
+
the append-only ledger path all pointed at the old flat layout.
|
|
362
|
+
- **Two wards are now documented**: `bin/secret-guard.sh` (a secret entering the
|
|
363
|
+
repo) and Eir's `hoard` surface (private data drifting outside the hoard, or a
|
|
364
|
+
`.ymir-layout.yaml` naming a path that does not exist).
|
|
365
|
+
- **Staging discipline is written down.** Stage named files in the home, never
|
|
366
|
+
`git add -A` — a scratch file written seconds earlier gets swept into a commit
|
|
367
|
+
and pushed. This happened this day and cost a history rewrite.
|
|
368
|
+
- **`hodd/AGENTS.example.md`** carried the same stale flat paths and a wrong
|
|
369
|
+
command (`secret-guard.sh emit`, which does not exist); both corrected.
|
|
370
|
+
|
|
371
|
+
## 2026-09-16 — the validator stops calling a dead visualizer healthy
|
|
372
|
+
|
|
373
|
+
`bin/ymir-validate.sh` reported `visualizer PASS "UI built and served on :8437"`
|
|
374
|
+
by looking at `./dist` alone. When the API had crashed on a bad `CMD_DB` and
|
|
375
|
+
nothing was listening on `:8437`, the validator still said PASS — the false-pass
|
|
376
|
+
class this night kept surfacing, in the very tool meant to catch it.
|
|
377
|
+
|
|
378
|
+
- **The check now probes the port as well as the build.** `dist` missing → FAIL;
|
|
379
|
+
built but nothing on `:8437` → FAIL with the fix (`run scripts/start.sh`);
|
|
380
|
+
built and listening → PASS. A PASS now means the thing is actually up.
|
|
381
|
+
- **The smidja-db check resolves the same DB pair** `scripts/start.sh` and
|
|
382
|
+
`bin/smidja-bootstrap.sh` do (an existing `$YMIR_HOME/smidja/smidja.db` first,
|
|
383
|
+
then an in-repo copy, `SMIDJA_DB` override) — previously it named the home path
|
|
384
|
+
only, so an in-repo DB read as missing.
|
|
385
|
+
- `galdr-reread`: `assets/installation.md` — a `visualizer` PASS means built *and*
|
|
386
|
+
listening.
|
|
387
|
+
|
|
388
|
+
## 2026-09-16 — the roster's effect lands, and the backend pin stops being committable
|
|
389
|
+
|
|
390
|
+
Applying the private roster (`bin/agents-config.sh apply`) writes the resolved
|
|
391
|
+
model into each agent's canonical profile. Flipping the two local agents to Pi
|
|
392
|
+
made that visible — and surfaced a small ignore hole.
|
|
393
|
+
|
|
394
|
+
- **Profiles follow the roster.** `sindri-developer.md` and `kvasir-scout.md`
|
|
395
|
+
now carry their **Pi** ids (`llamacpp-coder/qwen3-coder-30b`,
|
|
396
|
+
`llamacpp/qwen3.5-9b`), and `huginn-researcher.md` its declared model — the
|
|
397
|
+
output of `apply` against the operator's roster. These profiles are what the
|
|
398
|
+
harnesses load, so the local agents now run on Pi rather than through OpenCode.
|
|
399
|
+
- **`.agents/config/backend` is ignored.** The pinned terminal backend is
|
|
400
|
+
machine-local, but `config` is a **symlink** to `.agents/config`, so the
|
|
401
|
+
`config/*` rule never matched it and the pin was committable. The file is named
|
|
402
|
+
in `.gitignore` instead.
|
|
403
|
+
|
|
404
|
+
## 2026-09-16 — the roster can finally run an agent on Pi
|
|
405
|
+
|
|
406
|
+
`bin/agents-config.sh apply` wrote **every** agent's model into `opencode.json`'s
|
|
407
|
+
agent block, whatever harness that agent used. So an agent set to run on **Pi**
|
|
408
|
+
(native local models) would have had its Pi model id —
|
|
409
|
+
`llamacpp/qwen3.5-9b` — written into OpenCode's config, which cannot resolve it.
|
|
410
|
+
That is why the roster's two local agents were pinned to `harness: opencode` with
|
|
411
|
+
opencode-style ids: there was no working way to put an agent on Pi.
|
|
412
|
+
|
|
413
|
+
- **`apply` is now harness-aware.** Only `opencode`-harness agents are written
|
|
414
|
+
into `opencode.json`; a `pi` (or `hermes`) agent is left out, its model id going
|
|
415
|
+
to the resolve cache that `bin/agent-run.sh` reads. The providers block is
|
|
416
|
+
unchanged — a provider's endpoint is a real fact OpenCode may still want.
|
|
417
|
+
- The way this is meant to be used: declare a local agent's model as its **Pi**
|
|
418
|
+
id (`llamacpp/qwen3.5-9b`, `llamacpp-coder/qwen3-coder-30b` — the ids `pi
|
|
419
|
+
--list-models` reports) with `harness: pi`; the roster is then Pi-driven with no
|
|
420
|
+
per-machine hand-editing.
|
|
421
|
+
- `galdr-reread`: `assets/harness-integration/README.md` — the two writers of
|
|
422
|
+
`opencode.json`, and the rule that only OpenCode agents belong in it.
|
|
423
|
+
|
|
424
|
+
## 2026-09-16 — the mesh reaches Teams and Anchor, and `show` stops guessing
|
|
425
|
+
|
|
426
|
+
`bin/a2a-mcp.sh` wired only the well (`engram`) and the mesh (`a2abridge`). The
|
|
427
|
+
**Teams** plane and **Anchor** memory existed only in the operator's personal
|
|
428
|
+
harness config, so no agent *inside* Ymir could see tickets or anchored memory —
|
|
429
|
+
and `a2a-mcp.sh show` insisted on a **fixed** server list, reporting
|
|
430
|
+
`wayofteams-mcp not on PATH` even when the plane was wired and working.
|
|
431
|
+
|
|
432
|
+
- **Remote MCP servers, URL-driven.** `bin/a2a-mcp.sh` now wires `wayofteams`
|
|
433
|
+
(from `WAYOFTEAMS_MCP_URL`) and `way-of-anchor-sse` (from `ANCHOR_MCP_URL`).
|
|
434
|
+
OpenCode gets them natively (`type: remote`); Pi, which has no remote
|
|
435
|
+
transport, gets them through the `mcp-remote` stdio bridge. A URL wins over a
|
|
436
|
+
local `wayofteams-mcp` binary when both exist. The URLs are credential-ish and
|
|
437
|
+
live in the private platform env — never the tracked tree.
|
|
438
|
+
- **`show` reports what is actually wired.** It enumerates every key present in
|
|
439
|
+
Pi's `mcpServers` and OpenCode's `mcp` (union with what this run would add), so
|
|
440
|
+
a hand-added or previously-installed server is visible, and the hint only fires
|
|
441
|
+
when Teams/Anchor is genuinely absent.
|
|
442
|
+
- `galdr-reread`: `assets/harness-integration/README.md` — the MCP scope is now
|
|
443
|
+
well · mesh · Teams · Anchor, with the two env keys named.
|
|
444
|
+
|
|
445
|
+
## 2026-09-16 — the credential reaches the gate, and the hall stops leaking an IP
|
|
446
|
+
|
|
447
|
+
Setting the operator password had **no effect**. This is the bug that made that
|
|
448
|
+
true, and the runtime state that leaked a private address.
|
|
449
|
+
|
|
450
|
+
- **`scripts/start.sh` never loaded the platform env for the gate.** The gate is
|
|
451
|
+
`bun run apps/hlidskjalf/server/index.ts`, and the server reads
|
|
452
|
+
`process.env.HLIDSKJALF_AUTH` — but the launcher passed only `PORT`, and nothing
|
|
453
|
+
sourced `.env.local`. So a credential written by `bin/ymir-setup-auth.sh`
|
|
454
|
+
(correctly: `0600`, gitignored) never arrived, and because the gate treats an
|
|
455
|
+
empty `GATE_AUTH` as authenticated (`authed: GATE_AUTH ? … : true`) the gate
|
|
456
|
+
stayed **open**. `start.sh` now loads `.env.local` once, before the ports, for
|
|
457
|
+
every service it raises — the gate, Bifrost and Mimir.
|
|
458
|
+
- **`apps/odrerir/.astro/dev.json` was tracked.** Astro rewrites it on every
|
|
459
|
+
start with the live `pid` and the host's own addresses (LAN + tailnet) — a
|
|
460
|
+
private-IP leak into a public tree. It is now untracked and gitignored; the
|
|
461
|
+
generated types beside it stay tracked.
|
|
462
|
+
- `galdr-reread`: `assets/hlidskjalf-ui.md` (the gate must receive the credential)
|
|
463
|
+
and `assets/odrerir-hall.md` (`.astro/dev.json` is runtime state).
|
|
464
|
+
|
|
465
|
+
## 2026-09-17 — the fragment convention is enforced where GitHub runs it
|
|
466
|
+
|
|
467
|
+
- **The gap, found by doing it.** The pre-push hook folds fragments before a
|
|
468
|
+
push — but a **GitHub merge bypasses the local hook entirely**. PR #43 merged
|
|
469
|
+
and left its own fragment unfolded on `main`, so the ledger silently fell
|
|
470
|
+
behind what the fragments already told. `bin/changelog-assemble.sh --check`
|
|
471
|
+
catches exactly that state; nothing was calling it.
|
|
472
|
+
- **The gate, at the layer that runs.** `.github/workflows/ymir-changelog-fragments.yml`:
|
|
473
|
+
- **on `push` to main** — `bin/changelog-assemble.sh --check` fails when any
|
|
474
|
+
fragment is unfolded, so the ledger can never fall behind a merge.
|
|
475
|
+
- **on a PR** — a change touching code or docs must add a fragment, edit
|
|
476
|
+
`CHANGELOG.md`, or carry the `no-changelog` label. The label records the
|
|
477
|
+
deliberate decision that no entry belongs, rather than letting it be
|
|
478
|
+
forgotten.
|
|
479
|
+
- **The pattern is the standard one.** This is the well-trodden "news fragments"
|
|
480
|
+
design (towncrier — Twisted, pytest, pip, attrs; changesets; CPython). The
|
|
481
|
+
zeroc-ice proposal states the root cause exactly: *"PRs edit one shared file.
|
|
482
|
+
Better merge discipline doesn't fix it; not editing the shared file does."*
|
|
483
|
+
- **`merge=union` was considered and rejected on evidence.** The Rigor ADR-105
|
|
484
|
+
tried it and measured it: *"GitHub's PR-mergeability and merge computation
|
|
485
|
+
ignore `.gitattributes` merge drivers, union included."* It works against local
|
|
486
|
+
git and does nothing on GitHub — a trap already falsified.
|
|
487
|
+
- **Main's own pending fragment is folded in this change**, so the ledger and the
|
|
488
|
+
fragments agree from here on.
|
|
489
|
+
|
|
490
|
+
## 2026-09-17 — the changelog stops conflicting: fragments, folded by a script
|
|
491
|
+
|
|
492
|
+
- **The problem, measured.** `CHANGELOG.md` is one file and every branch appends
|
|
493
|
+
at the same position — the top. Git sees two branches inserting different lines
|
|
494
|
+
at the same spot and calls it a conflict, so **every merge re-conflicts every
|
|
495
|
+
open branch**. Sixteen open PRs were each resolved by hand for this reason
|
|
496
|
+
alone, and each merge re-conflicted the rest: O(N²) meaningless conflicts.
|
|
497
|
+
- **The fix — `CHANGELOG.d/`.** A change adds **one file with a unique name**
|
|
498
|
+
(`<YYYY-MM-DD>-<slug>.md`) instead of editing the ledger. Two branches never
|
|
499
|
+
touch the same fragment, so the collision cannot occur.
|
|
500
|
+
- **`bin/changelog-assemble.sh`** folds fragments into `CHANGELOG.md` — newest
|
|
501
|
+
first, above everything already recorded. Folding is an **append**: existing
|
|
502
|
+
entries are copied verbatim, never reordered, never rewritten. `--dry-run`
|
|
503
|
+
shows what would fold; `--check` exits 1 when fragments are unfolded.
|
|
504
|
+
- **The pre-push hook folds first.** `bin/changelog-guard.sh --install` now
|
|
505
|
+
writes a hook that runs the assembler before the guards, so a push never leaves
|
|
506
|
+
fragments unfolded; if folding changes the ledger the push is refused until the
|
|
507
|
+
fold is committed.
|
|
508
|
+
- **The guard accepts either form.** A push satisfies the duty by appending to
|
|
509
|
+
`CHANGELOG.md` **or** by adding a fragment. The refusal message now names both.
|
|
510
|
+
- **Rule 06 is amended, append-only** — the clause stands; the amendment records
|
|
511
|
+
fragments, and `CHANGELOG.d/` joins the append-only set so a move must carry it.
|
|
512
|
+
|
|
513
|
+
## 2026-09-17 — the hearth re-seeds on its container: Sessrúmnir's chat fire returns
|
|
514
|
+
|
|
515
|
+
- **The ember glow was gone from the chat because the canvas sized itself once
|
|
516
|
+
at mount and only re-seeded on `window.resize`.** Sessrúmnir's split panes
|
|
517
|
+
(file tree · editor · image) resize the chat column without any window resize,
|
|
518
|
+
so the hearth kept a stale or zero-sized canvas — invisible. Both the shared
|
|
519
|
+
hearth (`midgard/design-system/ember.js`) and Sessrúmnir's React port
|
|
520
|
+
(`ember-background.tsx`) now watch their container with a ResizeObserver and
|
|
521
|
+
re-seed only when the measured size actually changes (never per-frame).
|
|
522
|
+
Hlidskjalf inherits the same mend through the shared module.
|
|
523
|
+
- **Verified live**: Sessrúmnir restarted on the fresh build; a screen capture
|
|
524
|
+
of the running window shows the fire drawing (ember + warm-glow pixels across
|
|
525
|
+
the hearth area). The running app had been serving a stale bundle (missing
|
|
526
|
+
`react-i18next` — deps installed, rebuilt).
|
|
527
|
+
|
|
528
|
+
galdr-reread: `.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md` — the
|
|
529
|
+
EmberBackground hearth section (shared module + ResizeObserver mend).
|
|
530
|
+
|
|
531
|
+
# CHANGELOG
|
|
532
|
+
|
|
533
|
+
## 2026-09-17 — Pi gets its agents, and a dead extension comes back
|
|
534
|
+
|
|
535
|
+
- **Pi has no agent loader.** Agent loading in Pi is a *package* (`pi-agents`,
|
|
536
|
+
`pi-agent-mode`, `pi-simple-agents`), never a core feature — and Ymir installs
|
|
537
|
+
none. So `.pi/agents/` held twenty correct profile links that **nothing in Pi
|
|
538
|
+
ever read**. The same failure as OpenCode's singular `.opencode/agent/`,
|
|
539
|
+
arrived at from the other side.
|
|
540
|
+
- **The fix ships in this repo, not a root-pi package.**
|
|
541
|
+
`.pi/shared/extensions/ymir-subagents.ts` discovers the canonical
|
|
542
|
+
`.agents/agents/*.md` tree itself and registers a `subagent` tool. A call runs
|
|
543
|
+
the chosen figure as a nested model call in the current session: the figure's
|
|
544
|
+
markdown body is its system prompt, its frontmatter `model:` picks the model
|
|
545
|
+
where the machine serves it. `subagent({})` and `/subagents` list the roster.
|
|
546
|
+
- **It imports nothing.** `@earendil-works/pi-coding-agent` is not installed as a
|
|
547
|
+
package, so an extension importing its types cannot load at all. This one takes
|
|
548
|
+
`pi` as `any` and declares `parameters` as a plain JSON schema — the pattern
|
|
549
|
+
every working extension in the tree already uses.
|
|
550
|
+
- **A rename that left a reader behind.** `skuld-branch-supervision.ts` imported
|
|
551
|
+
`calmTranscriptClassIsVisible` / `CalmPresentationState` from
|
|
552
|
+
`./lib/ro-visibility.ts`, but that module exports `roTranscriptClassIsVisible` /
|
|
553
|
+
`RoPresentationState`. Pi refuses the **whole extension** at load, so Skuld's
|
|
554
|
+
supervision branch was dead in every session and nothing reported it. Fixed.
|
|
555
|
+
- **The check that catches it** is now recorded in the owning asset: import every
|
|
556
|
+
deployed extension with `node --input-type=module` and confirm it loads — a
|
|
557
|
+
module that cannot resolve is invisible from the file listing.
|
|
558
|
+
## 2026-09-17 — every figure loads: the agent directory was never read
|
|
559
|
+
|
|
560
|
+
- **The bug, stated plainly.** Twenty agent profiles existed, twenty symlinks
|
|
561
|
+
pointed at them, and every gate was green — yet OpenCode loaded **three**
|
|
562
|
+
agents. The symlinks lived in `.opencode/agent/` (SINGULAR). OpenCode reads
|
|
563
|
+
`.opencode/agents/` (PLURAL). Twenty correct links sat in a directory no loader
|
|
564
|
+
opened, so only `brokk` and `hnoss` — the two declared by hand in
|
|
565
|
+
`opencode.json` — ever appeared.
|
|
566
|
+
- **The directory is fixed and migrated.** `.opencode/agent/` → `.opencode/agents/`
|
|
567
|
+
(20 links, all resolving). `bin/valknut-load.sh` now writes the plural path and
|
|
568
|
+
**migrates a legacy singular dir forward**, so an old home heals instead of
|
|
569
|
+
silently keeping its agents invisible.
|
|
570
|
+
- **The roster now declares what it names.** `bin/agents-config.sh apply` only
|
|
571
|
+
touched an agent already present in `opencode.json` (`if a in ablock`), so a
|
|
572
|
+
figure the roster knew but the config had never seen stayed undeclared. The
|
|
573
|
+
roster is the source of truth; a name in it now reaches the harness config.
|
|
574
|
+
- **A new gate catches the class.** `compliance-check.sh` gains **`roster`**: the
|
|
575
|
+
roster (`config/agents.yaml.example`) and the canonical tree
|
|
576
|
+
(`.agents/agents/*.md`) must name the same figures. A figure in the tree but not
|
|
577
|
+
the roster falls to `default_model` and is never declared; a figure in the
|
|
578
|
+
roster with no profile is a phantom. This is the check that would have caught
|
|
579
|
+
the real failure while every other gate stayed green.
|
|
580
|
+
- **Verified, not assumed.** `opencode agent list` in the worktree reports all
|
|
581
|
+
twenty figures (bragi … vor) plus Ymir's own subagents — 33 agents, up from 3.
|
|
582
|
+
Compliance: 14/14 PASS.
|
|
583
|
+
- **References swept.** Every `.opencode/agent/` reference in code and docs moved
|
|
584
|
+
to the plural path: `bin/valknut-load.sh`, `bin/agents-config.sh`,
|
|
585
|
+
`apps/hlidskjalf/server/index.ts`, `RULES/02-agents.md`, `README.md`,
|
|
586
|
+
`docs/runbooks/agents.md`, `.pi/extensions/README.md`, and the Galdr assets
|
|
587
|
+
(`harness-integration`, `runtime-compliance`, `registry`, `hlidskjalf-ui`).
|
|
588
|
+
`CHANGELOG.md`'s own historical entry is left as written — append-only.
|
|
589
|
+
|
|
590
|
+
## 2026-09-16 — the core senses the real host, not Omarchy's shadow
|
|
591
|
+
|
|
592
|
+
- **`bin/ymir-install.sh` `step_host` ran the wrong sensor.** The core host step
|
|
593
|
+
called `bin/omarchy-sense.sh` — the **Omarchy-only** sensor — so on any
|
|
594
|
+
non-Omarchy host it learnt nothing and printed the sensor's own SKIP row as a
|
|
595
|
+
host snapshot: `host snapshot: sensor,SKIP,not an Omarchy host…`. On a Fedora
|
|
596
|
+
workstation that is the whole discovery step, reporting a skip as fact.
|
|
597
|
+
- **Now it senses THIS machine with `bin/host-sense.sh`** — the portable sensor
|
|
598
|
+
(the same one behind `ymir sense`) — on **every** host (Rule 05). Recording
|
|
599
|
+
stays the Omarchy layer's job: `omarchy-sense observe`, the post-update hook,
|
|
600
|
+
desktop placement, the plugin offer, and the alarm channel remain gated behind
|
|
601
|
+
`step_omarchy`. Nothing here assumes Omarchy; nothing here skips the core
|
|
602
|
+
machine either.
|
|
603
|
+
- `step_host` no longer branches on `--check`; it senses once and reports once:
|
|
604
|
+
`host sensed: <os> / <id> / <family> / <session> / <desktop>`.
|
|
605
|
+
- The owning asset reflects it in the same change:
|
|
606
|
+
`.agents/skills/galdr-ymirsystem/assets/installation.md` — the `host` step row,
|
|
607
|
+
the Verify list, the two-layer table (recording, not learning), and the
|
|
608
|
+
"Omarchy branches" note.
|
|
609
|
+
## 2026-09-16 — the visualizer finds its DB, and the seat-hall actually builds
|
|
610
|
+
|
|
611
|
+
Two more readers left behind — both discovered by *starting the apps*, not by any
|
|
612
|
+
gate. Each failed silently in its own way.
|
|
613
|
+
|
|
614
|
+
- **`scripts/start.sh` pointed the smithy at a repo path that no longer holds the
|
|
615
|
+
DB.** `0003-private-data-separation` moved it to `$YMIR_HOME/smidja/smidja.db`,
|
|
616
|
+
but the starter still passed `CMD_DB=<repo>/apps/smidja/smidja_data/smidja.db`
|
|
617
|
+
— so the visualizer API died on boot with `smidja.db not found` and `:8437`
|
|
618
|
+
answered nothing. It now resolves the same pair `bin/smidja-bootstrap.sh` does
|
|
619
|
+
(home first, in-repo fallback, `SMIDJA_DB` override). The asset already
|
|
620
|
+
*described* this resolution; the code now implements it.
|
|
621
|
+
- **`bin/sessrumnir-ensure.sh` never built the app.** `[ "$built_present" ]` tests
|
|
622
|
+
a **literal, non-empty string** — always true — so `ensure --install` skipped
|
|
623
|
+
`build_app` and reported `built: no` with exit 0. Sessrúmnir only built when the
|
|
624
|
+
build was run by hand. Now `built_present` (the function) is called.
|
|
625
|
+
- `galdr-reread`: `.agents/skills/galdr-ymirsystem/assets/smidja.md` — the DB
|
|
626
|
+
path, the `scripts/start.sh` DB resolution, and the observer's read list.
|
|
627
|
+
|
|
628
|
+
## 2026-09-16 — four readers that still pointed at the pre-split world
|
|
629
|
+
|
|
630
|
+
The app split and the hoard migration moved things; four readers never followed.
|
|
631
|
+
None failed loudly — each reported a clean PASS, a wrong SKIP, or a silent loss.
|
|
632
|
+
|
|
633
|
+
- **`bin/ymir-install.sh` wrote during `--check`.** The step chain ran
|
|
634
|
+
`bin/ymir-migrate.sh apply` unconditionally, so a preview that promises *"report
|
|
635
|
+
only, no writes"* actually **moved private data**. Migrations now apply only on
|
|
636
|
+
a real run: `if [ "$CHECK" = 0 ]; then ... apply; fi`.
|
|
637
|
+
- **`.agents/migrations/0003-private-data-separation.sh` skipped every directory.**
|
|
638
|
+
It pre-creates its target dirs, then its `copy` refused any target that already
|
|
639
|
+
existed — so `data/` (and every other directory source) was silently dropped.
|
|
640
|
+
The realm declaration never arrived and `0004` fell back to a neutral realm.
|
|
641
|
+
`copy` now **merges** a directory into its target (never overwriting a file) and
|
|
642
|
+
copies a single file only when it is absent.
|
|
643
|
+
- **`bin/smidja-bootstrap.sh` looked for the smithy at the old root.** `sys.path`
|
|
644
|
+
pointed at `smidja/`, but the split moved it to `apps/smidja/`, so the DB seed
|
|
645
|
+
died with `ModuleNotFoundError: No module named 'smidja_modules'`. It now
|
|
646
|
+
searches `apps/smidja` then `smidja`, so either layout works.
|
|
647
|
+
- **`bin/ymir-validate.sh` read the ledger from the pre-move path.** It looked at
|
|
648
|
+
`$YMIR_HOME/memory/`, but `0004-hoard-and-realms` put the ledger at
|
|
649
|
+
`$YMIR_HOME/hodd/memory/` — a false `runes FAIL` on a healthy home. It now tries
|
|
650
|
+
the hoard first, then the pre-move locations.
|
|
651
|
+
- `galdr-reread`: `.agents/skills/galdr-ymirsystem/assets/smidja.md` — the
|
|
652
|
+
protected-paths gotcha and the `smidja/` → `apps/smidja/` move.
|
|
653
|
+
|
|
654
|
+
## 2026-09-16 — Omarchy-first, host-aware: Windows and macOS get a door
|
|
655
|
+
|
|
656
|
+
- **`bin/host-sense.sh`** — the one place that looks before anything acts. It
|
|
657
|
+
reports THIS machine: distro and family, kernel, arch, platform (linux · wsl ·
|
|
658
|
+
macos · windows), session (Wayland/X11), desktop, compositor, package manager,
|
|
659
|
+
and what the desktop can actually *do* — `placement`, `launcher`, `tray`. No
|
|
660
|
+
layer may assert a machine it is not standing on.
|
|
661
|
+
- **Omarchy stays first-class, and is now gated.** `bin/omarchy-sense.sh` opens
|
|
662
|
+
by asserting *"Ymir runs on an Omarchy host"*; on any other host it now skips
|
|
663
|
+
cleanly and points at `bin/host-sense.sh`, rather than recording the wrong
|
|
664
|
+
machine. That is Rule 05's own rule: a layer is gated on its host.
|
|
665
|
+
- **Windows has a door:** `bin/bootstrap-windows.ps1` — enables WSL2, installs
|
|
666
|
+
Ubuntu, then hands the work to `bin/ymir-install.sh` inside the distro. It is
|
|
667
|
+
honest about needing elevation and about the one reboot a fresh machine needs.
|
|
668
|
+
- **macOS has a door:** `bin/bootstrap-macos.sh` — raises Ubuntu in a Lima VM and
|
|
669
|
+
installs Ymir inside it, plus `packaging/macos/Ymir Installer.command`, a
|
|
670
|
+
double-clickable launcher for an operator who should not need a terminal.
|
|
671
|
+
- **The installers themselves:** `packaging/build.sh --exe|--mac|--check`, the
|
|
672
|
+
NSIS script `packaging/windows/ymir-setup.nsi` (→ `Ymir-Setup.exe`), and
|
|
673
|
+
`.github/workflows/ymir-installers.yml`, which builds the exe on an Ubuntu
|
|
674
|
+
runner (NSIS is a compiler, not a Windows VM) and the .pkg on a macOS runner
|
|
675
|
+
(pkgbuild is Apple-only). Signing/notarisation stay with the operator, so the
|
|
676
|
+
artefacts ship unsigned.
|
|
677
|
+
- `README.md` gains "Bringing your own machine" — the host table and the build
|
|
678
|
+
commands; its `docs/masterplan.md` pointer is corrected to `$YMIR_HOME/docs/`.
|
|
679
|
+
|
|
680
|
+
## 2026-09-16 — app packaging prepared under the @ymir scope (Amendment C, part one)
|
|
681
|
+
|
|
682
|
+
- **Scoped names.** `apps/odrerir` was `ymir-odrerir` and `apps/sessrumnir` was
|
|
683
|
+
bare `sessrumnir`; both are now `@ymir/odrerir` and `@ymir/sessrumnir`.
|
|
684
|
+
- **Publishable metadata on all four apps** (hlidskjalf, hlidskjalf-mobile,
|
|
685
|
+
odrerir, sessrumnir): `license`, `repository`, `publishConfig.access: public`,
|
|
686
|
+
a `files` surface, and `prepublishOnly` where a build exists.
|
|
687
|
+
- **Measured with `npm pack --dry-run --ignore-scripts`:** hlidskjalf 1.3 MB /
|
|
688
|
+
21 files, odrerir 2.3 MB / 15, sessrumnir 4.0 MB / 116, hlidskjalf-mobile
|
|
689
|
+
2.0 kB / 4 (source only — it has no build script). `dist/ymir.apk` is excluded
|
|
690
|
+
by `!dist/*.apk`: it took the hlidskjalf tarball from 1.3 MB to 14.5 MB, and
|
|
691
|
+
npm is not an APK channel.
|
|
692
|
+
- **`private: true` stays until the Allfather's word** — nothing can publish by
|
|
693
|
+
accident; the flip is one line per app.
|
|
694
|
+
- The app repos were already registered in `$YMIR_HOME/identity/projects.yaml`
|
|
695
|
+
(`zerwiz/{hlidskjalf,hlidskjalf-mobile,odrerir,sessrumnir,smidja}`).
|
|
696
|
+
- `no-mistakes` is initialized for this repo (`no-mistakes init`): the clean-PR
|
|
697
|
+
gate now has its local remote. The vendored skill copy stays — it is the
|
|
698
|
+
canonical tree the skill index names.
|
|
699
|
+
|
|
700
|
+
## 2026-09-16 — the loader stops deleting: merge, never overwrite
|
|
701
|
+
|
|
702
|
+
- **Root cause of the Apodex-provider loss, mended at the source.** Two writers
|
|
703
|
+
share the untracked `opencode.json`: `bin/valknut-load.sh` (structure, from
|
|
704
|
+
`opencode.json.example`) and `bin/agents-config.sh apply` (the roster —
|
|
705
|
+
providers and per-agent models, from `config/agents.yaml`). The loader
|
|
706
|
+
re-rendered with `sed` + `mv`, so because the example carried only
|
|
707
|
+
`llama.cpp`, **every loader run silently deleted the Apodex provider** that
|
|
708
|
+
lived only in the live file. `config_out` now merges deep and
|
|
709
|
+
`setdefault`-style: missing keys are added, existing ones are never
|
|
710
|
+
overwritten, and the skills path is ensured. Verified by wiping the provider
|
|
711
|
+
by hand: the next run reports `merged(provider.apodex)` and restores it, while
|
|
712
|
+
an unrelated hand-added key survives untouched. Seeding happens only when the
|
|
713
|
+
file is absent.
|
|
714
|
+
- **The changelog guard still bites, without punishing a follow-up.** The
|
|
715
|
+
pre-push guard now accepts either the pushed range touching `CHANGELOG.md` or
|
|
716
|
+
the branch's whole range since it left the trunk touching it — a commit that
|
|
717
|
+
merely lands a file the record already tells needs no micro-entry. A branch
|
|
718
|
+
whose entire range leaves untold is still refused.
|
|
719
|
+
- `bin/valknut-load.sh --status` reports the config outcome
|
|
720
|
+
(`seeded` · `merged(…)` · `unchanged` · `kept`), so a silent stomp can never
|
|
721
|
+
hide behind a "rendered" line again.
|
|
722
|
+
- `harness-integration/README.md` records the two-writer boundary.
|
|
723
|
+
|
|
724
|
+
## 2026-09-16 — one skills tree, every harness; the config stomp mended
|
|
725
|
+
|
|
726
|
+
- **Every harness now reaches `.agents/skills`.** Pi was already right — its own
|
|
727
|
+
code walks up from the cwd to `.agents/skills` (and `~/.agents/skills`), so it
|
|
728
|
+
discovers Ymir's skills natively with no link and no config; a second root
|
|
729
|
+
under `.pi/` would only double-load. Claude Code, Codex and Cursor read project
|
|
730
|
+
skills from their own directory, so `bin/valknut-load.sh` now binds
|
|
731
|
+
`.claude/skills`, `.codex/skills` and `.cursor/skills` to `../.agents/skills`.
|
|
732
|
+
opencode reaches the tree through `skills.paths`. The install step `loaders`
|
|
733
|
+
runs the loader, so a fresh install gets all of it.
|
|
734
|
+
- **The `harnesses` gate (G14) now asserts the skills surfaces too** — opencode's
|
|
735
|
+
config, Pi's native root, and the three links — so a harness silently loading
|
|
736
|
+
nothing can no longer pass.
|
|
737
|
+
- **Defect mended: the loader was stomping `opencode.json`.** `bin/valknut-load.sh`
|
|
738
|
+
renders `opencode.json` from `opencode.json.example`, and that example carried
|
|
739
|
+
only `llama.cpp` — so a loader run silently **deleted the Apodex provider**,
|
|
740
|
+
which had only ever lived in the generated file. The example now carries Apodex
|
|
741
|
+
as well, with the served id `apodex-1.0-mini`, so a re-render cannot drop it.
|
|
742
|
+
- `bin/valknut-load.sh --status` now reports every surface (agents *and* skills)
|
|
743
|
+
with a true row count instead of a hardcoded header.
|
|
744
|
+
- Assets: `harness-integration/README.md` gains the skill-location table, and
|
|
745
|
+
each per-harness file states its own mechanism.
|
|
746
|
+
|
|
747
|
+
## 2026-09-16 — Hodd lives outside the repo, and the installer makes it so
|
|
748
|
+
|
|
749
|
+
- **One resolver.** `bin/hoard-lib.sh` (`hoard_root`) is now the single answer to
|
|
750
|
+
*where private data lives*: `$YMIR_HOARD`, else `$YMIR_HOME`, else
|
|
751
|
+
`$HOME/Documents/Ymir` — never the checkout. Rule 07's one documented default,
|
|
752
|
+
in one place.
|
|
753
|
+
- **The inward default is gone.** `bin/mimir-ingest.sh`, `bin/project-git.sh` and
|
|
754
|
+
`bin/workspace-provision.sh` each fell back to `$ROOT/hodd`, so on a machine
|
|
755
|
+
with neither `YMIR_HOARD` nor `YMIR_HOME` exported, memory ingest, the project
|
|
756
|
+
registry and workspace provisioning wrote private data **inside the repo**.
|
|
757
|
+
All three (plus `bin/hodd.sh` and the installer) now resolve through the lib.
|
|
758
|
+
- **The misplaced document is out.** `0003-private-data-separation.md`, which had
|
|
759
|
+
come to rest in the repo at `hodd/docs/plans/`, now lives in the hoard at
|
|
760
|
+
`$YMIR_HOME/docs/plans/`. The repo's `hodd/` holds exactly the guard, the
|
|
761
|
+
README and `AGENTS.example.md` — Rule 04's scaffold set, and nothing else.
|
|
762
|
+
- **Installed, not assumed.** `bin/ymir-install.sh` step `tree` now raises the
|
|
763
|
+
hoard layout *outside* the repo (`bin/hodd.sh init`) and seeds an empty
|
|
764
|
+
`secrets/platform.env` (mode 0600), so `bin/hodd.sh emit secrets/platform.env`
|
|
765
|
+
resolves on a fresh machine instead of failing with "not readable".
|
|
766
|
+
`assets/installation.md` and `assets/memory-well.md` updated in the same change.
|
|
767
|
+
|
|
768
|
+
## 2026-09-16 — the pane bridge keeps its quoting; Phase 3 verified
|
|
769
|
+
|
|
770
|
+
- **The Apodex plan's last open verification is closed.** Run in a herdr pane —
|
|
771
|
+
`bin/herdr-run.sh run huginn-research -- bin/huginn-research-worker.sh --brief
|
|
772
|
+
"…" --output-dir …` — the worker recalled, dispatched to the Apodex seat, wrote
|
|
773
|
+
its verdict, and observed it into Mimirsbrunn (`status: completed`, verdict
|
|
774
|
+
*"The capital of Norway is Oslo."*). Phase 3 needed a spawn, which the
|
|
775
|
+
read-only session lock had forbidden; it was run once the lock was this
|
|
776
|
+
session's.
|
|
777
|
+
- **Defect found and mended — `bin/herdr-run.sh run` lost its quoting.** A pane
|
|
778
|
+
runs its command through a *shell*, but the bridge handed herdr the raw argv.
|
|
779
|
+
An argument containing spaces reached the pane as separate words, so
|
|
780
|
+
`--brief "In one sentence: …"` arrived as `--brief In one sentence: …` and the
|
|
781
|
+
worker died with `error: unknown arg: one`. Every real brief is multi-word, so
|
|
782
|
+
the documented invocation could never have worked. `run` now quotes each
|
|
783
|
+
argument on the way in (`printf '%q'`), verified by re-running it.
|
|
784
|
+
- Asset updated in the same change: `.agents/skills/ymir-host/assets/thjazi.md`
|
|
785
|
+
carries the quoting rule.
|
|
786
|
+
|
|
787
|
+
## 2026-09-16 — the skill-loading audit: wrong skills unloaded, the index made true
|
|
788
|
+
|
|
789
|
+
- **Three phantom skills stopped loading.** opencode was loading `galdr-compliance`
|
|
790
|
+
and `galdr-crafter` — both superseded, their work long since moved to
|
|
791
|
+
`tyr-check` — and `NSR`, the NSR scaffolding spec, which sat at
|
|
792
|
+
`assets/nsr/SKILL.md` carrying frontmatter. A recursive scanner walks
|
|
793
|
+
`skills.paths` to *any* depth, so all three were announced to every agent as
|
|
794
|
+
live skills. The two galdr crafters are removed; the NSR spec is renamed
|
|
795
|
+
`assets/nsr/scaffold-spec.md` and stays a document (its sibling templates
|
|
796
|
+
carry no frontmatter and were already inert).
|
|
797
|
+
- **Two gates added, one per failure class** (`compliance-check.sh`):
|
|
798
|
+
- **`harnesses` (G14)** — every link in `.claude/agents`, `.codex/agents`,
|
|
799
|
+
`.cursor/agents`, `.pi/agents`, `.opencode/agent` must land, one hop, in the
|
|
800
|
+
canonical `.agents/agents/` tree (Rule 02), and no nested `SKILL.md` may
|
|
801
|
+
carry frontmatter. One hop deliberately: Galdr's agent file *is* the skill,
|
|
802
|
+
by the dual-surface rule.
|
|
803
|
+
- **`skillindex` (G15)** — every real skill dir must be named in
|
|
804
|
+
`.agents/skills/README.md`, and every `.agents/skills/<name>` path the assets
|
|
805
|
+
cite must exist. Lines marked planned/legacy/superseded/removed/abandoned/
|
|
806
|
+
retired are exempt by intent.
|
|
807
|
+
- **The drift they exposed, mended:** the canonical index listed 23 skills while
|
|
808
|
+
26 existed (`groa-update`, `lifecycle`, `rules-check-drift` were missing); the
|
|
809
|
+
Galdr and `.agents/assets/agents` registries still described a layout that no
|
|
810
|
+
longer existed (`smidja/`, `gunnlod`, `hamr`, `saga`, `ymir`, `open-design`),
|
|
811
|
+
pointing the agent at files that were not there; dead paths corrected to the
|
|
812
|
+
real names (`smidja-factory`, `saga-bearings`, `urdh-hold`, `nornir-schedule`,
|
|
813
|
+
`ymir-host`, `hamr-adapters`); `brokk-craft` marked planned rather than
|
|
814
|
+
presented as a working command.
|
|
815
|
+
- **`AGENTS.md` gains the invariant:** the delivery gate is enforced in git
|
|
816
|
+
hooks seated by the install step `gates` — `branch-guard` refuses a protected
|
|
817
|
+
branch, `changelog-guard` refuses a push whose range never touches
|
|
818
|
+
`CHANGELOG.md`.
|
|
819
|
+
|
|
820
|
+
## 2026-09-16 — the delivery gates install themselves; rename drift mended
|
|
821
|
+
|
|
822
|
+
- **Install seam.** `bin/ymir-install.sh` gains step **`gates`** (after
|
|
823
|
+
`loaders`): `bin/secret-guard.sh --install` seats the pre-commit guard and
|
|
824
|
+
`bin/changelog-guard.sh --install` the pre-push (branch + changelog). A fresh
|
|
825
|
+
clone now gets the delivery gate without a manual step — `--check` reports it
|
|
826
|
+
as `gates OK|WARN`, the consent preamble names it, and
|
|
827
|
+
`assets/installation.md` carries the row in the same change.
|
|
828
|
+
- **Drift mended — found by the compliance gate, not by me.** Two symlinks
|
|
829
|
+
still pointed at the retired `galdr-cli` skill, so the last rename was not in
|
|
830
|
+
fact complete: `.agents/agents/galdr.md` (Galdr's agent surface was a **dead
|
|
831
|
+
link**) and `.agents/skills/tyr-check/assets`. Both repointed at
|
|
832
|
+
`galdr-ymirsystem`, which is where the skill and its assets live.
|
|
833
|
+
- **`AGENTS.md` TOON mend.** The `security[4]` block carried a rule wrapped
|
|
834
|
+
across two lines, which the checker counted as a fifth row. Joined to one
|
|
835
|
+
line; the block now declares and holds exactly four.
|
|
836
|
+
- **Compliance.** All ten Galdr gates green: toon · naming · mocks · syntax ·
|
|
837
|
+
json · sync · surfaces · assets · duplicates · governed.
|
|
838
|
+
|
|
839
|
+
## 2026-09-16 — Smiðja moves into the app tree
|
|
840
|
+
|
|
841
|
+
- **The smithy is an app.** Its 148 source files moved from
|
|
842
|
+
`.agents/skills/smidja-factory/` to `apps/smidja-factory/`, joining
|
|
843
|
+
hlidskjalf, odrerir and sessrumnir under `apps/`.
|
|
844
|
+
- **Path-transparent.** `.agents/skills/smidja-factory` is now a symlink to
|
|
845
|
+
`../../apps/smidja-factory`, so every existing path resolves unchanged —
|
|
846
|
+
`scripts/start.sh`, `bin/ymir-install.sh`, `bin/ymir-validate.sh`, and the
|
|
847
|
+
skill loader (`.agents/skills` is a skills path). `node_modules/` stays
|
|
848
|
+
gitignored and is not carried.
|
|
849
|
+
- **Still open** (recorded, not done): the root `smidja/` runtime tree
|
|
850
|
+
Amendment A would move to `apps/smidja/`, and Amendment C's per-app GitHub
|
|
851
|
+
repos and npm publishing.
|
|
852
|
+
|
|
853
|
+
## 2026-09-16 — the changelog guard: no push ships untold
|
|
854
|
+
|
|
855
|
+
- **Every push carries a CHANGELOG entry.** `bin/changelog-guard.sh` installs a
|
|
856
|
+
pre-push hook that reads the refs git hands it, resolves the range being
|
|
857
|
+
pushed, and refuses the push when `CHANGELOG.md` is untouched in that range.
|
|
858
|
+
A change that ships is a change that was told; the record can no longer lag
|
|
859
|
+
silently behind the code.
|
|
860
|
+
- **Rule 08 extracted and versioned.** The protected-branch check that lived
|
|
861
|
+
only inside the ad-hoc `.git/hooks/pre-push` is now `bin/branch-guard.sh`, so
|
|
862
|
+
the delivery gate is reproducible: `bin/changelog-guard.sh --install` writes
|
|
863
|
+
the pre-push that runs both guards.
|
|
864
|
+
- **Escape hatch, deliberate and loud.** `YMIR_SKIP_CHANGELOG_GUARD=1 git push`
|
|
865
|
+
when an entry truly does not belong.
|
|
866
|
+
- Checks by hand: `bin/changelog-guard.sh --range A..B`,
|
|
867
|
+
`bin/branch-guard.sh --branch main`.
|
|
868
|
+
|
|
869
|
+
## 2026-09-16 — Apodex seat verified; the Weave mended
|
|
870
|
+
|
|
871
|
+
- **Correction (cites the entry below, never rewrites it).** The earlier
|
|
872
|
+
entry said *"LM Studio is retired; its :1234 port belongs to Apodex now."*
|
|
873
|
+
That was false as carved. LM Studio still holds `:1234` and is what serves
|
|
874
|
+
the Apodex GGUF; Apodex took the **model seat**, not the server.
|
|
875
|
+
- **Live verification.** `bin/apodex-smoke-test.sh` → PASS (valid tool-capable
|
|
876
|
+
response, exit 0). `bin/huginn-research-worker.sh` with **bare defaults** →
|
|
877
|
+
`status: completed`, verdict written, observed into Mimirsbrunn. The Apodex
|
|
878
|
+
seat (`http://127.0.0.1:1234/v1`) is live.
|
|
879
|
+
- **One model id, everywhere.** The seat serves **`apodex-1.0-mini`**; the
|
|
880
|
+
worker, smoke test, `.env.example`, `opencode.json`, `config/agents.yaml.example`
|
|
881
|
+
and Huginn's profile now all say so. Previously three names drifted
|
|
882
|
+
(`apodex/Apodex-1.0-mini-Q4_K_M`, `apodex/apodex-mini-q4`, the served id) and
|
|
883
|
+
the default worker call failed with `No models loaded`.
|
|
884
|
+
- **Four defects mended.** `bin/huginn-research-worker.sh` made executable
|
|
885
|
+
(was 644 — bare invocation died with `Permission denied`); the smoke test's
|
|
886
|
+
`--serve` GGUF path corrected to
|
|
887
|
+
`~/Models/FlameF0X/Apodex-1.0-mini-Q4_K_M-GGUF/apodex-1.0-mini-q4_k_m.gguf`;
|
|
888
|
+
`bin/models-detect.sh` env var renamed from the typo `APEDEX_URL` to
|
|
889
|
+
`APODEX_URL`.
|
|
890
|
+
- **Weight truth.** The Apodex Q4_K_M weights are **21.7 GB**, not the ~4–6 GB
|
|
891
|
+
the plan assumed — it cannot sit beside a coding model. `AGENTS.md` now says
|
|
892
|
+
so: one local model at a time, by weight.
|
|
893
|
+
- **Smiðja relocated.** `.agents/skills/smidja-factory` is now a symlink to the
|
|
894
|
+
app tree at `apps/smidja-factory/`, which is where the smithy's real files
|
|
895
|
+
live (Amendment A/C of the Apodex plan).
|
|
896
|
+
- Plan (private hoard): `$YMIR_HOME/docs/plans/apodex-integration-into-ymir.md`
|
|
897
|
+
— Amendment E records the live pass, the mended defects, and the one open
|
|
898
|
+
item: the herdr-seat verification (Phase 3), which needs a spawn.
|
|
899
|
+
|
|
900
|
+
## 2026-09-16 — Apodex joins the Weave (research/planning provider)
|
|
901
|
+
|
|
902
|
+
- **Apodex provider.** Apodex-1.0-mini-Q4_K_M climbs into the machine as
|
|
903
|
+
the research/planning GGUF on `http://127.0.0.1:1234/v1`, seated
|
|
904
|
+
alongside llama.cpp coding models on :8080. LM Studio is retired; its
|
|
905
|
+
:1234 port belongs to Apodex now.
|
|
906
|
+
- **Env template.** `.env.example` gains the `APODEX_*` block; the LM
|
|
907
|
+
Studio block is marked RETIRED with its port claim corrected.
|
|
908
|
+
- **Smoke test.** `bin/apodex-smoke-test.sh` — probe or serve-and-test an
|
|
909
|
+
Apodex seat; exits 0=pass, 1=fail, 2=unavailable. Never mutates config.
|
|
910
|
+
- **Research worker.** `bin/huginn-research-worker.sh` (Apodex-powered
|
|
911
|
+
Eindri): takes a brief, recalls from Mimirsbrunn, dispatches to the
|
|
912
|
+
Apodex chat/completions seat, writes a structured verdict, observes it
|
|
913
|
+
back into the well. Wears the name **Huginn** per the naming law (the
|
|
914
|
+
research seat; Gungnir stays the skill-synthesis engine).
|
|
915
|
+
- **Agents hall.** `.agents/agents/huginn-researcher.md` binds Huginn to
|
|
916
|
+
the apodex model; `config/agents.yaml.example` registers the apodex
|
|
917
|
+
provider and Huginn's seat; `opencode.json` carries the apodex provider
|
|
918
|
+
block alongside llama.cpp; `bin/models-detect.sh` probes and emits the
|
|
919
|
+
apodex provider for the Pi model file (`~/.pi/agent/models.json`).
|
|
920
|
+
- **Install seams.** Apodex rides the existing seams: models-detect merges
|
|
921
|
+
it into the Pi models file at install; agents-config applies it into
|
|
922
|
+
opencode.json. Model provider selection documented in AGENTS.md
|
|
923
|
+
(`## Model Provider Selection`), Apache 2.0 licence noted.
|
|
924
|
+
|
|
925
|
+
## 2026-09-16 — Gunnlöð joins the hall (SkillOpt integration)
|
|
926
|
+
|
|
927
|
+
- **SkillOpt integration.** `pip install skillopt` into `.venv/`; training
|
|
928
|
+
loop (`skillopt-train`), eval (`skillopt-eval`), and nightly
|
|
929
|
+
self-evolution (`skillopt-sleep`) available for Smíðja prompts and
|
|
930
|
+
Ymir skills. Nightly Nornir job at 00:30 (bin/nornir-job-skillopt-sleep.sh),
|
|
931
|
+
staged artifacts only — Allfather approves before adopt. One-time setup:
|
|
932
|
+
`bin/skillopt-setup.sh`.
|
|
933
|
+
- **Naming.** SkillOpt adopted the name **Gunnlöð** (keeper of the mead of
|
|
934
|
+
poetry — distills trajectories into refined skill artifacts). Added to
|
|
935
|
+
`.agents/assets/agents/naming.md` (platform map, 28 subsystems),
|
|
936
|
+
`.agents/skills/galdr-ymirsystem/assets/registry.md` (skills + external tools),
|
|
937
|
+
`README.md` (System Map + Skills + gratitude), `NOTICE` (MIT attribution).
|
|
938
|
+
|
|
939
|
+
## 2026-09-13 — the imported names leave the halls (Norse naming purge)
|
|
940
|
+
|
|
941
|
+
- **"firstmate" retargeted to Ymir's own names across every Ymir-owned surface.**
|
|
942
|
+
The upstream distro's nautical vocabulary is gone from the docs, skills, `bin/`,
|
|
943
|
+
config, and the Hlidskjalf review copy: `firstmate` → **Brokk**, `secondmate` →
|
|
944
|
+
**Eindri-home**, `crew`/`crewmate` → **Eindri**, `captain` → **Allfather**
|
|
945
|
+
(`docs/lore.md`, `docs/Architecture.md`, `.agents/agents/brokk.md`,
|
|
946
|
+
`.agents/skills/herdr-panes/assets/{herdr,tmux}-backend.md`,
|
|
947
|
+
`.agents/skills/eindri-homes/assets/control-plane.md`,
|
|
948
|
+
`.agents/skills/saga-bearings/assets/board-template.html`,
|
|
949
|
+
`.agents/skills/ymir-host/assets/thjazi.md`, `bin/README.md`,
|
|
950
|
+
`apps/hlidskjalf/**`).
|
|
951
|
+
- **Engine literals kept.** Every real upstream identifier stays verbatim — the
|
|
952
|
+
Herdr labels (`firstmate`, `2ndmate-<id>`, `firstmate-<id>`), the home marker
|
|
953
|
+
`.fm-secondmate-home`, the envelope `FIRSTMATE_OP: ` and `[fm-from-firstmate]`,
|
|
954
|
+
and all `FM_*`/`fm-*` names — because `.agents/backend/` (the vendored engine)
|
|
955
|
+
and `assets/reference/` (provenance) are untouched.
|
|
956
|
+
- **Licensing.** `NOTICE` now records the upstream **firstmate** distro
|
|
957
|
+
(`github.com/kunchenguid/firstmate`, MIT, © kunchenguid) and a README "Built on"
|
|
958
|
+
section points to it; the MIT copyright/permission notice is retained.
|
|
959
|
+
- **Governed asset:** `galdr-ymirsystem/assets/hlidskjalf-ui.md` records the Allfather
|
|
960
|
+
review copy in the same change. `compliance-check.sh` 10/10 PASS.
|
|
961
|
+
|
|
962
|
+
## 2026-09-13 — The realm seat, carved (wayof)
|
|
963
|
+
|
|
964
|
+
- **Problem:** the realm tree was bare (only the shipped example), no tenant
|
|
965
|
+
was seated, and the session digest resolved the Allfather's realm to
|
|
966
|
+
`default` — his company and private holdings unreachable by the map.
|
|
967
|
+
- **Seat:** `svartalfaheim/wayof/` carved from the example — `.env.realm`,
|
|
968
|
+
`SECRETS.md`, `AGENTS.md` (persona), `domains/`, `projects/`, the five
|
|
969
|
+
workspace branches, and the 9 company cards seeded from the identity hoard
|
|
970
|
+
(askr · brokkforge · dvalin · mannheim · muninn · runestone · utgard · wayof ·
|
|
971
|
+
ymirlabs), realm field unified to `wayof`, repo paths corrected to this
|
|
972
|
+
machine. `data/realm.md` now pins `wayof` (was drifting between `way-of`,
|
|
973
|
+
`wayof`, and `default`; hoard cards + persona updated to match).
|
|
974
|
+
- **Hood:** `svartalfaheim/wayof/HOOD.md` is the map of the hoard and the
|
|
975
|
+
seat; `bin/saga-session-start.sh` stage 6 (context digest) now prints
|
|
976
|
+
`--- hood ---` whole from the realm seat, so a session opens knowing the
|
|
977
|
+
operator's holdings. Living overviews: `workspace/company/wayof-overview.md`
|
|
978
|
+
and `workspace/company/aigf.md` (hodd stays the private store; the realm
|
|
979
|
+
points at it).
|
|
980
|
+
- **Verified:** `bash -n` green; realm-lib resolves `wayof`; `realm env:
|
|
981
|
+
present`.
|
|
982
|
+
|
|
983
|
+
## 2026-09-13 — Gleipnir sees when an agent is turned off
|
|
984
|
+
|
|
985
|
+
- **Problem:** the machine lock stuck “held by another Brokk session” forever.
|
|
986
|
+
Nothing released it ( `gleipnir_lock_release` had zero callers; Pi's exit
|
|
987
|
+
hook only stopped the arm child), and liveness was `kill(0)` alone — which
|
|
988
|
+
reports a zombie (dead but unreaped) and a recycled pid as alive, so an
|
|
989
|
+
agent you turned off kept the helm until its pid happened to look gone.
|
|
990
|
+
Worse, the Sessrúmnir desktop RPC session holds the live lock yet never
|
|
991
|
+
arms supervision (no turn ever calls `gna_watch_arm`), stranding every
|
|
992
|
+
other session read-only.
|
|
993
|
+
- **Fix:** `bin/gleipnir-lock-lib.sh` now records the owner's starttime in a
|
|
994
|
+
`brokk.lock.starttime` sidecar and reaps a holder whose `/proc/<pid>/stat`
|
|
995
|
+
state is `Z`/`X` or whose starttime no longer matches (pid reuse) — dead,
|
|
996
|
+
zombie, and recycled holders are cleared at session start/acquire. Gná
|
|
997
|
+
(`gna-pi-watch.ts`) mirrors that liveness, reclaims a stale lock directly in
|
|
998
|
+
`gna_watch_arm` (`missing` no longer punts to saga-session-start.sh), and
|
|
999
|
+
drops its own lock on real process exit (`releaseLockIfOwned`); the turn-end
|
|
1000
|
+
guard (`syn-turnend-guard.ts`) uses the same zombie-aware check.
|
|
1001
|
+
- **Impact:** turning an agent off — cleanly, by kill (zombie), or after pid
|
|
1002
|
+
reuse — frees the machine lock for the next session. The live desktop seat
|
|
1003
|
+
still holds it until that app is closed or its own session arms; that is the
|
|
1004
|
+
law (one live primary per machine), but it now releases and hands off
|
|
1005
|
+
correctly.
|
|
1006
|
+
## 2026-09-13 — the cloth reaches all three halls (Hlidskjalf · Smíðja · the seat)
|
|
1007
|
+
|
|
1008
|
+
- **One look, one source.** The carved cloth (the landing page's `:root`) now
|
|
1009
|
+
dresses every hall, each through its own thin adapter, and `docs/design.md`
|
|
1010
|
+
gained §0 *The cloth* plus the re-cut §4.1/§4.2 tables — the contract, not a
|
|
1011
|
+
wish. `midgard/design-system/tokens.css` keeps every `--ymir-*` **name** and
|
|
1012
|
+
changes only the values: stone `#0e0c09`/`#151209`/`#1a1610`/`#221d14`, bone
|
|
1013
|
+
text `#cfc3a9`/`#9a8f75`/`#6b6250`, bronze `#c9973f` accent with `#7d5f2a` as
|
|
1014
|
+
the brass rule, blood `#c2584a` danger, steel `#96a0a8` ok, brass bevel
|
|
1015
|
+
`inset 0 0 0 1px rgba(201,151,79,.12)`.
|
|
1016
|
+
- **Type.** Cormorant (display), Newsreader (body), IBM Plex Mono (data) — the
|
|
1017
|
+
landing's three faces — with Noto Sans Runic appended to every stack so runes
|
|
1018
|
+
fall through to the rune family. Hlidskjalf loads them from Google Fonts; the
|
|
1019
|
+
visualizer bundles them from `@fontsource` (its `@fontsource/play` is gone).
|
|
1020
|
+
- **Hlidskjalf:** 24 old-palette `rgba()` literals and every role hex in the
|
|
1021
|
+
stylesheets now read tokens (`color-mix(… var(--ymir-ok) …)`); workspace tints
|
|
1022
|
+
are cloth (work bronze, personal steel); the `HallsChooser` cards no longer name
|
|
1023
|
+
two tokens that never existed (`--ymir-line`/`--ymir-panel`); the login's GitHub
|
|
1024
|
+
button is a bone plate; the realm-tint fallbacks in `global.css` follow.
|
|
1025
|
+
- **Smíðja's eye:** the default theme is **fensalir** (the titlebar toggle cycles
|
|
1026
|
+
fensalir → classic → high-contrast, both overrides still winning); 77 hexes and
|
|
1027
|
+
62 `rgba()`s across the components were recast onto the theme's own tokens; the
|
|
1028
|
+
categorical event/lane palettes (`src/lib/events.ts`) were re-cut onto the cloth
|
|
1029
|
+
while staying mutually distinct.
|
|
1030
|
+
- **Sessrúmnir:** text selection is now a **theme token**
|
|
1031
|
+
(`--color-selection-bg`/`-fg`) — the landing's amber `#57411a` on pale bone
|
|
1032
|
+
`#f0e6cd` — carried in `fensalir`/`sessrumnir` and derived per theme for
|
|
1033
|
+
everyone else; the global rule sits in `@layer base`, and the CodeMirror editor
|
|
1034
|
+
needs a second unlayered rule because CodeMirror paints its selection layer with
|
|
1035
|
+
unlayered CSS that beats any layered rule. A **To the Hall** button joins the
|
|
1036
|
+
status bar (local `:4322` when it answers, else `hall.ymir.zerw.org`, resolved in
|
|
1037
|
+
the main process).
|
|
1038
|
+
- **Heraldry is not chrome:** the eight house/domain seals and the Emblem keep
|
|
1039
|
+
their own colours — exactly as the landing page keeps its house seals.
|
|
1040
|
+
- **Geometry is untouched** (radius, spacing, the shell): the carved-slate
|
|
1041
|
+
squaring remains an open question for the Allfather.
|
|
1042
|
+
- **Verified:** `tsc` clean and `npm run build` green in Hlidskjalf; the
|
|
1043
|
+
visualizer builds under `vue-tsc`; Sessrúmnir's build, lint, theme tests and
|
|
1044
|
+
semantic-colour check green. Headless passes: Hlidskjalf's gates render with
|
|
1045
|
+
**0 console errors** (login, fleet, tasks, processes, reviews, runtime, cron,
|
|
1046
|
+
stats), and the visualizer loads with 0 console problems.
|
|
1047
|
+
|
|
1048
|
+
## 2026-09-13 — the carved cloth reaches the seat-hall (Sessrúmnir)
|
|
1049
|
+
|
|
1050
|
+
- **The landing's cloth is now the seat's own look.** Every semantic token in
|
|
1051
|
+
`apps/sessrumnir/src/renderer/src/index.css` `@theme` was mapped to its carved
|
|
1052
|
+
twin from the landing page's `:root` (`CodeP/ymir-homepage/src/lore.html`):
|
|
1053
|
+
stone `#0e0c09` (app) with panels `#151209`/`#1a1610`/`#14100b`, bone text
|
|
1054
|
+
`#cfc3a9`/`#9a8f75`/`#6b6250` (faint/ghost as bone washes), bronze
|
|
1055
|
+
`#c9973f` accent and `#7d5f2a` brass rule for `border-strong`, blood
|
|
1056
|
+
`#c2584a`/`#7c3a30` for error, steel `#96a0a8` for success. Semantic names are
|
|
1057
|
+
unchanged — only the values moved.
|
|
1058
|
+
- **Fensalir** (the weaving halls) is registered as a built-in theme
|
|
1059
|
+
(`themes/fensalir.json`, id `fensalir`, appended to `BUILTIN_THEME_IDS` — an
|
|
1060
|
+
additive change that keeps every persisted id resolving). The seat's own
|
|
1061
|
+
built-in `sessrumnir` theme was carved to the same cloth, so the default look
|
|
1062
|
+
of an existing profile is the cloth on restart. A new test holds the two
|
|
1063
|
+
together (`the cloth is one`) and another holds the CSS `@theme` base to the
|
|
1064
|
+
theme file (`never drift`).
|
|
1065
|
+
- **Cloth is the default, not a cage:** the ThemeEngine's ordering is untouched —
|
|
1066
|
+
every other built-in theme, any user theme, and `high-contrast` still win when
|
|
1067
|
+
chosen.
|
|
1068
|
+
- **Type:** Cormorant (display), Newsreader (body), IBM Plex Mono (mono) bundled
|
|
1069
|
+
from `@fontsource*` (offline, `font-src 'self'`), with Inter/JetBrains Mono
|
|
1070
|
+
kept as glyph fallbacks; the landing's carved syntax palette (`--cm-*`) rides
|
|
1071
|
+
along in the theme files.
|
|
1072
|
+
- **Honest repairs on the way:** 29 raw `text-white` literals sat on token
|
|
1073
|
+
fills where white cannot be read on bronze (2.6:1). They now read the token
|
|
1074
|
+
that means "the rune on the filled plate" — `text-inverse` on `bg-accent`,
|
|
1075
|
+
`text-primary` on the dark blood `bg-error` — and the settings toggle knob is
|
|
1076
|
+
carved (stone when lit, bone when unlit). No colour literals remain in
|
|
1077
|
+
components.
|
|
1078
|
+
- **Paper:** `apps/sessrumnir/AGENTS.md` and `README.md` no longer claim the old
|
|
1079
|
+
sky-on-navy palette; they describe the cloth and its rules.
|
|
1080
|
+
|
|
1081
|
+
## 2026-09-13 — the new tree, the mesh, the seat-hall
|
|
1082
|
+
|
|
1083
|
+
- **Everything in the new tree:** the Sessrúmnir work plus the orphaned fixes
|
|
1084
|
+
were migrated from the `ymir-old` working tree into this canonical tree —
|
|
1085
|
+
`apps/sessrumnir/` (deps vendored locally, never committed), the two
|
|
1086
|
+
`bin/sessrumnir-*.sh` scripts, `step_sessrumnir` in `bin/ymir-install.sh`,
|
|
1087
|
+
the Hoard registry entry, the `installation.md` asset, and the
|
|
1088
|
+
`syn-watch-arm.js` continuity fix (re-arm when `.supervision-armed` exists
|
|
1089
|
+
even with no task metadata). The superseded self-service register-gate work
|
|
1090
|
+
was **not** ported — this tree's committed invite-gate is canonical.
|
|
1091
|
+
- **Full install ran green** in the new tree: every step OK, invite minted
|
|
1092
|
+
(`YMIR-DBN4-FXEX`), all five services up, `bin/ymir-validate.sh` 11/11 PASS.
|
|
1093
|
+
- **Ratatoskr mesh healed:** the `a2abridge` engine (MIT,
|
|
1094
|
+
`vbcherepanov/a2abridge` v3.0.0) is installed at `~/.a2abridge/bin/`, its
|
|
1095
|
+
directory daemon runs on `127.0.0.1:7777`, and `bin/ratatoskr.sh
|
|
1096
|
+
status|doctor` pass. Forged `bin/a2abridge-ensure.sh` (installs the engine,
|
|
1097
|
+
patches the systemd unit's unwritable `/var/log` log paths to journal,
|
|
1098
|
+
keeps the directory up) and wired it into migration `0002-a2a-mcp.sh`, so
|
|
1099
|
+
every install/update heals the mesh instead of leaving a dangling MCP path.
|
|
1100
|
+
- **MCP bridges fixed:** `engram-mcp` failed at startup (its Python env
|
|
1101
|
+
lacked the `mcp` SDK; mcp 2.x renamed FastMCP, so it is pinned to `mcp<2`)
|
|
1102
|
+
— the server now initializes against the `kaia.engram` store. `a2abridge`
|
|
1103
|
+
MCP is wired into both pi and opencode via `bin/a2a-mcp.sh install`.
|
|
1104
|
+
- **Docs:** `docs/design.md` §5.4 documents the gate exactly as committed
|
|
1105
|
+
(operator credential + invite-gated registration + GitHub door + httpOnly
|
|
1106
|
+
30-day session); the hlidskjalf-ui skill gained the `register` surface row.
|
|
1107
|
+
|
|
1108
|
+
## 2026-09-13 — Sessrúmnir, the seat-hall
|
|
1109
|
+
|
|
1110
|
+
- **Sessrúmnir adopted:** the Apache-2.0 **pi-desktop** GUI
|
|
1111
|
+
(`FaqFirebase/pi-desktop`, v0.1.7-alpha) is vendored at `apps/sessrumnir/`
|
|
1112
|
+
and rebranded **Sessrúmnir** — the seat-hall where the Allfather converses
|
|
1113
|
+
with the machine. The external engine keeps its product name; the GUI the
|
|
1114
|
+
user sees is Sessrúmnir, themed with the way-of palette (sky `#38bdf8` on
|
|
1115
|
+
deep navy) as the new default built-in theme. Window titles, launcher,
|
|
1116
|
+
package identity, tray/autostart strings, data-dir name, and the Pi logo
|
|
1117
|
+
(now a Sowilo rune bolt) are rebranded; upstream `LICENSE` is preserved and
|
|
1118
|
+
`NOTICE` records the adoption.
|
|
1119
|
+
- **Forge scripts:** `bin/sessrumnir-ensure.sh` (status/ensure/install — deps
|
|
1120
|
+
are never committed, installed on first run with the electron-binary heal
|
|
1121
|
+
`scripts/electron.sh` already uses) and `bin/sessrumnir.sh`
|
|
1122
|
+
(start/status/stop with a workspace argument).
|
|
1123
|
+
- **Install wiring:** `bin/ymir-install.sh` gains a `sessrumnir` step (after
|
|
1124
|
+
`hermes`) and lists Sessrúmnir in `workspace/INSTALL.md`; the
|
|
1125
|
+
`installation.md` asset's step table, adopted-engines table, and Hermes-style
|
|
1126
|
+
section are updated in the same change.
|
|
1127
|
+
- **Registry & audit:** the Hoard registry (`hodd/identity/projects.yaml`)
|
|
1128
|
+
gains the `sessrumnir` project (upstream remote); the adoption is inscribed
|
|
1129
|
+
in Runes.
|
|
1130
|
+
- **Not yet installed:** `apps/sessrumnir/node_modules` is absent — run
|
|
1131
|
+
`bin/sessrumnir-ensure.sh install` when ready.
|
|
1132
|
+
|
|
1133
|
+
### 2026-09-13 — the seat-hall raised
|
|
1134
|
+
|
|
1135
|
+
- `bin/sessrumnir-ensure.sh install` completed: deps + Electron binary + build
|
|
1136
|
+
all green; full test suite **989/989 pass**, typecheck and lint clean (the
|
|
1137
|
+
`autostart-linux` test was updated for the new brand name). `bin/sessrumnir.sh
|
|
1138
|
+
start` raised the window — Hyprland reports class `sessrumnir`, title
|
|
1139
|
+
`Sessrúmnir`, data under `~/.config/sessrumnir`.
|
|
1140
|
+
|
|
1141
|
+
## 2026-09-12 — The well actually installs (it never did)
|
|
1142
|
+
|
|
1143
|
+
- **The memory engine was never installed by the installer.** `bin/prereq-ensure.sh`
|
|
1144
|
+
had no `engram` target at all, and `bin/ymir-install.sh` only *checked* for it
|
|
1145
|
+
and printed `SKIP "optional — install engine then run bin/mimir-bridge.sh"`. A
|
|
1146
|
+
SKIP never blocks, so the well was silently down on every install.
|
|
1147
|
+
- **The hint named the wrong package.** PyPI's `engram` is an unrelated
|
|
1148
|
+
*rendering* library (mitsuba/drjit/torch): following the hint pulled gigabytes
|
|
1149
|
+
of CUDA wheels and still left no engine. The memory engine's distribution is
|
|
1150
|
+
**`engdbram`**; its module is `engram`. The pre-swap append-only log had the
|
|
1151
|
+
right answer all along (`PyPI engdbram, v2.2.1`).
|
|
1152
|
+
- **Now it installs.** `prereq-ensure.sh engram` installs `engdbram` into an
|
|
1153
|
+
interpreter that can run it (>=3.11; uv supplies 3.12 here), records that
|
|
1154
|
+
interpreter in `~/.config/ymir/engram-python`, and `bin/mimir-bridge.sh` reuses
|
|
1155
|
+
it for both the check and the run. The installer provisions rather than hints,
|
|
1156
|
+
and reports WARN instead of a silent SKIP when it cannot.
|
|
1157
|
+
- **Verified:** `curl 127.0.0.1:4602/health` -> `{"status": "up", "store":
|
|
1158
|
+
".agents/memory/kaia.engram"}`; `.agents/skills/lifecycle/smoke_test.sh` exits 0
|
|
1159
|
+
with all five checks green.
|
|
1160
|
+
|
|
1161
|
+
## 2026-09-12 — The dashboards stop crash-looping on the iGPU
|
|
1162
|
+
|
|
1163
|
+
- **`scripts/electron.sh` decides its own GPU path.** Both dashboards appeared to
|
|
1164
|
+
work while `coredumpctl` filled with SIGSEGV cores from
|
|
1165
|
+
`electron --type=gpu-process`. An iGPU backs its graphics memory with system
|
|
1166
|
+
RAM (GTT), a local model served on that same iGPU held 5.8-8.0 GiB of it, and
|
|
1167
|
+
the amdgpu driver then failed the desktop's command submissions — which
|
|
1168
|
+
Electron turned into a NULL dereference at a constant offset. Only the GPU
|
|
1169
|
+
process died, so the windows stayed up and the failure was easy to miss.
|
|
1170
|
+
`igpu_vram_small()` now reads the render device's VRAM carve-out and switches
|
|
1171
|
+
to software rendering under `YMIR_IGPU_VRAM_SMALL_MIB` (default 2048). The old
|
|
1172
|
+
comment promised this auto-detect; now it exists. `YMIR_DESKTOP_DISABLE_GPU`
|
|
1173
|
+
still overrides, both ways.
|
|
1174
|
+
- **Verified:** with the fix, the amdgpu submission errors stop and the
|
|
1175
|
+
gpu-process runs SwiftShader (`--use-angle=swiftshader-webgl`) rather than the
|
|
1176
|
+
hardware path; no new cores.
|
|
1177
|
+
|
|
1178
|
+
## 2026-09-12 — The editor keeps its own seat
|
|
1179
|
+
|
|
1180
|
+
- **`open-editor.ts` seats the editor in Þjazi:** inside herdr, `/edit` and
|
|
1181
|
+
`ctrl+shift+e` now open the Allfather's editor in its **own tab** of the home
|
|
1182
|
+
workspace (`herdr tab create --focus` + `herdr pane run`, label
|
|
1183
|
+
`ymir:edit[:<base>]`, recorded in `state/herdr-seats` for `close-all`) instead
|
|
1184
|
+
of suspending the pi session — the agent no longer dies when the editor
|
|
1185
|
+
opens. Outside herdr the old roads remain: GUI editors launch detached,
|
|
1186
|
+
terminal editors suspend the TUI and resume on exit.
|
|
1187
|
+
- **`open-editor.ts` shows hidden files:** the picker and `/edit`
|
|
1188
|
+
tab-completion now merge the git listing with a bounded walk, so gitignored
|
|
1189
|
+
dotfiles (`.env.local`, `.env.realm`, …) are openable too.
|
|
1190
|
+
|
|
1191
|
+
## 2026-09-11 — Omarchy-first: host skills, machine learning, native fixes
|
|
1192
|
+
|
|
1193
|
+
- **New skill `ymir-omarchy`:** Omarchy-native operation — the two laws (never
|
|
1194
|
+
edit `/usr/share/omarchy/`; Hyprland owns placement), host detection, the
|
|
1195
|
+
monitor/scale coordinate trap, the amdgpu GPU crash and mitigation, desktop-app
|
|
1196
|
+
placement, and a safe-customisation table.
|
|
1197
|
+
- **New skill `ymir-thjazi`:** Þjazi (herdr-first) — protocol floors (14+ panes,
|
|
1198
|
+
0.8.0 presentation spaces), verification, installation.
|
|
1199
|
+
- **Ymir learns the host:** `bin/omarchy-sense.sh` snapshots and *diffs* the
|
|
1200
|
+
machine (Omarchy version, explicit packages, config files, monitors, scale) into
|
|
1201
|
+
`state/omarchy-setup.json`; `bin/omarchy-hook-install.sh` adds an Omarchy
|
|
1202
|
+
`post-update` hook so it re-learns after every `omarchy update`.
|
|
1203
|
+
- **Þjazi in the installer:** `bin/herdr-ensure.sh` + new `step_backend`
|
|
1204
|
+
(herdr, else tmux — never a silent fallback).
|
|
1205
|
+
- **New `step_omarchy`** (SKIP on a non-Omarchy host).
|
|
1206
|
+
- **Desktop fixes:** window placement is now LOGICAL and work-area clamped, and
|
|
1207
|
+
prefers a non-primary display (the old math used physical pixels on a scale-1.5
|
|
1208
|
+
panel and filled the screen). Apps are identified by their command line, not the
|
|
1209
|
+
`.bin/electron` shim pid — which fixes the **double-launch** bug. `stop` kills
|
|
1210
|
+
every matching pid.
|
|
1211
|
+
- **GPU mitigation:** `YMIR_DESKTOP_DISABLE_GPU=1` adds
|
|
1212
|
+
`--disable-gpu --disable-gpu-compositing` for small-VRAM iGPUs (the crash was
|
|
1213
|
+
`amdgpu: Not enough memory for command submission`, SIGSEGV, not an OOM).
|
|
1214
|
+
- **Per-machine state un-shared:** `.agents/memory/kaia.engram*` and
|
|
1215
|
+
`well/*.jsonl` were tracked and pushed (one machine's private memory + volatile
|
|
1216
|
+
SQLite sidecars). Now gitignored and untracked; the contract is written in
|
|
1217
|
+
`.agents/memory/README.md`.
|
|
1218
|
+
- **Assets updated:** `installation.md` (15 rows, consent, validation, Omarchy),
|
|
1219
|
+
`hlidskjalf-ui.md` (the desktop-apps section).
|
|
1220
|
+
- **Verified:** full install green (15 rows; only the docker-group WARN), 9/9
|
|
1221
|
+
compliance, both skills registered.
|
|
1222
|
+
|
|
1223
|
+
## 2026-09-11 — Load the owning asset before editing a governed path (5 layers)
|
|
1224
|
+
|
|
1225
|
+
The runtime drifted from its documentation because the asset that governs a
|
|
1226
|
+
subsystem was never loaded before the code changed. Five layers now prevent it:
|
|
1227
|
+
|
|
1228
|
+
- **1. `AGENTS.md`:** a new `governed[6]` table maps each governed path to the
|
|
1229
|
+
asset to load first, and `manual[]` gained `installation`, `ui`, `runtime-spec`.
|
|
1230
|
+
- **2. Session digest:** `saga-session-start.sh` prints an `ASSET ROUTING` block
|
|
1231
|
+
every session, so the mapping is always in context.
|
|
1232
|
+
- **3. Router loadable:** `galdr`'s `disable-model-invocation` is removed (it hid
|
|
1233
|
+
the one router that owns the assets); `tyr-check` keeps it (deliberate).
|
|
1234
|
+
- **4. Enforced seatbelt:** new `bin/syn-asset-pretool-check.sh` denies an
|
|
1235
|
+
`edit`/`write` of a governed path until its asset was read (`state/asset-reads`);
|
|
1236
|
+
the Pi extension relays it and records asset reads.
|
|
1237
|
+
- **5. Compliance gate:** `compliance-check.sh` gains an `assets` check that
|
|
1238
|
+
FAILS when a governed path changed without its asset (it caught this very
|
|
1239
|
+
change), and `runtime-compliance.md` documents G12 + the routing map.
|
|
1240
|
+
|
|
1241
|
+
## 2026-09-11 — Automate the install: consent gate, self-healing prereqs, visualizer-ready
|
|
1242
|
+
|
|
1243
|
+
- **Consent gate:** a real install now prints its plan and waits for the operator
|
|
1244
|
+
to accept (`[y/N]`). Declining changes nothing (exit 3). `--check` still previews
|
|
1245
|
+
without asking; non-interactive callers must pass `--yes`.
|
|
1246
|
+
- **New `bin/prereq-ensure.sh`:** self-healing prerequisites in USER SPACE —
|
|
1247
|
+
installs `bun` and `uv` via their official installers, `mcp<2>` via pip, and can
|
|
1248
|
+
fetch a specific Python (e.g. `3.12`) with uv for packages that need one.
|
|
1249
|
+
- **New `bin/smidja-bootstrap.sh`:** creates `smidja/smidja_data/smidja.db` from
|
|
1250
|
+
the tracer's own schema and seeds a bootstrap session, so the Smíðja visualizer
|
|
1251
|
+
has data from the first install. Fixed: it now bootstraps on a bare call
|
|
1252
|
+
instead of printing help, and reports failure honestly when the DB is absent.
|
|
1253
|
+
- **`bin/ymir-install.sh`:** new `smidja` step; prerequisites delegated to the
|
|
1254
|
+
self-healing helper; `engram` reported as an honest optional `SKIP` with the
|
|
1255
|
+
exact next command; docker-group-permission and build-failure distinguished.
|
|
1256
|
+
- **Verified:** consent refuse/accept/decline paths; smidja db created and read
|
|
1257
|
+
back (8 tables, bootstrap session); compliance 8/8.
|
|
1258
|
+
|
|
1259
|
+
## 2026-09-11 — Smooth install: provider choice, no forced key, real prereqs
|
|
1260
|
+
|
|
1261
|
+
- **Model provider is now the operator's choice** (`YMIR_MODEL_PROVIDER`):
|
|
1262
|
+
`opencode-go` (needs a key), `lmstudio` (keyless local), or
|
|
1263
|
+
`openai-compatible`. The bridge no longer forces `OPENCODE_GO_API_KEY`;
|
|
1264
|
+
with no key it auto-selects the keyless local provider so a fresh install works.
|
|
1265
|
+
- **New:** `.agents/backend/model-bridge.py` (provider-aware, keyless-capable);
|
|
1266
|
+
`opencode-go-bridge.py` kept as a delegating shim so existing references work.
|
|
1267
|
+
- **`bin/bifrost-bridge.sh` v2:** `--provider`, provider auto-selection, no hard
|
|
1268
|
+
env-file requirement, actionable errors per provider.
|
|
1269
|
+
- **`bin/ymir-install.sh`:** installs `bun` for real (user-space, then a package
|
|
1270
|
+
hint); installs `mcp<2`; `engram` is now an honest `SKIP` with the Python
|
|
1271
|
+
version reason instead of a permanent WARN; distinguishes docker-group
|
|
1272
|
+
permission from a build failure.
|
|
1273
|
+
- **`scripts/start.sh`:** fixed the early exit that skipped the gate API and all
|
|
1274
|
+
services whenever the SPA was already running.
|
|
1275
|
+
- **Verified:** compliance 8/8; bridge relays models + chat + 404s; keyless
|
|
1276
|
+
start confirmed; `start.sh` raises Gate API, Nornir, Bifrost, visualizer.
|
|
1277
|
+
|
|
1278
|
+
## 2026-09-11 — Single-tenant workspaces shipped
|
|
1279
|
+
|
|
1280
|
+
- **First setup:** `bin/ymir-install.sh` (8 steps) + `bin/workspace-provision.sh`.
|
|
1281
|
+
- **Model:** single tenant; workspaces (personal|work) over domains; houses = brands.
|
|
1282
|
+
- **UI:** Login onboarding (name/kind/domains), Topbar workspace chip, AccountMenu/Profile relabelled.
|
|
1283
|
+
- **Engines:** treehouse → `yggdrasil.sh pool`; sandcastle → `utgard.sh sandcastle`; no-mistakes → Mjollnir gate.
|
|
1284
|
+
- **GitHub:** `bin/project-git.sh` reads `workspace/projects.yaml` `git{}`.
|
|
1285
|
+
- **Verified:** build green, compliance 8/8, smoke 8/8, lint 4/4.
|
|
1286
|
+
|
|
1287
|
+
All significant runtime, policy, and architectural changes for the Ymir platform.
|
|
1288
|
+
Entries are appended chronologically; never rewritten.
|
|
1289
|
+
|
|
1290
|
+
## 2026-09-11 — Hardcoded per-page feeds (header + stream)
|
|
1291
|
+
|
|
1292
|
+
- **New:** every gate has its own hardcoded, domain-appropriate rolling feed
|
|
1293
|
+
(16 pools, `src/data/feeds.ts`) — Fleet, Tasks, Well, Runes, Reviews,
|
|
1294
|
+
Processes (Valhalla), Files, Chat, Forge, Runtime, Cron, Sessions, Trace,
|
|
1295
|
+
Decisions, Stats, Profile. Extra Kaia “oracle by the well” lines for the chat
|
|
1296
|
+
page.
|
|
1297
|
+
- **Header:** a live `PageFeed` now sits in the page header of every gate
|
|
1298
|
+
(glyph + hint on the left, the current page's latest 3 messages on the
|
|
1299
|
+
right), rolling.
|
|
1300
|
+
- **Stream:** the bottom Stream keeps each page's last **40** domain messages,
|
|
1301
|
+
with the fleet-wide feed as fallback. A generator tops it up every 2.4s and
|
|
1302
|
+
the page is seeded on first visit so it is never cold.
|
|
1303
|
+
- **Verified:** `tsc` + `vite build` green, SPA 200, compliance 8/8, smoke 8/8,
|
|
1304
|
+
lint 4/4.
|
|
1305
|
+
|
|
1306
|
+
## 2026-09-11 — Per-page rolling 40 message feeds
|
|
1307
|
+
|
|
1308
|
+
- **Change:** the bottom stream is no longer one global 120-line feed. Every gate
|
|
1309
|
+
keeps its own rolling window of the **last 40** messages, and events are routed
|
|
1310
|
+
to the page they belong to (module → gate: `well`, `sessions`, `forge`,
|
|
1311
|
+
`runes`, `cron`, `reviews`, `processes`), with the fleet-wide feed as fallback.
|
|
1312
|
+
The stream header shows the current page. `STREAM_WINDOW = 40`, matching the
|
|
1313
|
+
chat's `CHAT_WINDOW = 40`.
|
|
1314
|
+
- **Verified:** `tsc` + `vite build` green, SPA 200.
|
|
1315
|
+
|
|
1316
|
+
## 2026-09-11 — Galdr/Tyr assets: symlink, not copies
|
|
1317
|
+
|
|
1318
|
+
- **Fix:** `tyr-check/assets` is now a **symlink** to the canonical
|
|
1319
|
+
`galdr/assets`, so the two can never drift. A background process had been
|
|
1320
|
+
rewriting the registry, flipping the sync gate red; a symlink makes drift
|
|
1321
|
+
structurally impossible. Compliance back to 8/8 stable.
|
|
1322
|
+
- **Verified:** compliance 8/8, smoke 8/8, lint 4/4.
|
|
1323
|
+
|
|
1324
|
+
## 2026-09-11 — Chat uses the root Pi model catalog
|
|
1325
|
+
|
|
1326
|
+
- **Fix:** the Kaia chat guessed a llama.cpp model id by regex and fell through
|
|
1327
|
+
to the Bifrost bridge (`:4603` → 401) when the guess failed.
|
|
1328
|
+
- **Now:** the gate API reads the operator's root Pi catalog
|
|
1329
|
+
(`~/.pi/agent/models.json`) for the exact provider → base URL, model id, and
|
|
1330
|
+
key (llama.cpp router `:8080`, `sk-not-key-required`). A chosen local model
|
|
1331
|
+
is tried only on its own base; the default is the operator's Pi default
|
|
1332
|
+
(`qwen3.6-35b-a3b@iq3_s`). `/api/chat/models` lists the real connected set.
|
|
1333
|
+
- **Verified:** `gemma-4-12b@q3_k_s`, `qwen3.6-35b-a3b@iq3_s` (default), and
|
|
1334
|
+
`qwen3.5-9b@q4_k_s` all answered live; no 401.
|
|
1335
|
+
|
|
1336
|
+
## 2026-09-11 — Shared well for every harness; no mock; clickable memories
|
|
1337
|
+
|
|
1338
|
+
- **Harnesses:** the engram MCP server is now registered for all four OpenCode
|
|
1339
|
+
accounts (`opencode`, `opencode-rd`, `opencode-work`, `opencode-oczer`), Pi
|
|
1340
|
+
(`~/.pi/agent/settings.json` + `mcp.json` + `.pi/mcp.json`), Claude, Cursor,
|
|
1341
|
+
and Codex. Registered **unscoped** so every harness reads the one shared well
|
|
1342
|
+
(per-call `agent_id` still attributes writes).
|
|
1343
|
+
- **No mock:** purged every test/mock episode (`smoke`/`Test observation`) from
|
|
1344
|
+
both the engram store and `episodes.jsonl` → 367 true episodes. Test writes
|
|
1345
|
+
never enter the well.
|
|
1346
|
+
- **UI:** Well memories are now **clickable** — `GET /api/well/episode?id=` and
|
|
1347
|
+
a bridge `/episode` endpoint feed a modal with the full memory text.
|
|
1348
|
+
- **Bridge fix:** `/recent` and `/recall` restored; added `/episode`.
|
|
1349
|
+
- **Lifecycle fix:** `bifrost-bridge.sh` / `mimir-bridge.sh` now stop by process
|
|
1350
|
+
match when the PID file is missing, and record the PID when the port is
|
|
1351
|
+
already up — so `scripts/stop.sh` truly lowers the whole system and
|
|
1352
|
+
`scripts/start.sh` truly raises it.
|
|
1353
|
+
- **Galdr:** new asset `.agents/skills/galdr-ymirsystem/assets/memory-well.md` (store,
|
|
1354
|
+
bridge, MCP, harness matrix, laws, verify), routed in `SKILL.md`; registry +
|
|
1355
|
+
harness README updated; mirrored to tyr.
|
|
1356
|
+
- **Verified:** MCP recall 1.0 / stats 367, full stop→start cycle (3888/3889/
|
|
1357
|
+
4602/4603/8437), compliance 8/8, smoke 8/8.
|
|
1358
|
+
|
|
1359
|
+
## 2026-09-11 — The well is real (Mimirsbrunn / engram)
|
|
1360
|
+
|
|
1361
|
+
- **New:** `bin/mimir-bridge.py` + `bin/mimir-bridge.sh` — the `:4602` HTTP face
|
|
1362
|
+
the supervision tree named but that upstream never shipped (engram exposes a
|
|
1363
|
+
CLI + MCP server only). Endpoints: `/health`, `/recall`, `/recent`,
|
|
1364
|
+
`/timeline`, `/inspect`, `/observe`.
|
|
1365
|
+
- **New:** repo-local store `.agents/memory/kaia.engram`, seeded from the
|
|
1366
|
+
368-episode JSONL well.
|
|
1367
|
+
- **Wired:** gate API `/api/well` now does semantic recall via the bridge (local
|
|
1368
|
+
file fallback) and `/api/mimir/health` is live; the Well gate's Bridge tile
|
|
1369
|
+
and timeline read real data (mock removed).
|
|
1370
|
+
- **Harnesses:** the engram MCP server is registered for OpenCode, Pi, Claude,
|
|
1371
|
+
Cursor, and Codex; requires the `mcp<2` SDK (`engram-mcp` breaks on mcp 2.x).
|
|
1372
|
+
- **Lifecycle:** the bridge is raised by `scripts/start.sh` and
|
|
1373
|
+
`bin/saga-session-start.sh`; the stale `engram.server` command was corrected.
|
|
1374
|
+
- **Verified:** bridge up (370 episodes), semantic recall, MCP handshake
|
|
1375
|
+
(engram 1.30), compliance 8/8, smoke 8/8.
|
|
1376
|
+
|
|
1377
|
+
## 2026-09-11 — Stats 1:1, Kaia chat, Forge prompts
|
|
1378
|
+
|
|
1379
|
+
- **Stats:** ported the full Smiðja `StatsResponse` 1:1 into the gate API and
|
|
1380
|
+
the Stats gate — runs/success/fail/running/rate, token optimization
|
|
1381
|
+
(input/output/cache_read/cache_write, cache-hit ratio, avg CHR/run),
|
|
1382
|
+
local-vs-online provider split with per-model table, 40-model commercial
|
|
1383
|
+
catalog (cached/total/savings/%), by-chain and by-workflow. A real run
|
|
1384
|
+
renders live.
|
|
1385
|
+
- **Chat (Kaia):** per-session JSONL store (`state/chat/`), list/history/delete
|
|
1386
|
+
endpoints, a rolling **40-message** window, query-grounded well recall before
|
|
1387
|
+
every dispatch, an animated "Kaia is thinking…" indicator, a session sidebar
|
|
1388
|
+
(new/switch/delete), a connected-model datalist (314 models) with free-type,
|
|
1389
|
+
and Eindri lane toggles.
|
|
1390
|
+
- **Forge:** a Prompts mode to read/edit the smithy's
|
|
1391
|
+
`prompt_engineering/<agent>/{system,user}.md` (path-guarded save) and a
|
|
1392
|
+
connected-model datalist for agent models.
|
|
1393
|
+
- **Verified:** `tsc` + `vite build` green, live chat via local model with
|
|
1394
|
+
recall on, prompt roundtrip + traversal guard, compliance 8/8, smoke 8/8,
|
|
1395
|
+
lint 4/4.
|
|
1396
|
+
|
|
1397
|
+
## 2026-09-11 — Smiðja views are repo-local
|
|
1398
|
+
|
|
1399
|
+
- **Change:** Removed the last external dependency. `bin/factory-observe.sh`
|
|
1400
|
+
(which defaulted to `~/command/factory/factory_data/factory.db`) is gone;
|
|
1401
|
+
`bin/smidja-observe.sh` reads the repo's own
|
|
1402
|
+
`smidja/smidja_data/smidja.db` read-only and reports absence honestly.
|
|
1403
|
+
- **API:** `/api/factory` replaced by `/api/smidja/{health,sessions,sessions/:id,decisions,stats}`
|
|
1404
|
+
(`bun:sqlite`, read-only).
|
|
1405
|
+
- **UI:** four Hlidskjalf gates added — Sessions, Trace, Decisions, Stats —
|
|
1406
|
+
reading the smithy's trace. No `command`/`factory` references remain in the
|
|
1407
|
+
runtime or portal.
|
|
1408
|
+
- **Verified:** `tsc` + `vite build` green, SPA 200, endpoints honest-absent,
|
|
1409
|
+
Galdr compliance 8/8, smoke 8/8.
|
|
1410
|
+
|
|
1411
|
+
## 2026-09-11 — Gleipnir lock PID binding fix
|
|
1412
|
+
|
|
1413
|
+
- **Problem:** The session lock (`state/.lock`) was written with the digest
|
|
1414
|
+
helper's PID (a short-lived child) instead of the live Pi harness PID. The
|
|
1415
|
+
harness adapter (`gna-pi-watch.ts`) reported "no live session holds the lock"
|
|
1416
|
+
and refused to arm the watcher.
|
|
1417
|
+
- **Root cause:** `BROKK_SESSION_PID` was never injected into the spawn chain.
|
|
1418
|
+
`gleipnir_lock_acquire` fell back to `$$` (helper PID).
|
|
1419
|
+
- **Fix:** `.pi/extensions/syn-turnend-guard.ts` and
|
|
1420
|
+
`.pi/extensions/gna-pi-watch.ts` now pass `BROKK_SESSION_PID: String(process.pid)`
|
|
1421
|
+
in the spawn env, so the lock binds to the live Pi process.
|
|
1422
|
+
- **Impact:** Session lock reclamation works on next Pi session start/reload.
|
|
1423
|
+
The stale lock (dead PID) is overwritten by the live PID.
|
|
1424
|
+
|
|
1425
|
+
## 2026-09-11 — Desktop shell, tunnel, and temporary auth
|
|
1426
|
+
|
|
1427
|
+
- **Electron:** `apps/hlidskjalf/electron` + `scripts/electron.sh` open Hlidskjalf
|
|
1428
|
+
(and Smiðja) as a native window; raises the stack if down.
|
|
1429
|
+
- **Tunnel:** `ymirdell.zerwiz.org` → `:3889` via `bin/gjallarhorn-tunnel.sh`
|
|
1430
|
+
(cloudflared config in `midgard/infrastructure/ingress/cloudflared-ymir.yml`).
|
|
1431
|
+
- **Auth:** hardcoded HTTP Basic (`zerwiz:allfather`, `HLIDSKJALF_AUTH`) on the
|
|
1432
|
+
gate API, which now also serves the built SPA. Temporary — move to Heimdall +
|
|
1433
|
+
`.env.local`.
|
|
1434
|
+
- **Mobile:** PWA manifest added; recommended APK = Capacitor over the tunnel.
|
|
1435
|
+
|
|
1436
|
+
## 2026-09-12 — Updater forged + credential moved to env
|
|
1437
|
+
|
|
1438
|
+
- **`bin/brokk-update.sh`** — the sanctioned, guarded updater the `ymir-update`
|
|
1439
|
+
skill calls: fast-forward only, refuses a dirty/diverged tree, `--yes` to
|
|
1440
|
+
stash+restore, `--check` to report. Never force-pushes.
|
|
1441
|
+
- **Credential law:** the gate login (`HLIDSKJALF_AUTH`) no longer has an inline
|
|
1442
|
+
default; it is read from `.env.local` (Bun auto-loads it). Server falls back to
|
|
1443
|
+
an open gate only when unset (dev), with the key added to `.env.example`.
|
|
1444
|
+
|
|
1445
|
+
## 2026-09-12 — Ró preference moved out of the tracked tree
|
|
1446
|
+
|
|
1447
|
+
- `.agents/config/ro` was a **git-tracked** per-user toggle (calm on/off); any
|
|
1448
|
+
toggle dirtied the tree and made `bin/brokk-update.sh` refuse. It now lives in
|
|
1449
|
+
the gitignored `state/ro`; `YMIR_RO`/`BROKK_RO` set a default; the legacy
|
|
1450
|
+
`config/ro` is read once for upgrade then never written. Tracked file removed.
|
|
1451
|
+
|
|
1452
|
+
## 2026-09-12 — Fleet preferences
|
|
1453
|
+
|
|
1454
|
+
- `data/fleet.md` (gitignored) holds fleet-wide per-user settings (`ro: on|off`).
|
|
1455
|
+
- `bin/fleet-apply.sh` applies them to this home + every registered Eindri-home
|
|
1456
|
+
(into each home's gitignored `state/`; remote routes reported).
|
|
1457
|
+
- `bin/brokk-update.sh` re-applies fleet preferences on every sweep — one setting
|
|
1458
|
+
reaches the whole fleet, no tracked tree dirtied.
|
|
1459
|
+
|
|
1460
|
+
## 2026-09-12 — House law (RULES/) and the Grein naming
|
|
1461
|
+
|
|
1462
|
+
- New `RULES/` (the house law): `01-domains.md` (house = company; domain = a
|
|
1463
|
+
**Grein**/**Greinar**; Eindri = specialists), `02-agents.md` (agents live only
|
|
1464
|
+
in `.agents/agents`; harness dirs are symlinks; no mock agents), `03-houses.md`
|
|
1465
|
+
(a house is a company — WayOf; the eight Labs are domains, never houses).
|
|
1466
|
+
- Live Fleet de-mocked (real domain/model/status; seeded stats only in demo).
|
|
1467
|
+
|
|
1468
|
+
## 2026-09-14 — A vacant helm is entered, not punted (watcher wake repair)
|
|
1469
|
+
|
|
1470
|
+
- **Problem:** a watcher wake reported the Pi extension could not restore
|
|
1471
|
+
continuity — "this session no longer owns the lock". Root cause found by
|
|
1472
|
+
inspection: an **empty/truncated** machine lock (`~/.local/state/ymir/brokk.lock`)
|
|
1473
|
+
was classified by `gna-pi-watch.ts` `lockOwnership()` as `other` (another
|
|
1474
|
+
live session) and by `bin/syn-watch-arm.sh`'s gate as read-only — so a helm
|
|
1475
|
+
with *no verifiably-live holder* was refused and punted to a manual
|
|
1476
|
+
`saga-session-start.sh` reclaim.
|
|
1477
|
+
- **Fix (both seams in one change):** the extension now classifies an empty
|
|
1478
|
+
lock as `missing`, so `gna_watch_arm`'s reclaim takes the helm in place; the
|
|
1479
|
+
arm script, on finding no owner (or an owner verifiably gone), runs
|
|
1480
|
+
`gleipnir_lock_acquire` itself — which refuses only a genuinely live other
|
|
1481
|
+
session — instead of printing read-only. The "run saga-session-start.sh"
|
|
1482
|
+
punt is gone; a vacant helm is entered by the watcher's own hand.
|
|
1483
|
+
- **Verified:** scratch-state test — empty machine lock → `watcher: started`,
|
|
1484
|
+
lock bound to the session pid + starttime sidecar, `.supervision-armed`
|
|
1485
|
+
touched; `gleipnir-machine-lock.test.sh` ALL PASS (zombie, recycled,
|
|
1486
|
+
migration); compliance 10/10; harness-integration asset updated in the same
|
|
1487
|
+
change (the governed rule).
|
|
1488
|
+
|
|
1489
|
+
## 2026-09-14 — The Eindri→Brokk wake bridge (they can talk back now)
|
|
1490
|
+
|
|
1491
|
+
- **Ask:** the seated smiths' reports lived in their panes only; the Allfather
|
|
1492
|
+
wanted a feature that wakes Brokk when an Eindri reports, so the fleet's
|
|
1493
|
+
doings reach the primary's session — "we are in control, Brokk".
|
|
1494
|
+
- **Built:** `bin/eindri-seen.sh` (condition — a report file landed or herdr
|
|
1495
|
+
shows the smith left `working`), `bin/eindri-acclaim.sh` (action — files the
|
|
1496
|
+
report durably under state/eindri-reports/, marks done under
|
|
1497
|
+
state/eindri-done/, appends the wake to state/.wake-queue for Sága's drain,
|
|
1498
|
+
sounds the desktop note), and `bin/eindri-watch.sh` (the control door —
|
|
1499
|
+
`arm | retire | list | reconcile`, one when-source per smith on the Norns'
|
|
1500
|
+
loom via fm-procevent-when.sh, action hash-bound, fires once on a stable
|
|
1501
|
+
true, terminal, re-armable).
|
|
1502
|
+
- **Armed live:** when-odrerir (already fired — his report was filed) and
|
|
1503
|
+
when-sessrumnir-cloth (still working). `fm-procement.sh reconcile` started=2.
|
|
1504
|
+
- **First report delivered through the wire:** odrerir's Óðrerir saga — deck
|
|
1505
|
+
green at :4322, 52 Chromium checks, commit 38a326b on yggdrasil/odrerir, main
|
|
1506
|
+
untouched, plus the hall.ymir.zerwiz.org server story (setup-hall.sh) and
|
|
1507
|
+
three asks awaiting the Allfather (go live, landing mobile wart, PLAN log).
|
|
1508
|
+
|
|
1509
|
+
## 2026-09-14 — Óðrerir forged (Eindri odrerir, pane w3:p7)
|
|
1510
|
+
|
|
1511
|
+
- The Live Hall carved on the landing per PLAN.md §14: dealt slate pile,
|
|
1512
|
+
choices + recommended marks, freeform, queue + limit guard, thread ledger,
|
|
1513
|
+
live tally, four empty states, fail-closed, keyboard, reveal, mobile (390px,
|
|
1514
|
+
zero overflow); cloth check green; §12 scan clean. Deployed plan for the
|
|
1515
|
+
public hall: hall.ymir.zerwiz.org via a second Caddy site :4322 (deploy/
|
|
1516
|
+
setup-hall.sh + tunnel-ingress.sh, idempotent, live provisioning untested).
|
|
1517
|
+
|
|
1518
|
+
## 2026-09-14 — The echo guard: no wake flood through Gná's door
|
|
1519
|
+
|
|
1520
|
+
- **Problem:** during a loud stretch (stale wake lines + the FM runner's
|
|
1521
|
+
durable queue holding ten old check-wakes), the watcher re-armed and
|
|
1522
|
+
re-signalled "signal: wake queue" across many generations; every actionable
|
|
1523
|
+
close queued one pi follow-up wake (`sendWake`, no dedup), which then
|
|
1524
|
+
dripped at the Allfather one per prompt — a long echo flood after the
|
|
1525
|
+
sources were drained.
|
|
1526
|
+
- **Fix:** `gna-pi-watch.ts` `sendWake` is **echo-guarded**: an identical
|
|
1527
|
+
watcher message is delivered at most once per drained state — when both
|
|
1528
|
+
durable doors (`state/.wake-queue` and the FM runner's
|
|
1529
|
+
`.agents/state/.wake-queue`) are empty, a repeat carry is the same drained
|
|
1530
|
+
news and is skipped. Genuine new content (different message, or a door with
|
|
1531
|
+
a line) always delivers. Harness asset updated in the same change.
|
|
1532
|
+
|
|
1533
|
+
## 2026-09-16 — one login for every app on the web; the gate fronts them all
|
|
1534
|
+
|
|
1535
|
+
- **Every app host is gated**, not just Smíðja. The gate now routes by host from
|
|
1536
|
+
an `APP_HOSTS` table and fronts each one: unauthenticated visitors get that
|
|
1537
|
+
app's own sign-in page, an API path gets 401, and the desktop seat (loopback +
|
|
1538
|
+
marker) walks straight in. Verified: `smidjadell…` → *Smíðja — Sign in*,
|
|
1539
|
+
`odrerirdell…` → *Óðrerir — Sign in*, API 401, desktop seat 200 (the hall).
|
|
1540
|
+
- **Every public hostname points at the gate (:3889)** — never at an app's own
|
|
1541
|
+
port. That was a hole straight past the login: `gjallarhorn-expose.sh` had been
|
|
1542
|
+
exposing each app on its own port, so the app answered the world directly.
|
|
1543
|
+
- **The gate learns the host map at start** (`state/gjallarhorn-hosts.env`,
|
|
1544
|
+
written by the expose script and sourced by `scripts/start.sh`), so routing is
|
|
1545
|
+
not an accident of whoever launched it last.
|
|
1546
|
+
- **No guessed credentials.** The generated tunnel config wrote
|
|
1547
|
+
`credentials-file: …/ymir.json`; cloudflared names that file for the tunnel's
|
|
1548
|
+
UUID, so it refused to start and the world got 530. The line is gone —
|
|
1549
|
+
cloudflared resolves a named tunnel's own credentials.
|
|
1550
|
+
- Verified through the tunnel: `https://ymirdell.zerwiz.org/` → 200. The app
|
|
1551
|
+
hostnames still answer 530: their DNS routes were made against an earlier
|
|
1552
|
+
tunnel and need re-creating (`cloudflared tunnel route dns ymir <host>`).
|
|
1553
|
+
|
|
1554
|
+
## 2026-09-16 — NO BLUE: the forge language replaces the old blue
|
|
1555
|
+
|
|
1556
|
+
The blue had a name. It was the platform's own house tint, `--ymir-house-ymirlabs:
|
|
1557
|
+
#38bdf8`, carried into every surface that wears Ymir's colours — the login, the
|
|
1558
|
+
emblem, the realm data, the Smíðja chrome. The design doctrine (homepage repo,
|
|
1559
|
+
`DESIGN-UNIFICATION-PLAN.md`) says the landing page **is** the language, and that
|
|
1560
|
+
language is **forge**: stone ground (`#0e0c09`), bronze accent (`#c9973f`), bone
|
|
1561
|
+
text (`#cfc3a9`).
|
|
1562
|
+
|
|
1563
|
+
- `midgard/design-system/tokens.css` — the house tint is bronze now, with the
|
|
1564
|
+
reason recorded in the token itself.
|
|
1565
|
+
- The blue's footprints removed: `Emblem.tsx`, `state/store.ts`, `data/realms.ts`
|
|
1566
|
+
(Hlidskjalf), `style.css` (Smíðja visualizer), and Sessrúmnir's terminal accent
|
|
1567
|
+
fallback.
|
|
1568
|
+
- Both built stylesheets rebuilt and verified: **zero blue** in the CSS the browser
|
|
1569
|
+
actually receives (`apps/hlidskjalf/dist`, the visualizer's `dist`).
|
|
1570
|
+
- The visualizer's build was failing on my own earlier edit (unused imports left
|
|
1571
|
+
when I moved `repoRootOf` into `db.ts`) — fixed, so `bun run build` is green.
|
|
1572
|
+
|
|
1573
|
+
The canonical token home is answered by what already exists: `midgard/design-system/`
|
|
1574
|
+
(tokens, icons, `ymir-mark.svg`, `icons.md`) — one source the apps import, so a
|
|
1575
|
+
colour changes once.
|
|
1576
|
+
|
|
1577
|
+
## 2026-09-16 — every app wears its own rune
|
|
1578
|
+
|
|
1579
|
+
The icon set is runecoded (`midgard/design-system/icons.md`): an Elder Futhark
|
|
1580
|
+
rune, stroked at the chisel bevel, tinted by the app's house colour. The apps were
|
|
1581
|
+
wearing the generic Ymir mark — or, worse, the old **blue** logo.
|
|
1582
|
+
|
|
1583
|
+
- **`bin/design-icon.sh`** mints an app's icon from a glyph plus a house tint: a
|
|
1584
|
+
stone tile with the rune stroked in bronze. `list` shows the mapping.
|
|
1585
|
+
- Minted and wired: **Hlidskjalf** `ehwaz` ᛖ (the seat), **Óðrerir** `valhalla` ᚹ
|
|
1586
|
+
(the hall), **Sessrúmnir** `sowilo` ᛊ (the sun), **Smíðja** `ansuz` ᚨ (Odin's
|
|
1587
|
+
breath — the forge). Óðrerir already carried a forge-coloured favicon set.
|
|
1588
|
+
- **The blue logo is retired**: `public/logo.svg` removed, and Smíðja's *inline*
|
|
1589
|
+
copy in `App.vue` — the mark in its own header, still `#0f172a`/`#1e293b` —
|
|
1590
|
+
replaced with the ansuz rune in bronze. Rebuilt; no blue in the bundle.
|
|
1591
|
+
|
|
1592
|
+
### The hearth stays, and spreads
|
|
1593
|
+
|
|
1594
|
+
Sessrúmnir's background fire is **`EmberBackground`** — 26 embers rising with a
|
|
1595
|
+
gentle sway on a canvas, *"the hearth of the landing page, carried into the
|
|
1596
|
+
chat"* — used by its home screen and chat panel. It stays. Next: one shared
|
|
1597
|
+
ember (a framework-neutral `midgard/design-system/ember.js` with a
|
|
1598
|
+
`prefers-reduced-motion` guard) so Hlidskjalf's shell, the login screen,
|
|
1599
|
+
Óðrerir's hall and the Smíðja chrome can warm the same fire.
|
|
1600
|
+
|
|
1601
|
+
## 2026-09-16 — the hearth spreads: one fire, three more surfaces
|
|
1602
|
+
|
|
1603
|
+
Sessrúmnir's fire is now shared rather than copied. `midgard/design-system/ember.js`
|
|
1604
|
+
is the framework-neutral original (the land page's Ginnungagap embers: 30 rising
|
|
1605
|
+
with a gentle sway over six drifting haze pools), with `ember.d.ts` for TypeScript
|
|
1606
|
+
consumers and a reader who asked for less motion gets a **still frame** instead of
|
|
1607
|
+
an animation.
|
|
1608
|
+
|
|
1609
|
+
Wired, and built:
|
|
1610
|
+
|
|
1611
|
+
- **Hlidskjalf** — `src/components/EmberBackground.tsx` imports the shared module;
|
|
1612
|
+
mounted behind the *login* and behind the *shell*, so the door and the hall burn
|
|
1613
|
+
over one hearth.
|
|
1614
|
+
- **Smíðja visualizer** — a `<canvas class="ember-bg">` behind every view.
|
|
1615
|
+
- **Óðrerir** — a `data-ember` canvas in its shell, so the hall warms too.
|
|
1616
|
+
- Sessrúmnir keeps its own React port untouched (two ports of one fire, the same
|
|
1617
|
+
physics; consolidating them on the shared module is the next tidy).
|
|
1618
|
+
|
|
1619
|
+
And the reference for the missing furniture: **Óðrerir already carries it all** —
|
|
1620
|
+
four favicons, `mask-icon` in bronze, `site.webmanifest`, canonical, description,
|
|
1621
|
+
theme-colour and Open Graph. The other apps should be brought up to *it*.
|
|
1622
|
+
|
|
1623
|
+
## 2026-09-16 — icons the operator can pin, and one pair of hands for the shells
|
|
1624
|
+
|
|
1625
|
+
**"Fail, no icons" — and the cause was a trap I had already been bitten by.**
|
|
1626
|
+
`bin/design-icon.sh install` writes an app's rune into the icon theme and a
|
|
1627
|
+
`.desktop` entry into the applications dir. It used `XDG_DATA_HOME`, and this
|
|
1628
|
+
agent session exports that as a **sandbox** (`…/opencode-rd`), so the icons went
|
|
1629
|
+
somewhere no desktop can see. It now targets the operator's real data dir
|
|
1630
|
+
(`$HOME/.local/share`, with `YMIR_DESKTOP_DATA_HOME` for a throwaway test) — the
|
|
1631
|
+
same class of bug that once hid `gh` from this session.
|
|
1632
|
+
|
|
1633
|
+
Installed now, for **every** app: hlidskjalf, **odrerir**, **sessrumnir**, the
|
|
1634
|
+
Smíðja visualizer and hlidskjalf-mobile — each with its rune icon and a dockable
|
|
1635
|
+
entry. Óðrerir and Sessrúmnir had **none**, which is exactly why they could not
|
|
1636
|
+
be pinned. The stale `ymir-smidja.desktop` (pointing at a repo PNG) is folded
|
|
1637
|
+
into the rune's own entry.
|
|
1638
|
+
|
|
1639
|
+
**One pair of hands for two lifecycles.** `scripts/start.sh` and
|
|
1640
|
+
`scripts/stop.sh` manage the web; `scripts/electron.sh` manages the shells — and
|
|
1641
|
+
they never met, which is why "the electrons are not running" was true while 28
|
|
1642
|
+
processes stood, and why a restart could leave a shell watching a dead port.
|
|
1643
|
+
`scripts/raise.sh` / `scripts/lower.sh` own both: lower takes the windows down
|
|
1644
|
+
**first**, so none is left watching a port that just vanished.
|
|
1645
|
+
|
|
1646
|
+
**A bug the restart surfaced:** `scripts/electron.sh stop` used `local` outside a
|
|
1647
|
+
function — it worked only because the assignment happened to be harmless, and it
|
|
1648
|
+
printed a shell error on every stop. Fixed.
|
|
1649
|
+
|
|
1650
|
+
**And the inventory is a tool:** `bin/feature-inventory.sh` — 132 tools, 5 jobs,
|
|
1651
|
+
26 skills, 20 agents, 8 workflows, 6 apps, 4 migrations, 6 registered projects,
|
|
1652
|
+
each with the way it must be proven written beside it.
|
|
1653
|
+
|
|
1654
|
+
## 2026-09-16 — the icons are real runes now (eight of them were drawings)
|
|
1655
|
+
|
|
1656
|
+
The Allfather looked at the icons and said what no check had: *"the icons must be
|
|
1657
|
+
based on real runes."* He was right, and the fault was in the **glyph set**, not
|
|
1658
|
+
just in the two icons I had minted.
|
|
1659
|
+
|
|
1660
|
+
`midgard/design-system/icons.md` claims every glyph is an Elder Futhark rune and
|
|
1661
|
+
gives each its unicode. **Eight of the twenty-one files were drawings** — a hall
|
|
1662
|
+
(`valhalla`, which Óðrerir was wearing), a horn, a shield, a spear, a well, a
|
|
1663
|
+
squirrel, a gate, a world-tree. Replaced with the real runes their own rows
|
|
1664
|
+
declare:
|
|
1665
|
+
|
|
1666
|
+
```
|
|
1667
|
+
gjallarhorn ᚷ Gebo · gungnir ᚦ Thurisaz · heimdall ᚺ Hagall · mimirsbrunn ᛜ Ingwaz
|
|
1668
|
+
ratatoskr ᛒ Berkanan · utgard ᚢ Uruz · valhalla ᚹ Wunjo · yggdrasil ᛃ Jera
|
|
1669
|
+
```
|
|
1670
|
+
|
|
1671
|
+
Gungnir was claiming Gebo, which Gjallarhorn already holds, so it takes
|
|
1672
|
+
**Thurisaz** (the thorn — the spear) and `icons.md` is corrected to match.
|
|
1673
|
+
|
|
1674
|
+
**Five apps, five different runes:** Hlidskjalf `ehwaz`, mobile `raidho` (the
|
|
1675
|
+
road), Óðrerir `valhalla`→ now genuinely `ᚹ Wunjo`, Sessrúmnir `sowilo`, Smíðja
|
|
1676
|
+
`kaunan` (the torch). The install table drives both mint and install now — it had
|
|
1677
|
+
been guessing paths, which is why the Smíðja visualizer had been given
|
|
1678
|
+
Hlidskjalf's icon.
|
|
1679
|
+
|
|
1680
|
+
Also this pass: the visualizer gained its furniture (description, canonical,
|
|
1681
|
+
manifest, OG + Twitter), Óðrerir's Electron shell asks for a window icon, and the
|
|
1682
|
+
apple-touch PNGs are rasterised (ImageMagick is present).
|
|
1683
|
+
|
|
1684
|
+
## 2026-09-16 — the desktop never dials out: Cloudflare stays outside Electron
|
|
1685
|
+
|
|
1686
|
+
The Allfather's rule: **"electron should never have anything with cloudflare to
|
|
1687
|
+
do."** It was not quite true — three doors stood open:
|
|
1688
|
+
|
|
1689
|
+
- **Sessrúmnir's "To the Hall"** preferred the local hall and, when it did not
|
|
1690
|
+
answer, fell back to `https://hall.ymir.zerwiz.org`. A desktop seat that
|
|
1691
|
+
reaches for a public hostname when its own machine is quiet is a seat that
|
|
1692
|
+
leaves the building to do its errands. It is now **local only** — when the hall
|
|
1693
|
+
is not running, the seat says so.
|
|
1694
|
+
- **Hlidskjalf's shell** took `HLIDSKJALF_URL` and `SMIDJA_URL` from the
|
|
1695
|
+
environment, and **Óðrerir's** took `HALL_URL` — each able to point a desktop
|
|
1696
|
+
window at a tunnel with one exported variable.
|
|
1697
|
+
- Both now pass their URL through a **loopback guard**: anything that is not
|
|
1698
|
+
`127.0.0.1`, `localhost` or `::1` is refused with a warning and replaced by the
|
|
1699
|
+
local default. The shell loads the machine, never the internet.
|
|
1700
|
+
|
|
1701
|
+
**Why this is the same fight as the bridge:** a desktop app that dials out is a
|
|
1702
|
+
desktop app whose failures belong to somebody else's edge. The bridge disguised a
|
|
1703
|
+
cloud endpoint as `127.0.0.1` and cost a night; these three would have disguised a
|
|
1704
|
+
tunnel as a local seat.
|
|
1705
|
+
|
|
1706
|
+
## 2026-09-16 — the panels that crashed, the gate that lied, and the well that would not open
|
|
1707
|
+
|
|
1708
|
+
- **Statistics now reports the HARNESSES** (pi + opencode), not the smithy's runs.
|
|
1709
|
+
`bin/hlidskjalf-usage.sh` aggregates opencode's SQLite token store and both pi
|
|
1710
|
+
stores, and emits the numbers under the names the gate renders (`gate{}`):
|
|
1711
|
+
totals, usage, providers local/online with per_model, by_chain, by_model.
|
|
1712
|
+
Verified: 21,497 runs (opencode 21,422 · pi 75) · 331.5M tokens ·
|
|
1713
|
+
local 239,623 / online 331,289,420 · cache-hit 91.5%.
|
|
1714
|
+
- **A failed fetch no longer takes the hall down.** Endpoints answering `{error}`
|
|
1715
|
+
were handed to panels as data — Rail read `.filter` on an object, Stats read
|
|
1716
|
+
`.totals` on a string, and both crashed. The store now runs every bootstrap
|
|
1717
|
+
answer through `ok()`: an error keeps the last good value.
|
|
1718
|
+
- **`/api/usage` was answering with a traceback** while the script passed by hand:
|
|
1719
|
+
the gate process had been started before the fix and caches a failure for 60s.
|
|
1720
|
+
Restarted; the endpoint serves the harness numbers.
|
|
1721
|
+
- **The engram MCP (`-32000: Connection closed`) is mended.** Not config, not the
|
|
1722
|
+
engram package: `python3.12 -c "import mcp"` failed because the system
|
|
1723
|
+
`python3-rpds-py` ships without its compiled `rpds.rpds` module, which
|
|
1724
|
+
`jsonschema` (inside `mcp` 1.x) imports. Mended with
|
|
1725
|
+
`python3.12 -m pip install --user --break-system-packages --force-reinstall rpds-py`
|
|
1726
|
+
(plus `mcp<2` under python3.12). The server now starts and waits on stdio.
|
|
1727
|
+
Eir should check this pair: `mcp` present for the interpreter that runs the
|
|
1728
|
+
binary, and `rpds` importable.
|
|
1729
|
+
|
|
1730
|
+
## 2026-09-17 — Sessrúmnir stops wearing Pi's clothes
|
|
1731
|
+
|
|
1732
|
+
- **The naming law, broken at the root.** Clicking the Sessrúmnir icon opened a
|
|
1733
|
+
window titled **Pi Desktop**: `apps/sessrumnir` is the Pi Desktop shell adopted
|
|
1734
|
+
whole, and its product name was still Pi's —
|
|
1735
|
+
`export const PI_DESKTOP_PRODUCT_NAME = 'Pi Desktop'` — rendered as the heading on
|
|
1736
|
+
the home screen, the sidebar and the chat panel. That is the title the Allfather
|
|
1737
|
+
saw, twice, on every launch.
|
|
1738
|
+
- **Mended at the name:** `SESSRUMNIR_PRODUCT_NAME = 'Sessrúmnir'` (Odin's hall of
|
|
1739
|
+
many seats), the three rendering components walked, and the old constant kept as an
|
|
1740
|
+
alias so no unwalked import breaks. `tsc --noEmit` exit 0.
|
|
1741
|
+
- **Still owed:** 1,255 English strings, **86 of them naming Pi** ("Pi is working",
|
|
1742
|
+
"Quit Pi Desktop", "Pi Desktop v{{latestVersion}} is available", "Start Pi/OMP
|
|
1743
|
+
before planning with Council"), and Pi's logo on the home screen. The locale is the
|
|
1744
|
+
one place they live — that pass is the order, not a patch.
|
|
1745
|
+
- Also in the launcher this session: an icon click now raises THE SYSTEM (converge
|
|
1746
|
+
the service, reborn a windowless app, focus a live window), and `stop --view X`
|
|
1747
|
+
stops only X — the loop that killed every view is gone. The Hall's own outage had
|
|
1748
|
+
a cause: an Astro dev server on :4323 while the app waited on :4322.
|
|
1749
|
+
|
|
1750
|
+
## 2026-09-17 — the smithy can see the well
|
|
1751
|
+
|
|
1752
|
+
- **Why the memory looked absent in the smithy:** the visualizer proxies the bridge's
|
|
1753
|
+
`/inspect`, and `/inspect` reported three fields — store, episodes, agents — while
|
|
1754
|
+
the well holds six layers. A panel told only the episode count cannot show that
|
|
1755
|
+
facts, entities and reflections exist. `/inspect` now reports them all:
|
|
1756
|
+
episodes, facts (active/superseded), entities, edges, reflections (with the last
|
|
1757
|
+
run's time) and the vector index.
|
|
1758
|
+
- **Through the smithy right now:**
|
|
1759
|
+
`store $YMIR_HOME/memory/kaia.engram · episodes 8 · facts 36 (35 active) ·
|
|
1760
|
+
entities 60 · edges 480 · reflections 1 (2026-09-16T21:01) · vec index 8`.
|
|
1761
|
+
- **A trap found while doing it:** restarting the bridge RAW (`python3 bin/mimir-bridge.py`)
|
|
1762
|
+
loses the env that carries the well's path, and the bridge silently re-points at the
|
|
1763
|
+
old store in the repo — 364 stale episodes and no facts. The well is the **blessed
|
|
1764
|
+
starter's** to raise: `bin/mimir-bridge.sh --start`. A raw restart is a different
|
|
1765
|
+
well wearing the same port.
|
|
1766
|
+
|
|
1767
|
+
## 2026-09-17 — Skrymir opens the hoard, not the checkout
|
|
1768
|
+
|
|
1769
|
+
- **The file browser was rooted in the wrong tree.** `workspaceRoot()` built every
|
|
1770
|
+
realm path under `ROOT` — the checkout — so `work` resolved to a directory that does
|
|
1771
|
+
not exist and the walk fell back to the repo's `docs/`. That is why Skrymir showed
|
|
1772
|
+
`lore.md`, `Architecture.md`, `research/`, `runbooks/`, and why a file it had just
|
|
1773
|
+
listed answered **"not found"**: the listing came from one tree and the read from
|
|
1774
|
+
another.
|
|
1775
|
+
- **The hoard first now (Rule 04):** `$YMIR_HOME/svartalfaheim/<realm>` → company
|
|
1776
|
+
container → `$YMIR_HOME/workspace/<realm>` → the checkout only as legacy. An empty
|
|
1777
|
+
realm shows the hoard's home, never the repo's docs. Verified: `work` lists
|
|
1778
|
+
`memory/daily/2026-09-13.md` and `workspace/`, and a read returns its body.
|
|
1779
|
+
- Note for the next hand: the gate runs **without** `--watch` — a server edit is on
|
|
1780
|
+
disk and not in the process until `scripts/start.sh` raises it again.
|
|
1781
|
+
|
|
1782
|
+
## 2026-09-17 — the Fleet was a rack of terminals; now it is the roster
|
|
1783
|
+
|
|
1784
|
+
- **We were tracking the tools.** `.agents/agents/` holds **21 agent definitions** —
|
|
1785
|
+
Brokk, Sindri, Bragi, Forseti, Mímir, Kvasir, Snotra, Huginn, Hnoss, Sága, Muninn,
|
|
1786
|
+
Frigg, Gróa, Jörð, Sýn, Týr, Galdr… — and the Fleet served **13 panes all named
|
|
1787
|
+
"OpenCode"**, role `opencode`. The board showed seats and never the smiths who might
|
|
1788
|
+
be standing in them.
|
|
1789
|
+
- **`bin/hlidskjalf-agents.sh` now reads the roster** (`.agents/agents/*.md`, canonical
|
|
1790
|
+
per RULES/02) and joins each agent to its standing pane: figure, craft, model from
|
|
1791
|
+
the definition's frontmatter, and `live{}` only when a pane answers to it. An
|
|
1792
|
+
**unseated agent is still an agent** — hiding it is what made the board a rack.
|
|
1793
|
+
- Harness seats that answer to no one on the roster are kept visible and named
|
|
1794
|
+
honestly, never dressed as agents.
|
|
1795
|
+
- Served: **34 entries — 21 agents (roster first) + 13 harness seats, 14 joined**.
|
|
1796
|
+
|
|
1797
|
+
## 2026-09-17 — the extensions deployed without their modules
|
|
1798
|
+
|
|
1799
|
+
- **pi would not start a seated worker, and the reason was a half-deploy.**
|
|
1800
|
+
The four shared pi extensions all reported
|
|
1801
|
+
`Failed to load extension: Cannot find module ./lib/<module>.ts` — and every one
|
|
1802
|
+
of those modules was present in the repo, one level away under the extensions'
|
|
1803
|
+
own `lib/`. The loader copied the top-level extension files and never their
|
|
1804
|
+
supporting modules.
|
|
1805
|
+
- **Mended in two places.** (1) The missing modules are now beside the deployed
|
|
1806
|
+
extensions, so a running pi loads all four. (2) `bin/valknut-load.sh` — the
|
|
1807
|
+
loader — now deploys that lib alongside the extensions, idempotently (identical
|
|
1808
|
+
files untouched), so a fresh machine cannot hit it. A deploy that copies a file
|
|
1809
|
+
but not the module it imports is not a deploy.
|
|
1810
|
+
- **What this cost:** the Forseti audit was seated on a **local** model, and the
|
|
1811
|
+
pane fell back to a bare shell when pi could not start — which is why the brief
|
|
1812
|
+
was typed at a prompt and answered `bash: syntax error near unexpected token '('`.
|
|
1813
|
+
With the extensions mended, pi's remaining blocker is the model: the llama-router
|
|
1814
|
+
has no raisable seat tonight (`:8080` unbound, and the installed llama.cpp cannot
|
|
1815
|
+
load the Apodex weights), so a local-first dispatch has nothing to reach.
|
|
1816
|
+
|
|
1817
|
+
## 2026-09-17 — the well as tools: Ymir's first custom pi extension
|
|
1818
|
+
|
|
1819
|
+
- **Why the extension tree was failing, from the upstream law:** pi auto-discovers
|
|
1820
|
+
extensions from BOTH the global home and the project-local tree. The same extension
|
|
1821
|
+
in both loads twice and pi refuses the duplicate tool —
|
|
1822
|
+
`Tool "gna_watch_arm" conflicts with …`. Ymir's own loader already says the shared
|
|
1823
|
+
extensions have **one** home; the tree contradicted it by carrying the extension
|
|
1824
|
+
files project-locally as well.
|
|
1825
|
+
- **Built: `ymir-well`** — the well, as tools inside every pi session.
|
|
1826
|
+
`well_recall(query, k)` reads Kaia's memory before work begins;
|
|
1827
|
+
`well_observe(content, tags, actors, salience)` writes the lesson after. Written in
|
|
1828
|
+
the house voice, honest about failure (a failed write says the lesson was NOT
|
|
1829
|
+
written), and it sends tags as LISTS — a comma-string is stored as an array of
|
|
1830
|
+
characters, which is exactly how a recall once returned `['r','u','n']`.
|
|
1831
|
+
- Authored in the SHARED source and deployed to the global home — one home, never a
|
|
1832
|
+
project copy. That is the pattern every future Ymir extension follows.
|
|
1833
|
+
|
|
1834
|
+
## 2026-09-17 — the duplicate extensions removed from the project tree
|
|
1835
|
+
|
|
1836
|
+
- **The fault, now measured exactly.** The project-local extension tree carried four
|
|
1837
|
+
files that the shared source also carries — `gna-pi-watch.ts`, `ro.ts`,
|
|
1838
|
+
`skuld-branch-supervision.ts`, `syn-turnend-guard.ts`. pi auto-discovers both the
|
|
1839
|
+
global home and the project tree, so each loaded twice and pi refused the second
|
|
1840
|
+
copy of every tool: `Tool "gna_watch_arm" conflicts with …`. Every `pi` start in
|
|
1841
|
+
every worktree died on it, which is why a seated worker fell back to a shell.
|
|
1842
|
+
- **The fix:** those four files are gone from the project tree. What remains there is
|
|
1843
|
+
`lib/` — the modules the *global* extensions import — and its README. The
|
|
1844
|
+
extensions themselves live in the shared source and in the one global home.
|
|
1845
|
+
- The seatbelt refused the plain shapes (`rm`, `mv`, `>`-bearing commands) on this
|
|
1846
|
+
path and named the remedy: *a reviewed commit*. This is that commit.
|
|
1847
|
+
|
|
1848
|
+
## 2026-09-17 — smoke test all UI: two checks that lied about their own subjects
|
|
1849
|
+
|
|
1850
|
+
- **The truth gate failed on my own change.** It demanded the connector's total equal
|
|
1851
|
+
the herdr pane count; the connector is roster-first now, so it legitimately reports
|
|
1852
|
+
agents AND seats (33 vs 13 panes). Panes are a subset of what the board must show.
|
|
1853
|
+
Corrected: a FAIL now means FEWER entries than panes — a standing seat hidden from
|
|
1854
|
+
the board — which is the fault worth catching. **Verdict: PASS.**
|
|
1855
|
+
- **The smoke test reported a present database absent.** It looked for the smithy's db
|
|
1856
|
+
at the repo path; the runtime keeps it under `$YMIR_HOME/smidja/`, which is where
|
|
1857
|
+
the bootstrap and the gate both resolve it. Same wound as Skrymir and the well: the
|
|
1858
|
+
check and the owner disagreeing about where the record lives. **Now: OK, 8 tables.**
|
|
1859
|
+
- **Smoke test all UI: 5/5 OK** — spa, api, well, smidja-db, loaders. Truth gate: PASS.
|
|
1860
|
+
|
|
1861
|
+
Also mended in the same pass: `StatusChip` read `STATUS_META[status].tone`, and the
|
|
1862
|
+
fleet now reports a status it was never taught (`seated`), so an unknown status threw
|
|
1863
|
+
and killed the gate. An unknown status can no longer take a panel down.
|
|
1864
|
+
|
|
1865
|
+
## 2026-09-17 — Glitnir stops hanging, and one process is one row
|
|
1866
|
+
|
|
1867
|
+
- **`/api/reviews` ran two 60-second shell checks on every poll**, so the review board
|
|
1868
|
+
hung for a minute and read as a dead surface. It is memoised for a minute now, the
|
|
1869
|
+
same discipline the usage endpoint already follows: a board a human reads does not
|
|
1870
|
+
need an answer fresher than its own usefulness.
|
|
1871
|
+
- **`/api/processes` returns the same id twice** — `systemd:dbus` arrives from two
|
|
1872
|
+
sources, 45 entries for 44 processes. The panel dedupes by id, so a repeated process
|
|
1873
|
+
renders as the one process it is, and React is no longer handed a duplicate key.
|
|
1874
|
+
The duplicate at the source is recorded, not hidden.
|
|
1875
|
+
- `/api/stream` answers 200; the live stream is not broken, it was the window.
|
|
1876
|
+
|
|
1877
|
+
## 2026-09-17 — the fleet stops colliding: a grid fan, and each smith's own house
|
|
1878
|
+
|
|
1879
|
+
- **The Fleet graph collided above ~8 agents.** `Fleet.tsx` fanned every
|
|
1880
|
+
non-hub agent into a single two-row line at ~4.4% pitch on 46px rings — with
|
|
1881
|
+
20 roster cards the rings and labels overlapped into an unreadable pile.
|
|
1882
|
+
`layout()` now fans a square-ish grid (`cols = ceil(sqrt(n))`, hub at top,
|
|
1883
|
+
rows pitched past ring+label), so 20 agents render separated.
|
|
1884
|
+
- **Every ring showed the same rune.** `bin/hlidskjalf-agents.sh` hardcoded
|
|
1885
|
+
`domain: ymirlabs` for every card and its roster parser never read the
|
|
1886
|
+
`domain:` frontmatter each figure carries — so all twenty cards wore the
|
|
1887
|
+
anonymous ᛦ. The roster now parses `domain:` and passes it through;
|
|
1888
|
+
`galdr.md` names its house (`brokkforge`); the graph falls back to
|
|
1889
|
+
`DOMAINS.ymirlabs` only when a domain is genuinely unknown (was a crash)
|
|
1890
|
+
— and the `AgentCard` already fell back safely.
|
|
1891
|
+
|
|
1892
|
+
galdr-reread: `.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md` — the
|
|
1893
|
+
Fleet graph paragraph (grid fan, roster domains, fallback).
|
|
1894
|
+
|
|
1895
|
+
## 2026-09-17 — the apps leave the monorepo; installation pulls them from their own repos
|
|
1896
|
+
|
|
1897
|
+
- **The app split lands in the installer.** The five apps (hlidskjalf,
|
|
1898
|
+
hlidskjalf-mobile, odrerir, sessrumnir, smidja) now live in their own repos
|
|
1899
|
+
registered in the home registry (`$HOARD/identity/projects.yaml`) — the
|
|
1900
|
+
monorepo never tracks them, and **`step_apps`** clones or fast-forwards each
|
|
1901
|
+
`apps/<path>` from its registered `git{}` block (never guessing a remote,
|
|
1902
|
+
always reading the registry). The smithy engine (`apps/smidja`) is stamped
|
|
1903
|
+
from the cloned factory's `templates/smidja`, exactly as `install.py` does
|
|
1904
|
+
for a target repo — so a fresh clone still gets a working smithy.
|
|
1905
|
+
- **The vendored app trees leave the index.** `apps/{hlidskjalf,
|
|
1906
|
+
hlidskjalf-mobile,odrerir,sessrumnir,smidja,smidja-factory}` are gitignored
|
|
1907
|
+
and `git rm --cached`-ed (751 files, 135k lines); `apps/README.md` stays.
|
|
1908
|
+
A dir present that is not a git clone is reported (`move it aside and
|
|
1909
|
+
re-run`) rather than silently replaced.
|
|
1910
|
+
|
|
1911
|
+
galdr-reread: `.agents/skills/galdr-ymirsystem/assets/installation.md` — the
|
|
1912
|
+
step table (`22 steps`, `24` `step_*` functions), the new `apps` row, and the
|
|
1913
|
+
Sessrúmnir rows now say "its own repo", not "vendored".
|