@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,721 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavior tests for fm-fleet-sync.sh drift handling.
|
|
3
|
+
#
|
|
4
|
+
# fm-fleet-sync fast-forwards a clone that is cleanly on its default branch. This
|
|
5
|
+
# suite pins the two behavioral additions on top of that:
|
|
6
|
+
# - the one safe drift self-heals: a clean, detached HEAD that holds no unique
|
|
7
|
+
# commits (it is an ancestor of origin/<default>) and whose <default> is free
|
|
8
|
+
# to check out is re-attached and then fast-forwarded ("recovered:").
|
|
9
|
+
# - every other off-default state is left untouched and reported as a loud,
|
|
10
|
+
# quantified "STUCK: ... N commits behind ... - needs attention" warning
|
|
11
|
+
# instead of a quiet skip.
|
|
12
|
+
# The pre-existing fast-forward / already-current / local-only / no-origin paths
|
|
13
|
+
# must be unchanged, and bootstrap must relay the new outcomes as FLEET_SYNC lines.
|
|
14
|
+
#
|
|
15
|
+
# It also pins the clone-root guard: a plain directory under projects/ resolves,
|
|
16
|
+
# through git's upward repository discovery, to the ENCLOSING repository - in a
|
|
17
|
+
# firstmate home, the firstmate checkout itself - so it must be skipped by name
|
|
18
|
+
# with the enclosing repo left untouched, in both the whole-fleet and
|
|
19
|
+
# single-project forms, while a symlinked clone dir still syncs.
|
|
20
|
+
#
|
|
21
|
+
# It also pins the orphaned .git/packed-refs.lock recovery in the fetch step
|
|
22
|
+
# (fetch_with_packed_refs_lock_guard, backed by bin/fm-lock-lib.sh's shared
|
|
23
|
+
# staleness proof): a provably-stale lock is retried then removed and the clone
|
|
24
|
+
# syncs (with a "recovered:" summary on stdout so a session-start refresh, which
|
|
25
|
+
# discards stderr, still surfaces it); a live lock (fake lsof holder) is never
|
|
26
|
+
# removed and the sync fails loudly; a live process merely holding the clone
|
|
27
|
+
# worktree dir as its cwd also blocks removal (the clone-dir liveness check); a
|
|
28
|
+
# transient lock that self-clears is retried without a force-remove; and any
|
|
29
|
+
# non-packed-refs.lock fetch failure keeps today's behavior with no retry.
|
|
30
|
+
set -u
|
|
31
|
+
|
|
32
|
+
# shellcheck source=tests/lib.sh
|
|
33
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
34
|
+
|
|
35
|
+
fm_git_identity fmtest fmtest@example.invalid
|
|
36
|
+
|
|
37
|
+
TMP_ROOT=$(fm_test_tmproot fm-fleet-sync-tests)
|
|
38
|
+
HOME_N=0
|
|
39
|
+
|
|
40
|
+
# --- fixtures ---------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
# new_home: fresh isolated FM_HOME with an empty projects/ dir. Each test gets its
|
|
43
|
+
# own so the whole-fleet form never sees another test's clones.
|
|
44
|
+
new_home() {
|
|
45
|
+
HOME_N=$((HOME_N + 1))
|
|
46
|
+
local h="$TMP_ROOT/home-$HOME_N"
|
|
47
|
+
mkdir -p "$h/projects"
|
|
48
|
+
printf '%s\n' "$h"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
commit_file() {
|
|
52
|
+
local dir=$1 file=$2 content=$3 msg=$4
|
|
53
|
+
printf '%s\n' "$content" > "$dir/$file"
|
|
54
|
+
git -C "$dir" add "$file"
|
|
55
|
+
git -C "$dir" commit -qm "$msg"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# build_pair <home> <name>: create projects/<name>, a clone of a fresh bare origin
|
|
59
|
+
# with one commit on main, plus a side "work-<name>" repo wired to that origin for
|
|
60
|
+
# advancing it later. Portable branch naming (no init -b) for older git.
|
|
61
|
+
build_pair() {
|
|
62
|
+
local home=$1 name=$2 work remote clone remote_abs
|
|
63
|
+
work="$home/work-$name"
|
|
64
|
+
remote="$home/remotes/$name.git"
|
|
65
|
+
clone="$home/projects/$name"
|
|
66
|
+
mkdir -p "$home/remotes"
|
|
67
|
+
|
|
68
|
+
git init -q "$work"
|
|
69
|
+
git -C "$work" symbolic-ref HEAD refs/heads/main
|
|
70
|
+
commit_file "$work" file.txt v0 C0
|
|
71
|
+
|
|
72
|
+
git clone --quiet --bare "$work" "$remote"
|
|
73
|
+
remote_abs=$(cd "$remote" && pwd)
|
|
74
|
+
git -C "$work" remote add origin "file://$remote_abs"
|
|
75
|
+
git -C "$work" push -q -u origin main
|
|
76
|
+
|
|
77
|
+
git clone --quiet "file://$remote_abs" "$clone"
|
|
78
|
+
printf '%s\n' "$clone"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# advance_origin <home> <name> <msg>: push one more commit to <name>'s origin via
|
|
82
|
+
# its work repo, so the clone (until it fetches) is one commit behind origin/main.
|
|
83
|
+
advance_origin() {
|
|
84
|
+
local home=$1 name=$2 msg=$3 work
|
|
85
|
+
work="$home/work-$name"
|
|
86
|
+
commit_file "$work" file.txt "$msg" "$msg"
|
|
87
|
+
git -C "$work" push -q origin main
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
head_sha() { git -C "$1" rev-parse HEAD; }
|
|
91
|
+
|
|
92
|
+
# run_sync <home> [args...]: run fleet-sync against an isolated home, stdout only.
|
|
93
|
+
run_sync() {
|
|
94
|
+
local home=$1
|
|
95
|
+
shift
|
|
96
|
+
FM_HOME="$home" FM_ROOT_OVERRIDE="$ROOT" "$ROOT/bin/fm-fleet-sync.sh" "$@" 2>/dev/null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# build_enclosing_home <name>: an FM_HOME that is itself nested inside another git
|
|
100
|
+
# repository - firstmate's own layout, where projects/ sits inside the firstmate
|
|
101
|
+
# checkout. The enclosing repo is a clean clone of a bare origin that is one commit
|
|
102
|
+
# ahead, so a sync that walked git discovery UP out of projects/<dir> would find a
|
|
103
|
+
# fast-forward available and visibly take it. Echoes the enclosing repo, which is
|
|
104
|
+
# also the home. Its work tree is left pristine so the only thing under projects/
|
|
105
|
+
# is what the test puts there.
|
|
106
|
+
build_enclosing_home() {
|
|
107
|
+
local name=$1 root work remote enclosing remote_abs
|
|
108
|
+
root="$TMP_ROOT/enclosing-$name"
|
|
109
|
+
work="$root/work"
|
|
110
|
+
remote="$root/remote.git"
|
|
111
|
+
enclosing="$root/enclosing"
|
|
112
|
+
mkdir -p "$root"
|
|
113
|
+
|
|
114
|
+
git init -q "$work"
|
|
115
|
+
git -C "$work" symbolic-ref HEAD refs/heads/main
|
|
116
|
+
printf '/projects/\n' > "$work/.gitignore"
|
|
117
|
+
git -C "$work" add .gitignore
|
|
118
|
+
commit_file "$work" AGENTS.md v0 C0
|
|
119
|
+
|
|
120
|
+
git clone --quiet --bare "$work" "$remote"
|
|
121
|
+
remote_abs=$(cd "$remote" && pwd)
|
|
122
|
+
git -C "$work" remote add origin "file://$remote_abs"
|
|
123
|
+
git -C "$work" push -q -u origin main
|
|
124
|
+
|
|
125
|
+
git clone --quiet "file://$remote_abs" "$enclosing"
|
|
126
|
+
commit_file "$work" AGENTS.md v1 C1
|
|
127
|
+
git -C "$work" push -q origin main
|
|
128
|
+
|
|
129
|
+
mkdir -p "$enclosing/projects"
|
|
130
|
+
printf '%s\n' "$enclosing"
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
# --- packed-refs.lock fixtures ----------------------------------------------
|
|
134
|
+
|
|
135
|
+
# build_packed_prunable <home> <name>: like build_pair, but the clone has PACKED
|
|
136
|
+
# refs plus a local `feature` branch tracking a since-deleted origin/feature, so a
|
|
137
|
+
# fetch --prune must rewrite packed-refs - which an orphaned .git/packed-refs.lock
|
|
138
|
+
# blocks with Git's "Unable to create '...packed-refs.lock': File exists". origin/main
|
|
139
|
+
# is advanced by one commit so a successful sync fast-forwards. Echoes the clone path.
|
|
140
|
+
build_packed_prunable() {
|
|
141
|
+
local home=$1 name=$2 work remote clone remote_abs
|
|
142
|
+
work="$home/work-$name"
|
|
143
|
+
remote="$home/remotes/$name.git"
|
|
144
|
+
clone="$home/projects/$name"
|
|
145
|
+
mkdir -p "$home/remotes"
|
|
146
|
+
|
|
147
|
+
git init -q "$work"
|
|
148
|
+
git -C "$work" symbolic-ref HEAD refs/heads/main
|
|
149
|
+
commit_file "$work" file.txt v0 C0
|
|
150
|
+
git clone --quiet --bare "$work" "$remote"
|
|
151
|
+
remote_abs=$(cd "$remote" && pwd)
|
|
152
|
+
git -C "$work" remote add origin "file://$remote_abs"
|
|
153
|
+
git -C "$work" push -q -u origin main
|
|
154
|
+
git -C "$work" push -q origin main:refs/heads/feature
|
|
155
|
+
|
|
156
|
+
git clone --quiet "file://$remote_abs" "$clone"
|
|
157
|
+
git -C "$clone" branch -q feature origin/feature
|
|
158
|
+
commit_file "$work" file.txt v1 C1
|
|
159
|
+
git -C "$work" push -q origin main
|
|
160
|
+
git -C "$work" push -q origin --delete feature
|
|
161
|
+
git -C "$clone" pack-refs --all
|
|
162
|
+
printf '%s\n' "$clone"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
plant_packed_refs_lock() { : > "$1/.git/packed-refs.lock"; }
|
|
166
|
+
|
|
167
|
+
# lsof shims mirror tests/fm-teardown.test.sh: no-holder (provably free), a live
|
|
168
|
+
# holder, and an lsof error. Written into a per-home fakebin/ prepended to PATH.
|
|
169
|
+
lsof_no_holder() {
|
|
170
|
+
cat > "$1/lsof" <<'SH'
|
|
171
|
+
#!/usr/bin/env bash
|
|
172
|
+
exit 1
|
|
173
|
+
SH
|
|
174
|
+
chmod +x "$1/lsof"
|
|
175
|
+
}
|
|
176
|
+
lsof_live_holder() {
|
|
177
|
+
cat > "$1/lsof" <<'SH'
|
|
178
|
+
#!/usr/bin/env bash
|
|
179
|
+
exit 0
|
|
180
|
+
SH
|
|
181
|
+
chmod +x "$1/lsof"
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# lsof shim: a holder ONLY for $FLEET_TEST_LIVE_DIR (a live `git -C <clone>` keeping
|
|
185
|
+
# its cwd there), and no holder of the lock file itself - the exact window the
|
|
186
|
+
# clone-dir liveness check must cover.
|
|
187
|
+
lsof_holds_only_live_dir() {
|
|
188
|
+
cat > "$1/lsof" <<'SH'
|
|
189
|
+
#!/usr/bin/env bash
|
|
190
|
+
target=
|
|
191
|
+
for a in "$@"; do case "$a" in --|-*) ;; *) target=$a ;; esac; done
|
|
192
|
+
[ -n "${FLEET_TEST_LIVE_DIR:-}" ] && [ "$target" = "$FLEET_TEST_LIVE_DIR" ] && exit 0
|
|
193
|
+
exit 1
|
|
194
|
+
SH
|
|
195
|
+
chmod +x "$1/lsof"
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
# git shim: fail the FIRST `fetch` with the packed-refs.lock signature and drop
|
|
199
|
+
# the lock (simulating the dying ref-rewrite finishing), then delegate every
|
|
200
|
+
# later call - including the retried fetch - to the real git so the sync completes.
|
|
201
|
+
git_transient_packed_refs_lock() {
|
|
202
|
+
cat > "$1/git" <<'SH'
|
|
203
|
+
#!/usr/bin/env bash
|
|
204
|
+
real=${REAL_GIT_FOR_TEST:?}
|
|
205
|
+
dir=; is_fetch=0
|
|
206
|
+
for a in "$@"; do [ "$a" = fetch ] && is_fetch=1; done
|
|
207
|
+
prev=
|
|
208
|
+
for a in "$@"; do [ "$prev" = -C ] && dir=$a; prev=$a; done
|
|
209
|
+
if [ "$is_fetch" = 1 ]; then
|
|
210
|
+
n=$(cat "${GIT_FETCH_COUNTER:?}" 2>/dev/null || echo 0); n=$(( n + 1 ))
|
|
211
|
+
printf '%s\n' "$n" > "$GIT_FETCH_COUNTER"
|
|
212
|
+
if [ "$n" -eq 1 ]; then
|
|
213
|
+
lock="$dir/.git/packed-refs.lock"
|
|
214
|
+
echo "error: could not delete reference refs/remotes/origin/feature: Unable to create '$lock': File exists." >&2
|
|
215
|
+
rm -f "$lock"
|
|
216
|
+
exit 1
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
exec "$real" "$@"
|
|
220
|
+
SH
|
|
221
|
+
chmod +x "$1/git"
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
# run_sync_guarded <home> <fakebin> <outfile> <errfile> [args...]: run fleet-sync
|
|
225
|
+
# with the fakebin on PATH and stdout/stderr captured separately. Per-test knobs
|
|
226
|
+
# (FM_FLEET_SYNC_PACKED_REFS_LOCK_*, GIT_FETCH_COUNTER) are read from the caller's
|
|
227
|
+
# exported environment.
|
|
228
|
+
run_sync_guarded() {
|
|
229
|
+
local home=$1 fakebin=$2 outf=$3 errf=$4 realgit
|
|
230
|
+
shift 4
|
|
231
|
+
realgit=$(command -v git)
|
|
232
|
+
PATH="$fakebin:$PATH" REAL_GIT_FOR_TEST="$realgit" \
|
|
233
|
+
FM_HOME="$home" FM_ROOT_OVERRIDE="$ROOT" \
|
|
234
|
+
"$ROOT/bin/fm-fleet-sync.sh" "$@" >"$outf" 2>"$errf"
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
# --- tests ------------------------------------------------------------------
|
|
238
|
+
|
|
239
|
+
test_detached_clean_ancestor_recovers() {
|
|
240
|
+
local home clone out before after
|
|
241
|
+
home=$(new_home)
|
|
242
|
+
clone=$(build_pair "$home" alpha)
|
|
243
|
+
advance_origin "$home" alpha C1
|
|
244
|
+
before=$(head_sha "$clone")
|
|
245
|
+
# Detach at the clone's main (C0), an ancestor of the now-advanced origin/main.
|
|
246
|
+
git -C "$clone" checkout --detach --quiet
|
|
247
|
+
|
|
248
|
+
out=$(run_sync "$home" "$clone")
|
|
249
|
+
|
|
250
|
+
assert_contains "$out" "alpha: recovered: re-attached main, synced" "detached-clean-ancestor reports recovered"
|
|
251
|
+
assert_not_contains "$out" "STUCK" "recovered case is not flagged STUCK"
|
|
252
|
+
[ "$(git -C "$clone" symbolic-ref --short HEAD 2>/dev/null)" = "main" ] \
|
|
253
|
+
|| fail "expected re-attach to main, HEAD still detached"
|
|
254
|
+
after=$(head_sha "$clone")
|
|
255
|
+
[ "$after" != "$before" ] || fail "expected fast-forward after re-attach, HEAD unchanged"
|
|
256
|
+
[ "$after" = "$(git -C "$clone" rev-parse origin/main)" ] \
|
|
257
|
+
|| fail "expected HEAD at origin/main after recovery"
|
|
258
|
+
pass "detached clean ancestor is re-attached and fast-forwarded (recovered)"
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
test_detached_unique_commit_is_stuck_untouched() {
|
|
262
|
+
local home clone out before
|
|
263
|
+
home=$(new_home)
|
|
264
|
+
clone=$(build_pair "$home" beta)
|
|
265
|
+
git -C "$clone" checkout --detach --quiet
|
|
266
|
+
commit_file "$clone" extra.txt unique "local unique work"
|
|
267
|
+
before=$(head_sha "$clone")
|
|
268
|
+
advance_origin "$home" beta C1
|
|
269
|
+
|
|
270
|
+
out=$(run_sync "$home" "$clone")
|
|
271
|
+
|
|
272
|
+
assert_contains "$out" "beta: STUCK:" "detached-with-unique-commit reports STUCK"
|
|
273
|
+
assert_contains "$out" "unique commits" "STUCK names the unique-commit state"
|
|
274
|
+
assert_contains "$out" "commits behind origin/main - needs attention" "STUCK is quantified"
|
|
275
|
+
assert_not_contains "$out" "recovered" "unique-commit case is never recovered"
|
|
276
|
+
[ "$(head_sha "$clone")" = "$before" ] || fail "expected unique-commit detached HEAD left untouched"
|
|
277
|
+
pass "detached HEAD with unique commits is reported STUCK and left untouched"
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
test_detached_clean_ancestor_with_diverged_local_default_is_stuck_untouched() {
|
|
281
|
+
local home clone out before local_main
|
|
282
|
+
home=$(new_home)
|
|
283
|
+
clone=$(build_pair "$home" beta-local-default)
|
|
284
|
+
commit_file "$clone" local.txt local "local divergent main commit"
|
|
285
|
+
local_main=$(git -C "$clone" rev-parse main)
|
|
286
|
+
git -C "$clone" checkout --detach --quiet HEAD^
|
|
287
|
+
before=$(head_sha "$clone")
|
|
288
|
+
advance_origin "$home" beta-local-default C1
|
|
289
|
+
|
|
290
|
+
out=$(run_sync "$home" "$clone")
|
|
291
|
+
|
|
292
|
+
assert_contains "$out" "beta-local-default: STUCK:" "diverged local default reports STUCK"
|
|
293
|
+
assert_contains "$out" "local main diverged from origin/main" "STUCK names the unsafe local default"
|
|
294
|
+
assert_not_contains "$out" "recovered" "diverged local default is never recovered"
|
|
295
|
+
[ "$(head_sha "$clone")" = "$before" ] || fail "detached HEAD was moved"
|
|
296
|
+
! git -C "$clone" symbolic-ref -q HEAD >/dev/null || fail "clone re-attached to local default"
|
|
297
|
+
[ "$(git -C "$clone" rev-parse main)" = "$local_main" ] || fail "local default branch was moved"
|
|
298
|
+
pass "detached clean ancestor with diverged local default is reported STUCK and left untouched"
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
test_dirty_is_stuck_untouched() {
|
|
302
|
+
local home clone out before
|
|
303
|
+
home=$(new_home)
|
|
304
|
+
clone=$(build_pair "$home" gamma)
|
|
305
|
+
advance_origin "$home" gamma C1
|
|
306
|
+
before=$(head_sha "$clone")
|
|
307
|
+
printf 'uncommitted edit\n' >> "$clone/file.txt"
|
|
308
|
+
|
|
309
|
+
out=$(run_sync "$home" "$clone")
|
|
310
|
+
|
|
311
|
+
assert_contains "$out" "gamma: STUCK:" "dirty clone reports STUCK"
|
|
312
|
+
assert_contains "$out" "uncommitted changes" "STUCK names the dirty state"
|
|
313
|
+
assert_contains "$out" "1 commits behind origin/main" "STUCK quantifies how far behind"
|
|
314
|
+
[ "$(head_sha "$clone")" = "$before" ] || fail "dirty clone HEAD was moved"
|
|
315
|
+
grep -q "uncommitted edit" "$clone/file.txt" || fail "dirty working-tree change was discarded"
|
|
316
|
+
pass "dirty working tree is reported STUCK and left untouched"
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
test_non_default_branch_is_stuck_untouched() {
|
|
320
|
+
local home clone out
|
|
321
|
+
home=$(new_home)
|
|
322
|
+
clone=$(build_pair "$home" delta)
|
|
323
|
+
git -C "$clone" checkout -q -b feature
|
|
324
|
+
advance_origin "$home" delta C1
|
|
325
|
+
|
|
326
|
+
out=$(run_sync "$home" "$clone")
|
|
327
|
+
|
|
328
|
+
assert_contains "$out" "delta: STUCK: on branch feature" "non-default branch reports STUCK with branch name"
|
|
329
|
+
assert_contains "$out" "commits behind origin/main - needs attention" "STUCK is quantified"
|
|
330
|
+
assert_not_contains "$out" "recovered" "named branch is never auto-changed"
|
|
331
|
+
[ "$(git -C "$clone" symbolic-ref --short HEAD)" = "feature" ] || fail "named branch checkout was changed"
|
|
332
|
+
pass "non-default named branch is reported STUCK and left untouched"
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
test_diverged_is_stuck_untouched() {
|
|
336
|
+
local home clone out before
|
|
337
|
+
home=$(new_home)
|
|
338
|
+
clone=$(build_pair "$home" epsilon)
|
|
339
|
+
# Local main gains its own commit; origin advances down a different line.
|
|
340
|
+
commit_file "$clone" local.txt local "local divergent commit"
|
|
341
|
+
before=$(head_sha "$clone")
|
|
342
|
+
advance_origin "$home" epsilon C1
|
|
343
|
+
|
|
344
|
+
out=$(run_sync "$home" "$clone")
|
|
345
|
+
|
|
346
|
+
assert_contains "$out" "epsilon: STUCK:" "diverged clone reports STUCK"
|
|
347
|
+
assert_contains "$out" "diverged main" "STUCK names the diverged state"
|
|
348
|
+
assert_contains "$out" "commits behind origin/main - needs attention" "STUCK is quantified"
|
|
349
|
+
[ "$(head_sha "$clone")" = "$before" ] || fail "diverged clone was moved"
|
|
350
|
+
pass "diverged default branch is reported STUCK and left untouched"
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
test_on_default_clean_behind_fast_forwards() {
|
|
354
|
+
local home clone out
|
|
355
|
+
home=$(new_home)
|
|
356
|
+
clone=$(build_pair "$home" zeta)
|
|
357
|
+
advance_origin "$home" zeta C1
|
|
358
|
+
|
|
359
|
+
out=$(run_sync "$home" "$clone")
|
|
360
|
+
|
|
361
|
+
assert_contains "$out" "zeta: synced" "on-default clean behind fast-forwards as before"
|
|
362
|
+
assert_not_contains "$out" "recovered" "ordinary fast-forward is not labelled recovered"
|
|
363
|
+
assert_not_contains "$out" "STUCK" "ordinary fast-forward is not flagged STUCK"
|
|
364
|
+
[ "$(head_sha "$clone")" = "$(git -C "$clone" rev-parse origin/main)" ] || fail "clone was not fast-forwarded"
|
|
365
|
+
pass "on-default clean behind clone still fast-forwards"
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
test_already_current_unchanged() {
|
|
369
|
+
local home clone out before
|
|
370
|
+
home=$(new_home)
|
|
371
|
+
clone=$(build_pair "$home" eta)
|
|
372
|
+
before=$(head_sha "$clone")
|
|
373
|
+
|
|
374
|
+
out=$(run_sync "$home" "$clone")
|
|
375
|
+
|
|
376
|
+
assert_contains "$out" "eta: already current" "already-current clone reports unchanged"
|
|
377
|
+
assert_not_contains "$out" "STUCK" "already-current is not flagged STUCK"
|
|
378
|
+
assert_not_contains "$out" "recovered" "already-current is not labelled recovered"
|
|
379
|
+
[ "$(head_sha "$clone")" = "$before" ] || fail "already-current clone was moved"
|
|
380
|
+
pass "already-current clone is reported unchanged"
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
test_no_origin_skipped() {
|
|
384
|
+
local home clone out
|
|
385
|
+
home=$(new_home)
|
|
386
|
+
clone="$home/projects/theta"
|
|
387
|
+
git init -q "$clone"
|
|
388
|
+
git -C "$clone" symbolic-ref HEAD refs/heads/main
|
|
389
|
+
commit_file "$clone" file.txt v0 C0
|
|
390
|
+
|
|
391
|
+
out=$(run_sync "$home" "$clone")
|
|
392
|
+
|
|
393
|
+
assert_contains "$out" "theta: skipped: no origin remote" "no-origin clone is skipped as before"
|
|
394
|
+
assert_not_contains "$out" "STUCK" "no-origin skip is not escalated to STUCK"
|
|
395
|
+
pass "no-origin clone is skipped (benign), not flagged STUCK"
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
test_local_only_skipped() {
|
|
399
|
+
local home clone out
|
|
400
|
+
home=$(new_home)
|
|
401
|
+
clone=$(build_pair "$home" iota)
|
|
402
|
+
advance_origin "$home" iota C1
|
|
403
|
+
mkdir -p "$home/data"
|
|
404
|
+
printf -- '- iota [local-only] - test project (added 2026-06-27)\n' > "$home/data/projects.md"
|
|
405
|
+
|
|
406
|
+
out=$(run_sync "$home" "$clone")
|
|
407
|
+
|
|
408
|
+
assert_contains "$out" "iota: skipped: local-only project" "local-only clone is skipped as before"
|
|
409
|
+
assert_not_contains "$out" "STUCK" "local-only skip is not escalated to STUCK"
|
|
410
|
+
pass "local-only clone is skipped (benign), not flagged STUCK"
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
test_single_project_by_bare_name_resolves() {
|
|
414
|
+
local home out
|
|
415
|
+
home=$(new_home)
|
|
416
|
+
build_pair "$home" kappa >/dev/null
|
|
417
|
+
advance_origin "$home" kappa C1
|
|
418
|
+
|
|
419
|
+
out=$(run_sync "$home" "kappa")
|
|
420
|
+
|
|
421
|
+
assert_contains "$out" "kappa: synced" "bare project name resolves against the home's projects dir"
|
|
422
|
+
pass "single-project form accepts a bare project name"
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
test_single_project_by_bare_name_ignores_cwd_shadow() {
|
|
426
|
+
local home cwd out
|
|
427
|
+
home=$(new_home)
|
|
428
|
+
build_pair "$home" mu >/dev/null
|
|
429
|
+
advance_origin "$home" mu C1
|
|
430
|
+
cwd="$home/shadow"
|
|
431
|
+
mkdir -p "$cwd/mu"
|
|
432
|
+
|
|
433
|
+
out=$(cd "$cwd" && run_sync "$home" "mu")
|
|
434
|
+
|
|
435
|
+
assert_contains "$out" "mu: synced" "bare project name prefers the home's projects dir"
|
|
436
|
+
assert_not_contains "$out" "skipped: not a git repo" "bare project name ignores a cwd shadow directory"
|
|
437
|
+
pass "single-project bare name resolution is not cwd-sensitive"
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
test_single_project_by_projects_relative_name_resolves() {
|
|
441
|
+
local home out
|
|
442
|
+
home=$(new_home)
|
|
443
|
+
build_pair "$home" lambda >/dev/null
|
|
444
|
+
advance_origin "$home" lambda C1
|
|
445
|
+
|
|
446
|
+
out=$(run_sync "$home" "projects/lambda")
|
|
447
|
+
|
|
448
|
+
assert_contains "$out" "lambda: synced" "projects/<name> form resolves against the home's projects dir"
|
|
449
|
+
pass "single-project form accepts a projects/<name> relative name"
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
test_single_project_by_projects_relative_name_ignores_cwd_shadow() {
|
|
453
|
+
local home cwd out
|
|
454
|
+
home=$(new_home)
|
|
455
|
+
build_pair "$home" nu >/dev/null
|
|
456
|
+
advance_origin "$home" nu C1
|
|
457
|
+
cwd="$home/shadow"
|
|
458
|
+
mkdir -p "$cwd/projects/nu"
|
|
459
|
+
|
|
460
|
+
out=$(cd "$cwd" && run_sync "$home" "projects/nu")
|
|
461
|
+
|
|
462
|
+
assert_contains "$out" "nu: synced" "projects/<name> form prefers the home's projects dir"
|
|
463
|
+
assert_not_contains "$out" "skipped: not a git repo" "projects/<name> form ignores a cwd shadow directory"
|
|
464
|
+
pass "single-project projects/<name> resolution is not cwd-sensitive"
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
test_single_project_unresolvable_name_still_skips() {
|
|
468
|
+
local home out
|
|
469
|
+
home=$(new_home)
|
|
470
|
+
|
|
471
|
+
out=$(run_sync "$home" "does-not-exist")
|
|
472
|
+
|
|
473
|
+
assert_contains "$out" "skipped: not a directory" "an unresolvable name still hits the existing not-a-directory skip"
|
|
474
|
+
pass "single-project form leaves a genuinely bad name unresolved"
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
test_whole_fleet_form() {
|
|
478
|
+
local home behind current out
|
|
479
|
+
home=$(new_home)
|
|
480
|
+
behind=$(build_pair "$home" fleet-behind)
|
|
481
|
+
advance_origin "$home" fleet-behind C1
|
|
482
|
+
current=$(build_pair "$home" fleet-current)
|
|
483
|
+
|
|
484
|
+
# Whole-fleet form: no project-dir argument.
|
|
485
|
+
out=$(run_sync "$home")
|
|
486
|
+
|
|
487
|
+
assert_contains "$out" "fleet-behind: synced" "whole-fleet form syncs a behind clone"
|
|
488
|
+
assert_contains "$out" "fleet-current: already current" "whole-fleet form reports a current clone"
|
|
489
|
+
: "$behind $current"
|
|
490
|
+
pass "whole-fleet form processes every clone under projects/"
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
test_bootstrap_relays_recovered_and_stuck() {
|
|
494
|
+
local home stuck rec out
|
|
495
|
+
home=$(new_home)
|
|
496
|
+
# A clone we will leave STUCK (dirty), and one that self-heals (detached-clean-ancestor).
|
|
497
|
+
stuck=$(build_pair "$home" stuck-clone)
|
|
498
|
+
advance_origin "$home" stuck-clone C1
|
|
499
|
+
printf 'dirty\n' >> "$stuck/file.txt"
|
|
500
|
+
rec=$(build_pair "$home" rec-clone)
|
|
501
|
+
advance_origin "$home" rec-clone C1
|
|
502
|
+
git -C "$rec" checkout --detach --quiet
|
|
503
|
+
|
|
504
|
+
# Full bootstrap: no state/ dir -> secondmate sync no-ops; no .env -> X mode off.
|
|
505
|
+
# We only assert the fleet-sync relay lines; other detect lines are irrelevant.
|
|
506
|
+
out=$(FM_HOME="$home" FM_ROOT_OVERRIDE="$ROOT" "$ROOT/bin/fm-bootstrap.sh" 2>/dev/null)
|
|
507
|
+
|
|
508
|
+
assert_contains "$out" "FLEET_SYNC: stuck-clone: STUCK:" "bootstrap relays the STUCK outcome"
|
|
509
|
+
assert_contains "$out" "FLEET_SYNC: rec-clone: recovered:" "bootstrap relays the recovered outcome"
|
|
510
|
+
pass "bootstrap relays recovered: and STUCK: fleet-sync outcomes"
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
# --- packed-refs.lock guard tests -------------------------------------------
|
|
514
|
+
|
|
515
|
+
test_orphaned_stale_packed_refs_lock_recovers() {
|
|
516
|
+
local home fakebin clone out err
|
|
517
|
+
home=$(new_home)
|
|
518
|
+
fakebin="$home/fb-lockstale"; rm -rf "$fakebin"; mkdir -p "$fakebin"
|
|
519
|
+
clone=$(build_packed_prunable "$home" lockstale)
|
|
520
|
+
plant_packed_refs_lock "$clone"
|
|
521
|
+
lsof_no_holder "$fakebin" # provably no live holder
|
|
522
|
+
out="$home/out-lockstale"; err="$home/err-lockstale"
|
|
523
|
+
|
|
524
|
+
set +e
|
|
525
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRIES=2 \
|
|
526
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS=0 \
|
|
527
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS=0 \
|
|
528
|
+
run_sync_guarded "$home" "$fakebin" "$out" "$err" lockstale
|
|
529
|
+
set -e
|
|
530
|
+
|
|
531
|
+
assert_grep "removed provably-stale packed-refs lock" "$err" \
|
|
532
|
+
"stale lock: guard did not force-remove the provably-stale lock"
|
|
533
|
+
assert_grep "fetch succeeded after stale packed-refs lock cleanup" "$err" \
|
|
534
|
+
"stale lock: fetch did not succeed after cleanup"
|
|
535
|
+
assert_contains "$(cat "$out")" "lockstale: synced" "stale lock: clone did not sync after recovery"
|
|
536
|
+
assert_grep "recovered: removed a stale packed-refs lock" "$out" \
|
|
537
|
+
"stale lock: recovery summary not emitted on stdout (bootstrap relays stdout, discards stderr)"
|
|
538
|
+
assert_absent "$clone/.git/packed-refs.lock" "stale lock: lock should be gone after removal"
|
|
539
|
+
[ "$(git -C "$clone" rev-parse HEAD)" = "$(git -C "$clone" rev-parse origin/main)" ] \
|
|
540
|
+
|| fail "stale lock: clone HEAD not at origin/main after recovery"
|
|
541
|
+
pass "orphaned provably-stale packed-refs.lock is cleared and the clone syncs"
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
test_live_packed_refs_lock_is_never_removed() {
|
|
545
|
+
local home fakebin clone out err before
|
|
546
|
+
home=$(new_home)
|
|
547
|
+
fakebin="$home/fb-locklive"; rm -rf "$fakebin"; mkdir -p "$fakebin"
|
|
548
|
+
clone=$(build_packed_prunable "$home" locklive)
|
|
549
|
+
plant_packed_refs_lock "$clone"
|
|
550
|
+
lsof_live_holder "$fakebin" # a live process holds the lock/.git open
|
|
551
|
+
before=$(head_sha "$clone")
|
|
552
|
+
out="$home/out-locklive"; err="$home/err-locklive"
|
|
553
|
+
|
|
554
|
+
set +e
|
|
555
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRIES=2 \
|
|
556
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS=0 \
|
|
557
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS=0 \
|
|
558
|
+
run_sync_guarded "$home" "$fakebin" "$out" "$err" locklive
|
|
559
|
+
set -e
|
|
560
|
+
|
|
561
|
+
assert_grep "is not provably stale" "$err" "live lock: guard did not explain the refusal"
|
|
562
|
+
assert_no_grep "removed provably-stale packed-refs lock" "$err" \
|
|
563
|
+
"live lock: guard force-removed a live lock"
|
|
564
|
+
assert_contains "$(cat "$out")" "locklive: skipped: fetch failed" "live lock: fleet-sync did not skip"
|
|
565
|
+
assert_present "$clone/.git/packed-refs.lock" "live lock: lock must never be removed"
|
|
566
|
+
[ "$(head_sha "$clone")" = "$before" ] || fail "live lock: clone was advanced despite the refusal"
|
|
567
|
+
pass "a live packed-refs.lock is never removed and the sync fails loudly"
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
test_live_git_cwd_in_clone_dir_blocks_removal() {
|
|
571
|
+
local home fakebin clone out err before
|
|
572
|
+
home=$(new_home)
|
|
573
|
+
fakebin="$home/fb-lockcwd"; rm -rf "$fakebin"; mkdir -p "$fakebin"
|
|
574
|
+
clone=$(build_packed_prunable "$home" lockcwd)
|
|
575
|
+
plant_packed_refs_lock "$clone"
|
|
576
|
+
# Nobody holds the lock file, but a live process holds the clone worktree as its
|
|
577
|
+
# cwd - the narrow race where git closed packed-refs.lock but has not yet exited.
|
|
578
|
+
lsof_holds_only_live_dir "$fakebin"
|
|
579
|
+
before=$(head_sha "$clone")
|
|
580
|
+
out="$home/out-lockcwd"; err="$home/err-lockcwd"
|
|
581
|
+
|
|
582
|
+
set +e
|
|
583
|
+
FLEET_TEST_LIVE_DIR="$clone" \
|
|
584
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRIES=2 \
|
|
585
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS=0 \
|
|
586
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS=0 \
|
|
587
|
+
run_sync_guarded "$home" "$fakebin" "$out" "$err" lockcwd
|
|
588
|
+
set -e
|
|
589
|
+
|
|
590
|
+
assert_grep "is not provably stale" "$err" "clone-cwd holder: guard did not refuse"
|
|
591
|
+
assert_no_grep "removed provably-stale packed-refs lock" "$err" \
|
|
592
|
+
"clone-cwd holder: guard removed a lock while a live process held the clone dir"
|
|
593
|
+
assert_present "$clone/.git/packed-refs.lock" "clone-cwd holder: lock must not be removed"
|
|
594
|
+
[ "$(head_sha "$clone")" = "$before" ] || fail "clone-cwd holder: clone was advanced despite the refusal"
|
|
595
|
+
pass "a live process holding the clone worktree dir blocks lock removal (clone-dir liveness)"
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
test_transient_packed_refs_lock_self_clears() {
|
|
599
|
+
local home fakebin clone out err counter
|
|
600
|
+
home=$(new_home)
|
|
601
|
+
fakebin="$home/fb-locktrans"; rm -rf "$fakebin"; mkdir -p "$fakebin"
|
|
602
|
+
clone=$(build_packed_prunable "$home" locktrans)
|
|
603
|
+
plant_packed_refs_lock "$clone"
|
|
604
|
+
git_transient_packed_refs_lock "$fakebin" # fail once + drop lock, then real git
|
|
605
|
+
counter="$home/git-fetch-count"; : > "$counter"
|
|
606
|
+
out="$home/out-locktrans"; err="$home/err-locktrans"
|
|
607
|
+
|
|
608
|
+
set +e
|
|
609
|
+
GIT_FETCH_COUNTER="$counter" \
|
|
610
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRIES=3 \
|
|
611
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS=0 \
|
|
612
|
+
run_sync_guarded "$home" "$fakebin" "$out" "$err" locktrans
|
|
613
|
+
set -e
|
|
614
|
+
|
|
615
|
+
assert_grep "cleared on its own" "$err" "transient lock: guard did not report the self-clear"
|
|
616
|
+
assert_no_grep "removed provably-stale packed-refs lock" "$err" \
|
|
617
|
+
"transient lock: guard force-removed a lock that only needed patience"
|
|
618
|
+
assert_contains "$(cat "$out")" "locktrans: synced" "transient lock: clone did not sync after self-clear"
|
|
619
|
+
assert_grep "recovered: packed-refs lock cleared on its own" "$out" \
|
|
620
|
+
"transient lock: recovery summary not emitted on stdout"
|
|
621
|
+
assert_absent "$clone/.git/packed-refs.lock" "transient lock: lock should be gone after self-clear"
|
|
622
|
+
pass "a transient packed-refs.lock that self-clears is retried without a force-remove"
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
test_non_clone_dir_never_syncs_the_enclosing_repo() {
|
|
626
|
+
local home before out after
|
|
627
|
+
home=$(build_enclosing_home nonclone)
|
|
628
|
+
# A worktree container, not a clone: the repo is one level BELOW it.
|
|
629
|
+
mkdir -p "$home/projects/not-a-clone/wt"
|
|
630
|
+
before=$(head_sha "$home")
|
|
631
|
+
|
|
632
|
+
out=$(run_sync "$home")
|
|
633
|
+
after=$(head_sha "$home")
|
|
634
|
+
|
|
635
|
+
assert_contains "$out" "not-a-clone: skipped: not a clone root" \
|
|
636
|
+
"a non-repo directory under projects/ must be skipped by name"
|
|
637
|
+
assert_not_contains "$out" "not-a-clone: synced" \
|
|
638
|
+
"a non-repo directory must never be reported as a synced project"
|
|
639
|
+
[ "$before" = "$after" ] || \
|
|
640
|
+
fail "fleet-sync fast-forwarded the enclosing repo ($before -> $after) under a project's label"
|
|
641
|
+
pass "a non-repo directory under projects/ never fast-forwards the enclosing repo"
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
test_non_clone_dir_named_directly_never_syncs_the_enclosing_repo() {
|
|
645
|
+
local home before out after
|
|
646
|
+
home=$(build_enclosing_home nonclonedirect)
|
|
647
|
+
mkdir -p "$home/projects/not-a-clone"
|
|
648
|
+
before=$(head_sha "$home")
|
|
649
|
+
|
|
650
|
+
out=$(run_sync "$home" not-a-clone)
|
|
651
|
+
after=$(head_sha "$home")
|
|
652
|
+
|
|
653
|
+
assert_contains "$out" "not-a-clone: skipped: not a clone root" \
|
|
654
|
+
"the single-project form must apply the same clone-root guard"
|
|
655
|
+
[ "$before" = "$after" ] || \
|
|
656
|
+
fail "the single-project form fast-forwarded the enclosing repo ($before -> $after)"
|
|
657
|
+
pass "the single-project form also refuses a directory that is not its own clone root"
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
test_symlinked_clone_still_syncs() {
|
|
661
|
+
local home clone out
|
|
662
|
+
home=$(new_home)
|
|
663
|
+
clone=$(build_pair "$home" sigma)
|
|
664
|
+
advance_origin "$home" sigma C1
|
|
665
|
+
# A symlinked clone dir is a real clone root; the guard compares resolved paths,
|
|
666
|
+
# so it must not be mistaken for a directory nested in someone else's repo.
|
|
667
|
+
mv "$clone" "$home/real-sigma"
|
|
668
|
+
ln -s "$home/real-sigma" "$clone"
|
|
669
|
+
|
|
670
|
+
out=$(run_sync "$home")
|
|
671
|
+
|
|
672
|
+
assert_contains "$out" "sigma: synced" "a symlinked clone must still fast-forward"
|
|
673
|
+
pass "the clone-root guard accepts a symlinked clone directory"
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
test_non_signature_fetch_failure_is_not_retried() {
|
|
677
|
+
local home fakebin clone out err
|
|
678
|
+
home=$(new_home)
|
|
679
|
+
fakebin="$home/fb-locknonsig"; rm -rf "$fakebin"; mkdir -p "$fakebin"
|
|
680
|
+
clone=$(build_pair "$home" locknonsig)
|
|
681
|
+
advance_origin "$home" locknonsig C1
|
|
682
|
+
git -C "$clone" remote set-url origin "file://$home/remotes/does-not-exist.git"
|
|
683
|
+
out="$home/out-locknonsig"; err="$home/err-locknonsig"
|
|
684
|
+
|
|
685
|
+
set +e
|
|
686
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRIES=3 \
|
|
687
|
+
FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS=0 \
|
|
688
|
+
run_sync_guarded "$home" "$fakebin" "$out" "$err" locknonsig
|
|
689
|
+
set -e
|
|
690
|
+
|
|
691
|
+
assert_contains "$(cat "$out")" "locknonsig: skipped: fetch failed" "non-signature: fleet-sync did not report the fetch failure"
|
|
692
|
+
assert_no_grep "waiting" "$err" "non-signature: a non-lock failure was wrongly retried"
|
|
693
|
+
assert_no_grep "packed-refs lock" "$err" "non-signature: a non-lock failure entered the lock guard"
|
|
694
|
+
pass "a non-packed-refs.lock fetch failure keeps today's behavior (no retry)"
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
test_detached_clean_ancestor_recovers
|
|
698
|
+
test_detached_unique_commit_is_stuck_untouched
|
|
699
|
+
test_detached_clean_ancestor_with_diverged_local_default_is_stuck_untouched
|
|
700
|
+
test_dirty_is_stuck_untouched
|
|
701
|
+
test_non_default_branch_is_stuck_untouched
|
|
702
|
+
test_diverged_is_stuck_untouched
|
|
703
|
+
test_on_default_clean_behind_fast_forwards
|
|
704
|
+
test_already_current_unchanged
|
|
705
|
+
test_no_origin_skipped
|
|
706
|
+
test_local_only_skipped
|
|
707
|
+
test_single_project_by_bare_name_resolves
|
|
708
|
+
test_single_project_by_bare_name_ignores_cwd_shadow
|
|
709
|
+
test_single_project_by_projects_relative_name_resolves
|
|
710
|
+
test_single_project_by_projects_relative_name_ignores_cwd_shadow
|
|
711
|
+
test_single_project_unresolvable_name_still_skips
|
|
712
|
+
test_whole_fleet_form
|
|
713
|
+
test_bootstrap_relays_recovered_and_stuck
|
|
714
|
+
test_orphaned_stale_packed_refs_lock_recovers
|
|
715
|
+
test_live_packed_refs_lock_is_never_removed
|
|
716
|
+
test_live_git_cwd_in_clone_dir_blocks_removal
|
|
717
|
+
test_transient_packed_refs_lock_self_clears
|
|
718
|
+
test_non_signature_fetch_failure_is_not_retried
|
|
719
|
+
test_non_clone_dir_never_syncs_the_enclosing_repo
|
|
720
|
+
test_non_clone_dir_named_directly_never_syncs_the_enclosing_repo
|
|
721
|
+
test_symlinked_clone_still_syncs
|