@zerwiz/ymir 0.1.4 → 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 -59
- 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,357 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Opt-in credentialed OpenCode continuity regression on an isolated project and
|
|
3
|
+
# FM_HOME. Existing OpenCode credentials stay in their managed store.
|
|
4
|
+
set -u
|
|
5
|
+
|
|
6
|
+
if [ "${FM_OPENCODE_LIVE_E2E:-0}" != 1 ]; then
|
|
7
|
+
echo "skip: set FM_OPENCODE_LIVE_E2E=1 to run the interactive OpenCode continuity regression"
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
12
|
+
unset NO_MISTAKES_GATE
|
|
13
|
+
|
|
14
|
+
fail() {
|
|
15
|
+
printf 'not ok - %s\n' "$1" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
command -v opencode >/dev/null 2>&1 || fail "opencode not found"
|
|
20
|
+
command -v tmux >/dev/null 2>&1 || fail "tmux not found"
|
|
21
|
+
command -v sqlite3 >/dev/null 2>&1 || fail "sqlite3 not found"
|
|
22
|
+
|
|
23
|
+
TMUX=$(command -v tmux)
|
|
24
|
+
SOCKET="fm-opencode-live-e2e-$$"
|
|
25
|
+
SESSION=opencode-live-e2e
|
|
26
|
+
LAB="$ROOT/.opencode-live-e2e.$$"
|
|
27
|
+
PROJECT="$LAB/project"
|
|
28
|
+
HOME_DIR="$LAB/fmhome"
|
|
29
|
+
OPENCODE_VERSION=$(opencode --version)
|
|
30
|
+
AHOY_PROJECT="$LAB/ahoy-project"
|
|
31
|
+
# shellcheck source=/dev/null
|
|
32
|
+
. "$ROOT/bin/fm-operational-input.sh"
|
|
33
|
+
# shellcheck disable=SC2016 # Backticks are literal prompt markup.
|
|
34
|
+
LEGACY_START='Run `bin/fm-session-start.sh` now, exactly once, before executing any other instructions.'
|
|
35
|
+
fm_operational_input_encode session-start "$LEGACY_START" CURRENT_START \
|
|
36
|
+
|| fail "could not construct the current session-start fixture"
|
|
37
|
+
MARKER_NEAR_MISS=$'\xE2\x81\xA3Captain note: this invisible separator is intentional.'
|
|
38
|
+
# shellcheck disable=SC2016 # Backticks are literal prompt markup.
|
|
39
|
+
START_NEAR_MISS='Captain quote: Run `bin/fm-session-start.sh` now, exactly once, before executing any other instructions.'
|
|
40
|
+
fm_operational_input_encode watcher "CURRENT_AHOY_WATCHER_BODY" CURRENT_WATCHER \
|
|
41
|
+
|| fail "could not construct current Ahoy watcher fixture"
|
|
42
|
+
QUOTED_CURRENT="Captain quote: $CURRENT_WATCHER"
|
|
43
|
+
ASCII_ONLY='FIRSTMATE_OP: v1 watcher: captain-authored text'
|
|
44
|
+
|
|
45
|
+
capture() {
|
|
46
|
+
"$TMUX" -L "$SOCKET" capture-pane -p -t "$SESSION" -S -800 2>/dev/null || true
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
wait_for_text() {
|
|
50
|
+
local expected=$1 attempts=${2:-180} i=0
|
|
51
|
+
while [ "$i" -lt "$attempts" ]; do
|
|
52
|
+
capture | grep -Fq "$expected" && return 0
|
|
53
|
+
sleep 0.5
|
|
54
|
+
i=$((i + 1))
|
|
55
|
+
done
|
|
56
|
+
capture >&2
|
|
57
|
+
return 1
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
wait_for_absent() {
|
|
61
|
+
local unexpected=$1 attempts=${2:-60} i=0
|
|
62
|
+
while [ "$i" -lt "$attempts" ]; do
|
|
63
|
+
capture | grep -Fq "$unexpected" || return 0
|
|
64
|
+
sleep 0.5
|
|
65
|
+
i=$((i + 1))
|
|
66
|
+
done
|
|
67
|
+
capture >&2
|
|
68
|
+
return 1
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
dismiss_update_offer() {
|
|
72
|
+
capture | grep -Fq "Update Available" || return 0
|
|
73
|
+
# Choose Skip explicitly. Escape merely hides the offer until the next idle
|
|
74
|
+
# event, which can obstruct the watcher follow-up under test.
|
|
75
|
+
"$TMUX" -L "$SOCKET" send-keys -t "$SESSION" Left Enter
|
|
76
|
+
wait_for_absent "Update Available" 60
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
wait_for_handled() {
|
|
80
|
+
local i=0
|
|
81
|
+
while [ "$i" -lt 240 ]; do
|
|
82
|
+
dismiss_update_offer || return 1
|
|
83
|
+
[ -f "$HOME_DIR/state/opencode-model-handled" ] && return 0
|
|
84
|
+
sleep 0.5
|
|
85
|
+
i=$((i + 1))
|
|
86
|
+
done
|
|
87
|
+
capture >&2
|
|
88
|
+
return 1
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
lab_pid_is_safe() {
|
|
92
|
+
local pid=$1 command
|
|
93
|
+
command=$(ps -p "$pid" -o command= 2>/dev/null || true)
|
|
94
|
+
case "$command" in
|
|
95
|
+
*"$LAB"*) return 0 ;;
|
|
96
|
+
*) return 1 ;;
|
|
97
|
+
esac
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
cleanup() {
|
|
101
|
+
local watcher_pid arm_pid
|
|
102
|
+
watcher_pid=$(cat "$HOME_DIR/state/.watch.lock/pid" 2>/dev/null || true)
|
|
103
|
+
arm_pid=$(ps -p "$watcher_pid" -o ppid= 2>/dev/null | tr -d ' ' || true)
|
|
104
|
+
"$TMUX" -L "$SOCKET" kill-server 2>/dev/null || true
|
|
105
|
+
sleep 0.1
|
|
106
|
+
if [ -n "$watcher_pid" ] && lab_pid_is_safe "$watcher_pid"; then
|
|
107
|
+
kill -TERM "$watcher_pid" 2>/dev/null || true
|
|
108
|
+
fi
|
|
109
|
+
if [ -n "$arm_pid" ] && lab_pid_is_safe "$arm_pid"; then
|
|
110
|
+
kill -TERM "$arm_pid" 2>/dev/null || true
|
|
111
|
+
fi
|
|
112
|
+
rm -rf "$LAB"
|
|
113
|
+
}
|
|
114
|
+
trap cleanup EXIT
|
|
115
|
+
|
|
116
|
+
run_ahoy_case() {
|
|
117
|
+
local label=$1 preceding=$2 expected=$3 db="$LAB/opencode-$1.db"
|
|
118
|
+
local assistant_text first_out second_out session_id status=0
|
|
119
|
+
first_out=$(
|
|
120
|
+
cd "$AHOY_PROJECT" &&
|
|
121
|
+
OPENCODE_DB="$db" OPENCODE_DISABLE_AUTOUPDATE=1 OPENCODE_DISABLE_LSP_DOWNLOAD=1 \
|
|
122
|
+
OPENCODE_CONFIG_CONTENT='{"permission":{"*":"allow"}}' \
|
|
123
|
+
opencode run --pure --format json "$preceding"
|
|
124
|
+
) || status=$?
|
|
125
|
+
[ "$status" -eq 0 ] || fail "OpenCode Ahoy $label setup exited $status: $first_out"
|
|
126
|
+
session_id=$(printf '%s\n' "$first_out" | jq -r 'select(.sessionID != null) | .sessionID' | head -1)
|
|
127
|
+
[ -n "$session_id" ] || fail "OpenCode Ahoy $label setup did not return a session id: $first_out"
|
|
128
|
+
|
|
129
|
+
status=0
|
|
130
|
+
second_out=$(
|
|
131
|
+
cd "$AHOY_PROJECT" &&
|
|
132
|
+
OPENCODE_DB="$db" OPENCODE_DISABLE_AUTOUPDATE=1 OPENCODE_DISABLE_LSP_DOWNLOAD=1 \
|
|
133
|
+
OPENCODE_CONFIG_CONTENT='{"permission":{"*":"allow"}}' \
|
|
134
|
+
opencode run --pure --format json --session "$session_id" "/ahoy"
|
|
135
|
+
) || status=$?
|
|
136
|
+
[ "$status" -eq 0 ] || fail "OpenCode Ahoy $label case exited $status: $second_out"
|
|
137
|
+
assistant_text=$(printf '%s\n' "$second_out" | jq -r 'select(.type == "text") | .part.text' | tail -1)
|
|
138
|
+
case "$expected" in
|
|
139
|
+
bearings)
|
|
140
|
+
printf '%s\n' "$assistant_text" | grep -Fq "AHOY_BEARINGS_BRANCH" \
|
|
141
|
+
|| fail "OpenCode Ahoy $label case did not take Bearings: $second_out"
|
|
142
|
+
;;
|
|
143
|
+
boundary)
|
|
144
|
+
printf '%s\n' "$assistant_text" | grep -Fq "AHOY_BEARINGS_BRANCH" \
|
|
145
|
+
&& fail "OpenCode Ahoy $label near miss was treated as operational: $second_out"
|
|
146
|
+
;;
|
|
147
|
+
esac
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
run_ahoy_transcript_regressions() {
|
|
151
|
+
mkdir -p \
|
|
152
|
+
"$AHOY_PROJECT/.opencode/plugins" \
|
|
153
|
+
"$AHOY_PROJECT/.agents/skills/ahoy" \
|
|
154
|
+
"$AHOY_PROJECT/.agents/skills/bearings" \
|
|
155
|
+
"$AHOY_PROJECT/bin"
|
|
156
|
+
git init -q "$AHOY_PROJECT"
|
|
157
|
+
cp "$ROOT/.opencode/plugins/fm-primary-sessionstart-nudge.js" \
|
|
158
|
+
"$ROOT/.opencode/plugins/package.json" \
|
|
159
|
+
"$AHOY_PROJECT/.opencode/plugins/"
|
|
160
|
+
cp \
|
|
161
|
+
"$ROOT/bin/fm-sessionstart-nudge.sh" \
|
|
162
|
+
"$ROOT/bin/fm-primary-scope-lib.sh" \
|
|
163
|
+
"$ROOT/bin/fm-gate-refuse-lib.sh" \
|
|
164
|
+
"$ROOT/bin/fm-operational-input.sh" \
|
|
165
|
+
"$AHOY_PROJECT/bin/"
|
|
166
|
+
cp "$ROOT/.agents/skills/ahoy/SKILL.md" "$AHOY_PROJECT/.agents/skills/ahoy/SKILL.md"
|
|
167
|
+
chmod +x "$AHOY_PROJECT/bin/fm-sessionstart-nudge.sh"
|
|
168
|
+
# shellcheck disable=SC2016 # Variables expand in the generated script, not this test shell.
|
|
169
|
+
printf '%s\n' \
|
|
170
|
+
'#!/usr/bin/env bash' \
|
|
171
|
+
'set -u' \
|
|
172
|
+
'file="${FM_HOME:?}/state/session-start-count"' \
|
|
173
|
+
'count=0' \
|
|
174
|
+
'[ ! -f "$file" ] || count=$(sed -n "1p" "$file")' \
|
|
175
|
+
'count=$((count + 1))' \
|
|
176
|
+
'printf "%s\n" "$count" > "$file"' \
|
|
177
|
+
'printf "SESSION_START_DONE count=%s\n" "$count"' \
|
|
178
|
+
> "$AHOY_PROJECT/bin/fm-session-start.sh"
|
|
179
|
+
chmod +x "$AHOY_PROJECT/bin/fm-session-start.sh"
|
|
180
|
+
# shellcheck disable=SC2016 # Backticks are literal prompt markup.
|
|
181
|
+
printf '%s\n' \
|
|
182
|
+
'---' \
|
|
183
|
+
'name: bearings' \
|
|
184
|
+
'description: Test-only Bearings branch sentinel.' \
|
|
185
|
+
'---' \
|
|
186
|
+
'' \
|
|
187
|
+
'# bearings' \
|
|
188
|
+
'' \
|
|
189
|
+
'Respond exactly `AHOY_BEARINGS_BRANCH`.' \
|
|
190
|
+
> "$AHOY_PROJECT/.agents/skills/bearings/SKILL.md"
|
|
191
|
+
# shellcheck disable=SC2016 # Backticks are literal prompt markup.
|
|
192
|
+
printf '%s\n' \
|
|
193
|
+
'# Native OpenCode Ahoy regression fixture' \
|
|
194
|
+
'' \
|
|
195
|
+
'Run `bin/fm-session-start.sh` exactly once at session start.' \
|
|
196
|
+
> "$AHOY_PROJECT/AGENTS.md"
|
|
197
|
+
|
|
198
|
+
run_ahoy_case marker-near-miss "$MARKER_NEAR_MISS" boundary
|
|
199
|
+
run_ahoy_case startup-near-miss "$START_NEAR_MISS" boundary
|
|
200
|
+
run_ahoy_case quoted-current "$QUOTED_CURRENT" boundary
|
|
201
|
+
run_ahoy_case ascii-only "$ASCII_ONLY" boundary
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
wait_for_db_count() {
|
|
205
|
+
local db=$1 query=$2 expected=$3 attempts=${4:-180} i=0 actual
|
|
206
|
+
while [ "$i" -lt "$attempts" ]; do
|
|
207
|
+
actual=
|
|
208
|
+
if [ -f "$db" ]; then
|
|
209
|
+
actual=$(sqlite3 "$db" "$query" 2>/dev/null || true)
|
|
210
|
+
fi
|
|
211
|
+
[ "$actual" = "$expected" ] && return 0
|
|
212
|
+
sleep 0.5
|
|
213
|
+
i=$((i + 1))
|
|
214
|
+
done
|
|
215
|
+
return 1
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
run_native_ahoy_regressions() {
|
|
219
|
+
local first_home="$LAB/opencode-ahoy-first-home"
|
|
220
|
+
local later_home="$LAB/opencode-ahoy-later-home"
|
|
221
|
+
local first_db="$LAB/opencode-ahoy-first.db"
|
|
222
|
+
local later_db="$LAB/opencode-ahoy-later.db"
|
|
223
|
+
local native_session=opencode-ahoy-native
|
|
224
|
+
local session_id startup_text assistant_text session_count status
|
|
225
|
+
|
|
226
|
+
mkdir -p \
|
|
227
|
+
"$first_home/state" "$first_home/config" \
|
|
228
|
+
"$later_home/state" "$later_home/config"
|
|
229
|
+
|
|
230
|
+
status=0
|
|
231
|
+
(
|
|
232
|
+
cd "$AHOY_PROJECT" &&
|
|
233
|
+
OPENCODE_DB="$first_db" FM_HOME="$first_home" \
|
|
234
|
+
OPENCODE_DISABLE_AUTOUPDATE=1 OPENCODE_DISABLE_LSP_DOWNLOAD=1 \
|
|
235
|
+
OPENCODE_CONFIG_CONTENT='{"permission":{"*":"allow"}}' \
|
|
236
|
+
opencode run --format json --auto "/ahoy"
|
|
237
|
+
) >/dev/null || status=$?
|
|
238
|
+
[ "$status" -eq 0 ] || fail "OpenCode native first-message Ahoy exited $status"
|
|
239
|
+
session_id=$(sqlite3 "$first_db" 'select id from session order by time_created desc limit 1;')
|
|
240
|
+
startup_text=$(sqlite3 -json "$first_db" \
|
|
241
|
+
"select json_extract(p.data,'$.text') text from message m join part p on p.message_id=m.id where json_extract(m.data,'$.role')='user' and json_extract(p.data,'$.text') like '%FIRSTMATE_OP:%' order by m.time_created limit 1;" \
|
|
242
|
+
| jq -r '.[0].text')
|
|
243
|
+
[ "$startup_text" = "$CURRENT_START" ] \
|
|
244
|
+
|| fail "OpenCode native first-message session stored an unexpected typed startup input: $startup_text"
|
|
245
|
+
assistant_text=$(sqlite3 -json "$first_db" \
|
|
246
|
+
"select json_extract(p.data,'$.text') text from message m join part p on p.message_id=m.id where json_extract(m.data,'$.role')='assistant' and json_extract(p.data,'$.type')='text' order by m.time_created desc limit 1;" \
|
|
247
|
+
| jq -r '.[0].text')
|
|
248
|
+
printf '%s\n' "$assistant_text" | grep -Fq "AHOY_BEARINGS_BRANCH" \
|
|
249
|
+
|| fail "OpenCode native first-message Ahoy did not take Bearings: $assistant_text"
|
|
250
|
+
[ "$(sed -n '1p' "$first_home/state/session-start-count")" = 1 ] \
|
|
251
|
+
|| fail "OpenCode native first-message Ahoy did not preserve one session-start execution"
|
|
252
|
+
session_count=$(sqlite3 "$first_db" 'select count(*) from session;')
|
|
253
|
+
[ "$session_count" = 1 ] || fail "OpenCode native first-message Ahoy left the original session"
|
|
254
|
+
|
|
255
|
+
"$TMUX" -L "$SOCKET" new-session -d -s "$native_session" -c "$AHOY_PROJECT" \
|
|
256
|
+
"env OPENCODE_DB='$later_db' FM_HOME='$later_home' OPENCODE_DISABLE_AUTOUPDATE=1 OPENCODE_DISABLE_LSP_DOWNLOAD=1 OPENCODE_CONFIG_CONTENT='{\"permission\":{\"*\":\"allow\"}}' opencode --auto"
|
|
257
|
+
i=0
|
|
258
|
+
while [ "$i" -lt 120 ]; do
|
|
259
|
+
"$TMUX" -L "$SOCKET" capture-pane -p -t "$native_session" 2>/dev/null | grep -Fq "$OPENCODE_VERSION" && break
|
|
260
|
+
sleep 0.5
|
|
261
|
+
i=$((i + 1))
|
|
262
|
+
done
|
|
263
|
+
[ "$i" -lt 120 ] || fail "OpenCode native later-message session did not reach its TUI"
|
|
264
|
+
"$TMUX" -L "$SOCKET" send-keys -t "$native_session" -l "Respond exactly PRIOR_BOUNDARY_ACK."
|
|
265
|
+
"$TMUX" -L "$SOCKET" send-keys -t "$native_session" Enter
|
|
266
|
+
wait_for_db_count "$later_db" \
|
|
267
|
+
"select count(*) from message m join part p on p.message_id=m.id where json_extract(m.data,'$.role')='assistant' and json_extract(p.data,'$.type')='text' and json_extract(p.data,'$.text') like '%PRIOR_BOUNDARY_ACK%';" \
|
|
268
|
+
1 || fail "OpenCode native later-message setup did not preserve the genuine captain boundary"
|
|
269
|
+
session_id=$(sqlite3 "$later_db" 'select id from session order by time_created desc limit 1;')
|
|
270
|
+
[ "$(sed -n '1p' "$later_home/state/session-start-count")" = 1 ] \
|
|
271
|
+
|| fail "OpenCode native later-message setup did not run session start exactly once"
|
|
272
|
+
"$TMUX" -L "$SOCKET" kill-server
|
|
273
|
+
|
|
274
|
+
status=0
|
|
275
|
+
(
|
|
276
|
+
cd "$AHOY_PROJECT" &&
|
|
277
|
+
OPENCODE_DB="$later_db" FM_HOME="$later_home" \
|
|
278
|
+
OPENCODE_DISABLE_AUTOUPDATE=1 OPENCODE_DISABLE_LSP_DOWNLOAD=1 \
|
|
279
|
+
OPENCODE_CONFIG_CONTENT='{"permission":{"*":"allow"}}' \
|
|
280
|
+
opencode run --format json --auto --session "$session_id" "/ahoy"
|
|
281
|
+
) >/dev/null || status=$?
|
|
282
|
+
[ "$status" -eq 0 ] || fail "OpenCode native later-message Ahoy exited $status"
|
|
283
|
+
assistant_text=$(sqlite3 -json "$later_db" \
|
|
284
|
+
"select json_extract(p.data,'$.text') text from message m join part p on p.message_id=m.id where m.session_id='$session_id' and json_extract(m.data,'$.role')='assistant' and json_extract(p.data,'$.type')='text' order by m.time_created desc limit 1;" \
|
|
285
|
+
| jq -r '.[0].text')
|
|
286
|
+
printf '%s\n' "$assistant_text" | grep -Fq "AHOY_BEARINGS_BRANCH" \
|
|
287
|
+
&& fail "OpenCode native later-message Ahoy gathered Bearings: $assistant_text"
|
|
288
|
+
[ "$(sed -n '1p' "$later_home/state/session-start-count")" = 1 ] \
|
|
289
|
+
|| fail "OpenCode native later-message Ahoy reran session start"
|
|
290
|
+
session_count=$(sqlite3 "$later_db" 'select count(*) from session;')
|
|
291
|
+
[ "$session_count" = 1 ] || fail "OpenCode native later-message Ahoy left the original session"
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
mkdir -p "$LAB"
|
|
295
|
+
run_ahoy_transcript_regressions
|
|
296
|
+
run_native_ahoy_regressions
|
|
297
|
+
git clone -q "$ROOT" "$PROJECT"
|
|
298
|
+
mkdir -p "$PROJECT/.opencode/plugins/lib"
|
|
299
|
+
cp "$ROOT/.opencode/plugins/fm-primary-watch-arm.js" "$PROJECT/.opencode/plugins/fm-primary-watch-arm.js"
|
|
300
|
+
cp "$ROOT/.opencode/plugins/lib/fm-operational-input.js" "$PROJECT/.opencode/plugins/lib/fm-operational-input.js"
|
|
301
|
+
cp "$ROOT/bin/fm-watch-arm.sh" "$PROJECT/bin/fm-watch-arm.sh"
|
|
302
|
+
cp "$ROOT/bin/fm-operational-input.sh" "$PROJECT/bin/fm-operational-input.sh"
|
|
303
|
+
chmod +x "$PROJECT/bin/fm-operational-input.sh"
|
|
304
|
+
mkdir -p "$HOME_DIR/state" "$HOME_DIR/config"
|
|
305
|
+
printf 'project=fixture\n' > "$HOME_DIR/state/opencode-e2e.meta"
|
|
306
|
+
|
|
307
|
+
# shellcheck disable=SC2016 # The model, not this test shell, expands FM_HOME.
|
|
308
|
+
PROMPT='Use the terminal to run `printf ready > "$FM_HOME/state/opencode-model-initial"`, then respond briefly. If a later watcher wake arrives, run bin/fm-wake-drain.sh, then run `printf handled > "$FM_HOME/state/opencode-model-handled"`. Never run or request any watcher arm command.'
|
|
309
|
+
"$TMUX" -L "$SOCKET" new-session -d -s "$SESSION" -c "$PROJECT" \
|
|
310
|
+
"env OPENCODE_CONFIG_CONTENT='{\"permission\":{\"*\":\"allow\"}}' FM_HOME='$HOME_DIR' FM_ROOT_OVERRIDE='$PROJECT' FM_POLL=1 FM_SIGNAL_GRACE=0 FM_HEARTBEAT=600 bash -lc 'printf \"%s\\n\" \"\$\$\" > \"\$FM_HOME/state/.lock\"; opencode --auto; rc=\$?; printf \"OPENCODE_EXIT=%s\\n\" \"\$rc\"; sleep 300'"
|
|
311
|
+
|
|
312
|
+
# Send the initial prompt through the ready composer so this exercises the same
|
|
313
|
+
# persistent TUI path as a primary session.
|
|
314
|
+
wait_for_text "$OPENCODE_VERSION" 120 || fail "OpenCode did not reach its TUI"
|
|
315
|
+
dismiss_update_offer || fail "OpenCode update offer did not dismiss"
|
|
316
|
+
sleep 1
|
|
317
|
+
"$TMUX" -L "$SOCKET" send-keys -t "$SESSION" -l "$PROMPT"
|
|
318
|
+
"$TMUX" -L "$SOCKET" send-keys -t "$SESSION" Enter
|
|
319
|
+
i=0
|
|
320
|
+
while [ "$i" -lt 240 ]; do
|
|
321
|
+
dismiss_update_offer || fail "OpenCode update offer obstructed the initial turn"
|
|
322
|
+
[ -f "$HOME_DIR/state/opencode-model-initial" ] && break
|
|
323
|
+
sleep 0.5
|
|
324
|
+
i=$((i + 1))
|
|
325
|
+
done
|
|
326
|
+
[ -f "$HOME_DIR/state/opencode-model-initial" ] || fail "OpenCode credentialed initial turn did not complete"
|
|
327
|
+
|
|
328
|
+
i=0
|
|
329
|
+
while [ "$i" -lt 120 ]; do
|
|
330
|
+
watcher_pid=$(cat "$HOME_DIR/state/.watch.lock/pid" 2>/dev/null || true)
|
|
331
|
+
[ -n "$watcher_pid" ] && kill -0 "$watcher_pid" 2>/dev/null && break
|
|
332
|
+
sleep 0.5
|
|
333
|
+
i=$((i + 1))
|
|
334
|
+
done
|
|
335
|
+
if [ -z "${watcher_pid:-}" ] || ! kill -0 "$watcher_pid" 2>/dev/null; then
|
|
336
|
+
fail "OpenCode idle event did not start the initial watcher"
|
|
337
|
+
fi
|
|
338
|
+
|
|
339
|
+
printf 'done: opencode live e2e watcher fire\n' > "$HOME_DIR/state/opencode-e2e.status"
|
|
340
|
+
i=0
|
|
341
|
+
while [ "$i" -lt 240 ]; do
|
|
342
|
+
grep -Eq 'reason=actionable-signal.*successor=started:[0-9]+' "$HOME_DIR/state/.watch-cycle-exits.log" 2>/dev/null && break
|
|
343
|
+
sleep 0.5
|
|
344
|
+
i=$((i + 1))
|
|
345
|
+
done
|
|
346
|
+
grep -Eq 'reason=actionable-signal.*successor=started:[0-9]+' "$HOME_DIR/state/.watch-cycle-exits.log" 2>/dev/null \
|
|
347
|
+
|| fail "OpenCode plugin did not start and ledger-link a successor after the actionable close"
|
|
348
|
+
wait_for_handled || fail "OpenCode did not drain and settle after plugin-owned re-arm"
|
|
349
|
+
|
|
350
|
+
pane=$(capture)
|
|
351
|
+
guard_count=$(printf '%s\n' "$pane" | grep -Fc "TURN WOULD END BLIND - supervision is off." || true)
|
|
352
|
+
[ "$guard_count" -eq 0 ] || fail "OpenCode successor was not protecting the next idle event (guard count $guard_count)"
|
|
353
|
+
if printf '%s\n' "$pane" | grep -Fq '$ bin/fm-watch-arm.sh'; then
|
|
354
|
+
fail "OpenCode model attempted to re-arm instead of leaving continuity to the plugin"
|
|
355
|
+
fi
|
|
356
|
+
|
|
357
|
+
printf 'ok - OpenCode %s live E2E covered native Ahoy first/later messages, near misses, and watcher continuity\n' "$OPENCODE_VERSION"
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Canonical current and isolated legacy operational-input protocol matrices.
|
|
3
|
+
set -u
|
|
4
|
+
|
|
5
|
+
# shellcheck source=tests/lib.sh
|
|
6
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
7
|
+
|
|
8
|
+
OWNER="$ROOT/bin/fm-operational-input.sh"
|
|
9
|
+
# shellcheck source=/dev/null
|
|
10
|
+
. "$OWNER"
|
|
11
|
+
|
|
12
|
+
cleanup() {
|
|
13
|
+
fm_test_cleanup
|
|
14
|
+
}
|
|
15
|
+
trap cleanup EXIT
|
|
16
|
+
|
|
17
|
+
classify_cli() {
|
|
18
|
+
printf '%s' "$1" | "$OWNER" classify 2>/dev/null
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
kind_cli() {
|
|
22
|
+
printf '%s' "$1" | "$OWNER" kind 2>/dev/null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test_current_generic_matrix() {
|
|
26
|
+
local kind body encoded parsed stripped prefix_hex
|
|
27
|
+
prefix_hex=$(printf '%s' "$FM_OPERATIONAL_PREFIX" | od -An -tx1 | tr -d ' \n')
|
|
28
|
+
[ "$prefix_hex" = e281a346495253544d4154455f4f503a20 ] \
|
|
29
|
+
|| fail "current operational prefix lost the landed U+2063 FIRSTMATE_OP bytes: $prefix_hex"
|
|
30
|
+
|
|
31
|
+
for kind in session-start watcher turn-end-guard away-supervisor launch-brief branch-outcome; do
|
|
32
|
+
body="CURRENT_BODY_FOR_${kind}"
|
|
33
|
+
fm_operational_input_encode "$kind" "$body" encoded \
|
|
34
|
+
|| fail "could not encode current $kind fixture"
|
|
35
|
+
fm_operational_input_kind "$encoded" parsed \
|
|
36
|
+
|| fail "could not parse current $kind fixture"
|
|
37
|
+
[ "$parsed" = "$kind" ] \
|
|
38
|
+
|| fail "current $kind fixture became $parsed"
|
|
39
|
+
[ "$(kind_cli "$encoded")" = "$kind" ] \
|
|
40
|
+
|| fail "cross-language CLI lost current $kind"
|
|
41
|
+
[ "$(classify_cli "$encoded")" = "$kind" ] \
|
|
42
|
+
|| fail "classifier lost current $kind"
|
|
43
|
+
fm_operational_input_body "$encoded" stripped \
|
|
44
|
+
|| fail "could not recover current $kind body"
|
|
45
|
+
[ "$stripped" = "$body" ] \
|
|
46
|
+
|| fail "current $kind body changed during encode/parse"
|
|
47
|
+
done
|
|
48
|
+
pass "operational input: every current generic envelope retains its exact structured kind"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
test_current_from_firstmate_carrier() {
|
|
52
|
+
local encoded parsed separator
|
|
53
|
+
separator=$(printf '\342\201\243')
|
|
54
|
+
fm_message_mark_from_firstmate "corr=0123456789abcdef inspect the report" encoded
|
|
55
|
+
[ "${encoded#"[fm-from-firstmate]$separator"}" != "$encoded" ] \
|
|
56
|
+
|| fail "from-firstmate lost its live-charter-compatible leading carrier"
|
|
57
|
+
fm_operational_input_kind "$encoded" parsed \
|
|
58
|
+
|| fail "from-firstmate current carrier did not parse"
|
|
59
|
+
[ "$parsed" = from-firstmate ] \
|
|
60
|
+
|| fail "from-firstmate current carrier became $parsed"
|
|
61
|
+
[ "$(classify_cli "$encoded")" = from-firstmate ] \
|
|
62
|
+
|| fail "cross-language classifier lost from-firstmate"
|
|
63
|
+
pass "operational input: the established from-firstmate carrier remains structurally typed and byte-compatible"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
test_landed_untyped_prefix_is_explicitly_legacy() {
|
|
67
|
+
local untyped parsed
|
|
68
|
+
untyped="${FM_OPERATIONAL_PREFIX}body whose historical subtype is unknowable"
|
|
69
|
+
fm_legacy_operational_input_kind "$untyped" parsed \
|
|
70
|
+
|| fail "landed untyped FIRSTMATE_OP input was not retained"
|
|
71
|
+
[ "$parsed" = legacy-operational ] \
|
|
72
|
+
|| fail "landed untyped FIRSTMATE_OP input falsely became $parsed"
|
|
73
|
+
! fm_operational_input_kind "$untyped" parsed \
|
|
74
|
+
|| fail "untyped FIRSTMATE_OP input passed the current typed parser"
|
|
75
|
+
[ "$(classify_cli "$untyped")" = legacy-operational ] \
|
|
76
|
+
|| fail "CLI did not expose the untyped prefix as legacy-operational"
|
|
77
|
+
pass "operational input: untyped landed FIRSTMATE_OP transcripts are explicit legacy-operational input"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
test_isolated_legacy_matrix() {
|
|
81
|
+
local watcher turnend away parsed
|
|
82
|
+
watcher="${FM_LEGACY_WATCHER_PREFIX}signal: legacy${FM_LEGACY_WATCHER_SUFFIX}"
|
|
83
|
+
turnend="${FM_LEGACY_TURNEND_PREFIX}watcher: FAILED - legacy"
|
|
84
|
+
away="${FM_LEGACY_AWAY_PREFIX}1 event(s)): done: legacy"
|
|
85
|
+
|
|
86
|
+
for fixture in \
|
|
87
|
+
"session-start|$FM_LEGACY_SESSIONSTART" \
|
|
88
|
+
"watcher|$watcher" \
|
|
89
|
+
"turn-end-guard|$turnend" \
|
|
90
|
+
"away-supervisor|$away"
|
|
91
|
+
do
|
|
92
|
+
expected=${fixture%%|*}
|
|
93
|
+
message=${fixture#*|}
|
|
94
|
+
! fm_operational_input_kind "$message" parsed \
|
|
95
|
+
|| fail "legacy $expected fixture leaked into the current parser"
|
|
96
|
+
fm_legacy_operational_input_kind "$message" parsed \
|
|
97
|
+
|| fail "legacy $expected fixture was not recognized"
|
|
98
|
+
[ "$parsed" = "$expected" ] \
|
|
99
|
+
|| fail "legacy $expected fixture became $parsed"
|
|
100
|
+
done
|
|
101
|
+
pass "operational input: historical prose compatibility is isolated from current parsing"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
test_genuine_near_misses_remain_unclassified() {
|
|
105
|
+
local marker fixture parsed
|
|
106
|
+
marker=$FM_OPERATIONAL_MARK
|
|
107
|
+
while IFS= read -r fixture || [ -n "$fixture" ]; do
|
|
108
|
+
[ -n "$fixture" ] || continue
|
|
109
|
+
! fm_operational_input_classify "$fixture" parsed \
|
|
110
|
+
|| fail "genuine near miss was classified as $parsed: $fixture"
|
|
111
|
+
[ -z "$(classify_cli "$fixture" || true)" ] \
|
|
112
|
+
|| fail "CLI classified a genuine near miss: $fixture"
|
|
113
|
+
done <<EOF
|
|
114
|
+
Captain quote: ${FM_OPERATIONAL_PREFIX}v1 watcher
|
|
115
|
+
FIRSTMATE_OP: v1 watcher
|
|
116
|
+
$marker arbitrary captain text
|
|
117
|
+
Captain quote: $FM_LEGACY_SESSIONSTART
|
|
118
|
+
${FM_LEGACY_SESSIONSTART} Please explain this sentence.
|
|
119
|
+
FIRSTMATE WATCHER WAKE: can you explain this phrase?
|
|
120
|
+
TURN WOULD END BLIND - can you make this warning friendlier?
|
|
121
|
+
Supervisor escalate (1 event(s)): is this wording clear?
|
|
122
|
+
[fm-from-firstmate] inspect this visible label
|
|
123
|
+
EOF
|
|
124
|
+
pass "operational input: quoted, ASCII-only, arbitrary-U+2063, altered-legacy, and label-only near misses stay genuine"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
test_cross_language_adapter_uses_the_owner() {
|
|
128
|
+
local encoded parsed
|
|
129
|
+
encoded=$(FM_TEST_ROOT="$ROOT" HELPER="$ROOT/.opencode/plugins/lib/fm-operational-input.js" \
|
|
130
|
+
node --input-type=module <<'JS'
|
|
131
|
+
import { pathToFileURL } from "node:url";
|
|
132
|
+
const { encodeFirstmateOperationalInput } = await import(pathToFileURL(process.env.HELPER).href);
|
|
133
|
+
process.stdout.write(await encodeFirstmateOperationalInput(process.env.FM_TEST_ROOT, "watcher", "CROSS_LANGUAGE_BODY"));
|
|
134
|
+
JS
|
|
135
|
+
) || fail "OpenCode cross-language adapter could not invoke the canonical owner"
|
|
136
|
+
fm_operational_input_kind "$encoded" parsed \
|
|
137
|
+
|| fail "OpenCode cross-language adapter returned an invalid current envelope"
|
|
138
|
+
[ "$parsed" = watcher ] \
|
|
139
|
+
|| fail "OpenCode cross-language adapter changed watcher to $parsed"
|
|
140
|
+
pass "operational input: the OpenCode adapter constructs through the canonical owner"
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
test_invalid_current_encodings_are_rejected() {
|
|
144
|
+
local output
|
|
145
|
+
output=$(printf 'body' | "$OWNER" encode legacy-operational 2>/dev/null) \
|
|
146
|
+
&& fail "legacy-operational was accepted as a current producer kind"
|
|
147
|
+
[ -z "$output" ] || fail "invalid current kind printed protocol data"
|
|
148
|
+
output=$(printf '' | "$OWNER" encode watcher 2>/dev/null) \
|
|
149
|
+
&& fail "empty current operational body was accepted"
|
|
150
|
+
[ -z "$output" ] || fail "empty current body printed protocol data"
|
|
151
|
+
pass "operational input: current construction rejects legacy kinds and empty bodies"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
test_current_generic_matrix
|
|
155
|
+
test_current_from_firstmate_carrier
|
|
156
|
+
test_landed_untyped_prefix_is_explicitly_legacy
|
|
157
|
+
test_isolated_legacy_matrix
|
|
158
|
+
test_genuine_near_misses_remain_unclassified
|
|
159
|
+
test_cross_language_adapter_uses_the_owner
|
|
160
|
+
test_invalid_current_encodings_are_rejected
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fm-peek remote-secondmate capture routing.
|
|
3
|
+
#
|
|
4
|
+
# A remote secondmate's pane lives on its own host. The old path resolved the
|
|
5
|
+
# meta's "remote:<id>" window through the local backend adapters and handed it
|
|
6
|
+
# to tmux, which failed with "can't find session: remote" - a healthy remote
|
|
7
|
+
# mate misreported as an unreadable endpoint. These tests drive the real
|
|
8
|
+
# fm-peek + fm-on executables with a stubbed ssh transport (FM_SSH_BIN seam)
|
|
9
|
+
# and a poisoned local tmux, pinning:
|
|
10
|
+
# 1. A remote selector routes the capture over the remote transport and
|
|
11
|
+
# prints the remote pane tail; the local adapters are never consulted.
|
|
12
|
+
# 2. An unreachable host fails loudly naming the host, without claiming the
|
|
13
|
+
# mate is dead.
|
|
14
|
+
set -u
|
|
15
|
+
|
|
16
|
+
# shellcheck source=tests/lib.sh
|
|
17
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
18
|
+
|
|
19
|
+
PEEK="$ROOT/bin/fm-peek.sh"
|
|
20
|
+
|
|
21
|
+
TMP_ROOT=$(fm_test_tmproot fm-peek-remote)
|
|
22
|
+
|
|
23
|
+
# fake-ssh prints the canned remote capture; the poisoned tmux records any
|
|
24
|
+
# local read attempt so the "never consulted" property is a real assertion.
|
|
25
|
+
make_stubs() { # <dir> -> echoes fakebin dir
|
|
26
|
+
local dir=$1 fb="$1/fakebin"
|
|
27
|
+
mkdir -p "$fb"
|
|
28
|
+
cat > "$fb/fake-ssh" <<'SH'
|
|
29
|
+
#!/usr/bin/env bash
|
|
30
|
+
cat > /dev/null
|
|
31
|
+
[ -z "${FM_FAKE_REMOTE_CAPTURE:-}" ] || printf '%s\n' "$FM_FAKE_REMOTE_CAPTURE"
|
|
32
|
+
exit "${FM_FAKE_SSH_RC:-0}"
|
|
33
|
+
SH
|
|
34
|
+
chmod +x "$fb/fake-ssh"
|
|
35
|
+
cat > "$fb/tmux" <<'SH'
|
|
36
|
+
#!/usr/bin/env bash
|
|
37
|
+
printf 'tmux\n' >> "${FM_FAKE_TMUX_TOUCHED:?}"
|
|
38
|
+
exit 1
|
|
39
|
+
SH
|
|
40
|
+
chmod +x "$fb/tmux"
|
|
41
|
+
printf '%s\n' "$fb"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setup_remote_home() { # <name> -> echoes home dir with remote meta + registry
|
|
45
|
+
local home="$TMP_ROOT/$1-$RANDOM"
|
|
46
|
+
mkdir -p "$home/state" "$home/data"
|
|
47
|
+
fm_write_meta "$home/state/rsm.meta" \
|
|
48
|
+
"window=remote:rsm" \
|
|
49
|
+
"endpoint_task_id=rsm" \
|
|
50
|
+
"harness=claude" \
|
|
51
|
+
"kind=secondmate" \
|
|
52
|
+
"mode=secondmate" \
|
|
53
|
+
"remote_host=remote-mac" \
|
|
54
|
+
"remote_root=/remote/root" \
|
|
55
|
+
"remote_backend=herdr" \
|
|
56
|
+
"remote_herdr_session=fm-remote" \
|
|
57
|
+
"remote_target=fm-remote:w1:p1"
|
|
58
|
+
cat > "$home/data/secondmates.md" <<EOF
|
|
59
|
+
- rsm - remote test domain (host: remote-mac; root: /remote/root; home: /remote/home; scope: remote testing; projects: alpha; added 2026-08-02)
|
|
60
|
+
EOF
|
|
61
|
+
printf '%s\n' "$home"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
test_remote_peek_reads_remote_pane() {
|
|
65
|
+
local dir fb home touched rc out
|
|
66
|
+
dir="$TMP_ROOT/peek-ok"; mkdir -p "$dir"
|
|
67
|
+
fb=$(make_stubs "$dir")
|
|
68
|
+
home=$(setup_remote_home peek-ok)
|
|
69
|
+
touched="$dir/tmux-touched"; : > "$touched"
|
|
70
|
+
|
|
71
|
+
out=$(env PATH="$fb:$PATH" \
|
|
72
|
+
FM_HOME="$home" FM_STATE_OVERRIDE="$home/state" \
|
|
73
|
+
FM_SSH_BIN="$fb/fake-ssh" FM_FAKE_SSH_RC=0 \
|
|
74
|
+
FM_FAKE_REMOTE_CAPTURE='● the remote mate is mid-refactor' \
|
|
75
|
+
FM_FAKE_TMUX_TOUCHED="$touched" \
|
|
76
|
+
"$PEEK" rsm 20 2>"$dir/err"); rc=$?
|
|
77
|
+
expect_code 0 "$rc" "a healthy remote peek should succeed"
|
|
78
|
+
assert_contains "$out" "the remote mate is mid-refactor" \
|
|
79
|
+
"the remote pane tail should be printed"
|
|
80
|
+
assert_not_contains "$out" "can't find session" \
|
|
81
|
+
"a remote peek must not fall into a local session lookup"
|
|
82
|
+
[ ! -s "$touched" ] || fail "the local tmux adapter was consulted for a remote target"
|
|
83
|
+
pass "fm-peek remote: the capture routes over the remote transport, local adapters untouched"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
test_remote_peek_unreachable_fails_loudly_without_death_claim() {
|
|
87
|
+
local dir fb home touched rc err
|
|
88
|
+
dir="$TMP_ROOT/peek-down"; mkdir -p "$dir"
|
|
89
|
+
fb=$(make_stubs "$dir")
|
|
90
|
+
home=$(setup_remote_home peek-down)
|
|
91
|
+
touched="$dir/tmux-touched"; : > "$touched"
|
|
92
|
+
|
|
93
|
+
env PATH="$fb:$PATH" \
|
|
94
|
+
FM_HOME="$home" FM_STATE_OVERRIDE="$home/state" \
|
|
95
|
+
FM_SSH_BIN="$fb/fake-ssh" FM_FAKE_SSH_RC=255 \
|
|
96
|
+
FM_FAKE_TMUX_TOUCHED="$touched" \
|
|
97
|
+
"$PEEK" rsm >"$dir/out" 2>"$dir/err"; rc=$?
|
|
98
|
+
err=$(cat "$dir/err")
|
|
99
|
+
[ "$rc" -ne 0 ] || fail "an unreachable remote peek must exit nonzero"
|
|
100
|
+
assert_contains "$err" "remote pane of rsm on remote-mac" \
|
|
101
|
+
"the failure must name the remote mate and host"
|
|
102
|
+
assert_contains "$err" "not thereby dead" \
|
|
103
|
+
"an unreadable remote pane must not be presented as a dead mate"
|
|
104
|
+
pass "fm-peek remote: an unreachable host fails loudly without a false death claim"
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
test_remote_peek_reads_remote_pane
|
|
108
|
+
test_remote_peek_unreachable_fails_loudly_without_death_claim
|
|
109
|
+
|
|
110
|
+
echo "all fm-peek-remote tests passed"
|