@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,552 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Tests for the Pi supervision branch's fleet-record layer
|
|
3
|
+
# (docs/pi-supervision-branch.md): the byte-stable branch prompt generator
|
|
4
|
+
# (bin/fm-branch-prompt.sh), the append-only outcome store
|
|
5
|
+
# (bin/fm-branch-outcome.sh), the per-task lease contract (bin/fm-lease.sh,
|
|
6
|
+
# bin/fm-lease-lib.sh), the lease and role-partition guards wired into the
|
|
7
|
+
# mutating entrypoints, and the proof that a home which never runs the branch
|
|
8
|
+
# is untouched by all of it.
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
# shellcheck source=tests/lib.sh
|
|
12
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
13
|
+
|
|
14
|
+
TMP_ROOT=$(fm_test_tmproot fm-branch-supervision)
|
|
15
|
+
|
|
16
|
+
# --- byte-stable branch prompt ------------------------------------------------
|
|
17
|
+
|
|
18
|
+
test_branch_prompt_is_byte_stable_and_above_cache_floor() {
|
|
19
|
+
local home_a home_b out_a out_b out_c size
|
|
20
|
+
home_a="$TMP_ROOT/prompt-home-a"
|
|
21
|
+
home_b="$TMP_ROOT/prompt-home-b"
|
|
22
|
+
mkdir -p "$home_a/state" "$home_b/state"
|
|
23
|
+
# Give the two homes deliberately different fleet state and clock context:
|
|
24
|
+
# a byte-stable prompt must not absorb any of it.
|
|
25
|
+
printf 'signal: task-1 done\n' > "$home_a/state/task-1.status"
|
|
26
|
+
printf 'window=x\nharness=pi\n' > "$home_a/state/task-1.meta"
|
|
27
|
+
|
|
28
|
+
out_a=$(cd "$TMP_ROOT" && FM_HOME="$home_a" TZ=UTC "$ROOT/bin/fm-branch-prompt.sh") \
|
|
29
|
+
|| fail "branch prompt generator failed for home A"
|
|
30
|
+
out_b=$(cd / && FM_HOME="$home_b" TZ=Australia/Eucla "$ROOT/bin/fm-branch-prompt.sh") \
|
|
31
|
+
|| fail "branch prompt generator failed for home B"
|
|
32
|
+
sleep 1
|
|
33
|
+
out_c=$("$ROOT/bin/fm-branch-prompt.sh") || fail "branch prompt generator failed on re-run"
|
|
34
|
+
|
|
35
|
+
[ "$out_a" = "$out_b" ] || fail "branch prompt differs across homes/cwd/timezone: prefix stability broken"
|
|
36
|
+
[ "$out_a" = "$out_c" ] || fail "branch prompt differs across runs at different times: prefix stability broken"
|
|
37
|
+
|
|
38
|
+
# Below the provider's 1024-token caching minimum a branch prompt gets no
|
|
39
|
+
# cache reuse at all (measured in the feasibility evidence), so hold a
|
|
40
|
+
# comfortable byte floor.
|
|
41
|
+
size=${#out_a}
|
|
42
|
+
[ "$size" -ge 5000 ] || fail "branch prompt is only $size bytes - below the provider caching minimum"
|
|
43
|
+
case "$out_a" in
|
|
44
|
+
"You are the SUPERVISION BRANCH"*) ;;
|
|
45
|
+
*) fail "branch prompt lost its role preamble" ;;
|
|
46
|
+
esac
|
|
47
|
+
case "$out_a" in
|
|
48
|
+
*"stuck-crewmate-recovery"*) ;;
|
|
49
|
+
*) fail "branch prompt lost the inlined recovery playbook" ;;
|
|
50
|
+
esac
|
|
51
|
+
case "$out_a" in
|
|
52
|
+
*"Report verdict captain for any outcome that directly answers an explicit captain request."*"This rule is unconditional"*"Keep an unsolicited routine outcome as verdict routine"*"Keep an unchanged fleet review silent"*) ;;
|
|
53
|
+
*) fail "branch prompt lost the unconditional requested-outcome or routine-silence rules" ;;
|
|
54
|
+
esac
|
|
55
|
+
pass "branch prompt is byte-stable across homes, cwd, timezone, and time, above the cache floor"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# --- append-only outcome store ------------------------------------------------
|
|
59
|
+
|
|
60
|
+
test_outcome_store_is_append_only_with_cursor_reads() {
|
|
61
|
+
local home store snapshot seq1 seq2 unread replay out status
|
|
62
|
+
home="$TMP_ROOT/store-home"
|
|
63
|
+
mkdir -p "$home/state"
|
|
64
|
+
store="$home/state/branch-outcomes.jsonl"
|
|
65
|
+
|
|
66
|
+
seq1=$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" append \
|
|
67
|
+
--task task-1 --verdict routine --summary 'worker healthy, "quoted" text kept' --wake 'signal: working') \
|
|
68
|
+
|| fail "first append failed"
|
|
69
|
+
[ "$seq1" = 1 ] || fail "first outcome seq was $seq1, not 1"
|
|
70
|
+
seq2=$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" append \
|
|
71
|
+
--task task-2 --verdict captain --summary 'PR https://example.com/pr/2 checks green') \
|
|
72
|
+
|| fail "second append failed"
|
|
73
|
+
[ "$seq2" = 2 ] || fail "second outcome seq was $seq2, not 2"
|
|
74
|
+
|
|
75
|
+
# The store is the owned durable contract: every line stays valid JSON.
|
|
76
|
+
python3 - "$store" <<'PY' || fail "outcome store holds invalid JSON"
|
|
77
|
+
import json, sys
|
|
78
|
+
rows = [json.loads(line) for line in open(sys.argv[1])]
|
|
79
|
+
assert [row["seq"] for row in rows] == [1, 2], rows
|
|
80
|
+
assert rows[0]["verdict"] == "routine" and rows[1]["verdict"] == "captain", rows
|
|
81
|
+
assert rows[0]["summary"] == 'worker healthy, "quoted" text kept', rows[0]
|
|
82
|
+
assert rows[0]["silent"] is False and rows[1]["silent"] is False, rows
|
|
83
|
+
PY
|
|
84
|
+
|
|
85
|
+
# mark-read moves only the cursor sidecar; the log bytes never change.
|
|
86
|
+
snapshot=$(cat "$store")
|
|
87
|
+
FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" mark-read --through 1 || fail "mark-read failed"
|
|
88
|
+
unread=$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" unread) || fail "unread failed"
|
|
89
|
+
case "$unread" in
|
|
90
|
+
'{"seq":2,'*) ;;
|
|
91
|
+
*) fail "unread did not return exactly the records above the cursor: $unread" ;;
|
|
92
|
+
esac
|
|
93
|
+
[ "$(cat "$store")" = "$snapshot" ] || fail "mark-read rewrote the append-only store"
|
|
94
|
+
|
|
95
|
+
# startup-replay surfaces the unread remainder once, then goes silent, and
|
|
96
|
+
# later appends land strictly after the earlier bytes (append-only merge).
|
|
97
|
+
replay=$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" startup-replay) || fail "startup-replay failed"
|
|
98
|
+
assert_contains "$replay" "BRANCH OUTCOMES" "replay lost its section header"
|
|
99
|
+
assert_contains "$replay" "https://example.com/pr/2" "replay lost the unread outcome"
|
|
100
|
+
[ -z "$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" startup-replay)" ] \
|
|
101
|
+
|| fail "startup-replay re-presented already-read outcomes"
|
|
102
|
+
FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" append \
|
|
103
|
+
--task task-3 --verdict routine --summary 'later outcome' >/dev/null || fail "third append failed"
|
|
104
|
+
case "$(cat "$store")" in
|
|
105
|
+
"$snapshot"*) ;;
|
|
106
|
+
*) fail "a later append disturbed earlier store bytes" ;;
|
|
107
|
+
esac
|
|
108
|
+
|
|
109
|
+
printf '{"seq":4,"epoch":' >> "$store"
|
|
110
|
+
snapshot=$(cat "$store")
|
|
111
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" append \
|
|
112
|
+
--task task-5 --verdict captain --summary 'must remain unrecorded' 2>&1)
|
|
113
|
+
status=$?
|
|
114
|
+
[ "$status" -ne 0 ] || fail "append accepted a malformed outcome-store tail"
|
|
115
|
+
assert_contains "$out" "malformed final record" "torn-tail refusal lost its diagnostic"
|
|
116
|
+
[ "$(cat "$store")" = "$snapshot" ] || fail "failed append changed the torn outcome store"
|
|
117
|
+
pass "outcome store is append-only and refuses sequence reuse after a torn tail"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
test_outcome_startup_replay_preserves_silence() {
|
|
121
|
+
local home replay
|
|
122
|
+
home="$TMP_ROOT/store-silent-home"
|
|
123
|
+
mkdir -p "$home/state"
|
|
124
|
+
|
|
125
|
+
FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" append \
|
|
126
|
+
--task fleet --verdict routine --summary 'fleet reviewed, nothing changed' --silent true >/dev/null \
|
|
127
|
+
|| fail "silent outcome append failed"
|
|
128
|
+
FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" append \
|
|
129
|
+
--task task-1 --verdict routine --summary 'worker recovered automatically' >/dev/null \
|
|
130
|
+
|| fail "visible outcome append failed"
|
|
131
|
+
|
|
132
|
+
replay=$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" startup-replay) || fail "mixed startup replay failed"
|
|
133
|
+
assert_not_contains "$replay" "fleet reviewed, nothing changed" "startup replay printed a silent outcome"
|
|
134
|
+
assert_contains "$replay" "worker recovered automatically" "startup replay lost a visible routine outcome"
|
|
135
|
+
[ -z "$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" unread)" ] \
|
|
136
|
+
|| fail "startup replay did not mark the silent and visible rows read"
|
|
137
|
+
|
|
138
|
+
printf '%s\n' '{"seq":3,"epoch":1,"task":"task-legacy","wake":"","verdict":"routine","summary":"legacy visible outcome"}' \
|
|
139
|
+
>> "$home/state/branch-outcomes.jsonl"
|
|
140
|
+
replay=$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" startup-replay) || fail "legacy startup replay failed"
|
|
141
|
+
assert_contains "$replay" "legacy visible outcome" "startup replay hid a legacy row with no silent field"
|
|
142
|
+
[ -z "$(FM_HOME="$home" "$ROOT/bin/fm-branch-outcome.sh" unread)" ] \
|
|
143
|
+
|| fail "startup replay did not mark the legacy row read"
|
|
144
|
+
pass "startup replay skips silent outcomes and preserves visible and legacy rows"
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# --- lease contract -----------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
test_lease_exclusivity_release_stale_and_sweep() {
|
|
150
|
+
local home out status
|
|
151
|
+
local -x PI_CODING_AGENT=true
|
|
152
|
+
home="$TMP_ROOT/lease-home"
|
|
153
|
+
mkdir -p "$home/state"
|
|
154
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
155
|
+
|
|
156
|
+
# Claim, exclusivity, same-actor refresh.
|
|
157
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-1 --actor branch \
|
|
158
|
+
|| fail "branch claim failed"
|
|
159
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-lease.sh" check task-1) || fail "check missed a held lease"
|
|
160
|
+
case "$out" in
|
|
161
|
+
"branch $$ "*" live") ;;
|
|
162
|
+
*) fail "check misreported the lease: $out" ;;
|
|
163
|
+
esac
|
|
164
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=main FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-1 2>&1)
|
|
165
|
+
status=$?
|
|
166
|
+
[ "$status" -eq 6 ] || fail "cross-actor claim exited $status, not the lease refusal 6"
|
|
167
|
+
assert_contains "$out" "leased to the branch supervision actor" "refusal did not name the holder"
|
|
168
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-1 \
|
|
169
|
+
|| fail "same-actor refresh was refused"
|
|
170
|
+
|
|
171
|
+
# Release by the calling holder; release of an unheld lease stays a silent no-op.
|
|
172
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-lease.sh" release task-1 --actor branch || fail "release failed"
|
|
173
|
+
FM_HOME="$home" "$ROOT/bin/fm-lease.sh" check task-1 >/dev/null && fail "released lease still reported"
|
|
174
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-lease.sh" release task-1 --actor branch || fail "idempotent release failed"
|
|
175
|
+
|
|
176
|
+
# A lease held by a dead process is stale: claimable by the other actor and
|
|
177
|
+
# removed by the sweep, while a live lease survives the sweep.
|
|
178
|
+
printf 'branch\t999999\t123\n' > "$home/state/.lease-task-dead"
|
|
179
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=main FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-dead \
|
|
180
|
+
|| fail "stale lease blocked a live claim"
|
|
181
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-lease.sh" check task-dead)
|
|
182
|
+
case "$out" in "main $$ "*) ;; *) fail "stale lease was not taken over: $out" ;; esac
|
|
183
|
+
printf 'branch\t999999\t123\n' > "$home/state/.lease-task-dead2"
|
|
184
|
+
FM_HOME="$home" "$ROOT/bin/fm-lease.sh" sweep || fail "sweep failed"
|
|
185
|
+
[ ! -e "$home/state/.lease-task-dead2" ] || fail "sweep left a provably stale lease"
|
|
186
|
+
[ -e "$home/state/.lease-task-dead" ] || fail "sweep removed a live lease"
|
|
187
|
+
|
|
188
|
+
# The reserved backlog resource claims like any task.
|
|
189
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim backlog --actor branch \
|
|
190
|
+
|| fail "backlog lease claim failed"
|
|
191
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=main FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim backlog 2>&1)
|
|
192
|
+
[ $? -eq 6 ] || fail "backlog lease did not enforce exclusivity"
|
|
193
|
+
pass "lease exclusivity, same-actor refresh, release, staleness, and sweep hold"
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# --- guards in the mutating entrypoints ---------------------------------------
|
|
197
|
+
|
|
198
|
+
test_mutating_scripts_refuse_the_other_actors_lease() {
|
|
199
|
+
local home root out status
|
|
200
|
+
local -x PI_CODING_AGENT=true
|
|
201
|
+
home="$TMP_ROOT/guard-home"
|
|
202
|
+
root="$TMP_ROOT/guard-root"
|
|
203
|
+
mkdir -p "$home/state" "$root"
|
|
204
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
205
|
+
git init -q -b main "$root"
|
|
206
|
+
git -C "$root" commit -q --allow-empty -m init
|
|
207
|
+
ln -s "$ROOT/bin" "$root/bin"
|
|
208
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-held --actor branch \
|
|
209
|
+
|| fail "fixture lease claim failed"
|
|
210
|
+
|
|
211
|
+
# fm-control: refused while the branch holds the lease; the ordinary no-task
|
|
212
|
+
# error (a different failure) proves pass-through once the lease is gone.
|
|
213
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-control.sh" task-held interrupt 2>&1)
|
|
214
|
+
status=$?
|
|
215
|
+
[ "$status" -eq 6 ] || fail "leased fm-control exited $status, not 6: $out"
|
|
216
|
+
assert_contains "$out" "leased to the branch supervision actor" "fm-control refusal lost the holder"
|
|
217
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-control.sh" task-unheld interrupt 2>&1)
|
|
218
|
+
status=$?
|
|
219
|
+
[ "$status" -ne 6 ] || fail "unleased fm-control still hit the lease refusal"
|
|
220
|
+
assert_contains "$out" "no task 'task-unheld'" "unleased fm-control lost its ordinary error"
|
|
221
|
+
|
|
222
|
+
# fm-teardown: same refusal shape before any teardown work.
|
|
223
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-teardown.sh" task-held 2>&1)
|
|
224
|
+
status=$?
|
|
225
|
+
[ "$status" -eq 6 ] || fail "leased fm-teardown exited $status, not 6: $out"
|
|
226
|
+
assert_contains "$out" "teardown (fm-teardown) refused" "fm-teardown refusal lost its action label"
|
|
227
|
+
|
|
228
|
+
# The same lease refuses the BRANCH actor when MAIN holds it - the guard is
|
|
229
|
+
# symmetric, not a branch-only fence.
|
|
230
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-lease.sh" release task-held --actor branch
|
|
231
|
+
FM_HOME="$home" FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-held --actor main \
|
|
232
|
+
|| fail "main fixture claim failed"
|
|
233
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-control.sh" task-held interrupt 2>&1)
|
|
234
|
+
status=$?
|
|
235
|
+
[ "$status" -eq 6 ] || fail "branch actor bypassed main's lease: $status: $out"
|
|
236
|
+
assert_contains "$out" "leased to the main supervision actor" "symmetric refusal lost the holder"
|
|
237
|
+
pass "fm-control and fm-teardown refuse the other actor's live lease and pass through otherwise"
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
test_main_owned_actions_refuse_the_branch_actor() {
|
|
241
|
+
local home root out status
|
|
242
|
+
home="$TMP_ROOT/partition-home"
|
|
243
|
+
root="$TMP_ROOT/partition-root"
|
|
244
|
+
mkdir -p "$home/state" "$root"
|
|
245
|
+
git init -q -b main "$root"
|
|
246
|
+
git -C "$root" commit -q --allow-empty -m init
|
|
247
|
+
ln -s "$ROOT/bin" "$root/bin"
|
|
248
|
+
|
|
249
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-pr-merge.sh" task-x https://github.com/o/r/pull/1 2>&1)
|
|
250
|
+
status=$?
|
|
251
|
+
[ "$status" -eq 6 ] || fail "branch fm-pr-merge exited $status, not 6: $out"
|
|
252
|
+
assert_contains "$out" "the supervision branch never performs this action" "pr-merge refusal lost the partition wording"
|
|
253
|
+
|
|
254
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-merge-local.sh" task-x 2>&1)
|
|
255
|
+
status=$?
|
|
256
|
+
[ "$status" -eq 6 ] || fail "branch fm-merge-local exited $status, not 6: $out"
|
|
257
|
+
|
|
258
|
+
out=$(FM_HOME="$home" FM_ROOT_OVERRIDE="$root" FM_SUPERVISION_ACTOR=branch \
|
|
259
|
+
"$ROOT/bin/fm-spawn.sh" task-new --mode no-mistakes --yolo off 2>&1)
|
|
260
|
+
status=$?
|
|
261
|
+
[ "$status" -eq 6 ] || fail "branch fm-spawn exited $status, not 6: $out"
|
|
262
|
+
assert_contains "$out" "new-task spawn (fm-spawn) refused" "spawn refusal lost its action label"
|
|
263
|
+
|
|
264
|
+
# The same calls as MAIN fail on their ORDINARY validation instead - the
|
|
265
|
+
# partition guard never fires for the main actor.
|
|
266
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-merge-local.sh" task-x 2>&1)
|
|
267
|
+
status=$?
|
|
268
|
+
[ "$status" -ne 6 ] || fail "main fm-merge-local hit the partition refusal"
|
|
269
|
+
assert_contains "$out" "no meta for task task-x" "main fm-merge-local lost its ordinary error"
|
|
270
|
+
pass "PR merge, local landing, and new-task spawn refuse the branch actor and spare main"
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
test_home_without_branch_is_untouched() {
|
|
274
|
+
local home out status
|
|
275
|
+
home="$TMP_ROOT/untouched-home"
|
|
276
|
+
mkdir -p "$home/state"
|
|
277
|
+
|
|
278
|
+
# No lease files, no actor variable: the guard layer must be invisible - the
|
|
279
|
+
# scripts fail (or succeed) exactly on their pre-existing logic, and nothing
|
|
280
|
+
# branch-related appears in state/.
|
|
281
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-control.sh" task-any interrupt 2>&1)
|
|
282
|
+
status=$?
|
|
283
|
+
[ "$status" -ne 6 ] || fail "no-branch home hit a lease refusal in fm-control"
|
|
284
|
+
assert_contains "$out" "no task 'task-any'" "no-branch fm-control lost its ordinary error"
|
|
285
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-pr-merge.sh" 2>&1)
|
|
286
|
+
status=$?
|
|
287
|
+
[ "$status" -eq 2 ] || fail "no-branch fm-pr-merge usage error changed: $status: $out"
|
|
288
|
+
[ -z "$(find "$home/state" -name '.lease-*' -o -name 'branch-outcomes*' -o -name '.branch-*' 2>/dev/null)" ] \
|
|
289
|
+
|| fail "guard layer created branch state in a home that never ran the branch"
|
|
290
|
+
|
|
291
|
+
# A stale Pi marker and recycled-but-live lease pid cannot activate leases in
|
|
292
|
+
# a no-lock Claude home; the guard removes the leftover and passes silently.
|
|
293
|
+
printf 'harness=claude\n' > "$home/state/fake.meta"
|
|
294
|
+
printf '%s\n' "$PPID" > "$home/state/.pi-branch-extension-loaded"
|
|
295
|
+
printf 'branch\t%s\t123\n' "$PPID" > "$home/state/.lease-task-reused"
|
|
296
|
+
out=$(STATE="$home/state" bash -c '. "$1"; fm_lease_guard task-reused "probe"; fm_lease_forbid_branch "probe"; echo silent-pass' _ "$ROOT/bin/fm-lease-lib.sh" 2>&1)
|
|
297
|
+
[ "$out" = "silent-pass" ] || fail "guard helpers honored a leftover Pi lease in a no-lock Claude home: $out"
|
|
298
|
+
[ ! -e "$home/state/.lease-task-reused" ] || fail "guard kept a leftover Pi lease without a session lock"
|
|
299
|
+
|
|
300
|
+
printf '%s\n' "$PPID" > "$home/state/.lock"
|
|
301
|
+
printf 'branch\t%s\t123\n' "$PPID" > "$home/state/.lease-task-reused"
|
|
302
|
+
# The positional parameter belongs to the nested shell.
|
|
303
|
+
# shellcheck disable=SC2016
|
|
304
|
+
out=$(env -u PI_CODING_AGENT -u FM_SUPERVISION_ACTOR CLAUDECODE=1 STATE="$home/state" bash -c '. "$1"; fm_lease_guard task-reused "probe"; echo silent-pass' _ "$ROOT/bin/fm-lease-lib.sh" 2>&1)
|
|
305
|
+
[ "$out" = "silent-pass" ] || fail "guard helpers honored a reused-pid Pi lease in a Claude context: $out"
|
|
306
|
+
[ ! -e "$home/state/.lease-task-reused" ] || fail "Claude context kept a Pi lease whose old pid matched its current lock"
|
|
307
|
+
pass "a non-Pi home ignores stale Pi leases even when the recycled pid owns its lock"
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
# --- session-bound staleness and the loud accidental-override guard ---------
|
|
311
|
+
|
|
312
|
+
test_lease_liveness_binds_to_the_session_lock() {
|
|
313
|
+
local home out
|
|
314
|
+
local -x PI_CODING_AGENT=true
|
|
315
|
+
home="$TMP_ROOT/lock-bound-home"
|
|
316
|
+
mkdir -p "$home/state"
|
|
317
|
+
|
|
318
|
+
# A lease recorded by a pid that is alive but is NOT the current session-lock
|
|
319
|
+
# holder is stale: a Pi session exited and its pid was recycled, or a non-Pi
|
|
320
|
+
# harness now owns this home. Either way the leftover lease must not bind.
|
|
321
|
+
printf '%s\n' "$$" > "$home/state/.lock.other"
|
|
322
|
+
printf 'branch\t%s\t123\n' "$PPID" > "$home/state/.lease-task-reused"
|
|
323
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
324
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-lease.sh" check task-reused) || fail "check missed the leftover lease"
|
|
325
|
+
case "$out" in
|
|
326
|
+
*" stale") ;;
|
|
327
|
+
*) fail "an alive non-lock-holder pid read as live: $out" ;;
|
|
328
|
+
esac
|
|
329
|
+
FM_HOME="$home" "$ROOT/bin/fm-lease.sh" sweep || fail "sweep failed"
|
|
330
|
+
[ ! -e "$home/state/.lease-task-reused" ] || fail "sweep kept a lease whose pid is not the lock holder"
|
|
331
|
+
|
|
332
|
+
# The same pid IS live while the lock names it.
|
|
333
|
+
FM_HOME="$home" FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-current --actor main \
|
|
334
|
+
|| fail "claim under the current lock holder failed"
|
|
335
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-lease.sh" check task-current)
|
|
336
|
+
case "$out" in
|
|
337
|
+
"main $$ "*" live") ;;
|
|
338
|
+
*) fail "the current lock holder's lease did not read live: $out" ;;
|
|
339
|
+
esac
|
|
340
|
+
|
|
341
|
+
printf '%sjunk\n' "$$" > "$home/state/.lock"
|
|
342
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-lease.sh" check task-current) || fail "check missed the lease under a malformed lock"
|
|
343
|
+
case "$out" in
|
|
344
|
+
*" stale") ;;
|
|
345
|
+
*) fail "a malformed lock proved lease liveness: $out" ;;
|
|
346
|
+
esac
|
|
347
|
+
FM_HOME="$home" "$ROOT/bin/fm-lease.sh" sweep || fail "sweep under malformed lock failed"
|
|
348
|
+
[ ! -e "$home/state/.lease-task-current" ] || fail "sweep kept a lease proven only by a malformed lock"
|
|
349
|
+
pass "lease liveness requires an exact valid session-lock pid"
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
test_concurrent_stale_lease_claims_have_one_winner() {
|
|
353
|
+
local home fakebin real_mv branch_pid main_pid branch_status main_status
|
|
354
|
+
local -x PI_CODING_AGENT=true
|
|
355
|
+
home="$TMP_ROOT/concurrent-lease-home"
|
|
356
|
+
fakebin="$TMP_ROOT/concurrent-lease-bin"
|
|
357
|
+
mkdir -p "$home/state" "$fakebin"
|
|
358
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
359
|
+
printf 'branch\t999999\t123\n' > "$home/state/.lease-task-race"
|
|
360
|
+
real_mv=$(command -v mv)
|
|
361
|
+
cat > "$fakebin/mv" <<'SH'
|
|
362
|
+
#!/usr/bin/env bash
|
|
363
|
+
last=${!#}
|
|
364
|
+
if [ "$last" = "$FM_TEST_LEASE_PATH" ] && mkdir "$FM_TEST_GATE.once" 2>/dev/null; then
|
|
365
|
+
: > "$FM_TEST_GATE.ready"
|
|
366
|
+
while [ ! -e "$FM_TEST_GATE.release" ]; do sleep 0.01; done
|
|
367
|
+
fi
|
|
368
|
+
exec "$FM_TEST_REAL_MV" "$@"
|
|
369
|
+
SH
|
|
370
|
+
chmod +x "$fakebin/mv"
|
|
371
|
+
|
|
372
|
+
PATH="$fakebin:$PATH" FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ \
|
|
373
|
+
FM_TEST_REAL_MV="$real_mv" FM_TEST_LEASE_PATH="$home/state/.lease-task-race" FM_TEST_GATE="$home/state/gate" \
|
|
374
|
+
"$ROOT/bin/fm-lease.sh" claim task-race --actor branch >/dev/null 2>&1 &
|
|
375
|
+
branch_pid=$!
|
|
376
|
+
while [ ! -e "$home/state/gate.ready" ]; do sleep 0.01; done
|
|
377
|
+
PATH="$fakebin:$PATH" FM_HOME="$home" FM_SUPERVISION_ACTOR=main FM_LEASE_HOLDER_PID=$$ \
|
|
378
|
+
FM_TEST_REAL_MV="$real_mv" FM_TEST_LEASE_PATH="$home/state/.lease-task-race" FM_TEST_GATE="$home/state/gate" \
|
|
379
|
+
"$ROOT/bin/fm-lease.sh" claim task-race --actor main >/dev/null 2>&1 &
|
|
380
|
+
main_pid=$!
|
|
381
|
+
sleep 0.1
|
|
382
|
+
: > "$home/state/gate.release"
|
|
383
|
+
wait "$branch_pid"; branch_status=$?
|
|
384
|
+
wait "$main_pid"; main_status=$?
|
|
385
|
+
[ "$branch_status" -eq 0 ] || fail "first serialized lease claim failed with $branch_status"
|
|
386
|
+
[ "$main_status" -eq 6 ] || fail "concurrent lease claim also succeeded or returned $main_status"
|
|
387
|
+
pass "concurrent stale-lease claims serialize so exactly one actor succeeds"
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
test_guard_stale_clear_cannot_delete_a_new_claim() {
|
|
391
|
+
local home fakebin real_rm guard_pid claim_pid guard_status claim_status out
|
|
392
|
+
local -x PI_CODING_AGENT=true
|
|
393
|
+
home="$TMP_ROOT/guard-claim-race-home"
|
|
394
|
+
fakebin="$TMP_ROOT/guard-claim-race-bin"
|
|
395
|
+
mkdir -p "$home/state" "$fakebin"
|
|
396
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
397
|
+
printf 'main\t999999\t123\n' > "$home/state/.lease-task-race"
|
|
398
|
+
real_rm=$(command -v rm)
|
|
399
|
+
cat > "$fakebin/rm" <<'SH'
|
|
400
|
+
#!/usr/bin/env bash
|
|
401
|
+
last=${!#}
|
|
402
|
+
if [ "$last" = "$FM_TEST_STALE_PATH" ] && mkdir "$FM_TEST_GATE.once" 2>/dev/null; then
|
|
403
|
+
: > "$FM_TEST_GATE.ready"
|
|
404
|
+
while [ ! -e "$FM_TEST_GATE.release" ]; do sleep 0.01; done
|
|
405
|
+
fi
|
|
406
|
+
exec "$FM_TEST_REAL_RM" "$@"
|
|
407
|
+
SH
|
|
408
|
+
chmod +x "$fakebin/rm"
|
|
409
|
+
|
|
410
|
+
PATH="$fakebin:$PATH" STATE="$home/state" FM_TEST_REAL_RM="$real_rm" \
|
|
411
|
+
FM_TEST_STALE_PATH="$home/state/.lease-task-race" FM_TEST_GATE="$home/state/gate" \
|
|
412
|
+
bash -c '. "$1"; fm_lease_guard task-race "probe"' _ "$ROOT/bin/fm-lease-lib.sh" &
|
|
413
|
+
guard_pid=$!
|
|
414
|
+
while [ ! -e "$home/state/gate.ready" ]; do sleep 0.01; done
|
|
415
|
+
PATH="$fakebin:$PATH" FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ \
|
|
416
|
+
FM_TEST_REAL_RM="$real_rm" FM_TEST_STALE_PATH="$home/state/.lease-task-race" FM_TEST_GATE="$home/state/gate" \
|
|
417
|
+
"$ROOT/bin/fm-lease.sh" claim task-race --actor branch >/dev/null 2>&1 &
|
|
418
|
+
claim_pid=$!
|
|
419
|
+
sleep 0.1
|
|
420
|
+
: > "$home/state/gate.release"
|
|
421
|
+
wait "$guard_pid"; guard_status=$?
|
|
422
|
+
wait "$claim_pid"; claim_status=$?
|
|
423
|
+
[ "$guard_status" -eq 0 ] || fail "guard stale cleanup failed with $guard_status"
|
|
424
|
+
[ "$claim_status" -eq 0 ] || fail "serialized claim failed with $claim_status"
|
|
425
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-lease.sh" check task-race) || fail "guard deleted the newer lease claim"
|
|
426
|
+
case "$out" in
|
|
427
|
+
"branch $$ "*" live") ;;
|
|
428
|
+
*) fail "newer claim was not preserved as live: $out" ;;
|
|
429
|
+
esac
|
|
430
|
+
pass "guard stale cleanup cannot race with or delete a newer lease claim"
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
test_guard_holds_exclusivity_through_mutation() {
|
|
434
|
+
local home operation_pid claim_pid claim_status
|
|
435
|
+
home="$TMP_ROOT/guard-mutation-home"
|
|
436
|
+
mkdir -p "$home/state"
|
|
437
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
438
|
+
|
|
439
|
+
PI_CODING_AGENT=true STATE="$home/state" FM_TEST_READY="$home/operation-ready" \
|
|
440
|
+
FM_TEST_RELEASE="$home/operation-release" bash -c '
|
|
441
|
+
. "$1"
|
|
442
|
+
fm_lease_guard task-race "probe"
|
|
443
|
+
trap "fm_lease_guard_release" EXIT
|
|
444
|
+
: > "$FM_TEST_READY"
|
|
445
|
+
while [ ! -e "$FM_TEST_RELEASE" ]; do sleep 0.01; done
|
|
446
|
+
' _ "$ROOT/bin/fm-lease-lib.sh" &
|
|
447
|
+
operation_pid=$!
|
|
448
|
+
while [ ! -e "$home/operation-ready" ]; do sleep 0.01; done
|
|
449
|
+
|
|
450
|
+
PI_CODING_AGENT=true FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ \
|
|
451
|
+
"$ROOT/bin/fm-lease.sh" claim task-race --actor branch >/dev/null 2>&1 &
|
|
452
|
+
claim_pid=$!
|
|
453
|
+
sleep 0.2
|
|
454
|
+
kill -0 "$claim_pid" 2>/dev/null \
|
|
455
|
+
|| fail "the other actor claimed while the guarded mutation was still running"
|
|
456
|
+
[ ! -e "$home/state/.lease-task-race" ] \
|
|
457
|
+
|| fail "the concurrent claim published a lease before the guarded mutation ended"
|
|
458
|
+
|
|
459
|
+
: > "$home/operation-release"
|
|
460
|
+
wait "$operation_pid" || fail "guarded mutation fixture failed"
|
|
461
|
+
wait "$claim_pid"; claim_status=$?
|
|
462
|
+
[ "$claim_status" -eq 0 ] || fail "claim did not proceed after guarded mutation ended: $claim_status"
|
|
463
|
+
pass "lease guard excludes a concurrent actor for the complete mutation"
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
test_claim_refuses_the_other_actors_name_loudly() {
|
|
467
|
+
local home out status
|
|
468
|
+
home="$TMP_ROOT/claim-guard-home"
|
|
469
|
+
mkdir -p "$home/state"
|
|
470
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ \
|
|
471
|
+
"$ROOT/bin/fm-lease.sh" claim task-z --actor main 2>&1)
|
|
472
|
+
status=$?
|
|
473
|
+
[ "$status" -eq 6 ] || fail "cross-actor claim exited $status, not 6: $out"
|
|
474
|
+
assert_contains "$out" "cannot claim a lease as main" "accidental-override refusal lost its wording"
|
|
475
|
+
[ ! -e "$home/state/.lease-task-z" ] || fail "refused claim still created a lease"
|
|
476
|
+
pass "a claim naming the other actor fails loudly instead of silently impersonating it"
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
test_release_actor_drops_only_that_actors_leases() {
|
|
480
|
+
local home out status
|
|
481
|
+
local -x PI_CODING_AGENT=true
|
|
482
|
+
home="$TMP_ROOT/release-actor-home"
|
|
483
|
+
mkdir -p "$home/state"
|
|
484
|
+
printf '%s\n' "$$" > "$home/state/.lock"
|
|
485
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-a --actor branch \
|
|
486
|
+
|| fail "branch claim failed"
|
|
487
|
+
FM_HOME="$home" FM_LEASE_HOLDER_PID=$$ "$ROOT/bin/fm-lease.sh" claim task-b --actor main \
|
|
488
|
+
|| fail "main claim failed"
|
|
489
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-lease.sh" release task-b --actor main 2>&1)
|
|
490
|
+
status=$?
|
|
491
|
+
[ "$status" -eq 6 ] || fail "branch release of main lease exited $status, not 6: $out"
|
|
492
|
+
assert_contains "$out" "cannot release a lease as main" "cross-actor release refusal lost its diagnostic"
|
|
493
|
+
[ -e "$home/state/.lease-task-b" ] || fail "refused release removed main's lease"
|
|
494
|
+
|
|
495
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-lease.sh" release-actor --actor main 2>&1)
|
|
496
|
+
status=$?
|
|
497
|
+
[ "$status" -eq 6 ] || fail "branch release-actor of main leases exited $status, not 6: $out"
|
|
498
|
+
assert_contains "$out" "cannot release leases as main" "cross-actor bulk release refusal lost its diagnostic"
|
|
499
|
+
[ -e "$home/state/.lease-task-b" ] || fail "refused bulk release removed main's lease"
|
|
500
|
+
|
|
501
|
+
FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-lease.sh" release-actor --actor branch || fail "release-actor failed"
|
|
502
|
+
[ ! -e "$home/state/.lease-task-a" ] || fail "release-actor kept the branch lease"
|
|
503
|
+
[ -e "$home/state/.lease-task-b" ] || fail "release-actor dropped main's lease"
|
|
504
|
+
pass "release commands authorize the caller and bulk release drops only that actor's leases"
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
# --- role-partition refinements ----------------------------------------------
|
|
508
|
+
|
|
509
|
+
test_branch_cannot_force_teardown_or_directly_relaunch() {
|
|
510
|
+
local home root out status
|
|
511
|
+
home="$TMP_ROOT/partition2-home"
|
|
512
|
+
root="$TMP_ROOT/partition2-root"
|
|
513
|
+
mkdir -p "$home/state" "$root"
|
|
514
|
+
git init -q -b main "$root"
|
|
515
|
+
git -C "$root" commit -q --allow-empty -m init
|
|
516
|
+
ln -s "$ROOT/bin" "$root/bin"
|
|
517
|
+
|
|
518
|
+
# Forced teardown discards work; the branch never discards anything.
|
|
519
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-teardown.sh" task-x --force 2>&1)
|
|
520
|
+
status=$?
|
|
521
|
+
[ "$status" -eq 6 ] || fail "branch forced teardown exited $status, not 6: $out"
|
|
522
|
+
assert_contains "$out" "cannot discard work" "forced-teardown refusal lost its wording"
|
|
523
|
+
# An ORDINARY branch teardown is not blocked by this guard (it fails later
|
|
524
|
+
# on its ordinary no-task validation instead).
|
|
525
|
+
out=$(FM_HOME="$home" FM_SUPERVISION_ACTOR=branch "$ROOT/bin/fm-teardown.sh" task-x 2>&1)
|
|
526
|
+
status=$?
|
|
527
|
+
[ "$status" -ne 6 ] || fail "ordinary branch teardown hit the forced-discard refusal: $out"
|
|
528
|
+
|
|
529
|
+
# A branch relaunch is legal only through fm-control's owned transaction,
|
|
530
|
+
# never by direct fm-spawn invocation.
|
|
531
|
+
out=$(FM_HOME="$home" FM_ROOT_OVERRIDE="$root" FM_SUPERVISION_ACTOR=branch \
|
|
532
|
+
"$ROOT/bin/fm-spawn.sh" task-x --relaunch 2>&1)
|
|
533
|
+
status=$?
|
|
534
|
+
[ "$status" -eq 6 ] || fail "direct branch relaunch exited $status, not 6: $out"
|
|
535
|
+
assert_contains "$out" "must relaunch through fm-control" "relaunch refusal lost its wording"
|
|
536
|
+
pass "the branch cannot force a teardown or bypass fm-control for a relaunch"
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
test_branch_prompt_is_byte_stable_and_above_cache_floor
|
|
540
|
+
test_outcome_store_is_append_only_with_cursor_reads
|
|
541
|
+
test_outcome_startup_replay_preserves_silence
|
|
542
|
+
test_lease_exclusivity_release_stale_and_sweep
|
|
543
|
+
test_mutating_scripts_refuse_the_other_actors_lease
|
|
544
|
+
test_main_owned_actions_refuse_the_branch_actor
|
|
545
|
+
test_home_without_branch_is_untouched
|
|
546
|
+
test_lease_liveness_binds_to_the_session_lock
|
|
547
|
+
test_concurrent_stale_lease_claims_have_one_winner
|
|
548
|
+
test_guard_stale_clear_cannot_delete_a_new_claim
|
|
549
|
+
test_guard_holds_exclusivity_through_mutation
|
|
550
|
+
test_claim_refuses_the_other_actors_name_loudly
|
|
551
|
+
test_release_actor_drops_only_that_actors_leases
|
|
552
|
+
test_branch_cannot_force_teardown_or_directly_relaunch
|