@zerwiz/ymir 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +291 -0
- package/.agents/agents/bragi-marketer.md +111 -0
- package/.agents/agents/brokk.md +352 -0
- package/.agents/agents/forseti-reviewer.md +93 -0
- package/.agents/agents/frigg-consent.md +77 -0
- package/.agents/agents/groa-update.md +77 -0
- package/.agents/agents/hnoss-designer.md +69 -0
- package/.agents/agents/huginn-researcher.md +99 -0
- package/.agents/agents/jord-projects.md +78 -0
- package/.agents/agents/kvasir-scout.md +91 -0
- package/.agents/agents/mimir-planner.md +92 -0
- package/.agents/agents/muninn-stow.md +77 -0
- package/.agents/agents/saga-bearings.md +78 -0
- package/.agents/agents/sindri-developer.md +114 -0
- package/.agents/agents/snotra-documenter.md +105 -0
- package/.agents/agents/syn-recovery.md +78 -0
- package/.agents/agents/tyr-check.md +78 -0
- package/.agents/agents/urdh-hold.md +77 -0
- package/.agents/agents/volundr-smith.md +80 -0
- package/.agents/agents/vor-diagnostics.md +77 -0
- package/.agents/assets/agents/naming.md +50 -0
- package/.agents/assets/agents/registry.md +93 -0
- package/.agents/assets/agents/runtime.md +36 -0
- package/.agents/assets/agents/toon-tasks-cli.md +42 -0
- package/.agents/assets/templates/company_entity.template.md +37 -0
- package/.agents/backend/backends/cmux.sh +649 -0
- package/.agents/backend/backends/herdr-eventwait.py +157 -0
- package/.agents/backend/backends/herdr-workspace-move.py +114 -0
- package/.agents/backend/backends/herdr.sh +3386 -0
- package/.agents/backend/backends/orca.sh +290 -0
- package/.agents/backend/backends/tmux.sh +357 -0
- package/.agents/backend/backends/zellij.sh +700 -0
- package/.agents/backend/fm-afk-launch.sh +654 -0
- package/.agents/backend/fm-afk-return.sh +241 -0
- package/.agents/backend/fm-afk-start.sh +172 -0
- package/.agents/backend/fm-arm-command-policy.mjs +960 -0
- package/.agents/backend/fm-arm-pretool-check.sh +200 -0
- package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
- package/.agents/backend/fm-backend.sh +981 -0
- package/.agents/backend/fm-backlog-handoff.sh +909 -0
- package/.agents/backend/fm-backlog-receive.sh +187 -0
- package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
- package/.agents/backend/fm-bearings-board.sh +204 -0
- package/.agents/backend/fm-bearings-snapshot.sh +546 -0
- package/.agents/backend/fm-bootstrap.sh +1568 -0
- package/.agents/backend/fm-branch-outcome.sh +203 -0
- package/.agents/backend/fm-branch-prompt.sh +101 -0
- package/.agents/backend/fm-brief.sh +452 -0
- package/.agents/backend/fm-busy-event.sh +234 -0
- package/.agents/backend/fm-busy-lib.sh +986 -0
- package/.agents/backend/fm-captain-hold.sh +1001 -0
- package/.agents/backend/fm-cd-command-policy.mjs +153 -0
- package/.agents/backend/fm-cd-pretool-check.sh +190 -0
- package/.agents/backend/fm-check-lib.sh +74 -0
- package/.agents/backend/fm-check-register.sh +42 -0
- package/.agents/backend/fm-check-unregister.sh +52 -0
- package/.agents/backend/fm-classify-lib.sh +1770 -0
- package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
- package/.agents/backend/fm-composer-lib.sh +1416 -0
- package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
- package/.agents/backend/fm-config-push.sh +254 -0
- package/.agents/backend/fm-control-lib.sh +251 -0
- package/.agents/backend/fm-control.sh +878 -0
- package/.agents/backend/fm-crew-state.sh +625 -0
- package/.agents/backend/fm-cursor-lib.sh +243 -0
- package/.agents/backend/fm-decision-hold.sh +232 -0
- package/.agents/backend/fm-doc-audience-check.sh +269 -0
- package/.agents/backend/fm-dod-lib.sh +67 -0
- package/.agents/backend/fm-ensure-agents-md.sh +253 -0
- package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
- package/.agents/backend/fm-extension.mjs +2577 -0
- package/.agents/backend/fm-extension.sh +16 -0
- package/.agents/backend/fm-ff-lib.sh +420 -0
- package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
- package/.agents/backend/fm-fleet-sync.sh +458 -0
- package/.agents/backend/fm-fleet-view.sh +96 -0
- package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
- package/.agents/backend/fm-guard.sh +242 -0
- package/.agents/backend/fm-harness.sh +195 -0
- package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
- package/.agents/backend/fm-herdr-lab.sh +346 -0
- package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
- package/.agents/backend/fm-home-seed.sh +984 -0
- package/.agents/backend/fm-home-summary-refresh.sh +255 -0
- package/.agents/backend/fm-hook-host-lib.sh +36 -0
- package/.agents/backend/fm-inactive-reconcile.sh +531 -0
- package/.agents/backend/fm-inbox.sh +399 -0
- package/.agents/backend/fm-install-actionlint.sh +84 -0
- package/.agents/backend/fm-install-herdr.sh +96 -0
- package/.agents/backend/fm-install-shellcheck.sh +84 -0
- package/.agents/backend/fm-install-treehouse.sh +95 -0
- package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
- package/.agents/backend/fm-lease-lib.sh +218 -0
- package/.agents/backend/fm-lease.sh +189 -0
- package/.agents/backend/fm-line-cap-lib.sh +51 -0
- package/.agents/backend/fm-lint-workflows.sh +137 -0
- package/.agents/backend/fm-lint.sh +591 -0
- package/.agents/backend/fm-lock-lib.sh +104 -0
- package/.agents/backend/fm-lock.sh +107 -0
- package/.agents/backend/fm-marker-lib.sh +12 -0
- package/.agents/backend/fm-merge-local.sh +74 -0
- package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
- package/.agents/backend/fm-nm-run-lib.sh +124 -0
- package/.agents/backend/fm-on.sh +125 -0
- package/.agents/backend/fm-operational-input.sh +253 -0
- package/.agents/backend/fm-peek.sh +46 -0
- package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
- package/.agents/backend/fm-pr-check.sh +135 -0
- package/.agents/backend/fm-pr-lib.sh +1016 -0
- package/.agents/backend/fm-pr-merge.sh +707 -0
- package/.agents/backend/fm-pr-poll.sh +110 -0
- package/.agents/backend/fm-primary-scope-lib.sh +33 -0
- package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
- package/.agents/backend/fm-procevent-lavish.sh +628 -0
- package/.agents/backend/fm-procevent-lib.sh +892 -0
- package/.agents/backend/fm-procevent-quota.sh +290 -0
- package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
- package/.agents/backend/fm-procevent-when.sh +504 -0
- package/.agents/backend/fm-procevent.sh +1466 -0
- package/.agents/backend/fm-project-mode.sh +92 -0
- package/.agents/backend/fm-project-origin-lib.sh +180 -0
- package/.agents/backend/fm-promote.sh +282 -0
- package/.agents/backend/fm-public-followup-emit.sh +260 -0
- package/.agents/backend/fm-public-followup-lib.sh +398 -0
- package/.agents/backend/fm-public-followup.sh +1330 -0
- package/.agents/backend/fm-push-transition-lib.sh +168 -0
- package/.agents/backend/fm-quota-axi-lib.sh +93 -0
- package/.agents/backend/fm-quota-choose.sh +384 -0
- package/.agents/backend/fm-remote-delta-read.sh +189 -0
- package/.agents/backend/fm-remote-doctor.sh +800 -0
- package/.agents/backend/fm-remote-entrypoint.sh +193 -0
- package/.agents/backend/fm-remote-file.sh +234 -0
- package/.agents/backend/fm-remote-home-provision.sh +259 -0
- package/.agents/backend/fm-remote-home-seed.sh +259 -0
- package/.agents/backend/fm-remote-inherit-push.sh +90 -0
- package/.agents/backend/fm-remote-inherit.sh +179 -0
- package/.agents/backend/fm-remote-job-lib.sh +1241 -0
- package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
- package/.agents/backend/fm-remote-job-worker.sh +1124 -0
- package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
- package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
- package/.agents/backend/fm-review-diff.sh +158 -0
- package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
- package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
- package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
- package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
- package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
- package/.agents/backend/fm-secondmate-report.sh +88 -0
- package/.agents/backend/fm-send.sh +1059 -0
- package/.agents/backend/fm-session-lock-lib.sh +176 -0
- package/.agents/backend/fm-session-start.sh +970 -0
- package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
- package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
- package/.agents/backend/fm-sessionstart-run.sh +145 -0
- package/.agents/backend/fm-spawn.sh +3153 -0
- package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
- package/.agents/backend/fm-startup-memory-budget.sh +94 -0
- package/.agents/backend/fm-startup-network.sh +642 -0
- package/.agents/backend/fm-stow-cascade.sh +251 -0
- package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
- package/.agents/backend/fm-supervise-daemon.sh +1732 -0
- package/.agents/backend/fm-supervision-instructions.sh +215 -0
- package/.agents/backend/fm-supervision-lib.sh +90 -0
- package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
- package/.agents/backend/fm-tangle-lib.sh +53 -0
- package/.agents/backend/fm-task-inbox-lib.sh +402 -0
- package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
- package/.agents/backend/fm-teardown.sh +2922 -0
- package/.agents/backend/fm-test-isolation-proof.sh +588 -0
- package/.agents/backend/fm-test-run.sh +2191 -0
- package/.agents/backend/fm-timeout-lib.sh +141 -0
- package/.agents/backend/fm-timing-lib.sh +179 -0
- package/.agents/backend/fm-tmux-lib.sh +291 -0
- package/.agents/backend/fm-tool-update-check.sh +898 -0
- package/.agents/backend/fm-trace-context-lib.sh +227 -0
- package/.agents/backend/fm-transition-lib.sh +103 -0
- package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
- package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
- package/.agents/backend/fm-turnend-guard.sh +432 -0
- package/.agents/backend/fm-update.sh +110 -0
- package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
- package/.agents/backend/fm-voice-client.py +1373 -0
- package/.agents/backend/fm-voice-relay.py +1256 -0
- package/.agents/backend/fm-wake-drain.sh +592 -0
- package/.agents/backend/fm-wake-grant.sh +127 -0
- package/.agents/backend/fm-wake-lib.sh +1849 -0
- package/.agents/backend/fm-watch-arm.sh +602 -0
- package/.agents/backend/fm-watch-checkpoint.sh +109 -0
- package/.agents/backend/fm-watch.sh +1962 -0
- package/.agents/backend/fm-x-dismiss.sh +116 -0
- package/.agents/backend/fm-x-followup.sh +286 -0
- package/.agents/backend/fm-x-lib.sh +1000 -0
- package/.agents/backend/fm-x-link.sh +234 -0
- package/.agents/backend/fm-x-poll.sh +185 -0
- package/.agents/backend/fm-x-reply.sh +385 -0
- package/.agents/backend/fm_voice_frame.py +166 -0
- package/.agents/backend/fm_voice_records.py +574 -0
- package/.agents/backend/model-bridge.py +290 -0
- package/.agents/backend/opencode-go-bridge.py +30 -0
- package/.agents/bus/README.md +12 -0
- package/.agents/bus/messages.json +1 -0
- package/.agents/config/agents.machine.example.yaml +16 -0
- package/.agents/config/agents.yaml +50 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +9 -0
- package/.agents/config/eindri-dispatch.json +67 -0
- package/.agents/config/eindri-harness +1 -0
- package/.agents/config/startup-memory-budget +1 -0
- package/.agents/config/tailscale-sync.yaml +27 -0
- package/.agents/filebrowser/.filebrowser.json +6 -0
- package/.agents/filebrowser/README.md +11 -0
- package/.agents/gateway/README.md +12 -0
- package/.agents/github/README.md +15 -0
- package/.agents/github/webhooks/.gitkeep +0 -0
- package/.agents/github/workflows/.gitkeep +0 -0
- package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
- package/.agents/harness/opencode/plugins/package.json +4 -0
- package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
- package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
- package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
- package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
- package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
- package/.agents/memory/README.md +46 -0
- package/.agents/memory/kaia.engram +0 -0
- package/.agents/memory/kaia.engram-shm +0 -0
- package/.agents/memory/kaia.engram-wal +0 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/memory/well/episodes.jsonl +367 -0
- package/.agents/memory/well/workspace.jsonl +27 -0
- package/.agents/migrations/0001-hodd-layout.sh +38 -0
- package/.agents/migrations/0002-a2a-mcp.sh +27 -0
- package/.agents/migrations/0003-private-data-separation.sh +111 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/sandbox/Dockerfile.utgard +19 -0
- package/.agents/sandbox/README.md +14 -0
- package/.agents/sandbox/utgard.config.json +14 -0
- package/.agents/skills/README.md +59 -0
- package/.agents/skills/bragi-marketing/README.md +3 -0
- package/.agents/skills/bragi-marketing/SKILL.md +82 -0
- package/.agents/skills/eindri-homes/README.md +3 -0
- package/.agents/skills/eindri-homes/SKILL.md +291 -0
- package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
- package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
- package/.agents/skills/frigg-consent/README.md +3 -0
- package/.agents/skills/frigg-consent/SKILL.md +56 -0
- package/.agents/skills/galdr-ymirsystem/README.md +3 -0
- package/.agents/skills/galdr-ymirsystem/SKILL.md +158 -0
- package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
- package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +673 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
- package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +496 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
- package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +161 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +96 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
- package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
- package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
- package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
- package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
- package/.agents/skills/galdr-ymirsystem/assets/smidja.md +175 -0
- package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
- package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
- package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
- package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +360 -0
- package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
- package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
- package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
- package/.agents/skills/gjallarhorn-relay/README.md +3 -0
- package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
- package/.agents/skills/groa-update/SKILL.md +70 -0
- package/.agents/skills/hamr-adapters/README.md +3 -0
- package/.agents/skills/hamr-adapters/SKILL.md +123 -0
- package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
- package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
- package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
- package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
- package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
- package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
- package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
- package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
- package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
- package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
- package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
- package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
- package/.agents/skills/herdr-panes/README.md +3 -0
- package/.agents/skills/herdr-panes/SKILL.md +92 -0
- package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
- package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
- package/.agents/skills/hnoss-design/DESIGN.md +19 -0
- package/.agents/skills/hnoss-design/README.md +3 -0
- package/.agents/skills/hnoss-design/SKILL.md +83 -0
- package/.agents/skills/hvild-afk/README.md +3 -0
- package/.agents/skills/hvild-afk/SKILL.md +241 -0
- package/.agents/skills/jord-projects/README.md +3 -0
- package/.agents/skills/jord-projects/SKILL.md +92 -0
- package/.agents/skills/lifecycle/SKILL.md +56 -0
- package/.agents/skills/lifecycle/smoke_test.sh +52 -0
- package/.agents/skills/lifecycle/start.sh +21 -0
- package/.agents/skills/lifecycle/status.sh +35 -0
- package/.agents/skills/lifecycle/stop.sh +16 -0
- package/.agents/skills/muninn-stow/README.md +3 -0
- package/.agents/skills/muninn-stow/SKILL.md +309 -0
- package/.agents/skills/no-mistakes/SKILL.md +379 -0
- package/.agents/skills/nornir-schedule/README.md +3 -0
- package/.agents/skills/nornir-schedule/SKILL.md +25 -0
- package/.agents/skills/nornir-schedule/assets/events.md +137 -0
- package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
- package/.agents/skills/nsr-compliance/README.md +3 -0
- package/.agents/skills/nsr-compliance/SKILL.md +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/pr-ops/README.md +3 -0
- package/.agents/skills/pr-ops/SKILL.md +109 -0
- package/.agents/skills/ratatoskr-a2a/README.md +3 -0
- package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
- package/.agents/skills/rules-check-drift/SKILL.md +81 -0
- package/.agents/skills/saga-bearings/README.md +3 -0
- package/.agents/skills/saga-bearings/SKILL.md +26 -0
- package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
- package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
- package/.agents/skills/saga-bearings/assets/recap.md +56 -0
- package/.agents/skills/syn-recovery/README.md +3 -0
- package/.agents/skills/syn-recovery/SKILL.md +54 -0
- package/.agents/skills/tyr-check/README.md +3 -0
- package/.agents/skills/tyr-check/SKILL.md +218 -0
- package/.agents/skills/urdh-hold/README.md +3 -0
- package/.agents/skills/urdh-hold/SKILL.md +25 -0
- package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
- package/.agents/skills/urdh-hold/assets/hold.md +54 -0
- package/.agents/skills/vor-diagnostics/README.md +3 -0
- package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
- package/.agents/skills/ymir-host/README.md +3 -0
- package/.agents/skills/ymir-host/SKILL.md +34 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
- package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
- package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
- package/.agents/skills/ymir-host/assets/update.md +64 -0
- package/.agents/tests/assets/board-render-harness.mjs +117 -0
- package/.agents/tests/cmux-test-safety.sh +51 -0
- package/.agents/tests/fixtures.sh +291 -0
- package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
- package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
- package/.agents/tests/fm-afk-launch.test.sh +961 -0
- package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
- package/.agents/tests/fm-afk-return.test.sh +283 -0
- package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
- package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
- package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
- package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
- package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
- package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
- package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
- package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
- package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
- package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
- package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
- package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
- package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
- package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
- package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
- package/.agents/tests/fm-backend-orca.test.sh +1357 -0
- package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
- package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
- package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
- package/.agents/tests/fm-backend.test.sh +1142 -0
- package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
- package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
- package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
- package/.agents/tests/fm-bearings-board.test.sh +414 -0
- package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
- package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
- package/.agents/tests/fm-bootstrap.test.sh +1178 -0
- package/.agents/tests/fm-branch-supervision.test.sh +552 -0
- package/.agents/tests/fm-brief.test.sh +785 -0
- package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
- package/.agents/tests/fm-busy-state.test.sh +465 -0
- package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
- package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
- package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
- package/.agents/tests/fm-check-unregister.test.sh +198 -0
- package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
- package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
- package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
- package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
- package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
- package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
- package/.agents/tests/fm-composer-ghost.test.sh +716 -0
- package/.agents/tests/fm-composer-lib.test.sh +666 -0
- package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
- package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
- package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
- package/.agents/tests/fm-control.test.sh +910 -0
- package/.agents/tests/fm-crew-state.test.sh +1610 -0
- package/.agents/tests/fm-cursor-harness.test.sh +404 -0
- package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
- package/.agents/tests/fm-cursor-primary.test.sh +708 -0
- package/.agents/tests/fm-daemon.test.sh +2740 -0
- package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
- package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
- package/.agents/tests/fm-extension-binding.test.sh +2187 -0
- package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
- package/.agents/tests/fm-fleet-sync.test.sh +721 -0
- package/.agents/tests/fm-gate-refuse.test.sh +356 -0
- package/.agents/tests/fm-gitignore-config.test.sh +89 -0
- package/.agents/tests/fm-gotmp.test.sh +230 -0
- package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
- package/.agents/tests/fm-grok-harness.test.sh +117 -0
- package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
- package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
- package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
- package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
- package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
- package/.agents/tests/fm-herdr-lab.test.sh +243 -0
- package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
- package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
- package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
- package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
- package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
- package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
- package/.agents/tests/fm-kimi-harness.test.sh +687 -0
- package/.agents/tests/fm-lint-workflows.test.sh +532 -0
- package/.agents/tests/fm-lint.test.sh +1023 -0
- package/.agents/tests/fm-muse-harness.test.sh +932 -0
- package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
- package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
- package/.agents/tests/fm-on.test.sh +507 -0
- package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
- package/.agents/tests/fm-operational-input.test.sh +160 -0
- package/.agents/tests/fm-peek-remote.test.sh +110 -0
- package/.agents/tests/fm-pending-reply.test.sh +1288 -0
- package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
- package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
- package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
- package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
- package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
- package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
- package/.agents/tests/fm-pr-merge.test.sh +2135 -0
- package/.agents/tests/fm-procevent-quota.test.sh +225 -0
- package/.agents/tests/fm-procevent-when.test.sh +406 -0
- package/.agents/tests/fm-procevent.test.sh +1745 -0
- package/.agents/tests/fm-project-origin.test.sh +110 -0
- package/.agents/tests/fm-public-followup.test.sh +2272 -0
- package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
- package/.agents/tests/fm-quota-choose.test.sh +626 -0
- package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
- package/.agents/tests/fm-remote-doctor.test.sh +625 -0
- package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
- package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
- package/.agents/tests/fm-remote-job.test.sh +768 -0
- package/.agents/tests/fm-remote-reply.test.sh +520 -0
- package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
- package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
- package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
- package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
- package/.agents/tests/fm-review-diff.test.sh +176 -0
- package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
- package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
- package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
- package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
- package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
- package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
- package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
- package/.agents/tests/fm-send-inbox.test.sh +352 -0
- package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
- package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
- package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
- package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
- package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
- package/.agents/tests/fm-send-settle.test.sh +147 -0
- package/.agents/tests/fm-send-strict.test.sh +241 -0
- package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
- package/.agents/tests/fm-session-start.test.sh +2515 -0
- package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
- package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
- package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
- package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
- package/.agents/tests/fm-spawn-batch.test.sh +148 -0
- package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
- package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
- package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
- package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
- package/.agents/tests/fm-startup-network.test.sh +712 -0
- package/.agents/tests/fm-stow-cascade.test.sh +370 -0
- package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
- package/.agents/tests/fm-supervision-events.test.sh +156 -0
- package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
- package/.agents/tests/fm-tangle-guard.test.sh +277 -0
- package/.agents/tests/fm-task-delivery.test.sh +420 -0
- package/.agents/tests/fm-task-inbox.test.sh +513 -0
- package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
- package/.agents/tests/fm-teardown.test.sh +2665 -0
- package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
- package/.agents/tests/fm-test-fixtures.test.sh +132 -0
- package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
- package/.agents/tests/fm-test-run.test.sh +1196 -0
- package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
- package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
- package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
- package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
- package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
- package/.agents/tests/fm-transition-lib.test.sh +54 -0
- package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
- package/.agents/tests/fm-update.test.sh +304 -0
- package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
- package/.agents/tests/fm-voice-relay.test.sh +4741 -0
- package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
- package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
- package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
- package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
- package/.agents/tests/fm-wake-queue.test.sh +1224 -0
- package/.agents/tests/fm-watch-arm.test.sh +821 -0
- package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
- package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
- package/.agents/tests/fm-watch-triage.test.sh +3889 -0
- package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
- package/.agents/tests/fm-x-mode.test.sh +3042 -0
- package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
- package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
- package/.agents/tests/herdr-test-safety.sh +42 -0
- package/.agents/tests/lib.sh +315 -0
- package/.agents/tests/remote-herdr-fixture.sh +125 -0
- package/.agents/tests/secondmate-helpers.sh +193 -0
- package/.agents/tests/smoke.test.sh +93 -0
- package/.agents/tests/wake-helpers.sh +338 -0
- package/.agents/tests/zellij-test-safety.sh +60 -0
- package/.agents/tools/README.md +10 -0
- package/.agents/tools/bin/tasks-cli +267 -0
- package/.agents/tools/tasks-cli.ts +216 -0
- package/AGENTS.md +454 -0
- package/CHANGELOG.md +881 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +113 -59
- package/RULES/01-domains.md +51 -0
- package/RULES/02-agents.md +78 -0
- package/RULES/03-houses.md +61 -0
- package/RULES/04-hoard.md +65 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +58 -0
- package/RULES/07-config.md +45 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/README.md +20 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +98 -0
- package/bin/a2a-serve.py +103 -0
- package/bin/a2a-serve.sh +8 -0
- package/bin/a2a-talk.sh +50 -0
- package/bin/a2abridge-ensure.sh +108 -0
- package/bin/agent-run.sh +43 -0
- package/bin/agents-config.sh +233 -0
- package/bin/apodex-smoke-test.sh +92 -0
- package/bin/bifrost-bridge.sh +112 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +107 -0
- package/bin/bootstrap-windows.ps1 +112 -0
- package/bin/branch-guard.sh +64 -0
- package/bin/brokk +73 -0
- package/bin/brokk-classify-lib.sh +1770 -0
- package/bin/brokk-lease-lib.sh +222 -0
- package/bin/brokk-lease.sh +193 -0
- package/bin/brokk-lint.sh +65 -0
- package/bin/brokk-send.sh +38 -0
- package/bin/brokk-update.sh +9 -0
- package/bin/brokk-wake-grant.sh +127 -0
- package/bin/brokk-wake-lib.sh +1849 -0
- package/bin/changelog-guard.sh +165 -0
- package/bin/crash-sense.sh +160 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +207 -0
- package/bin/eindri-acclaim.sh +34 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seen.sh +41 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +85 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +112 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/fleet-apply.sh +68 -0
- package/bin/github-deploy.sh +81 -0
- package/bin/gjallarhorn-expose.sh +102 -0
- package/bin/gjallarhorn-notify.sh +58 -0
- package/bin/gjallarhorn-purge.sh +54 -0
- package/bin/gjallarhorn-tunnel.sh +72 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +122 -0
- package/bin/hall-snapshot.sh +92 -0
- package/bin/hamr-harness.sh +246 -0
- package/bin/heimdall-ssh-keys.sh +374 -0
- package/bin/herdr-agents.py +44 -0
- package/bin/herdr-ensure.sh +104 -0
- package/bin/herdr-run.sh +431 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hoard-lib.sh +25 -0
- package/bin/hodd.sh +78 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +108 -0
- package/bin/local-model-lock.sh +51 -0
- package/bin/mimir-bridge.py +226 -0
- package/bin/mimir-bridge.sh +87 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +59 -0
- package/bin/mjollnir.sh +85 -0
- package/bin/model-hardware.sh +82 -0
- package/bin/model-resolve.sh +147 -0
- package/bin/models-detect.sh +178 -0
- package/bin/nornir-cron-start.sh +162 -0
- package/bin/nornir-job-daily-briefing.sh +191 -0
- package/bin/nornir-job-git-sync.sh +152 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +148 -0
- package/bin/omarchy-plugins.sh +174 -0
- package/bin/omarchy-sense.sh +149 -0
- package/bin/perm-guard.sh +30 -0
- package/bin/pi-agent.sh +68 -0
- package/bin/pi-ensure.sh +77 -0
- package/bin/pi-local.sh +37 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +38 -0
- package/bin/project-git.sh +55 -0
- package/bin/public-guard.sh +70 -0
- package/bin/ratatoskr.sh +49 -0
- package/bin/realm-lib.sh +32 -0
- package/bin/repo-scrub.sh +62 -0
- package/bin/rodd-operational-input.sh +250 -0
- package/bin/runes-append.sh +198 -0
- package/bin/saga-session-start.sh +172 -0
- package/bin/saga-sessionstart-run.sh +79 -0
- package/bin/saga-wake-drain.sh +41 -0
- package/bin/secret-guard.sh +63 -0
- package/bin/sessrumnir-ensure.sh +100 -0
- package/bin/sessrumnir-sync.sh +237 -0
- package/bin/sessrumnir.sh +91 -0
- package/bin/skillopt-setup.sh +76 -0
- package/bin/skuld-branch-outcome.sh +203 -0
- package/bin/skuld-branch-prompt.sh +101 -0
- package/bin/smidja-bootstrap.sh +90 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +76 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +190 -0
- package/bin/telegram-bot.sh +69 -0
- package/bin/toolchain.sh +74 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +260 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +47 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +150 -0
- package/bin/wyrd-db.sh +47 -0
- package/bin/yggdrasil.sh +152 -0
- package/bin/ymir-edit.sh +145 -0
- package/bin/ymir-install.sh +641 -0
- package/bin/ymir-invite.sh +93 -0
- package/bin/ymir-isolation.sh +88 -0
- package/bin/ymir-migrate.sh +61 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +97 -0
- package/bin/ymir-setup-auth.sh +108 -0
- package/bin/ymir-validate.sh +173 -0
- package/bin/ymir.js +74 -16
- package/docs/Architecture.md +339 -0
- package/docs/design.md +351 -0
- package/docs/installations/README.md +63 -0
- package/docs/installations/ymir-home.md +93 -0
- package/docs/integration.md +105 -0
- package/docs/lore.md +1056 -0
- package/docs/research/agent-harnesses.md +290 -0
- package/docs/runbooks/README.md +19 -0
- package/docs/runbooks/a2a.md +91 -0
- package/docs/runbooks/agent-permissions.md +99 -0
- package/docs/runbooks/agents.md +57 -0
- package/docs/runbooks/models.md +69 -0
- package/docs/runbooks/realm-onboarding.md +60 -0
- package/docs/runbooks/secrets-and-hoard.md +60 -0
- package/docs/runbooks/updates-and-migrations.md +110 -0
- package/docs/runbooks/worktrees-isolation.md +72 -0
- package/docs/session-start.md +105 -0
- package/docs/skillopt-integration.md +321 -0
- package/docs/sync-system.md +66 -0
- package/docs/workspaces.md +104 -0
- package/docs/ymir-rut.md +260 -0
- package/package.json +44 -14
- package/packaging/build.sh +74 -0
- package/packaging/macos/Ymir Installer.command +43 -0
- package/packaging/windows/ymir-setup.nsi +74 -0
- package/scripts/README.md +22 -0
- package/scripts/electron.sh +210 -0
- package/scripts/start.sh +167 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,642 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fm-startup-network.sh - the deferred network stage of a session start.
|
|
3
|
+
#
|
|
4
|
+
# WHY THIS EXISTS. Every external-network call a session start makes used to run
|
|
5
|
+
# BEFORE the digest printed, on a hook that blocks session initialization: `gh
|
|
6
|
+
# auth status`, the secondmate liveness and convergence sweeps (per-secondmate
|
|
7
|
+
# remote probes, which bootstrap runs concurrently), pending remote
|
|
8
|
+
# handoff delivery, and the fleet-sync fetch of every project clone. None of
|
|
9
|
+
# those calls is individually bounded, so one unreachable host could consume the
|
|
10
|
+
# whole FM_SESSION_START_TIMEOUT budget and truncate the digest outright, turning
|
|
11
|
+
# a slow network into a startup that never printed the work queue at all.
|
|
12
|
+
# This script runs exactly that work OFF the blocking path: the digest is
|
|
13
|
+
# composed from local reads alone while these checks run concurrently in a
|
|
14
|
+
# detached worker, and their result is reported back inline when it finishes in
|
|
15
|
+
# time, or as a durable wake when it does not.
|
|
16
|
+
#
|
|
17
|
+
# WHAT IS PRESERVED. Nothing is dropped. bin/fm-bootstrap.sh remains the single
|
|
18
|
+
# owner of every one of these sweeps and still runs all of them, unchanged, via
|
|
19
|
+
# its FM_BOOTSTRAP_NETWORK=only phase. Deferral changes WHEN they run, not
|
|
20
|
+
# WHETHER, and three properties make the later run safe:
|
|
21
|
+
# - The sweeps are idempotent DETECTORS. A run whose report is lost (killed
|
|
22
|
+
# worker, truncated digest, crashed session) loses no finding: the next run
|
|
23
|
+
# re-derives the same dead secondmate, the same stuck clone, the same
|
|
24
|
+
# undelivered handoff. There is no once-only signal to miss.
|
|
25
|
+
# - The result is durable and always surfaces. It lands in
|
|
26
|
+
# state/.startup-network.report and reaches the agent either inline in the
|
|
27
|
+
# digest or, when it finishes too late for the digest to inline it, as a
|
|
28
|
+
# `check: startup-network` wake - but only when the late result is itself
|
|
29
|
+
# actionable (state is not "done", or bootstrap emitted something other
|
|
30
|
+
# than its explicit BOOTSTRAP_INFO no-action record; report_requires_wake
|
|
31
|
+
# owns that transport test). A late-finishing clean run is not captain-facing progress
|
|
32
|
+
# (AGENTS.md section 8) and never becomes a wake row; it is still durable
|
|
33
|
+
# in the report file for `... report` to read on demand. Only a durable
|
|
34
|
+
# acknowledgement written after harvest prints the finished result
|
|
35
|
+
# suppresses the wake, so a claimant that exits first cannot lose the
|
|
36
|
+
# result. While the worker is still running the digest states by name what
|
|
37
|
+
# is not yet confirmed.
|
|
38
|
+
# - Mutation authority is leased. The worker outlives the command that launched
|
|
39
|
+
# it, so it takes the same acquisition lease a new session must hold before
|
|
40
|
+
# replacing a dead owner, re-checks the captured owner under that lease, and
|
|
41
|
+
# holds it through the bounded mutating run. A takeover stays read-only until
|
|
42
|
+
# that run settles, so old and new owners can never sweep concurrently.
|
|
43
|
+
#
|
|
44
|
+
# Usage: fm-startup-network.sh start --locked <0|1> --harvest-pid <pid>
|
|
45
|
+
# Launch the detached worker and return immediately. Single-flight: a
|
|
46
|
+
# worker already running for the same lock owner is left alone. A new
|
|
47
|
+
# owner gets a distinct generation. --locked 1 asks
|
|
48
|
+
# for the mutating sweeps as well as the read-only probe; --locked 0
|
|
49
|
+
# asks for the probe only. --harvest-pid names the session-start process
|
|
50
|
+
# that will try to print the result inline, so the worker can tell
|
|
51
|
+
# whether a wake is still needed.
|
|
52
|
+
# fm-startup-network.sh run --locked <0|1>
|
|
53
|
+
# Run the checks in the foreground and publish the result. This is what
|
|
54
|
+
# `start` detaches with its private generation reservation; run it
|
|
55
|
+
# directly to redo the stage by hand from the lock-owning harness.
|
|
56
|
+
# fm-startup-network.sh harvest --pid <pid>
|
|
57
|
+
# Print the digest's NETWORK CHECKS section and release the inline-print
|
|
58
|
+
# claim. Called by bin/fm-session-start.sh, not by hand.
|
|
59
|
+
# fm-startup-network.sh report
|
|
60
|
+
# Print the current state and report without changing anything, then the
|
|
61
|
+
# last run's per-step elapsed times. This is the ONLY command that prints
|
|
62
|
+
# those timings: `harvest` composes the session-start digest, and adding
|
|
63
|
+
# diagnostic detail there would make every startup pay for a question
|
|
64
|
+
# only a slow run raises.
|
|
65
|
+
# fm-startup-network.sh wait [<seconds>]
|
|
66
|
+
# Block until the report is published, up to <seconds> (default 120).
|
|
67
|
+
# For operators and tests only; a session start never waits.
|
|
68
|
+
#
|
|
69
|
+
# STATE, all under this home's state/ and gitignored with it:
|
|
70
|
+
# .startup-network.status key=value record - generation, lock_pid, state,
|
|
71
|
+
# pid, started, finished, rc, locked, phases, and
|
|
72
|
+
# whether the report was published. The single
|
|
73
|
+
# source of truth for what ran and how it ended.
|
|
74
|
+
# .startup-network.report the sweep output, byte for byte as
|
|
75
|
+
# bin/fm-bootstrap.sh produced it, plus a
|
|
76
|
+
# NETWORK_CHECKS: line whenever the stage itself
|
|
77
|
+
# could not complete or had to downgrade.
|
|
78
|
+
# .startup-network.claim the generation and pid of a session start that
|
|
79
|
+
# intends to print the result inline; a matching live
|
|
80
|
+
# claimant gives harvest a bounded chance to finish.
|
|
81
|
+
# .startup-network.delivered
|
|
82
|
+
# a durable acknowledgement that harvest printed the
|
|
83
|
+
# current finished result; only this suppresses its
|
|
84
|
+
# wake.
|
|
85
|
+
# .startup-network.timings per-step elapsed times for the last run, in
|
|
86
|
+
# bin/fm-timing-lib.sh's tab-separated format: the
|
|
87
|
+
# stage total, one record per network phase (gh auth,
|
|
88
|
+
# secondmate liveness, secondmate convergence, handoff
|
|
89
|
+
# delivery, fleet sync), one per secondmate for the
|
|
90
|
+
# remote-touching steps (id and host), and one per
|
|
91
|
+
# project clone. Published for a timed-out or failed
|
|
92
|
+
# run too, where a partial record is the answer.
|
|
93
|
+
# Diagnostic only: nothing reads it to make a
|
|
94
|
+
# decision, and losing it never downgrades a run.
|
|
95
|
+
# .startup-network.lock serializes publication, harvest acknowledgement,
|
|
96
|
+
# and the wake decision.
|
|
97
|
+
#
|
|
98
|
+
# The whole stage is bounded by FM_STARTUP_NETWORK_TIMEOUT (default 120s), one
|
|
99
|
+
# aggregate deadline replacing the per-call unboundedness that used to be able to
|
|
100
|
+
# wedge a startup. Hitting the bound is reported as an actionable NETWORK_CHECKS:
|
|
101
|
+
# line, never as silence.
|
|
102
|
+
set -u
|
|
103
|
+
|
|
104
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
105
|
+
FM_ROOT="${FM_ROOT_OVERRIDE:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
106
|
+
FM_HOME="${FM_HOME:-${FM_ROOT_OVERRIDE:-$FM_ROOT}}"
|
|
107
|
+
STATE="${FM_STATE_OVERRIDE:-$FM_HOME/state}"
|
|
108
|
+
|
|
109
|
+
STATUS_FILE="$STATE/.startup-network.status"
|
|
110
|
+
REPORT_FILE="$STATE/.startup-network.report"
|
|
111
|
+
CLAIM_FILE="$STATE/.startup-network.claim"
|
|
112
|
+
DELIVERED_FILE="$STATE/.startup-network.delivered"
|
|
113
|
+
TIMINGS_FILE="$STATE/.startup-network.timings"
|
|
114
|
+
PUBLISH_LOCK="$STATE/.startup-network.lock"
|
|
115
|
+
|
|
116
|
+
# shellcheck source=bin/fm-timeout-lib.sh
|
|
117
|
+
. "$SCRIPT_DIR/fm-timeout-lib.sh"
|
|
118
|
+
# fm-timing-lib.sh owns the per-step elapsed record this stage publishes beside
|
|
119
|
+
# its report. Recording is opt-in per run: it stays inert until cmd_run points
|
|
120
|
+
# FM_TIMING_LOG at a file, so nothing else that sources these scripts pays for it.
|
|
121
|
+
# shellcheck source=bin/fm-timing-lib.sh
|
|
122
|
+
. "$SCRIPT_DIR/fm-timing-lib.sh"
|
|
123
|
+
# fm-wake-lib.sh owns both the portable lock helpers used below and the durable
|
|
124
|
+
# wake queue this stage publishes into.
|
|
125
|
+
# shellcheck source=bin/fm-wake-lib.sh
|
|
126
|
+
. "$SCRIPT_DIR/fm-wake-lib.sh"
|
|
127
|
+
# shellcheck source=bin/fm-session-lock-lib.sh
|
|
128
|
+
. "$SCRIPT_DIR/fm-session-lock-lib.sh"
|
|
129
|
+
|
|
130
|
+
usage() {
|
|
131
|
+
sed -n '2,/^set -u$/p' "$SCRIPT_DIR/fm-startup-network.sh" | sed 's/^# \{0,1\}//; $d'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
status_get() { # <key>
|
|
135
|
+
[ -f "$STATUS_FILE" ] || return 0
|
|
136
|
+
sed -n "s/^$1=//p" "$STATUS_FILE" 2>/dev/null | tail -1
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
write_atomic() { # <dest>, content on stdin
|
|
140
|
+
local dest=$1 tmp
|
|
141
|
+
tmp=$(mktemp "$dest.XXXXXX" 2>/dev/null) || return 1
|
|
142
|
+
if cat > "$tmp" 2>/dev/null && mv -f "$tmp" "$dest" 2>/dev/null; then
|
|
143
|
+
return 0
|
|
144
|
+
fi
|
|
145
|
+
rm -f "$tmp" 2>/dev/null || true
|
|
146
|
+
return 1
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
now() { date +%s; }
|
|
150
|
+
|
|
151
|
+
age_of() { # <epoch> - seconds since, or empty when unreadable
|
|
152
|
+
local then=$1
|
|
153
|
+
case "$then" in ''|*[!0-9]*) return 0 ;; esac
|
|
154
|
+
printf '%s' "$(( $(now) - then ))"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
stage_budget() {
|
|
158
|
+
local budget=${FM_STARTUP_NETWORK_TIMEOUT:-120}
|
|
159
|
+
case "$budget" in ''|*[!0-9]*|0) budget=120 ;; esac
|
|
160
|
+
printf '%s' "$budget"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
delivery_budget() {
|
|
164
|
+
local budget=${FM_SESSION_START_TIMEOUT:-120}
|
|
165
|
+
case "$budget" in ''|*[!0-9]*|0) budget=120 ;; esac
|
|
166
|
+
printf '%s' "$budget"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Is a `running` record a stage that is genuinely still in flight? Two
|
|
170
|
+
# independent proofs are required, because either one alone can lie: a recorded
|
|
171
|
+
# pid can be reused by an unrelated process, and a worker killed with its process
|
|
172
|
+
# group (which is what a truncated digest does) leaves the record behind
|
|
173
|
+
# untouched. A record that outlives the stage's own aggregate bound is therefore
|
|
174
|
+
# treated as abandoned no matter what its pid says, which keeps "in progress"
|
|
175
|
+
# from becoming a permanent state.
|
|
176
|
+
worker_alive() {
|
|
177
|
+
local pid started age
|
|
178
|
+
pid=$(status_get pid)
|
|
179
|
+
case "$pid" in ''|*[!0-9]*) return 1 ;; esac
|
|
180
|
+
kill -0 "$pid" 2>/dev/null || return 1
|
|
181
|
+
started=$(status_get started)
|
|
182
|
+
age=$(age_of "$started")
|
|
183
|
+
case "$age" in ''|*[!0-9]*) return 0 ;; esac
|
|
184
|
+
[ "$age" -le "$(( $(stage_budget) + 30 ))" ]
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# The exact phase names the digest and the report use, so "what has not been
|
|
188
|
+
# confirmed yet" is always answerable from the status record alone.
|
|
189
|
+
phase_label() { # <phases>
|
|
190
|
+
case "$1" in
|
|
191
|
+
probe) printf 'GitHub authentication' ;;
|
|
192
|
+
probe,sweeps) printf 'GitHub authentication, dead-secondmate relaunch, secondmate convergence, pending handoff delivery, and project clone refresh with its drift reporting' ;;
|
|
193
|
+
*) printf 'the deferred network checks' ;;
|
|
194
|
+
esac
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# --- start -------------------------------------------------------------------
|
|
198
|
+
|
|
199
|
+
cmd_start() { # <locked> <harvest-pid>
|
|
200
|
+
local locked=$1 harvest_pid=$2 lock_pid generation worker_pid phases started
|
|
201
|
+
mkdir -p "$STATE" 2>/dev/null || return 1
|
|
202
|
+
# Captured HERE, at the moment the caller still holds the lock, and carried to
|
|
203
|
+
# the worker: re-reading the lock later would only prove that SOME session
|
|
204
|
+
# holds it, which is exactly the case this guard exists to reject.
|
|
205
|
+
lock_pid=$(cat "$STATE/.lock" 2>/dev/null || true)
|
|
206
|
+
if [ "$locked" = 1 ] && ! fm_session_lock_owned_by_self "$STATE"; then
|
|
207
|
+
return 1
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
fm_lock_acquire_wait "$PUBLISH_LOCK"
|
|
211
|
+
if [ "$(status_get state)" = running ] && worker_alive \
|
|
212
|
+
&& { [ "$locked" != 1 ] || [ "$(status_get lock_pid)" = "$lock_pid" ]; }; then
|
|
213
|
+
# A worker from this or a previous session is still going. Starting a second
|
|
214
|
+
# one would run the same mutating sweeps concurrently, so leave it alone and
|
|
215
|
+
# let the harvest report its real state.
|
|
216
|
+
generation=$(status_get generation)
|
|
217
|
+
printf '%s\t%s\n' "$generation" "$harvest_pid" > "$CLAIM_FILE" 2>/dev/null || true
|
|
218
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
219
|
+
return 0
|
|
220
|
+
fi
|
|
221
|
+
|
|
222
|
+
generation="$(now).$$.$harvest_pid"
|
|
223
|
+
started=$(now)
|
|
224
|
+
phases=probe
|
|
225
|
+
[ "$locked" != 1 ] || phases=probe,sweeps
|
|
226
|
+
if ! write_atomic "$STATUS_FILE" <<EOF
|
|
227
|
+
state=running
|
|
228
|
+
pid=0
|
|
229
|
+
started=$started
|
|
230
|
+
locked=$locked
|
|
231
|
+
phases=$phases
|
|
232
|
+
generation=$generation
|
|
233
|
+
lock_pid=$lock_pid
|
|
234
|
+
EOF
|
|
235
|
+
then
|
|
236
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
237
|
+
return 1
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
# Detached three ways, each closing a different failure:
|
|
241
|
+
# - stdio to /dev/null, because the digest's stdout is a pipe the harness
|
|
242
|
+
# reads to EOF; a worker holding that pipe open would strand session
|
|
243
|
+
# initialization behind the very work this stage exists to take off the
|
|
244
|
+
# blocking path.
|
|
245
|
+
# - nohup, so the worker outlives the shell that launched it.
|
|
246
|
+
# - its OWN process group (monitor mode), because the caller runs inside the
|
|
247
|
+
# digest's bounded child and that bound terminates its whole process group.
|
|
248
|
+
# Sharing the group would kill the worker on a truncated startup and, worse,
|
|
249
|
+
# orphan the bootstrap child it had already launched into a separate group -
|
|
250
|
+
# leaving unbounded network work running with nothing left to bound it. Its
|
|
251
|
+
# own group means a truncated digest leaves this stage running under its own
|
|
252
|
+
# deadline, which is exactly the independence deferral is for.
|
|
253
|
+
local monitor_was_on=0
|
|
254
|
+
case $- in *m*) monitor_was_on=1 ;; esac
|
|
255
|
+
set -m 2>/dev/null || true
|
|
256
|
+
nohup "$SCRIPT_DIR/fm-startup-network.sh" run --locked "$locked" --lock-pid "$lock_pid" \
|
|
257
|
+
--generation "$generation" \
|
|
258
|
+
>/dev/null 2>&1 </dev/null &
|
|
259
|
+
worker_pid=$!
|
|
260
|
+
if ! write_atomic "$STATUS_FILE" <<EOF
|
|
261
|
+
state=running
|
|
262
|
+
pid=$worker_pid
|
|
263
|
+
started=$started
|
|
264
|
+
locked=$locked
|
|
265
|
+
phases=$phases
|
|
266
|
+
generation=$generation
|
|
267
|
+
lock_pid=$lock_pid
|
|
268
|
+
EOF
|
|
269
|
+
then
|
|
270
|
+
kill "$worker_pid" 2>/dev/null || true
|
|
271
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
272
|
+
[ "$monitor_was_on" -eq 1 ] || set +m 2>/dev/null || true
|
|
273
|
+
return 1
|
|
274
|
+
fi
|
|
275
|
+
printf '%s\t%s\n' "$generation" "$harvest_pid" > "$CLAIM_FILE" 2>/dev/null || true
|
|
276
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
277
|
+
[ "$monitor_was_on" -eq 1 ] || set +m 2>/dev/null || true
|
|
278
|
+
return 0
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
# --- run ---------------------------------------------------------------------
|
|
282
|
+
|
|
283
|
+
# Re-verify mutation authority immediately before the mutating sweeps: "my
|
|
284
|
+
# session held the lock a moment ago" is not enough for a worker that outlives
|
|
285
|
+
# the command which launched it.
|
|
286
|
+
#
|
|
287
|
+
# The question is deliberately "does the lock still name the session that asked
|
|
288
|
+
# for this work?", not "is that session still alive". The hazard being closed is
|
|
289
|
+
# a SECOND session sweeping concurrently, and taking the lock is exactly what
|
|
290
|
+
# rewrites this value - bin/fm-lock.sh overwrites a dead holder's pid with its
|
|
291
|
+
# own. An unchanged value therefore proves no one else owns the sweeps, which is
|
|
292
|
+
# the whole guarantee. Requiring liveness instead would refuse to finish work
|
|
293
|
+
# nobody else has claimed, and the sweeps are idempotent, so finishing it is
|
|
294
|
+
# strictly better than abandoning it. A missing, unreadable, or replaced lock all
|
|
295
|
+
# fail closed to the read-only probe.
|
|
296
|
+
lock_unchanged() { # <expected-pid>
|
|
297
|
+
local expected=$1 current
|
|
298
|
+
case "$expected" in ''|*[!0-9]*) return 1 ;; esac
|
|
299
|
+
[ -f "$STATE/.lock" ] && [ ! -L "$STATE/.lock" ] || return 1
|
|
300
|
+
current=$(cat "$STATE/.lock" 2>/dev/null) || return 1
|
|
301
|
+
[ "$current" = "$expected" ]
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
# Bootstrap owns the meaning of its output protocol: silence is success,
|
|
305
|
+
# BOOTSTRAP_INFO is an explicit completed no-action fact, and every other line
|
|
306
|
+
# is a diagnostic. This delivery layer does not maintain a second semantic
|
|
307
|
+
# prefix list or decide what a diagnostic means; it only applies that producer-
|
|
308
|
+
# supplied transport type. Unknown non-empty output fails safe by waking.
|
|
309
|
+
report_requires_wake() { # <state>
|
|
310
|
+
local state=$1
|
|
311
|
+
[ "$state" = "done" ] || return 0
|
|
312
|
+
[ -s "$REPORT_FILE" ] || return 1
|
|
313
|
+
awk 'NF && $0 !~ /^BOOTSTRAP_INFO:/ { found=1; exit } END { exit !found }' \
|
|
314
|
+
"$REPORT_FILE" 2>/dev/null
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
await_delivery() { # <generation> <state>
|
|
318
|
+
local generation=$1 state=$2 limit waited=0 claim_record claim_generation claim_pid claim_live
|
|
319
|
+
limit=$(( $(delivery_budget) * 10 ))
|
|
320
|
+
while [ "$waited" -lt "$limit" ]; do
|
|
321
|
+
claim_live=0
|
|
322
|
+
fm_lock_acquire_wait "$PUBLISH_LOCK"
|
|
323
|
+
if [ "$(status_get generation)" != "$generation" ]; then
|
|
324
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
325
|
+
return 0
|
|
326
|
+
fi
|
|
327
|
+
if [ -f "$DELIVERED_FILE" ]; then
|
|
328
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
329
|
+
return 0
|
|
330
|
+
fi
|
|
331
|
+
if [ -f "$CLAIM_FILE" ]; then
|
|
332
|
+
claim_record=$(cat "$CLAIM_FILE" 2>/dev/null || true)
|
|
333
|
+
IFS=$'\t' read -r claim_generation claim_pid <<EOF
|
|
334
|
+
$claim_record
|
|
335
|
+
EOF
|
|
336
|
+
if [ "$claim_generation" = "$generation" ]; then
|
|
337
|
+
case "$claim_pid" in
|
|
338
|
+
''|*[!0-9]*) ;;
|
|
339
|
+
*) kill -0 "$claim_pid" 2>/dev/null && claim_live=1 ;;
|
|
340
|
+
esac
|
|
341
|
+
fi
|
|
342
|
+
[ "$claim_live" -eq 1 ] || rm -f "$CLAIM_FILE" 2>/dev/null || true
|
|
343
|
+
fi
|
|
344
|
+
if [ "$claim_live" -eq 0 ]; then
|
|
345
|
+
if report_requires_wake "$state"; then
|
|
346
|
+
fm_wake_append check startup-network \
|
|
347
|
+
"check: startup-network: deferred startup network checks finished ($state); read them with $FM_ROOT/bin/fm-startup-network.sh report" \
|
|
348
|
+
|| true
|
|
349
|
+
fi
|
|
350
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
351
|
+
return 0
|
|
352
|
+
fi
|
|
353
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
354
|
+
sleep 0.1
|
|
355
|
+
waited=$((waited + 1))
|
|
356
|
+
done
|
|
357
|
+
fm_lock_acquire_wait "$PUBLISH_LOCK"
|
|
358
|
+
if [ "$(status_get generation)" != "$generation" ] || [ -f "$DELIVERED_FILE" ]; then
|
|
359
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
360
|
+
return 0
|
|
361
|
+
fi
|
|
362
|
+
if report_requires_wake "$state"; then
|
|
363
|
+
fm_wake_append check startup-network \
|
|
364
|
+
"check: startup-network: deferred startup network checks finished ($state); read them with $FM_ROOT/bin/fm-startup-network.sh report" \
|
|
365
|
+
|| true
|
|
366
|
+
fi
|
|
367
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
publish() { # <generation> <state> <phases> <locked> <started> <rc> <output-file> <timing-file>
|
|
371
|
+
local generation=$1 state=$2 phases=$3 locked=$4 started=$5 rc=$6 out=$7 timings=${8:-} report_published=1
|
|
372
|
+
fm_lock_acquire_wait "$PUBLISH_LOCK"
|
|
373
|
+
if [ "$(status_get generation)" != "$generation" ]; then
|
|
374
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
375
|
+
return 0
|
|
376
|
+
fi
|
|
377
|
+
# Timings are published for EVERY outcome, including timeout and failure: a run
|
|
378
|
+
# that hit the bound is exactly the run whose per-step record is worth having,
|
|
379
|
+
# and whatever the killed sweeps managed to append is a real partial answer.
|
|
380
|
+
# A timing record is diagnostic only, so a failure to publish it is discarded
|
|
381
|
+
# rather than downgrading the run - the report itself is the contract.
|
|
382
|
+
if [ -n "$timings" ] && [ -f "$timings" ]; then
|
|
383
|
+
write_atomic "$TIMINGS_FILE" < "$timings" || true
|
|
384
|
+
fi
|
|
385
|
+
if ! write_atomic "$REPORT_FILE" < "$out"; then
|
|
386
|
+
state=failed
|
|
387
|
+
rc=1
|
|
388
|
+
report_published=0
|
|
389
|
+
fi
|
|
390
|
+
rm -f "$DELIVERED_FILE" 2>/dev/null || true
|
|
391
|
+
write_atomic "$STATUS_FILE" <<EOF || true
|
|
392
|
+
state=$state
|
|
393
|
+
pid=$$
|
|
394
|
+
started=$started
|
|
395
|
+
finished=$(now)
|
|
396
|
+
rc=$rc
|
|
397
|
+
locked=$locked
|
|
398
|
+
phases=$phases
|
|
399
|
+
generation=$generation
|
|
400
|
+
lock_pid=$(status_get lock_pid)
|
|
401
|
+
report_published=$report_published
|
|
402
|
+
EOF
|
|
403
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
404
|
+
await_delivery "$generation" "$state"
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
cmd_run() { # <locked> <lock-pid> <generation>
|
|
408
|
+
local locked=$1 lock_pid=$2 generation=$3 phases started budget out rc sweep_locked=0 downgraded=0 internal=0 lease_held=0 timings stage_started
|
|
409
|
+
mkdir -p "$STATE" 2>/dev/null || return 1
|
|
410
|
+
started=$(now)
|
|
411
|
+
budget=$(stage_budget)
|
|
412
|
+
phases=probe
|
|
413
|
+
if [ -n "$generation" ]; then
|
|
414
|
+
fm_lock_acquire_wait "$PUBLISH_LOCK"
|
|
415
|
+
if [ "$(status_get generation)" = "$generation" ] && [ "$(status_get pid)" = "$$" ]; then
|
|
416
|
+
internal=1
|
|
417
|
+
started=$(status_get started)
|
|
418
|
+
fi
|
|
419
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
420
|
+
[ "$internal" -eq 1 ] || return 1
|
|
421
|
+
elif [ "$locked" = 1 ] && ! fm_session_lock_owned_by_self "$STATE"; then
|
|
422
|
+
downgraded=1
|
|
423
|
+
locked=0
|
|
424
|
+
fi
|
|
425
|
+
if [ "$locked" = 1 ]; then
|
|
426
|
+
[ "$internal" -eq 1 ] || lock_pid=$(cat "$STATE/.lock" 2>/dev/null || true)
|
|
427
|
+
if lock_unchanged "$lock_pid"; then
|
|
428
|
+
sweep_locked=1
|
|
429
|
+
phases=probe,sweeps
|
|
430
|
+
else
|
|
431
|
+
downgraded=1
|
|
432
|
+
fi
|
|
433
|
+
fi
|
|
434
|
+
|
|
435
|
+
if [ "$internal" -eq 0 ]; then
|
|
436
|
+
generation="$(now).$$.manual"
|
|
437
|
+
fm_lock_acquire_wait "$PUBLISH_LOCK"
|
|
438
|
+
if [ "$(status_get state)" = running ] && worker_alive; then
|
|
439
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
440
|
+
return 1
|
|
441
|
+
fi
|
|
442
|
+
write_atomic "$STATUS_FILE" <<EOF || true
|
|
443
|
+
state=running
|
|
444
|
+
pid=$$
|
|
445
|
+
started=$started
|
|
446
|
+
locked=$sweep_locked
|
|
447
|
+
phases=$phases
|
|
448
|
+
generation=$generation
|
|
449
|
+
lock_pid=$lock_pid
|
|
450
|
+
EOF
|
|
451
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
452
|
+
fi
|
|
453
|
+
|
|
454
|
+
out=$(mktemp "${TMPDIR:-/tmp}/fm-startup-network.XXXXXX" 2>/dev/null) || return 1
|
|
455
|
+
# Recorded into a temp file rather than straight into state/ so a run that is
|
|
456
|
+
# killed mid-sweep cannot leave a half-written artifact where the previous
|
|
457
|
+
# run's complete one used to be; publish() promotes it atomically at the end.
|
|
458
|
+
# Sweeps run in child processes (bin/fm-bootstrap.sh, and bin/fm-fleet-sync.sh
|
|
459
|
+
# below it), so FM_TIMING_LOG is exported and appended to by all of them.
|
|
460
|
+
timings=$(mktemp "${TMPDIR:-/tmp}/fm-startup-network-timings.XXXXXX" 2>/dev/null) || timings=
|
|
461
|
+
[ -z "$timings" ] || fm_timing_start "$timings"
|
|
462
|
+
stage_started=$(fm_timing_now_ms)
|
|
463
|
+
rc=0
|
|
464
|
+
if [ "$sweep_locked" -eq 1 ]; then
|
|
465
|
+
fm_lock_acquire_wait "$STATE/.lock.acquire"
|
|
466
|
+
lease_held=1
|
|
467
|
+
if ! lock_unchanged "$lock_pid"; then
|
|
468
|
+
sweep_locked=0
|
|
469
|
+
phases=probe
|
|
470
|
+
downgraded=1
|
|
471
|
+
fi
|
|
472
|
+
fi
|
|
473
|
+
if [ "$sweep_locked" -eq 1 ]; then
|
|
474
|
+
fm_run_timed "$budget" env FM_BOOTSTRAP_NETWORK=only \
|
|
475
|
+
FM_BOOTSTRAP_NETWORK_LOCK_PID="$lock_pid" \
|
|
476
|
+
"$SCRIPT_DIR/fm-bootstrap.sh" >"$out" 2>&1 || rc=$?
|
|
477
|
+
else
|
|
478
|
+
fm_run_timed "$budget" env FM_BOOTSTRAP_NETWORK=only FM_BOOTSTRAP_DETECT_ONLY=1 \
|
|
479
|
+
"$SCRIPT_DIR/fm-bootstrap.sh" >"$out" 2>&1 || rc=$?
|
|
480
|
+
fi
|
|
481
|
+
[ "$lease_held" -eq 0 ] || fm_lock_release "$STATE/.lock.acquire"
|
|
482
|
+
# The bounded run as a whole, so the per-phase records can be read against the
|
|
483
|
+
# total even when the bound cut some of them off.
|
|
484
|
+
fm_timing_record stage network-checks "$stage_started" "$phases"
|
|
485
|
+
|
|
486
|
+
if [ "$downgraded" -eq 1 ]; then
|
|
487
|
+
printf 'NETWORK_CHECKS: the fleet lock was no longer held by the session that requested these, so dead-secondmate relaunch, secondmate convergence, pending handoff delivery, and project clone refresh were skipped; they belong to whichever session holds the lock now\n' >> "$out"
|
|
488
|
+
fi
|
|
489
|
+
case "$rc" in
|
|
490
|
+
0) publish "$generation" 'done' "$phases" "$sweep_locked" "$started" "$rc" "$out" "$timings" ;;
|
|
491
|
+
124)
|
|
492
|
+
printf 'NETWORK_CHECKS: hit the %ss bound before finishing, so %s may be incomplete; rerun %s/bin/fm-startup-network.sh run --locked %s\n' \
|
|
493
|
+
"$budget" "$(phase_label "$phases")" "$FM_ROOT" "$sweep_locked" >> "$out"
|
|
494
|
+
publish "$generation" timeout "$phases" "$sweep_locked" "$started" "$rc" "$out" "$timings"
|
|
495
|
+
;;
|
|
496
|
+
*)
|
|
497
|
+
printf 'NETWORK_CHECKS: the deferred check worker exited %s, so %s may be incomplete; rerun %s/bin/fm-startup-network.sh run --locked %s\n' \
|
|
498
|
+
"$rc" "$(phase_label "$phases")" "$FM_ROOT" "$sweep_locked" >> "$out"
|
|
499
|
+
publish "$generation" failed "$phases" "$sweep_locked" "$started" "$rc" "$out" "$timings"
|
|
500
|
+
;;
|
|
501
|
+
esac
|
|
502
|
+
rm -f "$out" 2>/dev/null || true
|
|
503
|
+
[ -z "$timings" ] || rm -f "$timings" 2>/dev/null || true
|
|
504
|
+
return 0
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
# --- harvest / report --------------------------------------------------------
|
|
508
|
+
|
|
509
|
+
print_finished() { # <state>
|
|
510
|
+
local state=$1 phases started finished took=unknown report_published
|
|
511
|
+
phases=$(status_get phases)
|
|
512
|
+
started=$(status_get started)
|
|
513
|
+
finished=$(status_get finished)
|
|
514
|
+
report_published=$(status_get report_published)
|
|
515
|
+
case "$started$finished" in
|
|
516
|
+
''|*[!0-9]*) ;;
|
|
517
|
+
*) took=$((finished - started)) ;;
|
|
518
|
+
esac
|
|
519
|
+
printf 'completed off the startup path in %ss: %s.\n' "$took" "$(phase_label "$phases")"
|
|
520
|
+
[ "$state" = 'done' ] || printf 'The stage itself did not finish cleanly (%s) - the NETWORK_CHECKS line below names what to rerun.\n' "$state"
|
|
521
|
+
if [ "$report_published" = 0 ]; then
|
|
522
|
+
printf 'NETWORK_CHECKS: could not publish the deferred check report, so %s results are unavailable; rerun %s/bin/fm-startup-network.sh run --locked %s\n' \
|
|
523
|
+
"$(phase_label "$phases")" "$FM_ROOT" "$(status_get locked)"
|
|
524
|
+
elif [ -s "$REPORT_FILE" ]; then
|
|
525
|
+
cat "$REPORT_FILE"
|
|
526
|
+
printf 'These ran AFTER the sections above were composed, so re-read any record a line here names.\n'
|
|
527
|
+
else
|
|
528
|
+
printf '(silent - no problems found)\n'
|
|
529
|
+
fi
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
# Deliberately NOT part of print_state, and so deliberately not part of harvest:
|
|
533
|
+
# harvest composes the digest's NETWORK CHECKS section, and this record is
|
|
534
|
+
# diagnostic detail nobody needs on an ordinary session start. It is printed only
|
|
535
|
+
# by the on-demand `report` command, so the timings cost a reader nothing until
|
|
536
|
+
# a run is actually slow enough to ask about.
|
|
537
|
+
print_timings() {
|
|
538
|
+
fm_timing_render "$TIMINGS_FILE"
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
print_pending() {
|
|
542
|
+
local phases started age
|
|
543
|
+
phases=$(status_get phases)
|
|
544
|
+
started=$(status_get started)
|
|
545
|
+
age=$(age_of "$started")
|
|
546
|
+
printf 'IN PROGRESS - the deferred network checks have not finished yet.\n'
|
|
547
|
+
printf 'NOT yet confirmed: %s.\n' "$(phase_label "$phases")"
|
|
548
|
+
[ -z "$age" ] || printf 'Started %ss ago, bounded at %ss.\n' "$age" "$(stage_budget)"
|
|
549
|
+
# shellcheck disable=SC2016 # The backticked wake name is literal digest text.
|
|
550
|
+
printf 'Only a FAILED or otherwise actionable result arrives as a `check: startup-network` wake; a clean success stays silent.\n'
|
|
551
|
+
printf 'The durable result is readable on demand with %s/bin/fm-startup-network.sh report; until it finishes, treat none of it as confirmed.\n' "$FM_ROOT"
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
print_state() {
|
|
555
|
+
case "$(status_get state)" in
|
|
556
|
+
done|timeout|failed) print_finished "$(status_get state)" ;;
|
|
557
|
+
running)
|
|
558
|
+
if worker_alive; then
|
|
559
|
+
print_pending
|
|
560
|
+
else
|
|
561
|
+
printf 'NETWORK_CHECKS: the deferred check worker stopped before publishing, so %s did not complete; rerun %s/bin/fm-startup-network.sh run --locked %s\n' \
|
|
562
|
+
"$(phase_label "$(status_get phases)")" "$FM_ROOT" "$(status_get locked)"
|
|
563
|
+
fi
|
|
564
|
+
;;
|
|
565
|
+
*) printf 'not started - no deferred network checks have run for this home yet.\n' ;;
|
|
566
|
+
esac
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
cmd_harvest() { # <pid>
|
|
570
|
+
local pid=$1 generation state claim_record claim_generation claim_pid
|
|
571
|
+
fm_lock_acquire_wait "$PUBLISH_LOCK"
|
|
572
|
+
generation=$(status_get generation)
|
|
573
|
+
# Another session's live claim is left alone; the worker reaps a dead one.
|
|
574
|
+
if [ -f "$CLAIM_FILE" ]; then
|
|
575
|
+
claim_record=$(cat "$CLAIM_FILE" 2>/dev/null || true)
|
|
576
|
+
IFS=$'\t' read -r claim_generation claim_pid <<EOF
|
|
577
|
+
$claim_record
|
|
578
|
+
EOF
|
|
579
|
+
if [ "$claim_generation" = "$generation" ] \
|
|
580
|
+
&& { [ -z "$pid" ] || [ "$claim_pid" = "$pid" ]; }; then
|
|
581
|
+
rm -f "$CLAIM_FILE" 2>/dev/null || true
|
|
582
|
+
fi
|
|
583
|
+
fi
|
|
584
|
+
state=$(status_get state)
|
|
585
|
+
print_state
|
|
586
|
+
case "$state" in
|
|
587
|
+
done|timeout|failed) [ "$(status_get report_published)" = 0 ] || write_atomic "$DELIVERED_FILE" <<EOF || true
|
|
588
|
+
delivered
|
|
589
|
+
EOF
|
|
590
|
+
;;
|
|
591
|
+
esac
|
|
592
|
+
fm_lock_release "$PUBLISH_LOCK"
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
cmd_wait() { # <seconds>
|
|
596
|
+
local limit=$1 waited=0
|
|
597
|
+
case "$limit" in ''|*[!0-9]*) limit=120 ;; esac
|
|
598
|
+
while [ "$waited" -lt "$limit" ]; do
|
|
599
|
+
case "$(status_get state)" in
|
|
600
|
+
done|timeout|failed) return 0 ;;
|
|
601
|
+
running) worker_alive || return 1 ;;
|
|
602
|
+
esac
|
|
603
|
+
sleep 1
|
|
604
|
+
waited=$((waited + 1))
|
|
605
|
+
done
|
|
606
|
+
return 1
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
# --- entry -------------------------------------------------------------------
|
|
610
|
+
|
|
611
|
+
LOCKED=0
|
|
612
|
+
HARVEST_PID=
|
|
613
|
+
LOCK_PID=
|
|
614
|
+
GENERATION=
|
|
615
|
+
MODE=${1:-}
|
|
616
|
+
[ $# -eq 0 ] || shift
|
|
617
|
+
while [ $# -gt 0 ]; do
|
|
618
|
+
case "$1" in
|
|
619
|
+
--locked) LOCKED=${2:-0}; shift; [ $# -eq 0 ] || shift ;;
|
|
620
|
+
--harvest-pid|--pid) HARVEST_PID=${2:-}; shift; [ $# -eq 0 ] || shift ;;
|
|
621
|
+
--lock-pid) LOCK_PID=${2:-}; shift; [ $# -eq 0 ] || shift ;;
|
|
622
|
+
--generation) GENERATION=${2:-}; shift; [ $# -eq 0 ] || shift ;;
|
|
623
|
+
-h|--help) usage; exit 0 ;;
|
|
624
|
+
*) break ;;
|
|
625
|
+
esac
|
|
626
|
+
done
|
|
627
|
+
case "$LOCKED" in 0|1) ;; *) LOCKED=0 ;; esac
|
|
628
|
+
|
|
629
|
+
case "$MODE" in
|
|
630
|
+
start) cmd_start "$LOCKED" "${HARVEST_PID:-0}" ;;
|
|
631
|
+
run) cmd_run "$LOCKED" "$LOCK_PID" "$GENERATION" ;;
|
|
632
|
+
harvest) cmd_harvest "${HARVEST_PID:-}" ;;
|
|
633
|
+
report) print_state; print_timings ;;
|
|
634
|
+
wait) cmd_wait "${1:-120}" || exit $? ;;
|
|
635
|
+
-h|--help) usage ;;
|
|
636
|
+
*)
|
|
637
|
+
printf 'fm-startup-network: unknown mode: %s\n' "${MODE:-<none>}" >&2
|
|
638
|
+
printf 'usage: fm-startup-network.sh start|run|harvest|report|wait\n' >&2
|
|
639
|
+
exit 2
|
|
640
|
+
;;
|
|
641
|
+
esac
|
|
642
|
+
exit 0
|