@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,458 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Refresh project clones: fast-forward the checked-out local default branch to
|
|
3
|
+
# origin/<default> when safe, and prune local branches whose upstream tracking
|
|
4
|
+
# branch is gone (the remote branch was deleted, i.e. its PR merged) and that no
|
|
5
|
+
# worktree still needs.
|
|
6
|
+
# Self-heals the one unambiguously safe drift: a clean, detached HEAD that holds
|
|
7
|
+
# no unique commits (it is an ancestor of origin/<default>) and whose <default>
|
|
8
|
+
# branch is free to check out is re-attached and then fast-forwarded ("recovered:").
|
|
9
|
+
# Every other off-default state - a non-default named branch, a detached HEAD with
|
|
10
|
+
# unique commits, a dirty tree, or a diverged default - may hold real work, so it
|
|
11
|
+
# is left untouched and reported as a quantified, loud "STUCK: ... N commits behind
|
|
12
|
+
# ... - needs attention" warning rather than a quiet drift. Nothing is ever forced,
|
|
13
|
+
# stashed, or discarded.
|
|
14
|
+
# Still skips (benignly) local-only/no-origin projects, missing remotes/branches,
|
|
15
|
+
# and fetch failures.
|
|
16
|
+
# A candidate under projects/ must be the root of its own work tree: git discovery
|
|
17
|
+
# walks up, so a plain nested directory would otherwise resolve to the enclosing
|
|
18
|
+
# repository (the firstmate checkout) and be synced under that directory's label.
|
|
19
|
+
# Anything else is reported as "skipped: not a clone root" naming the repository
|
|
20
|
+
# that would have been touched.
|
|
21
|
+
# Pruning never deletes the checked-out branch or a branch that still has a
|
|
22
|
+
# worktree, so it cannot discard unlanded work; set FM_FLEET_PRUNE=0 to disable it.
|
|
23
|
+
# When the fetch fails on an orphaned .git/packed-refs.lock (left by a ref rewrite
|
|
24
|
+
# killed mid-write - e.g. a timed-out bootstrap sync or a teardown process kill),
|
|
25
|
+
# it is retried with a bounded wait and removed only when provably stale; see
|
|
26
|
+
# fetch_with_packed_refs_lock_guard and the FM_FLEET_SYNC_PACKED_REFS_LOCK_* knobs.
|
|
27
|
+
# Usage: fm-fleet-sync.sh [<project-dir-or-name>]
|
|
28
|
+
# The single-project form accepts either a path (absolute, or relative to the
|
|
29
|
+
# caller's cwd) or a bare "<name>"/"projects/<name>" form, resolved against
|
|
30
|
+
# this home's projects dir ($FM_HOME/projects, or $FM_PROJECTS_OVERRIDE).
|
|
31
|
+
# Bare names and "projects/<name>" forms prefer this home's projects dir before
|
|
32
|
+
# falling back to an explicit path. Example: from anywhere,
|
|
33
|
+
# `fm-fleet-sync.sh dotfiles-private` syncs just that one clone, same as
|
|
34
|
+
# passing its full projects/dotfiles-private path.
|
|
35
|
+
set -eu
|
|
36
|
+
|
|
37
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
38
|
+
FM_ROOT="${FM_ROOT_OVERRIDE:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
39
|
+
FM_HOME="${FM_HOME:-${FM_ROOT_OVERRIDE:-$FM_ROOT}}"
|
|
40
|
+
PROJECTS="${FM_PROJECTS_OVERRIDE:-$FM_HOME/projects}"
|
|
41
|
+
# shellcheck source=bin/fm-lock-lib.sh
|
|
42
|
+
. "$SCRIPT_DIR/fm-lock-lib.sh"
|
|
43
|
+
# Inert unless FM_TIMING_LOG names a file; only the deferred network stage sets it.
|
|
44
|
+
# shellcheck source=bin/fm-timing-lib.sh
|
|
45
|
+
. "$SCRIPT_DIR/fm-timing-lib.sh"
|
|
46
|
+
FM_LOCK_LOG_PREFIX=fleet-sync
|
|
47
|
+
"$FM_ROOT/bin/fm-guard.sh" || true
|
|
48
|
+
|
|
49
|
+
# Bounded recovery for an orphaned .git/packed-refs.lock. A git ref rewrite
|
|
50
|
+
# (fetch --prune, branch -D, pack-refs) killed after creating the lock but before
|
|
51
|
+
# renaming it - e.g. bootstrap's fleet-sync timeout kill, or teardown's process
|
|
52
|
+
# kills - leaves a lock that makes the next sync's fetch fail with Git's
|
|
53
|
+
# "Unable to create '...packed-refs.lock': File exists". These knobs bound the
|
|
54
|
+
# patience-then-provably-stale-clear recovery; see fetch_with_packed_refs_lock_guard.
|
|
55
|
+
FLEET_SYNC_PACKED_REFS_LOCK_RETRIES=${FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRIES:-3}
|
|
56
|
+
FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS=${FM_FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS:-1}
|
|
57
|
+
FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS=${FM_FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS:-30}
|
|
58
|
+
case "$FLEET_SYNC_PACKED_REFS_LOCK_RETRIES" in ''|*[!0-9]*) FLEET_SYNC_PACKED_REFS_LOCK_RETRIES=3 ;; esac
|
|
59
|
+
case "$FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS" in ''|*[!0-9]*) FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS=30 ;; esac
|
|
60
|
+
if ! [[ "$FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS" =~ ^([0-9]+([.][0-9]*)?|[.][0-9]+)$ ]]; then
|
|
61
|
+
echo "fleet-sync: invalid packed-refs lock retry wait '$FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS'; using 1s" >&2
|
|
62
|
+
FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS=1
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
usage() {
|
|
66
|
+
echo "usage: fm-fleet-sync.sh [<project-dir-or-name>]" >&2
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
|
|
70
|
+
usage
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
[ $# -le 1 ] || { usage; exit 1; }
|
|
74
|
+
|
|
75
|
+
project_label() {
|
|
76
|
+
case "$PROJ" in
|
|
77
|
+
"$PROJECTS"/*) basename "$PROJ" ;;
|
|
78
|
+
projects/*) basename "$PROJ" ;;
|
|
79
|
+
*) printf '%s\n' "$PROJ" ;;
|
|
80
|
+
esac
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# resolve_project_arg <arg>: accept a path (used as-is when it already exists)
|
|
84
|
+
# or a bare/"projects/<name>" project name, resolved against $PROJECTS. Falls
|
|
85
|
+
# back to the original argument unresolved so a genuinely bad path still hits
|
|
86
|
+
# sync_project's existing "not a directory" skip.
|
|
87
|
+
resolve_project_arg() {
|
|
88
|
+
local arg=$1 candidate
|
|
89
|
+
case "$arg" in
|
|
90
|
+
projects/*)
|
|
91
|
+
candidate="$PROJECTS/${arg#projects/}"
|
|
92
|
+
if [ -d "$candidate" ]; then
|
|
93
|
+
printf '%s\n' "$candidate"
|
|
94
|
+
return 0
|
|
95
|
+
fi
|
|
96
|
+
;;
|
|
97
|
+
*/*)
|
|
98
|
+
if [ -d "$arg" ]; then
|
|
99
|
+
printf '%s\n' "$arg"
|
|
100
|
+
return 0
|
|
101
|
+
fi
|
|
102
|
+
;;
|
|
103
|
+
*)
|
|
104
|
+
candidate="$PROJECTS/$arg"
|
|
105
|
+
if [ -d "$candidate" ]; then
|
|
106
|
+
printf '%s\n' "$candidate"
|
|
107
|
+
return 0
|
|
108
|
+
fi
|
|
109
|
+
if [ -d "$arg" ]; then
|
|
110
|
+
printf '%s\n' "$arg"
|
|
111
|
+
return 0
|
|
112
|
+
fi
|
|
113
|
+
;;
|
|
114
|
+
esac
|
|
115
|
+
printf '%s\n' "$arg"
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
default_branch() {
|
|
119
|
+
local ref branch
|
|
120
|
+
ref=$(git -C "$PROJ" symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null || true)
|
|
121
|
+
if [ -n "$ref" ]; then
|
|
122
|
+
echo "${ref#origin/}"
|
|
123
|
+
return 0
|
|
124
|
+
fi
|
|
125
|
+
for branch in main master; do
|
|
126
|
+
if git -C "$PROJ" show-ref --verify --quiet "refs/heads/$branch"; then
|
|
127
|
+
echo "$branch"
|
|
128
|
+
return 0
|
|
129
|
+
fi
|
|
130
|
+
done
|
|
131
|
+
return 1
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
first_line() {
|
|
135
|
+
printf '%s\n' "$1" | sed -n '1s/[[:space:]]\{1,\}/ /g;1p'
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# True when git stderr shows the packed-refs.lock "File exists" race. The lock
|
|
139
|
+
# path can appear anywhere in the message (git prefixes it with the failed ref op,
|
|
140
|
+
# e.g. "could not delete reference ...:"). Other "File exists" errors must not match.
|
|
141
|
+
is_packed_refs_lock_error() {
|
|
142
|
+
printf '%s\n' "$1" | grep -Eq "Unable to create ['\"].*packed-refs\\.lock['\"]: File exists"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# Absolute path to $PROJ's packed-refs.lock, or empty when it cannot be resolved.
|
|
146
|
+
packed_refs_lock_path() {
|
|
147
|
+
local lock abs
|
|
148
|
+
lock=$(git -C "$PROJ" rev-parse --git-path packed-refs.lock 2>/dev/null) || return 1
|
|
149
|
+
[ -n "$lock" ] || return 1
|
|
150
|
+
case "$lock" in
|
|
151
|
+
/*) printf '%s\n' "$lock" ;;
|
|
152
|
+
*)
|
|
153
|
+
abs=$(cd "$PROJ" && pwd -P) || return 1
|
|
154
|
+
printf '%s/%s\n' "$abs" "$lock"
|
|
155
|
+
;;
|
|
156
|
+
esac
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Run `git -C "$PROJ" fetch origin --prune --quiet`, tolerating an orphaned
|
|
160
|
+
# packed-refs.lock left by a killed ref rewrite. Sets FETCH_OUTPUT to the git
|
|
161
|
+
# command's combined output and returns its exit status. On the packed-refs.lock
|
|
162
|
+
# signature ONLY: retry up to FLEET_SYNC_PACKED_REFS_LOCK_RETRIES times (a
|
|
163
|
+
# transient lock self-clears as the owning process exits), then - only if the lock
|
|
164
|
+
# is provably stale per fm-lock-lib.sh (still present, mtime age past the
|
|
165
|
+
# threshold, no lsof holder of the lock or the clone worktree $PROJ) - remove it
|
|
166
|
+
# and retry once more. A live lock, an unprovable one, or any other failure keeps
|
|
167
|
+
# today's behavior. Every wait, retry, and removal prints to stderr, and a
|
|
168
|
+
# successful recovery also prints one "$label: recovered: ..." summary to stdout so
|
|
169
|
+
# a session-start refresh (which discards fleet-sync stderr) still surfaces it.
|
|
170
|
+
fetch_with_packed_refs_lock_guard() {
|
|
171
|
+
local rc attempt=0 lock lock_desc
|
|
172
|
+
FETCH_OUTPUT=$(git -C "$PROJ" fetch origin --prune --quiet 2>&1); rc=$?
|
|
173
|
+
[ "$rc" -eq 0 ] && return 0
|
|
174
|
+
is_packed_refs_lock_error "$FETCH_OUTPUT" || return "$rc"
|
|
175
|
+
|
|
176
|
+
lock=$(packed_refs_lock_path) || lock=""
|
|
177
|
+
lock_desc=${lock:-packed-refs.lock}
|
|
178
|
+
while [ "$attempt" -lt "$FLEET_SYNC_PACKED_REFS_LOCK_RETRIES" ]; do
|
|
179
|
+
attempt=$(( attempt + 1 ))
|
|
180
|
+
echo "$label: fetch blocked by packed-refs lock ($lock_desc); waiting ${FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS}s and retrying ($attempt/${FLEET_SYNC_PACKED_REFS_LOCK_RETRIES}) (owning process may be exiting)" >&2
|
|
181
|
+
sleep "$FLEET_SYNC_PACKED_REFS_LOCK_RETRY_WAIT_SECS"
|
|
182
|
+
FETCH_OUTPUT=$(git -C "$PROJ" fetch origin --prune --quiet 2>&1); rc=$?
|
|
183
|
+
if [ "$rc" -eq 0 ]; then
|
|
184
|
+
echo "$label: fetch succeeded on retry; packed-refs lock cleared on its own" >&2
|
|
185
|
+
# One stdout summary so a session-start refresh (which discards fleet-sync
|
|
186
|
+
# stderr and relays only stdout) still surfaces the recovery.
|
|
187
|
+
echo "$label: recovered: packed-refs lock cleared on its own during retry"
|
|
188
|
+
return 0
|
|
189
|
+
fi
|
|
190
|
+
is_packed_refs_lock_error "$FETCH_OUTPUT" || return "$rc"
|
|
191
|
+
done
|
|
192
|
+
|
|
193
|
+
# Retries exhausted and still the lock signature. Clear ONLY if provably stale.
|
|
194
|
+
# The companion liveness dir is $PROJ (the clone worktree): a live `git -C "$PROJ"`
|
|
195
|
+
# keeps its cwd there even in the narrow window after it closes packed-refs.lock
|
|
196
|
+
# and before it exits, so lsof on $PROJ still catches a holder the lock-file check
|
|
197
|
+
# alone would miss.
|
|
198
|
+
lock=$(packed_refs_lock_path) || lock=""
|
|
199
|
+
if [ -n "$lock" ] && [ -e "$lock" ]; then
|
|
200
|
+
if fm_lock_is_provably_stale "$lock" "$PROJ" "$FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS"; then
|
|
201
|
+
if ! rm -f "$lock"; then
|
|
202
|
+
echo "$label: failed to remove provably-stale packed-refs lock $lock; leaving it in place" >&2
|
|
203
|
+
return "$rc"
|
|
204
|
+
fi
|
|
205
|
+
echo "$label: removed provably-stale packed-refs lock $lock (age >= ${FLEET_SYNC_PACKED_REFS_LOCK_AGE_SECS}s, no live holder) and retrying fetch" >&2
|
|
206
|
+
FETCH_OUTPUT=$(git -C "$PROJ" fetch origin --prune --quiet 2>&1); rc=$?
|
|
207
|
+
if [ "$rc" -eq 0 ]; then
|
|
208
|
+
echo "$label: fetch succeeded after stale packed-refs lock cleanup" >&2
|
|
209
|
+
echo "$label: recovered: removed a stale packed-refs lock (no live holder)"
|
|
210
|
+
return 0
|
|
211
|
+
fi
|
|
212
|
+
return "$rc"
|
|
213
|
+
fi
|
|
214
|
+
echo "$label: fetch blocked by packed-refs lock $lock that persisted across ${FLEET_SYNC_PACKED_REFS_LOCK_RETRIES} retries and is not provably stale (may belong to a live process); leaving it in place" >&2
|
|
215
|
+
return "$rc"
|
|
216
|
+
fi
|
|
217
|
+
echo "$label: fetch packed-refs lock signature persisted across ${FLEET_SYNC_PACKED_REFS_LOCK_RETRIES} retries even after the lock file disappeared" >&2
|
|
218
|
+
return "$rc"
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
prune_gone_branches() {
|
|
222
|
+
# Delete local branches whose upstream tracking branch is gone - the remote
|
|
223
|
+
# branch was deleted, which in this fleet means its PR merged - as long as
|
|
224
|
+
# nothing still needs them. Never the checked-out branch, and never a branch
|
|
225
|
+
# that still has a worktree (a live or not-yet-torn-down task). "Gone" plus
|
|
226
|
+
# "no worktree" already proves the work landed: teardown removes a branch's
|
|
227
|
+
# worktree only after confirming the work reached the remote. We deliberately
|
|
228
|
+
# do NOT also require the branch to be an ancestor of origin/<default> - PRs in
|
|
229
|
+
# this fleet are squash-merged, so a merged branch is never an ancestor and
|
|
230
|
+
# such a check would prune nothing. The no-worktree guard is the real safety
|
|
231
|
+
# net. Set FM_FLEET_PRUNE=0 to skip pruning entirely.
|
|
232
|
+
[ "${FM_FLEET_PRUNE:-1}" != "0" ] || return 0
|
|
233
|
+
|
|
234
|
+
local worktree_branches current refline branch track
|
|
235
|
+
worktree_branches=$(git -C "$PROJ" worktree list --porcelain 2>/dev/null \
|
|
236
|
+
| sed -n 's#^branch refs/heads/##p')
|
|
237
|
+
current=$(git -C "$PROJ" symbolic-ref --quiet --short HEAD 2>/dev/null || true)
|
|
238
|
+
|
|
239
|
+
while IFS= read -r refline; do
|
|
240
|
+
branch=${refline%% *}
|
|
241
|
+
track=${refline#* }
|
|
242
|
+
[ "$track" = "[gone]" ] || continue
|
|
243
|
+
[ -n "$branch" ] || continue
|
|
244
|
+
[ "$branch" != "$current" ] || continue
|
|
245
|
+
if printf '%s\n' "$worktree_branches" | grep -Fxq -- "$branch"; then
|
|
246
|
+
continue
|
|
247
|
+
fi
|
|
248
|
+
if git -C "$PROJ" branch -D -- "$branch" >/dev/null 2>&1; then
|
|
249
|
+
echo "$label: pruned $branch"
|
|
250
|
+
fi
|
|
251
|
+
done < <(git -C "$PROJ" for-each-ref \
|
|
252
|
+
--format='%(refname:short) %(upstream:track)' refs/heads 2>/dev/null)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
# True when some worktree of $PROJ has $DEFAULT checked out (so we cannot attach
|
|
256
|
+
# to it here). The current worktree is detached when this is consulted, so any
|
|
257
|
+
# match is necessarily another worktree.
|
|
258
|
+
default_checked_out_elsewhere() {
|
|
259
|
+
git -C "$PROJ" worktree list --porcelain 2>/dev/null \
|
|
260
|
+
| sed -n 's#^branch refs/heads/##p' \
|
|
261
|
+
| grep -Fxq -- "$DEFAULT"
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
local_default_safe_for_recovery() {
|
|
265
|
+
! git -C "$PROJ" rev-parse --verify --quiet "$DEFAULT^{commit}" >/dev/null \
|
|
266
|
+
|| git -C "$PROJ" merge-base --is-ancestor "$DEFAULT" "$BASE" 2>/dev/null
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
# Human-readable name for the unsafe state the clone is in, used in the STUCK
|
|
270
|
+
# warning. Reads $cur (current branch, empty when detached), $dirty, and the
|
|
271
|
+
# HEAD-vs-$BASE ancestry to pick the most informative description.
|
|
272
|
+
stuck_state() {
|
|
273
|
+
local s
|
|
274
|
+
if [ -n "$cur" ]; then
|
|
275
|
+
s="branch $cur"
|
|
276
|
+
elif [ "$dirty" = yes ]; then
|
|
277
|
+
s="detached HEAD"
|
|
278
|
+
elif ! git -C "$PROJ" merge-base --is-ancestor HEAD "$BASE" 2>/dev/null; then
|
|
279
|
+
s="detached HEAD with unique commits"
|
|
280
|
+
elif default_checked_out_elsewhere; then
|
|
281
|
+
s="detached HEAD ($DEFAULT checked out in another worktree)"
|
|
282
|
+
elif ! local_default_safe_for_recovery; then
|
|
283
|
+
s="detached HEAD (local $DEFAULT diverged from $BASE)"
|
|
284
|
+
else
|
|
285
|
+
s="detached HEAD"
|
|
286
|
+
fi
|
|
287
|
+
[ "$dirty" = no ] || s="$s with uncommitted changes"
|
|
288
|
+
printf '%s\n' "$s"
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
# Loud, quantified report for a clone we deliberately leave untouched. Includes
|
|
292
|
+
# how far behind origin/<default> it is, so a chronically-stuck clone is visibly
|
|
293
|
+
# distinct from a benign one-off skip.
|
|
294
|
+
report_stuck() {
|
|
295
|
+
local state=$1 behind
|
|
296
|
+
behind=$(git -C "$PROJ" rev-list --count "HEAD..$BASE" 2>/dev/null) || behind="?"
|
|
297
|
+
echo "$label: STUCK: on $state, $behind commits behind $BASE - needs attention"
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
sync_project() {
|
|
301
|
+
PROJ=$1
|
|
302
|
+
label=$(project_label)
|
|
303
|
+
|
|
304
|
+
if [ ! -d "$PROJ" ]; then
|
|
305
|
+
echo "$label: skipped: not a directory"
|
|
306
|
+
return 0
|
|
307
|
+
fi
|
|
308
|
+
# Git repository discovery walks UP from $PROJ, so a plain directory merely
|
|
309
|
+
# nested inside a repository - a worktree container left under projects/, say -
|
|
310
|
+
# resolves to the ENCLOSING repository, which in a firstmate home is the
|
|
311
|
+
# firstmate checkout itself. Every later `git -C "$PROJ"` would then read, prune
|
|
312
|
+
# and fast-forward that repository under this project's label, turning a routine
|
|
313
|
+
# refresh into an unrequested self-update reported as a project sync. Require
|
|
314
|
+
# $PROJ to be the root of its own work tree before any other git command runs.
|
|
315
|
+
proj_top=$(git -C "$PROJ" rev-parse --show-toplevel 2>/dev/null) || proj_top=""
|
|
316
|
+
if [ -z "$proj_top" ]; then
|
|
317
|
+
echo "$label: skipped: not a git repo"
|
|
318
|
+
return 0
|
|
319
|
+
fi
|
|
320
|
+
# Both sides are physical paths (git resolves --show-toplevel through symlinks),
|
|
321
|
+
# so a symlinked clone dir still compares equal to its own root.
|
|
322
|
+
proj_abs=$(cd "$PROJ" && pwd -P) || proj_abs=""
|
|
323
|
+
if [ "$proj_top" != "$proj_abs" ]; then
|
|
324
|
+
echo "$label: skipped: not a clone root (git would act on $proj_top)"
|
|
325
|
+
return 0
|
|
326
|
+
fi
|
|
327
|
+
mode_line=$("$FM_ROOT/bin/fm-project-mode.sh" "$label" 2>/dev/null || echo "no-mistakes off")
|
|
328
|
+
mode=${mode_line%% *}
|
|
329
|
+
if [ "$mode" = "local-only" ]; then
|
|
330
|
+
echo "$label: skipped: local-only project"
|
|
331
|
+
return 0
|
|
332
|
+
fi
|
|
333
|
+
if ! git -C "$PROJ" remote get-url origin >/dev/null 2>&1; then
|
|
334
|
+
echo "$label: skipped: no origin remote"
|
|
335
|
+
return 0
|
|
336
|
+
fi
|
|
337
|
+
|
|
338
|
+
if ! fetch_with_packed_refs_lock_guard; then
|
|
339
|
+
reason="fetch failed"
|
|
340
|
+
if [ -n "$FETCH_OUTPUT" ]; then
|
|
341
|
+
reason="$reason: $(first_line "$FETCH_OUTPUT")"
|
|
342
|
+
fi
|
|
343
|
+
echo "$label: skipped: $reason"
|
|
344
|
+
return 0
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
prune_gone_branches || true
|
|
348
|
+
|
|
349
|
+
DEFAULT=$(default_branch) || {
|
|
350
|
+
echo "$label: skipped: cannot determine default branch"
|
|
351
|
+
return 0
|
|
352
|
+
}
|
|
353
|
+
BASE="origin/$DEFAULT"
|
|
354
|
+
if ! git -C "$PROJ" rev-parse --verify --quiet "$BASE^{commit}" >/dev/null; then
|
|
355
|
+
echo "$label: skipped: $BASE does not exist"
|
|
356
|
+
return 0
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
cur=$(git -C "$PROJ" symbolic-ref --short HEAD 2>/dev/null || echo "")
|
|
360
|
+
dirty=no
|
|
361
|
+
[ -z "$(git -C "$PROJ" status --porcelain 2>/dev/null | head -1)" ] || dirty=yes
|
|
362
|
+
recovered=no
|
|
363
|
+
|
|
364
|
+
if [ "$cur" != "$DEFAULT" ]; then
|
|
365
|
+
# Off the default branch. Auto-recover only the one unambiguously safe drift:
|
|
366
|
+
# a clean, detached HEAD that holds no unique commits (it is an ancestor of
|
|
367
|
+
# origin/<default>) and whose <default> branch is free to check out here.
|
|
368
|
+
# Re-attaching to an already-published commit strands nothing, and the
|
|
369
|
+
# fast-forward path below then catches the clone up. Anything else - a
|
|
370
|
+
# non-default named branch, a detached HEAD with unique commits, a dirty tree,
|
|
371
|
+
# or <default> already checked out elsewhere - may hold real work, so it is
|
|
372
|
+
# reported loudly and left untouched.
|
|
373
|
+
if [ -z "$cur" ] && [ "$dirty" = no ] \
|
|
374
|
+
&& git -C "$PROJ" merge-base --is-ancestor HEAD "$BASE" 2>/dev/null \
|
|
375
|
+
&& ! default_checked_out_elsewhere \
|
|
376
|
+
&& local_default_safe_for_recovery; then
|
|
377
|
+
if ! git -C "$PROJ" checkout --quiet "$DEFAULT" 2>/dev/null; then
|
|
378
|
+
report_stuck "$(stuck_state)"
|
|
379
|
+
return 0
|
|
380
|
+
fi
|
|
381
|
+
recovered=yes
|
|
382
|
+
cur=$DEFAULT
|
|
383
|
+
else
|
|
384
|
+
report_stuck "$(stuck_state)"
|
|
385
|
+
return 0
|
|
386
|
+
fi
|
|
387
|
+
elif [ "$dirty" = yes ]; then
|
|
388
|
+
# On the default branch but with uncommitted changes we must not disturb.
|
|
389
|
+
report_stuck "$(stuck_state)"
|
|
390
|
+
return 0
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
if ! git -C "$PROJ" rev-parse --verify --quiet "$DEFAULT^{commit}" >/dev/null; then
|
|
394
|
+
echo "$label: skipped: local $DEFAULT does not exist"
|
|
395
|
+
return 0
|
|
396
|
+
fi
|
|
397
|
+
|
|
398
|
+
local_rev=$(git -C "$PROJ" rev-parse "$DEFAULT") || {
|
|
399
|
+
echo "$label: skipped: cannot read local $DEFAULT"
|
|
400
|
+
return 0
|
|
401
|
+
}
|
|
402
|
+
remote_rev=$(git -C "$PROJ" rev-parse "$BASE") || {
|
|
403
|
+
echo "$label: skipped: cannot read $BASE"
|
|
404
|
+
return 0
|
|
405
|
+
}
|
|
406
|
+
if [ "$local_rev" = "$remote_rev" ]; then
|
|
407
|
+
if [ "$recovered" = yes ]; then
|
|
408
|
+
echo "$label: recovered: re-attached $DEFAULT (already current)"
|
|
409
|
+
else
|
|
410
|
+
echo "$label: already current"
|
|
411
|
+
fi
|
|
412
|
+
return 0
|
|
413
|
+
fi
|
|
414
|
+
if ! git -C "$PROJ" merge-base --is-ancestor "$DEFAULT" "$BASE"; then
|
|
415
|
+
report_stuck "diverged $DEFAULT"
|
|
416
|
+
return 0
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
before=$(git -C "$PROJ" rev-parse --short "$DEFAULT") || {
|
|
420
|
+
echo "$label: skipped: cannot read local $DEFAULT"
|
|
421
|
+
return 0
|
|
422
|
+
}
|
|
423
|
+
if ! merge_output=$(git -C "$PROJ" merge --ff-only "$BASE" 2>&1); then
|
|
424
|
+
reason="fast-forward failed"
|
|
425
|
+
if [ -n "$merge_output" ]; then
|
|
426
|
+
reason="$reason: $(first_line "$merge_output")"
|
|
427
|
+
fi
|
|
428
|
+
echo "$label: skipped: $reason"
|
|
429
|
+
return 0
|
|
430
|
+
fi
|
|
431
|
+
after=$(git -C "$PROJ" rev-parse --short "$DEFAULT") || {
|
|
432
|
+
echo "$label: skipped: fast-forward completed but cannot read local $DEFAULT"
|
|
433
|
+
return 0
|
|
434
|
+
}
|
|
435
|
+
if [ "$recovered" = yes ]; then
|
|
436
|
+
echo "$label: recovered: re-attached $DEFAULT, synced $before..$after"
|
|
437
|
+
else
|
|
438
|
+
echo "$label: synced $before..$after"
|
|
439
|
+
fi
|
|
440
|
+
return 0
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if [ $# -eq 1 ]; then
|
|
444
|
+
sync_project "$(resolve_project_arg "$1")"
|
|
445
|
+
exit 0
|
|
446
|
+
fi
|
|
447
|
+
|
|
448
|
+
[ -d "$PROJECTS" ] || exit 0
|
|
449
|
+
for proj in "$PROJECTS"/*; do
|
|
450
|
+
[ -e "$proj" ] || continue
|
|
451
|
+
[ -d "$proj" ] || continue
|
|
452
|
+
# Per-clone elapsed, so a fleet refresh that runs long names WHICH clone cost
|
|
453
|
+
# the time instead of only its total. Recording is a no-op unless the deferred
|
|
454
|
+
# network stage asked for it.
|
|
455
|
+
__fm_timing_stamp=$(fm_timing_now_ms)
|
|
456
|
+
sync_project "$proj"
|
|
457
|
+
fm_timing_record clone sync "$__fm_timing_stamp" "$(basename "$proj")"
|
|
458
|
+
done
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fm-fleet-view.sh - human renderer over fm-fleet-snapshot.sh.
|
|
3
|
+
#
|
|
4
|
+
# This command intentionally does not parse fleet state itself.
|
|
5
|
+
# It shells out to fm-fleet-snapshot.sh --json and renders that stable
|
|
6
|
+
# structured contract for humans.
|
|
7
|
+
set -u
|
|
8
|
+
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
|
|
11
|
+
usage() {
|
|
12
|
+
cat <<'EOF'
|
|
13
|
+
usage: fm-fleet-view.sh [--json]
|
|
14
|
+
|
|
15
|
+
Render a human fleet view from fm-fleet-snapshot.sh.
|
|
16
|
+
Use --json to print the underlying snapshot.
|
|
17
|
+
EOF
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
case "${1:-}" in
|
|
21
|
+
-h|--help) usage; exit 0 ;;
|
|
22
|
+
--json) "$SCRIPT_DIR/fm-fleet-snapshot.sh" --json; exit $? ;;
|
|
23
|
+
"") ;;
|
|
24
|
+
*) usage >&2; exit 2 ;;
|
|
25
|
+
esac
|
|
26
|
+
|
|
27
|
+
command -v jq >/dev/null 2>&1 || { echo "fm-fleet-view: jq not found" >&2; exit 1; }
|
|
28
|
+
|
|
29
|
+
SNAPSHOT=$("$SCRIPT_DIR/fm-fleet-snapshot.sh" --json) || exit $?
|
|
30
|
+
|
|
31
|
+
printf '%s\n' "$SNAPSHOT" | jq -r '
|
|
32
|
+
def dash($v): if $v == null or $v == "" then "-" else $v end;
|
|
33
|
+
def endpoint_exists($t):
|
|
34
|
+
if $t.endpoint.exists == null then "unknown"
|
|
35
|
+
elif $t.endpoint.exists then "present"
|
|
36
|
+
else "absent" end;
|
|
37
|
+
def endpoint_of($t):
|
|
38
|
+
if $t.kind == "secondmate" then "\(endpoint_exists($t)) / \($t.endpoint.agent_alive)"
|
|
39
|
+
else endpoint_exists($t) end;
|
|
40
|
+
def artifact($t):
|
|
41
|
+
if $t.pr.url != null then $t.pr.url
|
|
42
|
+
elif $t.paths.report.present then $t.paths.report.path
|
|
43
|
+
else "-" end;
|
|
44
|
+
def path_of($t):
|
|
45
|
+
if $t.paths.home.present then $t.paths.home.path
|
|
46
|
+
elif $t.paths.home.path != null then $t.paths.home.path + " (absent)"
|
|
47
|
+
elif $t.paths.worktree.present then $t.paths.worktree.path
|
|
48
|
+
elif $t.paths.worktree.path != null then $t.paths.worktree.path + " (absent)"
|
|
49
|
+
else "-" end;
|
|
50
|
+
def action_of($t):
|
|
51
|
+
if $t.kind == "secondmate" then "\($t.actions.send) - \($t.actions.watch)"
|
|
52
|
+
else $t.actions.watch end;
|
|
53
|
+
def task_row($t):
|
|
54
|
+
"| \($t.id) | \($t.current_state.state) / \($t.current_state.source) | \($t.kind) | \(dash($t.backlog.repo // $t.project)) | \($t.backend) | \(endpoint_of($t)) | \(artifact($t)) | \(path_of($t)) | \(action_of($t)) |";
|
|
55
|
+
def blocker($r):
|
|
56
|
+
if ($r.blocked_by // "") == "" then "-"
|
|
57
|
+
elif ($r.blocked_reason // "") == "" then $r.blocked_by
|
|
58
|
+
else "\($r.blocked_by) - \($r.blocked_reason)" end;
|
|
59
|
+
def backlog_row($r):
|
|
60
|
+
"| \($r.id // "-") | \(dash($r.title // $r.raw)) | \(dash($r.repo)) | \(dash($r.kind)) | \(blocker($r)) | \(dash($r.pr_url // $r.report_path // $r.local_note)) |";
|
|
61
|
+
|
|
62
|
+
"# Fleet View",
|
|
63
|
+
"",
|
|
64
|
+
"Schema: \(.schema)",
|
|
65
|
+
"Home: \(.fm_home)",
|
|
66
|
+
"",
|
|
67
|
+
"## Under Way",
|
|
68
|
+
(if (.tasks | length) == 0 then
|
|
69
|
+
"No live task metadata found."
|
|
70
|
+
else
|
|
71
|
+
"| ID | Current | Kind | Repo/Project | Backend | Endpoint | Artifact | Path | Watch / return channel |",
|
|
72
|
+
"| --- | --- | --- | --- | --- | --- | --- | --- | --- |",
|
|
73
|
+
(.tasks[] | task_row(.))
|
|
74
|
+
end),
|
|
75
|
+
"",
|
|
76
|
+
"## Queued",
|
|
77
|
+
(if ([.backlog.records[]? | select(.state == "queued")] | length) == 0 then
|
|
78
|
+
"No queued backlog records found."
|
|
79
|
+
else
|
|
80
|
+
"| ID | Title | Repo | Kind | Blocked By | Artifact |",
|
|
81
|
+
"| --- | --- | --- | --- | --- | --- |",
|
|
82
|
+
(.backlog.records[] | select(.state == "queued") | backlog_row(.))
|
|
83
|
+
end),
|
|
84
|
+
"",
|
|
85
|
+
"## Done",
|
|
86
|
+
(if ([.backlog.records[]? | select(.state == "done")] | length) == 0 then
|
|
87
|
+
"No done backlog records found."
|
|
88
|
+
else
|
|
89
|
+
"| ID | Title | Repo | Kind | Blocked By | Artifact |",
|
|
90
|
+
"| --- | --- | --- | --- | --- | --- |",
|
|
91
|
+
(.backlog.records[] | select(.state == "done") | backlog_row(.))
|
|
92
|
+
end),
|
|
93
|
+
"",
|
|
94
|
+
"## Secondmates",
|
|
95
|
+
.secondmate_guidance.note
|
|
96
|
+
'
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fm-gate-refuse-lib.sh - fail-closed refusal that keeps a no-mistakes GATE agent
|
|
3
|
+
# out of firstmate's fleet lifecycle.
|
|
4
|
+
#
|
|
5
|
+
# The hazard (data/nm-gate-ambient-authority-containment-c3/report.md): a
|
|
6
|
+
# no-mistakes gate agent runs inside a firstmate checkout with a free shell, so
|
|
7
|
+
# it auto-loads firstmate's AGENTS.md, adopts the captain identity, and - seeing
|
|
8
|
+
# crew "in flight" - reaches for fm-spawn.sh/fm-send.sh/fm-teardown.sh to
|
|
9
|
+
# "delegate" and "reconcile" the shared worktree. It has real capability because
|
|
10
|
+
# those entrypoints self-locate their home and never knew a gate context existed.
|
|
11
|
+
#
|
|
12
|
+
# no-mistakes owns the authority-removal half (it neutralizes the project
|
|
13
|
+
# instructions and stamps NO_MISTAKES_GATE into the gate agent's environment).
|
|
14
|
+
# THIS is the firstmate capability-removal half: an enforceable script refusal,
|
|
15
|
+
# not a prose rule the neutralized agent would never read. It is sourced at the
|
|
16
|
+
# top of the three fleet-lifecycle entrypoints and called before any fleet
|
|
17
|
+
# mutation, so a gate agent that still reaches for the fleet is stopped cold.
|
|
18
|
+
#
|
|
19
|
+
# Two independent signals, either of which refuses (fail closed):
|
|
20
|
+
#
|
|
21
|
+
# 1. NO_MISTAKES_GATE set - the durable env marker no-mistakes stamps into every
|
|
22
|
+
# gate agent. This is the primary signal and covers a relocated NM_HOME.
|
|
23
|
+
# 2. The current worktree's git-common-dir resolves under a no-mistakes gate
|
|
24
|
+
# repo (.../.no-mistakes/repos/*.git) - the UNSPOOFABLE backstop. It derives
|
|
25
|
+
# from the checkout's real filesystem location, which the agent cannot
|
|
26
|
+
# relocate without breaking the gate's own git operations, so it still
|
|
27
|
+
# refuses even if the agent tampered NO_MISTAKES_GATE away. Its limit: the
|
|
28
|
+
# literal-path match only fires for the default NM_HOME (~/.no-mistakes); a
|
|
29
|
+
# relocated NM_HOME is covered by signal 1.
|
|
30
|
+
#
|
|
31
|
+
# A NORMAL firstmate session - a real primary checkout, a real treehouse/Orca
|
|
32
|
+
# crew worktree - has NEITHER signal and is COMPLETELY unaffected: the function
|
|
33
|
+
# returns 0 and the lifecycle proceeds exactly as before.
|
|
34
|
+
#
|
|
35
|
+
# This mirrors the unspoofable-marker precedent in bin/fm-marker-lib.sh: a signal
|
|
36
|
+
# the agent cannot forge, keyed on at a chokepoint, keeping the pattern familiar
|
|
37
|
+
# to firstmate maintainers. It layers ABOVE no-mistakes' separately-shipping
|
|
38
|
+
# HEAD-continuity guard, which remains the adversarial/residual backstop.
|
|
39
|
+
#
|
|
40
|
+
# TEST-HARNESS ESCAPE HATCH (FM_GATE_REFUSE_BYPASS=1): firstmate's own test suite
|
|
41
|
+
# must exercise the REAL fm-spawn/fm-send/fm-teardown, but the no-mistakes gate
|
|
42
|
+
# runs that suite FROM a gate worktree (cwd git-common-dir under
|
|
43
|
+
# .no-mistakes/repos/*.git, and possibly NO_MISTAKES_GATE set) - the exact
|
|
44
|
+
# environment this guard refuses. So both signals would fire during firstmate's
|
|
45
|
+
# own validation and break unrelated tests. FM_GATE_REFUSE_BYPASS=1 makes the
|
|
46
|
+
# guard a no-op; firstmate's shared test helpers (tests/lib.sh and the backend
|
|
47
|
+
# safety helpers) export it, so every test that drives these scripts against its
|
|
48
|
+
# temp-sandbox fleet is exempt. This does NOT weaken the boundary against the
|
|
49
|
+
# real hazard: the threat is a CONFUSED-not-adversarial gate agent that runs
|
|
50
|
+
# bin/fm-spawn.sh directly after adopting firstmate's identity - it never sources
|
|
51
|
+
# firstmate's test helpers, so it never carries the bypass; and the adversarial
|
|
52
|
+
# case (an agent that would deliberately set it) is covered by no-mistakes'
|
|
53
|
+
# neutral-execution-context and the HEAD-continuity guard. The dedicated
|
|
54
|
+
# tests/fm-gate-refuse.test.sh strips the bypass so it still verifies real refusal.
|
|
55
|
+
#
|
|
56
|
+
# Sourced by bin/fm-spawn.sh, bin/fm-send.sh, bin/fm-teardown.sh,
|
|
57
|
+
# bin/fm-sessionstart-nudge.sh, and the tests.
|
|
58
|
+
# No side effects on source. set -u / set -e safe. The refusal is a hard exit,
|
|
59
|
+
# not a return, because there is no safe way to continue a fleet mutation from a
|
|
60
|
+
# gate context.
|
|
61
|
+
|
|
62
|
+
# The exit code every refusal uses, distinct enough to recognize in a caller or
|
|
63
|
+
# test as "the gate refusal fired" rather than an ordinary usage error.
|
|
64
|
+
FM_GATE_REFUSE_EXIT=3
|
|
65
|
+
|
|
66
|
+
# fm_is_gate_agent: return 0 without output when this process looks like a
|
|
67
|
+
# no-mistakes gate agent. An optional root anchors the git-common-dir check;
|
|
68
|
+
# callers that omit it retain the historical current-worktree behavior.
|
|
69
|
+
fm_is_gate_agent() {
|
|
70
|
+
local anchor=${1:-.} common
|
|
71
|
+
if [ "${FM_GATE_REFUSE_BYPASS:-}" = 1 ]; then
|
|
72
|
+
return 1
|
|
73
|
+
fi
|
|
74
|
+
if [ "${NO_MISTAKES_GATE+x}" = x ]; then
|
|
75
|
+
FM_GATE_REFUSE_REASON='env'
|
|
76
|
+
return 0
|
|
77
|
+
fi
|
|
78
|
+
common=$(cd "$anchor" 2>/dev/null \
|
|
79
|
+
&& cd "$(git rev-parse --git-common-dir 2>/dev/null || echo /nonexistent)" 2>/dev/null \
|
|
80
|
+
&& pwd -P || true)
|
|
81
|
+
case "$common" in
|
|
82
|
+
*/.no-mistakes/repos/*.git)
|
|
83
|
+
FM_GATE_REFUSE_REASON='path'
|
|
84
|
+
FM_GATE_REFUSE_COMMON=$common
|
|
85
|
+
return 0 ;;
|
|
86
|
+
esac
|
|
87
|
+
return 1
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# fm_refuse_if_gate_agent: exit FM_GATE_REFUSE_EXIT with a clear stderr message if
|
|
91
|
+
# this process looks like a no-mistakes gate agent. Call before any fleet
|
|
92
|
+
# mutation. No-ops (returns 0) for a normal firstmate session, or when firstmate's
|
|
93
|
+
# own test harness sets FM_GATE_REFUSE_BYPASS=1 (see the header).
|
|
94
|
+
fm_refuse_if_gate_agent() {
|
|
95
|
+
fm_is_gate_agent "${1:-.}" || return 0
|
|
96
|
+
if [ "$FM_GATE_REFUSE_REASON" = env ]; then
|
|
97
|
+
echo "error: no-mistakes gate agent must not drive the fleet (NO_MISTAKES_GATE set)" >&2
|
|
98
|
+
else
|
|
99
|
+
echo "error: refusing fleet lifecycle from inside a no-mistakes gate worktree ($FM_GATE_REFUSE_COMMON)" >&2
|
|
100
|
+
fi
|
|
101
|
+
exit "$FM_GATE_REFUSE_EXIT"
|
|
102
|
+
}
|