@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,827 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavior tests for fm-spawn.sh concrete dispatch profile flags.
|
|
3
|
+
#
|
|
4
|
+
# These tests drive fm-spawn through meta writing and launch construction with a
|
|
5
|
+
# fake tmux pane and a real isolated git worktree. The fake tmux captures the
|
|
6
|
+
# literal launch command sent with `tmux send-keys -l`, so assertions pin the
|
|
7
|
+
# command firstmate would run without starting any real harness.
|
|
8
|
+
set -u
|
|
9
|
+
|
|
10
|
+
# shellcheck source=tests/fixtures.sh
|
|
11
|
+
. "$(dirname "${BASH_SOURCE[0]}")/fixtures.sh"
|
|
12
|
+
|
|
13
|
+
SPAWN="$ROOT/bin/fm-spawn.sh"
|
|
14
|
+
TMP_ROOT=$(fm_test_tmproot fm-spawn-dispatch-profile)
|
|
15
|
+
|
|
16
|
+
make_spawn_pi_probe() {
|
|
17
|
+
local fakebin=$1 tool=$2
|
|
18
|
+
cat > "$fakebin/$tool" <<'SH'
|
|
19
|
+
#!/usr/bin/env bash
|
|
20
|
+
set -u
|
|
21
|
+
if [ "${1:-}" = --help ]; then
|
|
22
|
+
if [ "${FM_FAKE_PI_VERSION:-0.84.0}" = 0.82.0 ]; then
|
|
23
|
+
printf '%s\n' 'Pi 0.82.0' 'Options: --help'
|
|
24
|
+
else
|
|
25
|
+
printf '%s\n' "Pi ${FM_FAKE_PI_VERSION:-0.84.0}" 'Options: --help --tui-mode <mode>'
|
|
26
|
+
fi
|
|
27
|
+
fi
|
|
28
|
+
exit 0
|
|
29
|
+
SH
|
|
30
|
+
chmod +x "$fakebin/$tool"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
make_spawn_fakebin() {
|
|
34
|
+
local dir=$1 fakebin
|
|
35
|
+
fakebin=$(fm_test_make_spawn_fakebin "$dir")
|
|
36
|
+
cat > "$fakebin/timeout" <<'SH'
|
|
37
|
+
#!/usr/bin/env bash
|
|
38
|
+
shift
|
|
39
|
+
exec "$@"
|
|
40
|
+
SH
|
|
41
|
+
cat > "$fakebin/cursor-agent" <<'SH'
|
|
42
|
+
#!/usr/bin/env bash
|
|
43
|
+
if [ "${1:-}" = --list-models ]; then
|
|
44
|
+
[ "${FM_FAKE_CURSOR_LIST_STATUS:-0}" -eq 0 ] || exit "${FM_FAKE_CURSOR_LIST_STATUS}"
|
|
45
|
+
printf '%b\n' "${FM_FAKE_CURSOR_MODELS:-Available models\ncursor-grok-4.5-high - Grok 4.5 High}"
|
|
46
|
+
fi
|
|
47
|
+
exit 0
|
|
48
|
+
SH
|
|
49
|
+
chmod +x "$fakebin/timeout" "$fakebin/cursor-agent"
|
|
50
|
+
make_spawn_pi_probe "$fakebin" pi
|
|
51
|
+
make_spawn_pi_probe "$fakebin" pi-signed
|
|
52
|
+
printf '%s\n' "$fakebin"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
make_spawn_case() {
|
|
56
|
+
local name=$1 harness=$2 case_dir home proj wt fakebin launchlog id
|
|
57
|
+
shift 2
|
|
58
|
+
case_dir="$TMP_ROOT/$name"
|
|
59
|
+
home="$case_dir/home"
|
|
60
|
+
proj="$case_dir/project"
|
|
61
|
+
wt="$case_dir/wt"
|
|
62
|
+
launchlog="$case_dir/launch.log"
|
|
63
|
+
fakebin=$(make_spawn_fakebin "$case_dir/fake")
|
|
64
|
+
fm_test_spawn_home "$home" "$harness"
|
|
65
|
+
fm_git_worktree "$proj" "$wt" "wt-$name"
|
|
66
|
+
for id in "$@"; do
|
|
67
|
+
fm_test_spawn_brief "$home" "$id"
|
|
68
|
+
done
|
|
69
|
+
printf '%s\n' "$case_dir|$home|$proj|$wt|$fakebin|$launchlog"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
enable_dispatch_profile() {
|
|
73
|
+
local home=$1
|
|
74
|
+
printf '%s\n' '{"rules":[{"when":"current events","use":{"harness":"grok","model":"grok-4","effort":"high"}}],"default":{"harness":"codex","model":"gpt-5","effort":"medium"}}' \
|
|
75
|
+
> "$home/config/crew-dispatch.json"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
make_seeded_secondmate_home() {
|
|
79
|
+
local home=$1 id=$2
|
|
80
|
+
mkdir -p "$home/bin" "$home/data"
|
|
81
|
+
printf '# Firstmate\n' > "$home/AGENTS.md"
|
|
82
|
+
printf '%s\n' "$id" > "$home/.fm-secondmate-home"
|
|
83
|
+
printf 'charter for %s\n' "$id" > "$home/data/charter.md"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
run_spawn() {
|
|
87
|
+
local home=$1 wt=$2 fakebin=$3 launchlog=$4
|
|
88
|
+
shift 4
|
|
89
|
+
: > "$launchlog"
|
|
90
|
+
# CLAUDE_CONFIG_DIR is forwarded onto claude launches by fm-spawn, so pin it
|
|
91
|
+
# explicitly (empty by default) instead of leaking the invoking shell's value,
|
|
92
|
+
# which would make launch assertions depend on the developer's environment.
|
|
93
|
+
# A test opts in to the set case via FM_TEST_CLAUDE_CONFIG_DIR.
|
|
94
|
+
CLAUDE_CONFIG_DIR="${FM_TEST_CLAUDE_CONFIG_DIR:-}" \
|
|
95
|
+
FM_FAKE_LAUNCH_LOG="$launchlog" FM_FAKE_PI_VERSION="${FM_TEST_PI_VERSION:-0.84.0}" \
|
|
96
|
+
FM_FAKE_CURSOR_MODELS="${FM_TEST_CURSOR_MODELS:-}" \
|
|
97
|
+
FM_FAKE_CURSOR_LIST_STATUS="${FM_TEST_CURSOR_LIST_STATUS:-0}" \
|
|
98
|
+
GROK_HOME="$home/grok-home" \
|
|
99
|
+
fm_test_run_spawn "$home" "$wt" "$fakebin" "$@"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# Ship spawns carry an explicit delivery contract (AGENTS.md section 7); these
|
|
103
|
+
# tests are about profile resolution, so they pass a fixed valid one.
|
|
104
|
+
run_ship_spawn() {
|
|
105
|
+
run_spawn "$@" --mode no-mistakes --yolo off
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
read_case_record() {
|
|
109
|
+
IFS='|' read -r CASE_DIR HOME_DIR PROJ_DIR WT_DIR FAKEBIN_DIR LAUNCH_LOG <<EOF
|
|
110
|
+
$1
|
|
111
|
+
EOF
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
assert_meta_profile() {
|
|
115
|
+
local meta=$1 harness=$2 model=$3 effort=$4
|
|
116
|
+
assert_grep "harness=$harness" "$meta" "meta missing harness=$harness"
|
|
117
|
+
assert_grep "model=$model" "$meta" "meta missing model=$model"
|
|
118
|
+
assert_grep "effort=$effort" "$meta" "meta missing effort=$effort"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
test_no_profile_keeps_claude_profile_defaults() {
|
|
122
|
+
local rec id out status expected launch
|
|
123
|
+
id=profile-off-z1
|
|
124
|
+
rec=$(make_spawn_case profile-off claude "$id")
|
|
125
|
+
read_case_record "$rec"
|
|
126
|
+
|
|
127
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR")
|
|
128
|
+
status=$?
|
|
129
|
+
expect_code 0 "$status" "claude spawn without profile flags should succeed"
|
|
130
|
+
assert_contains "$out" "spawned $id harness=claude" "spawn did not report claude"
|
|
131
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" claude default default
|
|
132
|
+
|
|
133
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
134
|
+
expected="env -u CURSOR_AGENT -u CURSOR_INVOKED_AS CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false claude --dangerously-skip-permissions \"\$('${ROOT}/bin/fm-operational-input.sh' encode launch-brief < '$HOME_DIR/data/$id/brief.md')\""
|
|
135
|
+
[ "$launch" = "$expected" ] || fail "no-profile claude launch did not use the canonical launch kind"$'\n'"expected: $expected"$'\n'"actual: $launch"
|
|
136
|
+
pass "no --model/--effort records defaults and types the claude launch instructions"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
test_non_cursor_launch_clears_inherited_cursor_markers() {
|
|
140
|
+
local rec id out status launch
|
|
141
|
+
id=profile-claude-cursor-markers-z1b
|
|
142
|
+
rec=$(make_spawn_case profile-claude-cursor-markers claude "$id")
|
|
143
|
+
read_case_record "$rec"
|
|
144
|
+
|
|
145
|
+
out=$(CURSOR_AGENT=1 CURSOR_INVOKED_AS=cursor-agent \
|
|
146
|
+
run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR")
|
|
147
|
+
status=$?
|
|
148
|
+
expect_code 0 "$status" "claude spawn under Cursor markers should succeed"
|
|
149
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
150
|
+
assert_contains "$launch" "env -u CURSOR_AGENT -u CURSOR_INVOKED_AS" \
|
|
151
|
+
"non-cursor launch must clear both inherited Cursor identity markers"
|
|
152
|
+
pass "non-cursor launches clear inherited Cursor identity markers"
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
test_relative_home_overrides_launch_with_absolute_cross_process_paths() {
|
|
156
|
+
local rec id out status launch home_real
|
|
157
|
+
id=profile-relative-paths-z1b
|
|
158
|
+
rec=$(make_spawn_case profile-relative-paths pi "$id")
|
|
159
|
+
read_case_record "$rec"
|
|
160
|
+
home_real=$(cd "$HOME_DIR" && pwd -P)
|
|
161
|
+
mkdir -p "$CASE_DIR/cdpath/home/state" "$CASE_DIR/cdpath/home/data"
|
|
162
|
+
: > "$LAUNCH_LOG"
|
|
163
|
+
|
|
164
|
+
out=$(
|
|
165
|
+
cd "$CASE_DIR" || exit 1
|
|
166
|
+
CDPATH="$CASE_DIR/cdpath" FM_ROOT_OVERRIDE='' FM_HOME=home \
|
|
167
|
+
FM_STATE_OVERRIDE=home/state FM_DATA_OVERRIDE=home/data \
|
|
168
|
+
FM_PROJECTS_OVERRIDE=home/projects FM_CONFIG_OVERRIDE=home/config \
|
|
169
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$WT_DIR" TMUX="fake,1,0" \
|
|
170
|
+
CLAUDE_CONFIG_DIR='' FM_FAKE_LAUNCH_LOG="$LAUNCH_LOG" \
|
|
171
|
+
GROK_HOME=home/grok-home PATH="$FAKEBIN_DIR:$PATH" \
|
|
172
|
+
"$SPAWN" "$id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1
|
|
173
|
+
)
|
|
174
|
+
status=$?
|
|
175
|
+
expect_code 0 "$status" "spawn with relative home overrides should succeed"
|
|
176
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
177
|
+
assert_contains "$launch" "-e '$home_real/state/$id.pi-ext.ts'" \
|
|
178
|
+
"relative FM_STATE_OVERRIDE leaked into Pi's cross-process extension path"
|
|
179
|
+
assert_contains "$launch" "< '$home_real/data/$id/brief.md'" \
|
|
180
|
+
"relative FM_DATA_OVERRIDE leaked into the cross-process brief path"
|
|
181
|
+
pass "relative home overrides ignore CDPATH and become absolute before spawn launch construction"
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
test_home_defaults_preserve_absolute_or_resolve_relative_paths() {
|
|
185
|
+
local rec relative_id absolute_id out status launch home_real linked_home
|
|
186
|
+
relative_id=profile-relative-home-defaults-z1c
|
|
187
|
+
absolute_id=profile-absolute-home-defaults-z1d
|
|
188
|
+
rec=$(make_spawn_case profile-home-defaults pi "$relative_id" "$absolute_id")
|
|
189
|
+
read_case_record "$rec"
|
|
190
|
+
home_real=$(cd "$HOME_DIR" && pwd -P)
|
|
191
|
+
|
|
192
|
+
: > "$LAUNCH_LOG"
|
|
193
|
+
out=$(
|
|
194
|
+
cd "$CASE_DIR" || exit 1
|
|
195
|
+
FM_ROOT_OVERRIDE='' FM_HOME=home \
|
|
196
|
+
FM_STATE_OVERRIDE='' FM_DATA_OVERRIDE='' \
|
|
197
|
+
FM_PROJECTS_OVERRIDE=home/projects FM_CONFIG_OVERRIDE=home/config \
|
|
198
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$WT_DIR" TMUX="fake,1,0" \
|
|
199
|
+
CLAUDE_CONFIG_DIR='' FM_FAKE_LAUNCH_LOG="$LAUNCH_LOG" \
|
|
200
|
+
GROK_HOME=home/grok-home PATH="$FAKEBIN_DIR:$PATH" \
|
|
201
|
+
"$SPAWN" "$relative_id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1
|
|
202
|
+
)
|
|
203
|
+
status=$?
|
|
204
|
+
expect_code 0 "$status" "spawn with relative FM_HOME defaults should succeed"
|
|
205
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
206
|
+
assert_contains "$launch" "-e '$home_real/state/$relative_id.pi-ext.ts'" \
|
|
207
|
+
"relative FM_HOME leaked into Pi's default cross-process extension path"
|
|
208
|
+
assert_contains "$launch" "< '$home_real/data/$relative_id/brief.md'" \
|
|
209
|
+
"relative FM_HOME leaked into the default cross-process brief path"
|
|
210
|
+
|
|
211
|
+
linked_home="$CASE_DIR/home-link"
|
|
212
|
+
ln -s "$HOME_DIR" "$linked_home"
|
|
213
|
+
: > "$LAUNCH_LOG"
|
|
214
|
+
out=$(
|
|
215
|
+
FM_ROOT_OVERRIDE='' FM_HOME="$linked_home" \
|
|
216
|
+
FM_STATE_OVERRIDE='' FM_DATA_OVERRIDE='' \
|
|
217
|
+
FM_PROJECTS_OVERRIDE="$linked_home/projects" FM_CONFIG_OVERRIDE="$linked_home/config" \
|
|
218
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$WT_DIR" TMUX="fake,1,0" \
|
|
219
|
+
CLAUDE_CONFIG_DIR='' FM_FAKE_LAUNCH_LOG="$LAUNCH_LOG" \
|
|
220
|
+
GROK_HOME="$linked_home/grok-home" PATH="$FAKEBIN_DIR:$PATH" \
|
|
221
|
+
"$SPAWN" "$absolute_id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1
|
|
222
|
+
)
|
|
223
|
+
status=$?
|
|
224
|
+
expect_code 0 "$status" "spawn with absolute symlink-spelled FM_HOME defaults should succeed"
|
|
225
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
226
|
+
assert_contains "$launch" "-e '$linked_home/state/$absolute_id.pi-ext.ts'" \
|
|
227
|
+
"absolute FM_HOME spelling changed in Pi's default cross-process extension path"
|
|
228
|
+
assert_contains "$launch" "< '$linked_home/data/$absolute_id/brief.md'" \
|
|
229
|
+
"absolute FM_HOME spelling changed in the default cross-process brief path"
|
|
230
|
+
pass "FM_HOME defaults resolve relative paths and preserve absolute spellings"
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
test_absolute_override_spelling_is_preserved_in_launch_paths() {
|
|
234
|
+
local rec id out status launch linked_home
|
|
235
|
+
id=profile-absolute-paths-z1c
|
|
236
|
+
rec=$(make_spawn_case profile-absolute-paths pi "$id")
|
|
237
|
+
read_case_record "$rec"
|
|
238
|
+
linked_home="$CASE_DIR/home-link"
|
|
239
|
+
ln -s "$HOME_DIR" "$linked_home"
|
|
240
|
+
: > "$LAUNCH_LOG"
|
|
241
|
+
|
|
242
|
+
out=$(
|
|
243
|
+
FM_ROOT_OVERRIDE='' FM_HOME="$linked_home" \
|
|
244
|
+
FM_STATE_OVERRIDE="$linked_home/state" FM_DATA_OVERRIDE="$linked_home/data" \
|
|
245
|
+
FM_PROJECTS_OVERRIDE="$linked_home/projects" FM_CONFIG_OVERRIDE="$linked_home/config" \
|
|
246
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$WT_DIR" TMUX="fake,1,0" \
|
|
247
|
+
CLAUDE_CONFIG_DIR='' FM_FAKE_LAUNCH_LOG="$LAUNCH_LOG" \
|
|
248
|
+
GROK_HOME="$linked_home/grok-home" PATH="$FAKEBIN_DIR:$PATH" \
|
|
249
|
+
"$SPAWN" "$id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1
|
|
250
|
+
)
|
|
251
|
+
status=$?
|
|
252
|
+
expect_code 0 "$status" "spawn with absolute symlink-spelled overrides should succeed"
|
|
253
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
254
|
+
assert_contains "$launch" "-e '$linked_home/state/$id.pi-ext.ts'" \
|
|
255
|
+
"absolute FM_STATE_OVERRIDE spelling changed in Pi's cross-process extension path"
|
|
256
|
+
assert_contains "$launch" "< '$linked_home/data/$id/brief.md'" \
|
|
257
|
+
"absolute FM_DATA_OVERRIDE spelling changed in the cross-process brief path"
|
|
258
|
+
pass "absolute override spellings are preserved in spawn launch paths"
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
test_unresolvable_relative_overrides_fail_loudly() {
|
|
262
|
+
local rec id out status
|
|
263
|
+
id=profile-unresolvable-paths-z1d
|
|
264
|
+
rec=$(make_spawn_case profile-unresolvable-paths pi "$id")
|
|
265
|
+
read_case_record "$rec"
|
|
266
|
+
|
|
267
|
+
out=$(
|
|
268
|
+
cd "$CASE_DIR" || exit 1
|
|
269
|
+
FM_ROOT_OVERRIDE='' FM_HOME=missing-home \
|
|
270
|
+
FM_STATE_OVERRIDE='' FM_DATA_OVERRIDE='' \
|
|
271
|
+
"$SPAWN" "$id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1
|
|
272
|
+
)
|
|
273
|
+
status=$?
|
|
274
|
+
expect_code 1 "$status" "spawn with an unresolvable relative home should fail"
|
|
275
|
+
assert_contains "$out" "FM_HOME directory cannot be resolved: missing-home" \
|
|
276
|
+
"spawn did not name the unresolvable FM_HOME"
|
|
277
|
+
|
|
278
|
+
out=$(
|
|
279
|
+
cd "$CASE_DIR" || exit 1
|
|
280
|
+
FM_ROOT_OVERRIDE='' FM_HOME=home \
|
|
281
|
+
FM_STATE_OVERRIDE=missing-state FM_DATA_OVERRIDE=home/data \
|
|
282
|
+
"$SPAWN" "$id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1
|
|
283
|
+
)
|
|
284
|
+
status=$?
|
|
285
|
+
expect_code 1 "$status" "spawn with an unresolvable relative state override should fail"
|
|
286
|
+
assert_contains "$out" "FM_STATE_OVERRIDE directory cannot be resolved: missing-state" \
|
|
287
|
+
"spawn did not name the unresolvable FM_STATE_OVERRIDE"
|
|
288
|
+
|
|
289
|
+
out=$(
|
|
290
|
+
cd "$CASE_DIR" || exit 1
|
|
291
|
+
FM_ROOT_OVERRIDE='' FM_HOME=home \
|
|
292
|
+
FM_STATE_OVERRIDE=home/state FM_DATA_OVERRIDE=missing-data \
|
|
293
|
+
"$SPAWN" "$id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1
|
|
294
|
+
)
|
|
295
|
+
status=$?
|
|
296
|
+
expect_code 1 "$status" "spawn with an unresolvable relative data override should fail"
|
|
297
|
+
assert_contains "$out" "FM_DATA_OVERRIDE directory cannot be resolved: missing-data" \
|
|
298
|
+
"spawn did not name the unresolvable FM_DATA_OVERRIDE"
|
|
299
|
+
pass "unresolvable relative spawn overrides fail with named diagnostics"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
test_active_dispatch_profile_requires_explicit_harness_for_ship() {
|
|
303
|
+
local rec id out status
|
|
304
|
+
id=profile-required-ship-z11
|
|
305
|
+
rec=$(make_spawn_case profile-required-ship claude "$id")
|
|
306
|
+
read_case_record "$rec"
|
|
307
|
+
enable_dispatch_profile "$HOME_DIR"
|
|
308
|
+
|
|
309
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR")
|
|
310
|
+
status=$?
|
|
311
|
+
expect_code 1 "$status" "ship spawn without explicit harness should fail when dispatch profiles are active"
|
|
312
|
+
assert_contains "$out" "config/crew-dispatch.json is active - pass an explicit harness resolved from the dispatch rules" \
|
|
313
|
+
"spawn did not explain the dispatch-profile backstop"
|
|
314
|
+
assert_absent "$HOME_DIR/state/$id.meta" "ship refusal should happen before meta is written"
|
|
315
|
+
pass "active crew-dispatch profile requires an explicit harness for ship spawns"
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
test_active_dispatch_profile_requires_explicit_harness_for_scout() {
|
|
319
|
+
local rec id out status
|
|
320
|
+
id=profile-required-scout-z12
|
|
321
|
+
rec=$(make_spawn_case profile-required-scout claude "$id")
|
|
322
|
+
read_case_record "$rec"
|
|
323
|
+
enable_dispatch_profile "$HOME_DIR"
|
|
324
|
+
|
|
325
|
+
out=$(run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --scout)
|
|
326
|
+
status=$?
|
|
327
|
+
expect_code 1 "$status" "scout spawn without explicit harness should fail when dispatch profiles are active"
|
|
328
|
+
assert_contains "$out" "config/crew-dispatch.json is active - pass an explicit harness resolved from the dispatch rules" \
|
|
329
|
+
"scout refusal did not explain the dispatch-profile backstop"
|
|
330
|
+
assert_absent "$HOME_DIR/state/$id.meta" "scout refusal should happen before meta is written"
|
|
331
|
+
pass "active crew-dispatch profile requires an explicit harness for scout spawns"
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
test_active_dispatch_profile_allows_explicit_harness() {
|
|
335
|
+
local rec id out status launch
|
|
336
|
+
id=profile-explicit-z13
|
|
337
|
+
rec=$(make_spawn_case profile-explicit claude "$id")
|
|
338
|
+
read_case_record "$rec"
|
|
339
|
+
enable_dispatch_profile "$HOME_DIR"
|
|
340
|
+
|
|
341
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" \
|
|
342
|
+
"$id" "$PROJ_DIR" --harness codex --model gpt-5 --effort high)
|
|
343
|
+
status=$?
|
|
344
|
+
expect_code 0 "$status" "explicit harness should satisfy active dispatch-profile requirement"
|
|
345
|
+
assert_contains "$out" "spawned $id harness=codex" "spawn did not report explicit codex harness"
|
|
346
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" codex gpt-5 high
|
|
347
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
348
|
+
assert_contains "$launch" "codex --model 'gpt-5' -c 'model_reasoning_effort=\"high\"' --dangerously-bypass-approvals-and-sandbox" \
|
|
349
|
+
"explicit harness launch did not thread model and effort"
|
|
350
|
+
pass "active crew-dispatch profile allows an explicit resolved harness"
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
test_active_dispatch_profile_allows_positional_harness() {
|
|
354
|
+
local rec id out status
|
|
355
|
+
id=profile-positional-z14
|
|
356
|
+
rec=$(make_spawn_case profile-positional claude "$id")
|
|
357
|
+
read_case_record "$rec"
|
|
358
|
+
enable_dispatch_profile "$HOME_DIR"
|
|
359
|
+
|
|
360
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" \
|
|
361
|
+
"$id" "$PROJ_DIR" codex --model gpt-5 --effort high)
|
|
362
|
+
status=$?
|
|
363
|
+
expect_code 0 "$status" "positional harness should satisfy active dispatch-profile requirement"
|
|
364
|
+
assert_contains "$out" "spawned $id harness=codex" "spawn did not report positional codex harness"
|
|
365
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" codex gpt-5 high
|
|
366
|
+
pass "active crew-dispatch profile allows the legacy positional harness form"
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
test_active_dispatch_profile_allows_raw_launch_command() {
|
|
370
|
+
local rec id out status launch
|
|
371
|
+
id=profile-raw-z15
|
|
372
|
+
rec=$(make_spawn_case profile-raw claude "$id")
|
|
373
|
+
read_case_record "$rec"
|
|
374
|
+
enable_dispatch_profile "$HOME_DIR"
|
|
375
|
+
|
|
376
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" \
|
|
377
|
+
"$id" "$PROJ_DIR" "custom-agent --flag")
|
|
378
|
+
status=$?
|
|
379
|
+
expect_code 0 "$status" "raw launch command should satisfy active dispatch-profile requirement"
|
|
380
|
+
assert_contains "$out" "spawned $id harness=custom-agent" "spawn did not report raw command harness"
|
|
381
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" custom-agent default default
|
|
382
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
383
|
+
[ "$launch" = "custom-agent --flag" ] || fail "raw launch command changed"$'\n'"actual: $launch"
|
|
384
|
+
pass "active crew-dispatch profile allows the raw launch-command escape hatch"
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
test_claude_threads_model_and_effort() {
|
|
388
|
+
local rec id out status launch
|
|
389
|
+
id=profile-claude-z2
|
|
390
|
+
rec=$(make_spawn_case profile-claude claude "$id")
|
|
391
|
+
read_case_record "$rec"
|
|
392
|
+
|
|
393
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --model sonnet --effort high)
|
|
394
|
+
status=$?
|
|
395
|
+
expect_code 0 "$status" "claude spawn with profile flags should succeed"
|
|
396
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" claude sonnet high
|
|
397
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
398
|
+
assert_contains "$launch" "claude --dangerously-skip-permissions --model 'sonnet' --effort 'high'" \
|
|
399
|
+
"claude launch did not thread model and effort flags"
|
|
400
|
+
assert_not_contains "$launch" "--tui-mode" "non-Pi launches must not receive Pi's TUI mode override"
|
|
401
|
+
pass "claude receives --model and --effort profile flags"
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
test_codex_threads_model_and_effort() {
|
|
405
|
+
local rec id out status launch
|
|
406
|
+
id=profile-codex-z3
|
|
407
|
+
rec=$(make_spawn_case profile-codex codex "$id")
|
|
408
|
+
read_case_record "$rec"
|
|
409
|
+
|
|
410
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --model gpt-5 --effort high)
|
|
411
|
+
status=$?
|
|
412
|
+
expect_code 0 "$status" "codex spawn with profile flags should succeed"
|
|
413
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" codex gpt-5 high
|
|
414
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
415
|
+
assert_contains "$launch" "codex --model 'gpt-5' -c 'model_reasoning_effort=\"high\"' --dangerously-bypass-approvals-and-sandbox" \
|
|
416
|
+
"codex launch did not thread model and reasoning effort config"
|
|
417
|
+
pass "codex receives --model and model_reasoning_effort profile flags"
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
test_codex_omits_invalid_max_effort() {
|
|
421
|
+
local rec id out status launch
|
|
422
|
+
id=profile-codex-max-z4
|
|
423
|
+
rec=$(make_spawn_case profile-codex-max codex "$id")
|
|
424
|
+
read_case_record "$rec"
|
|
425
|
+
|
|
426
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --model gpt-5 --effort max)
|
|
427
|
+
status=$?
|
|
428
|
+
expect_code 0 "$status" "codex spawn with unsupported max effort should omit the effort flag"
|
|
429
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" codex gpt-5 max
|
|
430
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
431
|
+
assert_contains "$launch" "codex --model 'gpt-5' --dangerously-bypass-approvals-and-sandbox" \
|
|
432
|
+
"codex launch did not preserve the model flag when max effort was omitted"
|
|
433
|
+
assert_not_contains "$launch" "model_reasoning_effort" "codex launch must omit unsupported max reasoning effort"
|
|
434
|
+
pass "codex omits unsupported max effort instead of passing a bad config value"
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
test_grok_threads_model_and_reasoning_effort() {
|
|
438
|
+
local rec id out status launch
|
|
439
|
+
id=profile-grok-z5
|
|
440
|
+
rec=$(make_spawn_case profile-grok grok "$id")
|
|
441
|
+
read_case_record "$rec"
|
|
442
|
+
|
|
443
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --model grok-4 --effort high)
|
|
444
|
+
status=$?
|
|
445
|
+
expect_code 0 "$status" "grok spawn with profile flags should succeed"
|
|
446
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" grok grok-4 high
|
|
447
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
448
|
+
assert_contains "$launch" "grok --always-approve --model 'grok-4' --reasoning-effort 'high'" \
|
|
449
|
+
"grok launch did not thread model and reasoning-effort flags"
|
|
450
|
+
assert_not_contains "$launch" "--effort" "grok launch must use --reasoning-effort, not --effort"
|
|
451
|
+
pass "grok receives --model and --reasoning-effort profile flags"
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
test_grok_omits_invalid_max_reasoning_effort() {
|
|
455
|
+
local rec id out status launch
|
|
456
|
+
id=profile-grok-max-z6
|
|
457
|
+
rec=$(make_spawn_case profile-grok-max grok "$id")
|
|
458
|
+
read_case_record "$rec"
|
|
459
|
+
|
|
460
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --model grok-4 --effort max)
|
|
461
|
+
status=$?
|
|
462
|
+
expect_code 0 "$status" "grok spawn with unsupported max reasoning effort should omit the effort flag"
|
|
463
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" grok grok-4 max
|
|
464
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
465
|
+
assert_contains "$launch" "grok --always-approve --model 'grok-4' \"\$('${ROOT}/bin/fm-operational-input.sh' encode launch-brief < " \
|
|
466
|
+
"grok launch did not preserve the model flag and typed brief when max effort was omitted"
|
|
467
|
+
assert_not_contains "$launch" "--reasoning-effort" "grok launch must omit unsupported max reasoning effort"
|
|
468
|
+
assert_not_contains "$launch" "--effort" "grok launch must not fall back to --effort for reasoning effort"
|
|
469
|
+
pass "grok omits unsupported max reasoning effort"
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
test_grok_omits_invalid_xhigh_reasoning_effort() {
|
|
473
|
+
local rec id out status launch
|
|
474
|
+
id=profile-grok-xhigh-z6b
|
|
475
|
+
rec=$(make_spawn_case profile-grok-xhigh grok "$id")
|
|
476
|
+
read_case_record "$rec"
|
|
477
|
+
|
|
478
|
+
# grok 0.2.99 rejects xhigh (accepted set is only low|medium|high).
|
|
479
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --model grok-4 --effort xhigh)
|
|
480
|
+
status=$?
|
|
481
|
+
expect_code 0 "$status" "grok spawn with unsupported xhigh reasoning effort should omit the effort flag"
|
|
482
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" grok grok-4 xhigh
|
|
483
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
484
|
+
assert_contains "$launch" "grok --always-approve --model 'grok-4' \"\$('${ROOT}/bin/fm-operational-input.sh' encode launch-brief < " \
|
|
485
|
+
"grok launch did not preserve the model flag and typed brief when xhigh effort was omitted"
|
|
486
|
+
assert_not_contains "$launch" "--reasoning-effort" "grok launch must omit unsupported xhigh reasoning effort"
|
|
487
|
+
assert_not_contains "$launch" "--effort" "grok launch must not fall back to --effort for reasoning effort"
|
|
488
|
+
pass "grok omits unsupported xhigh reasoning effort"
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
test_cursor_threads_model_workspace_and_omits_effort_axis() {
|
|
492
|
+
local rec id out status launch
|
|
493
|
+
id=profile-cursor-z6c
|
|
494
|
+
rec=$(make_spawn_case profile-cursor cursor "$id")
|
|
495
|
+
read_case_record "$rec"
|
|
496
|
+
|
|
497
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" \
|
|
498
|
+
--model cursor-grok-4.5-high --effort high)
|
|
499
|
+
status=$?
|
|
500
|
+
expect_code 0 "$status" "cursor spawn with a model-qualified reasoning class should succeed"
|
|
501
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" cursor cursor-grok-4.5-high high
|
|
502
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
503
|
+
assert_contains "$launch" "--trust --yolo --model 'cursor-grok-4.5-high' --workspace '$WT_DIR'" \
|
|
504
|
+
"cursor launch did not carry trust, autonomy, model, and exact workspace flags"
|
|
505
|
+
# The executable is RESOLVED, never named: `cursor` is not the CLI, so a
|
|
506
|
+
# literal `cursor agent` command cannot run on a machine that has only the
|
|
507
|
+
# real installed names.
|
|
508
|
+
assert_not_contains "$launch" "cursor agent --trust" \
|
|
509
|
+
"cursor launch must resolve its executable, not invoke a literal 'cursor agent'"
|
|
510
|
+
assert_contains "$launch" "cursor-agent" "cursor launch did not resolve a cursor executable"
|
|
511
|
+
# -w/--worktree would allocate a SECOND worktree under ~/.cursor/worktrees and
|
|
512
|
+
# break the isolation contract the spawn assertion depends on.
|
|
513
|
+
assert_not_contains "$launch" " --worktree" "cursor launch must never allocate a second worktree"
|
|
514
|
+
assert_not_contains "$launch" " -w " "cursor launch must never allocate a second worktree"
|
|
515
|
+
# An inherited CLAUDECODE would otherwise outrank cursor's own marker.
|
|
516
|
+
assert_contains "$launch" "env -u CLAUDECODE" "cursor launch must clear foreign primary markers"
|
|
517
|
+
assert_contains "$launch" "encode launch-brief" "cursor launch did not deliver the brief positionally"
|
|
518
|
+
assert_not_contains "$launch" "--effort" "cursor launch must not invent a separate effort flag"
|
|
519
|
+
assert_not_contains "$launch" "--reasoning-effort" "cursor launch must not invent a separate reasoning-effort flag"
|
|
520
|
+
assert_grep 'harness=cursor' "$HOME_DIR/state/$id.meta" "cursor harness was not recorded in meta"
|
|
521
|
+
assert_grep 'model=cursor-grok-4.5-high' "$HOME_DIR/state/$id.meta" "cursor model was recorded as default"
|
|
522
|
+
pass "cursor receives its model-qualified reasoning class and exact task workspace"
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
test_cursor_refuses_model_absent_from_live_catalog() {
|
|
526
|
+
local rec id out status
|
|
527
|
+
id=profile-cursor-unsupported-z6d
|
|
528
|
+
rec=$(make_spawn_case profile-cursor-unsupported cursor "$id")
|
|
529
|
+
read_case_record "$rec"
|
|
530
|
+
|
|
531
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" \
|
|
532
|
+
--model cursor-grok-4.5)
|
|
533
|
+
status=$?
|
|
534
|
+
expect_code 1 "$status" "cursor spawn should refuse a model absent from a successful catalog"
|
|
535
|
+
assert_contains "$out" "Cursor model 'cursor-grok-4.5' is not available" \
|
|
536
|
+
"cursor model refusal did not identify the unavailable model"
|
|
537
|
+
assert_contains "$out" "--list-models" \
|
|
538
|
+
"cursor model refusal did not tell the caller how to find valid ids"
|
|
539
|
+
[ ! -s "$LAUNCH_LOG" ] || fail "cursor model refusal must happen before launch"
|
|
540
|
+
pass "cursor refuses model ids absent from its resolved binary's live catalog"
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
test_cursor_failed_catalog_probe_does_not_block_spawn() {
|
|
544
|
+
local rec id out status launch
|
|
545
|
+
id=profile-cursor-catalog-unreachable-z6e
|
|
546
|
+
rec=$(make_spawn_case profile-cursor-catalog-unreachable cursor "$id")
|
|
547
|
+
read_case_record "$rec"
|
|
548
|
+
|
|
549
|
+
FM_TEST_CURSOR_LIST_STATUS=124 \
|
|
550
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" \
|
|
551
|
+
--model cursor-catalog-unreachable)
|
|
552
|
+
status=$?
|
|
553
|
+
expect_code 0 "$status" "cursor spawn should fail open when the bounded catalog query fails"
|
|
554
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
555
|
+
assert_contains "$launch" "--model 'cursor-catalog-unreachable'" \
|
|
556
|
+
"failed catalog lookup incorrectly removed the requested model"
|
|
557
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" cursor cursor-catalog-unreachable default
|
|
558
|
+
pass "cursor preserves the requested model when its live catalog is unreachable"
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
test_opencode_threads_model_and_ignores_effort_axis() {
|
|
562
|
+
local rec id out status launch
|
|
563
|
+
id=profile-opencode-z7
|
|
564
|
+
rec=$(make_spawn_case profile-opencode opencode "$id")
|
|
565
|
+
read_case_record "$rec"
|
|
566
|
+
|
|
567
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" --model anthropic/claude-sonnet-4-5 --effort high)
|
|
568
|
+
status=$?
|
|
569
|
+
expect_code 0 "$status" "opencode spawn with model and ignored effort should succeed"
|
|
570
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" opencode anthropic/claude-sonnet-4-5 high
|
|
571
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
572
|
+
assert_contains "$launch" "opencode --model 'anthropic/claude-sonnet-4-5' --prompt" \
|
|
573
|
+
"opencode launch did not thread model"
|
|
574
|
+
assert_not_contains "$launch" "--effort" "opencode launch must not pass unsupported --effort"
|
|
575
|
+
assert_not_contains "$launch" "--variant" "opencode launch must not pass run-only --variant"
|
|
576
|
+
assert_not_contains "$launch" "--thinking" "opencode launch must not pass pi thinking flag"
|
|
577
|
+
pass "opencode receives --model and omits the unsupported effort axis"
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
test_pi_threads_model_and_max_effort() {
|
|
581
|
+
local rec id out status launch
|
|
582
|
+
id=profile-pi-z8
|
|
583
|
+
rec=$(make_spawn_case profile-pi pi "$id")
|
|
584
|
+
read_case_record "$rec"
|
|
585
|
+
|
|
586
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" \
|
|
587
|
+
--model openai-codex/gpt-5.6-sol --effort max)
|
|
588
|
+
status=$?
|
|
589
|
+
expect_code 0 "$status" "pi spawn with max effort should succeed"
|
|
590
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" pi openai-codex/gpt-5.6-sol max
|
|
591
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
592
|
+
assert_contains "$launch" "FM_PI_HARNESS=pi '$FAKEBIN_DIR/pi' --tui-mode regular --model 'openai-codex/gpt-5.6-sol' --thinking 'max' -e" \
|
|
593
|
+
"pi launch did not force the regular TUI while threading the requested model and max thinking level"
|
|
594
|
+
assert_not_contains "$launch" "FM_FIRSTMATE_PI_LAUNCH_BRIEF=" \
|
|
595
|
+
"pi launch still exports the removed Calm input-reroute binding"
|
|
596
|
+
assert_contains "$launch" "fm-operational-input.sh' encode launch-brief" \
|
|
597
|
+
"pi launch lost the canonical typed launch-brief envelope"
|
|
598
|
+
pass "pi receives --model and --thinking max profile flags"
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
test_pi_signed_threads_shared_pi_profile_and_preserves_identity() {
|
|
602
|
+
local rec id out status launch
|
|
603
|
+
id=profile-pi-signed-z8b
|
|
604
|
+
rec=$(make_spawn_case profile-pi-signed pi-signed "$id")
|
|
605
|
+
read_case_record "$rec"
|
|
606
|
+
|
|
607
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR" \
|
|
608
|
+
--model openai-codex/gpt-5.6-sol --effort max)
|
|
609
|
+
status=$?
|
|
610
|
+
expect_code 0 "$status" "pi-signed spawn with max effort should succeed"
|
|
611
|
+
assert_contains "$out" "spawned $id harness=pi-signed" "pi-signed spawn did not preserve its visible identity"
|
|
612
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" pi-signed openai-codex/gpt-5.6-sol max
|
|
613
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
614
|
+
assert_contains "$launch" "FM_PI_HARNESS=pi-signed '$FAKEBIN_DIR/pi-signed' --tui-mode regular --model 'openai-codex/gpt-5.6-sol' --thinking 'max' -e" \
|
|
615
|
+
"pi-signed launch did not force the regular TUI with Pi's model, thinking, and extension semantics"
|
|
616
|
+
assert_contains "$launch" "fm-operational-input.sh' encode launch-brief" \
|
|
617
|
+
"pi-signed launch lost the canonical typed launch-brief envelope"
|
|
618
|
+
assert_present "$HOME_DIR/state/$id.pi-ext.ts" "pi-signed launch did not install Pi's turn-end extension"
|
|
619
|
+
assert_present "$HOME_DIR/state/$id.busy-gen" "pi-signed spawn did not arm the busy-state contract"
|
|
620
|
+
assert_contains "$(cat "$HOME_DIR/state/$id.busy-state")" "state=busy source=fm-spawn" \
|
|
621
|
+
"pi-signed spawn did not seed the busy-state record from the launch brief"
|
|
622
|
+
local ext gen
|
|
623
|
+
ext=$(cat "$HOME_DIR/state/$id.pi-ext.ts")
|
|
624
|
+
gen=$(cat "$HOME_DIR/state/$id.busy-gen")
|
|
625
|
+
assert_contains "$ext" 'pi.on("agent_start"' "pi extension lost the semantic agent_start busy edge"
|
|
626
|
+
assert_contains "$ext" 'pi.on("agent_settled"' "pi extension lost the semantic agent_settled idle edge"
|
|
627
|
+
assert_contains "$ext" 'ctx.isIdle()' "pi extension no longer confirms idle with ctx.isIdle()"
|
|
628
|
+
assert_contains "$ext" "\"--gen\", \"$gen\"" "pi extension does not carry the armed incarnation gen"
|
|
629
|
+
assert_contains "$ext" '"--source", "pi-ext"' "pi extension does not attribute its semantic source"
|
|
630
|
+
assert_contains "$ext" 'pi.on("turn_end"' "pi extension lost the turn-end notification touch"
|
|
631
|
+
pass "pi-signed shares Pi launch semantics while preserving its configured and recorded identity"
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
test_pi_tui_mode_probe_is_safe_for_old_and_new_pi() {
|
|
635
|
+
local harness version rec id out status launch
|
|
636
|
+
for harness in pi pi-signed; do
|
|
637
|
+
for version in 0.82.0 0.84.0; do
|
|
638
|
+
id="profile-${harness}-tui-${version//./}-z8d"
|
|
639
|
+
rec=$(make_spawn_case "profile-__MODELFLAG__-${harness}-tui-${version//./}" "$harness" "$id")
|
|
640
|
+
read_case_record "$rec"
|
|
641
|
+
|
|
642
|
+
out=$(FM_TEST_PI_VERSION="$version" \
|
|
643
|
+
run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" \
|
|
644
|
+
"$id" "$PROJ_DIR")
|
|
645
|
+
status=$?
|
|
646
|
+
expect_code 0 "$status" "$harness $version spawn should succeed"
|
|
647
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
648
|
+
assert_contains "$launch" "'$FAKEBIN_DIR/$harness'" \
|
|
649
|
+
"$harness $version launch must use the executable selected for probing"
|
|
650
|
+
assert_not_contains "$launch" "FM_PI_HARNESS=$harness $harness" \
|
|
651
|
+
"$harness $version launch must not re-resolve a bare executable in the worker"
|
|
652
|
+
if [ "$version" = 0.82.0 ]; then
|
|
653
|
+
assert_not_contains "$launch" "--tui-mode" \
|
|
654
|
+
"$harness $version launch must omit unsupported --tui-mode"
|
|
655
|
+
else
|
|
656
|
+
assert_contains "$launch" "'$FAKEBIN_DIR/$harness' --tui-mode regular" \
|
|
657
|
+
"$harness $version launch must preserve the regular TUI"
|
|
658
|
+
fi
|
|
659
|
+
done
|
|
660
|
+
done
|
|
661
|
+
pass "Pi launch probing omits --tui-mode on older Pi and preserves it on supporting Pi"
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
test_pi_signed_missing_binary_refuses_before_endpoint_or_metadata() {
|
|
665
|
+
local rec id out status
|
|
666
|
+
id=profile-pi-signed-missing-z8c
|
|
667
|
+
rec=$(make_spawn_case profile-pi-signed-missing pi-signed "$id")
|
|
668
|
+
read_case_record "$rec"
|
|
669
|
+
rm -f "$FAKEBIN_DIR/pi-signed"
|
|
670
|
+
: > "$LAUNCH_LOG"
|
|
671
|
+
|
|
672
|
+
out=$(FM_ROOT_OVERRIDE='' FM_HOME="$HOME_DIR" \
|
|
673
|
+
FM_STATE_OVERRIDE="$HOME_DIR/state" FM_DATA_OVERRIDE="$HOME_DIR/data" \
|
|
674
|
+
FM_PROJECTS_OVERRIDE="$HOME_DIR/projects" FM_CONFIG_OVERRIDE="$HOME_DIR/config" \
|
|
675
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$WT_DIR" TMUX="fake,1,0" \
|
|
676
|
+
FM_FAKE_LAUNCH_LOG="$LAUNCH_LOG" PATH="$FAKEBIN_DIR:/usr/bin:/bin:/usr/sbin:/sbin" \
|
|
677
|
+
"$SPAWN" "$id" "$PROJ_DIR" --mode no-mistakes --yolo off 2>&1)
|
|
678
|
+
status=$?
|
|
679
|
+
expect_code 1 "$status" "a missing pi-signed executable should refuse the spawn"
|
|
680
|
+
assert_contains "$out" "pi-signed executable not found on PATH" \
|
|
681
|
+
"missing pi-signed refusal did not name the actionable requirement"
|
|
682
|
+
assert_absent "$HOME_DIR/state/$id.meta" "missing pi-signed refusal wrote task metadata"
|
|
683
|
+
[ ! -s "$LAUNCH_LOG" ] || fail "missing pi-signed refusal typed a launch command"
|
|
684
|
+
pass "pi-signed refuses safely and actionably when the selected executable is unavailable"
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
test_pi_signed_persistent_secondmate_uses_pi_extensions_and_identity() {
|
|
688
|
+
local rec id sm out status launch
|
|
689
|
+
id=profile-pi-signed-secondmate-z8d
|
|
690
|
+
rec=$(make_spawn_case profile-pi-signed-secondmate codex "$id")
|
|
691
|
+
read_case_record "$rec"
|
|
692
|
+
printf '%s\n' pi-signed > "$HOME_DIR/config/secondmate-harness"
|
|
693
|
+
sm="$CASE_DIR/secondmate-home"
|
|
694
|
+
make_seeded_secondmate_home "$sm" "$id"
|
|
695
|
+
sm=$(cd "$sm" && pwd -P)
|
|
696
|
+
|
|
697
|
+
out=$(run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$sm" --secondmate)
|
|
698
|
+
status=$?
|
|
699
|
+
expect_code 0 "$status" "pi-signed persistent secondmate spawn should succeed"
|
|
700
|
+
assert_contains "$out" "spawned $id harness=pi-signed kind=secondmate" \
|
|
701
|
+
"pi-signed secondmate spawn did not preserve its runtime identity"
|
|
702
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" pi-signed default default
|
|
703
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
704
|
+
assert_contains "$launch" "FM_PI_HARNESS=pi-signed '$FAKEBIN_DIR/pi-signed' --tui-mode regular -e '$sm/.pi/extensions/fm-primary-turnend-guard.ts' -e '$sm/.pi/extensions/fm-primary-pi-watch.ts'" \
|
|
705
|
+
"pi-signed secondmate did not force the regular TUI with Pi's primary extension launch shape"
|
|
706
|
+
pass "pi-signed is a distinct persistent secondmate runtime with shared Pi supervision semantics"
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
test_batch_forwards_shared_profile_flags() {
|
|
710
|
+
local rec id1 id2 out status
|
|
711
|
+
id1=profile-batch-a-z9
|
|
712
|
+
id2=profile-batch-b-z10
|
|
713
|
+
rec=$(make_spawn_case profile-batch claude "$id1" "$id2")
|
|
714
|
+
read_case_record "$rec"
|
|
715
|
+
enable_dispatch_profile "$HOME_DIR"
|
|
716
|
+
|
|
717
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" \
|
|
718
|
+
"$id1=$PROJ_DIR" "$id2=$PROJ_DIR" --harness codex --model gpt-5 --effort high)
|
|
719
|
+
status=$?
|
|
720
|
+
expect_code 0 "$status" "batch spawn with shared profile flags should succeed"
|
|
721
|
+
assert_contains "$out" "spawned $id1 harness=codex" "first batch task did not use shared harness"
|
|
722
|
+
assert_contains "$out" "spawned $id2 harness=codex" "second batch task did not use shared harness"
|
|
723
|
+
assert_meta_profile "$HOME_DIR/state/$id1.meta" codex gpt-5 high
|
|
724
|
+
assert_meta_profile "$HOME_DIR/state/$id2.meta" codex gpt-5 high
|
|
725
|
+
pass "batch dispatch forwards shared --harness, --model, and --effort to every pair"
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
test_claude_forwards_firstmate_config_dir_when_set() {
|
|
729
|
+
local rec id out status launch
|
|
730
|
+
id=profile-claude-cfgdir-z17
|
|
731
|
+
rec=$(make_spawn_case profile-claude-cfgdir claude "$id")
|
|
732
|
+
read_case_record "$rec"
|
|
733
|
+
|
|
734
|
+
out=$(FM_TEST_CLAUDE_CONFIG_DIR="/opt/test/claude-work" \
|
|
735
|
+
run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR")
|
|
736
|
+
status=$?
|
|
737
|
+
expect_code 0 "$status" "claude spawn with CLAUDE_CONFIG_DIR set should succeed"
|
|
738
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
739
|
+
assert_contains "$launch" "CLAUDE_CONFIG_DIR='/opt/test/claude-work' env -u CURSOR_AGENT -u CURSOR_INVOKED_AS CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false claude" \
|
|
740
|
+
"claude launch did not forward firstmate's CLAUDE_CONFIG_DIR to the crewmate pane"
|
|
741
|
+
pass "claude forwards firstmate's CLAUDE_CONFIG_DIR so the crewmate uses the same credential store"
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
test_claude_omits_config_dir_prefix_when_unset() {
|
|
745
|
+
local rec id out status launch
|
|
746
|
+
id=profile-claude-nocfgdir-z18
|
|
747
|
+
rec=$(make_spawn_case profile-claude-nocfgdir claude "$id")
|
|
748
|
+
read_case_record "$rec"
|
|
749
|
+
|
|
750
|
+
# run_spawn pins CLAUDE_CONFIG_DIR empty by default, exercising the single-store
|
|
751
|
+
# default path where fm-spawn adds no prefix.
|
|
752
|
+
out=$(run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR")
|
|
753
|
+
status=$?
|
|
754
|
+
expect_code 0 "$status" "claude spawn without CLAUDE_CONFIG_DIR should succeed"
|
|
755
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
756
|
+
assert_not_contains "$launch" "CLAUDE_CONFIG_DIR=" \
|
|
757
|
+
"claude launch must not add a config-dir prefix when firstmate has no CLAUDE_CONFIG_DIR set"
|
|
758
|
+
pass "claude omits the config-dir prefix when firstmate runs with the single-store default"
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
test_non_claude_harness_ignores_config_dir() {
|
|
762
|
+
local rec id out status launch
|
|
763
|
+
id=profile-codex-nocfgdir-z19
|
|
764
|
+
rec=$(make_spawn_case profile-codex-nocfgdir codex "$id")
|
|
765
|
+
read_case_record "$rec"
|
|
766
|
+
|
|
767
|
+
out=$(FM_TEST_CLAUDE_CONFIG_DIR="/opt/test/claude-work" \
|
|
768
|
+
run_ship_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$PROJ_DIR")
|
|
769
|
+
status=$?
|
|
770
|
+
expect_code 0 "$status" "codex spawn with CLAUDE_CONFIG_DIR set should succeed"
|
|
771
|
+
launch=$(cat "$LAUNCH_LOG")
|
|
772
|
+
assert_not_contains "$launch" "CLAUDE_CONFIG_DIR=" \
|
|
773
|
+
"non-claude harness launch must not receive the claude-specific config-dir prefix"
|
|
774
|
+
pass "non-claude harnesses do not receive the claude CLAUDE_CONFIG_DIR prefix"
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
test_active_dispatch_profile_does_not_block_secondmate_launch() {
|
|
778
|
+
local rec id sm out status
|
|
779
|
+
id=profile-secondmate-z16
|
|
780
|
+
rec=$(make_spawn_case profile-secondmate codex "$id")
|
|
781
|
+
read_case_record "$rec"
|
|
782
|
+
enable_dispatch_profile "$HOME_DIR"
|
|
783
|
+
sm="$CASE_DIR/secondmate-home"
|
|
784
|
+
make_seeded_secondmate_home "$sm" "$id"
|
|
785
|
+
|
|
786
|
+
out=$(run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$id" "$sm" --secondmate)
|
|
787
|
+
status=$?
|
|
788
|
+
expect_code 0 "$status" "secondmate spawn should be exempt from the dispatch-profile explicit harness requirement"
|
|
789
|
+
assert_contains "$out" "spawned $id harness=codex kind=secondmate" "secondmate launch did not use secondmate harness resolution"
|
|
790
|
+
assert_grep "kind=secondmate" "$HOME_DIR/state/$id.meta" "secondmate meta missing kind=secondmate"
|
|
791
|
+
assert_meta_profile "$HOME_DIR/state/$id.meta" codex default default
|
|
792
|
+
pass "active crew-dispatch profile does not block secondmate launches"
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
test_no_profile_keeps_claude_profile_defaults
|
|
796
|
+
test_non_cursor_launch_clears_inherited_cursor_markers
|
|
797
|
+
test_relative_home_overrides_launch_with_absolute_cross_process_paths
|
|
798
|
+
test_home_defaults_preserve_absolute_or_resolve_relative_paths
|
|
799
|
+
test_absolute_override_spelling_is_preserved_in_launch_paths
|
|
800
|
+
test_unresolvable_relative_overrides_fail_loudly
|
|
801
|
+
test_active_dispatch_profile_requires_explicit_harness_for_ship
|
|
802
|
+
test_active_dispatch_profile_requires_explicit_harness_for_scout
|
|
803
|
+
test_active_dispatch_profile_allows_explicit_harness
|
|
804
|
+
test_active_dispatch_profile_allows_positional_harness
|
|
805
|
+
test_active_dispatch_profile_allows_raw_launch_command
|
|
806
|
+
test_claude_threads_model_and_effort
|
|
807
|
+
test_codex_threads_model_and_effort
|
|
808
|
+
test_codex_omits_invalid_max_effort
|
|
809
|
+
test_grok_threads_model_and_reasoning_effort
|
|
810
|
+
test_grok_omits_invalid_max_reasoning_effort
|
|
811
|
+
test_grok_omits_invalid_xhigh_reasoning_effort
|
|
812
|
+
test_cursor_threads_model_workspace_and_omits_effort_axis
|
|
813
|
+
test_cursor_refuses_model_absent_from_live_catalog
|
|
814
|
+
test_cursor_failed_catalog_probe_does_not_block_spawn
|
|
815
|
+
test_opencode_threads_model_and_ignores_effort_axis
|
|
816
|
+
test_pi_threads_model_and_max_effort
|
|
817
|
+
test_pi_tui_mode_probe_is_safe_for_old_and_new_pi
|
|
818
|
+
test_pi_signed_threads_shared_pi_profile_and_preserves_identity
|
|
819
|
+
test_pi_signed_missing_binary_refuses_before_endpoint_or_metadata
|
|
820
|
+
test_pi_signed_persistent_secondmate_uses_pi_extensions_and_identity
|
|
821
|
+
test_batch_forwards_shared_profile_flags
|
|
822
|
+
test_claude_forwards_firstmate_config_dir_when_set
|
|
823
|
+
test_claude_omits_config_dir_prefix_when_unset
|
|
824
|
+
test_non_claude_harness_ignores_config_dir
|
|
825
|
+
test_active_dispatch_profile_does_not_block_secondmate_launch
|
|
826
|
+
|
|
827
|
+
echo "# all fm-spawn-dispatch-profile tests passed"
|