@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,400 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# shellcheck disable=SC1091,SC2016
|
|
3
|
+
# Behavior tests for the cd-guard PreToolUse seatbelt (docs/cd-guard.md).
|
|
4
|
+
#
|
|
5
|
+
# bin/fm-cd-command-policy.mjs is the single owner of the block/allow decision;
|
|
6
|
+
# it reuses the shell classifier owned by bin/fm-arm-command-policy.mjs.
|
|
7
|
+
# bin/fm-cd-pretool-check.sh is the stable transport: it scopes the guard to the
|
|
8
|
+
# real primary checkout, then drives all five harness entry forms. This suite
|
|
9
|
+
# proves the decision matrix, the harness-output shaping, the primary-checkout
|
|
10
|
+
# scoping (including the deliberate secondmate-home difference from the turn-end
|
|
11
|
+
# guard), the fail-open transport behavior, the prefilter fast path, the
|
|
12
|
+
# end-to-end cwd-leak regression, and the per-harness wiring. No harness is
|
|
13
|
+
# spawned; live per-harness evidence lives in docs/cd-guard.md.
|
|
14
|
+
set -u
|
|
15
|
+
|
|
16
|
+
# shellcheck source=tests/lib.sh
|
|
17
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
18
|
+
|
|
19
|
+
fm_git_identity fmtest fmtest@example.invalid
|
|
20
|
+
TMP_ROOT=$(fm_test_tmproot fm-cd-pretool-check)
|
|
21
|
+
|
|
22
|
+
# A primary-shaped checkout: plain (non-worktree) git repo, AGENTS.md, bin/ with
|
|
23
|
+
# the transport plus both policy files (fm-cd-command-policy.mjs imports the
|
|
24
|
+
# shared classifier from fm-arm-command-policy.mjs). This is what the transport's
|
|
25
|
+
# scoping treats as the real primary firstmate checkout.
|
|
26
|
+
install_cd_scripts() {
|
|
27
|
+
local dir=$1
|
|
28
|
+
mkdir -p "$dir/bin"
|
|
29
|
+
cp "$ROOT/bin/fm-cd-pretool-check.sh" "$dir/bin/fm-cd-pretool-check.sh"
|
|
30
|
+
cp "$ROOT/bin/fm-hook-host-lib.sh" "$dir/bin/fm-hook-host-lib.sh"
|
|
31
|
+
cp "$ROOT/bin/fm-cd-command-policy.mjs" "$dir/bin/fm-cd-command-policy.mjs"
|
|
32
|
+
cp "$ROOT/bin/fm-arm-command-policy.mjs" "$dir/bin/fm-arm-command-policy.mjs"
|
|
33
|
+
chmod +x "$dir/bin/fm-cd-pretool-check.sh" "$dir/bin/fm-cd-command-policy.mjs"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
make_primary_fixture() {
|
|
37
|
+
local dir=$1
|
|
38
|
+
git init -q "$dir"
|
|
39
|
+
git -C "$dir" commit -q --allow-empty -m init
|
|
40
|
+
: > "$dir/AGENTS.md"
|
|
41
|
+
install_cd_scripts "$dir"
|
|
42
|
+
printf '%s\n' "$dir"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Same shape as primary plus the .fm-secondmate-home marker: a secondmate's own
|
|
46
|
+
# primary session, which the cd-guard DOES guard (unlike the turn-end guard).
|
|
47
|
+
make_secondmate_fixture() {
|
|
48
|
+
local dir=$1
|
|
49
|
+
make_primary_fixture "$dir" >/dev/null
|
|
50
|
+
printf 'sm-cd-1\n' > "$dir/.fm-secondmate-home"
|
|
51
|
+
printf '%s\n' "$dir"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# A genuine linked git worktree - the shape bin/fm-spawn.sh hands crewmate/scout
|
|
55
|
+
# tasks. git-dir and git-common-dir differ, so the guard must be inert.
|
|
56
|
+
make_child_worktree_fixture() {
|
|
57
|
+
local base=$1 dir=$2
|
|
58
|
+
fm_git_worktree "$base" "$dir" fm/cd-guard-test-branch
|
|
59
|
+
: > "$dir/AGENTS.md"
|
|
60
|
+
install_cd_scripts "$dir"
|
|
61
|
+
printf '%s\n' "$dir"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
PRIMARY=$(make_primary_fixture "$TMP_ROOT/primary")
|
|
65
|
+
CHECK="$PRIMARY/bin/fm-cd-pretool-check.sh"
|
|
66
|
+
|
|
67
|
+
# --- full cross-harness acceptance matrix ----------------------------------
|
|
68
|
+
|
|
69
|
+
MATRIX_IDS=()
|
|
70
|
+
MATRIX_EXPECTED=()
|
|
71
|
+
MATRIX_COMMANDS=()
|
|
72
|
+
|
|
73
|
+
matrix_case() {
|
|
74
|
+
MATRIX_IDS+=("$1")
|
|
75
|
+
MATRIX_EXPECTED+=("$2")
|
|
76
|
+
MATRIX_COMMANDS+=("$3")
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# BLOCK: a persistent top-level cwd change in the parent shell.
|
|
80
|
+
matrix_case B01 deny 'cd projects/foo'
|
|
81
|
+
matrix_case B02 deny 'cd ..'
|
|
82
|
+
matrix_case B03 deny 'cd'
|
|
83
|
+
matrix_case B04 deny 'cd -'
|
|
84
|
+
matrix_case B05 deny 'cd /abs/path'
|
|
85
|
+
matrix_case B06 deny 'pushd projects/foo'
|
|
86
|
+
matrix_case B07 deny 'popd'
|
|
87
|
+
matrix_case B08 deny 'X=1 cd projects/foo'
|
|
88
|
+
matrix_case B09 deny 'cd projects/foo && tasks-axi add x'
|
|
89
|
+
matrix_case B10 deny 'echo before; cd projects/foo'
|
|
90
|
+
matrix_case B11 deny 'true && cd projects/foo'
|
|
91
|
+
matrix_case B12 deny 'tasks-axi done x || cd projects/foo'
|
|
92
|
+
matrix_case B13 deny 'cd "projects/foo"'
|
|
93
|
+
matrix_case B14 deny '"cd" projects/foo'
|
|
94
|
+
matrix_case B15 deny 'sleep 1 & cd projects/foo'
|
|
95
|
+
matrix_case B16 deny 'command cd projects/foo'
|
|
96
|
+
matrix_case B17 deny 'cd projects/foo >/dev/null'
|
|
97
|
+
matrix_case B18 deny $'cd projects/foo\necho done'
|
|
98
|
+
matrix_case B19 deny "\$'\\143d' projects/foo"
|
|
99
|
+
matrix_case B20 deny "c'd' projects/foo"
|
|
100
|
+
matrix_case B21 deny 'c"d" projects/foo'
|
|
101
|
+
matrix_case B22 deny 'c\d projects/foo'
|
|
102
|
+
matrix_case B23 deny 'builtin cd projects/foo'
|
|
103
|
+
matrix_case B24 deny 'command builtin cd projects/foo'
|
|
104
|
+
matrix_case B25 deny 'builtin command cd projects/foo'
|
|
105
|
+
matrix_case B26 deny 'command -p cd projects/foo'
|
|
106
|
+
matrix_case B27 deny 'command -- cd projects/foo'
|
|
107
|
+
|
|
108
|
+
# ALLOW: not a persistent top-level cwd change (scoped, data, or non-cd).
|
|
109
|
+
matrix_case A01 allow 'git -C projects/foo status'
|
|
110
|
+
matrix_case A02 allow 'cat /abs/path/file'
|
|
111
|
+
matrix_case A03 allow 'ls projects/foo'
|
|
112
|
+
matrix_case A04 allow 'echo "cd projects/foo"'
|
|
113
|
+
matrix_case A05 allow 'grep cd file'
|
|
114
|
+
matrix_case A06 allow '(cd projects/foo && pwd)'
|
|
115
|
+
matrix_case A07 allow "bash -c 'cd projects/foo'"
|
|
116
|
+
matrix_case A08 allow 'env -C projects/foo make'
|
|
117
|
+
matrix_case A09 allow 'make -C projects/foo build'
|
|
118
|
+
matrix_case A10 allow 'find . -execdir cd {} \;'
|
|
119
|
+
matrix_case A11 allow 'cd projects/foo | cat'
|
|
120
|
+
matrix_case A12 allow 'cat foo | cd bar'
|
|
121
|
+
matrix_case A13 allow 'cd projects/foo &'
|
|
122
|
+
matrix_case A14 allow 'abcd project'
|
|
123
|
+
matrix_case A15 allow 'cdk deploy'
|
|
124
|
+
matrix_case A16 allow 'env cd projects/foo'
|
|
125
|
+
matrix_case A17 allow 'sudo cd projects/foo'
|
|
126
|
+
matrix_case A18 allow 'x=$(cd foo && pwd)'
|
|
127
|
+
matrix_case A19 allow 'dirs'
|
|
128
|
+
matrix_case A20 allow "echo 'pushd x'"
|
|
129
|
+
matrix_case A21 allow 'git checkout main'
|
|
130
|
+
matrix_case A22 allow "sh -c 'cd projects/foo && ls'"
|
|
131
|
+
matrix_case A23 allow "printf '%s\\n' 'cd projects/foo'"
|
|
132
|
+
matrix_case A24 allow 'ls -la'
|
|
133
|
+
matrix_case A25 allow './cd projects/foo'
|
|
134
|
+
matrix_case A26 allow '/tmp/cd projects/foo'
|
|
135
|
+
matrix_case A27 allow '/usr/bin/cd projects/foo'
|
|
136
|
+
matrix_case A28 allow './builtin cd projects/foo'
|
|
137
|
+
matrix_case A29 allow 'c\d\ projects/foo'
|
|
138
|
+
matrix_case A30 allow './command cd projects/foo'
|
|
139
|
+
matrix_case A31 allow '/usr/bin/command cd projects/foo'
|
|
140
|
+
matrix_case A32 allow '/tmp/builtin cd projects/foo'
|
|
141
|
+
matrix_case A33 allow 'command -v cd'
|
|
142
|
+
matrix_case A34 allow 'command -V cd'
|
|
143
|
+
matrix_case A35 allow 'command -pv cd'
|
|
144
|
+
matrix_case A36 allow 'command -vp cd'
|
|
145
|
+
|
|
146
|
+
MATRIX_TMP=$(mktemp -d "${TMPDIR:-/tmp}/fm-cd-policy-matrix.XXXXXX")
|
|
147
|
+
FM_TEST_CLEANUP_DIRS+=("$MATRIX_TMP")
|
|
148
|
+
|
|
149
|
+
run_matrix_entry() {
|
|
150
|
+
local id=$1 expected=$2 entry=$3 cmd=$4 payload out_file err_file rc
|
|
151
|
+
out_file="$MATRIX_TMP/$id-$entry.out"
|
|
152
|
+
err_file="$MATRIX_TMP/$id-$entry.err"
|
|
153
|
+
|
|
154
|
+
case "$entry" in
|
|
155
|
+
codex)
|
|
156
|
+
payload=$(jq -cn --arg command "$cmd" '{tool_name:"Bash",tool_input:{command:$command}}')
|
|
157
|
+
printf '%s' "$payload" | "$CHECK" >"$out_file" 2>"$err_file"
|
|
158
|
+
rc=$?
|
|
159
|
+
;;
|
|
160
|
+
claude)
|
|
161
|
+
payload=$(jq -cn --arg command "$cmd" '{tool_name:"Bash",tool_input:{command:$command}}')
|
|
162
|
+
printf '%s' "$payload" | "$CHECK" --claude >"$out_file" 2>"$err_file"
|
|
163
|
+
rc=$?
|
|
164
|
+
;;
|
|
165
|
+
grok)
|
|
166
|
+
payload=$(jq -cn --arg command "$cmd" '{toolName:"run_terminal_command",toolInput:{command:$command}}')
|
|
167
|
+
printf '%s' "$payload" | "$CHECK" >"$out_file" 2>"$err_file"
|
|
168
|
+
rc=$?
|
|
169
|
+
;;
|
|
170
|
+
opencode|pi)
|
|
171
|
+
"$CHECK" --command "$cmd" >"$out_file" 2>"$err_file"
|
|
172
|
+
rc=$?
|
|
173
|
+
;;
|
|
174
|
+
*)
|
|
175
|
+
fail "unknown matrix entry form: $entry"
|
|
176
|
+
;;
|
|
177
|
+
esac
|
|
178
|
+
|
|
179
|
+
if [ "$expected" = allow ]; then
|
|
180
|
+
[ "$rc" -eq 0 ] || fail "$id via $entry must allow, got exit $rc: $(cat "$err_file")"
|
|
181
|
+
[ ! -s "$out_file" ] || fail "$id via $entry allow must leave stdout empty: $(cat "$out_file")"
|
|
182
|
+
[ ! -s "$err_file" ] || fail "$id via $entry allow must leave stderr empty: $(cat "$err_file")"
|
|
183
|
+
return
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
[ "$rc" -eq 2 ] || fail "$id via $entry must deny, got exit $rc"
|
|
187
|
+
jq -e '.hookSpecificOutput.permissionDecision == "deny" and (.systemMessage | test("\\[persistent-cd\\]"))' "$err_file" >/dev/null 2>&1 \
|
|
188
|
+
|| fail "$id via $entry deny must carry the persistent-cd reason code on stderr: $(cat "$err_file")"
|
|
189
|
+
if [ "$entry" = claude ]; then
|
|
190
|
+
[ ! -s "$out_file" ] || fail "$id via claude deny must leave stdout empty: $(cat "$out_file")"
|
|
191
|
+
elif [ "$entry" = grok ]; then
|
|
192
|
+
jq -e '.decision == "deny"' "$out_file" >/dev/null 2>&1 \
|
|
193
|
+
|| fail "$id via grok deny must carry decision=deny on stdout: $(cat "$out_file")"
|
|
194
|
+
fi
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
test_full_acceptance_matrix() {
|
|
198
|
+
local i entry
|
|
199
|
+
for ((i = 0; i < ${#MATRIX_IDS[@]}; i++)); do
|
|
200
|
+
for entry in codex claude grok opencode pi; do
|
|
201
|
+
run_matrix_entry "${MATRIX_IDS[$i]}" "${MATRIX_EXPECTED[$i]}" "$entry" "${MATRIX_COMMANDS[$i]}"
|
|
202
|
+
done
|
|
203
|
+
done
|
|
204
|
+
pass "cd-guard acceptance matrix: ${#MATRIX_IDS[@]} cases x 5 harness entry forms, block/allow all correct"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# --- primary-checkout scoping ----------------------------------------------
|
|
208
|
+
|
|
209
|
+
test_fires_in_secondmate_home() {
|
|
210
|
+
local dir out rc
|
|
211
|
+
dir=$(make_secondmate_fixture "$TMP_ROOT/secondmate")
|
|
212
|
+
out=$("$dir/bin/fm-cd-pretool-check.sh" --claude --command 'cd projects/foo' 2>&1); rc=$?
|
|
213
|
+
expect_code 2 "$rc" "cd-guard must fire in a secondmate's own primary session (unlike the turn-end guard)"
|
|
214
|
+
assert_contains "$out" '[persistent-cd]' "secondmate-home block must carry the reason code"
|
|
215
|
+
pass "cd-guard: fires in a secondmate home (its own primary session is a primary)"
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
test_inert_in_child_worktree() {
|
|
219
|
+
local base dir out rc
|
|
220
|
+
base="$TMP_ROOT/child-base"
|
|
221
|
+
dir="$TMP_ROOT/child-wt"
|
|
222
|
+
make_child_worktree_fixture "$base" "$dir" >/dev/null
|
|
223
|
+
out=$("$dir/bin/fm-cd-pretool-check.sh" --claude --command 'cd projects/foo' 2>&1); rc=$?
|
|
224
|
+
expect_code 0 "$rc" "cd-guard must be inert in a crewmate/scout linked worktree"
|
|
225
|
+
[ -z "$out" ] || fail "cd-guard produced output in a child worktree: $out"
|
|
226
|
+
pass "cd-guard: inert in a crewmate/scout task worktree (linked git worktree)"
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
test_inert_when_not_firstmate_repo() {
|
|
230
|
+
local dir out rc
|
|
231
|
+
dir="$TMP_ROOT/not-firstmate"
|
|
232
|
+
git init -q "$dir"
|
|
233
|
+
git -C "$dir" commit -q --allow-empty -m init
|
|
234
|
+
install_cd_scripts "$dir" # bin/ present but no AGENTS.md
|
|
235
|
+
out=$("$dir/bin/fm-cd-pretool-check.sh" --claude --command 'cd projects/foo' 2>&1); rc=$?
|
|
236
|
+
expect_code 0 "$rc" "cd-guard must be inert without AGENTS.md (not a firstmate checkout)"
|
|
237
|
+
[ -z "$out" ] || fail "cd-guard produced output outside a firstmate checkout: $out"
|
|
238
|
+
pass "cd-guard: inert in a non-firstmate repo (no AGENTS.md)"
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
test_inert_when_not_a_git_repo() {
|
|
242
|
+
local dir out rc
|
|
243
|
+
dir="$TMP_ROOT/no-git"
|
|
244
|
+
mkdir -p "$dir"
|
|
245
|
+
: > "$dir/AGENTS.md"
|
|
246
|
+
install_cd_scripts "$dir" # AGENTS.md + bin/ but no git repo
|
|
247
|
+
out=$("$dir/bin/fm-cd-pretool-check.sh" --claude --command 'cd projects/foo' 2>&1); rc=$?
|
|
248
|
+
expect_code 0 "$rc" "cd-guard must be inert when the checkout is not a git repo"
|
|
249
|
+
[ -z "$out" ] || fail "cd-guard produced output in a non-git dir: $out"
|
|
250
|
+
pass "cd-guard: inert when not inside a git repo"
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# --- end-to-end cwd-leak regression ----------------------------------------
|
|
254
|
+
|
|
255
|
+
test_e2e_cwd_leak_regression() {
|
|
256
|
+
local sandbox home home_updated leaked out rc
|
|
257
|
+
sandbox="$TMP_ROOT/e2e"
|
|
258
|
+
home="$sandbox/home"
|
|
259
|
+
mkdir -p "$home/data" "$home/projects/clone/data"
|
|
260
|
+
printf '## In flight\n' > "$home/data/backlog.md"
|
|
261
|
+
|
|
262
|
+
# Without the guard, the persistent primary shell's cwd leaks: a stray
|
|
263
|
+
# `cd projects/clone` makes the next firstmate-owned backlog write land in the
|
|
264
|
+
# clone, and the home backlog is never updated.
|
|
265
|
+
(
|
|
266
|
+
cd "$home" || fail "cannot enter home"
|
|
267
|
+
cd projects/clone || fail "cannot enter clone"
|
|
268
|
+
printf -- '- [x] demo done\n' >> data/backlog.md
|
|
269
|
+
)
|
|
270
|
+
home_updated=0
|
|
271
|
+
grep -q 'demo done' "$home/data/backlog.md" && home_updated=1
|
|
272
|
+
leaked=0
|
|
273
|
+
grep -q 'demo done' "$home/projects/clone/data/backlog.md" 2>/dev/null && leaked=1
|
|
274
|
+
[ "$home_updated" -eq 0 ] || fail "baseline: home backlog was updated, cwd leak did not reproduce"
|
|
275
|
+
[ "$leaked" -eq 1 ] || fail "baseline: backlog write did not leak into the clone"
|
|
276
|
+
|
|
277
|
+
# With the guard, the exact stray command is denied before it can run, so the
|
|
278
|
+
# real harness never lets cwd leave the home.
|
|
279
|
+
out=$("$CHECK" --claude --command 'cd projects/clone' 2>&1); rc=$?
|
|
280
|
+
expect_code 2 "$rc" "guard must deny the stray persistent cd that caused the leak"
|
|
281
|
+
assert_contains "$out" '[persistent-cd]' "leak-preventing block must carry the reason code"
|
|
282
|
+
pass "cd-guard: reproduces the cwd leak and denies the exact command that causes it"
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
# --- fail-open transport behavior ------------------------------------------
|
|
286
|
+
|
|
287
|
+
test_fail_open_empty_stdin() {
|
|
288
|
+
local out rc
|
|
289
|
+
out=$("$CHECK" < /dev/null 2>&1); rc=$?
|
|
290
|
+
expect_code 0 "$rc" "transport must exit 0 on empty stdin"
|
|
291
|
+
[ -z "$out" ] || fail "transport produced output on empty stdin: $out"
|
|
292
|
+
pass "cd-guard: fails open on empty stdin"
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
test_fail_open_unparseable_json() {
|
|
296
|
+
local out rc
|
|
297
|
+
out=$(printf 'not json at all' | "$CHECK" 2>&1); rc=$?
|
|
298
|
+
expect_code 0 "$rc" "transport must exit 0 on unparseable stdin JSON"
|
|
299
|
+
[ -z "$out" ] || fail "transport produced output on unparseable JSON: $out"
|
|
300
|
+
pass "cd-guard: fails open on unparseable stdin JSON"
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
test_fail_open_missing_node() {
|
|
304
|
+
local fakebin tool tool_path out rc
|
|
305
|
+
fakebin=$(fm_fakebin "$TMP_ROOT/nonode")
|
|
306
|
+
for tool in bash sh git dirname cat printf sed tr jq; do
|
|
307
|
+
tool_path=$(command -v "$tool") || continue
|
|
308
|
+
ln -s "$tool_path" "$fakebin/$tool"
|
|
309
|
+
done
|
|
310
|
+
# node deliberately absent from this PATH.
|
|
311
|
+
out=$(PATH="$fakebin" "$CHECK" --command 'cd projects/foo' 2>&1); rc=$?
|
|
312
|
+
expect_code 0 "$rc" "transport must fail open when node is unavailable"
|
|
313
|
+
[ -z "$out" ] || fail "transport produced output without node: $out"
|
|
314
|
+
pass "cd-guard: fails open (never blocks) when node is missing"
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
test_fail_open_missing_jq_on_stdin() {
|
|
318
|
+
local fakebin tool tool_path out rc
|
|
319
|
+
fakebin=$(fm_fakebin "$TMP_ROOT/nojq")
|
|
320
|
+
for tool in bash sh git dirname cat printf sed tr node; do
|
|
321
|
+
tool_path=$(command -v "$tool") || continue
|
|
322
|
+
ln -s "$tool_path" "$fakebin/$tool"
|
|
323
|
+
done
|
|
324
|
+
# jq deliberately absent: the stdin transport cannot extract the command.
|
|
325
|
+
out=$(printf '{"tool_input":{"command":"cd projects/foo"}}' | PATH="$fakebin" "$CHECK" 2>&1); rc=$?
|
|
326
|
+
expect_code 0 "$rc" "stdin transport must fail open when jq is unavailable"
|
|
327
|
+
[ -z "$out" ] || fail "transport produced output without jq on the stdin path: $out"
|
|
328
|
+
pass "cd-guard: fails open on the stdin path when jq is missing"
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
# --- prefilter fast path ----------------------------------------------------
|
|
332
|
+
|
|
333
|
+
test_prefilter_skips_node_without_cd_substring() {
|
|
334
|
+
local dir fakebin marker tool tool_path out rc
|
|
335
|
+
dir="$TMP_ROOT/prefilter"
|
|
336
|
+
make_primary_fixture "$dir" >/dev/null
|
|
337
|
+
fakebin=$(fm_fakebin "$TMP_ROOT/prefilter-fake")
|
|
338
|
+
marker="$TMP_ROOT/prefilter-node-called"
|
|
339
|
+
for tool in bash sh git dirname cat printf sed tr jq; do
|
|
340
|
+
tool_path=$(command -v "$tool") || continue
|
|
341
|
+
ln -s "$tool_path" "$fakebin/$tool"
|
|
342
|
+
done
|
|
343
|
+
cat > "$fakebin/node" <<EOF
|
|
344
|
+
#!/usr/bin/env bash
|
|
345
|
+
: > "$marker"
|
|
346
|
+
exit 0
|
|
347
|
+
EOF
|
|
348
|
+
chmod +x "$fakebin/node"
|
|
349
|
+
# No cd/pushd/popd substring: the prefilter must fast-allow before scoping or
|
|
350
|
+
# the policy runtime is ever consulted.
|
|
351
|
+
out=$(PATH="$fakebin" "$dir/bin/fm-cd-pretool-check.sh" --command 'git status' 2>&1); rc=$?
|
|
352
|
+
expect_code 0 "$rc" "prefilter must fast-allow a command with no cd/pushd/popd substring"
|
|
353
|
+
[ -z "$out" ] || fail "prefilter fast-allow produced output: $out"
|
|
354
|
+
[ ! -e "$marker" ] || fail "prefilter fast-allow still invoked the node policy owner"
|
|
355
|
+
pass "cd-guard: prefilter fast-allows (skips node) when no cd/pushd/popd substring is present"
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
# --- policy CLI contract ----------------------------------------------------
|
|
359
|
+
|
|
360
|
+
test_policy_cli_direct() {
|
|
361
|
+
local policy
|
|
362
|
+
policy="$ROOT/bin/fm-cd-command-policy.mjs"
|
|
363
|
+
[ "$(node "$policy" --command 'cd projects/foo' | cut -f1)" = deny ] \
|
|
364
|
+
|| fail "policy CLI must deny a bare top-level cd"
|
|
365
|
+
[ "$(node "$policy" --command 'git -C projects/foo status')" = allow ] \
|
|
366
|
+
|| fail "policy CLI must allow git -C"
|
|
367
|
+
[ "$(node "$policy" --command '(cd projects/foo && pwd)')" = allow ] \
|
|
368
|
+
|| fail "policy CLI must allow a subshell-local cd"
|
|
369
|
+
[ "$(node "$policy")" = allow ] \
|
|
370
|
+
|| fail "policy CLI must allow when no command is supplied"
|
|
371
|
+
pass "cd-guard: fm-cd-command-policy.mjs CLI honors the deny/allow output contract"
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
# --- per-harness wiring -----------------------------------------------------
|
|
375
|
+
|
|
376
|
+
# Delegated to bin/fm-lint.sh, the single owner of the lint definition including
|
|
377
|
+
# --external-sources; calling the linter directly here would be a second copy of
|
|
378
|
+
# that definition, and would disagree the moment this checker sourced a shared
|
|
379
|
+
# library.
|
|
380
|
+
test_scripts_are_shellcheck_clean() {
|
|
381
|
+
local out
|
|
382
|
+
command -v shellcheck >/dev/null 2>&1 || { pass "shellcheck not installed, skipping"; return; }
|
|
383
|
+
out=$("$ROOT/bin/fm-lint.sh" "$ROOT/bin/fm-cd-pretool-check.sh" 2>&1) \
|
|
384
|
+
|| fail "bin/fm-cd-pretool-check.sh is not lint-clean under the pinned definition: $out"
|
|
385
|
+
pass "bin/fm-cd-pretool-check.sh is clean under bin/fm-lint.sh"
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
test_full_acceptance_matrix
|
|
389
|
+
test_fires_in_secondmate_home
|
|
390
|
+
test_inert_in_child_worktree
|
|
391
|
+
test_inert_when_not_firstmate_repo
|
|
392
|
+
test_inert_when_not_a_git_repo
|
|
393
|
+
test_e2e_cwd_leak_regression
|
|
394
|
+
test_fail_open_empty_stdin
|
|
395
|
+
test_fail_open_unparseable_json
|
|
396
|
+
test_fail_open_missing_node
|
|
397
|
+
test_fail_open_missing_jq_on_stdin
|
|
398
|
+
test_prefilter_skips_node_without_cd_substring
|
|
399
|
+
test_policy_cli_direct
|
|
400
|
+
test_scripts_are_shellcheck_clean
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavior tests for fm-check-unregister.sh: refuse empty-variable retirement,
|
|
3
|
+
# and remove only the two named custom-check files on the happy path.
|
|
4
|
+
set -u
|
|
5
|
+
|
|
6
|
+
# shellcheck source=tests/lib.sh
|
|
7
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
8
|
+
|
|
9
|
+
UNREGISTER="$ROOT/bin/fm-check-unregister.sh"
|
|
10
|
+
REGISTER="$ROOT/bin/fm-check-register.sh"
|
|
11
|
+
TMP_ROOT=$(fm_test_tmproot fm-check-unregister)
|
|
12
|
+
REAL_RM=$(command -v rm)
|
|
13
|
+
|
|
14
|
+
make_home() {
|
|
15
|
+
local name=$1 home
|
|
16
|
+
home="$TMP_ROOT/$name"
|
|
17
|
+
mkdir -p "$home/state" "$home/data" "$home/config"
|
|
18
|
+
printf '%s\n' "$home"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
write_registered_check() {
|
|
22
|
+
local home=$1 id=$2
|
|
23
|
+
cat > "$home/state/$id.check.sh" <<'SH'
|
|
24
|
+
#!/usr/bin/env bash
|
|
25
|
+
printf 'custom-ready\n'
|
|
26
|
+
SH
|
|
27
|
+
chmod 0700 "$home/state/$id.check.sh"
|
|
28
|
+
FM_HOME="$home" "$REGISTER" "$id" >/dev/null \
|
|
29
|
+
|| fail "could not register custom check $id"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
install_rm_logger() {
|
|
33
|
+
local home=$1 fakebin log
|
|
34
|
+
fakebin=$(fm_fakebin "$home")
|
|
35
|
+
log="$home/rm.log"
|
|
36
|
+
: > "$log"
|
|
37
|
+
cat > "$fakebin/rm" <<SH
|
|
38
|
+
#!/usr/bin/env bash
|
|
39
|
+
printf '%s\n' "\$*" >> "$log"
|
|
40
|
+
exec "$REAL_RM" "\$@"
|
|
41
|
+
SH
|
|
42
|
+
chmod +x "$fakebin/rm"
|
|
43
|
+
printf '%s\n' "$log"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
assert_rm_not_invoked() {
|
|
47
|
+
local log=$1
|
|
48
|
+
[ -s "$log" ] && fail "retire path invoked rm while refusing"$'\n'"--- rm log ---"$'\n'"$(cat "$log")"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
test_empty_id_and_empty_state_refuse_without_stray_rm() {
|
|
52
|
+
local home out err status log canary_empty_id canary_sibling decoy
|
|
53
|
+
home=$(make_home empty-var)
|
|
54
|
+
out="$home/out.txt"
|
|
55
|
+
err="$home/err.txt"
|
|
56
|
+
log=$(install_rm_logger "$home")
|
|
57
|
+
canary_empty_id="$home/state/.check.sh"
|
|
58
|
+
canary_sibling="$home/state/keep.check.sh"
|
|
59
|
+
decoy="$home/decoy.check.sh"
|
|
60
|
+
printf 'canary-empty-id\n' > "$canary_empty_id"
|
|
61
|
+
printf 'sibling\n' > "$canary_sibling"
|
|
62
|
+
printf 'decoy\n' > "$decoy"
|
|
63
|
+
chmod 0700 "$canary_empty_id" "$canary_sibling"
|
|
64
|
+
|
|
65
|
+
status=0
|
|
66
|
+
PATH="$home/fakebin:$PATH" STATE='' ID='' FM_HOME="$home" \
|
|
67
|
+
"$UNREGISTER" >"$out" 2>"$err" || status=$?
|
|
68
|
+
expect_code 2 "$status" "unregister with no id"
|
|
69
|
+
assert_contains "$(cat "$err")" "error:" "missing-id refusal had no stderr"
|
|
70
|
+
assert_present "$canary_empty_id" "empty-id expansion deleted state/.check.sh"
|
|
71
|
+
assert_present "$canary_sibling" "missing-id call deleted a sibling check file"
|
|
72
|
+
assert_present "$decoy" "missing-id call deleted a decoy outside state/"
|
|
73
|
+
assert_rm_not_invoked "$log"
|
|
74
|
+
|
|
75
|
+
status=0
|
|
76
|
+
: > "$log"
|
|
77
|
+
PATH="$home/fakebin:$PATH" STATE='' ID='' FM_HOME="$home" \
|
|
78
|
+
"$UNREGISTER" "" >"$out" 2>"$err" || status=$?
|
|
79
|
+
expect_code 2 "$status" "unregister with empty id"
|
|
80
|
+
assert_contains "$(cat "$err")" "error:" "empty-id refusal had no stderr"
|
|
81
|
+
assert_present "$canary_empty_id" "empty-string id deleted state/.check.sh"
|
|
82
|
+
assert_rm_not_invoked "$log"
|
|
83
|
+
|
|
84
|
+
status=0
|
|
85
|
+
: > "$log"
|
|
86
|
+
PATH="$home/fakebin:$PATH" STATE='' ID='' FM_HOME="$home" \
|
|
87
|
+
"$UNREGISTER" "../escape" >"$out" 2>"$err" || status=$?
|
|
88
|
+
expect_code 2 "$status" "unregister with unsafe id"
|
|
89
|
+
assert_present "$canary_empty_id" "unsafe id deleted state/.check.sh"
|
|
90
|
+
assert_rm_not_invoked "$log"
|
|
91
|
+
|
|
92
|
+
mkdir -p "$home/nostate-home"
|
|
93
|
+
printf 'pre-state-canary\n' > "$home/nostate-home/.check.sh"
|
|
94
|
+
status=0
|
|
95
|
+
: > "$log"
|
|
96
|
+
PATH="$home/fakebin:$PATH" STATE='' ID='' FM_HOME="$home/nostate-home" \
|
|
97
|
+
"$UNREGISTER" demo-check >"$out" 2>"$err" || status=$?
|
|
98
|
+
expect_code 1 "$status" "unregister with missing state dir"
|
|
99
|
+
assert_contains "$(cat "$err")" "state directory is unavailable" \
|
|
100
|
+
"missing state dir refusal used the wrong stderr"
|
|
101
|
+
assert_present "$home/nostate-home/.check.sh" \
|
|
102
|
+
"missing-state-dir call deleted a stray path in the home"
|
|
103
|
+
assert_present "$canary_empty_id" "missing-state-dir call reached another home's files"
|
|
104
|
+
assert_rm_not_invoked "$log"
|
|
105
|
+
|
|
106
|
+
status=0
|
|
107
|
+
: > "$log"
|
|
108
|
+
PATH="$home/fakebin:$PATH" STATE='' ID='' FM_HOME="$home" \
|
|
109
|
+
FM_STATE_OVERRIDE="$home/missing-state" \
|
|
110
|
+
"$UNREGISTER" demo-check >"$out" 2>"$err" || status=$?
|
|
111
|
+
expect_code 1 "$status" "unregister with empty-equivalent state override"
|
|
112
|
+
assert_contains "$(cat "$err")" "state directory is unavailable" \
|
|
113
|
+
"non-directory state override refusal used the wrong stderr"
|
|
114
|
+
assert_present "$canary_empty_id" "bad state override deleted state/.check.sh"
|
|
115
|
+
assert_present "$canary_sibling" "bad state override deleted a sibling"
|
|
116
|
+
assert_rm_not_invoked "$log"
|
|
117
|
+
|
|
118
|
+
write_registered_check "$home" override-empty
|
|
119
|
+
status=0
|
|
120
|
+
: > "$log"
|
|
121
|
+
PATH="$home/fakebin:$PATH" FM_HOME="$home" FM_STATE_OVERRIDE='' \
|
|
122
|
+
"$UNREGISTER" override-empty >"$out" 2>"$err" || status=$?
|
|
123
|
+
expect_code 1 "$status" "unregister with explicitly empty state override"
|
|
124
|
+
assert_contains "$(cat "$err")" "state directory is unavailable" \
|
|
125
|
+
"empty state override refusal used the wrong stderr"
|
|
126
|
+
assert_present "$home/state/override-empty.check.sh" \
|
|
127
|
+
"empty state override deleted the home state check"
|
|
128
|
+
assert_present "$home/state/override-empty.check-trust" \
|
|
129
|
+
"empty state override deleted the home state trust binding"
|
|
130
|
+
assert_rm_not_invoked "$log"
|
|
131
|
+
|
|
132
|
+
pass "empty id or missing state dir refuses loudly and never rms a stray path"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
test_happy_path_removes_only_check_and_trust() {
|
|
136
|
+
local home out err status sibling meta
|
|
137
|
+
home=$(make_home happy)
|
|
138
|
+
out="$home/out.txt"
|
|
139
|
+
err="$home/err.txt"
|
|
140
|
+
sibling="$home/state/other.check.sh"
|
|
141
|
+
meta="$home/state/demo-check.meta"
|
|
142
|
+
write_registered_check "$home" demo-check
|
|
143
|
+
printf '#!/usr/bin/env bash\nprintf other\n' > "$sibling"
|
|
144
|
+
chmod 0700 "$sibling"
|
|
145
|
+
printf 'keep-meta\n' > "$meta"
|
|
146
|
+
assert_present "$home/state/demo-check.check.sh" "fixture check.sh missing before unregister"
|
|
147
|
+
assert_present "$home/state/demo-check.check-trust" "fixture check-trust missing before unregister"
|
|
148
|
+
|
|
149
|
+
status=0
|
|
150
|
+
STATE='' ID='' FM_HOME="$home" "$UNREGISTER" demo-check >"$out" 2>"$err" || status=$?
|
|
151
|
+
expect_code 0 "$status" "happy-path unregister"
|
|
152
|
+
assert_contains "$(cat "$out")" "unregistered: state/demo-check.check.sh" \
|
|
153
|
+
"happy path did not report unregistration"
|
|
154
|
+
assert_absent "$home/state/demo-check.check.sh" "happy path left check.sh behind"
|
|
155
|
+
assert_absent "$home/state/demo-check.check-trust" "happy path left check-trust behind"
|
|
156
|
+
assert_present "$sibling" "happy path deleted a sibling check.sh"
|
|
157
|
+
assert_present "$meta" "happy path deleted an unrelated state file"
|
|
158
|
+
|
|
159
|
+
pass "happy path removes only the named check.sh and check-trust"
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
test_unsafe_hardlink_or_symlink_is_refused() {
|
|
163
|
+
local home out err status alias
|
|
164
|
+
home=$(make_home unsafe)
|
|
165
|
+
out="$home/out.txt"
|
|
166
|
+
err="$home/err.txt"
|
|
167
|
+
write_registered_check "$home" custom
|
|
168
|
+
alias="$home/custom-check.alias"
|
|
169
|
+
ln "$home/state/custom.check.sh" "$alias"
|
|
170
|
+
|
|
171
|
+
status=0
|
|
172
|
+
FM_HOME="$home" "$UNREGISTER" custom >"$out" 2>"$err" || status=$?
|
|
173
|
+
expect_code 1 "$status" "unregister hard-linked check.sh"
|
|
174
|
+
assert_contains "$(cat "$err")" "unsafe to remove" "hard-link refusal used the wrong stderr"
|
|
175
|
+
assert_present "$home/state/custom.check.sh" "hard-link refusal deleted check.sh"
|
|
176
|
+
assert_present "$home/state/custom.check-trust" "hard-link refusal deleted check-trust"
|
|
177
|
+
assert_present "$alias" "hard-link refusal deleted the external alias"
|
|
178
|
+
|
|
179
|
+
rm -f "$alias"
|
|
180
|
+
rm -f "$home/state/custom.check.sh"
|
|
181
|
+
printf '#!/usr/bin/env bash\nprintf target\n' > "$home/outside.check.sh"
|
|
182
|
+
chmod 0700 "$home/outside.check.sh"
|
|
183
|
+
ln -s "$home/outside.check.sh" "$home/state/custom.check.sh"
|
|
184
|
+
|
|
185
|
+
status=0
|
|
186
|
+
FM_HOME="$home" "$UNREGISTER" custom >"$out" 2>"$err" || status=$?
|
|
187
|
+
expect_code 1 "$status" "unregister symlink check.sh"
|
|
188
|
+
assert_contains "$(cat "$err")" "unsafe to remove" "symlink refusal used the wrong stderr"
|
|
189
|
+
assert_present "$home/state/custom.check.sh" "symlink refusal removed the state symlink"
|
|
190
|
+
assert_present "$home/outside.check.sh" "symlink refusal deleted the external target"
|
|
191
|
+
assert_present "$home/state/custom.check-trust" "symlink refusal deleted check-trust"
|
|
192
|
+
|
|
193
|
+
pass "hard-linked or symlinked artifacts are refused and left in place"
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
test_empty_id_and_empty_state_refuse_without_stray_rm
|
|
197
|
+
test_happy_path_removes_only_check_and_trust
|
|
198
|
+
test_unsafe_hardlink_or_symlink_is_refused
|