@zerwiz/ymir 0.1.3 → 0.1.5
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/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 +290 -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 +50 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +9 -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/config/tailscale-sync.yaml +27 -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/kaia.engram +0 -0
- package/.agents/memory/kaia.engram-shm +0 -0
- package/.agents/memory/kaia.engram-wal +0 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/memory/well/episodes.jsonl +367 -0
- package/.agents/memory/well/workspace.jsonl +27 -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 +111 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -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 +158 -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 +673 -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 +496 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -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 +161 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -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 +96 -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 +175 -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 +360 -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 +70 -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 +52 -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 +34 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -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 +454 -0
- package/CHANGELOG.md +881 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +113 -39
- 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 +65 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +58 -0
- package/RULES/07-config.md +45 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/README.md +20 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +98 -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 +233 -0
- package/bin/apodex-smoke-test.sh +92 -0
- package/bin/bifrost-bridge.sh +112 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +107 -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 +38 -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-guard.sh +165 -0
- package/bin/crash-sense.sh +160 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +207 -0
- package/bin/eindri-acclaim.sh +34 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seen.sh +41 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +85 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +112 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/fleet-apply.sh +68 -0
- package/bin/github-deploy.sh +81 -0
- package/bin/gjallarhorn-expose.sh +102 -0
- package/bin/gjallarhorn-notify.sh +58 -0
- package/bin/gjallarhorn-purge.sh +54 -0
- package/bin/gjallarhorn-tunnel.sh +72 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +122 -0
- package/bin/hall-snapshot.sh +92 -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 +431 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hoard-lib.sh +25 -0
- package/bin/hodd.sh +78 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +108 -0
- package/bin/local-model-lock.sh +51 -0
- package/bin/mimir-bridge.py +226 -0
- package/bin/mimir-bridge.sh +87 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +59 -0
- package/bin/mjollnir.sh +85 -0
- package/bin/model-hardware.sh +82 -0
- package/bin/model-resolve.sh +147 -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-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +148 -0
- package/bin/omarchy-plugins.sh +174 -0
- package/bin/omarchy-sense.sh +149 -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-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +38 -0
- package/bin/project-git.sh +55 -0
- package/bin/public-guard.sh +70 -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 +91 -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 +90 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +76 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +190 -0
- package/bin/telegram-bot.sh +69 -0
- package/bin/toolchain.sh +74 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +260 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +47 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +150 -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 +641 -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-platform.sh +348 -0
- package/bin/ymir-say.sh +97 -0
- package/bin/ymir-setup-auth.sh +108 -0
- package/bin/ymir-validate.sh +173 -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 +1056 -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 +44 -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 +210 -0
- package/scripts/start.sh +167 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-supervision-events.test.sh - unit tests for the watcher's native
|
|
3
|
+
# event-wait splice (event_wait_or_sleep in bin/fm-watch.sh and
|
|
4
|
+
# handle_push_transition in bin/fm-push-transition-lib.sh). The watcher's source
|
|
5
|
+
# guard lets this file source it to load
|
|
6
|
+
# the functions WITHOUT acquiring the singleton lock or entering the blocking
|
|
7
|
+
# loop; wake/sleep and the backend dispatchers are overridden so the exemptions,
|
|
8
|
+
# capability memo, and fail-closed disable are asserted deterministically with no
|
|
9
|
+
# real herdr, watcher process, or blocking sleeps.
|
|
10
|
+
set -u
|
|
11
|
+
|
|
12
|
+
# shellcheck source=tests/lib.sh
|
|
13
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
14
|
+
|
|
15
|
+
TMP=$(fm_test_tmproot fm-supervision-events)
|
|
16
|
+
STATE_DIR="$TMP/state"
|
|
17
|
+
mkdir -p "$STATE_DIR"
|
|
18
|
+
|
|
19
|
+
# Source the watcher with an isolated state/home. The guard returns before the
|
|
20
|
+
# lock/loop, so only the functions load.
|
|
21
|
+
export FM_STATE_OVERRIDE="$STATE_DIR"
|
|
22
|
+
export FM_ROOT_OVERRIDE="$ROOT"
|
|
23
|
+
# Production modules are independently linted canonical roots. Keep this test's
|
|
24
|
+
# ShellCheck context local while preserving its unchanged runtime source path.
|
|
25
|
+
# shellcheck source=/dev/null
|
|
26
|
+
. "$ROOT/bin/fm-watch.sh"
|
|
27
|
+
|
|
28
|
+
# Overrides: capture wake reasons and neutralize real sleeps (POLL is 15s).
|
|
29
|
+
WAKE_LOG="$TMP/wakes"
|
|
30
|
+
SLEEP_LOG="$TMP/sleeps"
|
|
31
|
+
wake() { printf '%s\n' "$1" >> "$WAKE_LOG"; return 0; }
|
|
32
|
+
sleep() { printf 'SLEEP\n' >> "$SLEEP_LOG"; }
|
|
33
|
+
|
|
34
|
+
reset_state() {
|
|
35
|
+
rm -f "$STATE_DIR"/*.meta "$STATE_DIR"/*.status "$STATE_DIR"/.wake-queue \
|
|
36
|
+
"$STATE_DIR"/.wake-queue.seq "$STATE_DIR"/.watch-triage.log \
|
|
37
|
+
"$STATE_DIR"/.herdr-escalated-* "$TMP"/panes "$TMP"/wtcalls "$TMP"/wtcalled 2>/dev/null || true
|
|
38
|
+
: > "$WAKE_LOG"
|
|
39
|
+
: > "$SLEEP_LOG"
|
|
40
|
+
_event_cap_key=""
|
|
41
|
+
_event_cap_ok=0
|
|
42
|
+
_event_cap_fails=0
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
mkrec() { # <pane_id> <status>
|
|
46
|
+
fm_transition_record "$1" "wG" "" "$2" claude
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# --- handle_push_transition: enqueue + wake for a non-paused blocked crew -----
|
|
50
|
+
|
|
51
|
+
reset_state
|
|
52
|
+
fm_write_meta "$STATE_DIR/tk1.meta" "window=default:wG:pQ" "backend=herdr" "kind=ship"
|
|
53
|
+
handle_push_transition herdr default "$(mkrec wG:pQ blocked)"
|
|
54
|
+
[ -e "$STATE_DIR/.wake-queue" ] || fail "handle_push_transition should enqueue a wake for a blocked crew"
|
|
55
|
+
grep -q 'stale' "$STATE_DIR/.wake-queue" || fail "the enqueued wake must be a stale record: $(cat "$STATE_DIR/.wake-queue")"
|
|
56
|
+
grep -q 'default:wG:pQ' "$STATE_DIR/.wake-queue" || fail "the stale record must name the crew's window"
|
|
57
|
+
grep -q 'herdr: agent blocked' "$STATE_DIR/.wake-queue" || fail "the stale payload must name the herdr-blocked cause"
|
|
58
|
+
[ -s "$WAKE_LOG" ] || fail "handle_push_transition must wake the supervisor for a blocked crew"
|
|
59
|
+
[ -e "$STATE_DIR/.herdr-escalated-default_wG_pQ" ] || fail "handle_push_transition must commit dedupe only after enqueue"
|
|
60
|
+
pass "handle_push_transition: a blocked crew enqueues a stale wake naming its window and wakes the supervisor"
|
|
61
|
+
|
|
62
|
+
reset_state
|
|
63
|
+
fm_write_meta "$STATE_DIR/tk1.meta" "window=default:wG:pQ" "backend=herdr" "kind=ship"
|
|
64
|
+
(
|
|
65
|
+
# shellcheck disable=SC2329 # Runtime override called by the isolated production owner.
|
|
66
|
+
fm_wake_append() { return 1; }
|
|
67
|
+
handle_push_transition herdr default "$(mkrec wG:pQ blocked)"
|
|
68
|
+
) >/dev/null 2>&1 || true
|
|
69
|
+
[ ! -e "$STATE_DIR/.herdr-escalated-default_wG_pQ" ] || fail "a failed durable enqueue must leave the blocked edge eligible for reconnect reconciliation"
|
|
70
|
+
pass "handle_push_transition: enqueue failure cannot commit the Herdr dedupe marker"
|
|
71
|
+
|
|
72
|
+
# --- handle_push_transition: absorb (no wake, no enqueue) for a declared pause -
|
|
73
|
+
|
|
74
|
+
reset_state
|
|
75
|
+
fm_write_meta "$STATE_DIR/tk2.meta" "window=default:wG:pQ" "backend=herdr" "kind=ship"
|
|
76
|
+
printf 'paused: waiting on the upstream release\n' > "$STATE_DIR/tk2.status"
|
|
77
|
+
handle_push_transition herdr default "$(mkrec wG:pQ blocked)"
|
|
78
|
+
if [ -e "$STATE_DIR/.wake-queue" ] && grep -q 'stale' "$STATE_DIR/.wake-queue"; then
|
|
79
|
+
fail "a declared-pause crew must NOT be fast-escalated: $(cat "$STATE_DIR/.wake-queue")"
|
|
80
|
+
fi
|
|
81
|
+
[ ! -s "$WAKE_LOG" ] || fail "a declared-pause crew must not wake the supervisor from the event fast-path"
|
|
82
|
+
grep -q 'absorbed push' "$STATE_DIR/.watch-triage.log" 2>/dev/null || fail "the paused absorb should be logged to the triage log"
|
|
83
|
+
pass "handle_push_transition: a declared-pause crew is absorbed (no fast wake), left to the poll loop's long cadence"
|
|
84
|
+
|
|
85
|
+
# --- handle_push_transition: absorb for a verified captain-held transfer -------
|
|
86
|
+
|
|
87
|
+
reset_state
|
|
88
|
+
fm_write_meta "$STATE_DIR/tk2h.meta" "window=default:wG:pQ" "backend=herdr" "kind=ship"
|
|
89
|
+
printf 'captain-held [key=route]: tracked by task-decision-route\n' > "$STATE_DIR/tk2h.status"
|
|
90
|
+
handle_push_transition herdr default "$(mkrec wG:pQ blocked)"
|
|
91
|
+
if [ -e "$STATE_DIR/.wake-queue" ] && grep -q 'stale' "$STATE_DIR/.wake-queue"; then
|
|
92
|
+
fail "a captain-held crew must NOT be fast-escalated: $(cat "$STATE_DIR/.wake-queue")"
|
|
93
|
+
fi
|
|
94
|
+
[ ! -s "$WAKE_LOG" ] || fail "a captain-held crew must not wake the supervisor from the event fast-path"
|
|
95
|
+
grep -q 'absorbed push' "$STATE_DIR/.watch-triage.log" 2>/dev/null || fail "the captain-held absorb should be logged to the triage log"
|
|
96
|
+
pass "handle_push_transition: a captain-held crew is absorbed (no fast wake), left to the poll loop's long cadence"
|
|
97
|
+
|
|
98
|
+
# --- event_wait_or_sleep: secondmate windows are excluded from the pane list --
|
|
99
|
+
|
|
100
|
+
reset_state
|
|
101
|
+
fm_write_meta "$STATE_DIR/tk3.meta" "window=default:wG:pQ" "backend=herdr" "kind=ship"
|
|
102
|
+
fm_write_meta "$STATE_DIR/sm1.meta" "window=default:wA:pS" "backend=herdr" "kind=secondmate"
|
|
103
|
+
# shellcheck disable=SC2329 # Runtime overrides called by the isolated watcher.
|
|
104
|
+
fm_backend_events_capable() { return 0; }
|
|
105
|
+
# shellcheck disable=SC2329 # Runtime overrides called by the isolated watcher.
|
|
106
|
+
fm_backend_wait_transition() { shift 4; printf '%s\n' "$*" > "$TMP/panes"; return 1; }
|
|
107
|
+
event_wait_or_sleep
|
|
108
|
+
PANES=$(cat "$TMP/panes" 2>/dev/null || true)
|
|
109
|
+
case "$PANES" in *"default:wG:pQ"*) : ;; *) fail "the ship window must be in the event pane list, got '$PANES'" ;; esac
|
|
110
|
+
case "$PANES" in *"default:wA:pS"*) fail "a kind=secondmate window must be EXCLUDED from the event pane list, got '$PANES'" ;; *) : ;; esac
|
|
111
|
+
pass "event_wait_or_sleep: herdr windows go on the event pane list, but kind=secondmate endpoints are excluded"
|
|
112
|
+
|
|
113
|
+
reset_state
|
|
114
|
+
fm_write_meta "$STATE_DIR/tk3.meta" "window=default:wG:pQ" "backend=herdr" "kind=ship"
|
|
115
|
+
CAP_CALLS=0
|
|
116
|
+
# shellcheck disable=SC2329 # Runtime overrides called by the isolated watcher.
|
|
117
|
+
fm_backend_events_capable() { CAP_CALLS=$((CAP_CALLS + 1)); return 0; }
|
|
118
|
+
# shellcheck disable=SC2329 # Runtime overrides called by the isolated watcher.
|
|
119
|
+
fm_backend_wait_transition() {
|
|
120
|
+
[ "${FM_BACKEND_EVENTS_CAPABILITY_CONFIRMED:-0}" = 1 ] || fail "cached capability verdict was not passed to the wait"
|
|
121
|
+
return 1
|
|
122
|
+
}
|
|
123
|
+
event_wait_or_sleep
|
|
124
|
+
event_wait_or_sleep
|
|
125
|
+
[ "$CAP_CALLS" = 1 ] || fail "capability probe must be memoized across waits, got $CAP_CALLS calls"
|
|
126
|
+
pass "event_wait_or_sleep: one cached capability probe owns validation across bounded waits"
|
|
127
|
+
|
|
128
|
+
# --- event_wait_or_sleep: a tmux-only home never runs the event path ----------
|
|
129
|
+
|
|
130
|
+
reset_state
|
|
131
|
+
fm_write_meta "$STATE_DIR/tk4.meta" "window=fmses:fm-tk4" "kind=ship" # no backend= -> tmux
|
|
132
|
+
# shellcheck disable=SC2329 # Runtime override called by the isolated watcher.
|
|
133
|
+
fm_backend_wait_transition() { printf 'CALLED\n' > "$TMP/wtcalled"; return 1; }
|
|
134
|
+
event_wait_or_sleep
|
|
135
|
+
[ ! -e "$TMP/wtcalled" ] || fail "a tmux-only home must never invoke the event wait path"
|
|
136
|
+
grep -q 'SLEEP' "$SLEEP_LOG" || fail "a tmux-only home must sleep POLL exactly as before"
|
|
137
|
+
pass "event_wait_or_sleep: a home with no push-capable window is inert (sleeps POLL, never touches the event path)"
|
|
138
|
+
|
|
139
|
+
# --- event_wait_or_sleep: runtime failures disable the event path (fail-closed)
|
|
140
|
+
|
|
141
|
+
reset_state
|
|
142
|
+
fm_write_meta "$STATE_DIR/tk5.meta" "window=default:wG:pQ" "backend=herdr" "kind=ship"
|
|
143
|
+
export EVENT_CAP_FAIL_MAX=2
|
|
144
|
+
# shellcheck disable=SC2329 # Runtime overrides called by the isolated watcher.
|
|
145
|
+
fm_backend_events_capable() { return 0; }
|
|
146
|
+
# shellcheck disable=SC2329 # Runtime overrides called by the isolated watcher.
|
|
147
|
+
fm_backend_wait_transition() { printf 'WT\n' >> "$TMP/wtcalls"; return 2; }
|
|
148
|
+
: > "$TMP/wtcalls"
|
|
149
|
+
event_wait_or_sleep # fails=1
|
|
150
|
+
event_wait_or_sleep # fails=2 -> disable
|
|
151
|
+
event_wait_or_sleep # disabled: sleeps without calling wait_transition
|
|
152
|
+
WTN=$(wc -l < "$TMP/wtcalls" | tr -d '[:space:]')
|
|
153
|
+
[ "$WTN" = 2 ] || fail "after EVENT_CAP_FAIL_MAX connect failures the event path must be disabled for the process (expected 2 wait_transition calls, got $WTN)"
|
|
154
|
+
pass "event_wait_or_sleep: consecutive event-path failures disable the fast-path and revert to pure polling (fail-closed)"
|
|
155
|
+
|
|
156
|
+
echo "# fm-supervision-events.test.sh: all assertions passed"
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Tests for harness-aware supervision instruction rendering.
|
|
3
|
+
set -u
|
|
4
|
+
|
|
5
|
+
# shellcheck source=tests/lib.sh
|
|
6
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
7
|
+
|
|
8
|
+
TMP_ROOT=$(fm_test_tmproot fm-supervision-instructions)
|
|
9
|
+
RENDER="$ROOT/bin/fm-supervision-instructions.sh"
|
|
10
|
+
|
|
11
|
+
test_selected_harness_block_only() {
|
|
12
|
+
local out
|
|
13
|
+
out=$("$RENDER" --harness codex)
|
|
14
|
+
assert_contains "$out" "SUPERVISION OPERATING INSTRUCTIONS - primary harness: codex" "codex heading missing"
|
|
15
|
+
assert_contains "$out" "Mode: Codex foreground checkpoint." "codex snippet missing"
|
|
16
|
+
assert_contains "$out" "bin/fm-watch-checkpoint.sh" "codex checkpoint helper missing"
|
|
17
|
+
assert_not_contains "$out" "Mode: Claude Stop-hook-owned supervision." "renderer printed the claude snippet too"
|
|
18
|
+
assert_not_contains "$out" "Mode: Pi extension background wake." "renderer printed the pi snippet too"
|
|
19
|
+
pass "renderer prints exactly the selected harness block"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
test_unknown_fallback() {
|
|
23
|
+
local out
|
|
24
|
+
out=$("$RENDER" --harness not-real)
|
|
25
|
+
assert_contains "$out" "primary harness: unknown" "unknown heading missing"
|
|
26
|
+
assert_contains "$out" "Mode: Unknown harness fallback." "unknown fallback snippet missing"
|
|
27
|
+
pass "renderer falls back to unknown.md for unverified harness names"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
test_conditional_stanzas() {
|
|
31
|
+
local home config out
|
|
32
|
+
home="$TMP_ROOT/conditional-home"
|
|
33
|
+
config="$TMP_ROOT/conditional-config"
|
|
34
|
+
mkdir -p "$home/state" "$home/config" "$config"
|
|
35
|
+
out=$(FM_HOME="$home" FM_CONFIG_OVERRIDE="$config" "$RENDER" --harness codex --read-only 1 --afk 1 --x-mode 1)
|
|
36
|
+
assert_contains "$out" "- Lock: read-only" "read-only stanza missing"
|
|
37
|
+
assert_contains "$out" "- Away mode: active" "afk stanza missing"
|
|
38
|
+
assert_contains "$out" "- X mode: active" "x-mode stanza missing"
|
|
39
|
+
assert_contains "$out" "$config/x-mode.env" "x-mode stanza did not render the effective config path"
|
|
40
|
+
assert_contains "$out" 'Mode: Codex foreground checkpoint.' "codex snippet missing"
|
|
41
|
+
assert_not_contains "$out" "Source \`config/x-mode.env\`" "snippet kept the repo-relative x-mode config path"
|
|
42
|
+
pass "renderer includes read-only, afk, and effective x-mode current-state stanzas"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
test_repair_lines() {
|
|
46
|
+
local home out
|
|
47
|
+
home="$TMP_ROOT/repair-home"
|
|
48
|
+
mkdir -p "$home/state" "$home/config"
|
|
49
|
+
out=$(FM_HOME="$home" FM_CODEX_WATCH_CHECKPOINT=7 "$RENDER" --harness codex --repair-line)
|
|
50
|
+
assert_contains "$out" "bin/fm-watch-checkpoint.sh --seconds 7" "codex repair line did not use checkpoint helper and env override"
|
|
51
|
+
|
|
52
|
+
out=$(FM_HOME="$home" "$RENDER" --harness claude --queue-pending 1 --repair-line)
|
|
53
|
+
assert_contains "$out" "After draining queued wakes" "queue-pending prefix missing"
|
|
54
|
+
assert_contains "$out" "watcher supervision needs Stop-owned automatic recovery" "claude pre-verification repair line is not neutral"
|
|
55
|
+
assert_not_contains "$out" "is broken" "claude pre-verification repair line claimed a verified mechanism failure"
|
|
56
|
+
assert_not_contains "$out" "FAILED" "claude pre-verification repair line emitted a verified failure notice"
|
|
57
|
+
assert_not_contains "$out" "manual background" "claude pre-verification repair line directed a manual background arm"
|
|
58
|
+
assert_not_contains "$out" "bin/fm-watch-arm.sh" "claude pre-verification repair line directed an arm command"
|
|
59
|
+
|
|
60
|
+
: > "$home/config/x-mode.env"
|
|
61
|
+
out=$(FM_HOME="$home" FM_CODEX_WATCH_CHECKPOINT=7 "$RENDER" --harness codex --x-mode 1 --repair-line)
|
|
62
|
+
assert_contains "$out" "source '$home/config/x-mode.env' first" "x-mode repair line did not source the effective cadence config"
|
|
63
|
+
assert_contains "$out" "bin/fm-watch-checkpoint.sh --seconds 7" "x-mode codex repair line lost the checkpoint helper"
|
|
64
|
+
|
|
65
|
+
out=$(FM_HOME="$home" "$RENDER" --harness opencode --read-only 1 --repair-line)
|
|
66
|
+
assert_contains "$out" "session holding the fleet lock" "read-only repair line missing"
|
|
67
|
+
|
|
68
|
+
out=$(FM_HOME="$home" "$RENDER" --harness pi --repair-line)
|
|
69
|
+
assert_contains "$out" "Pi tool fm_watch_arm_pi" "pi repair line does not direct the model to the extension-owned tool"
|
|
70
|
+
assert_not_contains "$out" "extension command /fm-watch-arm-pi" "pi repair line still directs the model to the human slash command"
|
|
71
|
+
pass "renderer repair-line mode is harness-aware and honors conditional state"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
test_cross_harness_ordinary_continuation_and_repair_matrix() {
|
|
75
|
+
local ordinary out
|
|
76
|
+
|
|
77
|
+
out=$("$RENDER" --harness pi)
|
|
78
|
+
ordinary=$(printf '%s\n' "$out" | grep -F -- '- Ordinary wake:')
|
|
79
|
+
assert_contains "$ordinary" "Pi extension already owns watcher continuity" "pi ordinary-wake line does not leave continuity to the extension"
|
|
80
|
+
assert_not_contains "$ordinary" "fm_watch_arm_pi" "pi ordinary-wake line incorrectly calls the recovery tool"
|
|
81
|
+
out=$("$RENDER" --harness pi --repair-line)
|
|
82
|
+
assert_contains "$out" "fm_watch_arm_pi" "pi recovery line lost the extension-owned repair tool"
|
|
83
|
+
|
|
84
|
+
out=$("$RENDER" --harness opencode)
|
|
85
|
+
ordinary=$(printf '%s\n' "$out" | grep -F -- '- Ordinary wake:')
|
|
86
|
+
assert_contains "$ordinary" "plugin already owns watcher continuity" "opencode ordinary-wake line does not leave continuity to the plugin"
|
|
87
|
+
assert_not_contains "$ordinary" "bin/fm-watch-arm.sh" "opencode ordinary-wake line incorrectly calls the recovery probe"
|
|
88
|
+
out=$("$RENDER" --harness opencode --repair-line)
|
|
89
|
+
assert_contains "$out" "manual recovery probe" "opencode recovery line lost its manual probe"
|
|
90
|
+
|
|
91
|
+
out=$("$RENDER" --harness claude)
|
|
92
|
+
ordinary=$(printf '%s\n' "$out" | grep -F -- '- Ordinary wake:')
|
|
93
|
+
assert_contains "$ordinary" "Stop-owned auto-arm" "claude ordinary-wake line does not leave continuity to the Stop hook"
|
|
94
|
+
assert_contains "$ordinary" "bin/fm-claude-stop-autoarm.sh" "claude ordinary-wake line lost the auto-arm script name"
|
|
95
|
+
assert_contains "$ordinary" "do not arm another cycle" "claude ordinary-wake line does not forbid a model re-arm"
|
|
96
|
+
assert_not_contains "$ordinary" "bin/fm-watch-arm.sh" "claude ordinary-wake line incorrectly calls the manual arm"
|
|
97
|
+
out=$("$RENDER" --harness claude --repair-line)
|
|
98
|
+
assert_contains "$out" "watcher supervision needs Stop-owned automatic recovery" "claude recovery line lost its neutral automatic-recovery guidance"
|
|
99
|
+
assert_not_contains "$out" "is broken" "claude recovery line claimed failure before verification"
|
|
100
|
+
assert_not_contains "$out" "bin/fm-watch-arm.sh" "claude recovery line must not create a repeatable manual arm loop"
|
|
101
|
+
|
|
102
|
+
out=$("$RENDER" --harness grok)
|
|
103
|
+
ordinary=$(printf '%s\n' "$out" | grep -F -- '- Ordinary wake:')
|
|
104
|
+
assert_contains "$ordinary" "re-arm" "grok ordinary-wake line does not tell the model to re-arm"
|
|
105
|
+
assert_contains "$ordinary" "Grok tracked background task" "grok ordinary-wake line lost tracked background ownership"
|
|
106
|
+
assert_contains "$ordinary" "bin/fm-watch-arm.sh" "grok ordinary-wake line lost the background arm command"
|
|
107
|
+
out=$("$RENDER" --harness grok --repair-line)
|
|
108
|
+
assert_contains "$out" "Grok tracked background task" "grok recovery line lost its tracked background repair"
|
|
109
|
+
assert_contains "$out" "bin/fm-watch-arm.sh" "grok recovery line lost the arm command"
|
|
110
|
+
|
|
111
|
+
out=$("$RENDER" --harness codex)
|
|
112
|
+
ordinary=$(printf '%s\n' "$out" | grep -F -- '- Ordinary wake:')
|
|
113
|
+
assert_contains "$ordinary" "next foreground" "codex ordinary-wake line lost its foreground checkpoint"
|
|
114
|
+
assert_contains "$ordinary" "bin/fm-watch-checkpoint.sh" "codex ordinary-wake line lost the checkpoint command"
|
|
115
|
+
assert_not_contains "$ordinary" "bin/fm-watch-arm.sh" "codex ordinary-wake line incorrectly uses a background arm"
|
|
116
|
+
out=$("$RENDER" --harness codex --repair-line)
|
|
117
|
+
assert_contains "$out" "foreground checkpoint" "codex recovery line lost its checkpoint repair"
|
|
118
|
+
assert_contains "$out" "bin/fm-watch-checkpoint.sh" "codex recovery line lost the checkpoint command"
|
|
119
|
+
|
|
120
|
+
pass "renderer preserves every harness ordinary-continuation and missing-cycle repair path"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
test_pi_signed_preserves_identity_with_pi_supervision_protocol() {
|
|
124
|
+
local out ordinary
|
|
125
|
+
out=$("$RENDER" --harness pi-signed)
|
|
126
|
+
assert_contains "$out" "primary harness: pi-signed" \
|
|
127
|
+
"pi-signed supervision normalized the visible runtime identity to pi"
|
|
128
|
+
assert_contains "$out" "Mode: Pi extension background wake." \
|
|
129
|
+
"pi-signed did not reuse Pi's authoritative supervision protocol"
|
|
130
|
+
ordinary=$(printf '%s\n' "$out" | grep -F -- '- Ordinary wake:')
|
|
131
|
+
assert_contains "$ordinary" "Pi extension already owns watcher continuity" \
|
|
132
|
+
"pi-signed ordinary-wake semantics diverged from Pi"
|
|
133
|
+
out=$("$RENDER" --harness pi-signed --repair-line)
|
|
134
|
+
assert_contains "$out" "Pi tool fm_watch_arm_pi" \
|
|
135
|
+
"pi-signed repair semantics diverged from Pi"
|
|
136
|
+
pass "pi-signed keeps its identity while sharing Pi's supervision protocol"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
test_grok_is_background_notify() {
|
|
140
|
+
local out
|
|
141
|
+
out=$("$RENDER" --harness grok)
|
|
142
|
+
assert_contains "$out" "Mode: Grok background-notify supervision." "grok snippet missing background-notify mode"
|
|
143
|
+
assert_contains "$out" "background: true" "grok snippet missing tracked background tool instruction"
|
|
144
|
+
assert_contains "$out" "synthetic_reason: task_completed" "grok snippet missing auto-wake synthetic prompt detail"
|
|
145
|
+
assert_contains "$out" "bin/fm-watch-arm.sh" "grok snippet missing watcher arm"
|
|
146
|
+
assert_not_contains "$out" "__FM_X_MODE_ENV" "renderer leaked an x-mode path placeholder"
|
|
147
|
+
assert_not_contains "$out" "foreground checkpoint" "grok snippet must not be Codex-style foreground checkpoint"
|
|
148
|
+
out=$("$RENDER" --harness grok --repair-line)
|
|
149
|
+
assert_contains "$out" "Grok tracked background task" "grok repair line is not background-notify shaped"
|
|
150
|
+
pass "grok supervision is Claude-shaped background notify with passive Stop-hook backstop"
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
test_grok_command_sources_effective_config() {
|
|
154
|
+
local home config out
|
|
155
|
+
home="$TMP_ROOT/grok-home"
|
|
156
|
+
config="$TMP_ROOT/grok-config"
|
|
157
|
+
mkdir -p "$home/state" "$config"
|
|
158
|
+
out=$(FM_HOME="$home" FM_CONFIG_OVERRIDE="$config" "$RENDER" --harness grok --x-mode 1)
|
|
159
|
+
assert_contains "$out" "[ -f '$config/x-mode.env' ] && . '$config/x-mode.env'; exec bin/fm-watch-arm.sh" "grok arm command did not use the effective x-mode config path"
|
|
160
|
+
pass "grok rendered command sources the effective x-mode config"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
test_pi_snippet_uses_effective_extension_path() {
|
|
164
|
+
local home out turnend watch
|
|
165
|
+
home="$TMP_ROOT/pi-home"
|
|
166
|
+
turnend="$ROOT/.pi/extensions/fm-primary-turnend-guard.ts"
|
|
167
|
+
watch="$ROOT/.pi/extensions/fm-primary-pi-watch.ts"
|
|
168
|
+
mkdir -p "$home/state" "$home/config"
|
|
169
|
+
out=$(FM_HOME="$home" "$RENDER" --harness pi)
|
|
170
|
+
assert_contains "$out" "-e $turnend -e $watch" "pi snippet did not render both effective extension launch paths"
|
|
171
|
+
assert_contains "$out" "The turn-end guard extension lives at \`$turnend\`" "pi snippet did not render the turn-end guard extension path"
|
|
172
|
+
assert_contains "$out" "The watcher extension lives at \`$watch\`" "pi snippet did not render the watcher extension path"
|
|
173
|
+
assert_contains "$out" "MAIN must not re-drain, re-run, or acknowledge it" "pi snippet lost merged-event ownership"
|
|
174
|
+
assert_contains "$out" "MAIN applies judgment about whether and how to surface, summarize, reference, or incorporate a merged sailboat outcome" "pi snippet imposed a mechanical sailboat treatment"
|
|
175
|
+
assert_not_contains "$out" "__FM_PI_EXT__" "renderer leaked the Pi extension path placeholder"
|
|
176
|
+
assert_not_contains "$out" "__FM_PI_TURNEND_EXT__" "renderer leaked the Pi turn-end extension path placeholder"
|
|
177
|
+
assert_not_contains "$out" "state/fm-primary-pi-watch.ts" "pi snippet kept the old generated state-relative extension path"
|
|
178
|
+
pass "pi supervision snippet renders the effective extension path"
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
test_selected_harness_block_only
|
|
182
|
+
test_unknown_fallback
|
|
183
|
+
test_conditional_stanzas
|
|
184
|
+
test_repair_lines
|
|
185
|
+
test_cross_harness_ordinary_continuation_and_repair_matrix
|
|
186
|
+
test_pi_signed_preserves_identity_with_pi_supervision_protocol
|
|
187
|
+
test_grok_is_background_notify
|
|
188
|
+
test_grok_command_sources_effective_config
|
|
189
|
+
test_pi_snippet_uses_effective_extension_path
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavior tests for the worktree-tangle guards.
|
|
3
|
+
#
|
|
4
|
+
# Firstmate is a treehouse-pooled git repo of itself: linked worktrees and
|
|
5
|
+
# secondmate homes all sit at a detached HEAD on the default branch, while the
|
|
6
|
+
# PRIMARY checkout (FM_ROOT) is a normal checkout on a real branch. The "tangle"
|
|
7
|
+
# is a crewmate branching/committing in the primary instead of its own worktree,
|
|
8
|
+
# stranding the primary on a feature branch. Two guards cover it:
|
|
9
|
+
# GUARD 1 (prevention) - the brief asserts isolation before its branch step, and
|
|
10
|
+
# fm-spawn refuses to launch unless the resolved worktree is isolated.
|
|
11
|
+
# GUARD 2 (detection) - fm-guard and fm-bootstrap alarm when the primary is on
|
|
12
|
+
# a feature branch, and stay silent on the default branch or detached.
|
|
13
|
+
# These cases pin: the shared lib's branch classification, the fm-guard banner,
|
|
14
|
+
# the fm-bootstrap problem line, the brief assertion ordering, and the fm-spawn
|
|
15
|
+
# abort - all hermetic over temp git repos and fakebins.
|
|
16
|
+
set -u
|
|
17
|
+
|
|
18
|
+
# shellcheck source=tests/fixtures.sh
|
|
19
|
+
. "$(dirname "${BASH_SOURCE[0]}")/fixtures.sh"
|
|
20
|
+
|
|
21
|
+
# shellcheck source=/dev/null
|
|
22
|
+
. "$ROOT/bin/fm-tangle-lib.sh"
|
|
23
|
+
|
|
24
|
+
TMP_ROOT=$(fm_test_tmproot fm-tangle-guard)
|
|
25
|
+
fm_git_identity fmtest fmtest@example.invalid
|
|
26
|
+
|
|
27
|
+
# A fresh git repo on `main` with one commit and a local origin. Echoes its path.
|
|
28
|
+
make_repo() {
|
|
29
|
+
local dir=$1
|
|
30
|
+
git init -q -b main "$dir"
|
|
31
|
+
git -C "$dir" commit -q --allow-empty -m init
|
|
32
|
+
fm_git_add_origin "$dir" "$dir.origin.git"
|
|
33
|
+
printf '%s\n' "$dir"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# --- shared lib: branch classification --------------------------------------
|
|
37
|
+
|
|
38
|
+
# fm_primary_tangle_branch is the whole scoping decision: a NAMED non-default
|
|
39
|
+
# branch is the tangle; the default branch and detached HEAD are healthy.
|
|
40
|
+
test_lib_classification() {
|
|
41
|
+
local repo n=0 label state branch expect out
|
|
42
|
+
repo=$(make_repo "$TMP_ROOT/lib-repo")
|
|
43
|
+
while IFS='|' read -r label state branch expect; do
|
|
44
|
+
[ -n "$label" ] || continue
|
|
45
|
+
n=$((n + 1))
|
|
46
|
+
case "$state" in
|
|
47
|
+
default) git -C "$repo" checkout -q main ;;
|
|
48
|
+
feature) git -C "$repo" checkout -q -B "$branch" ;;
|
|
49
|
+
detached) git -C "$repo" checkout -q main; git -C "$repo" checkout -q --detach ;;
|
|
50
|
+
esac
|
|
51
|
+
out=$(fm_primary_tangle_branch "$repo" || true)
|
|
52
|
+
[ "$out" = "$expect" ] || fail "$label: expected tangle='$expect', got '$out'"
|
|
53
|
+
done <<'ROWS'
|
|
54
|
+
on the default branch is healthy|default||
|
|
55
|
+
on a feature branch is the tangle|feature|fm/readme-restructure-d3|fm/readme-restructure-d3
|
|
56
|
+
detached HEAD on default is healthy (worktrees, secondmate homes)|detached||
|
|
57
|
+
ROWS
|
|
58
|
+
# A non-git directory is not a tangle and must not error.
|
|
59
|
+
out=$(fm_primary_tangle_branch "$TMP_ROOT" || true)
|
|
60
|
+
[ -z "$out" ] || fail "non-git dir wrongly reported a tangle: '$out'"
|
|
61
|
+
pass "fm_primary_tangle_branch: feature branch alarms; default/detached/non-git stay silent"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# --- GUARD 2a: fm-guard banner ----------------------------------------------
|
|
65
|
+
|
|
66
|
+
run_guard() {
|
|
67
|
+
# Scope the guard to a temp repo as the primary checkout; state lives under it.
|
|
68
|
+
FM_ROOT_OVERRIDE="$1" FM_HOME="$1" "$ROOT/bin/fm-guard.sh" 2>&1
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
test_guard_banner() {
|
|
72
|
+
local repo out
|
|
73
|
+
repo=$(make_repo "$TMP_ROOT/guard-repo")
|
|
74
|
+
|
|
75
|
+
out=$(run_guard "$repo")
|
|
76
|
+
assert_not_contains "$out" "WORKTREE TANGLE" "guard alarmed while primary was on main"
|
|
77
|
+
|
|
78
|
+
git -C "$repo" checkout -q --detach
|
|
79
|
+
out=$(run_guard "$repo")
|
|
80
|
+
assert_not_contains "$out" "WORKTREE TANGLE" "guard alarmed on a detached HEAD (legitimate worktree state)"
|
|
81
|
+
|
|
82
|
+
git -C "$repo" checkout -q -B fm/tangle-aa1
|
|
83
|
+
out=$(run_guard "$repo")
|
|
84
|
+
assert_contains "$out" "WORKTREE TANGLE" "guard did not alarm on a feature branch in the primary"
|
|
85
|
+
assert_contains "$out" "fm/tangle-aa1" "guard banner did not name the offending branch"
|
|
86
|
+
assert_contains "$out" "checkout main" "guard banner did not print the restore remediation"
|
|
87
|
+
out=$(FM_GUARD_READ_ONLY=1 run_guard "$repo")
|
|
88
|
+
assert_contains "$out" "WORKTREE TANGLE" "read-only guard did not keep the tangle alarm"
|
|
89
|
+
assert_contains "$out" "read-only session must leave restore work" "read-only guard did not explain restore ownership"
|
|
90
|
+
assert_not_contains "$out" "checkout main" "read-only guard printed a state-changing restore command"
|
|
91
|
+
pass "fm-guard: bordered tangle banner fires only for a feature branch and suppresses repair commands in read-only mode"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# --- GUARD 2b: fm-bootstrap problem line ------------------------------------
|
|
95
|
+
|
|
96
|
+
run_bootstrap() {
|
|
97
|
+
# No projects/ under the home keeps fleet sync inert; grep isolates the line.
|
|
98
|
+
FM_ROOT_OVERRIDE="$1" FM_HOME="$1" "$ROOT/bin/fm-bootstrap.sh" 2>/dev/null
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
test_bootstrap_line() {
|
|
102
|
+
local repo out
|
|
103
|
+
repo=$(make_repo "$TMP_ROOT/bootstrap-repo")
|
|
104
|
+
|
|
105
|
+
out=$(run_bootstrap "$repo" | grep '^TANGLE:' || true)
|
|
106
|
+
[ -z "$out" ] || fail "bootstrap emitted a TANGLE line while on main: $out"
|
|
107
|
+
|
|
108
|
+
git -C "$repo" checkout -q --detach
|
|
109
|
+
out=$(run_bootstrap "$repo" | grep '^TANGLE:' || true)
|
|
110
|
+
[ -z "$out" ] || fail "bootstrap emitted a TANGLE line on a detached HEAD: $out"
|
|
111
|
+
|
|
112
|
+
git -C "$repo" checkout -q -B fm/tangle-bb2
|
|
113
|
+
out=$(run_bootstrap "$repo" | grep '^TANGLE:' || true)
|
|
114
|
+
assert_contains "$out" "fm/tangle-bb2" "bootstrap did not report the tangled branch"
|
|
115
|
+
assert_contains "$out" "checkout main" "bootstrap TANGLE line lacked the restore remediation"
|
|
116
|
+
out=$(FM_ROOT_OVERRIDE="$repo" FM_HOME="$repo" FM_BOOTSTRAP_DETECT_ONLY=1 "$ROOT/bin/fm-bootstrap.sh" 2>/dev/null | grep '^TANGLE:' || true)
|
|
117
|
+
assert_contains "$out" "fm/tangle-bb2" "detect-only bootstrap did not report the tangled branch"
|
|
118
|
+
assert_contains "$out" "read-only session must leave restore work" "detect-only bootstrap did not explain restore ownership"
|
|
119
|
+
assert_not_contains "$out" "checkout main" "detect-only bootstrap printed a state-changing restore command"
|
|
120
|
+
pass "fm-bootstrap: TANGLE problem line fires only for a feature branch and suppresses repair commands in detect-only mode"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
# --- GUARD 1a: brief isolation assertion ------------------------------------
|
|
124
|
+
|
|
125
|
+
# The generated ship brief must carry the isolation assertion AHEAD of the
|
|
126
|
+
# `git checkout -b` step, so the crewmate verifies its worktree before branching.
|
|
127
|
+
test_brief_assertion_precedes_branch() {
|
|
128
|
+
local home brief iso br
|
|
129
|
+
home="$TMP_ROOT/brief-home"
|
|
130
|
+
mkdir -p "$home/data"
|
|
131
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" tangle-brief-cc3 alpha --mode no-mistakes >/dev/null 2>&1
|
|
132
|
+
brief="$home/data/tangle-brief-cc3/brief.md"
|
|
133
|
+
assert_present "$brief" "brief was not scaffolded"
|
|
134
|
+
assert_grep "blocked: launched in primary checkout, not an isolated worktree" "$brief" \
|
|
135
|
+
"brief is missing the isolation blocked-status contract"
|
|
136
|
+
assert_grep "The path check is authoritative" "$brief" \
|
|
137
|
+
"brief must make the path check authoritative"
|
|
138
|
+
assert_no_grep "A reliable test that you are in a linked worktree" "$brief" \
|
|
139
|
+
"brief must not present git-dir/common-dir as decisive"
|
|
140
|
+
assert_no_grep "they are identical in the primary checkout" "$brief" \
|
|
141
|
+
"brief must not claim the primary checkout has identical git dirs"
|
|
142
|
+
iso=$(grep -n 'launched in primary checkout, not an isolated worktree' "$brief" | head -1 | cut -d: -f1)
|
|
143
|
+
br=$(grep -n 'git checkout -b fm/' "$brief" | head -1 | cut -d: -f1)
|
|
144
|
+
if [ -z "$iso" ] || [ -z "$br" ]; then
|
|
145
|
+
fail "brief missing assertion ($iso) or branch step ($br)"
|
|
146
|
+
fi
|
|
147
|
+
[ "$iso" -lt "$br" ] || fail "isolation assertion (line $iso) must precede the branch step (line $br)"
|
|
148
|
+
pass "fm-brief: ship brief asserts worktree isolation before the branch step"
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# --- GUARD 1b: fm-spawn isolation abort -------------------------------------
|
|
152
|
+
|
|
153
|
+
# Spawn isolation uses the shared spawn fakebin (pane path + window ops).
|
|
154
|
+
run_spawn() {
|
|
155
|
+
local home=$1 id=$2 proj=$3 pane=$4 fakebin=$5
|
|
156
|
+
fm_test_spawn_brief "$home" "$id" brief
|
|
157
|
+
fm_test_run_spawn "$home" "$pane" "$fakebin" \
|
|
158
|
+
"$id" "$proj" codex --mode no-mistakes --yolo off
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
test_spawn_isolation_abort() {
|
|
162
|
+
local home proj fakebin out status
|
|
163
|
+
home="$TMP_ROOT/spawn-home"
|
|
164
|
+
mkdir -p "$home/data"
|
|
165
|
+
proj=$(make_repo "$TMP_ROOT/spawn-proj")
|
|
166
|
+
fakebin=$(make_spawn_fakebin "$TMP_ROOT/spawn-fake")
|
|
167
|
+
# A genuine isolated linked worktree of the project, detached on the default.
|
|
168
|
+
git -C "$proj" worktree add -q --detach "$TMP_ROOT/spawn-wt" >/dev/null 2>&1
|
|
169
|
+
mkdir -p "$TMP_ROOT/spawn-notgit" "$proj/sub"
|
|
170
|
+
|
|
171
|
+
# Abort: the pane resolves to a plain non-git directory (not a worktree at all).
|
|
172
|
+
out=$(run_spawn "$home" abort-notgit-dd4 "$proj" "$TMP_ROOT/spawn-notgit" "$fakebin"); status=$?
|
|
173
|
+
expect_code 1 "$status" "spawn into a non-worktree dir should abort"
|
|
174
|
+
assert_contains "$out" "did not yield an isolated worktree" "non-worktree spawn lacked the isolation error"
|
|
175
|
+
assert_absent "$home/state/abort-notgit-dd4.meta" "aborted spawn must not record meta"
|
|
176
|
+
|
|
177
|
+
# Abort: the pane resolves INTO the primary checkout (a subdir of PROJ_ABS).
|
|
178
|
+
out=$(run_spawn "$home" abort-primary-ee5 "$proj" "$proj/sub" "$fakebin"); status=$?
|
|
179
|
+
expect_code 1 "$status" "spawn landing inside the primary checkout should abort"
|
|
180
|
+
assert_contains "$out" "did not yield an isolated worktree" "primary-checkout spawn lacked the isolation error"
|
|
181
|
+
|
|
182
|
+
# Proceed: the pane resolves to a genuine, isolated worktree.
|
|
183
|
+
out=$(run_spawn "$home" ok-isolated-ff6 "$proj" "$TMP_ROOT/spawn-wt" "$fakebin"); status=$?
|
|
184
|
+
expect_code 0 "$status" "spawn into a genuine isolated worktree should succeed"
|
|
185
|
+
assert_contains "$out" "spawned ok-isolated-ff6" "isolated spawn did not report success"
|
|
186
|
+
assert_not_contains "$out" "did not yield an isolated worktree" "isolated spawn wrongly tripped the guard"
|
|
187
|
+
pass "fm-spawn: aborts unless the resolved worktree is a genuine, isolated worktree"
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# --- GUARD 1c: fm-spawn tmux window construction ----------------------------
|
|
191
|
+
|
|
192
|
+
# The prevention guard also depends on fm-spawn building robust tmux commands
|
|
193
|
+
# under a non-default tmux config (base-index 1, automatic-rename on). A RECORDING
|
|
194
|
+
# fake tmux logs every invocation and returns a sentinel window id, so these
|
|
195
|
+
# assertions pin the command construction deterministically, with no live tmux:
|
|
196
|
+
# - window creation targets the session with a trailing colon (append form), so
|
|
197
|
+
# tmux appends at the next free index instead of the active window index, which
|
|
198
|
+
# collides under base-index 1;
|
|
199
|
+
# - the window id is captured (-P -F #{window_id}) and automatic-rename/allow-rename
|
|
200
|
+
# are disabled so the fm-<id> name survives treehouse cd'ing into the worktree;
|
|
201
|
+
# - the treehouse-get send-keys and the worktree wait loop target that stable
|
|
202
|
+
# window id, never the (possibly-renamed) name - a lost name would let
|
|
203
|
+
# display-message fall back to the active client's window and misread firstmate's
|
|
204
|
+
# OWN pane as the worktree, tangling a hook into the primary checkout.
|
|
205
|
+
make_spawn_record_fakebin() {
|
|
206
|
+
local dir=$1 fakebin
|
|
207
|
+
fakebin=$(fm_fakebin "$dir")
|
|
208
|
+
cat > "$fakebin/tmux" <<'SH'
|
|
209
|
+
#!/usr/bin/env bash
|
|
210
|
+
set -u
|
|
211
|
+
[ -n "${FM_TMUX_REC:-}" ] && printf 'tmux %s\n' "$*" >> "$FM_TMUX_REC"
|
|
212
|
+
case "$*" in
|
|
213
|
+
*"#{pane_current_path}"*) printf '%s\n' "${FM_FAKE_PANE_PATH:-}"; exit 0 ;;
|
|
214
|
+
esac
|
|
215
|
+
case "${1:-}" in
|
|
216
|
+
display-message) printf 'firstmate\n'; exit 0 ;;
|
|
217
|
+
new-window) printf '%s\n' "@spawnwid"; exit 0 ;;
|
|
218
|
+
list-windows) exit 0 ;;
|
|
219
|
+
has-session|new-session|send-keys|set-window-option) exit 0 ;;
|
|
220
|
+
esac
|
|
221
|
+
exit 0
|
|
222
|
+
SH
|
|
223
|
+
chmod +x "$fakebin/tmux"
|
|
224
|
+
fm_fake_exit0 "$fakebin" treehouse
|
|
225
|
+
printf '%s\n' "$fakebin"
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
run_spawn_record() {
|
|
229
|
+
local home=$1 id=$2 proj=$3 pane=$4 fakebin=$5 rec=$6
|
|
230
|
+
fm_test_spawn_brief "$home" "$id" brief
|
|
231
|
+
FM_TMUX_REC="$rec" \
|
|
232
|
+
fm_test_run_spawn "$home" "$pane" "$fakebin" \
|
|
233
|
+
"$id" "$proj" codex --mode no-mistakes --yolo off
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
test_spawn_tmux_window_construction() {
|
|
237
|
+
local home proj fakebin rec wt out status
|
|
238
|
+
home="$TMP_ROOT/spawn-rec-home"
|
|
239
|
+
mkdir -p "$home/data"
|
|
240
|
+
proj=$(make_repo "$TMP_ROOT/spawn-rec-proj")
|
|
241
|
+
fakebin=$(make_spawn_record_fakebin "$TMP_ROOT/spawn-rec-fake")
|
|
242
|
+
rec="$TMP_ROOT/spawn-rec.log"
|
|
243
|
+
: > "$rec"
|
|
244
|
+
wt="$TMP_ROOT/spawn-rec-wt"
|
|
245
|
+
git -C "$proj" worktree add -q --detach "$wt" >/dev/null 2>&1
|
|
246
|
+
|
|
247
|
+
out=$(run_spawn_record "$home" rec-win-gg7 "$proj" "$wt" "$fakebin" "$rec"); status=$?
|
|
248
|
+
expect_code 0 "$status" "spawn into a genuine worktree should succeed"
|
|
249
|
+
assert_contains "$out" "spawned rec-win-gg7" "recording spawn did not report success"
|
|
250
|
+
|
|
251
|
+
# Bug 1 fix: append-form window creation (trailing colon on the session target).
|
|
252
|
+
assert_grep "new-window -dP -F #{window_id} -t firstmate: -n fm-rec-win-gg7" "$rec" \
|
|
253
|
+
"new-window must append at the session (trailing colon) and capture the window id"
|
|
254
|
+
assert_no_grep "new-window -dP -F #{window_id} -t firstmate -n" "$rec" \
|
|
255
|
+
"new-window must not target the bare session name (collides under base-index 1)"
|
|
256
|
+
|
|
257
|
+
# Bug 2 fix (a): pin the window name against automatic-rename / allow-rename.
|
|
258
|
+
assert_grep "set-window-option -t @spawnwid automatic-rename off" "$rec" \
|
|
259
|
+
"must disable automatic-rename on the spawned window"
|
|
260
|
+
assert_grep "set-window-option -t @spawnwid allow-rename off" "$rec" \
|
|
261
|
+
"must disable allow-rename on the spawned window"
|
|
262
|
+
|
|
263
|
+
# Bug 2 fix (b): treehouse-get and the worktree wait loop target the stable id.
|
|
264
|
+
assert_grep "send-keys -t @spawnwid treehouse get Enter" "$rec" \
|
|
265
|
+
"treehouse get must be sent to the stable window id"
|
|
266
|
+
assert_grep "display-message -p -t @spawnwid #{pane_current_path}" "$rec" \
|
|
267
|
+
"the worktree wait loop must query the stable window id, not the name"
|
|
268
|
+
|
|
269
|
+
pass "fm-spawn: appends windows by session-colon, pins the name, and targets the window id"
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
test_lib_classification
|
|
273
|
+
test_guard_banner
|
|
274
|
+
test_bootstrap_line
|
|
275
|
+
test_brief_assertion_precedes_branch
|
|
276
|
+
test_spawn_isolation_abort
|
|
277
|
+
test_spawn_tmux_window_construction
|