@zerwiz/ymir 0.1.4 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +291 -0
- package/.agents/agents/bragi-marketer.md +111 -0
- package/.agents/agents/brokk.md +352 -0
- package/.agents/agents/forseti-reviewer.md +93 -0
- package/.agents/agents/frigg-consent.md +77 -0
- package/.agents/agents/groa-update.md +77 -0
- package/.agents/agents/hnoss-designer.md +69 -0
- package/.agents/agents/huginn-researcher.md +99 -0
- package/.agents/agents/jord-projects.md +78 -0
- package/.agents/agents/kvasir-scout.md +91 -0
- package/.agents/agents/mimir-planner.md +92 -0
- package/.agents/agents/muninn-stow.md +77 -0
- package/.agents/agents/saga-bearings.md +78 -0
- package/.agents/agents/sindri-developer.md +114 -0
- package/.agents/agents/snotra-documenter.md +105 -0
- package/.agents/agents/syn-recovery.md +78 -0
- package/.agents/agents/tyr-check.md +78 -0
- package/.agents/agents/urdh-hold.md +77 -0
- package/.agents/agents/volundr-smith.md +80 -0
- package/.agents/agents/vor-diagnostics.md +77 -0
- package/.agents/assets/agents/naming.md +50 -0
- package/.agents/assets/agents/registry.md +93 -0
- package/.agents/assets/agents/runtime.md +36 -0
- package/.agents/assets/agents/toon-tasks-cli.md +42 -0
- package/.agents/assets/templates/company_entity.template.md +37 -0
- package/.agents/backend/README.md +74 -0
- package/.agents/backend/backends/cmux.sh +649 -0
- package/.agents/backend/backends/herdr-eventwait.py +157 -0
- package/.agents/backend/backends/herdr-workspace-move.py +114 -0
- package/.agents/backend/backends/herdr.sh +3386 -0
- package/.agents/backend/backends/orca.sh +290 -0
- package/.agents/backend/backends/tmux.sh +357 -0
- package/.agents/backend/backends/zellij.sh +700 -0
- package/.agents/backend/fm-afk-launch.sh +654 -0
- package/.agents/backend/fm-afk-return.sh +241 -0
- package/.agents/backend/fm-afk-start.sh +172 -0
- package/.agents/backend/fm-arm-command-policy.mjs +960 -0
- package/.agents/backend/fm-arm-pretool-check.sh +200 -0
- package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
- package/.agents/backend/fm-backend.sh +981 -0
- package/.agents/backend/fm-backlog-handoff.sh +909 -0
- package/.agents/backend/fm-backlog-receive.sh +187 -0
- package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
- package/.agents/backend/fm-bearings-board.sh +204 -0
- package/.agents/backend/fm-bearings-snapshot.sh +546 -0
- package/.agents/backend/fm-bootstrap.sh +1568 -0
- package/.agents/backend/fm-branch-outcome.sh +203 -0
- package/.agents/backend/fm-branch-prompt.sh +101 -0
- package/.agents/backend/fm-brief.sh +452 -0
- package/.agents/backend/fm-busy-event.sh +234 -0
- package/.agents/backend/fm-busy-lib.sh +986 -0
- package/.agents/backend/fm-captain-hold.sh +1001 -0
- package/.agents/backend/fm-cd-command-policy.mjs +153 -0
- package/.agents/backend/fm-cd-pretool-check.sh +190 -0
- package/.agents/backend/fm-check-lib.sh +74 -0
- package/.agents/backend/fm-check-register.sh +42 -0
- package/.agents/backend/fm-check-unregister.sh +52 -0
- package/.agents/backend/fm-classify-lib.sh +1770 -0
- package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
- package/.agents/backend/fm-composer-lib.sh +1416 -0
- package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
- package/.agents/backend/fm-config-push.sh +254 -0
- package/.agents/backend/fm-control-lib.sh +251 -0
- package/.agents/backend/fm-control.sh +878 -0
- package/.agents/backend/fm-crew-state.sh +625 -0
- package/.agents/backend/fm-cursor-lib.sh +243 -0
- package/.agents/backend/fm-decision-hold.sh +232 -0
- package/.agents/backend/fm-doc-audience-check.sh +269 -0
- package/.agents/backend/fm-dod-lib.sh +67 -0
- package/.agents/backend/fm-ensure-agents-md.sh +253 -0
- package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
- package/.agents/backend/fm-extension.mjs +2577 -0
- package/.agents/backend/fm-extension.sh +16 -0
- package/.agents/backend/fm-ff-lib.sh +420 -0
- package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
- package/.agents/backend/fm-fleet-sync.sh +458 -0
- package/.agents/backend/fm-fleet-view.sh +96 -0
- package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
- package/.agents/backend/fm-guard.sh +242 -0
- package/.agents/backend/fm-harness.sh +195 -0
- package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
- package/.agents/backend/fm-herdr-lab.sh +346 -0
- package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
- package/.agents/backend/fm-home-seed.sh +984 -0
- package/.agents/backend/fm-home-summary-refresh.sh +255 -0
- package/.agents/backend/fm-hook-host-lib.sh +36 -0
- package/.agents/backend/fm-inactive-reconcile.sh +531 -0
- package/.agents/backend/fm-inbox.sh +399 -0
- package/.agents/backend/fm-install-actionlint.sh +84 -0
- package/.agents/backend/fm-install-herdr.sh +96 -0
- package/.agents/backend/fm-install-shellcheck.sh +84 -0
- package/.agents/backend/fm-install-treehouse.sh +95 -0
- package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
- package/.agents/backend/fm-lease-lib.sh +218 -0
- package/.agents/backend/fm-lease.sh +189 -0
- package/.agents/backend/fm-line-cap-lib.sh +51 -0
- package/.agents/backend/fm-lint-workflows.sh +137 -0
- package/.agents/backend/fm-lint.sh +591 -0
- package/.agents/backend/fm-lock-lib.sh +104 -0
- package/.agents/backend/fm-lock.sh +107 -0
- package/.agents/backend/fm-marker-lib.sh +12 -0
- package/.agents/backend/fm-merge-local.sh +74 -0
- package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
- package/.agents/backend/fm-nm-run-lib.sh +124 -0
- package/.agents/backend/fm-on.sh +125 -0
- package/.agents/backend/fm-operational-input.sh +253 -0
- package/.agents/backend/fm-peek.sh +46 -0
- package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
- package/.agents/backend/fm-pr-check.sh +135 -0
- package/.agents/backend/fm-pr-lib.sh +1016 -0
- package/.agents/backend/fm-pr-merge.sh +707 -0
- package/.agents/backend/fm-pr-poll.sh +110 -0
- package/.agents/backend/fm-primary-scope-lib.sh +33 -0
- package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
- package/.agents/backend/fm-procevent-lavish.sh +628 -0
- package/.agents/backend/fm-procevent-lib.sh +892 -0
- package/.agents/backend/fm-procevent-quota.sh +290 -0
- package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
- package/.agents/backend/fm-procevent-when.sh +504 -0
- package/.agents/backend/fm-procevent.sh +1466 -0
- package/.agents/backend/fm-project-mode.sh +92 -0
- package/.agents/backend/fm-project-origin-lib.sh +180 -0
- package/.agents/backend/fm-promote.sh +282 -0
- package/.agents/backend/fm-public-followup-emit.sh +260 -0
- package/.agents/backend/fm-public-followup-lib.sh +398 -0
- package/.agents/backend/fm-public-followup.sh +1330 -0
- package/.agents/backend/fm-push-transition-lib.sh +168 -0
- package/.agents/backend/fm-quota-axi-lib.sh +93 -0
- package/.agents/backend/fm-quota-choose.sh +384 -0
- package/.agents/backend/fm-remote-delta-read.sh +189 -0
- package/.agents/backend/fm-remote-doctor.sh +800 -0
- package/.agents/backend/fm-remote-entrypoint.sh +193 -0
- package/.agents/backend/fm-remote-file.sh +234 -0
- package/.agents/backend/fm-remote-home-provision.sh +259 -0
- package/.agents/backend/fm-remote-home-seed.sh +259 -0
- package/.agents/backend/fm-remote-inherit-push.sh +90 -0
- package/.agents/backend/fm-remote-inherit.sh +179 -0
- package/.agents/backend/fm-remote-job-lib.sh +1241 -0
- package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
- package/.agents/backend/fm-remote-job-worker.sh +1124 -0
- package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
- package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
- package/.agents/backend/fm-review-diff.sh +158 -0
- package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
- package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
- package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
- package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
- package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
- package/.agents/backend/fm-secondmate-report.sh +88 -0
- package/.agents/backend/fm-send.sh +1059 -0
- package/.agents/backend/fm-session-lock-lib.sh +176 -0
- package/.agents/backend/fm-session-start.sh +970 -0
- package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
- package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
- package/.agents/backend/fm-sessionstart-run.sh +145 -0
- package/.agents/backend/fm-spawn.sh +3153 -0
- package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
- package/.agents/backend/fm-startup-memory-budget.sh +94 -0
- package/.agents/backend/fm-startup-network.sh +642 -0
- package/.agents/backend/fm-stow-cascade.sh +251 -0
- package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
- package/.agents/backend/fm-supervise-daemon.sh +1732 -0
- package/.agents/backend/fm-supervision-instructions.sh +215 -0
- package/.agents/backend/fm-supervision-lib.sh +90 -0
- package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
- package/.agents/backend/fm-tangle-lib.sh +53 -0
- package/.agents/backend/fm-task-inbox-lib.sh +402 -0
- package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
- package/.agents/backend/fm-teardown.sh +2922 -0
- package/.agents/backend/fm-test-isolation-proof.sh +588 -0
- package/.agents/backend/fm-test-run.sh +2191 -0
- package/.agents/backend/fm-timeout-lib.sh +141 -0
- package/.agents/backend/fm-timing-lib.sh +179 -0
- package/.agents/backend/fm-tmux-lib.sh +291 -0
- package/.agents/backend/fm-tool-update-check.sh +898 -0
- package/.agents/backend/fm-trace-context-lib.sh +227 -0
- package/.agents/backend/fm-transition-lib.sh +103 -0
- package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
- package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
- package/.agents/backend/fm-turnend-guard.sh +432 -0
- package/.agents/backend/fm-update.sh +110 -0
- package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
- package/.agents/backend/fm-voice-client.py +1373 -0
- package/.agents/backend/fm-voice-relay.py +1256 -0
- package/.agents/backend/fm-wake-drain.sh +592 -0
- package/.agents/backend/fm-wake-grant.sh +127 -0
- package/.agents/backend/fm-wake-lib.sh +1849 -0
- package/.agents/backend/fm-watch-arm.sh +602 -0
- package/.agents/backend/fm-watch-checkpoint.sh +109 -0
- package/.agents/backend/fm-watch.sh +1962 -0
- package/.agents/backend/fm-x-dismiss.sh +116 -0
- package/.agents/backend/fm-x-followup.sh +286 -0
- package/.agents/backend/fm-x-lib.sh +1000 -0
- package/.agents/backend/fm-x-link.sh +234 -0
- package/.agents/backend/fm-x-poll.sh +185 -0
- package/.agents/backend/fm-x-reply.sh +385 -0
- package/.agents/backend/fm_voice_frame.py +166 -0
- package/.agents/backend/fm_voice_records.py +574 -0
- package/.agents/backend/model-bridge.py +360 -0
- package/.agents/backend/opencode-go-bridge.py +30 -0
- package/.agents/bus/README.md +12 -0
- package/.agents/bus/messages.json +1 -0
- package/.agents/config/agents.machine.example.yaml +16 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +11 -0
- package/.agents/config/eindri-dispatch.json +67 -0
- package/.agents/config/eindri-harness +1 -0
- package/.agents/config/startup-memory-budget +1 -0
- package/.agents/filebrowser/.filebrowser.json +6 -0
- package/.agents/filebrowser/README.md +11 -0
- package/.agents/gateway/README.md +12 -0
- package/.agents/github/README.md +15 -0
- package/.agents/github/webhooks/.gitkeep +0 -0
- package/.agents/github/workflows/.gitkeep +0 -0
- package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
- package/.agents/harness/opencode/plugins/package.json +4 -0
- package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
- package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
- package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
- package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
- package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
- package/.agents/memory/README.md +46 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/migrations/0001-hodd-layout.sh +38 -0
- package/.agents/migrations/0002-a2a-mcp.sh +27 -0
- package/.agents/migrations/0003-private-data-separation.sh +121 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/migrations/0005-roots-out-of-tree.sh +158 -0
- package/.agents/sandbox/Dockerfile.utgard +19 -0
- package/.agents/sandbox/README.md +14 -0
- package/.agents/sandbox/utgard.config.json +14 -0
- package/.agents/skills/README.md +59 -0
- package/.agents/skills/bragi-marketing/README.md +3 -0
- package/.agents/skills/bragi-marketing/SKILL.md +82 -0
- package/.agents/skills/eindri-homes/README.md +3 -0
- package/.agents/skills/eindri-homes/SKILL.md +291 -0
- package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
- package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
- package/.agents/skills/frigg-consent/README.md +3 -0
- package/.agents/skills/frigg-consent/SKILL.md +56 -0
- package/.agents/skills/galdr-ymirsystem/README.md +3 -0
- package/.agents/skills/galdr-ymirsystem/SKILL.md +159 -0
- package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
- package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +736 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
- package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +539 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +763 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
- package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +415 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +133 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +101 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
- package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
- package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
- package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
- package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
- package/.agents/skills/galdr-ymirsystem/assets/smidja.md +180 -0
- package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
- package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
- package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
- package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +503 -0
- package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
- package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
- package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
- package/.agents/skills/gjallarhorn-relay/README.md +3 -0
- package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
- package/.agents/skills/groa-update/SKILL.md +90 -0
- package/.agents/skills/hamr-adapters/README.md +3 -0
- package/.agents/skills/hamr-adapters/SKILL.md +123 -0
- package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
- package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
- package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
- package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
- package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
- package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
- package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
- package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
- package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
- package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
- package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
- package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
- package/.agents/skills/herdr-panes/README.md +3 -0
- package/.agents/skills/herdr-panes/SKILL.md +92 -0
- package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
- package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
- package/.agents/skills/hnoss-design/DESIGN.md +19 -0
- package/.agents/skills/hnoss-design/README.md +3 -0
- package/.agents/skills/hnoss-design/SKILL.md +83 -0
- package/.agents/skills/hvild-afk/README.md +3 -0
- package/.agents/skills/hvild-afk/SKILL.md +241 -0
- package/.agents/skills/jord-projects/README.md +3 -0
- package/.agents/skills/jord-projects/SKILL.md +92 -0
- package/.agents/skills/lifecycle/SKILL.md +56 -0
- package/.agents/skills/lifecycle/smoke_test.sh +57 -0
- package/.agents/skills/lifecycle/start.sh +21 -0
- package/.agents/skills/lifecycle/status.sh +35 -0
- package/.agents/skills/lifecycle/stop.sh +16 -0
- package/.agents/skills/muninn-stow/README.md +3 -0
- package/.agents/skills/muninn-stow/SKILL.md +309 -0
- package/.agents/skills/no-mistakes/SKILL.md +379 -0
- package/.agents/skills/nornir-schedule/README.md +3 -0
- package/.agents/skills/nornir-schedule/SKILL.md +25 -0
- package/.agents/skills/nornir-schedule/assets/events.md +137 -0
- package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
- package/.agents/skills/nsr-compliance/README.md +3 -0
- package/.agents/skills/nsr-compliance/SKILL.md +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/pr-ops/README.md +3 -0
- package/.agents/skills/pr-ops/SKILL.md +109 -0
- package/.agents/skills/ratatoskr-a2a/README.md +3 -0
- package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
- package/.agents/skills/rules-check-drift/SKILL.md +81 -0
- package/.agents/skills/saga-bearings/README.md +3 -0
- package/.agents/skills/saga-bearings/SKILL.md +26 -0
- package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
- package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
- package/.agents/skills/saga-bearings/assets/recap.md +56 -0
- package/.agents/skills/syn-recovery/README.md +3 -0
- package/.agents/skills/syn-recovery/SKILL.md +54 -0
- package/.agents/skills/tyr-check/README.md +3 -0
- package/.agents/skills/tyr-check/SKILL.md +218 -0
- package/.agents/skills/urdh-hold/README.md +3 -0
- package/.agents/skills/urdh-hold/SKILL.md +25 -0
- package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
- package/.agents/skills/urdh-hold/assets/hold.md +54 -0
- package/.agents/skills/vor-diagnostics/README.md +3 -0
- package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
- package/.agents/skills/ymir-host/README.md +3 -0
- package/.agents/skills/ymir-host/SKILL.md +35 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/install.md +69 -0
- package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
- package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
- package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
- package/.agents/skills/ymir-host/assets/update.md +64 -0
- package/.agents/tests/assets/board-render-harness.mjs +117 -0
- package/.agents/tests/cmux-test-safety.sh +51 -0
- package/.agents/tests/fixtures.sh +291 -0
- package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
- package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
- package/.agents/tests/fm-afk-launch.test.sh +961 -0
- package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
- package/.agents/tests/fm-afk-return.test.sh +283 -0
- package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
- package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
- package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
- package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
- package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
- package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
- package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
- package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
- package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
- package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
- package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
- package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
- package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
- package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
- package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
- package/.agents/tests/fm-backend-orca.test.sh +1357 -0
- package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
- package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
- package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
- package/.agents/tests/fm-backend.test.sh +1142 -0
- package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
- package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
- package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
- package/.agents/tests/fm-bearings-board.test.sh +414 -0
- package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
- package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
- package/.agents/tests/fm-bootstrap.test.sh +1178 -0
- package/.agents/tests/fm-branch-supervision.test.sh +552 -0
- package/.agents/tests/fm-brief.test.sh +785 -0
- package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
- package/.agents/tests/fm-busy-state.test.sh +465 -0
- package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
- package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
- package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
- package/.agents/tests/fm-check-unregister.test.sh +198 -0
- package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
- package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
- package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
- package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
- package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
- package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
- package/.agents/tests/fm-composer-ghost.test.sh +716 -0
- package/.agents/tests/fm-composer-lib.test.sh +666 -0
- package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
- package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
- package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
- package/.agents/tests/fm-control.test.sh +910 -0
- package/.agents/tests/fm-crew-state.test.sh +1610 -0
- package/.agents/tests/fm-cursor-harness.test.sh +404 -0
- package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
- package/.agents/tests/fm-cursor-primary.test.sh +708 -0
- package/.agents/tests/fm-daemon.test.sh +2740 -0
- package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
- package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
- package/.agents/tests/fm-extension-binding.test.sh +2187 -0
- package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
- package/.agents/tests/fm-fleet-sync.test.sh +721 -0
- package/.agents/tests/fm-gate-refuse.test.sh +356 -0
- package/.agents/tests/fm-gitignore-config.test.sh +89 -0
- package/.agents/tests/fm-gotmp.test.sh +230 -0
- package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
- package/.agents/tests/fm-grok-harness.test.sh +117 -0
- package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
- package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
- package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
- package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
- package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
- package/.agents/tests/fm-herdr-lab.test.sh +243 -0
- package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
- package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
- package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
- package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
- package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
- package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
- package/.agents/tests/fm-kimi-harness.test.sh +687 -0
- package/.agents/tests/fm-lint-workflows.test.sh +532 -0
- package/.agents/tests/fm-lint.test.sh +1023 -0
- package/.agents/tests/fm-muse-harness.test.sh +932 -0
- package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
- package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
- package/.agents/tests/fm-on.test.sh +507 -0
- package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
- package/.agents/tests/fm-operational-input.test.sh +160 -0
- package/.agents/tests/fm-peek-remote.test.sh +110 -0
- package/.agents/tests/fm-pending-reply.test.sh +1288 -0
- package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
- package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
- package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
- package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
- package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
- package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
- package/.agents/tests/fm-pr-merge.test.sh +2135 -0
- package/.agents/tests/fm-procevent-quota.test.sh +225 -0
- package/.agents/tests/fm-procevent-when.test.sh +406 -0
- package/.agents/tests/fm-procevent.test.sh +1745 -0
- package/.agents/tests/fm-project-origin.test.sh +110 -0
- package/.agents/tests/fm-public-followup.test.sh +2272 -0
- package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
- package/.agents/tests/fm-quota-choose.test.sh +626 -0
- package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
- package/.agents/tests/fm-remote-doctor.test.sh +625 -0
- package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
- package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
- package/.agents/tests/fm-remote-job.test.sh +768 -0
- package/.agents/tests/fm-remote-reply.test.sh +520 -0
- package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
- package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
- package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
- package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
- package/.agents/tests/fm-review-diff.test.sh +176 -0
- package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
- package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
- package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
- package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
- package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
- package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
- package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
- package/.agents/tests/fm-send-inbox.test.sh +352 -0
- package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
- package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
- package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
- package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
- package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
- package/.agents/tests/fm-send-settle.test.sh +147 -0
- package/.agents/tests/fm-send-strict.test.sh +241 -0
- package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
- package/.agents/tests/fm-session-start.test.sh +2515 -0
- package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
- package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
- package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
- package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
- package/.agents/tests/fm-spawn-batch.test.sh +148 -0
- package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
- package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
- package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
- package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
- package/.agents/tests/fm-startup-network.test.sh +712 -0
- package/.agents/tests/fm-stow-cascade.test.sh +370 -0
- package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
- package/.agents/tests/fm-supervision-events.test.sh +156 -0
- package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
- package/.agents/tests/fm-tangle-guard.test.sh +277 -0
- package/.agents/tests/fm-task-delivery.test.sh +420 -0
- package/.agents/tests/fm-task-inbox.test.sh +513 -0
- package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
- package/.agents/tests/fm-teardown.test.sh +2665 -0
- package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
- package/.agents/tests/fm-test-fixtures.test.sh +132 -0
- package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
- package/.agents/tests/fm-test-run.test.sh +1196 -0
- package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
- package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
- package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
- package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
- package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
- package/.agents/tests/fm-transition-lib.test.sh +54 -0
- package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
- package/.agents/tests/fm-update.test.sh +304 -0
- package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
- package/.agents/tests/fm-voice-relay.test.sh +4741 -0
- package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
- package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
- package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
- package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
- package/.agents/tests/fm-wake-queue.test.sh +1224 -0
- package/.agents/tests/fm-watch-arm.test.sh +821 -0
- package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
- package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
- package/.agents/tests/fm-watch-triage.test.sh +3889 -0
- package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
- package/.agents/tests/fm-x-mode.test.sh +3042 -0
- package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
- package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
- package/.agents/tests/herdr-test-safety.sh +42 -0
- package/.agents/tests/lib.sh +315 -0
- package/.agents/tests/remote-herdr-fixture.sh +125 -0
- package/.agents/tests/secondmate-helpers.sh +193 -0
- package/.agents/tests/smoke.test.sh +93 -0
- package/.agents/tests/wake-helpers.sh +338 -0
- package/.agents/tests/zellij-test-safety.sh +60 -0
- package/.agents/tools/README.md +10 -0
- package/.agents/tools/bin/tasks-cli +267 -0
- package/.agents/tools/tasks-cli.ts +216 -0
- package/AGENTS.md +498 -0
- package/CHANGELOG.md +1913 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +114 -60
- package/RULES/01-domains.md +51 -0
- package/RULES/02-agents.md +78 -0
- package/RULES/03-houses.md +61 -0
- package/RULES/04-hoard.md +97 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +108 -0
- package/RULES/07-config.md +101 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/09-electron.md +58 -0
- package/RULES/README.md +22 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +133 -0
- package/bin/a2a-serve.py +103 -0
- package/bin/a2a-serve.sh +8 -0
- package/bin/a2a-talk.sh +50 -0
- package/bin/a2abridge-ensure.sh +108 -0
- package/bin/agent-run.sh +43 -0
- package/bin/agents-config.sh +256 -0
- package/bin/apodex-smoke-test.sh +105 -0
- package/bin/bifrost-bridge.sh +131 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +112 -0
- package/bin/bootstrap-windows.ps1 +112 -0
- package/bin/branch-guard.sh +64 -0
- package/bin/brokk +73 -0
- package/bin/brokk-classify-lib.sh +1770 -0
- package/bin/brokk-lease-lib.sh +222 -0
- package/bin/brokk-lease.sh +193 -0
- package/bin/brokk-lint.sh +65 -0
- package/bin/brokk-send.sh +51 -0
- package/bin/brokk-update.sh +9 -0
- package/bin/brokk-wake-grant.sh +127 -0
- package/bin/brokk-wake-lib.sh +1849 -0
- package/bin/changelog-assemble.sh +154 -0
- package/bin/changelog-guard.sh +197 -0
- package/bin/crash-sense.sh +173 -0
- package/bin/design-check.sh +80 -0
- package/bin/design-icon.sh +153 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +225 -0
- package/bin/eindri-acclaim.sh +47 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seat.sh +83 -0
- package/bin/eindri-seen.sh +54 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +98 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +158 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/feature-inventory.sh +73 -0
- package/bin/fleet-apply.sh +81 -0
- package/bin/github-deploy.sh +94 -0
- package/bin/gjallarhorn-expose.sh +136 -0
- package/bin/gjallarhorn-notify.sh +71 -0
- package/bin/gjallarhorn-purge.sh +67 -0
- package/bin/gjallarhorn-tunnel.sh +85 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +130 -0
- package/bin/hall-snapshot.sh +111 -0
- package/bin/hamr-harness.sh +246 -0
- package/bin/heimdall-ssh-keys.sh +374 -0
- package/bin/herdr-agents.py +44 -0
- package/bin/herdr-ensure.sh +104 -0
- package/bin/herdr-run.sh +452 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hlidskjalf-agents.sh +172 -0
- package/bin/hlidskjalf-usage.sh +196 -0
- package/bin/hoard-guard.sh +135 -0
- package/bin/hoard-lib.sh +105 -0
- package/bin/hodd.sh +102 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +121 -0
- package/bin/local-model-lock.sh +70 -0
- package/bin/mimir-bridge.py +259 -0
- package/bin/mimir-bridge.sh +100 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir-reflect.sh +27 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +72 -0
- package/bin/mjollnir.sh +104 -0
- package/bin/model-hardware.sh +96 -0
- package/bin/model-resolve.sh +160 -0
- package/bin/models-detect.sh +178 -0
- package/bin/nornir-cron-start.sh +162 -0
- package/bin/nornir-job-daily-briefing.sh +191 -0
- package/bin/nornir-job-git-sync.sh +152 -0
- package/bin/nornir-job-hall-snapshot.sh +28 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-nsr-compliance.sh +54 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/npm-publish.sh +136 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +161 -0
- package/bin/omarchy-plugins.sh +187 -0
- package/bin/omarchy-sense.sh +162 -0
- package/bin/perm-guard.sh +30 -0
- package/bin/pi-agent.sh +68 -0
- package/bin/pi-ensure.sh +77 -0
- package/bin/pi-local.sh +37 -0
- package/bin/pi-model-agnostic.sh +71 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +58 -0
- package/bin/project-git.sh +69 -0
- package/bin/public-guard.sh +71 -0
- package/bin/ratatoskr.sh +49 -0
- package/bin/realm-lib.sh +32 -0
- package/bin/repo-scrub.sh +62 -0
- package/bin/rodd-operational-input.sh +250 -0
- package/bin/runes-append.sh +198 -0
- package/bin/saga-session-start.sh +172 -0
- package/bin/saga-sessionstart-run.sh +79 -0
- package/bin/saga-wake-drain.sh +41 -0
- package/bin/secret-guard.sh +63 -0
- package/bin/sessrumnir-ensure.sh +100 -0
- package/bin/sessrumnir-sync.sh +237 -0
- package/bin/sessrumnir.sh +104 -0
- package/bin/skillopt-setup.sh +76 -0
- package/bin/skuld-branch-outcome.sh +203 -0
- package/bin/skuld-branch-prompt.sh +101 -0
- package/bin/smidja-bootstrap.sh +94 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +89 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-spawn-pretool-check.sh +58 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +203 -0
- package/bin/telegram-bot.sh +82 -0
- package/bin/toolchain.sh +74 -0
- package/bin/ui-truth-check.sh +75 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +298 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +60 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +163 -0
- package/bin/wyrd-db.sh +47 -0
- package/bin/yggdrasil.sh +152 -0
- package/bin/ymir-edit.sh +145 -0
- package/bin/ymir-install.sh +806 -0
- package/bin/ymir-invite.sh +93 -0
- package/bin/ymir-isolation.sh +88 -0
- package/bin/ymir-migrate.sh +61 -0
- package/bin/ymir-plan.sh +356 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +110 -0
- package/bin/ymir-setup-auth.sh +119 -0
- package/bin/ymir-validate.sh +193 -0
- package/bin/ymir.js +74 -16
- package/docs/Architecture.md +339 -0
- package/docs/design.md +351 -0
- package/docs/installations/README.md +63 -0
- package/docs/installations/ymir-home.md +93 -0
- package/docs/integration.md +105 -0
- package/docs/lore.md +1060 -0
- package/docs/research/agent-harnesses.md +290 -0
- package/docs/runbooks/README.md +19 -0
- package/docs/runbooks/a2a.md +91 -0
- package/docs/runbooks/agent-permissions.md +99 -0
- package/docs/runbooks/agents.md +57 -0
- package/docs/runbooks/models.md +69 -0
- package/docs/runbooks/realm-onboarding.md +60 -0
- package/docs/runbooks/secrets-and-hoard.md +60 -0
- package/docs/runbooks/updates-and-migrations.md +110 -0
- package/docs/runbooks/worktrees-isolation.md +72 -0
- package/docs/session-start.md +105 -0
- package/docs/skillopt-integration.md +321 -0
- package/docs/sync-system.md +66 -0
- package/docs/workspaces.md +104 -0
- package/docs/ymir-rut.md +260 -0
- package/package.json +54 -14
- package/packaging/build.sh +74 -0
- package/packaging/macos/Ymir Installer.command +43 -0
- package/packaging/windows/ymir-setup.nsi +74 -0
- package/scripts/README.md +22 -0
- package/scripts/electron.sh +269 -0
- package/scripts/lower.sh +34 -0
- package/scripts/raise.sh +42 -0
- package/scripts/start.sh +217 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fm-send strict target resolution and key delivery reporting.
|
|
3
|
+
#
|
|
4
|
+
# A send that cannot be tied to a recorded task/lane or to an explicit
|
|
5
|
+
# well-formed backend target must fail loudly. These tests pin the historical
|
|
6
|
+
# silent-fallback failures: missing FM_HOME, unresolved selectors, prefixless
|
|
7
|
+
# herdr pane ids, dead explicit endpoints, and the healthy exact/fm-id paths.
|
|
8
|
+
# They also verify that a key send reports whether delivery actually succeeded.
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
# shellcheck source=tests/lib.sh
|
|
12
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
13
|
+
|
|
14
|
+
SEND="$ROOT/bin/fm-send.sh"
|
|
15
|
+
TMP_ROOT=$(fm_test_tmproot fm-send-strict)
|
|
16
|
+
|
|
17
|
+
make_stubs() { # <dir> -> echoes fakebin dir
|
|
18
|
+
local dir=$1 fb="$1/fakebin"
|
|
19
|
+
mkdir -p "$fb"
|
|
20
|
+
cat > "$fb/tmux" <<'SH'
|
|
21
|
+
#!/usr/bin/env bash
|
|
22
|
+
set -u
|
|
23
|
+
case "${1:-}" in
|
|
24
|
+
send-keys)
|
|
25
|
+
shift
|
|
26
|
+
literal=0
|
|
27
|
+
target=
|
|
28
|
+
while [ $# -gt 0 ]; do
|
|
29
|
+
case "$1" in
|
|
30
|
+
-t) target=$2; shift 2 ;;
|
|
31
|
+
-l) literal=1; shift ;;
|
|
32
|
+
*) break ;;
|
|
33
|
+
esac
|
|
34
|
+
done
|
|
35
|
+
printf 'send-keys target=%s literal=%s arg=%s\n' "$target" "$literal" "${1:-}" >> "$FM_TMUX_LOG"
|
|
36
|
+
# FM_FAKE_TMUX_SEND_KEY_FAIL names one key whose delivery fails, so the
|
|
37
|
+
# --key exit contract can be driven both ways from the same stub.
|
|
38
|
+
if [ "$literal" = 0 ] && [ -n "${FM_FAKE_TMUX_SEND_KEY_FAIL:-}" ] \
|
|
39
|
+
&& [ "${1:-}" = "$FM_FAKE_TMUX_SEND_KEY_FAIL" ]; then
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
exit 0 ;;
|
|
43
|
+
display-message)
|
|
44
|
+
target=
|
|
45
|
+
cursor=0
|
|
46
|
+
while [ $# -gt 0 ]; do
|
|
47
|
+
case "$1" in
|
|
48
|
+
-t) target=$2; shift 2 ;;
|
|
49
|
+
*cursor_y*) cursor=1; shift ;;
|
|
50
|
+
*) shift ;;
|
|
51
|
+
esac
|
|
52
|
+
done
|
|
53
|
+
if [ -n "${FM_FAKE_TMUX_DEAD_TARGET:-}" ] && [ "$target" = "$FM_FAKE_TMUX_DEAD_TARGET" ]; then
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
[ "$cursor" = 1 ] && { printf '1\n'; exit 0; }
|
|
57
|
+
printf '%%1\n'
|
|
58
|
+
exit 0 ;;
|
|
59
|
+
capture-pane)
|
|
60
|
+
printf '╭────╮\n│ │\n╰────╯\n'
|
|
61
|
+
exit 0 ;;
|
|
62
|
+
list-windows)
|
|
63
|
+
printf 'foreign:%s\n' "${FM_FAKE_TMUX_WINDOW:-fm-lost}"
|
|
64
|
+
exit 0 ;;
|
|
65
|
+
esac
|
|
66
|
+
exit 0
|
|
67
|
+
SH
|
|
68
|
+
chmod +x "$fb/tmux"
|
|
69
|
+
cat > "$fb/herdr" <<'SH'
|
|
70
|
+
#!/usr/bin/env bash
|
|
71
|
+
set -u
|
|
72
|
+
printf '%s\n' "$*" >> "$FM_HERDR_LOG"
|
|
73
|
+
case "${1:-} ${2:-}" in
|
|
74
|
+
"status --json") printf '{"client":{"version":"0.7.5","protocol":16},"server":{"running":true}}\n' ;;
|
|
75
|
+
"pane get") printf '{"result":{"pane":{"pane_id":"%s"}}}\n' "${3:-}" ;;
|
|
76
|
+
"pane send-keys") : ;;
|
|
77
|
+
esac
|
|
78
|
+
SH
|
|
79
|
+
chmod +x "$fb/herdr"
|
|
80
|
+
cat > "$fb/sleep" <<'SH'
|
|
81
|
+
#!/usr/bin/env bash
|
|
82
|
+
exit 0
|
|
83
|
+
SH
|
|
84
|
+
chmod +x "$fb/sleep"
|
|
85
|
+
printf '%s\n' "$fb"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
setup_home() { # <name> -> echoes home dir
|
|
89
|
+
local home="$TMP_ROOT/$1-$RANDOM"
|
|
90
|
+
mkdir -p "$home/state"
|
|
91
|
+
printf '%s\n' "$home"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
test_exact_lane_id_send_still_works() {
|
|
95
|
+
local dir fb home err log rc got
|
|
96
|
+
dir="$TMP_ROOT/exact"; mkdir -p "$dir"
|
|
97
|
+
fb=$(make_stubs "$dir"); home=$(setup_home exact); err="$dir/send.err"; log="$dir/tmux.log"; : > "$log"
|
|
98
|
+
fm_write_meta "$home/state/mpf-lane-m8.meta" "window=sess:fm-mpf-lane-m8" "kind=ship"
|
|
99
|
+
|
|
100
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_SEND_SETTLE=0 \
|
|
101
|
+
"$SEND" mpf-lane-m8 "lost dispatch" >/dev/null 2>"$err"; rc=$?
|
|
102
|
+
expect_code 0 "$rc" "exact task id send should succeed when metadata exists"
|
|
103
|
+
got=$(cat "$log")
|
|
104
|
+
assert_contains "$got" "target=sess:fm-mpf-lane-m8 literal=1 arg=Firstmate instruction waiting" \
|
|
105
|
+
"exact id should ring the doorbell at the meta target"
|
|
106
|
+
assert_contains "$got" "target=sess:fm-mpf-lane-m8 literal=0 arg=Enter" "exact id should submit the doorbell with Enter"
|
|
107
|
+
grep -qF 'lost dispatch' "$home/state/mpf-lane-m8.inbox/001.msg" \
|
|
108
|
+
|| fail "exact id should record the steer in the task inbox"
|
|
109
|
+
pass "fm-send strict: exact task/lane ids resolve through home metadata"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
test_unset_fm_home_fails() {
|
|
113
|
+
local dir fb err log rc
|
|
114
|
+
dir="$TMP_ROOT/nohome"; mkdir -p "$dir"
|
|
115
|
+
fb=$(make_stubs "$dir"); err="$dir/send.err"; log="$dir/tmux.log"; : > "$log"
|
|
116
|
+
|
|
117
|
+
env -u FM_HOME PATH="$fb:$PATH" FM_ROOT_OVERRIDE="$dir" FM_TMUX_LOG="$log" FM_SEND_SETTLE=0 \
|
|
118
|
+
"$SEND" sess:win "hello" >/dev/null 2>"$err"; rc=$?
|
|
119
|
+
[ "$rc" -ne 0 ] || fail "unset FM_HOME should fail"
|
|
120
|
+
assert_contains "$(cat "$err")" "FM_HOME is not set" "unset FM_HOME diagnostic should be explicit"
|
|
121
|
+
[ ! -s "$log" ] || fail "unset FM_HOME still attempted a send"$'\n'"$(cat "$log")"
|
|
122
|
+
pass "fm-send strict: unset FM_HOME fails before target resolution"
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
test_unresolvable_target_does_not_tmux_fallback() {
|
|
126
|
+
local dir fb home err log rc
|
|
127
|
+
dir="$TMP_ROOT/unresolved"; mkdir -p "$dir"
|
|
128
|
+
fb=$(make_stubs "$dir"); home=$(setup_home unresolved); err="$dir/send.err"; log="$dir/tmux.log"; : > "$log"
|
|
129
|
+
|
|
130
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_FAKE_TMUX_WINDOW=lost-target FM_SEND_SETTLE=0 \
|
|
131
|
+
"$SEND" lost-target "hello" >/dev/null 2>"$err"; rc=$?
|
|
132
|
+
[ "$rc" -ne 0 ] || fail "unresolvable target should fail"
|
|
133
|
+
assert_contains "$(cat "$err")" "not resolvable" "unresolvable diagnostic should be loud"
|
|
134
|
+
assert_contains "$(cat "$err")" "metadata window/terminal lookup" "unresolvable diagnostic should name the attempted lookup"
|
|
135
|
+
assert_contains "$(cat "$err")" "backend=none" "unresolvable diagnostic should name that no backend was assumed"
|
|
136
|
+
[ ! -s "$log" ] || fail "unresolvable target fell through to tmux send"$'\n'"$(cat "$log")"
|
|
137
|
+
pass "fm-send strict: unresolvable selectors do not fall back to tmux"
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
test_prefixless_herdr_pane_id_fails() {
|
|
141
|
+
local dir fb home err log rc
|
|
142
|
+
dir="$TMP_ROOT/herdr-pane"; mkdir -p "$dir"
|
|
143
|
+
fb=$(make_stubs "$dir"); home=$(setup_home herdr); err="$dir/send.err"; log="$dir/tmux.log"; : > "$log"
|
|
144
|
+
fm_write_meta "$home/state/nudge.meta" \
|
|
145
|
+
"window=default:wB:p2" "backend=herdr" "herdr_session=default" "herdr_pane_id=wB:p2" "kind=ship"
|
|
146
|
+
|
|
147
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_SEND_SETTLE=0 \
|
|
148
|
+
"$SEND" wB:p2 "nudge" >/dev/null 2>"$err"; rc=$?
|
|
149
|
+
[ "$rc" -ne 0 ] || fail "prefixless herdr pane id should fail"
|
|
150
|
+
assert_contains "$(cat "$err")" "matches herdr_pane_id" "herdr pane diagnostic should name the meta match"
|
|
151
|
+
assert_contains "$(cat "$err")" "expected <herdr-session>:<pane-id>" "herdr pane diagnostic should show expected shape"
|
|
152
|
+
assert_contains "$(cat "$err")" "default:wB:p2" "herdr pane diagnostic should show the canonical target"
|
|
153
|
+
[ ! -s "$log" ] || fail "prefixless herdr pane id fell through to tmux send"$'\n'"$(cat "$log")"
|
|
154
|
+
pass "fm-send strict: prefixless herdr pane ids are rejected before tmux fallback"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
test_unmatched_single_colon_target_must_exist() {
|
|
158
|
+
local dir fb home err log rc
|
|
159
|
+
dir="$TMP_ROOT/dead-explicit"; mkdir -p "$dir"
|
|
160
|
+
fb=$(make_stubs "$dir"); home=$(setup_home deadexplicit); err="$dir/send.err"; log="$dir/tmux.log"; : > "$log"
|
|
161
|
+
|
|
162
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_FAKE_TMUX_DEAD_TARGET=sess:missing FM_SEND_SETTLE=0 \
|
|
163
|
+
"$SEND" sess:missing "hello" >/dev/null 2>"$err"; rc=$?
|
|
164
|
+
[ "$rc" -ne 0 ] || fail "dead explicit tmux-shaped target should fail"
|
|
165
|
+
assert_contains "$(cat "$err")" "not a live tmux endpoint" "dead explicit target diagnostic should name the assumed backend"
|
|
166
|
+
assert_contains "$(cat "$err")" "backend=tmux" "dead explicit target diagnostic should name the tried backend"
|
|
167
|
+
[ ! -s "$log" ] || fail "dead explicit target still attempted a send"$'\n'"$(cat "$log")"
|
|
168
|
+
pass "fm-send strict: unmatched single-colon explicit targets must verify live before sending"
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
test_fm_prefixed_herdr_session_is_an_explicit_target() {
|
|
172
|
+
local dir fb home err log herdr_log rc
|
|
173
|
+
dir="$TMP_ROOT/fm-remote-explicit"; mkdir -p "$dir"
|
|
174
|
+
fb=$(make_stubs "$dir"); home=$(setup_home fmremote); err="$dir/send.err"; log="$dir/tmux.log"; herdr_log="$dir/herdr.log"
|
|
175
|
+
: > "$log"
|
|
176
|
+
: > "$herdr_log"
|
|
177
|
+
|
|
178
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_HERDR_LOG="$herdr_log" FM_SEND_SETTLE=0 \
|
|
179
|
+
"$SEND" fm-remote:w1:p2 --key Enter >/dev/null 2>"$err"; rc=$?
|
|
180
|
+
expect_code 0 "$rc" "an fm-prefixed Herdr session target should be accepted as explicit"
|
|
181
|
+
assert_grep 'pane get w1:p2 --session fm-remote' "$herdr_log" "fm-prefixed Herdr target was not verified in its session"
|
|
182
|
+
assert_grep 'pane send-keys w1:p2 enter --session fm-remote' "$herdr_log" "fm-prefixed Herdr target was not sent its key in its session"
|
|
183
|
+
assert_no_grep '--session default' "$herdr_log" "fm-prefixed Herdr target fell back to the default session"
|
|
184
|
+
pass "fm-send strict: fm-prefixed Herdr sessions remain explicit backend targets"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
test_healthy_fm_id_send_still_works() {
|
|
188
|
+
local dir fb home err log rc got
|
|
189
|
+
dir="$TMP_ROOT/healthy"; mkdir -p "$dir"
|
|
190
|
+
fb=$(make_stubs "$dir"); home=$(setup_home healthy); err="$dir/send.err"; log="$dir/tmux.log"; : > "$log"
|
|
191
|
+
fm_write_meta "$home/state/lane-ok.meta" "window=sess:fm-lane-ok" "kind=ship" "harness=codex"
|
|
192
|
+
|
|
193
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_SEND_SETTLE=0 \
|
|
194
|
+
"$SEND" fm-lane-ok "hello captain" >/dev/null 2>"$err"; rc=$?
|
|
195
|
+
expect_code 0 "$rc" "healthy fm-id send should succeed"
|
|
196
|
+
got=$(cat "$log")
|
|
197
|
+
assert_contains "$got" "target=sess:fm-lane-ok literal=1 arg=Firstmate instruction waiting" \
|
|
198
|
+
"healthy send should ring the doorbell at the meta target"
|
|
199
|
+
assert_contains "$got" "target=sess:fm-lane-ok literal=0 arg=Enter" "healthy send should submit the doorbell with Enter"
|
|
200
|
+
grep -qF 'hello captain' "$home/state/lane-ok.inbox/001.msg" \
|
|
201
|
+
|| fail "healthy send should record the steer in the task inbox"
|
|
202
|
+
assert_contains "$(cat "$err")" "requested message WILL still be sent" "fm-send guard banner should keep send-specific continuation wording"
|
|
203
|
+
pass "fm-send strict: healthy fm-<id> sends record the steer and ring once"
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# A --key send is how firstmate interrupts a worker, so its exit status is the
|
|
207
|
+
# only signal that the interrupt actually landed.
|
|
208
|
+
# Reporting success for a key that was never delivered would leave supervision
|
|
209
|
+
# believing a runaway worker had been stopped, so the failing case must exit
|
|
210
|
+
# nonzero and name the key.
|
|
211
|
+
# Both directions are asserted from one stub so the failing case cannot go
|
|
212
|
+
# quietly vacuous if the key ever stops being delivered at all.
|
|
213
|
+
test_key_send_exit_status_follows_delivery() {
|
|
214
|
+
local dir fb home err log rc
|
|
215
|
+
dir="$TMP_ROOT/key-exit"; mkdir -p "$dir"
|
|
216
|
+
fb=$(make_stubs "$dir"); home=$(setup_home keyexit); err="$dir/send.err"; log="$dir/tmux.log"; : > "$log"
|
|
217
|
+
fm_write_meta "$home/state/lane-key.meta" "window=sess:fm-lane-key" "kind=ship"
|
|
218
|
+
|
|
219
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_SEND_SETTLE=0 \
|
|
220
|
+
"$SEND" lane-key --key Escape >/dev/null 2>"$err"; rc=$?
|
|
221
|
+
expect_code 0 "$rc" "a delivered --key interrupt should report success"
|
|
222
|
+
assert_contains "$(cat "$log")" "target=sess:fm-lane-key literal=0 arg=Escape" "the delivered case should send the named key"
|
|
223
|
+
|
|
224
|
+
: > "$log"
|
|
225
|
+
PATH="$fb:$PATH" FM_HOME="$home" FM_ROOT_OVERRIDE="$home" FM_TMUX_LOG="$log" FM_SEND_SETTLE=0 \
|
|
226
|
+
FM_FAKE_TMUX_SEND_KEY_FAIL=Escape \
|
|
227
|
+
"$SEND" lane-key --key Escape >/dev/null 2>"$err"; rc=$?
|
|
228
|
+
[ "$rc" -ne 0 ] || fail "an undelivered --key interrupt reported success"
|
|
229
|
+
assert_contains "$(cat "$err")" "key 'Escape' not sent" "the undelivered case should name the key that failed"
|
|
230
|
+
assert_contains "$(cat "$log")" "target=sess:fm-lane-key literal=0 arg=Escape" "the undelivered case should still have attempted the send"
|
|
231
|
+
pass "fm-send --key: exit status follows delivery, and an undelivered key never reports success"
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
test_exact_lane_id_send_still_works
|
|
235
|
+
test_key_send_exit_status_follows_delivery
|
|
236
|
+
test_unset_fm_home_fails
|
|
237
|
+
test_unresolvable_target_does_not_tmux_fallback
|
|
238
|
+
test_prefixless_herdr_pane_id_fails
|
|
239
|
+
test_unmatched_single_colon_target_must_exist
|
|
240
|
+
test_fm_prefixed_herdr_session_is_an_explicit_target
|
|
241
|
+
test_healthy_fm_id_send_still_works
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-session-lock-ancestry.test.sh - session-lock harness identity
|
|
3
|
+
# (bin/fm-session-lock-lib.sh).
|
|
4
|
+
#
|
|
5
|
+
# Two layers. The unit cases drive the library's own functions behind a
|
|
6
|
+
# deterministic fake ps, so both platforms' reporting semantics are covered from
|
|
7
|
+
# either host: macOS reports argv[0] in `ps -o comm=`, while procps on Linux
|
|
8
|
+
# reports the kernel exec name and ignores argv[0] entirely. The end-to-end cases
|
|
9
|
+
# run the REAL Stop auto-arm inside real process trees whose shapes differ only
|
|
10
|
+
# in how the per-session process is named and what its parent is. Those trees are
|
|
11
|
+
# orphaned before the hook fires, so the ancestry walk terminates inside the
|
|
12
|
+
# fixture and can never escape into the session running this suite.
|
|
13
|
+
# shellcheck disable=SC2016 # single quotes are deliberate: $FM_HOME and $$ expand inside the fixture child
|
|
14
|
+
set -u
|
|
15
|
+
|
|
16
|
+
# shellcheck source=tests/lib.sh
|
|
17
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
18
|
+
|
|
19
|
+
TMP_ROOT=$(fm_test_tmproot fm-session-lock-ancestry)
|
|
20
|
+
fm_git_identity fmtest fmtest@example.invalid
|
|
21
|
+
|
|
22
|
+
LIB="$ROOT/bin/fm-session-lock-lib.sh"
|
|
23
|
+
|
|
24
|
+
# Claude Code's native installer names the per-session executable by its version,
|
|
25
|
+
# so the harness identity has to survive a basename that says nothing.
|
|
26
|
+
CLAUDE_VERSION_DIR="$TMP_ROOT/claude-install/share/claude/versions"
|
|
27
|
+
mkdir -p "$CLAUDE_VERSION_DIR"
|
|
28
|
+
ln -s /bin/bash "$CLAUDE_VERSION_DIR/2.1.220"
|
|
29
|
+
VERSIONED_CLAUDE="$CLAUDE_VERSION_DIR/2.1.220"
|
|
30
|
+
|
|
31
|
+
FAKEBIN=$(fm_fakebin "$TMP_ROOT/harness-bin")
|
|
32
|
+
ln -s /bin/bash "$FAKEBIN/claude"
|
|
33
|
+
NAMED_CLAUDE="$FAKEBIN/claude"
|
|
34
|
+
|
|
35
|
+
# --- unit layer: identity behind a deterministic process table ---------------
|
|
36
|
+
|
|
37
|
+
# Run one library expression with <fakebin> shadowing ps. kill is stubbed so
|
|
38
|
+
# liveness questions are decided by the process table alone.
|
|
39
|
+
lib_eval() { # <fakebin> <expression>
|
|
40
|
+
local fakebin=$1 expr=$2
|
|
41
|
+
PATH="$fakebin:$PATH" bash -c "
|
|
42
|
+
. \"\$0\"
|
|
43
|
+
kill() { return 0; }
|
|
44
|
+
$expr
|
|
45
|
+
" "$LIB"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
test_version_named_session_is_identified_on_both_platforms() {
|
|
49
|
+
local dir fakebin shape got
|
|
50
|
+
dir="$TMP_ROOT/version-named"
|
|
51
|
+
fakebin=$(fm_fakebin "$dir")
|
|
52
|
+
mkdir -p "$dir/state"
|
|
53
|
+
cat > "$fakebin/ps" <<'SH'
|
|
54
|
+
#!/usr/bin/env bash
|
|
55
|
+
set -u
|
|
56
|
+
field= pid=
|
|
57
|
+
while [ "$#" -gt 0 ]; do
|
|
58
|
+
case "$1" in
|
|
59
|
+
-o) field=$2; shift 2 ;;
|
|
60
|
+
-p) pid=$2; shift 2 ;;
|
|
61
|
+
*) shift ;;
|
|
62
|
+
esac
|
|
63
|
+
done
|
|
64
|
+
case "$pid:$field:${FM_TEST_CLAUDE_SHAPE:-linux}" in
|
|
65
|
+
700:comm=:linux) printf '%s\n' '2.1.220' ;;
|
|
66
|
+
700:args=:linux) printf '%s\n' '/opt/claude/versions/2.1.220 --resume' ;;
|
|
67
|
+
700:comm=:macos) printf '%s\n' '/Users/u/.local/share/claude/versions/2.1.220' ;;
|
|
68
|
+
700:args=:macos) printf '%s\n' '/Users/u/.local/share/claude/versions/2.1.220 --resume' ;;
|
|
69
|
+
700:ppid=:*) printf '%s\n' 1 ;;
|
|
70
|
+
*:comm=:*) printf '%s\n' bash ;;
|
|
71
|
+
*:args=:*) printf '%s\n' 'bash /repo/bin/fm-claude-stop-autoarm.sh' ;;
|
|
72
|
+
*:ppid=:*) printf '%s\n' 700 ;;
|
|
73
|
+
esac
|
|
74
|
+
SH
|
|
75
|
+
chmod +x "$fakebin/ps"
|
|
76
|
+
printf '700\n' > "$dir/state/.lock"
|
|
77
|
+
|
|
78
|
+
for shape in linux macos; do
|
|
79
|
+
got=$(FM_TEST_CLAUDE_SHAPE="$shape" lib_eval "$fakebin" 'fm_harness_ancestry_pid') \
|
|
80
|
+
|| fail "$shape: the version-named session was not found in the ancestry at all"
|
|
81
|
+
[ "$got" = 700 ] || fail "$shape: ancestry resolved '$got', expected the version-named session pid 700"
|
|
82
|
+
FM_TEST_CLAUDE_SHAPE="$shape" lib_eval "$fakebin" 'fm_harness_pid_alive 700' \
|
|
83
|
+
|| fail "$shape: a live version-named session was not recognized as a harness"
|
|
84
|
+
FM_TEST_CLAUDE_SHAPE="$shape" lib_eval "$fakebin" "fm_session_lock_owned_by_self '$dir/state'" \
|
|
85
|
+
|| fail "$shape: the session holding the lock did not recognize itself as the owner"
|
|
86
|
+
done
|
|
87
|
+
pass "session-lock: a version-named Claude Code session is identified from its install path and argv[0]"
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
test_ordinary_paths_are_never_harness_processes() {
|
|
91
|
+
local dir fakebin shape
|
|
92
|
+
dir="$TMP_ROOT/ordinary-paths"
|
|
93
|
+
fakebin=$(fm_fakebin "$dir")
|
|
94
|
+
mkdir -p "$dir/state"
|
|
95
|
+
cat > "$fakebin/ps" <<'SH'
|
|
96
|
+
#!/usr/bin/env bash
|
|
97
|
+
set -u
|
|
98
|
+
field= pid=
|
|
99
|
+
while [ "$#" -gt 0 ]; do
|
|
100
|
+
case "$1" in
|
|
101
|
+
-o) field=$2; shift 2 ;;
|
|
102
|
+
-p) pid=$2; shift 2 ;;
|
|
103
|
+
*) shift ;;
|
|
104
|
+
esac
|
|
105
|
+
done
|
|
106
|
+
case "$pid:$field:${FM_TEST_PATH_SHAPE:-hookdir}" in
|
|
107
|
+
810:comm=:hookdir) printf '%s\n' '/home/u/.claude/hooks/notify.sh' ;;
|
|
108
|
+
810:args=:hookdir) printf '%s\n' '/home/u/.claude/hooks/notify.sh --quiet' ;;
|
|
109
|
+
810:comm=:piprefix) printf '%s\n' '/opt/pipeline/bin/runner' ;;
|
|
110
|
+
810:args=:piprefix) printf '%s\n' '/opt/pipeline/bin/runner --once' ;;
|
|
111
|
+
810:ppid=:*) printf '%s\n' 1 ;;
|
|
112
|
+
*:comm=:*) printf '%s\n' bash ;;
|
|
113
|
+
*:args=:*) printf '%s\n' 'bash /repo/bin/fm-watch-arm.sh' ;;
|
|
114
|
+
*:ppid=:*) printf '%s\n' 810 ;;
|
|
115
|
+
esac
|
|
116
|
+
SH
|
|
117
|
+
chmod +x "$fakebin/ps"
|
|
118
|
+
printf '810\n' > "$dir/state/.lock"
|
|
119
|
+
|
|
120
|
+
# Identity may be read from an executable path, but only from whole path
|
|
121
|
+
# components: anything merely living under ~/.claude, and any component that
|
|
122
|
+
# merely starts with a harness name, must stay outside the harness identity.
|
|
123
|
+
for shape in hookdir piprefix; do
|
|
124
|
+
if FM_TEST_PATH_SHAPE="$shape" lib_eval "$fakebin" 'fm_harness_ancestry_pid'; then
|
|
125
|
+
fail "$shape: an ordinary script path was treated as a harness process"
|
|
126
|
+
fi
|
|
127
|
+
if FM_TEST_PATH_SHAPE="$shape" lib_eval "$fakebin" 'fm_harness_pid_alive 810'; then
|
|
128
|
+
fail "$shape: an ordinary script path passed the harness-liveness predicate"
|
|
129
|
+
fi
|
|
130
|
+
if FM_TEST_PATH_SHAPE="$shape" lib_eval "$fakebin" "fm_session_lock_owned_by_self '$dir/state'"; then
|
|
131
|
+
fail "$shape: an ordinary script path claimed the home's session lock"
|
|
132
|
+
fi
|
|
133
|
+
done
|
|
134
|
+
pass "session-lock: ordinary script paths under a harness directory are not harness processes"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
test_harness_beyond_a_gap_never_owns_the_lock() {
|
|
138
|
+
local dir fakebin got
|
|
139
|
+
dir="$TMP_ROOT/gap"
|
|
140
|
+
fakebin=$(fm_fakebin "$dir")
|
|
141
|
+
mkdir -p "$dir/state"
|
|
142
|
+
cat > "$fakebin/ps" <<'SH'
|
|
143
|
+
#!/usr/bin/env bash
|
|
144
|
+
set -u
|
|
145
|
+
field= pid=
|
|
146
|
+
while [ "$#" -gt 0 ]; do
|
|
147
|
+
case "$1" in
|
|
148
|
+
-o) field=$2; shift 2 ;;
|
|
149
|
+
-p) pid=$2; shift 2 ;;
|
|
150
|
+
*) shift ;;
|
|
151
|
+
esac
|
|
152
|
+
done
|
|
153
|
+
case "$pid:$field" in
|
|
154
|
+
900:comm=) printf '%s\n' claude ;;
|
|
155
|
+
900:args=) printf '%s\n' 'claude' ;;
|
|
156
|
+
900:ppid=) printf '%s\n' 910 ;;
|
|
157
|
+
910:comm=) printf '%s\n' bash ;;
|
|
158
|
+
910:args=) printf '%s\n' 'bash tests/run.sh' ;;
|
|
159
|
+
910:ppid=) printf '%s\n' 920 ;;
|
|
160
|
+
920:comm=) printf '%s\n' claude ;;
|
|
161
|
+
920:args=) printf '%s\n' 'claude' ;;
|
|
162
|
+
920:ppid=) printf '%s\n' 1 ;;
|
|
163
|
+
*:comm=) printf '%s\n' bash ;;
|
|
164
|
+
*:args=) printf '%s\n' bash ;;
|
|
165
|
+
*:ppid=) printf '%s\n' 900 ;;
|
|
166
|
+
esac
|
|
167
|
+
SH
|
|
168
|
+
chmod +x "$fakebin/ps"
|
|
169
|
+
|
|
170
|
+
got=$(lib_eval "$fakebin" 'fm_harness_ancestry_pid') || fail "the contiguous harness run was not resolved"
|
|
171
|
+
[ "$got" = 900 ] || fail "ancestry crossed a non-harness gap, resolved '$got' instead of 900"
|
|
172
|
+
printf '920\n' > "$dir/state/.lock"
|
|
173
|
+
if lib_eval "$fakebin" "fm_session_lock_owned_by_self '$dir/state'"; then
|
|
174
|
+
fail "an unrelated harness beyond a non-harness gap was accepted as this session's lock owner"
|
|
175
|
+
fi
|
|
176
|
+
printf '900\n' > "$dir/state/.lock"
|
|
177
|
+
lib_eval "$fakebin" "fm_session_lock_owned_by_self '$dir/state'" \
|
|
178
|
+
|| fail "the contiguous harness run did not recognize its own lock"
|
|
179
|
+
pass "session-lock: ownership stops at the first non-harness gap above the contiguous run"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
test_competing_version_named_session_is_seen_as_live() {
|
|
183
|
+
local dir fakebin
|
|
184
|
+
dir="$TMP_ROOT/competing"
|
|
185
|
+
fakebin=$(fm_fakebin "$dir")
|
|
186
|
+
mkdir -p "$dir/state"
|
|
187
|
+
cat > "$fakebin/ps" <<'SH'
|
|
188
|
+
#!/usr/bin/env bash
|
|
189
|
+
set -u
|
|
190
|
+
field= pid=
|
|
191
|
+
while [ "$#" -gt 0 ]; do
|
|
192
|
+
case "$1" in
|
|
193
|
+
-o) field=$2; shift 2 ;;
|
|
194
|
+
-p) pid=$2; shift 2 ;;
|
|
195
|
+
*) shift ;;
|
|
196
|
+
esac
|
|
197
|
+
done
|
|
198
|
+
case "$pid:$field" in
|
|
199
|
+
600:comm=) printf '%s\n' '2.1.220' ;;
|
|
200
|
+
600:args=) printf '%s\n' '/opt/claude/versions/2.1.220' ;;
|
|
201
|
+
600:ppid=) printf '%s\n' 1 ;;
|
|
202
|
+
650:comm=) printf '%s\n' claude ;;
|
|
203
|
+
650:args=) printf '%s\n' claude ;;
|
|
204
|
+
650:ppid=) printf '%s\n' 1 ;;
|
|
205
|
+
*:comm=) printf '%s\n' bash ;;
|
|
206
|
+
*:args=) printf '%s\n' bash ;;
|
|
207
|
+
*:ppid=) printf '%s\n' 650 ;;
|
|
208
|
+
esac
|
|
209
|
+
SH
|
|
210
|
+
chmod +x "$fakebin/ps"
|
|
211
|
+
# pid 600 is a different live session that holds the lock; this process
|
|
212
|
+
# descends from 650 instead. Treating 600 as dead would let this session
|
|
213
|
+
# reclaim a live competitor's home.
|
|
214
|
+
printf '600\n' > "$dir/state/.lock"
|
|
215
|
+
if lib_eval "$fakebin" "fm_session_lock_owned_by_self '$dir/state'"; then
|
|
216
|
+
fail "a lock held outside this ancestry was claimed as this session's own"
|
|
217
|
+
fi
|
|
218
|
+
lib_eval "$fakebin" 'fm_harness_pid_alive 600' \
|
|
219
|
+
|| fail "a live competing version-named session was classified as a dead lock owner"
|
|
220
|
+
pass "session-lock: a live version-named session holding the lock is not mistaken for a stale owner"
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
# --- end-to-end layer: the real Stop auto-arm in real process trees ----------
|
|
224
|
+
|
|
225
|
+
install_autoarm_scripts() {
|
|
226
|
+
local dir=$1
|
|
227
|
+
mkdir -p "$dir/bin"
|
|
228
|
+
cp "$ROOT/bin/fm-claude-stop-autoarm.sh" "$dir/bin/fm-claude-stop-autoarm.sh"
|
|
229
|
+
cp "$ROOT/bin/fm-primary-scope-lib.sh" "$dir/bin/fm-primary-scope-lib.sh"
|
|
230
|
+
cp "$ROOT/bin/fm-supervision-lib.sh" "$dir/bin/fm-supervision-lib.sh"
|
|
231
|
+
cp "$ROOT/bin/fm-wake-lib.sh" "$dir/bin/fm-wake-lib.sh"
|
|
232
|
+
cp "$ROOT/bin/fm-session-lock-lib.sh" "$dir/bin/fm-session-lock-lib.sh"
|
|
233
|
+
cp "$ROOT/bin/fm-cursor-lib.sh" "$dir/bin/fm-cursor-lib.sh"
|
|
234
|
+
cp "$ROOT/bin/fm-hook-host-lib.sh" "$dir/bin/fm-hook-host-lib.sh"
|
|
235
|
+
cp "$ROOT/bin/fm-lock.sh" "$dir/bin/fm-lock.sh"
|
|
236
|
+
chmod +x "$dir/bin/fm-claude-stop-autoarm.sh" "$dir/bin/fm-lock.sh"
|
|
237
|
+
cat > "$dir/bin/fm-watch-arm.sh" <<'SH'
|
|
238
|
+
#!/usr/bin/env bash
|
|
239
|
+
echo "$$" >> "$FM_HOME/state/arm-ran"
|
|
240
|
+
printf 'watcher: started pid=%s (beacon fresh)\n' "$$"
|
|
241
|
+
printf 'stale: fixture-win actionable\n'
|
|
242
|
+
exit 0
|
|
243
|
+
SH
|
|
244
|
+
chmod +x "$dir/bin/fm-watch-arm.sh"
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
# A primary home with one task in flight, so the hook's scope and supervision-need
|
|
248
|
+
# gates both pass and only identity decides the outcome.
|
|
249
|
+
make_primary_home() { # <dir>
|
|
250
|
+
local dir=$1
|
|
251
|
+
mkdir -p "$dir/state"
|
|
252
|
+
git init -q "$dir"
|
|
253
|
+
git -C "$dir" commit -q --allow-empty -m init
|
|
254
|
+
: > "$dir/AGENTS.md"
|
|
255
|
+
: > "$dir/state/task.meta"
|
|
256
|
+
install_autoarm_scripts "$dir"
|
|
257
|
+
# The process that fires the hook records its own pid as the session lock
|
|
258
|
+
# owner, exactly as a real session does at session start.
|
|
259
|
+
cat > "$dir/session.sh" <<'SH'
|
|
260
|
+
#!/usr/bin/env bash
|
|
261
|
+
if [ "${FM_FIXTURE_ORPHAN_HERE:-0}" = 1 ]; then
|
|
262
|
+
i=0
|
|
263
|
+
while [ "$i" -lt 200 ] && [ "$(ps -o ppid= -p $$ 2>/dev/null | tr -d ' ')" != 1 ]; do
|
|
264
|
+
sleep 0.05
|
|
265
|
+
i=$((i + 1))
|
|
266
|
+
done
|
|
267
|
+
fi
|
|
268
|
+
printf '%s\n' "$$" > "$FM_HOME/state/session-pid"
|
|
269
|
+
printf '%s\n' "$$" > "$FM_HOME/state/.lock"
|
|
270
|
+
"$FM_HOME/bin/fm-claude-stop-autoarm.sh" </dev/null > "$FM_HOME/state/hook.out" 2>&1
|
|
271
|
+
printf '%s\n' "$?" > "$FM_HOME/state/hook.rc"
|
|
272
|
+
SH
|
|
273
|
+
cat > "$dir/daemon.sh" <<'SH'
|
|
274
|
+
#!/usr/bin/env bash
|
|
275
|
+
i=0
|
|
276
|
+
while [ "$i" -lt 200 ] && [ "$(ps -o ppid= -p $$ 2>/dev/null | tr -d ' ')" != 1 ]; do
|
|
277
|
+
sleep 0.05
|
|
278
|
+
i=$((i + 1))
|
|
279
|
+
done
|
|
280
|
+
printf '%s\n' "$$" > "$FM_HOME/state/daemon-pid"
|
|
281
|
+
"$FM_SESSION_BIN" "$FM_HOME/session.sh"
|
|
282
|
+
exit 0
|
|
283
|
+
SH
|
|
284
|
+
chmod +x "$dir/session.sh" "$dir/daemon.sh"
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
# Start the fixture tree detached from this suite's own process tree: the
|
|
288
|
+
# launcher exits immediately, so the tree is reparented to init and the ancestry
|
|
289
|
+
# walk terminates inside the fixture. Returns once the hook has recorded its exit
|
|
290
|
+
# code.
|
|
291
|
+
run_fixture_tree() { # <dir> <session-bin> [<daemon-bin>]
|
|
292
|
+
local dir=$1 session_bin=$2 daemon_bin=${3:-} i
|
|
293
|
+
if [ -n "$daemon_bin" ]; then
|
|
294
|
+
FM_HOME="$dir" FM_SESSION_BIN="$session_bin" FM_FIXTURE_ORPHAN_HERE=0 \
|
|
295
|
+
bash -c '"$0" "$1" &' "$daemon_bin" "$dir/daemon.sh"
|
|
296
|
+
else
|
|
297
|
+
FM_HOME="$dir" FM_FIXTURE_ORPHAN_HERE=1 \
|
|
298
|
+
bash -c '"$0" "$1" &' "$session_bin" "$dir/session.sh"
|
|
299
|
+
fi
|
|
300
|
+
i=0
|
|
301
|
+
while [ "$i" -lt 400 ] && [ ! -s "$dir/state/hook.rc" ]; do
|
|
302
|
+
sleep 0.05
|
|
303
|
+
i=$((i + 1))
|
|
304
|
+
done
|
|
305
|
+
[ -s "$dir/state/hook.rc" ] || fail "the fixture hook never finished"
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
hook_rc() {
|
|
309
|
+
tr -d '[:space:]' < "$1/state/hook.rc"
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
epoch_outcome() {
|
|
313
|
+
sed -n 's/^.*outcome=\([a-z][a-z]*\) .*$/\1/p' "$1/state/.claude-autoarm-epoch" 2>/dev/null || true
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
test_e2e_version_named_session_claims_the_home() {
|
|
317
|
+
local dir
|
|
318
|
+
dir="$TMP_ROOT/e2e-version-named"
|
|
319
|
+
make_primary_home "$dir"
|
|
320
|
+
run_fixture_tree "$dir" "$VERSIONED_CLAUDE"
|
|
321
|
+
expect_code 2 "$(hook_rc "$dir")" "a version-named session must claim its home and rewake"
|
|
322
|
+
[ -e "$dir/state/arm-ran" ] || fail "supervision never armed for a version-named session"
|
|
323
|
+
[ "$(epoch_outcome "$dir")" = rewake ] || fail "no claim was recorded, got: $(epoch_outcome "$dir")"
|
|
324
|
+
pass "session-lock e2e: a version-named session claims the home and arms supervision"
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
test_e2e_daemon_parented_session_claims_the_home() {
|
|
328
|
+
local dir session_pid daemon_pid lock_after
|
|
329
|
+
dir="$TMP_ROOT/e2e-daemon-parented"
|
|
330
|
+
make_primary_home "$dir"
|
|
331
|
+
run_fixture_tree "$dir" "$NAMED_CLAUDE" "$NAMED_CLAUDE"
|
|
332
|
+
session_pid=$(tr -d '[:space:]' < "$dir/state/session-pid")
|
|
333
|
+
daemon_pid=$(tr -d '[:space:]' < "$dir/state/daemon-pid")
|
|
334
|
+
[ -n "$session_pid" ] && [ "$session_pid" != "$daemon_pid" ] \
|
|
335
|
+
|| fail "fixture did not produce a distinct daemon and session: session=$session_pid daemon=$daemon_pid"
|
|
336
|
+
lock_after=$(tr -d '[:space:]' < "$dir/state/.lock")
|
|
337
|
+
expect_code 2 "$(hook_rc "$dir")" "a session parented by a harness-named daemon must claim its home and rewake"
|
|
338
|
+
[ -e "$dir/state/arm-ran" ] || fail "supervision never armed for a daemon-parented session"
|
|
339
|
+
[ "$lock_after" = "$session_pid" ] || fail "the session lock moved off the session: expected $session_pid, got $lock_after"
|
|
340
|
+
pass "session-lock e2e: a session parented by a harness-named daemon claims the home and arms supervision"
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
test_e2e_daemon_parented_version_named_session_keeps_its_lock() {
|
|
344
|
+
local dir session_pid daemon_pid lock_after
|
|
345
|
+
dir="$TMP_ROOT/e2e-daemon-version-named"
|
|
346
|
+
make_primary_home "$dir"
|
|
347
|
+
run_fixture_tree "$dir" "$VERSIONED_CLAUDE" "$NAMED_CLAUDE"
|
|
348
|
+
session_pid=$(tr -d '[:space:]' < "$dir/state/session-pid")
|
|
349
|
+
daemon_pid=$(tr -d '[:space:]' < "$dir/state/daemon-pid")
|
|
350
|
+
lock_after=$(tr -d '[:space:]' < "$dir/state/.lock")
|
|
351
|
+
[ "$lock_after" != "$daemon_pid" ] \
|
|
352
|
+
|| fail "the live session's lock was reclaimed as stale and rewritten to the shared daemon pid $daemon_pid"
|
|
353
|
+
[ "$lock_after" = "$session_pid" ] || fail "the session lock moved off the session: expected $session_pid, got $lock_after"
|
|
354
|
+
expect_code 2 "$(hook_rc "$dir")" "a version-named session under a daemon must claim its home and rewake"
|
|
355
|
+
[ -e "$dir/state/arm-ran" ] || fail "supervision never armed for a version-named daemon-parented session"
|
|
356
|
+
pass "session-lock e2e: a version-named session under a harness-named daemon keeps its own lock"
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
test_version_named_session_is_identified_on_both_platforms
|
|
360
|
+
test_ordinary_paths_are_never_harness_processes
|
|
361
|
+
test_harness_beyond_a_gap_never_owns_the_lock
|
|
362
|
+
test_competing_version_named_session_is_seen_as_live
|
|
363
|
+
test_e2e_version_named_session_claims_the_home
|
|
364
|
+
test_e2e_daemon_parented_session_claims_the_home
|
|
365
|
+
test_e2e_daemon_parented_version_named_session_keeps_its_lock
|