@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,520 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# End-to-end remote reply relay through fm-on and the process-event runner.
|
|
3
|
+
set -u
|
|
4
|
+
|
|
5
|
+
# shellcheck source=tests/lib.sh
|
|
6
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
7
|
+
|
|
8
|
+
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)
|
|
9
|
+
TMP_ROOT=$(fm_test_tmproot fm-remote-reply)
|
|
10
|
+
mkdir -p "$TMP_ROOT"
|
|
11
|
+
TMP_ROOT=$(cd "$TMP_ROOT" && pwd -P)
|
|
12
|
+
PARENT="$TMP_ROOT/parent"
|
|
13
|
+
REMOTE="$TMP_ROOT/remote"
|
|
14
|
+
FAKEBIN=$(fm_fakebin "$TMP_ROOT/fake")
|
|
15
|
+
CLAIMS="$TMP_ROOT/claims"
|
|
16
|
+
mkdir -p "$PARENT/data" "$PARENT/state" "$REMOTE/state" "$REMOTE/data/reply" "$CLAIMS"
|
|
17
|
+
# shellcheck source=bin/fm-remote-job-lib.sh
|
|
18
|
+
. "$ROOT/bin/fm-remote-job-lib.sh"
|
|
19
|
+
# The recorded worker pid is the serving child, not its restart supervisor, so
|
|
20
|
+
# stopping that pid alone leaves the supervisor to respawn - the leak
|
|
21
|
+
# tests/fm-remote-job-orphan-reap.test.sh pins. Stop the whole worker tree.
|
|
22
|
+
cleanup() {
|
|
23
|
+
local worker_pid=''
|
|
24
|
+
FM_HOME="$PARENT" FM_PROCEVENT_CLAIM_ROOT="$CLAIMS" \
|
|
25
|
+
"$ROOT/bin/fm-procevent.sh" sweep-home >/dev/null 2>&1 || true
|
|
26
|
+
if [ -f "$TMP_ROOT/remote-jobs/worker.pid" ]; then
|
|
27
|
+
worker_pid=$(cat "$TMP_ROOT/remote-jobs/worker.pid")
|
|
28
|
+
fm_remote_job_stop_worker_tree "$worker_pid" || true
|
|
29
|
+
fi
|
|
30
|
+
rm -rf -- "$TMP_ROOT"
|
|
31
|
+
}
|
|
32
|
+
trap cleanup EXIT
|
|
33
|
+
|
|
34
|
+
cat > "$PARENT/data/secondmates.md" <<EOF
|
|
35
|
+
- ios - iOS delivery (host: remote-mac; root: $ROOT; home: $REMOTE; scope: iOS work; projects: alpha; added 2026-08-02)
|
|
36
|
+
EOF
|
|
37
|
+
printf '# Detailed remote answer\n\nThe build is green.\n' > "$REMOTE/data/reply/report.md"
|
|
38
|
+
: > "$REMOTE/state/parent-replies.status"
|
|
39
|
+
SOURCE_BEFORE="$TMP_ROOT/source-before"
|
|
40
|
+
cp "$REMOTE/state/parent-replies.status" "$SOURCE_BEFORE"
|
|
41
|
+
|
|
42
|
+
cat > "$FAKEBIN/fake-ssh" <<'SH'
|
|
43
|
+
#!/usr/bin/env bash
|
|
44
|
+
while [ "$#" -gt 0 ]; do
|
|
45
|
+
case "$1" in
|
|
46
|
+
-o) shift 2 ;;
|
|
47
|
+
--) shift; break ;;
|
|
48
|
+
*) exit 90 ;;
|
|
49
|
+
esac
|
|
50
|
+
done
|
|
51
|
+
host=$1
|
|
52
|
+
entry=$2
|
|
53
|
+
shift 2
|
|
54
|
+
[ "$host" = remote-mac ] || exit 91
|
|
55
|
+
[ "$entry" = fm-remote-entrypoint.sh ] || exit 92
|
|
56
|
+
exec "$FM_FAKE_REMOTE_ENTRYPOINT" "$@"
|
|
57
|
+
SH
|
|
58
|
+
chmod +x "$FAKEBIN/fake-ssh"
|
|
59
|
+
|
|
60
|
+
remote_env() {
|
|
61
|
+
FM_HOME="$PARENT" \
|
|
62
|
+
FM_ROOT_OVERRIDE="$ROOT" \
|
|
63
|
+
FM_PROCEVENT_CLAIM_ROOT="$CLAIMS" \
|
|
64
|
+
FM_SSH_BIN="$FAKEBIN/fake-ssh" \
|
|
65
|
+
FM_FAKE_REMOTE_ENTRYPOINT="$ROOT/bin/fm-remote-entrypoint.sh" \
|
|
66
|
+
FM_REMOTE_JOB_PLATFORM_OVERRIDE=Linux \
|
|
67
|
+
FM_REMOTE_JOB_STATE_ROOT="$TMP_ROOT/remote-jobs" \
|
|
68
|
+
FM_REMOTE_REPLY_WAIT_SECONDS=10 \
|
|
69
|
+
"$@"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
wait_for() {
|
|
73
|
+
local path=$1
|
|
74
|
+
for _ in $(seq 1 100); do
|
|
75
|
+
[ -e "$path" ] && return 0
|
|
76
|
+
sleep 0.05
|
|
77
|
+
done
|
|
78
|
+
return 1
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
sha256_file() {
|
|
82
|
+
if command -v shasum >/dev/null 2>&1; then
|
|
83
|
+
shasum -a 256 "$1" | awk '{print $1}'
|
|
84
|
+
else
|
|
85
|
+
sha256sum "$1" | awk '{print $1}'
|
|
86
|
+
fi
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
ADAPTER="$ROOT/bin/fm-procevent-remote-reply.sh"
|
|
90
|
+
SID=$(remote_env "$ADAPTER" source-id ios)
|
|
91
|
+
out=$(remote_env "$ADAPTER" arm ios)
|
|
92
|
+
assert_contains "$out" "armed: $SID offset=0" "remote reply source was not armed at the empty cursor"
|
|
93
|
+
|
|
94
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" > "$TMP_ROOT/start-one.out" 2>&1 &
|
|
95
|
+
RUNNER=$!
|
|
96
|
+
wait_for "$CLAIMS/$SID.claim" || fail "process-event runner never claimed the remote reply source"
|
|
97
|
+
printf 'done [corr=0123456789abcdef]: build verified (data/reply/report.md)\n' \
|
|
98
|
+
>> "$REMOTE/state/parent-replies.status"
|
|
99
|
+
wait "$RUNNER" || fail "remote reply source failed to capture its first delta"
|
|
100
|
+
RESULT=$(find "$PARENT/state/procevent-inbox" -name "$SID.1.result" -print -quit 2>/dev/null)
|
|
101
|
+
if [ -z "$RESULT" ]; then
|
|
102
|
+
printf 'runner output:\n%s\n' "$(cat "$TMP_ROOT/start-one.out")" >&2
|
|
103
|
+
fail "the remote reply delta was not durably captured"
|
|
104
|
+
fi
|
|
105
|
+
assert_grep 'done [corr=0123456789abcdef]' "$RESULT" "captured delta lost the correlated status line"
|
|
106
|
+
# One remote note, one announcement: the adapter declares self-announcing, so a
|
|
107
|
+
# fully autohandled capture publishes NO check wake - the mirrored status bytes
|
|
108
|
+
# are the single announcement, observed here through the same signature-vs-seen
|
|
109
|
+
# gate the watcher's signal scan and the drain's annotation check consume.
|
|
110
|
+
if [ -e "$PARENT/state/.wake-queue" ] && grep -q "procevent remote-reply $SID 1" "$PARENT/state/.wake-queue"; then
|
|
111
|
+
fail "an autohandled remote-reply capture still published a duplicate check wake"
|
|
112
|
+
fi
|
|
113
|
+
FM_STATE_OVERRIDE="$PARENT/state" bash -c '
|
|
114
|
+
. "$1/bin/fm-wake-lib.sh"
|
|
115
|
+
fm_wake_signal_seen_current "$2/state" "$2/state/ios.status"
|
|
116
|
+
' _ "$ROOT" "$PARENT" && fail "the mirrored reply bytes are not visible to the watcher signal scan"
|
|
117
|
+
cmp -s "$SOURCE_BEFORE" "$REMOTE/state/parent-replies.status" \
|
|
118
|
+
&& fail "fixture did not append the expected source line"
|
|
119
|
+
SOURCE_AFTER="$TMP_ROOT/source-after"
|
|
120
|
+
cp "$REMOTE/state/parent-replies.status" "$SOURCE_AFTER"
|
|
121
|
+
pass "a blocking non-destructive remote delta reaches durable process-event capture"
|
|
122
|
+
|
|
123
|
+
# The runner applies a captured result through this adapter itself, so the reply
|
|
124
|
+
# is already mirrored, acknowledged, and the next source re-armed before any
|
|
125
|
+
# handler runs. That is the primary guarantee; assert it before exercising the
|
|
126
|
+
# handler's own path below.
|
|
127
|
+
assert_grep 'done [corr=0123456789abcdef]' "$PARENT/state/ios.status" \
|
|
128
|
+
"the captured reply was not applied to the parent status stream at capture"
|
|
129
|
+
assert_present "$PARENT/state/procevent-inbox/$SID.1.handled" \
|
|
130
|
+
"the applied capture was left unacknowledged"
|
|
131
|
+
assert_present "$PARENT/state/procevent/$SID.source" \
|
|
132
|
+
"applying the capture left the relay unarmed for the next delta"
|
|
133
|
+
pass "a captured delta is applied, acknowledged, and re-armed without a handler"
|
|
134
|
+
|
|
135
|
+
# Now the handler's own retry path, from the state a crash between applying and
|
|
136
|
+
# acknowledging leaves behind: the acknowledgement is gone and re-arming fails.
|
|
137
|
+
rm -f "$PARENT/state/procevent-inbox/$SID.1.handled"
|
|
138
|
+
rm -rf "$PARENT/state/procevent"
|
|
139
|
+
: > "$PARENT/state/procevent"
|
|
140
|
+
set +e
|
|
141
|
+
remote_env "$ADAPTER" handle ios 1 "$RESULT" > "$TMP_ROOT/handle-arm-fail.out" 2>&1
|
|
142
|
+
handle_arm_rc=$?
|
|
143
|
+
set -e
|
|
144
|
+
[ "$handle_arm_rc" -ne 0 ] || fail "reply handling acknowledged a result whose re-arm failed"
|
|
145
|
+
assert_grep 'done [corr=0123456789abcdef]' "$PARENT/state/ios.status" "failed re-arm lost the ingested reply"
|
|
146
|
+
assert_grep 'ingested: ios appended=0' "$TMP_ROOT/handle-arm-fail.out" "failed re-arm did not replay the committed reply"
|
|
147
|
+
rm -f "$PARENT/state/procevent"
|
|
148
|
+
mkdir "$PARENT/state/procevent"
|
|
149
|
+
reconcile_out=$(remote_env "$ROOT/bin/fm-procevent.sh" reconcile)
|
|
150
|
+
assert_contains "$reconcile_out" 'published=1' "failed re-arm did not leave the result eligible for retry"
|
|
151
|
+
out=$(remote_env "$ADAPTER" handle ios 1 "$RESULT")
|
|
152
|
+
assert_contains "$out" 'ingested: ios appended=0' "retried reply ingest was not idempotent"
|
|
153
|
+
assert_contains "$out" 'handled: remote-reply-ios 1' "captured generation was not acknowledged"
|
|
154
|
+
assert_grep 'done [corr=0123456789abcdef]' "$PARENT/state/ios.status" "parent status did not receive the correlated reply"
|
|
155
|
+
assert_grep 'data/remote-secondmates/ios/data/reply/report.md' "$PARENT/state/ios.status" "remote document pointer was not rewritten locally"
|
|
156
|
+
cmp -s "$REMOTE/data/reply/report.md" "$PARENT/data/remote-secondmates/ios/data/reply/report.md" \
|
|
157
|
+
|| fail "the path-confined remote document copy is not byte-identical"
|
|
158
|
+
cmp -s "$SOURCE_AFTER" "$REMOTE/state/parent-replies.status" \
|
|
159
|
+
|| fail "handling consumed or rewrote the remote append-only log"
|
|
160
|
+
expected_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
161
|
+
assert_grep "offset=$expected_offset" "$PARENT/state/remote-replies/ios.cursor" "reply cursor did not advance to the committed delta"
|
|
162
|
+
pass "ingest appends one validated line, fetches its document, and advances the cursor"
|
|
163
|
+
|
|
164
|
+
out=$(remote_env "$ADAPTER" handle ios 1 "$RESULT")
|
|
165
|
+
assert_contains "$out" 'ingested: ios appended=0' "replayed result was not deduplicated"
|
|
166
|
+
assert_contains "$out" 'already-handled: remote-reply-ios 1' "replayed generation was not acknowledged idempotently"
|
|
167
|
+
[ "$(grep -cF 'done [corr=0123456789abcdef]' "$PARENT/state/ios.status")" -eq 1 ] \
|
|
168
|
+
|| fail "replayed ingest duplicated the parent status line"
|
|
169
|
+
pass "replayed capture has one deduplicated append and one durable handling identity"
|
|
170
|
+
|
|
171
|
+
printf 'working [corr=1111111111111111]: second generation\n' \
|
|
172
|
+
>> "$REMOTE/state/parent-replies.status"
|
|
173
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null \
|
|
174
|
+
|| fail "second reply generation was not captured"
|
|
175
|
+
RESULT_TWO="$PARENT/state/procevent-inbox/$SID.2.result"
|
|
176
|
+
# The runner already applied and acknowledged this capture. Drop that genuine
|
|
177
|
+
# acknowledgement and put an unsafe one in its place, so the handler's refusal
|
|
178
|
+
# to trust a non-regular marker stays under test.
|
|
179
|
+
rm -f "$PARENT/state/procevent-inbox/$SID.2.handled"
|
|
180
|
+
ln -s "$TMP_ROOT/missing-handled-marker" "$PARENT/state/procevent-inbox/$SID.2.handled"
|
|
181
|
+
set +e
|
|
182
|
+
remote_env "$ADAPTER" handle ios 2 "$RESULT_TWO" > "$TMP_ROOT/handle-two-unacked.out" 2>&1
|
|
183
|
+
handle_two_rc=$?
|
|
184
|
+
set -e
|
|
185
|
+
[ "$handle_two_rc" -ne 0 ] || fail "second generation acknowledged through an unsafe handled marker"
|
|
186
|
+
assert_grep 'working [corr=1111111111111111]' "$PARENT/state/ios.status" "unacknowledged generation was not ingested"
|
|
187
|
+
printf 'done [corr=2222222222222222]: third generation\n' \
|
|
188
|
+
>> "$REMOTE/state/parent-replies.status"
|
|
189
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null \
|
|
190
|
+
|| fail "third reply generation was not captured"
|
|
191
|
+
RESULT_THREE="$PARENT/state/procevent-inbox/$SID.3.result"
|
|
192
|
+
remote_env "$ADAPTER" handle ios 3 "$RESULT_THREE" >/dev/null \
|
|
193
|
+
|| fail "third reply generation was not handled"
|
|
194
|
+
rm -f "$PARENT/state/procevent-inbox/$SID.2.handled"
|
|
195
|
+
out=$(remote_env "$ADAPTER" handle ios 2 "$RESULT_TWO")
|
|
196
|
+
assert_contains "$out" 'ingested: ios appended=0' "earlier generation did not replay from its durable ingestion receipt"
|
|
197
|
+
assert_contains "$out" 'handled: remote-reply-ios 2' "earlier generation remained unacknowledged after later cursor advancement"
|
|
198
|
+
[ "$(grep -cF 'working [corr=1111111111111111]' "$PARENT/state/ios.status")" -eq 1 ] \
|
|
199
|
+
|| fail "earlier generation replay duplicated its parent status"
|
|
200
|
+
pass "later generations cannot invalidate an unacknowledged ingested result"
|
|
201
|
+
|
|
202
|
+
# The channel mirrors the remote mate's content-bearing status lines at most once
|
|
203
|
+
# while omitting blank separators. A remote mate's own progress line and a NEWLY
|
|
204
|
+
# raised needs-decision carry no corr= by charter contract, and a delta carrying
|
|
205
|
+
# them alongside a correlated answer must ingest whole: every content-bearing
|
|
206
|
+
# line reaches the parent stream, the new decision reaches the parent's
|
|
207
|
+
# open-decision fold, the correlated line still settles its pending-reply record,
|
|
208
|
+
# and the cursor advances so the channel cannot wedge on a line it once refused.
|
|
209
|
+
# shellcheck source=bin/fm-pending-reply-lib.sh
|
|
210
|
+
. "$ROOT/bin/fm-pending-reply-lib.sh"
|
|
211
|
+
PENDING_CORR=$(fm_pending_reply_create "$PARENT" "$PARENT/state" ios 'audit the release chain')
|
|
212
|
+
[ -n "$PENDING_CORR" ] || fail "could not create the parent pending-reply record"
|
|
213
|
+
fm_pending_reply_mark_delivered "$PARENT/state" "$PENDING_CORR" \
|
|
214
|
+
|| fail "could not mark the pending-reply request delivered"
|
|
215
|
+
{
|
|
216
|
+
printf 'working [key=version-audit]: family --version audit complete (data/reply/report.md)\n'
|
|
217
|
+
printf 'needs-decision [key=rough-cut-version]: implement --version or retire the tool\n'
|
|
218
|
+
printf 'done [corr=%s]: release chain audited\n' "$PENDING_CORR"
|
|
219
|
+
} >> "$REMOTE/state/parent-replies.status"
|
|
220
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null \
|
|
221
|
+
|| fail "the mirrored status stream was not captured"
|
|
222
|
+
RESULT_FOUR="$PARENT/state/procevent-inbox/$SID.4.result"
|
|
223
|
+
remote_env "$ADAPTER" handle ios 4 "$RESULT_FOUR" > "$TMP_ROOT/handle-mirror.out" 2>&1 \
|
|
224
|
+
|| fail "an uncorrelated status line stopped the delta: $(cat "$TMP_ROOT/handle-mirror.out")"
|
|
225
|
+
assert_grep 'working [key=version-audit]' "$PARENT/state/ios.status" "an uncorrelated progress line never reached the parent stream"
|
|
226
|
+
assert_grep 'needs-decision [key=rough-cut-version]' "$PARENT/state/ios.status" "a newly raised remote decision never reached the parent stream"
|
|
227
|
+
assert_grep "done [corr=$PENDING_CORR]" "$PARENT/state/ios.status" "the correlated answer sharing the delta was lost"
|
|
228
|
+
mirror_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
229
|
+
assert_grep "offset=$mirror_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
230
|
+
"the cursor did not advance past an uncorrelated line"
|
|
231
|
+
pass "the remote status and decision model mirrors and the cursor advances"
|
|
232
|
+
|
|
233
|
+
# The newly raised decision must be indistinguishable from a local mate's, so the
|
|
234
|
+
# shared fold - not this adapter - decides it is open.
|
|
235
|
+
# shellcheck source=bin/fm-classify-lib.sh
|
|
236
|
+
. "$ROOT/bin/fm-classify-lib.sh"
|
|
237
|
+
OPEN=$(status_open_decisions "$PARENT/state/ios.status")
|
|
238
|
+
printf '%s' "$OPEN" | grep -q '^rough-cut-version needs-decision ' \
|
|
239
|
+
|| fail "the remote mate's new decision did not surface as open to the parent: $OPEN"
|
|
240
|
+
[ "$(fm_pending_reply_get "$PARENT/state/pending-replies/$PENDING_CORR" phase)" = resolved ] \
|
|
241
|
+
|| fail "the correlated answer in the same delta did not settle its pending-reply record"
|
|
242
|
+
pass "a remote mate's new decision folds open exactly as a local mate's does"
|
|
243
|
+
|
|
244
|
+
# Ingesting the same generation again is idempotent: no duplicated lines and no
|
|
245
|
+
# cursor movement, so a replay can never wedge or double-count the stream.
|
|
246
|
+
remote_env "$ADAPTER" handle ios 4 "$RESULT_FOUR" >/dev/null 2>&1 || true
|
|
247
|
+
[ "$(grep -cF 'needs-decision [key=rough-cut-version]' "$PARENT/state/ios.status")" -eq 1 ] \
|
|
248
|
+
|| fail "replaying the mirrored delta duplicated the new decision"
|
|
249
|
+
assert_grep "offset=$mirror_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
250
|
+
"replaying the mirrored delta moved the cursor"
|
|
251
|
+
pass "a replayed mirrored delta is idempotent in both the stream and the cursor"
|
|
252
|
+
|
|
253
|
+
# Bytes crossing a machine boundary are normalized, never dropped: a control
|
|
254
|
+
# character cannot make the parent's status file unsafe and cannot stop the
|
|
255
|
+
# stream either.
|
|
256
|
+
printf 'blocked [key=ctl]: escape \033[31mhere\033[0m bell \007 caf\xc3\xa9 end\n' \
|
|
257
|
+
>> "$REMOTE/state/parent-replies.status"
|
|
258
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null \
|
|
259
|
+
|| fail "the control-character line was not captured"
|
|
260
|
+
RESULT_FIVE="$PARENT/state/procevent-inbox/$SID.5.result"
|
|
261
|
+
remote_env "$ADAPTER" handle ios 5 "$RESULT_FIVE" >/dev/null 2>&1 \
|
|
262
|
+
|| fail "a control character stopped the stream"
|
|
263
|
+
assert_grep 'blocked [key=ctl]: escape ?[31mhere' "$PARENT/state/ios.status" \
|
|
264
|
+
"the control-character line was not mirrored in normalized form"
|
|
265
|
+
[ -z "$(LC_ALL=C tr -d '\11\12\40-\176\200-\377' < "$PARENT/state/ios.status")" ] \
|
|
266
|
+
|| fail "a control byte reached the parent status file"
|
|
267
|
+
assert_grep "$(printf 'caf\xc3\xa9 end')" "$PARENT/state/ios.status" \
|
|
268
|
+
"normalization mangled a UTF-8 note a local secondmate could have written"
|
|
269
|
+
ctl_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
270
|
+
assert_grep "offset=$ctl_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
271
|
+
"the cursor did not advance past a control-character line"
|
|
272
|
+
pass "transported control bytes are normalized in place and never stop the stream"
|
|
273
|
+
|
|
274
|
+
printf 'status=delta\n' >> "$REMOTE/state/parent-replies.status"
|
|
275
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null \
|
|
276
|
+
|| fail "the header-collision line was not captured"
|
|
277
|
+
RESULT_SIX="$PARENT/state/procevent-inbox/$SID.6.result"
|
|
278
|
+
remote_env "$ADAPTER" handle ios 6 "$RESULT_SIX" >/dev/null 2>&1 \
|
|
279
|
+
|| fail "a payload protocol-field name stopped the stream"
|
|
280
|
+
assert_grep 'status=delta' "$PARENT/state/ios.status" \
|
|
281
|
+
"the payload protocol-field line did not reach the parent stream"
|
|
282
|
+
collision_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
283
|
+
assert_grep "offset=$collision_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
284
|
+
"the cursor did not advance past a payload protocol-field line"
|
|
285
|
+
pass "payload protocol-field names cannot collide with transport metadata"
|
|
286
|
+
|
|
287
|
+
printf 'working [key=nul-byte]: before\000after\n' >> "$REMOTE/state/parent-replies.status"
|
|
288
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null \
|
|
289
|
+
|| fail "the NUL-bearing line was not captured"
|
|
290
|
+
RESULT_SEVEN="$PARENT/state/procevent-inbox/$SID.7.result"
|
|
291
|
+
remote_env "$ADAPTER" handle ios 7 "$RESULT_SEVEN" >/dev/null 2>&1 \
|
|
292
|
+
|| fail "a NUL byte stopped the stream"
|
|
293
|
+
assert_grep 'working [key=nul-byte]: before?after' "$PARENT/state/ios.status" \
|
|
294
|
+
"the NUL byte was not normalized in place"
|
|
295
|
+
nul_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
296
|
+
assert_grep "offset=$nul_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
297
|
+
"the cursor did not advance past a NUL-bearing line"
|
|
298
|
+
pass "NUL bytes are normalized in place before shell line processing"
|
|
299
|
+
|
|
300
|
+
printf '# Retryable remote answer\n' > "$REMOTE/data/reply/retry.md"
|
|
301
|
+
printf 'done [key=retry-document]: retry local storage (data/reply/retry.md)\n' \
|
|
302
|
+
>> "$REMOTE/state/parent-replies.status"
|
|
303
|
+
# Obstruct local document storage BEFORE the capture, so the runner's own
|
|
304
|
+
# automatic application fails for real. That is the documented fallback: a
|
|
305
|
+
# capture whose application does not complete stays unacknowledged and
|
|
306
|
+
# uncommitted, and the handler finishes it once storage recovers.
|
|
307
|
+
retry_destination="$PARENT/data/remote-secondmates/ios/data/reply/retry.md"
|
|
308
|
+
retry_decoy="$TMP_ROOT/retry-decoy.md"
|
|
309
|
+
printf 'local decoy\n' > "$retry_decoy"
|
|
310
|
+
ln -s "$retry_decoy" "$retry_destination"
|
|
311
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null 2>&1 \
|
|
312
|
+
|| fail "the retryable document line was not captured"
|
|
313
|
+
RESULT_EIGHT="$PARENT/state/procevent-inbox/$SID.8.result"
|
|
314
|
+
assert_absent "$PARENT/state/procevent-inbox/$SID.8.handled" \
|
|
315
|
+
"a capture whose automatic application failed was acknowledged anyway"
|
|
316
|
+
# The self-announcing declaration never silences a capture the adapter could
|
|
317
|
+
# NOT fully apply: this one must still publish its check wake for the handler.
|
|
318
|
+
assert_grep "procevent remote-reply $SID 8" "$PARENT/state/.wake-queue" \
|
|
319
|
+
"a not-fully-applied capture lost its check-wake announcement"
|
|
320
|
+
assert_no_grep 'retry local storage' "$PARENT/state/.wake-queue" \
|
|
321
|
+
"reply payload leaked into the event queue"
|
|
322
|
+
retry_cursor_before=$(cat "$PARENT/state/remote-replies/ios.cursor")
|
|
323
|
+
set +e
|
|
324
|
+
remote_env "$ADAPTER" handle ios 8 "$RESULT_EIGHT" > "$TMP_ROOT/handle-local-document-failure.out" 2>&1
|
|
325
|
+
local_document_rc=$?
|
|
326
|
+
set -e
|
|
327
|
+
[ "$local_document_rc" -ne 0 ] || fail "local document storage failure committed the delta"
|
|
328
|
+
assert_grep 'could not store referenced remote document' "$TMP_ROOT/handle-local-document-failure.out" \
|
|
329
|
+
"local document storage failure was misclassified as remote refusal"
|
|
330
|
+
[ "$(cat "$PARENT/state/remote-replies/ios.cursor")" = "$retry_cursor_before" ] \
|
|
331
|
+
|| fail "local document storage failure advanced the cursor"
|
|
332
|
+
assert_no_grep 'done [key=retry-document]' "$PARENT/state/ios.status" \
|
|
333
|
+
"local document storage failure mirrored an undelivered line"
|
|
334
|
+
assert_no_grep 'blocked [key=remote-reply-document-ios]' "$PARENT/state/ios.status" \
|
|
335
|
+
"local document storage failure raised a permanent remote refusal"
|
|
336
|
+
rm -f "$retry_destination"
|
|
337
|
+
remote_env "$ADAPTER" handle ios 8 "$RESULT_EIGHT" >/dev/null \
|
|
338
|
+
|| fail "the document delta did not succeed after local storage recovered"
|
|
339
|
+
assert_grep 'data/remote-secondmates/ios/data/reply/retry.md' "$PARENT/state/ios.status" \
|
|
340
|
+
"the retried document pointer was not rewritten locally"
|
|
341
|
+
cmp -s "$REMOTE/data/reply/retry.md" "$retry_destination" \
|
|
342
|
+
|| fail "the retried remote document was not copied byte-identically"
|
|
343
|
+
retry_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
344
|
+
assert_grep "offset=$retry_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
345
|
+
"the recovered document delta did not advance the cursor"
|
|
346
|
+
pass "local document storage failures remain retryable until delivery succeeds"
|
|
347
|
+
|
|
348
|
+
# A remote mate cannot squat the decision keys this parent's pending-reply
|
|
349
|
+
# library owns. The guard is deliberately NOT in this adapter: rejecting a line
|
|
350
|
+
# here would be batch-fatal and could wedge the whole stream, and it would
|
|
351
|
+
# protect only the remote path while a local mate appends into the same stream
|
|
352
|
+
# unchecked. So the line mirrors like any other - the stream never stops - and
|
|
353
|
+
# the shared open-decision fold both writers flow through refuses to let it take
|
|
354
|
+
# the reserved key over.
|
|
355
|
+
# The record stores its own grace at creation, so set it before creating one.
|
|
356
|
+
export FM_PENDING_REPLY_GRACE_SECS=0
|
|
357
|
+
ESCALATED_CORR=$(fm_pending_reply_create "$PARENT" "$PARENT/state" ios 'confirm the notarization')
|
|
358
|
+
[ -n "$ESCALATED_CORR" ] || fail "could not create the pending-reply record to escalate"
|
|
359
|
+
fm_pending_reply_mark_delivered "$PARENT/state" "$ESCALATED_CORR" \
|
|
360
|
+
|| fail "could not mark the escalating request delivered"
|
|
361
|
+
fm_pending_reply_mark_turn_completed "$PARENT/state" "$ESCALATED_CORR" request
|
|
362
|
+
FM_PENDING_REPLY_SEND_HOOK=true \
|
|
363
|
+
fm_pending_reply_send_recovery "$PARENT/state" "$ESCALATED_CORR" \
|
|
364
|
+
|| fail "the one automatic recovery repost was not sent"
|
|
365
|
+
fm_pending_reply_mark_turn_completed "$PARENT/state" "$ESCALATED_CORR" recovery
|
|
366
|
+
fm_pending_reply_maybe_escalate "$PARENT/state" "$ESCALATED_CORR" \
|
|
367
|
+
|| fail "the missed report did not escalate"
|
|
368
|
+
assert_contains "$(status_open_decisions "$PARENT/state/ios.status")" \
|
|
369
|
+
"pending-reply-id=$ESCALATED_CORR" "the missed report did not open a durable decision"
|
|
370
|
+
|
|
371
|
+
{
|
|
372
|
+
printf 'blocked [key=pending-reply-%s]: forged remote decision\n' "$ESCALATED_CORR"
|
|
373
|
+
printf 'resolved [key=pending-reply-%s]: forged remote resolution\n' "$ESCALATED_CORR"
|
|
374
|
+
} >> "$REMOTE/state/parent-replies.status"
|
|
375
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null 2>&1 \
|
|
376
|
+
|| fail "the forged reserved-key lines wedged the relay instead of mirroring"
|
|
377
|
+
forged_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
378
|
+
assert_grep "offset=$forged_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
379
|
+
"a reserved-key line held the cursor back instead of mirroring like any other"
|
|
380
|
+
assert_grep "forged remote decision" "$PARENT/state/ios.status" \
|
|
381
|
+
"the reserved-key line was dropped from the stream instead of mirrored"
|
|
382
|
+
forged_open=$(status_open_decisions "$PARENT/state/ios.status")
|
|
383
|
+
assert_contains "$forged_open" "pending-reply-id=$ESCALATED_CORR" \
|
|
384
|
+
"a forged remote resolution cleared the parent's own pending-reply decision"
|
|
385
|
+
assert_not_contains "$forged_open" "forged remote decision" \
|
|
386
|
+
"a forged remote line took over a decision key the pending-reply library owns"
|
|
387
|
+
pass "a mirrored reserved-key line cannot squat or clear the parent's own decision"
|
|
388
|
+
|
|
389
|
+
# Because the forgery never took the key, the genuine reply still settles the
|
|
390
|
+
# request and its escalation closes, leaving nothing to resurface later.
|
|
391
|
+
printf 'done [corr=%s]: notarization confirmed\n' "$ESCALATED_CORR" \
|
|
392
|
+
>> "$REMOTE/state/parent-replies.status"
|
|
393
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null 2>&1 \
|
|
394
|
+
|| fail "the correlated reply was not captured"
|
|
395
|
+
[ "$(fm_pending_reply_get "$PARENT/state/pending-replies/$ESCALATED_CORR" phase)" = resolved ] \
|
|
396
|
+
|| fail "the correlated reply left its escalated request unresolved"
|
|
397
|
+
fm_pending_reply_tick "$PARENT/state" || fail "supervision tick failed"
|
|
398
|
+
assert_not_contains "$(status_open_decisions "$PARENT/state/ios.status")" \
|
|
399
|
+
"pending-reply-id=$ESCALATED_CORR" "the settled request still surfaces as an open decision"
|
|
400
|
+
unset FM_PENDING_REPLY_GRACE_SECS
|
|
401
|
+
pass "a reply that arrives after escalation resolves it and clears the open decision"
|
|
402
|
+
|
|
403
|
+
rm -f -- "$PARENT/state/remote-replies/ios.caught-up"
|
|
404
|
+
remote_env "$ADAPTER" source ios > "$TMP_ROOT/preempted-source.out" 2>&1 &
|
|
405
|
+
PREEMPTED_SOURCE=$!
|
|
406
|
+
running_poll=''
|
|
407
|
+
for _ in $(seq 1 100); do
|
|
408
|
+
for job in "$TMP_ROOT"/remote-jobs/jobs/job-*; do
|
|
409
|
+
[ -d "$job" ] || continue
|
|
410
|
+
if [ "$(fm_remote_job_read_state "$job" 2>/dev/null || true)" = running ]; then
|
|
411
|
+
running_poll=$job
|
|
412
|
+
break 2
|
|
413
|
+
fi
|
|
414
|
+
done
|
|
415
|
+
sleep 0.05
|
|
416
|
+
done
|
|
417
|
+
[ -n "$running_poll" ] || fail "the reply poll did not begin running before preemption"
|
|
418
|
+
remote_env "$ROOT/bin/fm-on.sh" ios fm-remote-file.sh get data/reply/report.md 262144 >/dev/null
|
|
419
|
+
set +e
|
|
420
|
+
wait "$PREEMPTED_SOURCE"
|
|
421
|
+
preempted_rc=$?
|
|
422
|
+
set -e
|
|
423
|
+
[ "$preempted_rc" -eq "$FM_REMOTE_JOB_PREEMPTED_EXIT" ] \
|
|
424
|
+
|| fail "the reply poll did not expose remote-job preemption: $preempted_rc"
|
|
425
|
+
assert_absent "$PARENT/state/remote-replies/ios.caught-up" \
|
|
426
|
+
"a preempted reply poll published a caught-up watermark"
|
|
427
|
+
pass "a preempted reply poll cannot publish channel freshness"
|
|
428
|
+
|
|
429
|
+
# A quiet window is the one moment this channel can prove it is NOT behind, and
|
|
430
|
+
# the parent's pending-reply guard needs that proof: a remote report that exists
|
|
431
|
+
# but has not been mirrored yet must never be mistaken for a report the mate
|
|
432
|
+
# never wrote. The window opened with the log matching the committed cursor, so
|
|
433
|
+
# the published watermark is the window's start.
|
|
434
|
+
watermark_before=$(date +%s)
|
|
435
|
+
set +e
|
|
436
|
+
FM_REMOTE_REPLY_WAIT_SECONDS=1 remote_env "$ADAPTER" source ios >/dev/null 2>&1
|
|
437
|
+
quiet_rc=$?
|
|
438
|
+
set -e
|
|
439
|
+
[ "$quiet_rc" -eq 75 ] || fail "a quiet reply window exited with an unexpected status: $quiet_rc"
|
|
440
|
+
watermark_after=$(date +%s)
|
|
441
|
+
caught_up=$(FM_STATE_OVERRIDE="$PARENT/state" bash -c '
|
|
442
|
+
. "$1/bin/fm-pending-reply-lib.sh"
|
|
443
|
+
fm_pending_reply_remote_channel_epoch "$2/state" ios
|
|
444
|
+
' _ "$ROOT" "$PARENT")
|
|
445
|
+
[ -n "$caught_up" ] || fail "a quiet reply window published no caught-up watermark"
|
|
446
|
+
[ "$caught_up" -ge "$watermark_before" ] && [ "$caught_up" -le "$watermark_after" ] \
|
|
447
|
+
|| fail "the caught-up watermark ($caught_up) is outside the quiet window"
|
|
448
|
+
pass "a quiet reply window publishes the caught-up watermark the reply guard reads"
|
|
449
|
+
|
|
450
|
+
# The observed already-handled replay class: a lost cursor (an update or
|
|
451
|
+
# convergence retire) makes the next armed source recapture the WHOLE remote
|
|
452
|
+
# log from offset 0. Every line is already mirrored, so the at-most-once
|
|
453
|
+
# append adds no bytes, the adapter acknowledges the generation, and the
|
|
454
|
+
# self-announcing runner publishes nothing - the replay stays completely
|
|
455
|
+
# quiet, observed through the same seen-signature gate the watcher consumes.
|
|
456
|
+
FM_STATE_OVERRIDE="$PARENT/state" bash -c '
|
|
457
|
+
. "$1/bin/fm-wake-lib.sh"
|
|
458
|
+
fm_wake_status_mark_current "$2/state" "$2/state/ios.status"
|
|
459
|
+
' _ "$ROOT" "$PARENT" || fail "could not prime the seen marker for the replay leg"
|
|
460
|
+
cp "$PARENT/state/ios.status" "$TMP_ROOT/ios-status-before-replay"
|
|
461
|
+
mv "$PARENT/state/.wake-queue" "$TMP_ROOT/wake-queue-before-replay" 2>/dev/null || true
|
|
462
|
+
rm -f "$PARENT/state/remote-replies/ios.cursor"
|
|
463
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" >/dev/null 2>&1 \
|
|
464
|
+
|| fail "the cursor-loss recapture was not captured"
|
|
465
|
+
assert_present "$PARENT/state/procevent-inbox/$SID.11.handled" \
|
|
466
|
+
"the whole-log recapture was not acknowledged by the adapter"
|
|
467
|
+
cmp -s "$TMP_ROOT/ios-status-before-replay" "$PARENT/state/ios.status" \
|
|
468
|
+
|| fail "the whole-log recapture duplicated already-mirrored lines"
|
|
469
|
+
if [ -e "$PARENT/state/.wake-queue" ] && grep -q "procevent remote-reply $SID 11" "$PARENT/state/.wake-queue"; then
|
|
470
|
+
fail "an already-mirrored recapture still published a check wake"
|
|
471
|
+
fi
|
|
472
|
+
FM_STATE_OVERRIDE="$PARENT/state" bash -c '
|
|
473
|
+
. "$1/bin/fm-wake-lib.sh"
|
|
474
|
+
fm_wake_signal_seen_current "$2/state" "$2/state/ios.status"
|
|
475
|
+
' _ "$ROOT" "$PARENT" || fail "a byte-identical recapture left unannounced status bytes behind"
|
|
476
|
+
replay_offset=$(LC_ALL=C wc -c < "$REMOTE/state/parent-replies.status" | tr -d ' ')
|
|
477
|
+
assert_grep "offset=$replay_offset" "$PARENT/state/remote-replies/ios.cursor" \
|
|
478
|
+
"the recapture did not rebuild the lost cursor"
|
|
479
|
+
pass "a cursor-loss whole-log recapture is acknowledged quietly with no duplicate wake"
|
|
480
|
+
|
|
481
|
+
# The adapter re-armed at the committed cursor. Truncation is detected from the
|
|
482
|
+
# next blocking source and escalated once; it is never silently treated as a new
|
|
483
|
+
# log or re-armed past the break.
|
|
484
|
+
printf 'failed [corr=fedcba9876543210]: source was replaced\n' > "$REMOTE/state/parent-replies.status"
|
|
485
|
+
remote_env "$ROOT/bin/fm-procevent.sh" start "$SID" > "$TMP_ROOT/start-two.out" 2>&1 &
|
|
486
|
+
RUNNER=$!
|
|
487
|
+
wait "$RUNNER" || fail "continuity break was not captured as a structured result"
|
|
488
|
+
RESULT_TWELVE=$(find "$PARENT/state/procevent-inbox" -name "$SID.12.result" -print -quit)
|
|
489
|
+
[ -n "$RESULT_TWELVE" ] || fail "continuity break produced no durable result"
|
|
490
|
+
[ "$(remote_env "$ADAPTER" classify "$RESULT_TWELVE")" = continuity-broken ] \
|
|
491
|
+
|| fail "truncated source was not classified as a continuity break"
|
|
492
|
+
set +e
|
|
493
|
+
remote_env "$ADAPTER" handle ios 12 "$RESULT_TWELVE" > "$TMP_ROOT/handle-nine.out" 2>&1
|
|
494
|
+
handle_rc=$?
|
|
495
|
+
set -e
|
|
496
|
+
[ "$handle_rc" -eq 3 ] || fail "continuity handling returned an unexpected status: $handle_rc"
|
|
497
|
+
assert_grep 'blocked [key=remote-reply-continuity-ios]' "$PARENT/state/ios.status" "continuity break did not escalate"
|
|
498
|
+
assert_absent "$PARENT/state/procevent/$SID.source" "continuity break was re-armed without an operator rebase"
|
|
499
|
+
remote_env "$ADAPTER" ingest ios "$RESULT_TWELVE" >/dev/null 2>&1 || true
|
|
500
|
+
[ "$(grep -cF 'blocked [key=remote-reply-continuity-ios]' "$PARENT/state/ios.status")" -eq 1 ] \
|
|
501
|
+
|| fail "continuity replay duplicated the escalation"
|
|
502
|
+
pass "truncation is detected, escalated once, and not silently rebased"
|
|
503
|
+
|
|
504
|
+
rm -f "$PARENT/state/procevent-inbox/$SID.12.handled"
|
|
505
|
+
if remote_env "$ADAPTER" retire ios > "$TMP_ROOT/retire-pending.out" 2>&1; then
|
|
506
|
+
fail "remote reply retirement accepted an unhandled captured result"
|
|
507
|
+
fi
|
|
508
|
+
assert_grep 'unhandled captured result' "$TMP_ROOT/retire-pending.out" \
|
|
509
|
+
"remote reply retirement did not explain its pending-result refusal"
|
|
510
|
+
assert_absent "$PARENT/state/procevent/$SID.source" \
|
|
511
|
+
"refused retirement left the reply source running past its pending-result check"
|
|
512
|
+
remote_env "$ADAPTER" handle ios 12 "$RESULT_TWELVE" >/dev/null 2>&1 || [ "$?" -eq 3 ] \
|
|
513
|
+
|| fail "pending continuity result could not be acknowledged after retirement refusal"
|
|
514
|
+
remote_env "$ADAPTER" retire ios >/dev/null
|
|
515
|
+
assert_absent "$PARENT/state/remote-replies/ios.cursor" "adapter retirement left its cursor"
|
|
516
|
+
assert_absent "$PARENT/state/remote-replies/ios.caught-up" \
|
|
517
|
+
"adapter retirement left a caught-up watermark a later route could inherit"
|
|
518
|
+
pass "remote reply retirement quiesces and refuses unhandled captured results"
|
|
519
|
+
|
|
520
|
+
echo "ALL TESTS PASSED"
|