@zerwiz/ymir 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +291 -0
- package/.agents/agents/bragi-marketer.md +111 -0
- package/.agents/agents/brokk.md +352 -0
- package/.agents/agents/forseti-reviewer.md +93 -0
- package/.agents/agents/frigg-consent.md +77 -0
- package/.agents/agents/groa-update.md +77 -0
- package/.agents/agents/hnoss-designer.md +69 -0
- package/.agents/agents/huginn-researcher.md +99 -0
- package/.agents/agents/jord-projects.md +78 -0
- package/.agents/agents/kvasir-scout.md +91 -0
- package/.agents/agents/mimir-planner.md +92 -0
- package/.agents/agents/muninn-stow.md +77 -0
- package/.agents/agents/saga-bearings.md +78 -0
- package/.agents/agents/sindri-developer.md +114 -0
- package/.agents/agents/snotra-documenter.md +105 -0
- package/.agents/agents/syn-recovery.md +78 -0
- package/.agents/agents/tyr-check.md +78 -0
- package/.agents/agents/urdh-hold.md +77 -0
- package/.agents/agents/volundr-smith.md +80 -0
- package/.agents/agents/vor-diagnostics.md +77 -0
- package/.agents/assets/agents/naming.md +50 -0
- package/.agents/assets/agents/registry.md +93 -0
- package/.agents/assets/agents/runtime.md +36 -0
- package/.agents/assets/agents/toon-tasks-cli.md +42 -0
- package/.agents/assets/templates/company_entity.template.md +37 -0
- package/.agents/backend/backends/cmux.sh +649 -0
- package/.agents/backend/backends/herdr-eventwait.py +157 -0
- package/.agents/backend/backends/herdr-workspace-move.py +114 -0
- package/.agents/backend/backends/herdr.sh +3386 -0
- package/.agents/backend/backends/orca.sh +290 -0
- package/.agents/backend/backends/tmux.sh +357 -0
- package/.agents/backend/backends/zellij.sh +700 -0
- package/.agents/backend/fm-afk-launch.sh +654 -0
- package/.agents/backend/fm-afk-return.sh +241 -0
- package/.agents/backend/fm-afk-start.sh +172 -0
- package/.agents/backend/fm-arm-command-policy.mjs +960 -0
- package/.agents/backend/fm-arm-pretool-check.sh +200 -0
- package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
- package/.agents/backend/fm-backend.sh +981 -0
- package/.agents/backend/fm-backlog-handoff.sh +909 -0
- package/.agents/backend/fm-backlog-receive.sh +187 -0
- package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
- package/.agents/backend/fm-bearings-board.sh +204 -0
- package/.agents/backend/fm-bearings-snapshot.sh +546 -0
- package/.agents/backend/fm-bootstrap.sh +1568 -0
- package/.agents/backend/fm-branch-outcome.sh +203 -0
- package/.agents/backend/fm-branch-prompt.sh +101 -0
- package/.agents/backend/fm-brief.sh +452 -0
- package/.agents/backend/fm-busy-event.sh +234 -0
- package/.agents/backend/fm-busy-lib.sh +986 -0
- package/.agents/backend/fm-captain-hold.sh +1001 -0
- package/.agents/backend/fm-cd-command-policy.mjs +153 -0
- package/.agents/backend/fm-cd-pretool-check.sh +190 -0
- package/.agents/backend/fm-check-lib.sh +74 -0
- package/.agents/backend/fm-check-register.sh +42 -0
- package/.agents/backend/fm-check-unregister.sh +52 -0
- package/.agents/backend/fm-classify-lib.sh +1770 -0
- package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
- package/.agents/backend/fm-composer-lib.sh +1416 -0
- package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
- package/.agents/backend/fm-config-push.sh +254 -0
- package/.agents/backend/fm-control-lib.sh +251 -0
- package/.agents/backend/fm-control.sh +878 -0
- package/.agents/backend/fm-crew-state.sh +625 -0
- package/.agents/backend/fm-cursor-lib.sh +243 -0
- package/.agents/backend/fm-decision-hold.sh +232 -0
- package/.agents/backend/fm-doc-audience-check.sh +269 -0
- package/.agents/backend/fm-dod-lib.sh +67 -0
- package/.agents/backend/fm-ensure-agents-md.sh +253 -0
- package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
- package/.agents/backend/fm-extension.mjs +2577 -0
- package/.agents/backend/fm-extension.sh +16 -0
- package/.agents/backend/fm-ff-lib.sh +420 -0
- package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
- package/.agents/backend/fm-fleet-sync.sh +458 -0
- package/.agents/backend/fm-fleet-view.sh +96 -0
- package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
- package/.agents/backend/fm-guard.sh +242 -0
- package/.agents/backend/fm-harness.sh +195 -0
- package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
- package/.agents/backend/fm-herdr-lab.sh +346 -0
- package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
- package/.agents/backend/fm-home-seed.sh +984 -0
- package/.agents/backend/fm-home-summary-refresh.sh +255 -0
- package/.agents/backend/fm-hook-host-lib.sh +36 -0
- package/.agents/backend/fm-inactive-reconcile.sh +531 -0
- package/.agents/backend/fm-inbox.sh +399 -0
- package/.agents/backend/fm-install-actionlint.sh +84 -0
- package/.agents/backend/fm-install-herdr.sh +96 -0
- package/.agents/backend/fm-install-shellcheck.sh +84 -0
- package/.agents/backend/fm-install-treehouse.sh +95 -0
- package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
- package/.agents/backend/fm-lease-lib.sh +218 -0
- package/.agents/backend/fm-lease.sh +189 -0
- package/.agents/backend/fm-line-cap-lib.sh +51 -0
- package/.agents/backend/fm-lint-workflows.sh +137 -0
- package/.agents/backend/fm-lint.sh +591 -0
- package/.agents/backend/fm-lock-lib.sh +104 -0
- package/.agents/backend/fm-lock.sh +107 -0
- package/.agents/backend/fm-marker-lib.sh +12 -0
- package/.agents/backend/fm-merge-local.sh +74 -0
- package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
- package/.agents/backend/fm-nm-run-lib.sh +124 -0
- package/.agents/backend/fm-on.sh +125 -0
- package/.agents/backend/fm-operational-input.sh +253 -0
- package/.agents/backend/fm-peek.sh +46 -0
- package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
- package/.agents/backend/fm-pr-check.sh +135 -0
- package/.agents/backend/fm-pr-lib.sh +1016 -0
- package/.agents/backend/fm-pr-merge.sh +707 -0
- package/.agents/backend/fm-pr-poll.sh +110 -0
- package/.agents/backend/fm-primary-scope-lib.sh +33 -0
- package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
- package/.agents/backend/fm-procevent-lavish.sh +628 -0
- package/.agents/backend/fm-procevent-lib.sh +892 -0
- package/.agents/backend/fm-procevent-quota.sh +290 -0
- package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
- package/.agents/backend/fm-procevent-when.sh +504 -0
- package/.agents/backend/fm-procevent.sh +1466 -0
- package/.agents/backend/fm-project-mode.sh +92 -0
- package/.agents/backend/fm-project-origin-lib.sh +180 -0
- package/.agents/backend/fm-promote.sh +282 -0
- package/.agents/backend/fm-public-followup-emit.sh +260 -0
- package/.agents/backend/fm-public-followup-lib.sh +398 -0
- package/.agents/backend/fm-public-followup.sh +1330 -0
- package/.agents/backend/fm-push-transition-lib.sh +168 -0
- package/.agents/backend/fm-quota-axi-lib.sh +93 -0
- package/.agents/backend/fm-quota-choose.sh +384 -0
- package/.agents/backend/fm-remote-delta-read.sh +189 -0
- package/.agents/backend/fm-remote-doctor.sh +800 -0
- package/.agents/backend/fm-remote-entrypoint.sh +193 -0
- package/.agents/backend/fm-remote-file.sh +234 -0
- package/.agents/backend/fm-remote-home-provision.sh +259 -0
- package/.agents/backend/fm-remote-home-seed.sh +259 -0
- package/.agents/backend/fm-remote-inherit-push.sh +90 -0
- package/.agents/backend/fm-remote-inherit.sh +179 -0
- package/.agents/backend/fm-remote-job-lib.sh +1241 -0
- package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
- package/.agents/backend/fm-remote-job-worker.sh +1124 -0
- package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
- package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
- package/.agents/backend/fm-review-diff.sh +158 -0
- package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
- package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
- package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
- package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
- package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
- package/.agents/backend/fm-secondmate-report.sh +88 -0
- package/.agents/backend/fm-send.sh +1059 -0
- package/.agents/backend/fm-session-lock-lib.sh +176 -0
- package/.agents/backend/fm-session-start.sh +970 -0
- package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
- package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
- package/.agents/backend/fm-sessionstart-run.sh +145 -0
- package/.agents/backend/fm-spawn.sh +3153 -0
- package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
- package/.agents/backend/fm-startup-memory-budget.sh +94 -0
- package/.agents/backend/fm-startup-network.sh +642 -0
- package/.agents/backend/fm-stow-cascade.sh +251 -0
- package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
- package/.agents/backend/fm-supervise-daemon.sh +1732 -0
- package/.agents/backend/fm-supervision-instructions.sh +215 -0
- package/.agents/backend/fm-supervision-lib.sh +90 -0
- package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
- package/.agents/backend/fm-tangle-lib.sh +53 -0
- package/.agents/backend/fm-task-inbox-lib.sh +402 -0
- package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
- package/.agents/backend/fm-teardown.sh +2922 -0
- package/.agents/backend/fm-test-isolation-proof.sh +588 -0
- package/.agents/backend/fm-test-run.sh +2191 -0
- package/.agents/backend/fm-timeout-lib.sh +141 -0
- package/.agents/backend/fm-timing-lib.sh +179 -0
- package/.agents/backend/fm-tmux-lib.sh +291 -0
- package/.agents/backend/fm-tool-update-check.sh +898 -0
- package/.agents/backend/fm-trace-context-lib.sh +227 -0
- package/.agents/backend/fm-transition-lib.sh +103 -0
- package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
- package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
- package/.agents/backend/fm-turnend-guard.sh +432 -0
- package/.agents/backend/fm-update.sh +110 -0
- package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
- package/.agents/backend/fm-voice-client.py +1373 -0
- package/.agents/backend/fm-voice-relay.py +1256 -0
- package/.agents/backend/fm-wake-drain.sh +592 -0
- package/.agents/backend/fm-wake-grant.sh +127 -0
- package/.agents/backend/fm-wake-lib.sh +1849 -0
- package/.agents/backend/fm-watch-arm.sh +602 -0
- package/.agents/backend/fm-watch-checkpoint.sh +109 -0
- package/.agents/backend/fm-watch.sh +1962 -0
- package/.agents/backend/fm-x-dismiss.sh +116 -0
- package/.agents/backend/fm-x-followup.sh +286 -0
- package/.agents/backend/fm-x-lib.sh +1000 -0
- package/.agents/backend/fm-x-link.sh +234 -0
- package/.agents/backend/fm-x-poll.sh +185 -0
- package/.agents/backend/fm-x-reply.sh +385 -0
- package/.agents/backend/fm_voice_frame.py +166 -0
- package/.agents/backend/fm_voice_records.py +574 -0
- package/.agents/backend/model-bridge.py +290 -0
- package/.agents/backend/opencode-go-bridge.py +30 -0
- package/.agents/bus/README.md +12 -0
- package/.agents/bus/messages.json +1 -0
- package/.agents/config/agents.machine.example.yaml +16 -0
- package/.agents/config/agents.yaml +50 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +9 -0
- package/.agents/config/eindri-dispatch.json +67 -0
- package/.agents/config/eindri-harness +1 -0
- package/.agents/config/startup-memory-budget +1 -0
- package/.agents/config/tailscale-sync.yaml +27 -0
- package/.agents/filebrowser/.filebrowser.json +6 -0
- package/.agents/filebrowser/README.md +11 -0
- package/.agents/gateway/README.md +12 -0
- package/.agents/github/README.md +15 -0
- package/.agents/github/webhooks/.gitkeep +0 -0
- package/.agents/github/workflows/.gitkeep +0 -0
- package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
- package/.agents/harness/opencode/plugins/package.json +4 -0
- package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
- package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
- package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
- package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
- package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
- package/.agents/memory/README.md +46 -0
- package/.agents/memory/kaia.engram +0 -0
- package/.agents/memory/kaia.engram-shm +0 -0
- package/.agents/memory/kaia.engram-wal +0 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/memory/well/episodes.jsonl +367 -0
- package/.agents/memory/well/workspace.jsonl +27 -0
- package/.agents/migrations/0001-hodd-layout.sh +38 -0
- package/.agents/migrations/0002-a2a-mcp.sh +27 -0
- package/.agents/migrations/0003-private-data-separation.sh +111 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/sandbox/Dockerfile.utgard +19 -0
- package/.agents/sandbox/README.md +14 -0
- package/.agents/sandbox/utgard.config.json +14 -0
- package/.agents/skills/README.md +59 -0
- package/.agents/skills/bragi-marketing/README.md +3 -0
- package/.agents/skills/bragi-marketing/SKILL.md +82 -0
- package/.agents/skills/eindri-homes/README.md +3 -0
- package/.agents/skills/eindri-homes/SKILL.md +291 -0
- package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
- package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
- package/.agents/skills/frigg-consent/README.md +3 -0
- package/.agents/skills/frigg-consent/SKILL.md +56 -0
- package/.agents/skills/galdr-ymirsystem/README.md +3 -0
- package/.agents/skills/galdr-ymirsystem/SKILL.md +158 -0
- package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
- package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +673 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
- package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +496 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
- package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +161 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +96 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
- package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
- package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
- package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
- package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
- package/.agents/skills/galdr-ymirsystem/assets/smidja.md +175 -0
- package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
- package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
- package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
- package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +360 -0
- package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
- package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
- package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
- package/.agents/skills/gjallarhorn-relay/README.md +3 -0
- package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
- package/.agents/skills/groa-update/SKILL.md +70 -0
- package/.agents/skills/hamr-adapters/README.md +3 -0
- package/.agents/skills/hamr-adapters/SKILL.md +123 -0
- package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
- package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
- package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
- package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
- package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
- package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
- package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
- package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
- package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
- package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
- package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
- package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
- package/.agents/skills/herdr-panes/README.md +3 -0
- package/.agents/skills/herdr-panes/SKILL.md +92 -0
- package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
- package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
- package/.agents/skills/hnoss-design/DESIGN.md +19 -0
- package/.agents/skills/hnoss-design/README.md +3 -0
- package/.agents/skills/hnoss-design/SKILL.md +83 -0
- package/.agents/skills/hvild-afk/README.md +3 -0
- package/.agents/skills/hvild-afk/SKILL.md +241 -0
- package/.agents/skills/jord-projects/README.md +3 -0
- package/.agents/skills/jord-projects/SKILL.md +92 -0
- package/.agents/skills/lifecycle/SKILL.md +56 -0
- package/.agents/skills/lifecycle/smoke_test.sh +52 -0
- package/.agents/skills/lifecycle/start.sh +21 -0
- package/.agents/skills/lifecycle/status.sh +35 -0
- package/.agents/skills/lifecycle/stop.sh +16 -0
- package/.agents/skills/muninn-stow/README.md +3 -0
- package/.agents/skills/muninn-stow/SKILL.md +309 -0
- package/.agents/skills/no-mistakes/SKILL.md +379 -0
- package/.agents/skills/nornir-schedule/README.md +3 -0
- package/.agents/skills/nornir-schedule/SKILL.md +25 -0
- package/.agents/skills/nornir-schedule/assets/events.md +137 -0
- package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
- package/.agents/skills/nsr-compliance/README.md +3 -0
- package/.agents/skills/nsr-compliance/SKILL.md +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/pr-ops/README.md +3 -0
- package/.agents/skills/pr-ops/SKILL.md +109 -0
- package/.agents/skills/ratatoskr-a2a/README.md +3 -0
- package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
- package/.agents/skills/rules-check-drift/SKILL.md +81 -0
- package/.agents/skills/saga-bearings/README.md +3 -0
- package/.agents/skills/saga-bearings/SKILL.md +26 -0
- package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
- package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
- package/.agents/skills/saga-bearings/assets/recap.md +56 -0
- package/.agents/skills/syn-recovery/README.md +3 -0
- package/.agents/skills/syn-recovery/SKILL.md +54 -0
- package/.agents/skills/tyr-check/README.md +3 -0
- package/.agents/skills/tyr-check/SKILL.md +218 -0
- package/.agents/skills/urdh-hold/README.md +3 -0
- package/.agents/skills/urdh-hold/SKILL.md +25 -0
- package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
- package/.agents/skills/urdh-hold/assets/hold.md +54 -0
- package/.agents/skills/vor-diagnostics/README.md +3 -0
- package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
- package/.agents/skills/ymir-host/README.md +3 -0
- package/.agents/skills/ymir-host/SKILL.md +34 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
- package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
- package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
- package/.agents/skills/ymir-host/assets/update.md +64 -0
- package/.agents/tests/assets/board-render-harness.mjs +117 -0
- package/.agents/tests/cmux-test-safety.sh +51 -0
- package/.agents/tests/fixtures.sh +291 -0
- package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
- package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
- package/.agents/tests/fm-afk-launch.test.sh +961 -0
- package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
- package/.agents/tests/fm-afk-return.test.sh +283 -0
- package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
- package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
- package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
- package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
- package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
- package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
- package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
- package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
- package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
- package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
- package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
- package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
- package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
- package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
- package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
- package/.agents/tests/fm-backend-orca.test.sh +1357 -0
- package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
- package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
- package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
- package/.agents/tests/fm-backend.test.sh +1142 -0
- package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
- package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
- package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
- package/.agents/tests/fm-bearings-board.test.sh +414 -0
- package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
- package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
- package/.agents/tests/fm-bootstrap.test.sh +1178 -0
- package/.agents/tests/fm-branch-supervision.test.sh +552 -0
- package/.agents/tests/fm-brief.test.sh +785 -0
- package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
- package/.agents/tests/fm-busy-state.test.sh +465 -0
- package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
- package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
- package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
- package/.agents/tests/fm-check-unregister.test.sh +198 -0
- package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
- package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
- package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
- package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
- package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
- package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
- package/.agents/tests/fm-composer-ghost.test.sh +716 -0
- package/.agents/tests/fm-composer-lib.test.sh +666 -0
- package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
- package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
- package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
- package/.agents/tests/fm-control.test.sh +910 -0
- package/.agents/tests/fm-crew-state.test.sh +1610 -0
- package/.agents/tests/fm-cursor-harness.test.sh +404 -0
- package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
- package/.agents/tests/fm-cursor-primary.test.sh +708 -0
- package/.agents/tests/fm-daemon.test.sh +2740 -0
- package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
- package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
- package/.agents/tests/fm-extension-binding.test.sh +2187 -0
- package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
- package/.agents/tests/fm-fleet-sync.test.sh +721 -0
- package/.agents/tests/fm-gate-refuse.test.sh +356 -0
- package/.agents/tests/fm-gitignore-config.test.sh +89 -0
- package/.agents/tests/fm-gotmp.test.sh +230 -0
- package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
- package/.agents/tests/fm-grok-harness.test.sh +117 -0
- package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
- package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
- package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
- package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
- package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
- package/.agents/tests/fm-herdr-lab.test.sh +243 -0
- package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
- package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
- package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
- package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
- package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
- package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
- package/.agents/tests/fm-kimi-harness.test.sh +687 -0
- package/.agents/tests/fm-lint-workflows.test.sh +532 -0
- package/.agents/tests/fm-lint.test.sh +1023 -0
- package/.agents/tests/fm-muse-harness.test.sh +932 -0
- package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
- package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
- package/.agents/tests/fm-on.test.sh +507 -0
- package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
- package/.agents/tests/fm-operational-input.test.sh +160 -0
- package/.agents/tests/fm-peek-remote.test.sh +110 -0
- package/.agents/tests/fm-pending-reply.test.sh +1288 -0
- package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
- package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
- package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
- package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
- package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
- package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
- package/.agents/tests/fm-pr-merge.test.sh +2135 -0
- package/.agents/tests/fm-procevent-quota.test.sh +225 -0
- package/.agents/tests/fm-procevent-when.test.sh +406 -0
- package/.agents/tests/fm-procevent.test.sh +1745 -0
- package/.agents/tests/fm-project-origin.test.sh +110 -0
- package/.agents/tests/fm-public-followup.test.sh +2272 -0
- package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
- package/.agents/tests/fm-quota-choose.test.sh +626 -0
- package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
- package/.agents/tests/fm-remote-doctor.test.sh +625 -0
- package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
- package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
- package/.agents/tests/fm-remote-job.test.sh +768 -0
- package/.agents/tests/fm-remote-reply.test.sh +520 -0
- package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
- package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
- package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
- package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
- package/.agents/tests/fm-review-diff.test.sh +176 -0
- package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
- package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
- package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
- package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
- package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
- package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
- package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
- package/.agents/tests/fm-send-inbox.test.sh +352 -0
- package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
- package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
- package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
- package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
- package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
- package/.agents/tests/fm-send-settle.test.sh +147 -0
- package/.agents/tests/fm-send-strict.test.sh +241 -0
- package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
- package/.agents/tests/fm-session-start.test.sh +2515 -0
- package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
- package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
- package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
- package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
- package/.agents/tests/fm-spawn-batch.test.sh +148 -0
- package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
- package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
- package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
- package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
- package/.agents/tests/fm-startup-network.test.sh +712 -0
- package/.agents/tests/fm-stow-cascade.test.sh +370 -0
- package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
- package/.agents/tests/fm-supervision-events.test.sh +156 -0
- package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
- package/.agents/tests/fm-tangle-guard.test.sh +277 -0
- package/.agents/tests/fm-task-delivery.test.sh +420 -0
- package/.agents/tests/fm-task-inbox.test.sh +513 -0
- package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
- package/.agents/tests/fm-teardown.test.sh +2665 -0
- package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
- package/.agents/tests/fm-test-fixtures.test.sh +132 -0
- package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
- package/.agents/tests/fm-test-run.test.sh +1196 -0
- package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
- package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
- package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
- package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
- package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
- package/.agents/tests/fm-transition-lib.test.sh +54 -0
- package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
- package/.agents/tests/fm-update.test.sh +304 -0
- package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
- package/.agents/tests/fm-voice-relay.test.sh +4741 -0
- package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
- package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
- package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
- package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
- package/.agents/tests/fm-wake-queue.test.sh +1224 -0
- package/.agents/tests/fm-watch-arm.test.sh +821 -0
- package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
- package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
- package/.agents/tests/fm-watch-triage.test.sh +3889 -0
- package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
- package/.agents/tests/fm-x-mode.test.sh +3042 -0
- package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
- package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
- package/.agents/tests/herdr-test-safety.sh +42 -0
- package/.agents/tests/lib.sh +315 -0
- package/.agents/tests/remote-herdr-fixture.sh +125 -0
- package/.agents/tests/secondmate-helpers.sh +193 -0
- package/.agents/tests/smoke.test.sh +93 -0
- package/.agents/tests/wake-helpers.sh +338 -0
- package/.agents/tests/zellij-test-safety.sh +60 -0
- package/.agents/tools/README.md +10 -0
- package/.agents/tools/bin/tasks-cli +267 -0
- package/.agents/tools/tasks-cli.ts +216 -0
- package/AGENTS.md +454 -0
- package/CHANGELOG.md +881 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +113 -39
- package/RULES/01-domains.md +51 -0
- package/RULES/02-agents.md +78 -0
- package/RULES/03-houses.md +61 -0
- package/RULES/04-hoard.md +65 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +58 -0
- package/RULES/07-config.md +45 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/README.md +20 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +98 -0
- package/bin/a2a-serve.py +103 -0
- package/bin/a2a-serve.sh +8 -0
- package/bin/a2a-talk.sh +50 -0
- package/bin/a2abridge-ensure.sh +108 -0
- package/bin/agent-run.sh +43 -0
- package/bin/agents-config.sh +233 -0
- package/bin/apodex-smoke-test.sh +92 -0
- package/bin/bifrost-bridge.sh +112 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +107 -0
- package/bin/bootstrap-windows.ps1 +112 -0
- package/bin/branch-guard.sh +64 -0
- package/bin/brokk +73 -0
- package/bin/brokk-classify-lib.sh +1770 -0
- package/bin/brokk-lease-lib.sh +222 -0
- package/bin/brokk-lease.sh +193 -0
- package/bin/brokk-lint.sh +65 -0
- package/bin/brokk-send.sh +38 -0
- package/bin/brokk-update.sh +9 -0
- package/bin/brokk-wake-grant.sh +127 -0
- package/bin/brokk-wake-lib.sh +1849 -0
- package/bin/changelog-guard.sh +165 -0
- package/bin/crash-sense.sh +160 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +207 -0
- package/bin/eindri-acclaim.sh +34 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seen.sh +41 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +85 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +112 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/fleet-apply.sh +68 -0
- package/bin/github-deploy.sh +81 -0
- package/bin/gjallarhorn-expose.sh +102 -0
- package/bin/gjallarhorn-notify.sh +58 -0
- package/bin/gjallarhorn-purge.sh +54 -0
- package/bin/gjallarhorn-tunnel.sh +72 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +122 -0
- package/bin/hall-snapshot.sh +92 -0
- package/bin/hamr-harness.sh +246 -0
- package/bin/heimdall-ssh-keys.sh +374 -0
- package/bin/herdr-agents.py +44 -0
- package/bin/herdr-ensure.sh +104 -0
- package/bin/herdr-run.sh +431 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hoard-lib.sh +25 -0
- package/bin/hodd.sh +78 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +108 -0
- package/bin/local-model-lock.sh +51 -0
- package/bin/mimir-bridge.py +226 -0
- package/bin/mimir-bridge.sh +87 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +59 -0
- package/bin/mjollnir.sh +85 -0
- package/bin/model-hardware.sh +82 -0
- package/bin/model-resolve.sh +147 -0
- package/bin/models-detect.sh +178 -0
- package/bin/nornir-cron-start.sh +162 -0
- package/bin/nornir-job-daily-briefing.sh +191 -0
- package/bin/nornir-job-git-sync.sh +152 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +148 -0
- package/bin/omarchy-plugins.sh +174 -0
- package/bin/omarchy-sense.sh +149 -0
- package/bin/perm-guard.sh +30 -0
- package/bin/pi-agent.sh +68 -0
- package/bin/pi-ensure.sh +77 -0
- package/bin/pi-local.sh +37 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +38 -0
- package/bin/project-git.sh +55 -0
- package/bin/public-guard.sh +70 -0
- package/bin/ratatoskr.sh +49 -0
- package/bin/realm-lib.sh +32 -0
- package/bin/repo-scrub.sh +62 -0
- package/bin/rodd-operational-input.sh +250 -0
- package/bin/runes-append.sh +198 -0
- package/bin/saga-session-start.sh +172 -0
- package/bin/saga-sessionstart-run.sh +79 -0
- package/bin/saga-wake-drain.sh +41 -0
- package/bin/secret-guard.sh +63 -0
- package/bin/sessrumnir-ensure.sh +100 -0
- package/bin/sessrumnir-sync.sh +237 -0
- package/bin/sessrumnir.sh +91 -0
- package/bin/skillopt-setup.sh +76 -0
- package/bin/skuld-branch-outcome.sh +203 -0
- package/bin/skuld-branch-prompt.sh +101 -0
- package/bin/smidja-bootstrap.sh +90 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +76 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +190 -0
- package/bin/telegram-bot.sh +69 -0
- package/bin/toolchain.sh +74 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +260 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +47 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +150 -0
- package/bin/wyrd-db.sh +47 -0
- package/bin/yggdrasil.sh +152 -0
- package/bin/ymir-edit.sh +145 -0
- package/bin/ymir-install.sh +641 -0
- package/bin/ymir-invite.sh +93 -0
- package/bin/ymir-isolation.sh +88 -0
- package/bin/ymir-migrate.sh +61 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +97 -0
- package/bin/ymir-setup-auth.sh +108 -0
- package/bin/ymir-validate.sh +173 -0
- package/bin/ymir.js +74 -16
- package/docs/Architecture.md +339 -0
- package/docs/design.md +351 -0
- package/docs/installations/README.md +63 -0
- package/docs/installations/ymir-home.md +93 -0
- package/docs/integration.md +105 -0
- package/docs/lore.md +1056 -0
- package/docs/research/agent-harnesses.md +290 -0
- package/docs/runbooks/README.md +19 -0
- package/docs/runbooks/a2a.md +91 -0
- package/docs/runbooks/agent-permissions.md +99 -0
- package/docs/runbooks/agents.md +57 -0
- package/docs/runbooks/models.md +69 -0
- package/docs/runbooks/realm-onboarding.md +60 -0
- package/docs/runbooks/secrets-and-hoard.md +60 -0
- package/docs/runbooks/updates-and-migrations.md +110 -0
- package/docs/runbooks/worktrees-isolation.md +72 -0
- package/docs/session-start.md +105 -0
- package/docs/skillopt-integration.md +321 -0
- package/docs/sync-system.md +66 -0
- package/docs/workspaces.md +104 -0
- package/docs/ymir-rut.md +260 -0
- package/package.json +44 -14
- package/packaging/build.sh +74 -0
- package/packaging/macos/Ymir Installer.command +43 -0
- package/packaging/windows/ymir-setup.nsi +74 -0
- package/scripts/README.md +22 -0
- package/scripts/electron.sh +210 -0
- package/scripts/start.sh +167 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-trace-context-spawn.test.sh - spawn-path integration regressions for
|
|
3
|
+
# native W3C trace context using fake tmux panes and real isolated git worktrees.
|
|
4
|
+
# See docs/verification/trace-context.md for the maintained coverage inventory.
|
|
5
|
+
set -u
|
|
6
|
+
|
|
7
|
+
# shellcheck source=tests/lib.sh
|
|
8
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
9
|
+
# shellcheck source=/dev/null
|
|
10
|
+
. "$ROOT/bin/fm-trace-context-lib.sh"
|
|
11
|
+
|
|
12
|
+
SPAWN="$ROOT/bin/fm-spawn.sh"
|
|
13
|
+
TMP_ROOT=$(fm_test_tmproot fm-trace-context-spawn)
|
|
14
|
+
|
|
15
|
+
# Fake tmux: answers the pane-path query and logs every literal `send-keys -l`
|
|
16
|
+
# argument (the GOTMPDIR export, the TRACEPARENT export, and the launch command)
|
|
17
|
+
# one per line, in send order, so ordering is observable.
|
|
18
|
+
make_spawn_fakebin() {
|
|
19
|
+
local dir=$1 fakebin
|
|
20
|
+
fakebin=$(fm_fakebin "$dir")
|
|
21
|
+
cat > "$fakebin/tmux" <<'SH'
|
|
22
|
+
#!/usr/bin/env bash
|
|
23
|
+
set -u
|
|
24
|
+
case "$*" in
|
|
25
|
+
*"#{pane_current_path}"*) printf '%s\n' "${FM_FAKE_PANE_PATH:-}"; exit 0 ;;
|
|
26
|
+
esac
|
|
27
|
+
case "${1:-}" in
|
|
28
|
+
display-message) printf 'firstmate\n'; exit 0 ;;
|
|
29
|
+
list-windows)
|
|
30
|
+
[ -z "${FM_FAKE_DUPLICATE_WINDOW:-}" ] || printf '%s\n' "$FM_FAKE_DUPLICATE_WINDOW"
|
|
31
|
+
exit 0
|
|
32
|
+
;;
|
|
33
|
+
has-session|new-session|new-window|kill-window) exit 0 ;;
|
|
34
|
+
send-keys)
|
|
35
|
+
if [ "${FM_FAKE_TRACEPARENT_SEND_FAIL:-0}" = 1 ]; then
|
|
36
|
+
for a in "$@"; do
|
|
37
|
+
case "$a" in
|
|
38
|
+
"export TRACEPARENT="*) exit 1 ;;
|
|
39
|
+
esac
|
|
40
|
+
done
|
|
41
|
+
fi
|
|
42
|
+
if [ "${FM_FAKE_TRACEPARENT_SEND_UNSAFE:-0}" = 1 ]; then
|
|
43
|
+
for a in "$@"; do
|
|
44
|
+
case "$a" in
|
|
45
|
+
"export TRACEPARENT="*) exit 2 ;;
|
|
46
|
+
esac
|
|
47
|
+
done
|
|
48
|
+
fi
|
|
49
|
+
if [ "${FM_FAKE_TRACE_METADATA_APPEND_FAIL:-0}" = 1 ]; then
|
|
50
|
+
for a in "$@"; do
|
|
51
|
+
case "$a" in
|
|
52
|
+
"export TRACEPARENT="*)
|
|
53
|
+
chmod a-w "$FM_FAKE_META_PATH"
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
done
|
|
57
|
+
fi
|
|
58
|
+
# Capture the text payload of both send forms: the literal launch
|
|
59
|
+
# (`send-keys -t <target> -l <text>`) and a text line
|
|
60
|
+
# (`send-keys -t <target> <text> Enter`). Skip the flags, the target, and
|
|
61
|
+
# the trailing key so only the payload is logged, one per line, in order.
|
|
62
|
+
if [ -n "${FM_FAKE_LAUNCH_LOG:-}" ]; then
|
|
63
|
+
shift
|
|
64
|
+
skip_next=
|
|
65
|
+
for a in "$@"; do
|
|
66
|
+
if [ -n "$skip_next" ]; then skip_next=; continue; fi
|
|
67
|
+
case "$a" in
|
|
68
|
+
-t) skip_next=1; continue ;;
|
|
69
|
+
-l) continue ;;
|
|
70
|
+
Enter|C-m) continue ;;
|
|
71
|
+
*) printf '%s\n' "$a" >> "$FM_FAKE_LAUNCH_LOG" ;;
|
|
72
|
+
esac
|
|
73
|
+
done
|
|
74
|
+
fi
|
|
75
|
+
exit 0
|
|
76
|
+
;;
|
|
77
|
+
esac
|
|
78
|
+
exit 0
|
|
79
|
+
SH
|
|
80
|
+
chmod +x "$fakebin/tmux"
|
|
81
|
+
fm_fake_exit0 "$fakebin" treehouse
|
|
82
|
+
printf '%s\n' "$fakebin"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
make_spawn_case() {
|
|
86
|
+
local name=$1 case_dir home proj wt fakebin launchlog id
|
|
87
|
+
case_dir="$TMP_ROOT/$name"
|
|
88
|
+
home="$case_dir/home"
|
|
89
|
+
proj="$case_dir/project"
|
|
90
|
+
wt="$case_dir/wt"
|
|
91
|
+
launchlog="$case_dir/launch.log"
|
|
92
|
+
fakebin=$(make_spawn_fakebin "$case_dir/fake")
|
|
93
|
+
mkdir -p "$home/data" "$home/projects" "$home/state" "$home/config"
|
|
94
|
+
printf 'claude\n' > "$home/config/crew-harness"
|
|
95
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
96
|
+
printf '%s off\n' "$$" > "$home/state/.trace-context-effective"
|
|
97
|
+
fm_git_worktree "$proj" "$wt" "wt-$name"
|
|
98
|
+
touch "$home/state/.last-watcher-beat"
|
|
99
|
+
id=$name-z1
|
|
100
|
+
mkdir -p "$home/data/$id"
|
|
101
|
+
printf 'brief for %s\n' "$id" > "$home/data/$id/brief.md"
|
|
102
|
+
printf '%s\n' "$home|$proj|$wt|$fakebin|$launchlog|$id"
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Hermetic against an ambient FM_TRACE_CONTEXT: `env -u` unsets it so enablement
|
|
106
|
+
# is decided ONLY by the home's config/trace-context, whether the runner's own
|
|
107
|
+
# environment enables or disables trace context.
|
|
108
|
+
run_spawn() {
|
|
109
|
+
local home=$1 wt=$2 fakebin=$3 launchlog=$4
|
|
110
|
+
shift 4
|
|
111
|
+
: > "$launchlog"
|
|
112
|
+
env -u FM_TRACE_CONTEXT \
|
|
113
|
+
FM_ROOT_OVERRIDE='' FM_HOME="$home" \
|
|
114
|
+
FM_STATE_OVERRIDE="$home/state" FM_DATA_OVERRIDE="$home/data" \
|
|
115
|
+
FM_PROJECTS_OVERRIDE="$home/projects" FM_CONFIG_OVERRIDE="$home/config" \
|
|
116
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$wt" TMUX="fake,1,0" \
|
|
117
|
+
FM_FAKE_TRACEPARENT_SEND_FAIL="${FM_FAKE_TRACEPARENT_SEND_FAIL:-0}" \
|
|
118
|
+
FM_FAKE_TRACEPARENT_SEND_UNSAFE="${FM_FAKE_TRACEPARENT_SEND_UNSAFE:-0}" \
|
|
119
|
+
FM_FAKE_TRACE_METADATA_APPEND_FAIL="${FM_FAKE_TRACE_METADATA_APPEND_FAIL:-0}" \
|
|
120
|
+
FM_FAKE_META_PATH="$home/state/$1.meta" \
|
|
121
|
+
FM_FAKE_LAUNCH_LOG="$launchlog" PATH="$fakebin:$PATH" \
|
|
122
|
+
"$SPAWN" "$@" --mode no-mistakes --yolo off 2>&1
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# Same, but with an explicit FM_TRACE_CONTEXT override, to prove the env decides.
|
|
126
|
+
run_spawn_tc() {
|
|
127
|
+
local tc=$1 home=$2 wt=$3 fakebin=$4 launchlog=$5
|
|
128
|
+
shift 5
|
|
129
|
+
: > "$launchlog"
|
|
130
|
+
env FM_TRACE_CONTEXT="$tc" \
|
|
131
|
+
FM_ROOT_OVERRIDE='' FM_HOME="$home" \
|
|
132
|
+
FM_STATE_OVERRIDE="$home/state" FM_DATA_OVERRIDE="$home/data" \
|
|
133
|
+
FM_PROJECTS_OVERRIDE="$home/projects" FM_CONFIG_OVERRIDE="$home/config" \
|
|
134
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$wt" TMUX="fake,1,0" \
|
|
135
|
+
FM_FAKE_LAUNCH_LOG="$launchlog" PATH="$fakebin:$PATH" \
|
|
136
|
+
"$SPAWN" "$@" --mode no-mistakes --yolo off 2>&1
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
start_trace_session() {
|
|
140
|
+
local home=$1 tc=${2-}
|
|
141
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
142
|
+
if [ -n "$tc" ]; then
|
|
143
|
+
FM_TRACE_CONTEXT="$tc" fm_trace_context_session_start \
|
|
144
|
+
"$home/config" "$home/state/.trace-context-effective"
|
|
145
|
+
else
|
|
146
|
+
(
|
|
147
|
+
unset FM_TRACE_CONTEXT
|
|
148
|
+
fm_trace_context_session_start \
|
|
149
|
+
"$home/config" "$home/state/.trace-context-effective"
|
|
150
|
+
)
|
|
151
|
+
fi
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
read_case_record() {
|
|
155
|
+
IFS='|' read -r HOME_DIR PROJ_DIR WT_DIR FAKEBIN_DIR LAUNCH_LOG CASE_ID <<EOF
|
|
156
|
+
$1
|
|
157
|
+
EOF
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
meta_traceparent() { sed -n 's/^traceparent=//p' "$1"; }
|
|
161
|
+
injected_traceparent() { sed -n 's/^export TRACEPARENT=//p' "$1"; }
|
|
162
|
+
|
|
163
|
+
# Two-level primary -> secondmate -> worker regression for the FM_TRACE_CONTEXT
|
|
164
|
+
# effective override. Drives bin/fm-spawn.sh TWICE against real homes and a real
|
|
165
|
+
# worktree: first the primary launches a secondmate (capturing the exact env the
|
|
166
|
+
# primary injects into it), then that secondmate launches its OWN worker with
|
|
167
|
+
# exactly that inherited env, reading the secondmate home's own inherited config.
|
|
168
|
+
# This is what proves the primary's effective on/off decision - not only the
|
|
169
|
+
# copied config/trace-context file - governs the nested worker, which a
|
|
170
|
+
# single-home spawn test cannot reach. Sets TL_ENV_TC, TL_CARRIER, TL_WORKER_TP,
|
|
171
|
+
# and TL_SM_FILE for the caller.
|
|
172
|
+
# run_two_level <name> <present|absent primary file> <on|off primary env>
|
|
173
|
+
run_two_level() {
|
|
174
|
+
local name=$1 pfile=$2 penv=$3
|
|
175
|
+
local base prim sm sm_id smlog smfake worker_id wproj wwt wlog wfake
|
|
176
|
+
base="$TMP_ROOT/2level-$name"
|
|
177
|
+
prim="$base/primary"
|
|
178
|
+
sm="$base/sm"
|
|
179
|
+
mkdir -p "$prim/config" "$prim/data" "$prim/state" "$prim/projects"
|
|
180
|
+
printf 'claude\n' > "$prim/config/crew-harness"
|
|
181
|
+
[ "$pfile" = present ] && : > "$prim/config/trace-context"
|
|
182
|
+
touch "$prim/state/.last-watcher-beat"
|
|
183
|
+
start_trace_session "$prim" "$penv"
|
|
184
|
+
|
|
185
|
+
# Seed the secondmate home so validate_firstmate_home_for_spawn accepts it.
|
|
186
|
+
mkdir -p "$sm/bin" "$sm/data"
|
|
187
|
+
printf '# Firstmate\n' > "$sm/AGENTS.md"
|
|
188
|
+
printf 'sm-%s\n' "$name" > "$sm/.fm-secondmate-home"
|
|
189
|
+
printf 'charter\n' > "$sm/data/charter.md"
|
|
190
|
+
|
|
191
|
+
# Spawn 1: the primary launches the secondmate; capture what it injects.
|
|
192
|
+
sm_id="sm-$name"
|
|
193
|
+
mkdir -p "$prim/data/$sm_id"
|
|
194
|
+
printf 'charter brief\n' > "$prim/data/$sm_id/brief.md"
|
|
195
|
+
smlog="$base/sm-launch.log"
|
|
196
|
+
smfake=$(make_spawn_fakebin "$base/sm-fake")
|
|
197
|
+
: > "$smlog"
|
|
198
|
+
env FM_TRACE_CONTEXT="$penv" \
|
|
199
|
+
FM_ROOT_OVERRIDE="$ROOT" FM_HOME="$prim" \
|
|
200
|
+
FM_STATE_OVERRIDE="$prim/state" FM_DATA_OVERRIDE="$prim/data" \
|
|
201
|
+
FM_PROJECTS_OVERRIDE="$prim/projects" FM_CONFIG_OVERRIDE="$prim/config" \
|
|
202
|
+
FM_SPAWN_NO_GUARD=1 CLAUDECODE=1 TMUX="fake,1,0" \
|
|
203
|
+
FM_FAKE_LAUNCH_LOG="$smlog" PATH="$smfake:$PATH" \
|
|
204
|
+
"$SPAWN" "$sm_id" "$sm" --secondmate >/dev/null 2>&1 || true
|
|
205
|
+
|
|
206
|
+
# Extract the EXACT env the primary put on the secondmate: the normalized
|
|
207
|
+
# FM_TRACE_CONTEXT in the launch prefix, and the TRACEPARENT carrier (if any).
|
|
208
|
+
TL_ENV_TC=$(grep -o 'FM_TRACE_CONTEXT=[a-z]*' "$smlog" | head -1 | cut -d= -f2)
|
|
209
|
+
TL_CARRIER=$(injected_traceparent "$smlog" | head -1)
|
|
210
|
+
|
|
211
|
+
# Spawn 2: the secondmate launches its own worker with exactly that inherited
|
|
212
|
+
# env, reading the secondmate home's own (inherited) config.
|
|
213
|
+
worker_id="w-$name"
|
|
214
|
+
wproj="$base/wproj"
|
|
215
|
+
wwt="$base/wwt"
|
|
216
|
+
fm_git_worktree "$wproj" "$wwt" "wt-$name"
|
|
217
|
+
mkdir -p "$sm/state" "$sm/projects" "$sm/data/$worker_id"
|
|
218
|
+
printf 'worker brief\n' > "$sm/data/$worker_id/brief.md"
|
|
219
|
+
touch "$sm/state/.last-watcher-beat"
|
|
220
|
+
start_trace_session "$sm" "$TL_ENV_TC"
|
|
221
|
+
wlog="$base/worker-launch.log"
|
|
222
|
+
wfake=$(make_spawn_fakebin "$base/w-fake")
|
|
223
|
+
: > "$wlog"
|
|
224
|
+
env FM_TRACE_CONTEXT="$TL_ENV_TC" TRACEPARENT="$TL_CARRIER" \
|
|
225
|
+
FM_ROOT_OVERRIDE="$ROOT" FM_HOME="$sm" \
|
|
226
|
+
FM_STATE_OVERRIDE="$sm/state" FM_DATA_OVERRIDE="$sm/data" \
|
|
227
|
+
FM_PROJECTS_OVERRIDE="$sm/projects" FM_CONFIG_OVERRIDE="$sm/config" \
|
|
228
|
+
FM_SPAWN_NO_GUARD=1 FM_FAKE_PANE_PATH="$wwt" TMUX="fake,1,0" \
|
|
229
|
+
FM_FAKE_LAUNCH_LOG="$wlog" PATH="$wfake:$PATH" \
|
|
230
|
+
"$SPAWN" "$worker_id" "$wproj" --mode no-mistakes --yolo off >/dev/null 2>&1 || true
|
|
231
|
+
|
|
232
|
+
TL_WORKER_TP=$(meta_traceparent "$sm/state/$worker_id.meta")
|
|
233
|
+
TL_SM_FILE=absent
|
|
234
|
+
[ -f "$sm/config/trace-context" ] && TL_SM_FILE=present
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
test_enabled_records_and_injects_identical_carrier_before_launch() {
|
|
238
|
+
local rec out status meta mtp itp gl tl ll
|
|
239
|
+
rec=$(make_spawn_case tc-on)
|
|
240
|
+
read_case_record "$rec"
|
|
241
|
+
: > "$HOME_DIR/config/trace-context" # enable via the real config path
|
|
242
|
+
start_trace_session "$HOME_DIR"
|
|
243
|
+
|
|
244
|
+
out=$(run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
245
|
+
status=$?
|
|
246
|
+
expect_code 0 "$status" "enabled trace-context spawn should succeed"
|
|
247
|
+
assert_contains "$out" "spawned $CASE_ID" "enabled spawn should report success"
|
|
248
|
+
meta="$HOME_DIR/state/$CASE_ID.meta"
|
|
249
|
+
jq -e --arg id "$CASE_ID" '
|
|
250
|
+
.schema == "fm-secondmate-home-summary.v1"
|
|
251
|
+
and any(.endpoints[]; .id == $id)
|
|
252
|
+
' "$HOME_DIR/state/home-summary.json" >/dev/null \
|
|
253
|
+
|| fail "successful task spawn did not publish the task in the home summary ledger"
|
|
254
|
+
|
|
255
|
+
mtp=$(meta_traceparent "$meta")
|
|
256
|
+
fm_trace_context_valid "$mtp" || fail "enabled spawn must record a valid traceparent= in meta (got '$mtp')"
|
|
257
|
+
itp=$(injected_traceparent "$LAUNCH_LOG")
|
|
258
|
+
fm_trace_context_valid "$itp" || fail "enabled spawn must inject a valid TRACEPARENT export (got '$itp')"
|
|
259
|
+
[ "$mtp" = "$itp" ] || fail "the recorded and injected carriers must be identical (meta='$mtp' injected='$itp')"
|
|
260
|
+
|
|
261
|
+
gl=$(grep -n '^export GOTMPDIR=' "$LAUNCH_LOG" | tail -1 | cut -d: -f1)
|
|
262
|
+
tl=$(grep -n '^export TRACEPARENT=' "$LAUNCH_LOG" | tail -1 | cut -d: -f1)
|
|
263
|
+
ll=$(grep -n 'claude' "$LAUNCH_LOG" | tail -1 | cut -d: -f1)
|
|
264
|
+
[ -n "$gl" ] && [ -n "$tl" ] && [ -n "$ll" ] || fail "launch log missing GOTMPDIR/TRACEPARENT/launch lines"
|
|
265
|
+
[ "$tl" -gt "$gl" ] || fail "TRACEPARENT export must ride the GOTMPDIR pre-launch site (gotmp=$gl tp=$tl)"
|
|
266
|
+
[ "$tl" -lt "$ll" ] || fail "TRACEPARENT export must be sent before the launch literal (tp=$tl launch=$ll)"
|
|
267
|
+
pass "enabled: one resolved carrier is recorded in meta and the identical TRACEPARENT is exported before launch"
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
test_disabled_writes_and_injects_neither() {
|
|
271
|
+
local rec out status meta
|
|
272
|
+
rec=$(make_spawn_case tc-off)
|
|
273
|
+
read_case_record "$rec"
|
|
274
|
+
# No config/trace-context and no FM_TRACE_CONTEXT: default-off.
|
|
275
|
+
|
|
276
|
+
out=$(run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
277
|
+
status=$?
|
|
278
|
+
expect_code 0 "$status" "default-off spawn should succeed"
|
|
279
|
+
assert_contains "$out" "spawned $CASE_ID" "default-off spawn should report success"
|
|
280
|
+
meta="$HOME_DIR/state/$CASE_ID.meta"
|
|
281
|
+
|
|
282
|
+
# Anchored regex checks (the assert_grep helpers are fixed-string).
|
|
283
|
+
! grep -q '^traceparent=' "$meta" || fail "default-off spawn must not write a traceparent= line to meta"
|
|
284
|
+
! grep -q '^export TRACEPARENT=' "$LAUNCH_LOG" || fail "default-off spawn must not inject a TRACEPARENT export"
|
|
285
|
+
grep -q '^export GOTMPDIR=' "$LAUNCH_LOG" || fail "the spawn should still run (GOTMPDIR is always injected)"
|
|
286
|
+
pass "disabled: neither traceparent= in meta nor a TRACEPARENT export is produced"
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
test_failed_delivery_omits_metadata_and_still_launches() {
|
|
290
|
+
local rec out status meta
|
|
291
|
+
rec=$(make_spawn_case tc-send-failure)
|
|
292
|
+
read_case_record "$rec"
|
|
293
|
+
: > "$HOME_DIR/config/trace-context"
|
|
294
|
+
start_trace_session "$HOME_DIR"
|
|
295
|
+
|
|
296
|
+
out=$(FM_FAKE_TRACEPARENT_SEND_FAIL=1 \
|
|
297
|
+
run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
298
|
+
status=$?
|
|
299
|
+
expect_code 0 "$status" "failed traceparent delivery must not abort spawn"
|
|
300
|
+
assert_contains "$out" "spawned $CASE_ID" "spawn should report success after failed traceparent delivery"
|
|
301
|
+
meta="$HOME_DIR/state/$CASE_ID.meta"
|
|
302
|
+
|
|
303
|
+
! grep -q '^traceparent=' "$meta" \
|
|
304
|
+
|| fail "failed traceparent delivery must not leave a traceparent= claim in meta"
|
|
305
|
+
! grep -q '^export TRACEPARENT=' "$LAUNCH_LOG" \
|
|
306
|
+
|| fail "the failed TRACEPARENT export must not be recorded as delivered"
|
|
307
|
+
grep -q 'claude' "$LAUNCH_LOG" || fail "the source task must still launch"
|
|
308
|
+
pass "failed TRACEPARENT delivery omits metadata while the source task still launches"
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
test_unsafe_delivery_refuses_to_append_launch() {
|
|
312
|
+
local rec out status
|
|
313
|
+
rec=$(make_spawn_case tc-send-unsafe)
|
|
314
|
+
read_case_record "$rec"
|
|
315
|
+
: > "$HOME_DIR/config/trace-context"
|
|
316
|
+
start_trace_session "$HOME_DIR"
|
|
317
|
+
|
|
318
|
+
out=$(FM_FAKE_TRACEPARENT_SEND_UNSAFE=1 \
|
|
319
|
+
run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
320
|
+
status=$?
|
|
321
|
+
[ "$status" -ne 0 ] || fail "uncleared traceparent input must stop spawn"
|
|
322
|
+
assert_contains "$out" "refusing to append the launch command" \
|
|
323
|
+
"unsafe traceparent delivery should report why spawn stopped"
|
|
324
|
+
! grep -q 'claude' "$LAUNCH_LOG" \
|
|
325
|
+
|| fail "unsafe traceparent delivery must not append the launch command"
|
|
326
|
+
pass "uncleared TRACEPARENT input stops before the launch command is appended"
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
test_failed_metadata_append_unsets_carrier_and_still_launches() {
|
|
330
|
+
local rec out status meta
|
|
331
|
+
rec=$(make_spawn_case tc-metadata-failure)
|
|
332
|
+
read_case_record "$rec"
|
|
333
|
+
: > "$HOME_DIR/config/trace-context"
|
|
334
|
+
start_trace_session "$HOME_DIR"
|
|
335
|
+
|
|
336
|
+
out=$(FM_FAKE_TRACE_METADATA_APPEND_FAIL=1 \
|
|
337
|
+
run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
338
|
+
status=$?
|
|
339
|
+
expect_code 0 "$status" "failed traceparent metadata append must not abort spawn"
|
|
340
|
+
assert_contains "$out" "spawned $CASE_ID" "spawn should report success after failed metadata append"
|
|
341
|
+
meta="$HOME_DIR/state/$CASE_ID.meta"
|
|
342
|
+
|
|
343
|
+
! grep -q '^traceparent=' "$meta" \
|
|
344
|
+
|| fail "failed metadata append must not leave a traceparent= claim in meta"
|
|
345
|
+
grep -q '^unset TRACEPARENT; .*claude' "$LAUNCH_LOG" \
|
|
346
|
+
|| fail "failed metadata append must unset TRACEPARENT in the launch command"
|
|
347
|
+
pass "failed traceparent metadata append removes the carrier from the launched task"
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
test_duplicate_secondmate_spawn_does_not_converge_trace_context() {
|
|
351
|
+
local base prim sm id log fake out status
|
|
352
|
+
base="$TMP_ROOT/duplicate-secondmate"
|
|
353
|
+
prim="$base/primary"
|
|
354
|
+
sm="$base/sm"
|
|
355
|
+
# shellcheck disable=SC2100 # Literal task id, not arithmetic.
|
|
356
|
+
id=sm-duplicate
|
|
357
|
+
log="$base/launch.log"
|
|
358
|
+
mkdir -p "$prim/config" "$prim/data/$id" "$prim/state" "$prim/projects"
|
|
359
|
+
: > "$prim/config/trace-context"
|
|
360
|
+
printf 'charter brief\n' > "$prim/data/$id/brief.md"
|
|
361
|
+
touch "$prim/state/.last-watcher-beat"
|
|
362
|
+
start_trace_session "$prim"
|
|
363
|
+
mkdir -p "$sm/bin" "$sm/data"
|
|
364
|
+
printf '# Firstmate\n' > "$sm/AGENTS.md"
|
|
365
|
+
printf '%s\n' "$id" > "$sm/.fm-secondmate-home"
|
|
366
|
+
printf 'charter\n' > "$sm/data/charter.md"
|
|
367
|
+
fake=$(make_spawn_fakebin "$base/fake")
|
|
368
|
+
|
|
369
|
+
out=$(env -u FM_TRACE_CONTEXT \
|
|
370
|
+
FM_ROOT_OVERRIDE="$ROOT" FM_HOME="$prim" \
|
|
371
|
+
FM_STATE_OVERRIDE="$prim/state" FM_DATA_OVERRIDE="$prim/data" \
|
|
372
|
+
FM_PROJECTS_OVERRIDE="$prim/projects" FM_CONFIG_OVERRIDE="$prim/config" \
|
|
373
|
+
FM_SPAWN_NO_GUARD=1 CLAUDECODE=1 TMUX="fake,1,0" \
|
|
374
|
+
FM_FAKE_DUPLICATE_WINDOW="fm-$id" FM_FAKE_LAUNCH_LOG="$log" \
|
|
375
|
+
PATH="$fake:$PATH" "$SPAWN" "$id" "$sm" --secondmate 2>&1)
|
|
376
|
+
status=$?
|
|
377
|
+
|
|
378
|
+
[ "$status" -ne 0 ] || fail "duplicate secondmate spawn should be refused"
|
|
379
|
+
assert_contains "$out" "already exists" "duplicate secondmate spawn should report the existing endpoint"
|
|
380
|
+
[ ! -e "$sm/config/trace-context" ] \
|
|
381
|
+
|| fail "duplicate preflight must not converge trace-context into the secondmate home"
|
|
382
|
+
pass "duplicate secondmate preflight leaves trace-context unchanged"
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
test_relaunch_reuses_recorded_carrier() {
|
|
386
|
+
local rec out status meta first second injected
|
|
387
|
+
rec=$(make_spawn_case tc-relaunch)
|
|
388
|
+
read_case_record "$rec"
|
|
389
|
+
: > "$HOME_DIR/config/trace-context"
|
|
390
|
+
start_trace_session "$HOME_DIR"
|
|
391
|
+
meta="$HOME_DIR/state/$CASE_ID.meta"
|
|
392
|
+
|
|
393
|
+
out=$(run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
394
|
+
status=$?
|
|
395
|
+
expect_code 0 "$status" "first trace-context spawn should succeed"
|
|
396
|
+
assert_contains "$out" "spawned $CASE_ID" "first spawn should report success"
|
|
397
|
+
first=$(meta_traceparent "$meta")
|
|
398
|
+
fm_trace_context_valid "$first" || fail "first spawn must record a valid carrier (got '$first')"
|
|
399
|
+
|
|
400
|
+
# Relaunch the same task: the recorded carrier must be reused verbatim for both
|
|
401
|
+
# the meta and the injected export, so an observer keeps one identity across
|
|
402
|
+
# restarts.
|
|
403
|
+
out=$(run_spawn "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
404
|
+
status=$?
|
|
405
|
+
expect_code 0 "$status" "relaunch spawn should succeed"
|
|
406
|
+
assert_contains "$out" "spawned $CASE_ID" "relaunch spawn should report success"
|
|
407
|
+
second=$(meta_traceparent "$meta")
|
|
408
|
+
injected=$(injected_traceparent "$LAUNCH_LOG")
|
|
409
|
+
[ "$second" = "$first" ] || fail "relaunch must reuse the recorded carrier in meta (first='$first' second='$second')"
|
|
410
|
+
[ "$injected" = "$first" ] || fail "relaunch must inject the same recorded carrier (first='$first' injected='$injected')"
|
|
411
|
+
pass "relaunch reuses the recorded carrier verbatim for both the meta record and the injected export"
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
test_session_start_freezes_env_override_and_ignores_later_edits() {
|
|
415
|
+
local rec out status meta
|
|
416
|
+
rec=$(make_spawn_case tc-envoff)
|
|
417
|
+
read_case_record "$rec"
|
|
418
|
+
: > "$HOME_DIR/config/trace-context"
|
|
419
|
+
start_trace_session "$HOME_DIR" off
|
|
420
|
+
out=$(run_spawn_tc on "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
421
|
+
status=$?
|
|
422
|
+
expect_code 0 "$status" "env-off spawn should succeed"
|
|
423
|
+
assert_contains "$out" "spawned $CASE_ID" "env-off spawn should report success"
|
|
424
|
+
meta="$HOME_DIR/state/$CASE_ID.meta"
|
|
425
|
+
! grep -q '^traceparent=' "$meta" || fail "session-frozen off must ignore a later FM_TRACE_CONTEXT=on"
|
|
426
|
+
! grep -q '^export TRACEPARENT=' "$LAUNCH_LOG" || fail "session-frozen off must remain disabled after launch-time edits"
|
|
427
|
+
|
|
428
|
+
rec=$(make_spawn_case tc-envon)
|
|
429
|
+
read_case_record "$rec"
|
|
430
|
+
start_trace_session "$HOME_DIR" on
|
|
431
|
+
: > "$HOME_DIR/config/trace-context"
|
|
432
|
+
out=$(run_spawn_tc off "$HOME_DIR" "$WT_DIR" "$FAKEBIN_DIR" "$LAUNCH_LOG" "$CASE_ID" "$PROJ_DIR")
|
|
433
|
+
status=$?
|
|
434
|
+
expect_code 0 "$status" "env-on spawn should succeed"
|
|
435
|
+
meta="$HOME_DIR/state/$CASE_ID.meta"
|
|
436
|
+
fm_trace_context_valid "$(meta_traceparent "$meta")" \
|
|
437
|
+
|| fail "session-frozen on must ignore a later FM_TRACE_CONTEXT=off"
|
|
438
|
+
pass "session start freezes the env override and later config or environment edits do not alter spawns"
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
# End-to-end two-level enable path: the primary is enabled by the environment
|
|
442
|
+
# override with NO config file, and that enablement must reach the newly launched
|
|
443
|
+
# secondmate's own worker. Before the effective-override fix, the secondmate saw
|
|
444
|
+
# only the (absent) inherited file and left its worker untraced despite holding
|
|
445
|
+
# the delivered carrier. Enablement is what propagates; trace identity is not:
|
|
446
|
+
# the worker is a routed task with its own trace boundary, so it must root a
|
|
447
|
+
# fresh trace rather than adopt the Secondmate's carrier from the environment.
|
|
448
|
+
test_secondmate_env_on_file_absent_keeps_nested_worker_enabled() {
|
|
449
|
+
run_two_level enable absent on
|
|
450
|
+
[ "$TL_ENV_TC" = on ] || fail "the primary must deliver FM_TRACE_CONTEXT=on to the secondmate (got '$TL_ENV_TC')"
|
|
451
|
+
fm_trace_context_valid "$TL_CARRIER" || fail "an enabled primary must mint a carrier for the secondmate (got '$TL_CARRIER')"
|
|
452
|
+
fm_trace_context_valid "$TL_WORKER_TP" \
|
|
453
|
+
|| fail "env-on/file-absent must keep the nested worker enabled (got '$TL_WORKER_TP')"
|
|
454
|
+
[ "${TL_CARRIER:3:32}" != "${TL_WORKER_TP:3:32}" ] \
|
|
455
|
+
|| fail "the nested worker must root its own trace, not adopt the Secondmate's trace id (secondmate='${TL_CARRIER:3:32}' worker='${TL_WORKER_TP:3:32}')"
|
|
456
|
+
pass "two-level: env-on/file-absent keeps the nested worker enabled, rooting its own per-task trace"
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
# End-to-end two-level disable path: the primary is disabled by the environment
|
|
460
|
+
# override while the config file is PRESENT (so it is copied into the secondmate
|
|
461
|
+
# home). The override must still disable the secondmate's own worker, or
|
|
462
|
+
# FM_TRACE_CONTEXT=off is not a real kill switch. Before the fix the copied file
|
|
463
|
+
# re-enabled the nested worker.
|
|
464
|
+
test_secondmate_env_off_file_present_keeps_nested_worker_disabled() {
|
|
465
|
+
run_two_level disable present off
|
|
466
|
+
[ "$TL_ENV_TC" = off ] || fail "the primary must deliver FM_TRACE_CONTEXT=off to the secondmate (got '$TL_ENV_TC')"
|
|
467
|
+
[ -z "$TL_CARRIER" ] || fail "a disabled primary must inject no carrier into the secondmate (got '$TL_CARRIER')"
|
|
468
|
+
[ "$TL_SM_FILE" = present ] \
|
|
469
|
+
|| fail "the disable case must exercise a copied config/trace-context in the secondmate home (got '$TL_SM_FILE')"
|
|
470
|
+
[ -z "$TL_WORKER_TP" ] \
|
|
471
|
+
|| fail "env-off must keep the nested worker disabled even with the file present (got '$TL_WORKER_TP')"
|
|
472
|
+
pass "two-level: env-off/file-present keeps the nested worker disabled even though the config file was copied into the secondmate home"
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
# The trace boundary is each routed task, not the routing agent: a persistent
|
|
476
|
+
# Secondmate exports one TRACEPARENT into its process environment at its own
|
|
477
|
+
# launch, and later routed requests never replace that environment. Two
|
|
478
|
+
# unrelated tasks spawned sequentially from that one environment must root two
|
|
479
|
+
# distinct traces, and neither may adopt the Secondmate's own trace id, while
|
|
480
|
+
# each task still keeps one stable identity across its own relaunch.
|
|
481
|
+
test_two_routed_tasks_through_one_secondmate_root_distinct_traces() {
|
|
482
|
+
local base sm fakebin sm_tp out status
|
|
483
|
+
local id_a id_b proj_a proj_b wt_a wt_b log_a log_b
|
|
484
|
+
local tp_a tp_b in_a in_b relaunch_tp relaunch_in
|
|
485
|
+
base="$TMP_ROOT/routed-boundary"
|
|
486
|
+
sm="$base/sm-home"
|
|
487
|
+
mkdir -p "$sm/data" "$sm/projects" "$sm/state" "$sm/config"
|
|
488
|
+
printf 'claude\n' > "$sm/config/crew-harness"
|
|
489
|
+
: > "$sm/config/trace-context"
|
|
490
|
+
printf '%s\n' "$$" > "$sm/state/.lock"
|
|
491
|
+
touch "$sm/state/.last-watcher-beat"
|
|
492
|
+
start_trace_session "$sm"
|
|
493
|
+
# The Secondmate's own launch-time carrier: exported once into its pane shell
|
|
494
|
+
# by the primary's spawn and inherited by every subprocess for the process's
|
|
495
|
+
# whole life. Fixed here so any adoption of its trace id is unambiguous.
|
|
496
|
+
sm_tp='00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab-bbbbbbbbbbbbbbbb-01'
|
|
497
|
+
fakebin=$(make_spawn_fakebin "$base/fake")
|
|
498
|
+
|
|
499
|
+
id_a=routed-a-z1
|
|
500
|
+
id_b=routed-b-z1
|
|
501
|
+
proj_a="$base/proj-a"; wt_a="$base/wt-a"
|
|
502
|
+
proj_b="$base/proj-b"; wt_b="$base/wt-b"
|
|
503
|
+
fm_git_worktree "$proj_a" "$wt_a" wt-routed-a
|
|
504
|
+
fm_git_worktree "$proj_b" "$wt_b" wt-routed-b
|
|
505
|
+
mkdir -p "$sm/data/$id_a" "$sm/data/$id_b"
|
|
506
|
+
printf 'brief a\n' > "$sm/data/$id_a/brief.md"
|
|
507
|
+
printf 'brief b\n' > "$sm/data/$id_b/brief.md"
|
|
508
|
+
log_a="$base/launch-a.log"
|
|
509
|
+
log_b="$base/launch-b.log"
|
|
510
|
+
|
|
511
|
+
out=$(TRACEPARENT="$sm_tp" run_spawn "$sm" "$wt_a" "$fakebin" "$log_a" "$id_a" "$proj_a")
|
|
512
|
+
status=$?
|
|
513
|
+
expect_code 0 "$status" "routed task A spawn should succeed"
|
|
514
|
+
assert_contains "$out" "spawned $id_a" "routed task A spawn should report success"
|
|
515
|
+
out=$(TRACEPARENT="$sm_tp" run_spawn "$sm" "$wt_b" "$fakebin" "$log_b" "$id_b" "$proj_b")
|
|
516
|
+
status=$?
|
|
517
|
+
expect_code 0 "$status" "routed task B spawn should succeed"
|
|
518
|
+
assert_contains "$out" "spawned $id_b" "routed task B spawn should report success"
|
|
519
|
+
|
|
520
|
+
tp_a=$(meta_traceparent "$sm/state/$id_a.meta")
|
|
521
|
+
tp_b=$(meta_traceparent "$sm/state/$id_b.meta")
|
|
522
|
+
in_a=$(injected_traceparent "$log_a")
|
|
523
|
+
in_b=$(injected_traceparent "$log_b")
|
|
524
|
+
fm_trace_context_valid "$tp_a" || fail "routed task A must record a valid carrier (got '$tp_a')"
|
|
525
|
+
fm_trace_context_valid "$tp_b" || fail "routed task B must record a valid carrier (got '$tp_b')"
|
|
526
|
+
[ "$in_a" = "$tp_a" ] || fail "task A's injected and recorded carriers must match (injected='$in_a' meta='$tp_a')"
|
|
527
|
+
[ "$in_b" = "$tp_b" ] || fail "task B's injected and recorded carriers must match (injected='$in_b' meta='$tp_b')"
|
|
528
|
+
[ "${tp_a:3:32}" != "${sm_tp:3:32}" ] \
|
|
529
|
+
|| fail "routed task A must not adopt the persistent Secondmate's trace id (got '$tp_a')"
|
|
530
|
+
[ "${tp_b:3:32}" != "${sm_tp:3:32}" ] \
|
|
531
|
+
|| fail "routed task B must not adopt the persistent Secondmate's trace id (got '$tp_b')"
|
|
532
|
+
[ "${tp_a:3:32}" != "${tp_b:3:32}" ] \
|
|
533
|
+
|| fail "two unrelated routed tasks must root distinct trace ids (A='$tp_a' B='$tp_b')"
|
|
534
|
+
|
|
535
|
+
# Same environment, same task: a relaunch must reuse task A's recorded
|
|
536
|
+
# carrier verbatim, so the per-task boundary never costs recovery identity.
|
|
537
|
+
out=$(TRACEPARENT="$sm_tp" run_spawn "$sm" "$wt_a" "$fakebin" "$log_a" "$id_a" "$proj_a")
|
|
538
|
+
status=$?
|
|
539
|
+
expect_code 0 "$status" "routed task A relaunch should succeed"
|
|
540
|
+
relaunch_tp=$(meta_traceparent "$sm/state/$id_a.meta")
|
|
541
|
+
relaunch_in=$(injected_traceparent "$log_a")
|
|
542
|
+
[ "$relaunch_tp" = "$tp_a" ] \
|
|
543
|
+
|| fail "task A's relaunch must keep its original carrier (first='$tp_a' relaunch='$relaunch_tp')"
|
|
544
|
+
[ "$relaunch_in" = "$tp_a" ] \
|
|
545
|
+
|| fail "task A's relaunch must inject its original carrier (first='$tp_a' injected='$relaunch_in')"
|
|
546
|
+
pass "two unrelated routed tasks through one persistent Secondmate root distinct traces, adopt nothing from its environment, and keep per-task identity across relaunch"
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
# Single-frozen-decision guarantee: for a secondmate spawn the recorded/injected
|
|
550
|
+
# carrier and the delivered FM_TRACE_CONTEXT snapshot are always derived from ONE
|
|
551
|
+
# effective decision, so they cannot disagree (no carrier paired with off, no
|
|
552
|
+
# off snapshot paired with a carrier). This drives the file-decided path
|
|
553
|
+
# (FM_TRACE_CONTEXT unset), which is exactly where the two-read correction matters
|
|
554
|
+
# because the environment override is empty and only the config file decides.
|
|
555
|
+
test_secondmate_carrier_and_snapshot_share_one_decision() {
|
|
556
|
+
run_two_level fileon present ""
|
|
557
|
+
[ "$TL_ENV_TC" = on ] || fail "a file-enabled secondmate must snapshot FM_TRACE_CONTEXT=on (got '$TL_ENV_TC')"
|
|
558
|
+
fm_trace_context_valid "$TL_CARRIER" \
|
|
559
|
+
|| fail "a file-enabled secondmate's carrier must be present and valid, consistent with the on snapshot (got '$TL_CARRIER')"
|
|
560
|
+
|
|
561
|
+
run_two_level fileoff absent ""
|
|
562
|
+
[ "$TL_ENV_TC" = off ] || fail "a file-disabled secondmate must snapshot FM_TRACE_CONTEXT=off (got '$TL_ENV_TC')"
|
|
563
|
+
[ -z "$TL_CARRIER" ] \
|
|
564
|
+
|| fail "a file-disabled secondmate must inject no carrier, consistent with the off snapshot (got '$TL_CARRIER')"
|
|
565
|
+
pass "secondmate carrier and FM_TRACE_CONTEXT snapshot always agree, both derived from one frozen decision (file-decided path)"
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
test_enabled_records_and_injects_identical_carrier_before_launch
|
|
569
|
+
test_disabled_writes_and_injects_neither
|
|
570
|
+
test_failed_delivery_omits_metadata_and_still_launches
|
|
571
|
+
test_unsafe_delivery_refuses_to_append_launch
|
|
572
|
+
test_failed_metadata_append_unsets_carrier_and_still_launches
|
|
573
|
+
test_duplicate_secondmate_spawn_does_not_converge_trace_context
|
|
574
|
+
test_relaunch_reuses_recorded_carrier
|
|
575
|
+
test_session_start_freezes_env_override_and_ignores_later_edits
|
|
576
|
+
test_secondmate_env_on_file_absent_keeps_nested_worker_enabled
|
|
577
|
+
test_secondmate_env_off_file_present_keeps_nested_worker_disabled
|
|
578
|
+
test_two_routed_tasks_through_one_secondmate_root_distinct_traces
|
|
579
|
+
test_secondmate_carrier_and_snapshot_share_one_decision
|
|
580
|
+
|
|
581
|
+
echo "# all fm-trace-context-spawn tests passed"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-transition-lib.test.sh - unit tests for the shared, backend-neutral
|
|
3
|
+
# normalized-transition shape and the single-owner status->action policy table
|
|
4
|
+
# (bin/fm-transition-lib.sh). Pure functions, no backend required.
|
|
5
|
+
set -u
|
|
6
|
+
|
|
7
|
+
# shellcheck source=tests/lib.sh
|
|
8
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
9
|
+
|
|
10
|
+
# shellcheck source=/dev/null
|
|
11
|
+
. "$ROOT/bin/fm-transition-lib.sh"
|
|
12
|
+
|
|
13
|
+
# --- record construction + accessors ----------------------------------------
|
|
14
|
+
|
|
15
|
+
REC=$(fm_transition_record "wG:pQ" "wG" "" "blocked" "claude")
|
|
16
|
+
[ "$(fm_transition_pane_id "$REC")" = "wG:pQ" ] || fail "pane_id accessor wrong: $REC"
|
|
17
|
+
[ "$(fm_transition_workspace_id "$REC")" = "wG" ] || fail "workspace_id accessor wrong: $REC"
|
|
18
|
+
[ "$(fm_transition_from_status "$REC")" = "" ] || fail "from_status should be empty: $REC"
|
|
19
|
+
[ "$(fm_transition_to_status "$REC")" = "blocked" ] || fail "to_status accessor wrong: $REC"
|
|
20
|
+
[ "$(fm_transition_agent "$REC")" = "claude" ] || fail "agent accessor wrong: $REC"
|
|
21
|
+
pass "fm_transition_record builds a 5-field record and every accessor reads its field"
|
|
22
|
+
|
|
23
|
+
# The record is exactly TAB-separated (five fields, four tabs).
|
|
24
|
+
TABS=$(printf '%s' "$REC" | tr -cd '\t' | wc -c | tr -d '[:space:]')
|
|
25
|
+
[ "$TABS" = "4" ] || fail "record must have exactly 4 TAB separators, got $TABS"
|
|
26
|
+
pass "fm_transition_record uses a single TAB between each of the five fields"
|
|
27
|
+
|
|
28
|
+
# A field containing a stray TAB/newline is scrubbed to spaces so the record
|
|
29
|
+
# never desyncs into more than five fields.
|
|
30
|
+
DIRTY=$(fm_transition_record "wG:pQ" "wG" "" "blocked" $'multi\tline\nagent')
|
|
31
|
+
DIRTY_TABS=$(printf '%s' "$DIRTY" | tr -cd '\t' | wc -c | tr -d '[:space:]')
|
|
32
|
+
[ "$DIRTY_TABS" = "4" ] || fail "a field with a stray TAB must not add columns, got $DIRTY_TABS tabs"
|
|
33
|
+
[ "$(fm_transition_to_status "$DIRTY")" = "blocked" ] || fail "stray-field scrub desynced to_status: $DIRTY"
|
|
34
|
+
pass "fm_transition_record scrubs TAB/newline out of fields so the record stays exactly five columns"
|
|
35
|
+
|
|
36
|
+
# Empty optional fields are allowed (herdr leaves workspace/agent empty on the
|
|
37
|
+
# reconcile path).
|
|
38
|
+
REC2=$(fm_transition_record "w1:p3" "" "" "working" "")
|
|
39
|
+
[ "$(fm_transition_pane_id "$REC2")" = "w1:p3" ] || fail "pane_id wrong with empty optionals: $REC2"
|
|
40
|
+
[ "$(fm_transition_to_status "$REC2")" = "working" ] || fail "to_status wrong with empty optionals: $REC2"
|
|
41
|
+
pass "fm_transition_record tolerates empty workspace/from/agent fields"
|
|
42
|
+
|
|
43
|
+
# --- the single-owner policy table ------------------------------------------
|
|
44
|
+
|
|
45
|
+
[ "$(fm_transition_policy blocked)" = "actionable" ] || fail "blocked must be actionable"
|
|
46
|
+
[ "$(fm_transition_policy working)" = "absorb" ] || fail "working must be absorb"
|
|
47
|
+
[ "$(fm_transition_policy idle)" = "defer" ] || fail "idle must be defer"
|
|
48
|
+
[ "$(fm_transition_policy "done")" = "defer" ] || fail "done must be defer"
|
|
49
|
+
[ "$(fm_transition_policy unknown)" = "fallback" ] || fail "unknown must be fallback"
|
|
50
|
+
[ "$(fm_transition_policy "")" = "fallback" ] || fail "empty status must be fallback"
|
|
51
|
+
[ "$(fm_transition_policy some-future-status)" = "fallback" ] || fail "an unrecognized status must be fallback"
|
|
52
|
+
pass "fm_transition_policy is the single-owner status->action table (blocked=actionable, working=absorb, idle/done=defer, else=fallback)"
|
|
53
|
+
|
|
54
|
+
echo "# fm-transition-lib.test.sh: all assertions passed"
|