@zerwiz/ymir 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +291 -0
- package/.agents/agents/bragi-marketer.md +111 -0
- package/.agents/agents/brokk.md +352 -0
- package/.agents/agents/forseti-reviewer.md +93 -0
- package/.agents/agents/frigg-consent.md +77 -0
- package/.agents/agents/groa-update.md +77 -0
- package/.agents/agents/hnoss-designer.md +69 -0
- package/.agents/agents/huginn-researcher.md +99 -0
- package/.agents/agents/jord-projects.md +78 -0
- package/.agents/agents/kvasir-scout.md +91 -0
- package/.agents/agents/mimir-planner.md +92 -0
- package/.agents/agents/muninn-stow.md +77 -0
- package/.agents/agents/saga-bearings.md +78 -0
- package/.agents/agents/sindri-developer.md +114 -0
- package/.agents/agents/snotra-documenter.md +105 -0
- package/.agents/agents/syn-recovery.md +78 -0
- package/.agents/agents/tyr-check.md +78 -0
- package/.agents/agents/urdh-hold.md +77 -0
- package/.agents/agents/volundr-smith.md +80 -0
- package/.agents/agents/vor-diagnostics.md +77 -0
- package/.agents/assets/agents/naming.md +50 -0
- package/.agents/assets/agents/registry.md +93 -0
- package/.agents/assets/agents/runtime.md +36 -0
- package/.agents/assets/agents/toon-tasks-cli.md +42 -0
- package/.agents/assets/templates/company_entity.template.md +37 -0
- package/.agents/backend/backends/cmux.sh +649 -0
- package/.agents/backend/backends/herdr-eventwait.py +157 -0
- package/.agents/backend/backends/herdr-workspace-move.py +114 -0
- package/.agents/backend/backends/herdr.sh +3386 -0
- package/.agents/backend/backends/orca.sh +290 -0
- package/.agents/backend/backends/tmux.sh +357 -0
- package/.agents/backend/backends/zellij.sh +700 -0
- package/.agents/backend/fm-afk-launch.sh +654 -0
- package/.agents/backend/fm-afk-return.sh +241 -0
- package/.agents/backend/fm-afk-start.sh +172 -0
- package/.agents/backend/fm-arm-command-policy.mjs +960 -0
- package/.agents/backend/fm-arm-pretool-check.sh +200 -0
- package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
- package/.agents/backend/fm-backend.sh +981 -0
- package/.agents/backend/fm-backlog-handoff.sh +909 -0
- package/.agents/backend/fm-backlog-receive.sh +187 -0
- package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
- package/.agents/backend/fm-bearings-board.sh +204 -0
- package/.agents/backend/fm-bearings-snapshot.sh +546 -0
- package/.agents/backend/fm-bootstrap.sh +1568 -0
- package/.agents/backend/fm-branch-outcome.sh +203 -0
- package/.agents/backend/fm-branch-prompt.sh +101 -0
- package/.agents/backend/fm-brief.sh +452 -0
- package/.agents/backend/fm-busy-event.sh +234 -0
- package/.agents/backend/fm-busy-lib.sh +986 -0
- package/.agents/backend/fm-captain-hold.sh +1001 -0
- package/.agents/backend/fm-cd-command-policy.mjs +153 -0
- package/.agents/backend/fm-cd-pretool-check.sh +190 -0
- package/.agents/backend/fm-check-lib.sh +74 -0
- package/.agents/backend/fm-check-register.sh +42 -0
- package/.agents/backend/fm-check-unregister.sh +52 -0
- package/.agents/backend/fm-classify-lib.sh +1770 -0
- package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
- package/.agents/backend/fm-composer-lib.sh +1416 -0
- package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
- package/.agents/backend/fm-config-push.sh +254 -0
- package/.agents/backend/fm-control-lib.sh +251 -0
- package/.agents/backend/fm-control.sh +878 -0
- package/.agents/backend/fm-crew-state.sh +625 -0
- package/.agents/backend/fm-cursor-lib.sh +243 -0
- package/.agents/backend/fm-decision-hold.sh +232 -0
- package/.agents/backend/fm-doc-audience-check.sh +269 -0
- package/.agents/backend/fm-dod-lib.sh +67 -0
- package/.agents/backend/fm-ensure-agents-md.sh +253 -0
- package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
- package/.agents/backend/fm-extension.mjs +2577 -0
- package/.agents/backend/fm-extension.sh +16 -0
- package/.agents/backend/fm-ff-lib.sh +420 -0
- package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
- package/.agents/backend/fm-fleet-sync.sh +458 -0
- package/.agents/backend/fm-fleet-view.sh +96 -0
- package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
- package/.agents/backend/fm-guard.sh +242 -0
- package/.agents/backend/fm-harness.sh +195 -0
- package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
- package/.agents/backend/fm-herdr-lab.sh +346 -0
- package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
- package/.agents/backend/fm-home-seed.sh +984 -0
- package/.agents/backend/fm-home-summary-refresh.sh +255 -0
- package/.agents/backend/fm-hook-host-lib.sh +36 -0
- package/.agents/backend/fm-inactive-reconcile.sh +531 -0
- package/.agents/backend/fm-inbox.sh +399 -0
- package/.agents/backend/fm-install-actionlint.sh +84 -0
- package/.agents/backend/fm-install-herdr.sh +96 -0
- package/.agents/backend/fm-install-shellcheck.sh +84 -0
- package/.agents/backend/fm-install-treehouse.sh +95 -0
- package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
- package/.agents/backend/fm-lease-lib.sh +218 -0
- package/.agents/backend/fm-lease.sh +189 -0
- package/.agents/backend/fm-line-cap-lib.sh +51 -0
- package/.agents/backend/fm-lint-workflows.sh +137 -0
- package/.agents/backend/fm-lint.sh +591 -0
- package/.agents/backend/fm-lock-lib.sh +104 -0
- package/.agents/backend/fm-lock.sh +107 -0
- package/.agents/backend/fm-marker-lib.sh +12 -0
- package/.agents/backend/fm-merge-local.sh +74 -0
- package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
- package/.agents/backend/fm-nm-run-lib.sh +124 -0
- package/.agents/backend/fm-on.sh +125 -0
- package/.agents/backend/fm-operational-input.sh +253 -0
- package/.agents/backend/fm-peek.sh +46 -0
- package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
- package/.agents/backend/fm-pr-check.sh +135 -0
- package/.agents/backend/fm-pr-lib.sh +1016 -0
- package/.agents/backend/fm-pr-merge.sh +707 -0
- package/.agents/backend/fm-pr-poll.sh +110 -0
- package/.agents/backend/fm-primary-scope-lib.sh +33 -0
- package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
- package/.agents/backend/fm-procevent-lavish.sh +628 -0
- package/.agents/backend/fm-procevent-lib.sh +892 -0
- package/.agents/backend/fm-procevent-quota.sh +290 -0
- package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
- package/.agents/backend/fm-procevent-when.sh +504 -0
- package/.agents/backend/fm-procevent.sh +1466 -0
- package/.agents/backend/fm-project-mode.sh +92 -0
- package/.agents/backend/fm-project-origin-lib.sh +180 -0
- package/.agents/backend/fm-promote.sh +282 -0
- package/.agents/backend/fm-public-followup-emit.sh +260 -0
- package/.agents/backend/fm-public-followup-lib.sh +398 -0
- package/.agents/backend/fm-public-followup.sh +1330 -0
- package/.agents/backend/fm-push-transition-lib.sh +168 -0
- package/.agents/backend/fm-quota-axi-lib.sh +93 -0
- package/.agents/backend/fm-quota-choose.sh +384 -0
- package/.agents/backend/fm-remote-delta-read.sh +189 -0
- package/.agents/backend/fm-remote-doctor.sh +800 -0
- package/.agents/backend/fm-remote-entrypoint.sh +193 -0
- package/.agents/backend/fm-remote-file.sh +234 -0
- package/.agents/backend/fm-remote-home-provision.sh +259 -0
- package/.agents/backend/fm-remote-home-seed.sh +259 -0
- package/.agents/backend/fm-remote-inherit-push.sh +90 -0
- package/.agents/backend/fm-remote-inherit.sh +179 -0
- package/.agents/backend/fm-remote-job-lib.sh +1241 -0
- package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
- package/.agents/backend/fm-remote-job-worker.sh +1124 -0
- package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
- package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
- package/.agents/backend/fm-review-diff.sh +158 -0
- package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
- package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
- package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
- package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
- package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
- package/.agents/backend/fm-secondmate-report.sh +88 -0
- package/.agents/backend/fm-send.sh +1059 -0
- package/.agents/backend/fm-session-lock-lib.sh +176 -0
- package/.agents/backend/fm-session-start.sh +970 -0
- package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
- package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
- package/.agents/backend/fm-sessionstart-run.sh +145 -0
- package/.agents/backend/fm-spawn.sh +3153 -0
- package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
- package/.agents/backend/fm-startup-memory-budget.sh +94 -0
- package/.agents/backend/fm-startup-network.sh +642 -0
- package/.agents/backend/fm-stow-cascade.sh +251 -0
- package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
- package/.agents/backend/fm-supervise-daemon.sh +1732 -0
- package/.agents/backend/fm-supervision-instructions.sh +215 -0
- package/.agents/backend/fm-supervision-lib.sh +90 -0
- package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
- package/.agents/backend/fm-tangle-lib.sh +53 -0
- package/.agents/backend/fm-task-inbox-lib.sh +402 -0
- package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
- package/.agents/backend/fm-teardown.sh +2922 -0
- package/.agents/backend/fm-test-isolation-proof.sh +588 -0
- package/.agents/backend/fm-test-run.sh +2191 -0
- package/.agents/backend/fm-timeout-lib.sh +141 -0
- package/.agents/backend/fm-timing-lib.sh +179 -0
- package/.agents/backend/fm-tmux-lib.sh +291 -0
- package/.agents/backend/fm-tool-update-check.sh +898 -0
- package/.agents/backend/fm-trace-context-lib.sh +227 -0
- package/.agents/backend/fm-transition-lib.sh +103 -0
- package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
- package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
- package/.agents/backend/fm-turnend-guard.sh +432 -0
- package/.agents/backend/fm-update.sh +110 -0
- package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
- package/.agents/backend/fm-voice-client.py +1373 -0
- package/.agents/backend/fm-voice-relay.py +1256 -0
- package/.agents/backend/fm-wake-drain.sh +592 -0
- package/.agents/backend/fm-wake-grant.sh +127 -0
- package/.agents/backend/fm-wake-lib.sh +1849 -0
- package/.agents/backend/fm-watch-arm.sh +602 -0
- package/.agents/backend/fm-watch-checkpoint.sh +109 -0
- package/.agents/backend/fm-watch.sh +1962 -0
- package/.agents/backend/fm-x-dismiss.sh +116 -0
- package/.agents/backend/fm-x-followup.sh +286 -0
- package/.agents/backend/fm-x-lib.sh +1000 -0
- package/.agents/backend/fm-x-link.sh +234 -0
- package/.agents/backend/fm-x-poll.sh +185 -0
- package/.agents/backend/fm-x-reply.sh +385 -0
- package/.agents/backend/fm_voice_frame.py +166 -0
- package/.agents/backend/fm_voice_records.py +574 -0
- package/.agents/backend/model-bridge.py +290 -0
- package/.agents/backend/opencode-go-bridge.py +30 -0
- package/.agents/bus/README.md +12 -0
- package/.agents/bus/messages.json +1 -0
- package/.agents/config/agents.machine.example.yaml +16 -0
- package/.agents/config/agents.yaml +50 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +9 -0
- package/.agents/config/eindri-dispatch.json +67 -0
- package/.agents/config/eindri-harness +1 -0
- package/.agents/config/startup-memory-budget +1 -0
- package/.agents/config/tailscale-sync.yaml +27 -0
- package/.agents/filebrowser/.filebrowser.json +6 -0
- package/.agents/filebrowser/README.md +11 -0
- package/.agents/gateway/README.md +12 -0
- package/.agents/github/README.md +15 -0
- package/.agents/github/webhooks/.gitkeep +0 -0
- package/.agents/github/workflows/.gitkeep +0 -0
- package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
- package/.agents/harness/opencode/plugins/package.json +4 -0
- package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
- package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
- package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
- package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
- package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
- package/.agents/memory/README.md +46 -0
- package/.agents/memory/kaia.engram +0 -0
- package/.agents/memory/kaia.engram-shm +0 -0
- package/.agents/memory/kaia.engram-wal +0 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/memory/well/episodes.jsonl +367 -0
- package/.agents/memory/well/workspace.jsonl +27 -0
- package/.agents/migrations/0001-hodd-layout.sh +38 -0
- package/.agents/migrations/0002-a2a-mcp.sh +27 -0
- package/.agents/migrations/0003-private-data-separation.sh +111 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/sandbox/Dockerfile.utgard +19 -0
- package/.agents/sandbox/README.md +14 -0
- package/.agents/sandbox/utgard.config.json +14 -0
- package/.agents/skills/README.md +59 -0
- package/.agents/skills/bragi-marketing/README.md +3 -0
- package/.agents/skills/bragi-marketing/SKILL.md +82 -0
- package/.agents/skills/eindri-homes/README.md +3 -0
- package/.agents/skills/eindri-homes/SKILL.md +291 -0
- package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
- package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
- package/.agents/skills/frigg-consent/README.md +3 -0
- package/.agents/skills/frigg-consent/SKILL.md +56 -0
- package/.agents/skills/galdr-ymirsystem/README.md +3 -0
- package/.agents/skills/galdr-ymirsystem/SKILL.md +158 -0
- package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
- package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +673 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
- package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +496 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
- package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +161 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +96 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
- package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
- package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
- package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
- package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
- package/.agents/skills/galdr-ymirsystem/assets/smidja.md +175 -0
- package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
- package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
- package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
- package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +360 -0
- package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
- package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
- package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
- package/.agents/skills/gjallarhorn-relay/README.md +3 -0
- package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
- package/.agents/skills/groa-update/SKILL.md +70 -0
- package/.agents/skills/hamr-adapters/README.md +3 -0
- package/.agents/skills/hamr-adapters/SKILL.md +123 -0
- package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
- package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
- package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
- package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
- package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
- package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
- package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
- package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
- package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
- package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
- package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
- package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
- package/.agents/skills/herdr-panes/README.md +3 -0
- package/.agents/skills/herdr-panes/SKILL.md +92 -0
- package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
- package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
- package/.agents/skills/hnoss-design/DESIGN.md +19 -0
- package/.agents/skills/hnoss-design/README.md +3 -0
- package/.agents/skills/hnoss-design/SKILL.md +83 -0
- package/.agents/skills/hvild-afk/README.md +3 -0
- package/.agents/skills/hvild-afk/SKILL.md +241 -0
- package/.agents/skills/jord-projects/README.md +3 -0
- package/.agents/skills/jord-projects/SKILL.md +92 -0
- package/.agents/skills/lifecycle/SKILL.md +56 -0
- package/.agents/skills/lifecycle/smoke_test.sh +52 -0
- package/.agents/skills/lifecycle/start.sh +21 -0
- package/.agents/skills/lifecycle/status.sh +35 -0
- package/.agents/skills/lifecycle/stop.sh +16 -0
- package/.agents/skills/muninn-stow/README.md +3 -0
- package/.agents/skills/muninn-stow/SKILL.md +309 -0
- package/.agents/skills/no-mistakes/SKILL.md +379 -0
- package/.agents/skills/nornir-schedule/README.md +3 -0
- package/.agents/skills/nornir-schedule/SKILL.md +25 -0
- package/.agents/skills/nornir-schedule/assets/events.md +137 -0
- package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
- package/.agents/skills/nsr-compliance/README.md +3 -0
- package/.agents/skills/nsr-compliance/SKILL.md +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/pr-ops/README.md +3 -0
- package/.agents/skills/pr-ops/SKILL.md +109 -0
- package/.agents/skills/ratatoskr-a2a/README.md +3 -0
- package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
- package/.agents/skills/rules-check-drift/SKILL.md +81 -0
- package/.agents/skills/saga-bearings/README.md +3 -0
- package/.agents/skills/saga-bearings/SKILL.md +26 -0
- package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
- package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
- package/.agents/skills/saga-bearings/assets/recap.md +56 -0
- package/.agents/skills/syn-recovery/README.md +3 -0
- package/.agents/skills/syn-recovery/SKILL.md +54 -0
- package/.agents/skills/tyr-check/README.md +3 -0
- package/.agents/skills/tyr-check/SKILL.md +218 -0
- package/.agents/skills/urdh-hold/README.md +3 -0
- package/.agents/skills/urdh-hold/SKILL.md +25 -0
- package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
- package/.agents/skills/urdh-hold/assets/hold.md +54 -0
- package/.agents/skills/vor-diagnostics/README.md +3 -0
- package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
- package/.agents/skills/ymir-host/README.md +3 -0
- package/.agents/skills/ymir-host/SKILL.md +34 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
- package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
- package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
- package/.agents/skills/ymir-host/assets/update.md +64 -0
- package/.agents/tests/assets/board-render-harness.mjs +117 -0
- package/.agents/tests/cmux-test-safety.sh +51 -0
- package/.agents/tests/fixtures.sh +291 -0
- package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
- package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
- package/.agents/tests/fm-afk-launch.test.sh +961 -0
- package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
- package/.agents/tests/fm-afk-return.test.sh +283 -0
- package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
- package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
- package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
- package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
- package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
- package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
- package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
- package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
- package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
- package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
- package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
- package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
- package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
- package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
- package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
- package/.agents/tests/fm-backend-orca.test.sh +1357 -0
- package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
- package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
- package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
- package/.agents/tests/fm-backend.test.sh +1142 -0
- package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
- package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
- package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
- package/.agents/tests/fm-bearings-board.test.sh +414 -0
- package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
- package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
- package/.agents/tests/fm-bootstrap.test.sh +1178 -0
- package/.agents/tests/fm-branch-supervision.test.sh +552 -0
- package/.agents/tests/fm-brief.test.sh +785 -0
- package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
- package/.agents/tests/fm-busy-state.test.sh +465 -0
- package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
- package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
- package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
- package/.agents/tests/fm-check-unregister.test.sh +198 -0
- package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
- package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
- package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
- package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
- package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
- package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
- package/.agents/tests/fm-composer-ghost.test.sh +716 -0
- package/.agents/tests/fm-composer-lib.test.sh +666 -0
- package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
- package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
- package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
- package/.agents/tests/fm-control.test.sh +910 -0
- package/.agents/tests/fm-crew-state.test.sh +1610 -0
- package/.agents/tests/fm-cursor-harness.test.sh +404 -0
- package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
- package/.agents/tests/fm-cursor-primary.test.sh +708 -0
- package/.agents/tests/fm-daemon.test.sh +2740 -0
- package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
- package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
- package/.agents/tests/fm-extension-binding.test.sh +2187 -0
- package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
- package/.agents/tests/fm-fleet-sync.test.sh +721 -0
- package/.agents/tests/fm-gate-refuse.test.sh +356 -0
- package/.agents/tests/fm-gitignore-config.test.sh +89 -0
- package/.agents/tests/fm-gotmp.test.sh +230 -0
- package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
- package/.agents/tests/fm-grok-harness.test.sh +117 -0
- package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
- package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
- package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
- package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
- package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
- package/.agents/tests/fm-herdr-lab.test.sh +243 -0
- package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
- package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
- package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
- package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
- package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
- package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
- package/.agents/tests/fm-kimi-harness.test.sh +687 -0
- package/.agents/tests/fm-lint-workflows.test.sh +532 -0
- package/.agents/tests/fm-lint.test.sh +1023 -0
- package/.agents/tests/fm-muse-harness.test.sh +932 -0
- package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
- package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
- package/.agents/tests/fm-on.test.sh +507 -0
- package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
- package/.agents/tests/fm-operational-input.test.sh +160 -0
- package/.agents/tests/fm-peek-remote.test.sh +110 -0
- package/.agents/tests/fm-pending-reply.test.sh +1288 -0
- package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
- package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
- package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
- package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
- package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
- package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
- package/.agents/tests/fm-pr-merge.test.sh +2135 -0
- package/.agents/tests/fm-procevent-quota.test.sh +225 -0
- package/.agents/tests/fm-procevent-when.test.sh +406 -0
- package/.agents/tests/fm-procevent.test.sh +1745 -0
- package/.agents/tests/fm-project-origin.test.sh +110 -0
- package/.agents/tests/fm-public-followup.test.sh +2272 -0
- package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
- package/.agents/tests/fm-quota-choose.test.sh +626 -0
- package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
- package/.agents/tests/fm-remote-doctor.test.sh +625 -0
- package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
- package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
- package/.agents/tests/fm-remote-job.test.sh +768 -0
- package/.agents/tests/fm-remote-reply.test.sh +520 -0
- package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
- package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
- package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
- package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
- package/.agents/tests/fm-review-diff.test.sh +176 -0
- package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
- package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
- package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
- package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
- package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
- package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
- package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
- package/.agents/tests/fm-send-inbox.test.sh +352 -0
- package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
- package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
- package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
- package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
- package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
- package/.agents/tests/fm-send-settle.test.sh +147 -0
- package/.agents/tests/fm-send-strict.test.sh +241 -0
- package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
- package/.agents/tests/fm-session-start.test.sh +2515 -0
- package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
- package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
- package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
- package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
- package/.agents/tests/fm-spawn-batch.test.sh +148 -0
- package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
- package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
- package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
- package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
- package/.agents/tests/fm-startup-network.test.sh +712 -0
- package/.agents/tests/fm-stow-cascade.test.sh +370 -0
- package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
- package/.agents/tests/fm-supervision-events.test.sh +156 -0
- package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
- package/.agents/tests/fm-tangle-guard.test.sh +277 -0
- package/.agents/tests/fm-task-delivery.test.sh +420 -0
- package/.agents/tests/fm-task-inbox.test.sh +513 -0
- package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
- package/.agents/tests/fm-teardown.test.sh +2665 -0
- package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
- package/.agents/tests/fm-test-fixtures.test.sh +132 -0
- package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
- package/.agents/tests/fm-test-run.test.sh +1196 -0
- package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
- package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
- package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
- package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
- package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
- package/.agents/tests/fm-transition-lib.test.sh +54 -0
- package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
- package/.agents/tests/fm-update.test.sh +304 -0
- package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
- package/.agents/tests/fm-voice-relay.test.sh +4741 -0
- package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
- package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
- package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
- package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
- package/.agents/tests/fm-wake-queue.test.sh +1224 -0
- package/.agents/tests/fm-watch-arm.test.sh +821 -0
- package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
- package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
- package/.agents/tests/fm-watch-triage.test.sh +3889 -0
- package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
- package/.agents/tests/fm-x-mode.test.sh +3042 -0
- package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
- package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
- package/.agents/tests/herdr-test-safety.sh +42 -0
- package/.agents/tests/lib.sh +315 -0
- package/.agents/tests/remote-herdr-fixture.sh +125 -0
- package/.agents/tests/secondmate-helpers.sh +193 -0
- package/.agents/tests/smoke.test.sh +93 -0
- package/.agents/tests/wake-helpers.sh +338 -0
- package/.agents/tests/zellij-test-safety.sh +60 -0
- package/.agents/tools/README.md +10 -0
- package/.agents/tools/bin/tasks-cli +267 -0
- package/.agents/tools/tasks-cli.ts +216 -0
- package/AGENTS.md +454 -0
- package/CHANGELOG.md +881 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +113 -39
- package/RULES/01-domains.md +51 -0
- package/RULES/02-agents.md +78 -0
- package/RULES/03-houses.md +61 -0
- package/RULES/04-hoard.md +65 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +58 -0
- package/RULES/07-config.md +45 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/README.md +20 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +98 -0
- package/bin/a2a-serve.py +103 -0
- package/bin/a2a-serve.sh +8 -0
- package/bin/a2a-talk.sh +50 -0
- package/bin/a2abridge-ensure.sh +108 -0
- package/bin/agent-run.sh +43 -0
- package/bin/agents-config.sh +233 -0
- package/bin/apodex-smoke-test.sh +92 -0
- package/bin/bifrost-bridge.sh +112 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +107 -0
- package/bin/bootstrap-windows.ps1 +112 -0
- package/bin/branch-guard.sh +64 -0
- package/bin/brokk +73 -0
- package/bin/brokk-classify-lib.sh +1770 -0
- package/bin/brokk-lease-lib.sh +222 -0
- package/bin/brokk-lease.sh +193 -0
- package/bin/brokk-lint.sh +65 -0
- package/bin/brokk-send.sh +38 -0
- package/bin/brokk-update.sh +9 -0
- package/bin/brokk-wake-grant.sh +127 -0
- package/bin/brokk-wake-lib.sh +1849 -0
- package/bin/changelog-guard.sh +165 -0
- package/bin/crash-sense.sh +160 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +207 -0
- package/bin/eindri-acclaim.sh +34 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seen.sh +41 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +85 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +112 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/fleet-apply.sh +68 -0
- package/bin/github-deploy.sh +81 -0
- package/bin/gjallarhorn-expose.sh +102 -0
- package/bin/gjallarhorn-notify.sh +58 -0
- package/bin/gjallarhorn-purge.sh +54 -0
- package/bin/gjallarhorn-tunnel.sh +72 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +122 -0
- package/bin/hall-snapshot.sh +92 -0
- package/bin/hamr-harness.sh +246 -0
- package/bin/heimdall-ssh-keys.sh +374 -0
- package/bin/herdr-agents.py +44 -0
- package/bin/herdr-ensure.sh +104 -0
- package/bin/herdr-run.sh +431 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hoard-lib.sh +25 -0
- package/bin/hodd.sh +78 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +108 -0
- package/bin/local-model-lock.sh +51 -0
- package/bin/mimir-bridge.py +226 -0
- package/bin/mimir-bridge.sh +87 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +59 -0
- package/bin/mjollnir.sh +85 -0
- package/bin/model-hardware.sh +82 -0
- package/bin/model-resolve.sh +147 -0
- package/bin/models-detect.sh +178 -0
- package/bin/nornir-cron-start.sh +162 -0
- package/bin/nornir-job-daily-briefing.sh +191 -0
- package/bin/nornir-job-git-sync.sh +152 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +148 -0
- package/bin/omarchy-plugins.sh +174 -0
- package/bin/omarchy-sense.sh +149 -0
- package/bin/perm-guard.sh +30 -0
- package/bin/pi-agent.sh +68 -0
- package/bin/pi-ensure.sh +77 -0
- package/bin/pi-local.sh +37 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +38 -0
- package/bin/project-git.sh +55 -0
- package/bin/public-guard.sh +70 -0
- package/bin/ratatoskr.sh +49 -0
- package/bin/realm-lib.sh +32 -0
- package/bin/repo-scrub.sh +62 -0
- package/bin/rodd-operational-input.sh +250 -0
- package/bin/runes-append.sh +198 -0
- package/bin/saga-session-start.sh +172 -0
- package/bin/saga-sessionstart-run.sh +79 -0
- package/bin/saga-wake-drain.sh +41 -0
- package/bin/secret-guard.sh +63 -0
- package/bin/sessrumnir-ensure.sh +100 -0
- package/bin/sessrumnir-sync.sh +237 -0
- package/bin/sessrumnir.sh +91 -0
- package/bin/skillopt-setup.sh +76 -0
- package/bin/skuld-branch-outcome.sh +203 -0
- package/bin/skuld-branch-prompt.sh +101 -0
- package/bin/smidja-bootstrap.sh +90 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +76 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +190 -0
- package/bin/telegram-bot.sh +69 -0
- package/bin/toolchain.sh +74 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +260 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +47 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +150 -0
- package/bin/wyrd-db.sh +47 -0
- package/bin/yggdrasil.sh +152 -0
- package/bin/ymir-edit.sh +145 -0
- package/bin/ymir-install.sh +641 -0
- package/bin/ymir-invite.sh +93 -0
- package/bin/ymir-isolation.sh +88 -0
- package/bin/ymir-migrate.sh +61 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +97 -0
- package/bin/ymir-setup-auth.sh +108 -0
- package/bin/ymir-validate.sh +173 -0
- package/bin/ymir.js +74 -16
- package/docs/Architecture.md +339 -0
- package/docs/design.md +351 -0
- package/docs/installations/README.md +63 -0
- package/docs/installations/ymir-home.md +93 -0
- package/docs/integration.md +105 -0
- package/docs/lore.md +1056 -0
- package/docs/research/agent-harnesses.md +290 -0
- package/docs/runbooks/README.md +19 -0
- package/docs/runbooks/a2a.md +91 -0
- package/docs/runbooks/agent-permissions.md +99 -0
- package/docs/runbooks/agents.md +57 -0
- package/docs/runbooks/models.md +69 -0
- package/docs/runbooks/realm-onboarding.md +60 -0
- package/docs/runbooks/secrets-and-hoard.md +60 -0
- package/docs/runbooks/updates-and-migrations.md +110 -0
- package/docs/runbooks/worktrees-isolation.md +72 -0
- package/docs/session-start.md +105 -0
- package/docs/skillopt-integration.md +321 -0
- package/docs/sync-system.md +66 -0
- package/docs/workspaces.md +104 -0
- package/docs/ymir-rut.md +260 -0
- package/package.json +44 -14
- package/packaging/build.sh +74 -0
- package/packaging/macos/Ymir Installer.command +43 -0
- package/packaging/windows/ymir-setup.nsi +74 -0
- package/scripts/README.md +22 -0
- package/scripts/electron.sh +210 -0
- package/scripts/start.sh +167 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavioral tests for bin/fm-procevent-quota.sh.
|
|
3
|
+
set -u
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
FM_ROOT="${FM_ROOT_OVERRIDE:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
7
|
+
BIN="$FM_ROOT/bin"
|
|
8
|
+
LAB=$(mktemp -d "${TMPDIR:-/tmp}/fm-procevent-quota.XXXXXX")
|
|
9
|
+
FAKEBIN="$LAB/fakebin"
|
|
10
|
+
COUNT="$LAB/count"
|
|
11
|
+
|
|
12
|
+
cleanup() { rm -rf "$LAB"; }
|
|
13
|
+
trap cleanup EXIT
|
|
14
|
+
mkdir -p "$FAKEBIN"
|
|
15
|
+
|
|
16
|
+
cat > "$FAKEBIN/quota-axi" <<'SH'
|
|
17
|
+
#!/usr/bin/env bash
|
|
18
|
+
if [ "${1:-}" = "--version" ]; then
|
|
19
|
+
printf 'quota-axi 0.1.29\n'
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
case "${QUOTA_AXI_MALFORMED:-}" in
|
|
23
|
+
schema)
|
|
24
|
+
printf '{"schemaVersion":4,"providers":[]}\n'
|
|
25
|
+
exit 0
|
|
26
|
+
;;
|
|
27
|
+
duplicate)
|
|
28
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"unknown","effectiveAvailability":[]}},{"provider":"codex","quotaSemantics":{"status":"unknown","effectiveAvailability":[]}}]}\n'
|
|
29
|
+
exit 0
|
|
30
|
+
;;
|
|
31
|
+
types)
|
|
32
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":"0","runway":{"status":"through_reset"}}]}}]}\n'
|
|
33
|
+
exit 0
|
|
34
|
+
;;
|
|
35
|
+
range)
|
|
36
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":150,"runway":{"status":"through_reset"}}]}}]}\n'
|
|
37
|
+
exit 0
|
|
38
|
+
;;
|
|
39
|
+
runway)
|
|
40
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":50,"runway":{"status":"invalid"}}]}}]}\n'
|
|
41
|
+
exit 0
|
|
42
|
+
;;
|
|
43
|
+
availability)
|
|
44
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"typo","effectivePercentRemaining":0,"runway":{"status":"exhausted_now"}},{"scope":"model:codex_bengalfox","status":"known","effectivePercentRemaining":50,"runway":{"status":"through_reset"}}]}}]}\n'
|
|
45
|
+
exit 0
|
|
46
|
+
;;
|
|
47
|
+
known-empty)
|
|
48
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[]}}]}\n'
|
|
49
|
+
exit 0
|
|
50
|
+
;;
|
|
51
|
+
semantics-mismatch)
|
|
52
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"unknown","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":50,"runway":{"status":"through_reset"}}]}}]}\n'
|
|
53
|
+
exit 0
|
|
54
|
+
;;
|
|
55
|
+
identity)
|
|
56
|
+
printf '{"schemaVersion":5,"providers":[{"provider":" codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":0,"runway":{"status":"exhausted_now"}}]}}]}\n'
|
|
57
|
+
exit 0
|
|
58
|
+
;;
|
|
59
|
+
esac
|
|
60
|
+
if [ "${QUOTA_AXI_EXHAUSTED_DETAIL:-0}" = 1 ]; then
|
|
61
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":10,"runway":{"status":"exhausted_now"}},{"scope":"model:foo","status":"known","effectivePercentRemaining":5,"runway":{"status":"through_reset"}}]}}]}\n'
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
if [ "${QUOTA_AXI_UNKNOWN_EXHAUSTED:-0}" = 1 ]; then
|
|
65
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"unknown","runway":{"status":"exhausted_now"}}]}}]}\n'
|
|
66
|
+
exit 0
|
|
67
|
+
fi
|
|
68
|
+
count=0
|
|
69
|
+
[ ! -f "$QUOTA_AXI_COUNT" ] || read -r count < "$QUOTA_AXI_COUNT"
|
|
70
|
+
count=$((count + 1))
|
|
71
|
+
printf '%s\n' "$count" > "$QUOTA_AXI_COUNT"
|
|
72
|
+
if [ "${QUOTA_AXI_UNKNOWN_FIRST:-0}" = 1 ] && [ "$count" -eq 1 ]; then
|
|
73
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"unknown","effectiveAvailability":[]}}]}\n'
|
|
74
|
+
exit 0
|
|
75
|
+
fi
|
|
76
|
+
if [ "${QUOTA_AXI_KNOWN_UNKNOWN_FIRST:-0}" = 1 ] && [ "$count" -eq 1 ]; then
|
|
77
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"unknown","runway":{"status":"unknown"}}]}}]}\n'
|
|
78
|
+
exit 0
|
|
79
|
+
fi
|
|
80
|
+
if [ "${QUOTA_AXI_EMPTY_FIRST:-0}" = 1 ] && [ "$count" -eq 1 ]; then
|
|
81
|
+
printf '{"schemaVersion":5,"providers":[]}\n'
|
|
82
|
+
exit 0
|
|
83
|
+
fi
|
|
84
|
+
if [ "${QUOTA_AXI_AT_THRESHOLD:-0}" = 1 ]; then
|
|
85
|
+
if [ "$count" -eq 1 ]; then
|
|
86
|
+
remaining=10
|
|
87
|
+
else
|
|
88
|
+
remaining=9
|
|
89
|
+
fi
|
|
90
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":%s,"runway":{"status":"through_reset"}}]}}]}\n' "$remaining"
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
if [ "$count" -eq 1 ]; then
|
|
94
|
+
model_remaining=20
|
|
95
|
+
runway=through_reset
|
|
96
|
+
else
|
|
97
|
+
model_remaining=0
|
|
98
|
+
runway=exhausted_now
|
|
99
|
+
fi
|
|
100
|
+
printf '{"schemaVersion":5,"providers":[{"provider":"codex","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":20,"runway":{"status":"through_reset"}},{"scope":"model:codex_bengalfox","status":"known","effectivePercentRemaining":%s,"runway":{"status":"%s"}}]}},{"provider":"claude","quotaSemantics":{"status":"known","effectiveAvailability":[{"scope":"all_models","status":"known","effectivePercentRemaining":50,"runway":{"status":"through_reset"}}]}}]}\n' "$model_remaining" "$runway"
|
|
101
|
+
SH
|
|
102
|
+
chmod +x "$FAKEBIN/quota-axi"
|
|
103
|
+
|
|
104
|
+
fail() { printf 'not ok - %s\n' "$1" >&2; exit 1; }
|
|
105
|
+
ok() { printf 'ok - %s\n' "$1"; }
|
|
106
|
+
|
|
107
|
+
if help=$("$BIN/fm-procevent-quota.sh" --help 2>&1); then
|
|
108
|
+
fail "help unexpectedly exited zero"
|
|
109
|
+
fi
|
|
110
|
+
printf '%s\n' "$help" | grep -Fq 'fm-procevent-quota.sh retire [--provider <provider>]' \
|
|
111
|
+
|| fail "help omitted the retire usage"
|
|
112
|
+
if printf '%s\n' "$help" | grep -Fq 'set -u'; then
|
|
113
|
+
fail "help leaked executable source"
|
|
114
|
+
fi
|
|
115
|
+
ok "help renders only the complete header"
|
|
116
|
+
|
|
117
|
+
out=$(QUOTA_AXI_EXHAUSTED_DETAIL=1 QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" \
|
|
118
|
+
"$BIN/fm-procevent-quota.sh" poll)
|
|
119
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' \
|
|
120
|
+
|| fail "default aggregate poll did not report exhaustion"
|
|
121
|
+
printf '%s\n' "$out" | grep -qx 'quota: quota' \
|
|
122
|
+
|| fail "default aggregate poll did not use the aggregate source"
|
|
123
|
+
ok "poll accepts its documented defaults"
|
|
124
|
+
|
|
125
|
+
out=$(QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 10 --provider codex --timeout 1)
|
|
126
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' || fail "provider watch did not report exhaustion"
|
|
127
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "provider watch did not wait through the healthy poll"
|
|
128
|
+
ok "provider watch blocks until a model scope is exhausted"
|
|
129
|
+
|
|
130
|
+
out=$(QUOTA_AXI_EXHAUSTED_DETAIL=1 QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" \
|
|
131
|
+
"$BIN/fm-procevent-quota.sh" poll --interval 1 --threshold 10 --provider codex --timeout 1)
|
|
132
|
+
detail=$(printf '%s\n' "$out" | sed -n 's/^detail: //p')
|
|
133
|
+
printf '%s\n' "$detail" | jq -e '
|
|
134
|
+
.best.scope == "all_models" and
|
|
135
|
+
.best.runway.status == "exhausted_now"
|
|
136
|
+
' >/dev/null || fail "exhausted poll recorded non-triggering detail: $detail"
|
|
137
|
+
ok "exhausted poll records the triggering scope"
|
|
138
|
+
|
|
139
|
+
out=$(QUOTA_AXI_UNKNOWN_EXHAUSTED=1 QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" \
|
|
140
|
+
"$BIN/fm-procevent-quota.sh" poll --interval 1 --threshold 10 --provider codex --timeout 1)
|
|
141
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' \
|
|
142
|
+
|| fail "unknown headroom with exhausted runway did not wake as exhausted"
|
|
143
|
+
ok "poll detects exhausted runway under unknown headroom"
|
|
144
|
+
|
|
145
|
+
rm -f "$COUNT"
|
|
146
|
+
out=$(QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 10 --provider '' --timeout 1)
|
|
147
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' || fail "aggregate watch did not report exhaustion"
|
|
148
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "aggregate watch did not evaluate all providers"
|
|
149
|
+
ok "aggregate watch blocks until any scope is exhausted"
|
|
150
|
+
|
|
151
|
+
rm -f "$COUNT"
|
|
152
|
+
out=$(QUOTA_AXI_EMPTY_FIRST=1 QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 10 --provider '' --timeout 1)
|
|
153
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' || fail "empty aggregate quota did not continue polling"
|
|
154
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "empty aggregate quota stopped early"
|
|
155
|
+
ok "aggregate watch preserves empty quota uncertainty"
|
|
156
|
+
|
|
157
|
+
if err=$(QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" arm --provider 2>&1); then
|
|
158
|
+
fail "missing provider value unexpectedly armed a watch"
|
|
159
|
+
fi
|
|
160
|
+
[ "$err" = "error: --provider needs a value" ] || fail "missing provider value returned: $err"
|
|
161
|
+
ok "arm rejects a missing provider value"
|
|
162
|
+
|
|
163
|
+
for provider in -- codex-; do
|
|
164
|
+
if err=$(QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" arm --provider "$provider" 2>&1); then
|
|
165
|
+
fail "noncanonical provider unexpectedly armed a watch: $provider"
|
|
166
|
+
fi
|
|
167
|
+
[ "$err" = "error: invalid provider: $provider" ] || fail "noncanonical provider returned: $err"
|
|
168
|
+
done
|
|
169
|
+
ok "arm rejects noncanonical provider identities"
|
|
170
|
+
|
|
171
|
+
out=$(FM_HOME="$LAB/retire-home" FM_STATE_OVERRIDE="$LAB/retire-state" \
|
|
172
|
+
"$BIN/fm-procevent-quota.sh" retire --provider codex)
|
|
173
|
+
[ "$out" = "retired: quota-codex" ] || fail "provider retire targeted the wrong source: $out"
|
|
174
|
+
ok "provider retire resolves the armed source id"
|
|
175
|
+
|
|
176
|
+
if err=$(QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 1 --threshold 100.5 --provider codex --timeout 1 2>&1); then
|
|
177
|
+
fail "threshold above 100 unexpectedly started polling"
|
|
178
|
+
fi
|
|
179
|
+
[ "$err" = "error: --threshold needs a percent 0-100" ] || fail "invalid threshold returned: $err"
|
|
180
|
+
ok "poll rejects a decimal threshold above 100"
|
|
181
|
+
|
|
182
|
+
rm -f "$COUNT"
|
|
183
|
+
out=$(QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 010 --provider codex --timeout 1)
|
|
184
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' || fail "leading-zero threshold did not evaluate quota"
|
|
185
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "leading-zero threshold stopped before exhaustion"
|
|
186
|
+
ok "poll accepts a leading-zero threshold"
|
|
187
|
+
|
|
188
|
+
rm -f "$COUNT"
|
|
189
|
+
out=$(QUOTA_AXI_AT_THRESHOLD=1 QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 10 --provider codex --timeout 1)
|
|
190
|
+
printf '%s\n' "$out" | grep -qx 'status: low' || fail "quota below the threshold did not report low"
|
|
191
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "quota at the threshold fired before dropping below it"
|
|
192
|
+
ok "poll fires only after quota drops below the threshold"
|
|
193
|
+
|
|
194
|
+
if err=$(QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --provider 2>&1); then
|
|
195
|
+
fail "missing poll provider value unexpectedly succeeded"
|
|
196
|
+
fi
|
|
197
|
+
[ "$err" = "error: --provider needs a value" ] || fail "missing poll provider returned: $err"
|
|
198
|
+
ok "poll rejects a missing option value"
|
|
199
|
+
|
|
200
|
+
rm -f "$COUNT"
|
|
201
|
+
out=$(FM_TIMEOUT_MECHANISM_OVERRIDE=bash QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 10 --provider codex --timeout 1)
|
|
202
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' || fail "bash timeout fallback did not poll quota"
|
|
203
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "bash timeout fallback stopped before exhaustion"
|
|
204
|
+
ok "quota polling uses the shared bash timeout fallback"
|
|
205
|
+
|
|
206
|
+
for malformed in schema duplicate types range runway availability known-empty semantics-mismatch identity; do
|
|
207
|
+
out=$(QUOTA_AXI_MALFORMED="$malformed" QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 1 --threshold 10 --provider codex --timeout 1)
|
|
208
|
+
printf '%s\n' "$out" | grep -qx 'status: error' || fail "$malformed snapshot did not report an error"
|
|
209
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 1' || fail "$malformed snapshot did not stop immediately"
|
|
210
|
+
done
|
|
211
|
+
ok "poll rejects malformed schema-five snapshots"
|
|
212
|
+
|
|
213
|
+
rm -f "$COUNT"
|
|
214
|
+
out=$(QUOTA_AXI_UNKNOWN_FIRST=1 QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 10 --provider codex --timeout 1)
|
|
215
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' || fail "unknown quota did not continue to exhaustion"
|
|
216
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "unknown quota stopped polling"
|
|
217
|
+
ok "poll preserves provider-level unknown quota"
|
|
218
|
+
|
|
219
|
+
rm -f "$COUNT"
|
|
220
|
+
out=$(QUOTA_AXI_KNOWN_UNKNOWN_FIRST=1 QUOTA_AXI_COUNT="$COUNT" PATH="$FAKEBIN:$PATH" "$BIN/fm-procevent-quota.sh" poll --interval 0.01 --threshold 10 --provider codex --timeout 1)
|
|
221
|
+
printf '%s\n' "$out" | grep -qx 'status: exhausted' || fail "known semantics with unknown headroom did not continue polling"
|
|
222
|
+
printf '%s\n' "$out" | grep -qx 'condition_polls: 2' || fail "known semantics with unknown headroom stopped early"
|
|
223
|
+
ok "poll preserves unknown headroom under known semantics"
|
|
224
|
+
|
|
225
|
+
printf '# all fm-procevent-quota tests passed\n'
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavior tests for the condition->action adapter of the process-to-event
|
|
3
|
+
# runner (bin/fm-procevent-when.sh).
|
|
4
|
+
#
|
|
5
|
+
# Every scenario is exercised through the adapter's public commands plus the
|
|
6
|
+
# generic runner, against real condition and action processes; nothing here
|
|
7
|
+
# asserts implementation-source bytes. The suite proves the load-bearing
|
|
8
|
+
# guarantees: the action fires exactly once on a stable true, never on a flap,
|
|
9
|
+
# never twice across a restart, never from a mutated spec, and every failure
|
|
10
|
+
# path ends in a captured terminal outcome that reaches the durable wake queue
|
|
11
|
+
# instead of a silent retry.
|
|
12
|
+
set -u
|
|
13
|
+
|
|
14
|
+
# shellcheck source=tests/lib.sh
|
|
15
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
16
|
+
|
|
17
|
+
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
18
|
+
TMP_ROOT=$(fm_test_tmproot fm-procevent-when-tests)
|
|
19
|
+
export FM_PROCEVENT_CLAIM_ROOT="$TMP_ROOT/claims"
|
|
20
|
+
|
|
21
|
+
pe() { FM_HOME="$1" "$ROOT/bin/fm-procevent.sh" "${@:2}"; }
|
|
22
|
+
when() { FM_HOME="$1" "$ROOT/bin/fm-procevent-when.sh" "${@:2}"; }
|
|
23
|
+
|
|
24
|
+
# Every home this suite arms is tracked so teardown can stop any runner still
|
|
25
|
+
# blocked on a condition that never fires.
|
|
26
|
+
WHEN_HOMES=()
|
|
27
|
+
when_teardown() {
|
|
28
|
+
local home seen=$'\n'
|
|
29
|
+
for home in ${WHEN_HOMES[@]+"${WHEN_HOMES[@]}"}; do
|
|
30
|
+
case "$seen" in
|
|
31
|
+
*$'\n'"$home"$'\n'*) continue ;;
|
|
32
|
+
esac
|
|
33
|
+
seen+="$home"$'\n'
|
|
34
|
+
FM_HOME="$home" "$ROOT/bin/fm-procevent.sh" sweep-home >/dev/null 2>&1 || true
|
|
35
|
+
done
|
|
36
|
+
fm_test_cleanup
|
|
37
|
+
}
|
|
38
|
+
trap when_teardown EXIT
|
|
39
|
+
|
|
40
|
+
new_home() { mkdir -p "$1/state"; WHEN_HOMES+=("$1"); }
|
|
41
|
+
|
|
42
|
+
wake_payloads() { awk -F '\t' '{print $5}' "$1/state/.wake-queue" 2>/dev/null; }
|
|
43
|
+
|
|
44
|
+
first_result() { # <home> <source-id>
|
|
45
|
+
local g
|
|
46
|
+
for g in "$1/state/procevent-inbox/$2".*.result; do
|
|
47
|
+
[ -e "$g" ] || continue
|
|
48
|
+
printf '%s\n' "$g"
|
|
49
|
+
return 0
|
|
50
|
+
done
|
|
51
|
+
return 1
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
wait_for_result() { # <home> <source-id> [tries]
|
|
55
|
+
local n=${3:-150}
|
|
56
|
+
for _ in $(seq 1 "$n"); do
|
|
57
|
+
first_result "$1" "$2" >/dev/null 2>&1 && return 0
|
|
58
|
+
sleep 0.1
|
|
59
|
+
done
|
|
60
|
+
return 1
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
wait_for_file() { # <file> [tries]
|
|
64
|
+
local n=${2:-150}
|
|
65
|
+
for _ in $(seq 1 "$n"); do [ -e "$1" ] && return 0; sleep 0.1; done
|
|
66
|
+
return 1
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# A condition that is true exactly when its trigger file exists, and counts
|
|
70
|
+
# every evaluation so flap tests can wait on real poll activity.
|
|
71
|
+
COND="$TMP_ROOT/cond.sh"
|
|
72
|
+
cat > "$COND" <<'SH'
|
|
73
|
+
#!/usr/bin/env bash
|
|
74
|
+
trigger=$1
|
|
75
|
+
counter=$2
|
|
76
|
+
echo x >> "$counter"
|
|
77
|
+
[ -e "$trigger" ]
|
|
78
|
+
SH
|
|
79
|
+
chmod +x "$COND"
|
|
80
|
+
|
|
81
|
+
# An action that records every invocation, so exactly-once is observable.
|
|
82
|
+
ACT="$TMP_ROOT/act.sh"
|
|
83
|
+
cat > "$ACT" <<'SH'
|
|
84
|
+
#!/usr/bin/env bash
|
|
85
|
+
log=$1
|
|
86
|
+
exit_code=${2:-0}
|
|
87
|
+
echo invoked >> "$log"
|
|
88
|
+
echo "action ran against $log"
|
|
89
|
+
exit "$exit_code"
|
|
90
|
+
SH
|
|
91
|
+
chmod +x "$ACT"
|
|
92
|
+
|
|
93
|
+
count_lines() { [ -e "$1" ] && grep -c . "$1" || echo 0; }
|
|
94
|
+
|
|
95
|
+
# --- arm binds the pair and refuses a duplicate ------------------------------
|
|
96
|
+
H="$TMP_ROOT/h-arm"; new_home "$H"
|
|
97
|
+
out=$(when "$H" arm arm-test --interval 0.1 \
|
|
98
|
+
--condition "$COND" "$TMP_ROOT/never" "$TMP_ROOT/arm-count" \
|
|
99
|
+
--action "$ACT" "$TMP_ROOT/arm-act")
|
|
100
|
+
assert_contains "$out" "armed: when-arm-test" "arm reports the canonical source id"
|
|
101
|
+
assert_present "$H/state/when/when-arm-test.spec" "arm writes the private spec"
|
|
102
|
+
assert_present "$H/state/when/when-arm-test.trust" "arm writes the trust binding"
|
|
103
|
+
assert_present "$H/state/procevent/when-arm-test.source" "arm registers the process-event source"
|
|
104
|
+
mode=$(PATH="${FM_TEST_BASE_PATH:-/usr/bin:/bin:/usr/sbin:/sbin}" bash -c \
|
|
105
|
+
'. "$1/bin/fm-pr-lib.sh"; fm_pr_file_mode "$2"' _ "$ROOT" "$H/state/when/when-arm-test.spec")
|
|
106
|
+
assert_contains "$mode" 600 "the spec is private"
|
|
107
|
+
if when "$H" arm arm-test --condition true --action true 2>"$TMP_ROOT/dup.err"; then
|
|
108
|
+
fail "re-arming an existing watch must be refused"
|
|
109
|
+
fi
|
|
110
|
+
assert_grep "already exists" "$TMP_ROOT/dup.err" "the duplicate refusal names the leftover state"
|
|
111
|
+
sid=$(when "$H" source-id arm-test)
|
|
112
|
+
assert_contains "$sid" "when-arm-test" "source-id prints the canonical id"
|
|
113
|
+
out=$(when "$H" retire arm-test)
|
|
114
|
+
assert_contains "$out" "retired: when-arm-test" "retire reports the source"
|
|
115
|
+
assert_absent "$H/state/when/when-arm-test.spec" "retire removes the spec"
|
|
116
|
+
assert_absent "$H/state/when/when-arm-test.trust" "retire removes the trust binding"
|
|
117
|
+
assert_absent "$H/state/procevent/when-arm-test.source" "retire drops the registration"
|
|
118
|
+
out=$(when "$H" retire arm-test)
|
|
119
|
+
assert_contains "$out" "retired: when-arm-test" "retire is idempotent"
|
|
120
|
+
pass "arm binds, refuses duplicates, and retire cleans up"
|
|
121
|
+
|
|
122
|
+
# --- concurrent arms publish exactly one complete registration ---------------
|
|
123
|
+
H="$TMP_ROOT/h-concurrent-arm"; new_home "$H"
|
|
124
|
+
(
|
|
125
|
+
when "$H" arm race --stable 1 --condition true --action "$ACT" "$TMP_ROOT/race-a" \
|
|
126
|
+
>"$TMP_ROOT/race-a.out" 2>"$TMP_ROOT/race-a.err"
|
|
127
|
+
printf '%s\n' "$?" > "$TMP_ROOT/race-a.rc"
|
|
128
|
+
) &
|
|
129
|
+
pid_a=$!
|
|
130
|
+
(
|
|
131
|
+
when "$H" arm race --stable 1 --condition true --action "$ACT" "$TMP_ROOT/race-b" \
|
|
132
|
+
>"$TMP_ROOT/race-b.out" 2>"$TMP_ROOT/race-b.err"
|
|
133
|
+
printf '%s\n' "$?" > "$TMP_ROOT/race-b.rc"
|
|
134
|
+
) &
|
|
135
|
+
pid_b=$!
|
|
136
|
+
wait "$pid_a" "$pid_b"
|
|
137
|
+
rc_a=$(cat "$TMP_ROOT/race-a.rc")
|
|
138
|
+
rc_b=$(cat "$TMP_ROOT/race-b.rc")
|
|
139
|
+
[ $((rc_a + rc_b)) -eq 1 ] || fail "exactly one concurrent arm must succeed"
|
|
140
|
+
pe "$H" reconcile >/dev/null
|
|
141
|
+
wait_for_result "$H" when-race || fail "the winning concurrent arm did not produce an outcome"
|
|
142
|
+
assert_contains "$(( $(count_lines "$TMP_ROOT/race-a") + $(count_lines "$TMP_ROOT/race-b") ))" 1 \
|
|
143
|
+
"only the winning concurrent registration fires"
|
|
144
|
+
pass "concurrent arms publish exactly one complete watch"
|
|
145
|
+
|
|
146
|
+
# --- the happy path: stable true fires the action exactly once ---------------
|
|
147
|
+
H="$TMP_ROOT/h-fire"; new_home "$H"
|
|
148
|
+
TRIG="$TMP_ROOT/fire-trigger"
|
|
149
|
+
ACTLOG="$TMP_ROOT/fire-act"
|
|
150
|
+
when "$H" arm fire --interval 0.1 --stable 2 \
|
|
151
|
+
--condition "$COND" "$TRIG" "$TMP_ROOT/fire-count" \
|
|
152
|
+
--action "$ACT" "$ACTLOG" >/dev/null
|
|
153
|
+
pe "$H" reconcile >/dev/null
|
|
154
|
+
# Let the runner observe some clean falses before the condition turns true.
|
|
155
|
+
wait_for_file "$TMP_ROOT/fire-count" || fail "the condition was never polled"
|
|
156
|
+
: > "$TRIG"
|
|
157
|
+
wait_for_result "$H" when-fire || fail "no outcome was captured after the condition held"
|
|
158
|
+
RESULT=$(first_result "$H" when-fire)
|
|
159
|
+
assert_grep 'status: fired' "$RESULT" "the outcome records a fired action"
|
|
160
|
+
assert_grep 'action_exit: 0' "$RESULT" "the outcome records the action exit"
|
|
161
|
+
assert_grep 'action ran against' "$RESULT" "the outcome carries the action output"
|
|
162
|
+
assert_contains "$(when "$H" classify "$RESULT")" fired "classify reads the outcome"
|
|
163
|
+
when "$H" terminal "$RESULT" || fail "a fired outcome must be terminal"
|
|
164
|
+
# The generic runner retires a terminal source: no restart, no second fire.
|
|
165
|
+
for _ in $(seq 1 100); do
|
|
166
|
+
[ ! -e "$H/state/procevent/when-fire.source" ] && break
|
|
167
|
+
sleep 0.1
|
|
168
|
+
done
|
|
169
|
+
assert_absent "$H/state/procevent/when-fire.source" "a fired watch retires its registration"
|
|
170
|
+
pe "$H" reconcile >/dev/null
|
|
171
|
+
sleep 0.5
|
|
172
|
+
assert_contains "$(count_lines "$ACTLOG")" 1 "the action ran exactly once"
|
|
173
|
+
payload=$(wake_payloads "$H")
|
|
174
|
+
assert_contains "$payload" "procevent when when-fire 1" "the outcome wake reached the durable queue"
|
|
175
|
+
assert_not_contains "$payload" "action ran" "action output never reaches the event line"
|
|
176
|
+
out=$(pe "$H" handled when-fire 1)
|
|
177
|
+
assert_contains "$out" "handled: when-fire 1" "the outcome acknowledges through the generic channel"
|
|
178
|
+
pass "a stable true fires the action exactly once and wakes with the outcome"
|
|
179
|
+
|
|
180
|
+
# --- a flapping condition never fires ----------------------------------------
|
|
181
|
+
H="$TMP_ROOT/h-flap"; new_home "$H"
|
|
182
|
+
FLAPLOG="$TMP_ROOT/flap-act"
|
|
183
|
+
# True on the first poll only, then false forever: with --stable 2 this must
|
|
184
|
+
# never fire.
|
|
185
|
+
FLAP="$TMP_ROOT/flap.sh"
|
|
186
|
+
cat > "$FLAP" <<'SH'
|
|
187
|
+
#!/usr/bin/env bash
|
|
188
|
+
counter=$1
|
|
189
|
+
echo x >> "$counter"
|
|
190
|
+
[ "$(grep -c . "$counter")" -eq 1 ]
|
|
191
|
+
SH
|
|
192
|
+
chmod +x "$FLAP"
|
|
193
|
+
when "$H" arm flap --interval 0.1 --stable 2 \
|
|
194
|
+
--condition "$FLAP" "$TMP_ROOT/flap-count" \
|
|
195
|
+
--action "$ACT" "$FLAPLOG" >/dev/null
|
|
196
|
+
pe "$H" reconcile >/dev/null
|
|
197
|
+
for _ in $(seq 1 150); do
|
|
198
|
+
[ "$(count_lines "$TMP_ROOT/flap-count")" -ge 5 ] && break
|
|
199
|
+
sleep 0.1
|
|
200
|
+
done
|
|
201
|
+
[ "$(count_lines "$TMP_ROOT/flap-count")" -ge 5 ] || fail "the flapping condition was not polled enough to judge"
|
|
202
|
+
assert_absent "$FLAPLOG" "a one-shot true below the stable count never fires the action"
|
|
203
|
+
assert_absent "$H/state/when/when-flap.fired" "no fire was claimed"
|
|
204
|
+
when "$H" retire flap >/dev/null
|
|
205
|
+
pass "a flapping condition never reaches the action"
|
|
206
|
+
|
|
207
|
+
# --- an action failure is captured and surfaced, never swallowed -------------
|
|
208
|
+
H="$TMP_ROOT/h-actfail"; new_home "$H"
|
|
209
|
+
FAILLOG="$TMP_ROOT/actfail-act"
|
|
210
|
+
when "$H" arm actfail --interval 0.1 --stable 1 \
|
|
211
|
+
--condition true \
|
|
212
|
+
--action "$ACT" "$FAILLOG" 7 >/dev/null
|
|
213
|
+
pe "$H" reconcile >/dev/null
|
|
214
|
+
wait_for_result "$H" when-actfail || fail "no outcome was captured for the failing action"
|
|
215
|
+
RESULT=$(first_result "$H" when-actfail)
|
|
216
|
+
assert_grep 'status: action-failed' "$RESULT" "the outcome records the failure"
|
|
217
|
+
assert_grep 'action_exit: 7' "$RESULT" "the outcome records the exact exit code"
|
|
218
|
+
assert_contains "$(when "$H" classify "$RESULT")" action-failed "classify distinguishes the failure"
|
|
219
|
+
when "$H" terminal "$RESULT" || fail "a failed action outcome must be terminal"
|
|
220
|
+
assert_contains "$(count_lines "$FAILLOG")" 1 "the failing action still ran exactly once"
|
|
221
|
+
pass "an action failure wakes with the captured error"
|
|
222
|
+
|
|
223
|
+
# --- a condition that errors past its budget wakes instead of retrying -------
|
|
224
|
+
H="$TMP_ROOT/h-conderr"; new_home "$H"
|
|
225
|
+
CONDERRLOG="$TMP_ROOT/conderr-act"
|
|
226
|
+
BROKEN="$TMP_ROOT/broken.sh"
|
|
227
|
+
cat > "$BROKEN" <<'SH'
|
|
228
|
+
#!/usr/bin/env bash
|
|
229
|
+
echo "cannot reach the service" >&2
|
|
230
|
+
exit 3
|
|
231
|
+
SH
|
|
232
|
+
chmod +x "$BROKEN"
|
|
233
|
+
when "$H" arm conderr --interval 0.1 --error-budget 2 \
|
|
234
|
+
--condition "$BROKEN" \
|
|
235
|
+
--action "$ACT" "$CONDERRLOG" >/dev/null
|
|
236
|
+
pe "$H" reconcile >/dev/null
|
|
237
|
+
wait_for_result "$H" when-conderr || fail "no outcome was captured for the erroring condition"
|
|
238
|
+
RESULT=$(first_result "$H" when-conderr)
|
|
239
|
+
assert_grep 'status: condition-error' "$RESULT" "the outcome records the condition error"
|
|
240
|
+
assert_grep 'cannot reach the service' "$RESULT" "the outcome carries the condition diagnostics"
|
|
241
|
+
assert_absent "$CONDERRLOG" "an erroring condition never reaches the action"
|
|
242
|
+
assert_absent "$H/state/when/when-conderr.fired" "no fire was claimed on an ambiguous condition"
|
|
243
|
+
pass "a repeatedly erroring condition wakes firstmate instead of firing"
|
|
244
|
+
|
|
245
|
+
# --- a deadline that passes wakes with never-true -----------------------------
|
|
246
|
+
H="$TMP_ROOT/h-deadline"; new_home "$H"
|
|
247
|
+
DEADLOG="$TMP_ROOT/deadline-act"
|
|
248
|
+
when "$H" arm deadline --interval 0.1 --deadline 1 \
|
|
249
|
+
--condition false \
|
|
250
|
+
--action "$ACT" "$DEADLOG" >/dev/null
|
|
251
|
+
pe "$H" reconcile >/dev/null
|
|
252
|
+
wait_for_result "$H" when-deadline || fail "no outcome was captured after the deadline"
|
|
253
|
+
RESULT=$(first_result "$H" when-deadline)
|
|
254
|
+
assert_grep 'status: never-true' "$RESULT" "the outcome records the expired deadline"
|
|
255
|
+
assert_absent "$DEADLOG" "the action never ran"
|
|
256
|
+
pass "an expired deadline wakes with never-true"
|
|
257
|
+
|
|
258
|
+
# --- a poll completing true after its deadline cannot fire -------------------
|
|
259
|
+
H="$TMP_ROOT/h-late-true"; new_home "$H"
|
|
260
|
+
LATELOG="$TMP_ROOT/late-true-act"
|
|
261
|
+
LATE="$TMP_ROOT/late-true.sh"
|
|
262
|
+
cat > "$LATE" <<'SH'
|
|
263
|
+
#!/usr/bin/env bash
|
|
264
|
+
sleep 2
|
|
265
|
+
exit 0
|
|
266
|
+
SH
|
|
267
|
+
chmod +x "$LATE"
|
|
268
|
+
when "$H" arm late-true --stable 1 --deadline 1 --condition-timeout 3 \
|
|
269
|
+
--condition "$LATE" --action "$ACT" "$LATELOG" >/dev/null
|
|
270
|
+
pe "$H" reconcile >/dev/null
|
|
271
|
+
wait_for_result "$H" when-late-true || fail "no outcome was captured for a condition completing after deadline"
|
|
272
|
+
RESULT=$(first_result "$H" when-late-true)
|
|
273
|
+
assert_grep 'status: never-true' "$RESULT" "a late true is rejected after the deadline"
|
|
274
|
+
assert_absent "$LATELOG" "a condition completing true after deadline never fires"
|
|
275
|
+
pass "a late true poll cannot fire after its deadline"
|
|
276
|
+
|
|
277
|
+
# --- a timed-out action cannot leave descendants running ---------------------
|
|
278
|
+
H="$TMP_ROOT/h-timeout"; new_home "$H"
|
|
279
|
+
DESCENDANT_EFFECT="$TMP_ROOT/descendant-effect"
|
|
280
|
+
DESCENDANT_PID="$TMP_ROOT/descendant-pid"
|
|
281
|
+
SPAWNER="$TMP_ROOT/spawner.sh"
|
|
282
|
+
cat > "$SPAWNER" <<'SH'
|
|
283
|
+
#!/usr/bin/env bash
|
|
284
|
+
(
|
|
285
|
+
trap '' TERM
|
|
286
|
+
sleep 10
|
|
287
|
+
printf 'late effect\n' > "$1"
|
|
288
|
+
) &
|
|
289
|
+
printf '%s\n' "$!" > "$2"
|
|
290
|
+
wait
|
|
291
|
+
SH
|
|
292
|
+
chmod +x "$SPAWNER"
|
|
293
|
+
when "$H" arm timeout --stable 1 --action-timeout 1 \
|
|
294
|
+
--condition true --action "$SPAWNER" "$DESCENDANT_EFFECT" "$DESCENDANT_PID" >/dev/null
|
|
295
|
+
pe "$H" reconcile >/dev/null
|
|
296
|
+
wait_for_result "$H" when-timeout || fail "no outcome was captured for the timed-out action"
|
|
297
|
+
RESULT=$(first_result "$H" when-timeout)
|
|
298
|
+
assert_grep 'status: action-failed' "$RESULT" "the action timeout is captured as a failure"
|
|
299
|
+
assert_grep 'action_exit: 124' "$RESULT" "the action timeout uses the shared timeout status"
|
|
300
|
+
wait_for_file "$DESCENDANT_PID" || fail "the timeout fixture did not record its descendant"
|
|
301
|
+
descendant_pid=$(cat "$DESCENDANT_PID")
|
|
302
|
+
for _ in $(seq 1 20); do
|
|
303
|
+
descendant_state=$(ps -o stat= -p "$descendant_pid" 2>/dev/null | tr -d ' ' || true)
|
|
304
|
+
case "$descendant_state" in ''|Z*) break ;; esac
|
|
305
|
+
sleep 0.1
|
|
306
|
+
done
|
|
307
|
+
descendant_state=$(ps -o stat= -p "$descendant_pid" 2>/dev/null | tr -d ' ' || true)
|
|
308
|
+
case "$descendant_state" in
|
|
309
|
+
''|Z*) ;;
|
|
310
|
+
*)
|
|
311
|
+
kill -KILL "$descendant_pid" 2>/dev/null || true
|
|
312
|
+
fail "a timed-out action left descendant $descendant_pid alive ($descendant_state)"
|
|
313
|
+
;;
|
|
314
|
+
esac
|
|
315
|
+
assert_absent "$DESCENDANT_EFFECT" "a timed-out action leaves no descendant effect"
|
|
316
|
+
pass "action timeouts terminate the complete process group"
|
|
317
|
+
|
|
318
|
+
# --- command output staging remains bounded while the command runs -----------
|
|
319
|
+
H="$TMP_ROOT/h-bounded-output"; new_home "$H"
|
|
320
|
+
NOISY_READY="$TMP_ROOT/noisy-ready"
|
|
321
|
+
NOISY="$TMP_ROOT/noisy.sh"
|
|
322
|
+
cat > "$NOISY" <<'SH'
|
|
323
|
+
#!/usr/bin/env bash
|
|
324
|
+
printf 'ready\n' > "$1"
|
|
325
|
+
i=0
|
|
326
|
+
while [ "$i" -lt 20000 ]; do
|
|
327
|
+
printf '0123456789012345678901234567890123456789\n'
|
|
328
|
+
i=$((i + 1))
|
|
329
|
+
done
|
|
330
|
+
sleep 1
|
|
331
|
+
SH
|
|
332
|
+
chmod +x "$NOISY"
|
|
333
|
+
FM_WHEN_OUTPUT_TAIL_BYTES=128 when "$H" arm bounded-output --stable 1 \
|
|
334
|
+
--condition true --action "$NOISY" "$NOISY_READY" >/dev/null
|
|
335
|
+
FM_WHEN_OUTPUT_TAIL_BYTES=128 pe "$H" reconcile >/dev/null
|
|
336
|
+
wait_for_file "$NOISY_READY" || fail "the noisy action did not start"
|
|
337
|
+
for staged in "$H/state/when"/.run-out.*; do
|
|
338
|
+
[ -e "$staged" ] || continue
|
|
339
|
+
staged_size=$(wc -c < "$staged" | tr -d ' ')
|
|
340
|
+
[ "$staged_size" -le 128 ] || fail "command output staging exceeded its configured bound"
|
|
341
|
+
done
|
|
342
|
+
wait_for_result "$H" when-bounded-output || fail "no outcome was captured for the noisy action"
|
|
343
|
+
pass "command output staging stays within its byte bound"
|
|
344
|
+
|
|
345
|
+
# --- a restart after a claimed fire never runs the action twice ---------------
|
|
346
|
+
H="$TMP_ROOT/h-crash"; new_home "$H"
|
|
347
|
+
CRASHLOG="$TMP_ROOT/crash-act"
|
|
348
|
+
when "$H" arm crash --interval 0.1 --stable 1 \
|
|
349
|
+
--condition true \
|
|
350
|
+
--action "$ACT" "$CRASHLOG" >/dev/null
|
|
351
|
+
# Simulate a runner that claimed the fire and died before capturing an outcome.
|
|
352
|
+
date +%s > "$H/state/when/when-crash.fired"
|
|
353
|
+
pe "$H" reconcile >/dev/null
|
|
354
|
+
wait_for_result "$H" when-crash || fail "no outcome was captured after the simulated crash"
|
|
355
|
+
RESULT=$(first_result "$H" when-crash)
|
|
356
|
+
assert_grep 'status: ambiguous' "$RESULT" "the outcome reports the uncaptured earlier fire"
|
|
357
|
+
assert_absent "$CRASHLOG" "the action was not fired a second time"
|
|
358
|
+
assert_contains "$(when "$H" classify "$RESULT")" ambiguous "classify reads the ambiguity"
|
|
359
|
+
when "$H" terminal "$RESULT" || fail "an ambiguous outcome must be terminal"
|
|
360
|
+
pass "a restart after a claimed fire reports ambiguity instead of double-firing"
|
|
361
|
+
|
|
362
|
+
# --- a mutated spec is refused without executing anything ---------------------
|
|
363
|
+
H="$TMP_ROOT/h-tamper"; new_home "$H"
|
|
364
|
+
TAMPERLOG="$TMP_ROOT/tamper-act"
|
|
365
|
+
when "$H" arm tamper --interval 0.1 --stable 1 \
|
|
366
|
+
--condition "$COND" "$TMP_ROOT/tamper-trigger" "$TMP_ROOT/tamper-count" \
|
|
367
|
+
--action "$ACT" "$TAMPERLOG" >/dev/null
|
|
368
|
+
# Mutate the registered spec after arming: swap the action for a different one.
|
|
369
|
+
perl -pi -e "s/\Qtamper-act\E/tamper-EVIL/" "$H/state/when/when-tamper.spec"
|
|
370
|
+
: > "$TMP_ROOT/tamper-trigger"
|
|
371
|
+
pe "$H" reconcile >/dev/null
|
|
372
|
+
wait_for_result "$H" when-tamper || fail "no outcome was captured for the mutated spec"
|
|
373
|
+
RESULT=$(first_result "$H" when-tamper)
|
|
374
|
+
assert_grep 'status: rejected' "$RESULT" "the outcome reports the trust refusal"
|
|
375
|
+
assert_grep 'trust' "$RESULT" "the refusal names the trust binding"
|
|
376
|
+
assert_absent "$TAMPERLOG" "nothing from the original spec was executed"
|
|
377
|
+
assert_absent "$TMP_ROOT/tamper-count" "nothing from the mutated spec was executed either"
|
|
378
|
+
assert_contains "$(when "$H" classify "$RESULT")" rejected "classify reads the refusal"
|
|
379
|
+
pass "a mutated spec is refused without executing anything"
|
|
380
|
+
|
|
381
|
+
# --- mutated action bytes are refused before the fire is claimed -------------
|
|
382
|
+
H="$TMP_ROOT/h-action-tamper"; new_home "$H"
|
|
383
|
+
ACTION_TAMPER_LOG="$TMP_ROOT/action-tamper-act"
|
|
384
|
+
MUTABLE_ACT="$TMP_ROOT/mutable-act.sh"
|
|
385
|
+
cat > "$MUTABLE_ACT" <<'SH'
|
|
386
|
+
#!/usr/bin/env bash
|
|
387
|
+
printf 'original action ran\n' >> "$1"
|
|
388
|
+
SH
|
|
389
|
+
chmod +x "$MUTABLE_ACT"
|
|
390
|
+
when "$H" arm action-tamper --stable 1 \
|
|
391
|
+
--condition true --action "$MUTABLE_ACT" "$ACTION_TAMPER_LOG" >/dev/null
|
|
392
|
+
cat > "$MUTABLE_ACT" <<'SH'
|
|
393
|
+
#!/usr/bin/env bash
|
|
394
|
+
printf 'mutated action ran\n' >> "$1"
|
|
395
|
+
SH
|
|
396
|
+
chmod +x "$MUTABLE_ACT"
|
|
397
|
+
pe "$H" reconcile >/dev/null
|
|
398
|
+
wait_for_result "$H" when-action-tamper || fail "no outcome was captured for the mutated action"
|
|
399
|
+
RESULT=$(first_result "$H" when-action-tamper)
|
|
400
|
+
assert_grep 'status: rejected' "$RESULT" "the outcome reports the action trust refusal"
|
|
401
|
+
assert_grep 'trust binding' "$RESULT" "the refusal names the action trust binding"
|
|
402
|
+
assert_absent "$ACTION_TAMPER_LOG" "the mutated action was not executed"
|
|
403
|
+
assert_absent "$H/state/when/when-action-tamper.fired" "no fire was claimed for mutated action bytes"
|
|
404
|
+
pass "mutated action bytes are refused before claiming the fire"
|
|
405
|
+
|
|
406
|
+
printf 'all fm-procevent-when tests passed\n'
|