@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,171 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-wake-daemon-lifecycle-e2e.test.sh - the watcher + supervise-daemon
|
|
3
|
+
# lifecycle, end to end, over one shared state root and a shimmed tmux:
|
|
4
|
+
#
|
|
5
|
+
# routine status -> self-handled, queued
|
|
6
|
+
# terminal status written while the watcher is DOWN -> caught on restart (catch-up)
|
|
7
|
+
# drain queued records -> exactly ONE captain-relevant digest is buffered
|
|
8
|
+
# housekeeping catch-all scan -> NO duplicate digest
|
|
9
|
+
# buffered digest flushes to the supervisor pane as exactly ONE submission
|
|
10
|
+
# stale working-pane: transient (self + marker) -> persistent (escalates once,
|
|
11
|
+
# clears its marker) -> resumed/busy (clears without escalating)
|
|
12
|
+
#
|
|
13
|
+
# This proves the operator-visible routing/queueing/dedupe behavior through real
|
|
14
|
+
# fm-watch.sh runs plus the daemon's own functions. The captain-relevant
|
|
15
|
+
# status-phrase matrix and the lock-primitive races stay as focused units
|
|
16
|
+
# (fm-daemon.test.sh, fm-watcher-lock.test.sh) - an e2e cannot deterministically
|
|
17
|
+
# cover a race, and the phrase list is a product contract worth a dedicated test.
|
|
18
|
+
set -u
|
|
19
|
+
|
|
20
|
+
# shellcheck source=tests/wake-helpers.sh
|
|
21
|
+
. "$(dirname "${BASH_SOURCE[0]}")/wake-helpers.sh"
|
|
22
|
+
|
|
23
|
+
WATCH="$ROOT/bin/fm-watch.sh"
|
|
24
|
+
DRAIN="$ROOT/bin/fm-wake-drain.sh"
|
|
25
|
+
DAEMON="$ROOT/bin/fm-supervise-daemon.sh"
|
|
26
|
+
|
|
27
|
+
# Source the daemon's pure functions (its main loop is guarded out under sourcing).
|
|
28
|
+
if [ -z "${FM_TEST_DAEMON_SOURCED:-}" ]; then
|
|
29
|
+
export FM_TEST_DAEMON_SOURCED=1
|
|
30
|
+
# shellcheck source=/dev/null
|
|
31
|
+
. "$DAEMON"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
TMP_ROOT=$(fm_test_tmproot fm-wake-daemon-e2e)
|
|
35
|
+
|
|
36
|
+
# Run the daemon-managed watcher once: under the supervise-daemon (away mode) the
|
|
37
|
+
# watcher is one-shot - it exits with a single reason line on EVERY wake and the
|
|
38
|
+
# daemon does the triage. This e2e exercises exactly that path, so it runs with
|
|
39
|
+
# state/.afk present (which the daemon owns) to keep the watcher one-shot; the
|
|
40
|
+
# always-on standalone triage is covered by fm-watch-triage.test.sh. fakebin
|
|
41
|
+
# shadows tmux. Echoes nothing; the caller reads $out.
|
|
42
|
+
run_watcher_once() {
|
|
43
|
+
local state=$1 fakebin=$2 out=$3
|
|
44
|
+
mkdir -p "$state"
|
|
45
|
+
date '+%s' > "$state/.afk"
|
|
46
|
+
PATH="$fakebin:$PATH" FM_STATE_OVERRIDE="$state" FM_POLL=1 FM_SIGNAL_GRACE=1 \
|
|
47
|
+
FM_CHECK_INTERVAL=999999 FM_HEARTBEAT=999999 "$WATCH" > "$out" &
|
|
48
|
+
wait_for_exit "$!" 50
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ack_handled_wakes() { # <state> <drain-stderr>
|
|
52
|
+
local state=$1 drain_err=$2 sequence generation
|
|
53
|
+
sequence=$(sed -n 's/^WAKE_ACK_REQUIRED:.*--ack-through \([0-9][0-9]*\) --recovery-generation [A-Za-z0-9._-][A-Za-z0-9._-]*$/\1/p' "$drain_err")
|
|
54
|
+
generation=$(sed -n 's/^WAKE_ACK_REQUIRED:.*--ack-through [0-9][0-9]* --recovery-generation \([A-Za-z0-9._-][A-Za-z0-9._-]*\)$/\1/p' "$drain_err")
|
|
55
|
+
[ -n "$sequence" ] && [ -n "$generation" ] || return 1
|
|
56
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" --ack-through "$sequence" \
|
|
57
|
+
--recovery-generation "$generation"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# --- Phase 1: routine self-handled, queued; terminal caught after restart ---
|
|
61
|
+
test_routine_then_terminal_after_restart() {
|
|
62
|
+
local dir state fakebin out drain_out drain_err status_file
|
|
63
|
+
dir=$(make_supercase wd-lifecycle)
|
|
64
|
+
state="$dir/state"
|
|
65
|
+
fakebin="$dir/fakebin"
|
|
66
|
+
out="$dir/watch.out"
|
|
67
|
+
drain_out="$dir/drain.out"
|
|
68
|
+
drain_err="$dir/drain.err"
|
|
69
|
+
status_file="$state/task-w1.status"
|
|
70
|
+
|
|
71
|
+
# A routine status fires a signal; the watcher queues it and exits.
|
|
72
|
+
printf 'working: building\n' > "$status_file"
|
|
73
|
+
run_watcher_once "$state" "$fakebin" "$out" || fail "watcher did not exit for the routine signal"
|
|
74
|
+
grep -F "signal: $status_file" "$out" >/dev/null || fail "watcher did not report the routine signal"
|
|
75
|
+
|
|
76
|
+
# Drain it and route through the daemon: a routine status self-handles.
|
|
77
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$drain_out" 2> "$drain_err" \
|
|
78
|
+
|| fail "drain after routine signal failed"
|
|
79
|
+
grep "$(printf '\tsignal\t')" "$drain_out" | grep -F "$status_file" >/dev/null \
|
|
80
|
+
|| fail "routine signal was not queued"
|
|
81
|
+
FM_STATE_OVERRIDE="$state" handle_wake "signal: $status_file" "$state"
|
|
82
|
+
ack_handled_wakes "$state" "$drain_err" || fail "routine wake acknowledgement failed"
|
|
83
|
+
[ ! -s "$state/.subsuper-escalations" ] || fail "routine status was escalated by the daemon"
|
|
84
|
+
|
|
85
|
+
# The watcher is now DOWN (one-shot exit). A terminal status lands while it is
|
|
86
|
+
# down; the next watcher run must catch it up (losslessness across restart).
|
|
87
|
+
printf 'done: PR https://example.test/pr/900\n' >> "$status_file"
|
|
88
|
+
: > "$out"
|
|
89
|
+
run_watcher_once "$state" "$fakebin" "$out" || fail "restarted watcher did not exit for the terminal signal"
|
|
90
|
+
grep -F "signal: $status_file" "$out" >/dev/null || fail "terminal signal written while watcher down was not caught on restart"
|
|
91
|
+
|
|
92
|
+
# Drain and route the terminal: exactly ONE digest is buffered.
|
|
93
|
+
: > "$drain_out"
|
|
94
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$drain_out" 2> "$drain_err" \
|
|
95
|
+
|| fail "drain after terminal signal failed"
|
|
96
|
+
FM_STATE_OVERRIDE="$state" handle_wake "signal: $status_file" "$state"
|
|
97
|
+
ack_handled_wakes "$state" "$drain_err" || fail "terminal wake acknowledgement failed"
|
|
98
|
+
[ -s "$state/.subsuper-escalations" ] || fail "captain-relevant terminal status was not buffered"
|
|
99
|
+
[ "$(wc -l < "$state/.subsuper-escalations" | tr -d ' ')" -eq 1 ] \
|
|
100
|
+
|| fail "expected exactly one buffered digest after the terminal signal"
|
|
101
|
+
|
|
102
|
+
# The catch-all heartbeat scan must NOT re-escalate the same status (no dup).
|
|
103
|
+
FM_STATE_OVERRIDE="$state" housekeeping "$state"
|
|
104
|
+
[ "$(wc -l < "$state/.subsuper-escalations" | tr -d ' ')" -eq 1 ] \
|
|
105
|
+
|| fail "catch-all scan duplicated the already-buffered digest"
|
|
106
|
+
|
|
107
|
+
# With afk active, the buffered digest flushes to the supervisor pane as ONE
|
|
108
|
+
# submission (one typed line + one Enter), then the buffer clears.
|
|
109
|
+
local sent
|
|
110
|
+
sent="$dir/sent.log"; : > "$sent"
|
|
111
|
+
printf '❯\n' > "$dir/pane.txt"
|
|
112
|
+
afk_enter "$state"
|
|
113
|
+
PATH="$fakebin:$PATH" FM_FAKE_TMUX_PANE_ALIVE=1 FM_FAKE_TMUX_SENT="$sent" \
|
|
114
|
+
FM_FAKE_TMUX_CAPTURE="$dir/pane.txt" FM_ESCALATE_BATCH_SECS=0 escalate_flush "$state" \
|
|
115
|
+
|| fail "escalate_flush failed for the buffered digest"
|
|
116
|
+
[ "$(grep -c '\[ENTER\]' "$sent")" -eq 1 ] || fail "buffered digest was not submitted exactly once"
|
|
117
|
+
[ ! -s "$state/.subsuper-escalations" ] || fail "buffer not cleared after a successful flush"
|
|
118
|
+
pass "lifecycle: routine self-handles, terminal survives a watcher restart, buffers once, no dup, injects once"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# --- Phase 2: stale working-pane transient -> persistent -> resumed ----------
|
|
122
|
+
test_stale_pane_transient_persistent_resume() {
|
|
123
|
+
local dir state fakebin win key resumed_gen
|
|
124
|
+
dir=$(make_supercase wd-stale)
|
|
125
|
+
state="$dir/state"
|
|
126
|
+
fakebin="$dir/fakebin"
|
|
127
|
+
win="sess:fm-stale-w2"
|
|
128
|
+
key=$(printf '%s' "stale-w2" | tr ':/.' '___')
|
|
129
|
+
printf 'working: compiling\n' > "$state/stale-w2.status"
|
|
130
|
+
|
|
131
|
+
# Transient: first stale observation self-handles and records a marker.
|
|
132
|
+
stale_marker_record "$win" "$state"
|
|
133
|
+
case "$(FM_STATE_OVERRIDE="$state" classify_stale "$win" "$state")" in
|
|
134
|
+
self\|*) : ;;
|
|
135
|
+
*) fail "transient stale did not self-handle" ;;
|
|
136
|
+
esac
|
|
137
|
+
[ -e "$state/.subsuper-stale-$key" ] || fail "transient stale did not record a persistence marker"
|
|
138
|
+
|
|
139
|
+
# Persistent: the marker ages past the threshold and the pane is still idle, so
|
|
140
|
+
# housekeeping escalates exactly once and clears the marker.
|
|
141
|
+
printf 'idle prompt $\n' > "$dir/pane.txt"
|
|
142
|
+
echo $(( $(date +%s) - 500 )) > "$state/.subsuper-stale-$key"
|
|
143
|
+
: > "$state/.subsuper-escalations" 2>/dev/null || true
|
|
144
|
+
PATH="$fakebin:$PATH" FM_FAKE_TMUX_WINDOW="$win" FM_FAKE_TMUX_CAPTURE="$dir/pane.txt" \
|
|
145
|
+
FM_STATE_OVERRIDE="$state" FM_STALE_ESCALATE_SECS=240 housekeeping "$state" \
|
|
146
|
+
2>"$dir/housekeeping.err"
|
|
147
|
+
[ ! -s "$dir/housekeeping.err" ] \
|
|
148
|
+
|| fail "missing task metadata leaked a raw read error: $(cat "$dir/housekeeping.err")"
|
|
149
|
+
[ -s "$state/.subsuper-escalations" ] || fail "persistent stale did not escalate"
|
|
150
|
+
[ ! -e "$state/.subsuper-stale-$key" ] || fail "stale marker not cleared after escalation"
|
|
151
|
+
|
|
152
|
+
# Resumed: a fresh transient marker but the crew is provably working again ->
|
|
153
|
+
# housekeeping clears the marker without escalating. The proof is the crew's
|
|
154
|
+
# own semantic busy-state record (bin/fm-busy-lib.sh), not rendered pane text.
|
|
155
|
+
stale_marker_record "$win" "$state"
|
|
156
|
+
echo $(( $(date +%s) - 500 )) > "$state/.subsuper-stale-$key"
|
|
157
|
+
printf 'Working...\n' > "$dir/pane.txt"
|
|
158
|
+
fm_write_meta "$state/stale-w2.meta" "window=$win" "worktree=$dir/wt" "kind=ship" "harness=pi"
|
|
159
|
+
resumed_gen=$("$ROOT/bin/fm-busy-event.sh" arm "$state" stale-w2)
|
|
160
|
+
"$ROOT/bin/fm-busy-event.sh" apply "$state" stale-w2 busy --gen "$resumed_gen" \
|
|
161
|
+
--source pi-ext --event agent-start
|
|
162
|
+
: > "$state/.subsuper-escalations"
|
|
163
|
+
PATH="$fakebin:$PATH" FM_FAKE_TMUX_WINDOW="$win" FM_FAKE_TMUX_CAPTURE="$dir/pane.txt" \
|
|
164
|
+
FM_STATE_OVERRIDE="$state" FM_STALE_ESCALATE_SECS=240 housekeeping "$state"
|
|
165
|
+
[ ! -e "$state/.subsuper-stale-$key" ] || fail "resumed stale marker was not cleared"
|
|
166
|
+
[ ! -s "$state/.subsuper-escalations" ] || fail "resumed (busy) stale was escalated"
|
|
167
|
+
pass "lifecycle: stale pane transient self-handles, persistent escalates once and clears, resumed clears quietly"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
test_routine_then_terminal_after_restart
|
|
171
|
+
test_stale_pane_transient_persistent_resume
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-wake-drain-open-decisions-cursor.test.sh - end-to-end behavior tests
|
|
3
|
+
# for the incremental, cursor-backed OPEN DECISIONS scan
|
|
4
|
+
# (fm-classify-lib.sh's status_open_decisions_incremental /
|
|
5
|
+
# scan_open_decisions_incremental, wired into bin/fm-wake-drain.sh). These drive
|
|
6
|
+
# the REAL drain script across MANY successive invocations over a status log
|
|
7
|
+
# that keeps growing, and assert both the printed output and a bounded-cost
|
|
8
|
+
# property, not the fold's own source text. tests/fm-wake-drain-open-decisions.test.sh
|
|
9
|
+
# already covers the fold's single-drain correctness; this file covers the
|
|
10
|
+
# cursor's cross-drain persistence and cost bound.
|
|
11
|
+
set -u
|
|
12
|
+
|
|
13
|
+
# shellcheck source=tests/wake-helpers.sh
|
|
14
|
+
. "$(dirname "${BASH_SOURCE[0]}")/wake-helpers.sh"
|
|
15
|
+
|
|
16
|
+
DRAIN="$ROOT/bin/fm-wake-drain.sh"
|
|
17
|
+
|
|
18
|
+
TMP_ROOT=$(fm_test_tmproot fm-wake-drain-open-decisions-cursor-tests)
|
|
19
|
+
|
|
20
|
+
# Append <count> harmless filler lines (routine working: notes, never a
|
|
21
|
+
# needs-decision/blocked/resolved verb) to <file> and print the exact number of
|
|
22
|
+
# bytes appended, so a test can assert the read-probe's byte count against a
|
|
23
|
+
# known ground truth rather than an approximation.
|
|
24
|
+
append_filler() { # <file> <count>
|
|
25
|
+
local file=$1 count=$2 i=0 before after
|
|
26
|
+
before=$(LC_ALL=C wc -c < "$file" 2>/dev/null | tr -d '[:space:]')
|
|
27
|
+
[ -n "$before" ] || before=0
|
|
28
|
+
while [ "$i" -lt "$count" ]; do
|
|
29
|
+
printf 'working: routine filler padding line %04d of growing status log\n' "$i" >> "$file"
|
|
30
|
+
i=$((i + 1))
|
|
31
|
+
done
|
|
32
|
+
after=$(LC_ALL=C wc -c < "$file" 2>/dev/null | tr -d '[:space:]')
|
|
33
|
+
printf '%s\n' "$((after - before))"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# The byte count the read-probe recorded for <file> on its MOST RECENT
|
|
37
|
+
# incremental fold call (last matching line in the probe log).
|
|
38
|
+
last_probe_bytes() { # <probe-file> <status-file>
|
|
39
|
+
grep -F "$(printf '%s\t' "$2")" "$1" 2>/dev/null | tail -1 | cut -f2
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
test_buried_decision_survives_many_growing_drains_and_resolution_clears_it() {
|
|
43
|
+
local dir state out probe status bootstrap_bytes total_size round increment_bytes probe_bytes
|
|
44
|
+
dir=$(make_case cursor-lifecycle)
|
|
45
|
+
state="$dir/state"
|
|
46
|
+
out="$dir/drain.out"
|
|
47
|
+
probe="$dir/probe.tsv"
|
|
48
|
+
status="$state/task1.status"
|
|
49
|
+
: > "$probe"
|
|
50
|
+
|
|
51
|
+
# Open a keyed decision, buried under an initial filler round big enough to
|
|
52
|
+
# make a full-file rescan cost visibly more than a small incremental one.
|
|
53
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$status"
|
|
54
|
+
append_filler "$status" 400 >/dev/null
|
|
55
|
+
|
|
56
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
57
|
+
|| fail "first drain over a large buried decision failed"
|
|
58
|
+
grep -F 'task1' "$out" | grep -F '[key=api-shape]' | grep -F 'pick REST or RPC' >/dev/null \
|
|
59
|
+
|| fail "the buried decision did not surface on the bootstrap drain"
|
|
60
|
+
bootstrap_bytes=$(last_probe_bytes "$probe" "$status")
|
|
61
|
+
[ -n "$bootstrap_bytes" ] && [ "$bootstrap_bytes" -gt 0 ] \
|
|
62
|
+
|| fail "the bootstrap drain recorded no incremental read at all"
|
|
63
|
+
|
|
64
|
+
# Many further drains, each appending only a SMALL increment while the total
|
|
65
|
+
# log keeps growing large. The buried decision must resurface on EVERY one of
|
|
66
|
+
# them (never dropped just because it is old or buried under more appends),
|
|
67
|
+
# and each drain's read-probe byte count must match ONLY that round's small
|
|
68
|
+
# increment - never the ever-growing total file size - proving the read cost
|
|
69
|
+
# is bounded by new appends, not by total log size.
|
|
70
|
+
for round in 1 2 3 4 5; do
|
|
71
|
+
increment_bytes=$(append_filler "$status" 20)
|
|
72
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
73
|
+
|| fail "drain $round over a growing log failed"
|
|
74
|
+
grep -F 'task1' "$out" | grep -F '[key=api-shape]' | grep -F 'pick REST or RPC' >/dev/null \
|
|
75
|
+
|| fail "the buried decision was dropped on growth round $round"
|
|
76
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
77
|
+
[ "$probe_bytes" = "$increment_bytes" ] \
|
|
78
|
+
|| fail "round $round read $probe_bytes bytes, expected exactly this round's $increment_bytes-byte increment (cost is not bounded)"
|
|
79
|
+
done
|
|
80
|
+
total_size=$(LC_ALL=C wc -c < "$status" | tr -d '[:space:]')
|
|
81
|
+
[ "$total_size" -gt "$bootstrap_bytes" ] \
|
|
82
|
+
|| fail "test setup error: the log never grew past its bootstrap size"
|
|
83
|
+
|
|
84
|
+
# Now resolve it. The very next drain's own read (a small increment) must
|
|
85
|
+
# clear it - not by rescanning the whole now-large file, but by folding the
|
|
86
|
+
# small resolved line into the still-persisted open set.
|
|
87
|
+
increment_bytes=$(printf 'resolved [key=api-shape]: went with REST\n' | tee -a "$status" | LC_ALL=C wc -c | tr -d '[:space:]')
|
|
88
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
89
|
+
|| fail "resolution drain failed"
|
|
90
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
91
|
+
fail "the resolved decision still printed as open right after resolution: $(cat "$out")"
|
|
92
|
+
fi
|
|
93
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
94
|
+
[ "$probe_bytes" = "$increment_bytes" ] \
|
|
95
|
+
|| fail "the resolution drain read $probe_bytes bytes, expected exactly the $increment_bytes-byte resolved line (cost is not bounded)"
|
|
96
|
+
|
|
97
|
+
# Grow the log again after resolution: the decision must stay cleared (a
|
|
98
|
+
# closed decision is not resurrected by unrelated later growth), and the read
|
|
99
|
+
# cost for this final round must still be bounded to that round's increment.
|
|
100
|
+
increment_bytes=$(append_filler "$status" 20)
|
|
101
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
102
|
+
|| fail "post-resolution growth drain failed"
|
|
103
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
104
|
+
fail "a resolved decision reappeared after later unrelated growth: $(cat "$out")"
|
|
105
|
+
fi
|
|
106
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
107
|
+
[ "$probe_bytes" = "$increment_bytes" ] \
|
|
108
|
+
|| fail "the post-resolution drain read $probe_bytes bytes, expected exactly the $increment_bytes-byte increment (cost is not bounded)"
|
|
109
|
+
|
|
110
|
+
pass "a buried decision survives many growing drains with bounded read cost, and resolution durably clears it at bounded cost too"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
test_truncated_log_falls_back_to_a_full_refold_not_a_dropped_decision() {
|
|
114
|
+
local dir state out probe status rewritten_bytes probe_bytes
|
|
115
|
+
dir=$(make_case cursor-truncation)
|
|
116
|
+
state="$dir/state"
|
|
117
|
+
out="$dir/drain.out"
|
|
118
|
+
probe="$dir/probe.tsv"
|
|
119
|
+
status="$state/task2.status"
|
|
120
|
+
: > "$probe"
|
|
121
|
+
|
|
122
|
+
printf 'needs-decision [key=migration]: pick the rollout plan\n' > "$status"
|
|
123
|
+
append_filler "$status" 100 >/dev/null
|
|
124
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
125
|
+
|| fail "initial drain before truncation failed"
|
|
126
|
+
grep -F 'task2' "$out" | grep -F '[key=migration]' >/dev/null \
|
|
127
|
+
|| fail "the decision did not surface before truncation"
|
|
128
|
+
|
|
129
|
+
# Simulate a rewritten/truncated log (shrunk below the persisted cursor
|
|
130
|
+
# offset): the decision is re-opened by a fresh needs-decision line in the
|
|
131
|
+
# rewritten content, and the incremental scan must fall back to a full
|
|
132
|
+
# re-fold of the new, smaller file rather than trusting a now-invalid cursor.
|
|
133
|
+
printf 'needs-decision [key=migration]: rewritten after truncation\n' > "$status"
|
|
134
|
+
rewritten_bytes=$(LC_ALL=C wc -c < "$status" | tr -d '[:space:]')
|
|
135
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
136
|
+
|| fail "post-truncation drain failed"
|
|
137
|
+
grep -F 'task2' "$out" | grep -F '[key=migration]' | grep -F 'rewritten after truncation' >/dev/null \
|
|
138
|
+
|| fail "the rewritten decision after truncation did not surface"
|
|
139
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
140
|
+
[ "$probe_bytes" = "$rewritten_bytes" ] \
|
|
141
|
+
|| fail "post-truncation drain read $probe_bytes bytes, expected a full re-fold of the $rewritten_bytes-byte rewritten file"
|
|
142
|
+
|
|
143
|
+
pass "a truncated/rewritten log falls back to a full re-fold instead of dropping or misreading the decision"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
test_same_size_rewrite_is_detected_via_inode_identity() {
|
|
147
|
+
local dir state out probe status new_bytes probe_bytes
|
|
148
|
+
dir=$(make_case cursor-rotation)
|
|
149
|
+
state="$dir/state"
|
|
150
|
+
out="$dir/drain.out"
|
|
151
|
+
probe="$dir/probe.tsv"
|
|
152
|
+
status="$state/task3.status"
|
|
153
|
+
: > "$probe"
|
|
154
|
+
|
|
155
|
+
printf 'needs-decision [key=migration]: pick the rollout plan\n' > "$status"
|
|
156
|
+
append_filler "$status" 100 >/dev/null
|
|
157
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
158
|
+
|| fail "initial drain before rotation failed"
|
|
159
|
+
grep -F 'task3' "$out" | grep -F '[key=migration]' >/dev/null \
|
|
160
|
+
|| fail "the decision did not surface before rotation"
|
|
161
|
+
|
|
162
|
+
# Replace the file at the same path with a DIFFERENT file of the SAME byte
|
|
163
|
+
# size (mv gives the destination path a new inode) - a same-size rewrite,
|
|
164
|
+
# which a plain offset>size shrink check alone would NOT catch. The buried
|
|
165
|
+
# decision must still surface: the device+inode identity check must detect
|
|
166
|
+
# this as a rotation/recreation and fall back to a full re-fold.
|
|
167
|
+
new_bytes=$(LC_ALL=C wc -c < "$status" | tr -d '[:space:]')
|
|
168
|
+
printf 'needs-decision [key=migration]: rewritten via rotation\n' > "$dir/replacement"
|
|
169
|
+
padded=$(LC_ALL=C wc -c < "$dir/replacement" | tr -d '[:space:]')
|
|
170
|
+
pad=$((new_bytes - padded))
|
|
171
|
+
[ "$pad" -gt 0 ] && head -c "$pad" /dev/zero | tr '\0' 'x' >> "$dir/replacement"
|
|
172
|
+
mv "$dir/replacement" "$status"
|
|
173
|
+
[ "$(LC_ALL=C wc -c < "$status" | tr -d '[:space:]')" = "$new_bytes" ] \
|
|
174
|
+
|| fail "test setup error: the rotated replacement is not the same size as the original"
|
|
175
|
+
|
|
176
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
177
|
+
|| fail "post-rotation drain failed"
|
|
178
|
+
grep -F 'task3' "$out" | grep -F '[key=migration]' | grep -F 'rewritten via rotation' >/dev/null \
|
|
179
|
+
|| fail "the same-size rotated file's decision did not surface (inode-identity check did not fire)"
|
|
180
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
181
|
+
[ "$probe_bytes" = "$new_bytes" ] \
|
|
182
|
+
|| fail "post-rotation drain read $probe_bytes bytes, expected a full re-fold of the $new_bytes-byte replacement"
|
|
183
|
+
|
|
184
|
+
pass "a same-size file rotation (new inode) is detected and falls back to a full re-fold"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
test_read_failure_preserves_state_for_retry() {
|
|
188
|
+
local dir state reader statusfile cursor out before_cursor after_cursor
|
|
189
|
+
dir=$(make_case cursor-read-failure)
|
|
190
|
+
state="$dir/state"
|
|
191
|
+
reader="$dir/fail-reader"
|
|
192
|
+
statusfile="$state/task4.status"
|
|
193
|
+
cursor="$state/.task4.open-decisions-cursor"
|
|
194
|
+
out="$dir/drain.out"
|
|
195
|
+
|
|
196
|
+
printf 'needs-decision [key=x]: something important\n' > "$statusfile"
|
|
197
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
198
|
+
|| fail "bootstrap drain before the injected read failure failed"
|
|
199
|
+
grep -F 'task4' "$out" | grep -F '[key=x]' | grep -F 'something important' >/dev/null \
|
|
200
|
+
|| fail "the decision did not surface on the bootstrap drain"
|
|
201
|
+
[ -s "$cursor" ] || fail "no cursor was persisted after the bootstrap drain"
|
|
202
|
+
before_cursor=$(LC_ALL=C cksum "$cursor")
|
|
203
|
+
|
|
204
|
+
printf 'working: more routine content\n' >> "$statusfile"
|
|
205
|
+
printf '#!/usr/bin/env bash\nexit 1\n' > "$reader"
|
|
206
|
+
chmod +x "$reader"
|
|
207
|
+
|
|
208
|
+
FM_STATE_OVERRIDE="$state" FM_STATUS_SPAN_READER="$reader" "$DRAIN" > "$out" \
|
|
209
|
+
|| fail "wake drain failed instead of preserving state after the injected read failure"
|
|
210
|
+
[ ! -s "$out" ] \
|
|
211
|
+
|| fail "the failed presentation read emitted a partial status presentation: $(command cat "$out")"
|
|
212
|
+
after_cursor=$(LC_ALL=C cksum "$cursor")
|
|
213
|
+
[ "$after_cursor" = "$before_cursor" ] \
|
|
214
|
+
|| fail "the failed read advanced or rewrote the persisted cursor"
|
|
215
|
+
|
|
216
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
217
|
+
|| fail "wake drain did not recover after the injected read failure"
|
|
218
|
+
grep -F 'task4' "$out" | grep -F '[key=x]' | grep -F 'something important' >/dev/null \
|
|
219
|
+
|| fail "the open decision disappeared when presentation reads recovered: $(command cat "$out")"
|
|
220
|
+
|
|
221
|
+
pass "a failed presentation read preserves status state for retry"
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
test_cursor_cache_read_failure_refolds_without_replaying_unread_status() {
|
|
225
|
+
local dir state fakebin statusfile cursor out probe real_cat status_bytes probe_bytes
|
|
226
|
+
dir=$(make_case cursor-cache-read-failure)
|
|
227
|
+
state="$dir/state"
|
|
228
|
+
fakebin="$dir/failbin"
|
|
229
|
+
mkdir -p "$fakebin"
|
|
230
|
+
statusfile="$state/task5.status"
|
|
231
|
+
cursor="$state/.task5.open-decisions-cursor"
|
|
232
|
+
out="$dir/drain.out"
|
|
233
|
+
probe="$dir/probe.tsv"
|
|
234
|
+
real_cat=$(command -v cat)
|
|
235
|
+
|
|
236
|
+
{
|
|
237
|
+
printf 'needs-decision [key=cache]: recover from authoritative status\n'
|
|
238
|
+
printf 'note: already handled informational status\n'
|
|
239
|
+
} > "$statusfile"
|
|
240
|
+
append_filler "$statusfile" 40 >/dev/null
|
|
241
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
242
|
+
|| fail "bootstrap drain before the cursor-cache read failure failed"
|
|
243
|
+
grep -F 'task5' "$out" | grep -F '[key=cache]' | grep -F 'authoritative status' >/dev/null \
|
|
244
|
+
|| fail "the decision did not surface before the cursor-cache read failure"
|
|
245
|
+
grep -F 'task5 note: already handled informational status' "$out" >/dev/null \
|
|
246
|
+
|| fail "the bootstrap drain did not surface the informational status"
|
|
247
|
+
[ -s "$cursor" ] || fail "no cursor was persisted before the cursor-cache read failure"
|
|
248
|
+
|
|
249
|
+
printf 'working: appended before cache failure\n' >> "$statusfile"
|
|
250
|
+
status_bytes=$(LC_ALL=C wc -c < "$statusfile" | tr -d '[:space:]')
|
|
251
|
+
: > "$probe"
|
|
252
|
+
cat > "$fakebin/cat" <<SH
|
|
253
|
+
#!/usr/bin/env bash
|
|
254
|
+
if [ "\$#" -eq 1 ] && [ "\$1" = "$cursor" ]; then
|
|
255
|
+
exit 1
|
|
256
|
+
fi
|
|
257
|
+
exec "$real_cat" "\$@"
|
|
258
|
+
SH
|
|
259
|
+
chmod +x "$fakebin/cat"
|
|
260
|
+
|
|
261
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" PATH="$fakebin:$PATH" "$DRAIN" > "$out" \
|
|
262
|
+
|| fail "wake drain failed instead of refolding after the cursor-cache read failure"
|
|
263
|
+
grep -F 'task5' "$out" | grep -F '[key=cache]' | grep -F 'authoritative status' >/dev/null \
|
|
264
|
+
|| fail "the cursor-cache read failure hid the recurring open decision: $(command cat "$out")"
|
|
265
|
+
if grep -F 'UNREAD STATUS' "$out" >/dev/null \
|
|
266
|
+
|| grep -F 'already handled informational status' "$out" >/dev/null; then
|
|
267
|
+
fail "the cursor-cache read failure replayed handled informational status as new: $(command cat "$out")"
|
|
268
|
+
fi
|
|
269
|
+
probe_bytes=$(last_probe_bytes "$probe" "$statusfile")
|
|
270
|
+
[ "$probe_bytes" = "$status_bytes" ] \
|
|
271
|
+
|| fail "the cursor-cache read failure read $probe_bytes bytes, expected a full $status_bytes-byte authoritative refold"
|
|
272
|
+
|
|
273
|
+
pass "a cursor-cache read failure refolds decisions without replaying handled unread status"
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
test_pre_fix_cursor_refolds_corr_tagged_decision() {
|
|
277
|
+
local dir state status cursor out probe status_bytes ident probe_bytes
|
|
278
|
+
dir=$(make_case cursor-corr-tag-migration)
|
|
279
|
+
state="$dir/state"
|
|
280
|
+
status="$state/task7.status"
|
|
281
|
+
cursor="$state/.task7.open-decisions-cursor"
|
|
282
|
+
out="$dir/drain.out"
|
|
283
|
+
probe="$dir/probe.tsv"
|
|
284
|
+
|
|
285
|
+
printf 'needs-decision [corr=d448ea86afa4bf67] [key=loan-installment-cadence-amount]: pick the cadence\n' > "$status"
|
|
286
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
287
|
+
|| fail "bootstrap drain for the corr-tag cursor migration failed"
|
|
288
|
+
ident=$(sed -n 's/^ident=//p' "$cursor")
|
|
289
|
+
[ -n "$ident" ] || fail "bootstrap drain did not persist a file identity"
|
|
290
|
+
status_bytes=$(LC_ALL=C wc -c < "$status" | tr -d '[:space:]')
|
|
291
|
+
{
|
|
292
|
+
printf 'version=3\n'
|
|
293
|
+
printf 'offset=%s\n' "$status_bytes"
|
|
294
|
+
printf 'ident=%s\n' "$ident"
|
|
295
|
+
} > "$cursor"
|
|
296
|
+
: > "$probe"
|
|
297
|
+
|
|
298
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
299
|
+
|| fail "drain failed while migrating the pre-fix corr-tag cursor"
|
|
300
|
+
grep -F 'task7 [key=loan-installment-cadence-amount] needs-decision: pick the cadence' "$out" >/dev/null \
|
|
301
|
+
|| fail "the pre-fix cursor hid the corr-tagged decision after migration: $(cat "$out")"
|
|
302
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
303
|
+
[ "$probe_bytes" = "$status_bytes" ] \
|
|
304
|
+
|| fail "the pre-fix cursor read $probe_bytes bytes instead of refolding all $status_bytes authoritative bytes"
|
|
305
|
+
|
|
306
|
+
pass "a pre-fix cursor is rebuilt so a previously skipped corr-tagged decision surfaces"
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
test_previous_fold_cache_is_refolded_under_current_semantics() {
|
|
310
|
+
local dir state status cursor out probe status_bytes ident appended_bytes probe_bytes
|
|
311
|
+
dir=$(make_case cursor-fold-version)
|
|
312
|
+
state="$dir/state"
|
|
313
|
+
status="$state/task6.status"
|
|
314
|
+
cursor="$state/.task6.open-decisions-cursor"
|
|
315
|
+
out="$dir/drain.out"
|
|
316
|
+
probe="$dir/probe.tsv"
|
|
317
|
+
|
|
318
|
+
printf 'blocked [key=pending-reply-abcdef0123456789]: forged decision\n' > "$status"
|
|
319
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
320
|
+
|| fail "bootstrap drain for the fold-version migration failed"
|
|
321
|
+
[ ! -s "$out" ] || fail "the current whole-file semantics accepted the foreign reserved-key decision: $(cat "$out")"
|
|
322
|
+
ident=$(sed -n 's/^ident=//p' "$cursor")
|
|
323
|
+
status_bytes=$(LC_ALL=C wc -c < "$status" | tr -d '[:space:]')
|
|
324
|
+
{
|
|
325
|
+
printf 'offset=%s\n' "$status_bytes"
|
|
326
|
+
printf 'ident=%s\n' "$ident"
|
|
327
|
+
printf 'pending-reply-abcdef0123456789\tblocked\tforged decision'
|
|
328
|
+
} > "$cursor"
|
|
329
|
+
: > "$probe"
|
|
330
|
+
|
|
331
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
332
|
+
|| fail "drain failed while upgrading the previous fold cache"
|
|
333
|
+
[ ! -s "$out" ] || fail "the previous fold cache kept surfacing a foreign reserved-key decision: $(cat "$out")"
|
|
334
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
335
|
+
[ "$probe_bytes" = "$status_bytes" ] \
|
|
336
|
+
|| fail "the previous fold cache read $probe_bytes bytes instead of refolding all $status_bytes authoritative bytes"
|
|
337
|
+
|
|
338
|
+
appended_bytes=$(printf 'needs-decision [key=current]: choose the current path\n' | tee -a "$status" | LC_ALL=C wc -c | tr -d '[:space:]')
|
|
339
|
+
FM_STATE_OVERRIDE="$state" FM_OPEN_DECISIONS_READ_PROBE="$probe" "$DRAIN" > "$out" \
|
|
340
|
+
|| fail "same-version incremental drain failed after cache migration"
|
|
341
|
+
grep -F 'task6 [key=current] needs-decision: choose the current path' "$out" >/dev/null \
|
|
342
|
+
|| fail "the same-version append did not fold into the migrated open set"
|
|
343
|
+
probe_bytes=$(last_probe_bytes "$probe" "$status")
|
|
344
|
+
[ "$probe_bytes" = "$appended_bytes" ] \
|
|
345
|
+
|| fail "the same-version fold read $probe_bytes bytes instead of only the $appended_bytes-byte append"
|
|
346
|
+
|
|
347
|
+
pass "an old fold cache is rebuilt once before same-version incremental reads resume"
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
test_truncated_log_falls_back_to_a_full_refold_not_a_dropped_decision
|
|
351
|
+
test_same_size_rewrite_is_detected_via_inode_identity
|
|
352
|
+
test_read_failure_preserves_state_for_retry
|
|
353
|
+
test_cursor_cache_read_failure_refolds_without_replaying_unread_status
|
|
354
|
+
test_pre_fix_cursor_refolds_corr_tagged_decision
|
|
355
|
+
test_previous_fold_cache_is_refolded_under_current_semantics
|
|
356
|
+
test_buried_decision_survives_many_growing_drains_and_resolution_clears_it
|