@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,206 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-send-inbox-doorbell-live-e2e.test.sh - the live doorbell guard
|
|
3
|
+
# (live-harness-optin family).
|
|
4
|
+
#
|
|
5
|
+
# The steering inbox's one behavioral assumption is that a real worker agent
|
|
6
|
+
# follows the constant self-describing doorbell line: list the inbox, read and
|
|
7
|
+
# act on its records in numeric order, then mv each into handled/. A stub can
|
|
8
|
+
# only confirm the assumption already
|
|
9
|
+
# written into the stub, so per .agents/skills/firstmate-coding-guidelines
|
|
10
|
+
# this is proven against every INSTALLED verified harness: each is launched
|
|
11
|
+
# idle in an isolated tmux server, steered through the REAL fm-send (durable
|
|
12
|
+
# record + doorbell), and must both ACT on the instruction (create a named
|
|
13
|
+
# file) and ACKNOWLEDGE it (the mv into handled/), failing loudly with the
|
|
14
|
+
# harness name and version.
|
|
15
|
+
#
|
|
16
|
+
# Run explicitly with FM_SEND_INBOX_LIVE_E2E=1. This test spends a small
|
|
17
|
+
# number of real model tokens per installed harness (one short turn each) -
|
|
18
|
+
# authorized by the harness-dependent-checks rule. An absent harness is
|
|
19
|
+
# reported explicitly and skipped; a run that verified nothing fails rather
|
|
20
|
+
# than passing vacuously. Restrict with
|
|
21
|
+
# FM_SEND_INBOX_LIVE_HARNESSES="claude codex ..." when needed, and tune the
|
|
22
|
+
# per-harness wait with FM_SEND_INBOX_LIVE_TIMEOUT (seconds, default 240).
|
|
23
|
+
# Record the dated per-harness result in
|
|
24
|
+
# docs/verification/runtime-backends.md ("Steering-inbox doorbell").
|
|
25
|
+
#
|
|
26
|
+
# Folder trust: harnesses launch with the repo root as cwd, which the
|
|
27
|
+
# operator's machine has normally already trusted; a trust dialog is a real
|
|
28
|
+
# unready state and correctly fails that harness's check.
|
|
29
|
+
set -u
|
|
30
|
+
|
|
31
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
32
|
+
|
|
33
|
+
if [ "${FM_SEND_INBOX_LIVE_E2E:-0}" != 1 ]; then
|
|
34
|
+
echo "skip: set FM_SEND_INBOX_LIVE_E2E=1 to run the live steering-inbox doorbell guard"
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
command -v tmux >/dev/null 2>&1 || { echo "not ok - FM_SEND_INBOX_LIVE_E2E=1 but tmux is not installed" >&2; exit 1; }
|
|
39
|
+
unset NO_MISTAKES_GATE
|
|
40
|
+
|
|
41
|
+
SOCKET="fm-inbox-live-$$"
|
|
42
|
+
SESSION="inboxlive"
|
|
43
|
+
LAB=$(mktemp -d "${TMPDIR:-/tmp}/fm-inbox-live.XXXXXX")
|
|
44
|
+
LAB=$(cd "$LAB" && pwd)
|
|
45
|
+
TIMEOUT=${FM_SEND_INBOX_LIVE_TIMEOUT:-240}
|
|
46
|
+
CHECKED=0
|
|
47
|
+
FAILED=0
|
|
48
|
+
|
|
49
|
+
pass() { printf 'ok - %s\n' "$1"; }
|
|
50
|
+
note() { printf '# %s\n' "$1"; }
|
|
51
|
+
|
|
52
|
+
cleanup() {
|
|
53
|
+
tmux -L "$SOCKET" kill-server 2>/dev/null || true
|
|
54
|
+
rm -rf "$LAB"
|
|
55
|
+
}
|
|
56
|
+
trap cleanup EXIT
|
|
57
|
+
|
|
58
|
+
# fm-send and the composer readiness read both reach tmux through bare `tmux`
|
|
59
|
+
# calls, so a PATH shim pins them to the private socket.
|
|
60
|
+
SHIM_DIR="$LAB/shim"
|
|
61
|
+
mkdir -p "$SHIM_DIR"
|
|
62
|
+
REAL_TMUX=$(command -v tmux)
|
|
63
|
+
cat > "$SHIM_DIR/tmux" <<SH
|
|
64
|
+
#!/usr/bin/env bash
|
|
65
|
+
exec "$REAL_TMUX" -L "$SOCKET" "\$@"
|
|
66
|
+
SH
|
|
67
|
+
chmod +x "$SHIM_DIR/tmux"
|
|
68
|
+
PATH="$SHIM_DIR:$PATH"
|
|
69
|
+
# shellcheck source=/dev/null
|
|
70
|
+
. "$ROOT/bin/fm-tmux-lib.sh"
|
|
71
|
+
# shellcheck source=/dev/null
|
|
72
|
+
. "$ROOT/bin/fm-task-inbox-lib.sh"
|
|
73
|
+
|
|
74
|
+
tmux -L "$SOCKET" new-session -d -s "$SESSION" -x 220 -y 50 -c "$ROOT"
|
|
75
|
+
|
|
76
|
+
harness_version() { # <binary>
|
|
77
|
+
"$1" --version 2>/dev/null | head -1 || printf 'version-unknown'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Launch <name> idle with its unattended-autonomy flags (the same posture
|
|
81
|
+
# bin/fm-spawn.sh uses), so the doorbell-triggered shell actions need no
|
|
82
|
+
# interactive approval.
|
|
83
|
+
launch_cmd() { # <name>
|
|
84
|
+
case "$1" in
|
|
85
|
+
claude) printf '%s' 'CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false claude --dangerously-skip-permissions' ;;
|
|
86
|
+
codex) printf '%s' 'codex --dangerously-bypass-approvals-and-sandbox' ;;
|
|
87
|
+
opencode) printf '%s' "OPENCODE_CONFIG_CONTENT='{\"permission\":{\"*\":\"allow\"}}' opencode" ;;
|
|
88
|
+
pi|pi-signed) printf '%s' "$1" ;;
|
|
89
|
+
grok) printf '%s' 'grok --always-approve' ;;
|
|
90
|
+
kimi) printf '%s' 'kimi --auto' ;;
|
|
91
|
+
muse) printf '%s' 'MUSE_EXPERIMENTAL_FOREIGN_PERSONAL_CONTEXT_KILL=on muse --yolo' ;;
|
|
92
|
+
*) return 1 ;;
|
|
93
|
+
esac
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Wait for the harness to look steerable. 0 = the composer classified a
|
|
97
|
+
# proven empty; 2 = the readiness budget expired without an empty verdict but
|
|
98
|
+
# also without a pending one. The caller proceeds on 2 with a note, because
|
|
99
|
+
# that mirrors production exactly: the send path's composer check is ADVISORY
|
|
100
|
+
# and skips only on visibly pending text, so a harness whose idle screen the
|
|
101
|
+
# classifier cannot positively identify still gets its doorbell (the composer
|
|
102
|
+
# matrix guard, not this one, owns re-proving the classifier per release).
|
|
103
|
+
wait_ready() { # <window>
|
|
104
|
+
local win=$1 i=0 budget=60 verdict dismissed=0 screen
|
|
105
|
+
while [ "$i" -lt "$budget" ]; do
|
|
106
|
+
verdict=$(fm_tmux_composer_state "$SESSION:$win")
|
|
107
|
+
[ "$verdict" = empty ] && return 0
|
|
108
|
+
i=$((i + 1))
|
|
109
|
+
# Dismiss one non-trust startup modal (update prompts), as the composer
|
|
110
|
+
# matrix guard does; never Enter, which could accept an upgrade.
|
|
111
|
+
if [ "$dismissed" -eq 0 ] && [ "$i" -ge $((budget / 3)) ]; then
|
|
112
|
+
screen=$(tmux -L "$SOCKET" capture-pane -p -t "$SESSION:$win" 2>/dev/null || true)
|
|
113
|
+
if ! printf '%s\n' "$screen" | grep -qi 'trust'; then
|
|
114
|
+
tmux -L "$SOCKET" send-keys -t "$SESSION:$win" Escape 2>/dev/null || true
|
|
115
|
+
fi
|
|
116
|
+
dismissed=1
|
|
117
|
+
fi
|
|
118
|
+
sleep 1
|
|
119
|
+
done
|
|
120
|
+
case "$verdict" in
|
|
121
|
+
pending) return 1 ;;
|
|
122
|
+
esac
|
|
123
|
+
return 2
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
check_harness_doorbell() { # <name>
|
|
127
|
+
local name=$1 version cmd win="hx-$1" home task acted rec handled i ready_rc
|
|
128
|
+
version=$(harness_version "$name")
|
|
129
|
+
cmd=$(launch_cmd "$name") || { note "no launch recipe for $name"; return 0; }
|
|
130
|
+
home="$LAB/$name-home"
|
|
131
|
+
mkdir -p "$home/state"
|
|
132
|
+
task="live-$name"
|
|
133
|
+
acted="$LAB/acted-$name"
|
|
134
|
+
tmux -L "$SOCKET" new-window -d -t "$SESSION:" -n "$win" -c "$ROOT" \
|
|
135
|
+
-- bash -lc "$cmd" \
|
|
136
|
+
|| { FAILED=1; printf 'not ok - %s (%s): could not launch in the isolated tmux server\n' "$name" "$version" >&2; return 0; }
|
|
137
|
+
wait_ready "$win"; ready_rc=$?
|
|
138
|
+
if [ "$ready_rc" -eq 1 ]; then
|
|
139
|
+
FAILED=1
|
|
140
|
+
printf 'not ok - %s (%s): composer stayed visibly pending; the pane is not steerable\n' "$name" "$version" >&2
|
|
141
|
+
tmux -L "$SOCKET" capture-pane -p -t "$SESSION:$win" 2>/dev/null | grep '[^[:space:]]' | tail -6 | sed 's/^/# /' >&2
|
|
142
|
+
tmux -L "$SOCKET" kill-window -t "$SESSION:$win" 2>/dev/null || true
|
|
143
|
+
return 0
|
|
144
|
+
fi
|
|
145
|
+
[ "$ready_rc" -eq 0 ] || note "$name ($version): idle composer never classified empty; proceeding as production does (advisory check skips only on pending)"
|
|
146
|
+
printf 'window=%s:%s\nkind=ship\nharness=%s\n' "$SESSION" "$win" "$name" > "$home/state/$task.meta"
|
|
147
|
+
if ! FM_HOME="$home" FM_ROOT_OVERRIDE="$home" "$ROOT/bin/fm-send.sh" "$task" \
|
|
148
|
+
"Firstmate live check: run exactly this shell command now: touch $acted - then follow the mv instruction you were given for this message. Reply with one short line." \
|
|
149
|
+
>/dev/null 2>&1; then
|
|
150
|
+
FAILED=1
|
|
151
|
+
printf 'not ok - %s (%s): fm-send refused the live steer\n' "$name" "$version" >&2
|
|
152
|
+
tmux -L "$SOCKET" kill-window -t "$SESSION:$win" 2>/dev/null || true
|
|
153
|
+
return 0
|
|
154
|
+
fi
|
|
155
|
+
rec="$home/state/$task.inbox/001.msg"
|
|
156
|
+
handled="$home/state/$task.inbox/handled/001.msg"
|
|
157
|
+
[ -f "$rec" ] || {
|
|
158
|
+
FAILED=1
|
|
159
|
+
printf 'not ok - %s (%s): fm-send left no durable inbox record\n' "$name" "$version" >&2
|
|
160
|
+
tmux -L "$SOCKET" kill-window -t "$SESSION:$win" 2>/dev/null || true
|
|
161
|
+
return 0
|
|
162
|
+
}
|
|
163
|
+
i=0
|
|
164
|
+
while [ "$i" -lt "$TIMEOUT" ]; do
|
|
165
|
+
[ -f "$handled" ] && [ -e "$acted" ] && break
|
|
166
|
+
# Halfway through, play the watcher's role once: re-ring an unacknowledged
|
|
167
|
+
# message so a doorbell swallowed by a startup or update modal recovers
|
|
168
|
+
# exactly as the production re-ring ladder recovers it.
|
|
169
|
+
if [ "$i" -eq $((TIMEOUT / 2)) ] && [ -f "$rec" ]; then
|
|
170
|
+
fm_task_inbox_ring tmux "$SESSION:$win" "$rec" || true
|
|
171
|
+
note "$name ($version): re-rang the doorbell once (watcher's role) at ${i}s"
|
|
172
|
+
fi
|
|
173
|
+
sleep 1
|
|
174
|
+
i=$((i + 1))
|
|
175
|
+
done
|
|
176
|
+
if [ -f "$handled" ] && [ -e "$acted" ]; then
|
|
177
|
+
CHECKED=$((CHECKED + 1))
|
|
178
|
+
pass "$name ($version): the doorbell reached a real worker, which acted and acked with the mv"
|
|
179
|
+
else
|
|
180
|
+
FAILED=1
|
|
181
|
+
printf 'not ok - %s (%s): doorbell not honored within %ss (acted=%s acked=%s)\n' \
|
|
182
|
+
"$name" "$version" "$TIMEOUT" "$([ -e "$acted" ] && echo yes || echo no)" \
|
|
183
|
+
"$([ -f "$handled" ] && echo yes || echo no)" >&2
|
|
184
|
+
tmux -L "$SOCKET" capture-pane -p -t "$SESSION:$win" 2>/dev/null | grep '[^[:space:]]' | tail -10 | sed 's/^/# /' >&2
|
|
185
|
+
fi
|
|
186
|
+
tmux -L "$SOCKET" kill-window -t "$SESSION:$win" 2>/dev/null || true
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
HARNESSES=${FM_SEND_INBOX_LIVE_HARNESSES:-'claude codex opencode pi grok kimi muse'}
|
|
190
|
+
for h in $HARNESSES; do
|
|
191
|
+
if command -v "$h" >/dev/null 2>&1; then
|
|
192
|
+
check_harness_doorbell "$h"
|
|
193
|
+
else
|
|
194
|
+
note "harness absent, not verified here: $h"
|
|
195
|
+
fi
|
|
196
|
+
done
|
|
197
|
+
|
|
198
|
+
if [ "$FAILED" -ne 0 ]; then
|
|
199
|
+
printf 'not ok - live steering-inbox doorbell guard found failures above\n' >&2
|
|
200
|
+
exit 1
|
|
201
|
+
fi
|
|
202
|
+
if [ "$CHECKED" -eq 0 ]; then
|
|
203
|
+
printf 'not ok - live steering-inbox doorbell guard verified nothing (no harness installed?)\n' >&2
|
|
204
|
+
exit 1
|
|
205
|
+
fi
|
|
206
|
+
pass "live steering-inbox doorbell guard: $CHECKED harness(es) honored the doorbell contract"
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-send-inbox.test.sh - fm-send's inbox data plane.
|
|
3
|
+
#
|
|
4
|
+
# An ordinary text steer to a task recorded in this home no longer types its
|
|
5
|
+
# payload: fm-send appends a durable sequenced record to state/<id>.inbox/ and
|
|
6
|
+
# rings one constant self-describing doorbell line, best-effort. These tests
|
|
7
|
+
# drive the real fm-send executable over a stubbed tmux and pin:
|
|
8
|
+
# 1. The payload is durably recorded and never typed; only the doorbell
|
|
9
|
+
# crosses the terminal, and the send exits 0 at enqueue.
|
|
10
|
+
# 2. Multi-line steers are legal and round-trip byte-exact.
|
|
11
|
+
# 3. A re-send enqueues a NEW sequence and still never retypes a payload,
|
|
12
|
+
# so the terminal can never truncate, garble, or duplicate a steer.
|
|
13
|
+
# 4. The composer pre-check is advisory: visibly pending text skips the ring
|
|
14
|
+
# with a notice, and the steer is still durably sent (exit 0).
|
|
15
|
+
# 5. A failed doorbell is still a sent steer (exit 0, record durable): the
|
|
16
|
+
# watcher's re-ring ladder owns delivery from the record on.
|
|
17
|
+
# 6. Carve-outs keep the typed plane: a leading "/" (any harness), a leading
|
|
18
|
+
# "$" to codex, an explicit backend target, and the --key path.
|
|
19
|
+
# 7. A marked secondmate steer carries its marker + corr token in the record
|
|
20
|
+
# body, and the pending-reply expectation is marked delivered at enqueue.
|
|
21
|
+
# 8. Pending-reply bookkeeping failure after enqueue never reports a
|
|
22
|
+
# retryable send failure that could duplicate the durable instruction.
|
|
23
|
+
# 9. An unwritable inbox is a real local failure: nonzero exit, nothing
|
|
24
|
+
# typed, and a just-created pending-reply expectation is discarded.
|
|
25
|
+
# Every case below that passes a literal `$...` message quotes it on purpose
|
|
26
|
+
# (the point is sending an unexpanded `$` line), so SC2016 is disabled.
|
|
27
|
+
# shellcheck disable=SC2016
|
|
28
|
+
set -u
|
|
29
|
+
|
|
30
|
+
# shellcheck source=tests/lib.sh
|
|
31
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
32
|
+
# shellcheck source=/dev/null
|
|
33
|
+
. "$ROOT/bin/fm-marker-lib.sh"
|
|
34
|
+
|
|
35
|
+
SEND="$ROOT/bin/fm-send.sh"
|
|
36
|
+
|
|
37
|
+
TMP_ROOT=$(fm_test_tmproot fm-send-inbox)
|
|
38
|
+
TMP_ROOT=$(cd "$TMP_ROOT" && pwd)
|
|
39
|
+
|
|
40
|
+
# Stub tmux: logs literal typed text to FM_SEND_LOG and lets the submit and
|
|
41
|
+
# composer paths reach clean verdicts. FM_FAKE_TMUX_COMPOSER=pending renders a
|
|
42
|
+
# composer visibly holding text; FM_FAKE_TMUX_SEND_FAIL=1 fails send-keys.
|
|
43
|
+
make_stubs() { # <dir> -> echoes fakebin dir
|
|
44
|
+
local dir=$1 fb="$1/fakebin"
|
|
45
|
+
mkdir -p "$fb"
|
|
46
|
+
cat > "$fb/tmux" <<'SH'
|
|
47
|
+
#!/usr/bin/env bash
|
|
48
|
+
set -u
|
|
49
|
+
case "${1:-}" in
|
|
50
|
+
send-keys)
|
|
51
|
+
[ "${FM_FAKE_TMUX_SEND_FAIL:-0}" = 1 ] && exit 1
|
|
52
|
+
shift
|
|
53
|
+
literal=0
|
|
54
|
+
while [ $# -gt 0 ]; do
|
|
55
|
+
case "$1" in
|
|
56
|
+
-t) shift 2 ;;
|
|
57
|
+
-l) literal=1; shift ;;
|
|
58
|
+
*) break ;;
|
|
59
|
+
esac
|
|
60
|
+
done
|
|
61
|
+
if [ "$literal" = 1 ]; then
|
|
62
|
+
printf '%s\n' "${1:-}" >> "$FM_SEND_LOG"
|
|
63
|
+
fi
|
|
64
|
+
exit 0 ;;
|
|
65
|
+
display-message)
|
|
66
|
+
for a in "$@"; do case "$a" in *cursor_y*) printf '1\n'; exit 0 ;; esac; done
|
|
67
|
+
printf 'fakepane\n'; exit 0 ;;
|
|
68
|
+
capture-pane)
|
|
69
|
+
if [ "${FM_FAKE_TMUX_COMPOSER:-}" = pending ]; then
|
|
70
|
+
printf '╭──────────────╮\n│ leftover txt │\n╰──────────────╯\n'
|
|
71
|
+
else
|
|
72
|
+
printf '╭────╮\n│ │\n╰────╯\n'
|
|
73
|
+
fi
|
|
74
|
+
exit 0 ;;
|
|
75
|
+
list-windows) exit 0 ;;
|
|
76
|
+
esac
|
|
77
|
+
exit 0
|
|
78
|
+
SH
|
|
79
|
+
chmod +x "$fb/tmux"
|
|
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_case() { # <name> [harness] -> echoes case dir with home/state + t1 meta
|
|
89
|
+
local name=$1 harness=${2:-claude} dir
|
|
90
|
+
dir="$TMP_ROOT/$name"
|
|
91
|
+
mkdir -p "$dir/home/state"
|
|
92
|
+
make_stubs "$dir" >/dev/null
|
|
93
|
+
fm_write_meta "$dir/home/state/t1.meta" "window=sess:fm-t1" "kind=ship" "harness=$harness"
|
|
94
|
+
printf '%s\n' "$dir"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
run_send() { # <case-dir> <err-file> [env...] -- <fm-send args...>
|
|
98
|
+
local dir=$1 err=$2
|
|
99
|
+
shift 2
|
|
100
|
+
local envs=()
|
|
101
|
+
while [ "$#" -gt 0 ] && [ "$1" != "--" ]; do
|
|
102
|
+
envs+=("$1")
|
|
103
|
+
shift
|
|
104
|
+
done
|
|
105
|
+
shift
|
|
106
|
+
: > "$dir/send.log"
|
|
107
|
+
env PATH="$dir/fakebin:$PATH" \
|
|
108
|
+
FM_ROOT_OVERRIDE="$dir/home" FM_HOME="$dir/home" FM_SEND_LOG="$dir/send.log" \
|
|
109
|
+
FM_SEND_SETTLE=0 ${envs[@]+"${envs[@]}"} \
|
|
110
|
+
"$SEND" "$@" >/dev/null 2>"$err"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
record_body() { # <record>
|
|
114
|
+
bash -c '. "$1"; fm_task_inbox_body "$2"' _ "$ROOT/bin/fm-task-inbox-lib.sh" "$2"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
test_text_steer_rides_inbox() {
|
|
118
|
+
local dir err rc rec body typed
|
|
119
|
+
dir=$(setup_case rides); err="$dir/send.err"
|
|
120
|
+
run_send "$dir" "$err" -- t1 "please rebase onto main"; rc=$?
|
|
121
|
+
expect_code 0 "$rc" "an inbox-plane steer should exit 0 at enqueue"
|
|
122
|
+
rec="$dir/home/state/t1.inbox/001.msg"
|
|
123
|
+
[ -f "$rec" ] || fail "the steer was not durably recorded at $rec"
|
|
124
|
+
body=$(record_body _ "$rec")
|
|
125
|
+
[ "$body" = "please rebase onto main" ] || fail "the recorded body differs: $body"
|
|
126
|
+
typed=$(cat "$dir/send.log")
|
|
127
|
+
assert_contains "$typed" "Firstmate instruction waiting: list $dir/home/state/t1.inbox/*.msg" \
|
|
128
|
+
"the doorbell should direct the worker to drain the inbox"
|
|
129
|
+
case "$typed" in
|
|
130
|
+
*"please rebase onto main"*) fail "the payload must never be typed:"$'\n'"$typed" ;;
|
|
131
|
+
esac
|
|
132
|
+
pass "fm-send inbox: the payload is recorded durably and only the doorbell is typed"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
test_multiline_steer_is_legal() {
|
|
136
|
+
local dir err rc body
|
|
137
|
+
dir=$(setup_case multiline); err="$dir/send.err"
|
|
138
|
+
run_send "$dir" "$err" -- t1 $'first line\nsecond line\nthird: with punctuation'; rc=$?
|
|
139
|
+
expect_code 0 "$rc" "a multi-line steer should succeed"
|
|
140
|
+
body=$(record_body _ "$dir/home/state/t1.inbox/001.msg")
|
|
141
|
+
[ "$body" = $'first line\nsecond line\nthird: with punctuation' ] \
|
|
142
|
+
|| fail "the multi-line body did not round-trip:"$'\n'"$body"
|
|
143
|
+
case "$(cat "$dir/send.log")" in
|
|
144
|
+
*"second line"*) fail "a payload line leaked onto the typed channel" ;;
|
|
145
|
+
esac
|
|
146
|
+
pass "fm-send inbox: newlines are legal and the terminal can no longer truncate a steer"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
test_resend_enqueues_new_sequence() {
|
|
150
|
+
local dir err doorbells typed
|
|
151
|
+
dir=$(setup_case resend); err="$dir/send.err"
|
|
152
|
+
run_send "$dir" "$err" -- t1 "check the CI result" || fail "first send failed"
|
|
153
|
+
run_send "$dir" "$err" -- t1 "check the CI result" || fail "second send failed"
|
|
154
|
+
[ -f "$dir/home/state/t1.inbox/001.msg" ] && [ -f "$dir/home/state/t1.inbox/002.msg" ] \
|
|
155
|
+
|| fail "a re-send should enqueue a new sequence:"$'\n'"$(ls "$dir/home/state/t1.inbox")"
|
|
156
|
+
doorbells=$(grep -cF 'Firstmate instruction waiting' "$dir/send.log" || true)
|
|
157
|
+
[ "$doorbells" = 1 ] || fail "each send rings once (the log is truncated per send), got $doorbells"
|
|
158
|
+
typed=$(cat "$dir/send.log")
|
|
159
|
+
assert_contains "$typed" "numeric order" \
|
|
160
|
+
"a newer record's doorbell should preserve inbox sequence ordering"
|
|
161
|
+
case "$typed" in
|
|
162
|
+
*"check the CI result"*) fail "a re-send typed the payload" ;;
|
|
163
|
+
esac
|
|
164
|
+
pass "fm-send inbox: a re-send is a new durable record, never a retyped payload"
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
test_pending_composer_skips_ring_advisorily() {
|
|
168
|
+
local dir err rc
|
|
169
|
+
dir=$(setup_case pendingskip); err="$dir/send.err"
|
|
170
|
+
run_send "$dir" "$err" FM_FAKE_TMUX_COMPOSER=pending -- t1 "steer past a stuck composer"; rc=$?
|
|
171
|
+
expect_code 0 "$rc" "a skipped ring is still a sent steer"
|
|
172
|
+
[ -f "$dir/home/state/t1.inbox/001.msg" ] || fail "the steer was not recorded"
|
|
173
|
+
[ ! -s "$dir/send.log" ] || fail "a visibly pending composer should skip the ring:"$'\n'"$(cat "$dir/send.log")"
|
|
174
|
+
assert_contains "$(cat "$err")" "watcher will re-ring" \
|
|
175
|
+
"the skip notice should point at the re-ring"
|
|
176
|
+
pass "fm-send inbox: a visibly pending composer skips the ring, and the steer stays durably sent"
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
test_failed_ring_is_still_sent() {
|
|
180
|
+
local dir err rc
|
|
181
|
+
dir=$(setup_case ringfail); err="$dir/send.err"
|
|
182
|
+
run_send "$dir" "$err" FM_FAKE_TMUX_SEND_FAIL=1 -- t1 "steer into a dead pane"; rc=$?
|
|
183
|
+
expect_code 0 "$rc" "a failed doorbell must not fail the send"
|
|
184
|
+
[ -f "$dir/home/state/t1.inbox/001.msg" ] || fail "the steer was not recorded"
|
|
185
|
+
assert_contains "$(cat "$err")" "watcher will re-ring" \
|
|
186
|
+
"the failed-ring notice should point at the re-ring"
|
|
187
|
+
pass "fm-send inbox: a failed doorbell is still a durably sent steer"
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
test_harness_invocations_stay_typed() {
|
|
191
|
+
local dir err typed
|
|
192
|
+
# A slash command must reach the harness's own parser, on any harness.
|
|
193
|
+
dir=$(setup_case slash); err="$dir/send.err"
|
|
194
|
+
run_send "$dir" "$err" -- t1 "/no-mistakes" || fail "a slash send should succeed"
|
|
195
|
+
typed=$(cat "$dir/send.log")
|
|
196
|
+
assert_contains "$typed" "/no-mistakes" "the slash command should be typed literally"
|
|
197
|
+
[ ! -d "$dir/home/state/t1.inbox" ] || fail "a slash command must not be routed to the inbox"
|
|
198
|
+
# A codex `$<skill>` invocation likewise stays typed.
|
|
199
|
+
dir=$(setup_case codexskill codex); err="$dir/send.err"
|
|
200
|
+
run_send "$dir" "$err" -- t1 '$no-mistakes' || fail "a codex \$skill send should succeed"
|
|
201
|
+
assert_contains "$(cat "$dir/send.log")" '$no-mistakes' "the codex \$skill should be typed literally"
|
|
202
|
+
[ ! -d "$dir/home/state/t1.inbox" ] || fail "a codex \$skill must not be routed to the inbox"
|
|
203
|
+
# The same `$` message to a non-codex harness is plain text: inbox plane.
|
|
204
|
+
dir=$(setup_case dollartext claude); err="$dir/send.err"
|
|
205
|
+
run_send "$dir" "$err" -- t1 '$5/month is cheap' || fail "a claude \$-text send should succeed"
|
|
206
|
+
[ -f "$dir/home/state/t1.inbox/001.msg" ] || fail "a non-codex \$-message should ride the inbox"
|
|
207
|
+
case "$(cat "$dir/send.log")" in
|
|
208
|
+
*'$5/month'*) fail "a non-codex \$-message payload was typed" ;;
|
|
209
|
+
esac
|
|
210
|
+
pass "fm-send planes: slash and codex \$skill invocations stay typed; plain \$-text rides the inbox"
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
test_explicit_target_stays_typed() {
|
|
214
|
+
local dir err
|
|
215
|
+
dir=$(setup_case explicit); err="$dir/send.err"
|
|
216
|
+
run_send "$dir" "$err" -- sess:win "hello there" || fail "an explicit-target send should succeed"
|
|
217
|
+
assert_contains "$(cat "$dir/send.log")" "hello there" \
|
|
218
|
+
"an explicit backend target should receive the literal text"
|
|
219
|
+
[ -z "$(find "$dir/home/state" -maxdepth 1 -name '*.inbox' -print 2>/dev/null)" ] \
|
|
220
|
+
|| fail "an explicit target has no task record here and must not grow an inbox"
|
|
221
|
+
pass "fm-send planes: an explicit backend target keeps the typed plane"
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
test_key_path_never_touches_inbox() {
|
|
225
|
+
local dir err
|
|
226
|
+
dir=$(setup_case keypath); err="$dir/send.err"
|
|
227
|
+
run_send "$dir" "$err" -- t1 --key Enter || fail "a --key send should succeed"
|
|
228
|
+
[ ! -d "$dir/home/state/t1.inbox" ] || fail "the --key path must never write an inbox record"
|
|
229
|
+
pass "fm-send planes: the --key lifecycle path never touches the inbox"
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
test_secondmate_marker_and_enqueue_delivery() {
|
|
233
|
+
local dir err body corr pr_rec delivered
|
|
234
|
+
dir=$(setup_case secondmate); err="$dir/send.err"
|
|
235
|
+
fm_write_secondmate_meta "$dir/home/state/domain.meta" "$dir/home" "sess:fm-domain"
|
|
236
|
+
run_send "$dir" "$err" -- fm-domain "please summarize fleet health" \
|
|
237
|
+
|| fail "a secondmate steer should succeed"
|
|
238
|
+
body=$(record_body _ "$dir/home/state/domain.inbox/001.msg")
|
|
239
|
+
case "$body" in
|
|
240
|
+
"$FM_FROMFIRST_MARK"corr=*) : ;;
|
|
241
|
+
*) fail "the recorded body lost the from-firstmate marker/corr framing:"$'\n'"$body" ;;
|
|
242
|
+
esac
|
|
243
|
+
corr=$(printf '%s' "$body" | grep -oE 'corr=[a-f0-9]{16}' | head -1 | cut -d= -f2)
|
|
244
|
+
[ -n "$corr" ] || fail "no corr token in the recorded body"
|
|
245
|
+
pr_rec="$dir/home/state/pending-replies/$corr"
|
|
246
|
+
[ -f "$pr_rec" ] || fail "no pending-reply expectation was recorded at $pr_rec"
|
|
247
|
+
delivered=$(grep '^delivered_epoch=' "$pr_rec" | cut -d= -f2)
|
|
248
|
+
[ -n "$delivered" ] || fail "enqueue IS delivery: delivered_epoch should be set at enqueue time:"$'\n'"$(cat "$pr_rec")"
|
|
249
|
+
case "$(cat "$dir/send.log")" in
|
|
250
|
+
*"summarize fleet health"*) fail "the marked payload was typed" ;;
|
|
251
|
+
esac
|
|
252
|
+
pass "fm-send inbox: a secondmate steer records marker+corr in the body and is delivered at enqueue"
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
test_post_enqueue_bookkeeping_failure_is_not_retryable() {
|
|
256
|
+
local dir err rc rec body
|
|
257
|
+
dir=$(setup_case bookkeeping-failure); err="$dir/send.err"
|
|
258
|
+
fm_write_secondmate_meta "$dir/home/state/domain.meta" "$dir/home" "sess:fm-domain"
|
|
259
|
+
cat > "$dir/fakebin/mv" <<'SH'
|
|
260
|
+
#!/usr/bin/env bash
|
|
261
|
+
set -u
|
|
262
|
+
source_arg=${@: -2:1}
|
|
263
|
+
target_arg=${@: -1}
|
|
264
|
+
if [ "${FM_FAIL_DELIVERY_CONFIRM:-0}" = 1 ] \
|
|
265
|
+
&& grep -q '^confirmed=' "$source_arg" 2>/dev/null; then
|
|
266
|
+
# Simulate losing both the delivery commit and its prepared recovery marker.
|
|
267
|
+
rm -f "$target_arg"
|
|
268
|
+
exit 1
|
|
269
|
+
fi
|
|
270
|
+
exec /bin/mv "$@"
|
|
271
|
+
SH
|
|
272
|
+
chmod +x "$dir/fakebin/mv"
|
|
273
|
+
|
|
274
|
+
run_send "$dir" "$err" FM_FAIL_DELIVERY_CONFIRM=1 -- domain "durable once"; rc=$?
|
|
275
|
+
# The durable record IS the delivery: even with the commit AND its recovery
|
|
276
|
+
# marker both lost, the steer was delivered, so fm-send must not signal a
|
|
277
|
+
# status that invites a resend (a nonzero would make automated callers
|
|
278
|
+
# enqueue the same instruction again under a new sequence). The degradation
|
|
279
|
+
# surfaces as its own distinct do-not-resend condition instead.
|
|
280
|
+
expect_code 0 "$rc" "a delivered steer must not report a resend-inviting failure over lost bookkeeping"
|
|
281
|
+
rec="$dir/home/state/domain.inbox/001.msg"
|
|
282
|
+
[ -f "$rec" ] || fail "bookkeeping failure test did not durably enqueue the steer"
|
|
283
|
+
[ "$(find "$dir/home/state/domain.inbox" -maxdepth 1 -name '*.msg' | wc -l | tr -d ' ')" = 1 ] \
|
|
284
|
+
|| fail "the delivered steer was duplicated:"$'\n'"$(ls "$dir/home/state/domain.inbox")"
|
|
285
|
+
body=$(record_body _ "$rec")
|
|
286
|
+
case "$body" in
|
|
287
|
+
"$FM_FROMFIRST_MARK"corr=*) : ;;
|
|
288
|
+
*) fail "bookkeeping failure test lost the secondmate marker: $body" ;;
|
|
289
|
+
esac
|
|
290
|
+
assert_contains "$(cat "$err")" "reply-tracking-degraded" \
|
|
291
|
+
"lost bookkeeping should surface as its own distinct degraded condition"
|
|
292
|
+
assert_contains "$(cat "$err")" "do not resend" \
|
|
293
|
+
"the degraded condition should give explicit do-not-resend guidance"
|
|
294
|
+
assert_contains "$(cat "$err")" "durably recorded at" \
|
|
295
|
+
"the degraded condition should name the already-delivered record"
|
|
296
|
+
pass "fm-send inbox: lost reply bookkeeping never invites a resend, and the delivered steer is never duplicated"
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
test_meta_lock_contention_fails_bounded() {
|
|
300
|
+
local dir err rc holder marker lock i
|
|
301
|
+
dir=$(setup_case meta-lock); err="$dir/send.err"
|
|
302
|
+
marker="$dir/meta-lock-held"
|
|
303
|
+
lock="$dir/home/state/.meta-t1.lock"
|
|
304
|
+
bash -c '
|
|
305
|
+
. "$1"
|
|
306
|
+
fm_lock_acquire_wait "$2"
|
|
307
|
+
touch "$3"
|
|
308
|
+
sleep 30
|
|
309
|
+
' _ "$ROOT/bin/fm-wake-lib.sh" "$lock" "$marker" &
|
|
310
|
+
holder=$!
|
|
311
|
+
i=0
|
|
312
|
+
while [ ! -e "$marker" ] && [ "$i" -lt 100 ]; do
|
|
313
|
+
sleep 0.05
|
|
314
|
+
i=$((i + 1))
|
|
315
|
+
done
|
|
316
|
+
[ -e "$marker" ] || { kill "$holder" 2>/dev/null; fail "the metadata lock holder did not start"; }
|
|
317
|
+
run_send "$dir" "$err" FM_TASK_INBOX_LOCK_WAIT_SECS=0 -- t1 "must not hang"; rc=$?
|
|
318
|
+
kill "$holder" 2>/dev/null; wait "$holder" 2>/dev/null
|
|
319
|
+
[ "$rc" -ne 0 ] || fail "metadata lock contention should fail after the bounded wait"
|
|
320
|
+
[ ! -d "$dir/home/state/t1.inbox" ] || fail "a lock refusal must not enqueue a record"
|
|
321
|
+
assert_contains "$(cat "$err")" "metadata could not be locked" \
|
|
322
|
+
"the bounded metadata lock refusal should be explicit"
|
|
323
|
+
pass "fm-send inbox: metadata lock contention fails bounded without enqueue"
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
test_unwritable_inbox_fails_loudly() {
|
|
327
|
+
local dir err rc
|
|
328
|
+
dir=$(setup_case unwritable); err="$dir/send.err"
|
|
329
|
+
fm_write_secondmate_meta "$dir/home/state/domain.meta" "$dir/home" "sess:fm-domain"
|
|
330
|
+
: > "$dir/home/state/domain.inbox" # a FILE where the inbox dir must go
|
|
331
|
+
run_send "$dir" "$err" -- fm-domain "this cannot be recorded"; rc=$?
|
|
332
|
+
[ "$rc" -ne 0 ] || fail "an unwritable inbox must fail the send"
|
|
333
|
+
assert_contains "$(cat "$err")" "inbox record could not be written" \
|
|
334
|
+
"the failure should name the unwritable inbox"
|
|
335
|
+
[ ! -s "$dir/send.log" ] || fail "a failed enqueue still typed something:"$'\n'"$(cat "$dir/send.log")"
|
|
336
|
+
[ -z "$(find "$dir/home/state/pending-replies" -type f -not -name '.*' 2>/dev/null)" ] \
|
|
337
|
+
|| fail "a failed enqueue should discard the just-created pending-reply expectation"
|
|
338
|
+
pass "fm-send inbox: an unwritable record is a loud local failure that leaves no false expectation"
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
test_text_steer_rides_inbox
|
|
342
|
+
test_multiline_steer_is_legal
|
|
343
|
+
test_resend_enqueues_new_sequence
|
|
344
|
+
test_pending_composer_skips_ring_advisorily
|
|
345
|
+
test_failed_ring_is_still_sent
|
|
346
|
+
test_harness_invocations_stay_typed
|
|
347
|
+
test_explicit_target_stays_typed
|
|
348
|
+
test_key_path_never_touches_inbox
|
|
349
|
+
test_secondmate_marker_and_enqueue_delivery
|
|
350
|
+
test_post_enqueue_bookkeeping_failure_is_not_retryable
|
|
351
|
+
test_meta_lock_contention_fails_bounded
|
|
352
|
+
test_unwritable_inbox_fails_loudly
|