@zerwiz/ymir 0.1.4 → 0.1.7
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/README.md +74 -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 +360 -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.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +11 -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/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/runes_audit.md +5 -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 +121 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/migrations/0005-roots-out-of-tree.sh +158 -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 +159 -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 +736 -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 +539 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +763 -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 +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +415 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +133 -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 +101 -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 +180 -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 +503 -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 +90 -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 +57 -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 +35 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/install.md +69 -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 +498 -0
- package/CHANGELOG.md +1913 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +114 -60
- 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 +97 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +108 -0
- package/RULES/07-config.md +101 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/09-electron.md +58 -0
- package/RULES/README.md +22 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +133 -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 +256 -0
- package/bin/apodex-smoke-test.sh +105 -0
- package/bin/bifrost-bridge.sh +131 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +112 -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 +51 -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-assemble.sh +154 -0
- package/bin/changelog-guard.sh +197 -0
- package/bin/crash-sense.sh +173 -0
- package/bin/design-check.sh +80 -0
- package/bin/design-icon.sh +153 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +225 -0
- package/bin/eindri-acclaim.sh +47 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seat.sh +83 -0
- package/bin/eindri-seen.sh +54 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +98 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +158 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/feature-inventory.sh +73 -0
- package/bin/fleet-apply.sh +81 -0
- package/bin/github-deploy.sh +94 -0
- package/bin/gjallarhorn-expose.sh +136 -0
- package/bin/gjallarhorn-notify.sh +71 -0
- package/bin/gjallarhorn-purge.sh +67 -0
- package/bin/gjallarhorn-tunnel.sh +85 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +130 -0
- package/bin/hall-snapshot.sh +111 -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 +452 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hlidskjalf-agents.sh +172 -0
- package/bin/hlidskjalf-usage.sh +196 -0
- package/bin/hoard-guard.sh +135 -0
- package/bin/hoard-lib.sh +105 -0
- package/bin/hodd.sh +102 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +121 -0
- package/bin/local-model-lock.sh +70 -0
- package/bin/mimir-bridge.py +259 -0
- package/bin/mimir-bridge.sh +100 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir-reflect.sh +27 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +72 -0
- package/bin/mjollnir.sh +104 -0
- package/bin/model-hardware.sh +96 -0
- package/bin/model-resolve.sh +160 -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-hall-snapshot.sh +28 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-nsr-compliance.sh +54 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/npm-publish.sh +136 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +161 -0
- package/bin/omarchy-plugins.sh +187 -0
- package/bin/omarchy-sense.sh +162 -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-model-agnostic.sh +71 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +58 -0
- package/bin/project-git.sh +69 -0
- package/bin/public-guard.sh +71 -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 +104 -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 +94 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +89 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-spawn-pretool-check.sh +58 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +203 -0
- package/bin/telegram-bot.sh +82 -0
- package/bin/toolchain.sh +74 -0
- package/bin/ui-truth-check.sh +75 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +298 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +60 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +163 -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 +806 -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-plan.sh +356 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +110 -0
- package/bin/ymir-setup-auth.sh +119 -0
- package/bin/ymir-validate.sh +193 -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 +1060 -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 +54 -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 +269 -0
- package/scripts/lower.sh +34 -0
- package/scripts/raise.sh +42 -0
- package/scripts/start.sh +217 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-wake-drain-open-decisions.test.sh - behavior tests for the OPEN
|
|
3
|
+
# DECISIONS section bin/fm-wake-drain.sh prints on every drain (including the
|
|
4
|
+
# empty-queue fast path). The section is pure wiring around
|
|
5
|
+
# fm-classify-lib.sh's status_open_decisions fold (the ONE authoritative
|
|
6
|
+
# open/resolved statement); these tests exercise the real drain script over
|
|
7
|
+
# crafted status logs and assert on its printed output, not on the fold's own
|
|
8
|
+
# source text.
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
# shellcheck source=tests/wake-helpers.sh
|
|
12
|
+
. "$(dirname "${BASH_SOURCE[0]}")/wake-helpers.sh"
|
|
13
|
+
|
|
14
|
+
DRAIN="$ROOT/bin/fm-wake-drain.sh"
|
|
15
|
+
|
|
16
|
+
TMP_ROOT=$(fm_test_tmproot fm-wake-drain-open-decisions-tests)
|
|
17
|
+
|
|
18
|
+
test_buried_decision_still_surfaces() {
|
|
19
|
+
local dir state out
|
|
20
|
+
dir=$(make_case buried)
|
|
21
|
+
state="$dir/state"
|
|
22
|
+
out="$dir/drain.out"
|
|
23
|
+
# The needs-decision line sits under later routine and unrelated-key lines,
|
|
24
|
+
# exactly the burial scenario the fix targets: last-line-only reads would
|
|
25
|
+
# show "resolved [key=other]" and hide the still-open api-shape decision.
|
|
26
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$state/task1.status"
|
|
27
|
+
printf 'working: continuing other work\n' >> "$state/task1.status"
|
|
28
|
+
printf 'resolved [key=other]: unrelated decision closed\n' >> "$state/task1.status"
|
|
29
|
+
|
|
30
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed on a buried decision"
|
|
31
|
+
|
|
32
|
+
grep -F 'OPEN DECISIONS' "$out" >/dev/null || fail "buried decision produced no OPEN DECISIONS section"
|
|
33
|
+
grep -F 'task1' "$out" | grep -F '[key=api-shape]' | grep -F 'pick REST or RPC' >/dev/null \
|
|
34
|
+
|| fail "buried needs-decision was not surfaced with its task, key, and note"
|
|
35
|
+
grep -F "close one by answering it: bin/fm-send.sh <task> --resolve-key <key>" "$out" >/dev/null \
|
|
36
|
+
|| fail "open section is missing the answerer-closes hint"
|
|
37
|
+
pass "a needs-decision buried under later routine/other-key lines still reports as open"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
test_explicit_resolution_closes_it() {
|
|
41
|
+
local dir state out
|
|
42
|
+
dir=$(make_case resolved)
|
|
43
|
+
state="$dir/state"
|
|
44
|
+
out="$dir/drain.out"
|
|
45
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$state/task2.status"
|
|
46
|
+
printf 'resolved [key=api-shape]: went with REST\n' >> "$state/task2.status"
|
|
47
|
+
printf 'done: shipped\n' >> "$state/task2.status"
|
|
48
|
+
|
|
49
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed after an explicit resolution"
|
|
50
|
+
|
|
51
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
52
|
+
fail "an explicitly resolved decision still printed as open: $(cat "$out")"
|
|
53
|
+
fi
|
|
54
|
+
pass "an explicit resolved [key=X] closes the keyed decision"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
test_reserved_key_namespace_is_owned_by_its_library() {
|
|
58
|
+
local dir state out
|
|
59
|
+
dir=$(make_case reserved-key)
|
|
60
|
+
state="$dir/state"
|
|
61
|
+
out="$dir/drain.out"
|
|
62
|
+
# `pending-reply-<id>` names a decision bin/fm-pending-reply-lib.sh raises and
|
|
63
|
+
# is the only writer that closes it. Every writer reaches this same stream - a
|
|
64
|
+
# local mate appends into it directly, and a remote mate's lines are mirrored
|
|
65
|
+
# into it verbatim - so another writer must not be able to take that key over
|
|
66
|
+
# or clear it just by naming it.
|
|
67
|
+
printf 'blocked [key=pending-reply-abcdef0123456789]: pending-reply-missed: task=ios pending-reply-id=abcdef0123456789 request=ship it\n' > "$state/task9.status"
|
|
68
|
+
printf 'blocked [key=pending-reply-abcdef0123456789]: shipping is blocked on infra\n' >> "$state/task9.status"
|
|
69
|
+
printf 'resolved [key=pending-reply-abcdef0123456789]: all good now\n' >> "$state/task9.status"
|
|
70
|
+
|
|
71
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed on reserved-key lines"
|
|
72
|
+
|
|
73
|
+
grep -F 'pending-reply-id=abcdef0123456789' "$out" >/dev/null \
|
|
74
|
+
|| fail "a foreign resolution cleared a reserved decision it does not own: $(cat "$out")"
|
|
75
|
+
if grep -F 'shipping is blocked on infra' "$out" >/dev/null; then
|
|
76
|
+
fail "a foreign line took over a reserved decision key: $(cat "$out")"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# The owner's own resolution, which speaks that namespace's vocabulary, closes it.
|
|
80
|
+
printf 'resolved [key=pending-reply-abcdef0123456789]: pending-reply-resolved: task=ios pending-reply-id=abcdef0123456789 via=status\n' >> "$state/task9.status"
|
|
81
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed after the owner closed its decision"
|
|
82
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
83
|
+
fail "the owner's own resolution did not close its reserved decision: $(cat "$out")"
|
|
84
|
+
fi
|
|
85
|
+
pass "a reserved decision key can only be opened or closed by its owning library"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
test_later_unrelated_terminal_line_does_not_close_it() {
|
|
89
|
+
local dir state out
|
|
90
|
+
dir=$(make_case unrelated-terminal)
|
|
91
|
+
state="$dir/state"
|
|
92
|
+
out="$dir/drain.out"
|
|
93
|
+
# A later done: with no matching [key=...] token opens/closes only the
|
|
94
|
+
# "default" key; it must never clear the still-open api-shape decision.
|
|
95
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$state/task3.status"
|
|
96
|
+
printf 'done: unrelated later milestone\n' >> "$state/task3.status"
|
|
97
|
+
|
|
98
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed after an unrelated terminal line"
|
|
99
|
+
|
|
100
|
+
grep -F 'task3' "$out" | grep -F '[key=api-shape]' | grep -F 'pick REST or RPC' >/dev/null \
|
|
101
|
+
|| fail "a later unrelated terminal line incorrectly cleared the open decision"
|
|
102
|
+
pass "a later unrelated terminal line never clears an open decision"
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
test_no_open_decisions_prints_nothing() {
|
|
106
|
+
local dir state out
|
|
107
|
+
dir=$(make_case none-open)
|
|
108
|
+
state="$dir/state"
|
|
109
|
+
out="$dir/drain.out"
|
|
110
|
+
printf 'working: on it\n' > "$state/task4.status"
|
|
111
|
+
printf 'done: shipped clean\n' > "$state/task5.status"
|
|
112
|
+
|
|
113
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed with no open decisions"
|
|
114
|
+
|
|
115
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
116
|
+
fail "the empty case printed an OPEN DECISIONS section: $(cat "$out")"
|
|
117
|
+
fi
|
|
118
|
+
[ ! -s "$out" ] || fail "the empty case with no queued wakes was not silent: $(cat "$out")"
|
|
119
|
+
pass "no open decisions across the fleet prints nothing"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
test_open_decision_surfaces_even_with_an_unrelated_queued_wake() {
|
|
123
|
+
local dir state out
|
|
124
|
+
dir=$(make_case fleet-wide)
|
|
125
|
+
state="$dir/state"
|
|
126
|
+
out="$dir/drain.out"
|
|
127
|
+
# task6 has a buried, still-open decision but generates NO new queue record
|
|
128
|
+
# this turn; task7 is what actually wakes the drain. The fleet-wide scan
|
|
129
|
+
# must still catch task6's decision alongside task7's own raw row.
|
|
130
|
+
printf 'needs-decision [key=migration]: pick the rollout plan\n' > "$state/task6.status"
|
|
131
|
+
printf 'working: continuing\n' >> "$state/task6.status"
|
|
132
|
+
printf 'blocked: waiting on credentials\n' > "$state/task7.status"
|
|
133
|
+
append_wake "$state" signal task7.status "blocked: waiting on credentials" \
|
|
134
|
+
|| fail "queueing the unrelated wake failed"
|
|
135
|
+
|
|
136
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed with a mixed fleet"
|
|
137
|
+
|
|
138
|
+
grep "$(printf '\tsignal\ttask7.status\t')" "$out" >/dev/null || fail "task7's own raw row is missing"
|
|
139
|
+
grep -F 'task6' "$out" | grep -F '[key=migration]' >/dev/null \
|
|
140
|
+
|| fail "task6's buried decision was not surfaced even though only task7 queued a wake"
|
|
141
|
+
pass "the open-decision section is fleet-wide, not scoped to this drain's own queued records"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
test_buried_decision_surfaces_on_the_empty_queue_fast_path() {
|
|
145
|
+
local dir state out
|
|
146
|
+
dir=$(make_case empty-queue-fast-path)
|
|
147
|
+
state="$dir/state"
|
|
148
|
+
out="$dir/drain.out"
|
|
149
|
+
# No wake is queued at all (the empty-queue exit), but the decision is still
|
|
150
|
+
# open on disk - session-start relies on exactly this path.
|
|
151
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$state/task8.status"
|
|
152
|
+
printf 'working: continuing\n' >> "$state/task8.status"
|
|
153
|
+
|
|
154
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "empty-queue drain failed"
|
|
155
|
+
|
|
156
|
+
grep -F 'task8' "$out" | grep -F '[key=api-shape]' >/dev/null \
|
|
157
|
+
|| fail "the empty-queue fast path did not surface a still-open decision"
|
|
158
|
+
pass "a buried open decision surfaces even when the wake queue itself is empty"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
test_status_symlink_is_not_followed() {
|
|
162
|
+
local dir state out
|
|
163
|
+
dir=$(make_case status-symlink)
|
|
164
|
+
state="$dir/state"
|
|
165
|
+
out="$dir/drain.out"
|
|
166
|
+
mkdir -p "$dir/outside"
|
|
167
|
+
printf 'needs-decision [key=local]: keep this visible\n' > "$state/local.status"
|
|
168
|
+
printf 'needs-decision [key=foreign]: do not expose this\n' > "$dir/outside/foreign.status"
|
|
169
|
+
ln -s ../outside/foreign.status "$state/linked.status"
|
|
170
|
+
|
|
171
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed with a symlinked status file"
|
|
172
|
+
|
|
173
|
+
grep -F 'local [key=local] needs-decision: keep this visible' "$out" >/dev/null \
|
|
174
|
+
|| fail "the valid local decision did not surface alongside a rejected status symlink"
|
|
175
|
+
if grep -F 'do not expose this' "$out" >/dev/null; then
|
|
176
|
+
fail "the fleet scan followed a status symlink outside the state directory"
|
|
177
|
+
fi
|
|
178
|
+
pass "the fleet-wide decision scan does not follow status symlinks"
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
# The per-item cut now comes from bin/fm-line-cap-lib.sh, shared with the
|
|
182
|
+
# session-start digest's status tails so one truncation marker means the same
|
|
183
|
+
# thing wherever an agent meets it. This pins the drain's own end of that
|
|
184
|
+
# contract: the lede survives, the marker appears, and the item still fits the
|
|
185
|
+
# section's per-item budget including the newline it is charged for.
|
|
186
|
+
test_over_long_decision_note_is_capped_with_a_marker() {
|
|
187
|
+
local dir state out line longest
|
|
188
|
+
dir=$(make_case long-note)
|
|
189
|
+
state="$dir/state"
|
|
190
|
+
out="$dir/drain.out"
|
|
191
|
+
{
|
|
192
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC'
|
|
193
|
+
awk 'BEGIN { while (i++ < 200) printf " and-then-some" }'
|
|
194
|
+
printf '\n'
|
|
195
|
+
} > "$state/task-long.status"
|
|
196
|
+
|
|
197
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed on an over-long decision note"
|
|
198
|
+
|
|
199
|
+
line=$(grep -F 'task-long' "$out")
|
|
200
|
+
case "$line" in
|
|
201
|
+
'task-long [key=api-shape] needs-decision: pick REST or RPC'*' [truncated]') : ;;
|
|
202
|
+
*) fail "an over-long decision note was not capped with its lede intact: $line" ;;
|
|
203
|
+
esac
|
|
204
|
+
longest=${#line}
|
|
205
|
+
[ "$longest" -le 219 ] || fail "a capped decision item ran $longest characters past its per-item budget"
|
|
206
|
+
|
|
207
|
+
printf 'needs-decision [key=short]: brief enough to keep whole\n' > "$state/task-short.status"
|
|
208
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed on a short decision note"
|
|
209
|
+
grep -F 'task-short [key=short] needs-decision: brief enough to keep whole' "$out" >/dev/null \
|
|
210
|
+
|| fail "a decision note already under the cap was altered"
|
|
211
|
+
if grep -F 'brief enough to keep whole [truncated]' "$out" >/dev/null; then
|
|
212
|
+
fail "a decision note already under the cap was marked truncated"
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
pass "an over-long open decision is cut to its per-item budget with the shared truncation marker"
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
test_buried_decision_still_surfaces
|
|
219
|
+
test_over_long_decision_note_is_capped_with_a_marker
|
|
220
|
+
test_explicit_resolution_closes_it
|
|
221
|
+
test_later_unrelated_terminal_line_does_not_close_it
|
|
222
|
+
test_reserved_key_namespace_is_owned_by_its_library
|
|
223
|
+
test_no_open_decisions_prints_nothing
|
|
224
|
+
test_open_decision_surfaces_even_with_an_unrelated_queued_wake
|
|
225
|
+
test_buried_decision_surfaces_on_the_empty_queue_fast_path
|
|
226
|
+
test_status_symlink_is_not_followed
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-wake-drain-unread-status.test.sh - drain must surface every still-
|
|
3
|
+
# unread informational status line since the last presentation, not only the
|
|
4
|
+
# newest line. This is a portable tests/ regression: the drain decides WHICH
|
|
5
|
+
# status lines to surface, so the real drain/classify functions over crafted
|
|
6
|
+
# status logs are sufficient (no harness). The incident this pins: a `note:`
|
|
7
|
+
# answer immediately followed by a routine `note:` was buried because the
|
|
8
|
+
# annotation kept only the newest line and `note:` never folds into OPEN
|
|
9
|
+
# DECISIONS.
|
|
10
|
+
set -u
|
|
11
|
+
|
|
12
|
+
# shellcheck source=tests/wake-helpers.sh
|
|
13
|
+
. "$(dirname "${BASH_SOURCE[0]}")/wake-helpers.sh"
|
|
14
|
+
|
|
15
|
+
DRAIN="$ROOT/bin/fm-wake-drain.sh"
|
|
16
|
+
|
|
17
|
+
TMP_ROOT=$(fm_test_tmproot fm-wake-drain-unread-status-tests)
|
|
18
|
+
|
|
19
|
+
# Establish the durable last-presentation cursor by draining once over a
|
|
20
|
+
# bootstrap line so later appends are "new since last drain".
|
|
21
|
+
prime_cursor() { # <state> <status-file>
|
|
22
|
+
local state=$1 status=$2
|
|
23
|
+
printf 'note: bootstrap cursor line\n' > "$status"
|
|
24
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" >/dev/null 2>/dev/null \
|
|
25
|
+
|| fail "bootstrap drain failed while priming the unread cursor"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
test_incident_note_answer_buried_under_routine_note_surfaces_both() {
|
|
29
|
+
local dir state out status
|
|
30
|
+
dir=$(make_case incident-buried-note)
|
|
31
|
+
state="$dir/state"
|
|
32
|
+
out="$dir/drain.out"
|
|
33
|
+
status="$state/task1.status"
|
|
34
|
+
prime_cursor "$state" "$status"
|
|
35
|
+
|
|
36
|
+
printf 'note: captain said use REST not RPC\n' >> "$status"
|
|
37
|
+
printf 'note: re-read acknowledgement\n' >> "$status"
|
|
38
|
+
|
|
39
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed on the incident shape"
|
|
40
|
+
|
|
41
|
+
grep -F 'UNREAD STATUS' "$out" >/dev/null \
|
|
42
|
+
|| fail "the incident shape produced no UNREAD STATUS section: $(cat "$out")"
|
|
43
|
+
grep -F 'task1 note: captain said use REST not RPC' "$out" >/dev/null \
|
|
44
|
+
|| fail "the buried answer note was not surfaced: $(cat "$out")"
|
|
45
|
+
grep -F 'task1 note: re-read acknowledgement' "$out" >/dev/null \
|
|
46
|
+
|| fail "the newest routine note was dropped while surfacing the answer: $(cat "$out")"
|
|
47
|
+
pass "a note: answer buried under a later routine note: is surfaced with both lines"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
test_already_presented_notes_are_not_replayed() {
|
|
51
|
+
local dir state out status
|
|
52
|
+
dir=$(make_case no-replay)
|
|
53
|
+
state="$dir/state"
|
|
54
|
+
out="$dir/drain.out"
|
|
55
|
+
status="$state/task2.status"
|
|
56
|
+
prime_cursor "$state" "$status"
|
|
57
|
+
|
|
58
|
+
printf 'note: captain said use REST not RPC\n' >> "$status"
|
|
59
|
+
printf 'note: re-read acknowledgement\n' >> "$status"
|
|
60
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "first drain of unread notes failed"
|
|
61
|
+
grep -F 'captain said use REST not RPC' "$out" >/dev/null \
|
|
62
|
+
|| fail "setup error: first drain did not surface the answer note"
|
|
63
|
+
|
|
64
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "second drain after presentation failed"
|
|
65
|
+
if grep -F 'captain said use REST not RPC' "$out" >/dev/null; then
|
|
66
|
+
fail "an already-presented answer note was replayed as new: $(cat "$out")"
|
|
67
|
+
fi
|
|
68
|
+
if grep -F 're-read acknowledgement' "$out" >/dev/null; then
|
|
69
|
+
fail "an already-presented routine note was replayed as new: $(cat "$out")"
|
|
70
|
+
fi
|
|
71
|
+
if grep -F 'UNREAD STATUS' "$out" >/dev/null; then
|
|
72
|
+
fail "the second drain reprinted an UNREAD STATUS section with no new lines: $(cat "$out")"
|
|
73
|
+
fi
|
|
74
|
+
pass "already-presented note: lines are not re-surfaced on the next drain"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
test_brand_new_note_after_presentation_is_surfaced() {
|
|
78
|
+
local dir state out status
|
|
79
|
+
dir=$(make_case brand-new-note)
|
|
80
|
+
state="$dir/state"
|
|
81
|
+
out="$dir/drain.out"
|
|
82
|
+
status="$state/task3.status"
|
|
83
|
+
prime_cursor "$state" "$status"
|
|
84
|
+
|
|
85
|
+
printf 'note: first answer\n' >> "$status"
|
|
86
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain of the first note failed"
|
|
87
|
+
grep -F 'task3 note: first answer' "$out" >/dev/null \
|
|
88
|
+
|| fail "setup error: first note was not presented"
|
|
89
|
+
|
|
90
|
+
printf 'note: follow-up after ack\n' >> "$status"
|
|
91
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain of the brand-new note failed"
|
|
92
|
+
grep -F 'task3 note: follow-up after ack' "$out" >/dev/null \
|
|
93
|
+
|| fail "a brand-new note after presentation was not surfaced: $(cat "$out")"
|
|
94
|
+
if grep -F 'task3 note: first answer' "$out" >/dev/null; then
|
|
95
|
+
fail "the already-presented first note was replayed next to the new one: $(cat "$out")"
|
|
96
|
+
fi
|
|
97
|
+
pass "a brand-new note: after presentation is surfaced without replaying handled lines"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
test_signal_annotation_surfaces_every_unread_note_not_only_the_newest() {
|
|
101
|
+
local dir state out err status
|
|
102
|
+
dir=$(make_case signal-annotation)
|
|
103
|
+
state="$dir/state"
|
|
104
|
+
out="$dir/drain.out"
|
|
105
|
+
err="$dir/drain.err"
|
|
106
|
+
status="$state/task4.status"
|
|
107
|
+
prime_cursor "$state" "$status"
|
|
108
|
+
|
|
109
|
+
printf 'note: captain said use REST not RPC\n' >> "$status"
|
|
110
|
+
printf 'note: re-read acknowledgement\n' >> "$status"
|
|
111
|
+
append_wake "$state" signal task4.status "signal: task4.status" \
|
|
112
|
+
|| fail "queueing the incident-shape status signal failed"
|
|
113
|
+
|
|
114
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" 2> "$err" \
|
|
115
|
+
|| fail "signal drain failed on the incident shape"
|
|
116
|
+
|
|
117
|
+
grep -F 'unread wake-EVENT since last drain, not current state: task4.status: note: captain said use REST not RPC' "$out" >/dev/null \
|
|
118
|
+
|| fail "the signal annotation dropped the buried answer note: $(cat "$out")"
|
|
119
|
+
grep -F 'latest wake-EVENT observed at drain, not current state: task4.status: note: re-read acknowledgement' "$out" >/dev/null \
|
|
120
|
+
|| fail "the signal annotation dropped the newest routine note: $(cat "$out")"
|
|
121
|
+
grep "$(printf '\tsignal\ttask4.status\t')" "$out" >/dev/null \
|
|
122
|
+
|| fail "surfacing unread notes hid the authoritative raw wake row"
|
|
123
|
+
pass "a queued status signal annotates every unread note, not only the newest"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
test_pending_reply_resolution_surfaces_once() {
|
|
127
|
+
local dir state out status
|
|
128
|
+
dir=$(make_case pending-reply-resolution)
|
|
129
|
+
state="$dir/state"
|
|
130
|
+
out="$dir/drain.out"
|
|
131
|
+
status="$state/task5.status"
|
|
132
|
+
prime_cursor "$state" "$status"
|
|
133
|
+
|
|
134
|
+
printf 'blocked [key=pending-reply-abcdef0123456789]: pending-reply-missed: task=task5 pending-reply-id=abcdef0123456789 request=ship it\n' >> "$status"
|
|
135
|
+
append_wake "$state" signal task5.status "signal: task5.status" \
|
|
136
|
+
|| fail "queueing the pending-reply request signal failed"
|
|
137
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" >/dev/null \
|
|
138
|
+
|| fail "drain failed while acknowledging the pending-reply request"
|
|
139
|
+
{
|
|
140
|
+
printf 'resolved [key=pending-reply-abcdef0123456789]: pending-reply-resolved: task=task5 pending-reply-id=abcdef0123456789 via=status\n'
|
|
141
|
+
printf 'note: re-read acknowledgement\n'
|
|
142
|
+
} >> "$status"
|
|
143
|
+
|
|
144
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed on a pending-reply resolution"
|
|
145
|
+
|
|
146
|
+
grep -F 'pending-reply-resolved: task=task5 pending-reply-id=abcdef0123456789 via=status' "$out" >/dev/null \
|
|
147
|
+
|| fail "the pending-reply resolution was buried under the later note: $(cat "$out")"
|
|
148
|
+
grep -F 'task5 note: re-read acknowledgement' "$out" >/dev/null \
|
|
149
|
+
|| fail "the trailing note was not surfaced with the pending-reply resolution: $(cat "$out")"
|
|
150
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
151
|
+
fail "the pending-reply resolution did not close its open decision: $(cat "$out")"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "second drain after pending-reply presentation failed"
|
|
155
|
+
if grep -F 'pending-reply-resolved:' "$out" >/dev/null; then
|
|
156
|
+
fail "an already-presented pending-reply resolution was replayed: $(cat "$out")"
|
|
157
|
+
fi
|
|
158
|
+
pass "a pending-reply resolution buried under a later note surfaces once and closes OPEN DECISIONS"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
test_unread_output_over_cap_remains_recoverable() {
|
|
162
|
+
local dir state out status i payload
|
|
163
|
+
dir=$(make_case unread-over-cap)
|
|
164
|
+
state="$dir/state"
|
|
165
|
+
out="$dir/drain.out"
|
|
166
|
+
status="$state/task-cap.status"
|
|
167
|
+
prime_cursor "$state" "$status"
|
|
168
|
+
payload=$(printf '%0180d' 0)
|
|
169
|
+
i=1
|
|
170
|
+
while [ "$i" -le 30 ]; do
|
|
171
|
+
printf 'note: overflow-%02d %s\n' "$i" "$payload" >> "$status"
|
|
172
|
+
i=$((i + 1))
|
|
173
|
+
done
|
|
174
|
+
|
|
175
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed for unread output over the former cap"
|
|
176
|
+
grep -F 'task-cap note: overflow-01' "$out" >/dev/null \
|
|
177
|
+
|| fail "the first over-cap note was not surfaced"
|
|
178
|
+
grep -F 'task-cap note: overflow-30' "$out" >/dev/null \
|
|
179
|
+
|| fail "a later note vanished behind the unread byte cap: $(cat "$out")"
|
|
180
|
+
if grep -F 'more omitted' "$out" >/dev/null; then
|
|
181
|
+
fail "the unread section still omitted complete lines: $(cat "$out")"
|
|
182
|
+
fi
|
|
183
|
+
pass "unread status over the former byte cap preserves every line"
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
test_snapshot_does_not_ack_a_later_append() {
|
|
187
|
+
local dir state status first second
|
|
188
|
+
dir=$(make_case snapshot-append)
|
|
189
|
+
state="$dir/state"
|
|
190
|
+
status="$state/task-race.status"
|
|
191
|
+
prime_cursor "$state" "$status"
|
|
192
|
+
printf 'note: included in presentation snapshot\n' >> "$status"
|
|
193
|
+
|
|
194
|
+
FM_STATE_OVERRIDE="$state" bash -c '
|
|
195
|
+
set -u
|
|
196
|
+
. "$1/bin/fm-wake-lib.sh"
|
|
197
|
+
. "$1/bin/fm-classify-lib.sh"
|
|
198
|
+
snapshot=$(status_presentation_snapshot "$STATE")
|
|
199
|
+
scan_unread_surface_snapshot "$STATE" "$snapshot" > "$2"
|
|
200
|
+
printf "note: appended after presentation snapshot\n" >> "$STATE/task-race.status"
|
|
201
|
+
scan_open_decisions_snapshot "$STATE" "$snapshot" >/dev/null
|
|
202
|
+
status_commit_presentation_snapshot "$STATE" "$snapshot"
|
|
203
|
+
scan_unread_surface_lines "$STATE" > "$3"
|
|
204
|
+
' _ "$ROOT" "$dir/first" "$dir/second" || fail "snapshot race exercise failed"
|
|
205
|
+
first=$(cat "$dir/first")
|
|
206
|
+
second=$(cat "$dir/second")
|
|
207
|
+
case "$first" in *'included in presentation snapshot'*) ;; *) fail "snapshot omitted the line it captured: $first" ;; esac
|
|
208
|
+
case "$first" in *'appended after presentation snapshot'*) fail "snapshot read beyond its endpoint: $first" ;; esac
|
|
209
|
+
case "$second" in *'appended after presentation snapshot'*) ;; *) fail "fold advancement swallowed a post-snapshot append: $second" ;; esac
|
|
210
|
+
case "$second" in *'included in presentation snapshot'*) fail "the next scan replayed a presented line: $second" ;; esac
|
|
211
|
+
pass "presentation cursor advances only through its captured endpoint"
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
test_retired_task_id_starts_new_status_unread() {
|
|
215
|
+
local dir state out offset event old_ident
|
|
216
|
+
dir=$(make_case retired-task-reuse)
|
|
217
|
+
state="$dir/state"
|
|
218
|
+
out="$dir/drain.out"
|
|
219
|
+
printf 'note: old reused-task history\n' > "$state/reused.status"
|
|
220
|
+
printf 'note: stable neighboring history\n' > "$state/neighbor.status"
|
|
221
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" >/dev/null \
|
|
222
|
+
|| fail "drain failed while acknowledging pre-retirement histories"
|
|
223
|
+
|
|
224
|
+
FM_STATE_OVERRIDE="$state" bash -c '
|
|
225
|
+
. "$1/bin/fm-wake-lib.sh"
|
|
226
|
+
. "$1/bin/fm-classify-lib.sh"
|
|
227
|
+
_fm_open_decisions_file_ident "$STATE/reused.status" > "$2"
|
|
228
|
+
printf "40@$(cat "$2")" > "$(status_signal_seen_marker_path "$STATE" reused)"
|
|
229
|
+
printf "40@$(cat "$2")" > "$(status_heartbeat_seen_marker_path "$STATE" reused)"
|
|
230
|
+
printf "40@$(cat "$2")" > "$(status_daemon_seen_marker_path "$STATE" reused)"
|
|
231
|
+
status_retire_presentation_task "$STATE" reused || exit 1
|
|
232
|
+
for marker in \
|
|
233
|
+
"$(status_signal_seen_marker_path "$STATE" reused)" \
|
|
234
|
+
"$(status_heartbeat_seen_marker_path "$STATE" reused)" \
|
|
235
|
+
"$(status_daemon_seen_marker_path "$STATE" reused)"; do
|
|
236
|
+
[ ! -e "$marker" ] && [ ! -L "$marker" ] || exit 1
|
|
237
|
+
done
|
|
238
|
+
' _ "$ROOT" "$dir/old-ident" || fail "retiring the reused task presentation state failed"
|
|
239
|
+
printf 'blocked: release host unavailable\nworking: routine padding after the reused task started again\nnote: first event from reused task id\n' \
|
|
240
|
+
> "$state/reused.status"
|
|
241
|
+
old_ident=$(cat "$dir/old-ident")
|
|
242
|
+
printf '40@%s' "$old_ident" > "$state/.seen-reused_status"
|
|
243
|
+
offset=$(bash -c '
|
|
244
|
+
. "$1/bin/fm-wake-lib.sh"
|
|
245
|
+
. "$1/bin/fm-classify-lib.sh"
|
|
246
|
+
fm_wake_signal_seen_size "$2" "$2/reused.status"
|
|
247
|
+
' _ "$ROOT" "$state")
|
|
248
|
+
[ "$offset" = 0 ] || fail "a retired file identity restored a stale offset after task reuse"
|
|
249
|
+
event=$(bash -c '
|
|
250
|
+
. "$1/bin/fm-classify-lib.sh"
|
|
251
|
+
status_span_first_actionable "$2/reused.status" "$3"
|
|
252
|
+
' _ "$ROOT" "$state" "$offset")
|
|
253
|
+
[ "$event" = 'blocked: release host unavailable' ] \
|
|
254
|
+
|| fail "retired supervision offsets hid the replacement task blocker: $event"
|
|
255
|
+
|
|
256
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
257
|
+
|| fail "drain failed after reusing a retired task id"
|
|
258
|
+
grep -F 'reused note: first event from reused task id' "$out" >/dev/null \
|
|
259
|
+
|| fail "the retired manifest row skipped the new task prefix: $(cat "$out")"
|
|
260
|
+
if grep -F 'stable neighboring history' "$out" >/dev/null; then
|
|
261
|
+
fail "retiring one task replayed a neighboring task's handled history: $(cat "$out")"
|
|
262
|
+
fi
|
|
263
|
+
pass "a reused task id starts its replacement status log unread at byte zero"
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
test_weak_identity_still_presents_and_advances() {
|
|
267
|
+
local dir state out second reader
|
|
268
|
+
dir=$(make_case weak-identity); state="$dir/state"
|
|
269
|
+
out="$dir/first.out"; second="$dir/second.out"; reader="$dir/identity-reader"
|
|
270
|
+
printf '#!/usr/bin/env bash\nprintf "weak:7:8"\n' > "$reader"; chmod +x "$reader"
|
|
271
|
+
printf 'needs-decision [key=release]: choose target\nnote: release context attached\n' > "$state/weak.status"
|
|
272
|
+
FM_STATUS_IDENTITY_READER="$reader" FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
273
|
+
|| fail "drain failed with the platform-strength fallback identity"
|
|
274
|
+
grep -F 'weak [key=release] needs-decision: choose target' "$out" >/dev/null \
|
|
275
|
+
|| fail "weak identity omitted OPEN DECISIONS: $(cat "$out")"
|
|
276
|
+
grep -F 'weak note: release context attached' "$out" >/dev/null \
|
|
277
|
+
|| fail "weak identity omitted unread status: $(cat "$out")"
|
|
278
|
+
FM_STATUS_IDENTITY_READER="$reader" FM_STATE_OVERRIDE="$state" "$DRAIN" > "$second" \
|
|
279
|
+
|| fail "second drain failed with the platform-strength fallback identity"
|
|
280
|
+
grep -F 'release context attached' "$second" >/dev/null \
|
|
281
|
+
&& fail "weak identity did not advance the presented-status cursor"
|
|
282
|
+
pass "fallback identity still presents and advances status state"
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
test_snapshot_failure_is_visible() {
|
|
286
|
+
local dir state out reader
|
|
287
|
+
dir=$(make_case snapshot-failure); state="$dir/state"; out="$dir/drain.out"; reader="$dir/identity-reader"
|
|
288
|
+
printf '#!/usr/bin/env bash\nexit 1\n' > "$reader"; chmod +x "$reader"
|
|
289
|
+
printf 'needs-decision: choose target\n' > "$state/fail.status"
|
|
290
|
+
FM_STATUS_IDENTITY_READER="$reader" FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
291
|
+
|| fail "drain aborted instead of reporting its incomplete status surface"
|
|
292
|
+
grep -F 'STATUS PRESENTATION INCOMPLETE:' "$out" >/dev/null \
|
|
293
|
+
|| fail "snapshot failure produced a silently incomplete drain: $(cat "$out")"
|
|
294
|
+
pass "snapshot failures are reported visibly"
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
test_open_decisions_fold_is_unchanged() {
|
|
298
|
+
local dir state out
|
|
299
|
+
dir=$(make_case open-decisions-regression)
|
|
300
|
+
state="$dir/state"
|
|
301
|
+
out="$dir/drain.out"
|
|
302
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$state/task6.status"
|
|
303
|
+
printf 'working: continuing other work\n' >> "$state/task6.status"
|
|
304
|
+
printf 'note: re-read acknowledgement\n' >> "$state/task6.status"
|
|
305
|
+
|
|
306
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed on a buried needs-decision plus a note"
|
|
307
|
+
|
|
308
|
+
grep -F 'task6 [key=api-shape] needs-decision: pick REST or RPC' "$out" >/dev/null \
|
|
309
|
+
|| fail "OPEN DECISIONS no longer surfaces a buried needs-decision: $(cat "$out")"
|
|
310
|
+
grep -F 'task6 note: re-read acknowledgement' "$out" >/dev/null \
|
|
311
|
+
|| fail "the unread note was not surfaced alongside the still-open decision: $(cat "$out")"
|
|
312
|
+
grep -F "close one by answering it: bin/fm-send.sh <task> --resolve-key <key>" "$out" >/dev/null \
|
|
313
|
+
|| fail "OPEN DECISIONS lost its answerer-closes hint"
|
|
314
|
+
|
|
315
|
+
printf 'resolved [key=api-shape]: went with REST\n' >> "$state/task6.status"
|
|
316
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed after resolving the keyed decision"
|
|
317
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
318
|
+
fail "an explicitly resolved decision still printed as open: $(cat "$out")"
|
|
319
|
+
fi
|
|
320
|
+
if grep -F 'pick REST or RPC' "$out" >/dev/null; then
|
|
321
|
+
fail "a resolved decision leaked back through the unread surface: $(cat "$out")"
|
|
322
|
+
fi
|
|
323
|
+
pass "OPEN DECISIONS still folds needs-decision/blocked independently of unread notes"
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
test_empty_queue_does_not_swallow_later_signal_annotation() {
|
|
327
|
+
local dir state out status
|
|
328
|
+
dir=$(make_case delayed-signal-annotation)
|
|
329
|
+
state="$dir/state"
|
|
330
|
+
out="$dir/drain.out"
|
|
331
|
+
status="$state/task-delayed.status"
|
|
332
|
+
printf 'done: shipped before watcher published signal\n' > "$status"
|
|
333
|
+
|
|
334
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
335
|
+
|| fail "empty-queue drain failed before delayed signal publication"
|
|
336
|
+
[ ! -s "$out" ] || fail "routine status unexpectedly broke the silent empty-queue contract: $(cat "$out")"
|
|
337
|
+
|
|
338
|
+
append_wake "$state" signal task-delayed.status "signal: task-delayed.status" \
|
|
339
|
+
|| fail "publishing the delayed status signal failed"
|
|
340
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" \
|
|
341
|
+
|| fail "drain failed after delayed signal publication"
|
|
342
|
+
grep -F 'latest wake-EVENT observed at drain, not current state: task-delayed.status: done: shipped before watcher published signal' "$out" >/dev/null \
|
|
343
|
+
|| fail "the empty-queue drain acknowledged an event before its signal annotation: $(cat "$out")"
|
|
344
|
+
pass "an empty-queue drain preserves routine status for a later signal annotation"
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
test_routine_working_lines_stay_silent_on_the_empty_queue() {
|
|
348
|
+
local dir state out
|
|
349
|
+
dir=$(make_case silent-working)
|
|
350
|
+
state="$dir/state"
|
|
351
|
+
out="$dir/drain.out"
|
|
352
|
+
printf 'working: on it\n' > "$state/task7.status"
|
|
353
|
+
printf 'done: shipped clean\n' > "$state/task8.status"
|
|
354
|
+
|
|
355
|
+
FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed with only routine working/done lines"
|
|
356
|
+
|
|
357
|
+
if grep -F 'UNREAD STATUS' "$out" >/dev/null; then
|
|
358
|
+
fail "routine working/done lines printed an UNREAD STATUS section: $(cat "$out")"
|
|
359
|
+
fi
|
|
360
|
+
if grep -F 'OPEN DECISIONS' "$out" >/dev/null; then
|
|
361
|
+
fail "routine working/done lines printed OPEN DECISIONS: $(cat "$out")"
|
|
362
|
+
fi
|
|
363
|
+
[ ! -s "$out" ] || fail "the empty-queue routine case was not silent: $(cat "$out")"
|
|
364
|
+
pass "routine working/done lines still print nothing on an empty-queue drain"
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
test_incident_note_answer_buried_under_routine_note_surfaces_both
|
|
368
|
+
test_already_presented_notes_are_not_replayed
|
|
369
|
+
test_brand_new_note_after_presentation_is_surfaced
|
|
370
|
+
test_signal_annotation_surfaces_every_unread_note_not_only_the_newest
|
|
371
|
+
test_pending_reply_resolution_surfaces_once
|
|
372
|
+
test_unread_output_over_cap_remains_recoverable
|
|
373
|
+
test_snapshot_does_not_ack_a_later_append
|
|
374
|
+
test_retired_task_id_starts_new_status_unread
|
|
375
|
+
test_weak_identity_still_presents_and_advances
|
|
376
|
+
test_snapshot_failure_is_visible
|
|
377
|
+
test_open_decisions_fold_is_unchanged
|
|
378
|
+
test_empty_queue_does_not_swallow_later_signal_annotation
|
|
379
|
+
test_routine_working_lines_stay_silent_on_the_empty_queue
|