@zerwiz/ymir 0.1.3 → 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 -39
- 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,785 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavior tests for bin/fm-brief.sh.
|
|
3
|
+
#
|
|
4
|
+
# Regression coverage for the heredoc-in-command-substitution parse bug (issues
|
|
5
|
+
# #166, #958, #1069). Building a variable with `VAR=$(cat <<EOF ... EOF)` is
|
|
6
|
+
# unsafe on Bash 3.2 (macOS /bin/bash): the lexer scans for the matching `)` of
|
|
7
|
+
# the command substitution textually and tracks quote state through the heredoc
|
|
8
|
+
# body, so a single apostrophe, unbalanced quote, or unbalanced paren anywhere
|
|
9
|
+
# in that body breaks parsing of the *entire rest of the script* - `bash -n`
|
|
10
|
+
# fails, not just the generated brief. The DOD and Herdr-section builders now
|
|
11
|
+
# use `IFS= read -r -d '' VAR <<EOF || true` instead, which removes the `$(...)`
|
|
12
|
+
# wrapper and eliminates the whole defect class regardless of future prose.
|
|
13
|
+
# test_no_heredoc_in_command_substitution guards that structure directly.
|
|
14
|
+
# Ambient `bash -n` here is Bash 5 and cannot see the bug, so the real
|
|
15
|
+
# cross-version enforcement lives in the macos-stock-bash CI job.
|
|
16
|
+
set -u
|
|
17
|
+
|
|
18
|
+
# shellcheck source=tests/lib.sh
|
|
19
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
20
|
+
|
|
21
|
+
TMP_ROOT=$(fm_test_tmproot fm-brief)
|
|
22
|
+
BRIEF_HOME="$TMP_ROOT/home"
|
|
23
|
+
mkdir -p "$BRIEF_HOME/data"
|
|
24
|
+
|
|
25
|
+
# The script itself must always parse under the ambient bash. That is Bash 5 in
|
|
26
|
+
# CI and locally, where the issue #958/#1069 parser bug does not fire, so this
|
|
27
|
+
# is a weak guard on its own; test_no_heredoc_in_command_substitution and the
|
|
28
|
+
# macos-stock-bash CI job carry the real cross-version enforcement.
|
|
29
|
+
test_script_parses() {
|
|
30
|
+
local out rc
|
|
31
|
+
out=$(bash -n "$ROOT/bin/fm-brief.sh" 2>&1); rc=$?
|
|
32
|
+
expect_code 0 "$rc" "bash -n bin/fm-brief.sh must parse cleanly (got: $out)"
|
|
33
|
+
[ -z "$out" ] || fail "bash -n bin/fm-brief.sh emitted unexpected output: $out"
|
|
34
|
+
pass "fm-brief.sh: bash -n succeeds"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Structural class guard (issues #166, #958, #1069): never build a variable by
|
|
38
|
+
# wrapping a heredoc in a command substitution (`VAR=$(cat <<EOF ... EOF)`).
|
|
39
|
+
# That construct is what breaks Bash 3.2 parsing, and pinning one historical
|
|
40
|
+
# apostrophe phrase (as the old test did) missed the #945 reintroduction. This
|
|
41
|
+
# guards the *shape* directly against the whole file, so any future DOD or
|
|
42
|
+
# section builder that reintroduces the class fails here regardless of prose.
|
|
43
|
+
test_no_heredoc_in_command_substitution() {
|
|
44
|
+
local unsafe safe
|
|
45
|
+
unsafe="$TMP_ROOT/heredoc-in-substitution.sh"
|
|
46
|
+
safe="$TMP_ROOT/plain-heredoc.sh"
|
|
47
|
+
# shellcheck disable=SC2016 # Literal shell fixtures must remain unexpanded.
|
|
48
|
+
printf '%s\n' 'value=$(' ' cat <<EOF' 'body' 'EOF' ')' > "$unsafe"
|
|
49
|
+
# shellcheck disable=SC2016 # Literal shell fixtures must remain unexpanded.
|
|
50
|
+
printf '%s\n' 'cat <<EOF' '$(' ' cat <<INNER' 'INNER' ')' 'EOF' > "$safe"
|
|
51
|
+
if no_heredoc_in_command_substitution "$unsafe"; then
|
|
52
|
+
fail "structural guard accepted a multiline heredoc nested in a command substitution"
|
|
53
|
+
fi
|
|
54
|
+
no_heredoc_in_command_substitution "$safe" \
|
|
55
|
+
|| fail "structural guard treated heredoc body prose as shell structure"
|
|
56
|
+
no_heredoc_in_command_substitution "$ROOT/bin/fm-brief.sh" \
|
|
57
|
+
|| fail "fm-brief.sh wraps a heredoc in a command substitution (breaks Bash 3.2 parsing)"
|
|
58
|
+
pass "fm-brief.sh: no heredoc is nested inside a command substitution (Bash 3.2 parse-safe)"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
no_heredoc_in_command_substitution() {
|
|
62
|
+
perl - "$1" <<'PERL'
|
|
63
|
+
use strict;
|
|
64
|
+
use warnings;
|
|
65
|
+
|
|
66
|
+
my $path = shift;
|
|
67
|
+
open my $source, '<', $path or die "$path: $!\n";
|
|
68
|
+
my @frames;
|
|
69
|
+
my @heredocs;
|
|
70
|
+
my $quote = '';
|
|
71
|
+
my $line_number = 0;
|
|
72
|
+
|
|
73
|
+
while (my $line = <$source>) {
|
|
74
|
+
$line_number++;
|
|
75
|
+
if (@heredocs) {
|
|
76
|
+
my $candidate = $line;
|
|
77
|
+
$candidate =~ s/\r?\n\z//;
|
|
78
|
+
$candidate =~ s/^\t+// if $heredocs[0]{strip_tabs};
|
|
79
|
+
shift @heredocs if $candidate eq $heredocs[0]{delimiter};
|
|
80
|
+
next;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
my $length = length $line;
|
|
84
|
+
for (my $i = 0; $i < $length; $i++) {
|
|
85
|
+
my $char = substr($line, $i, 1);
|
|
86
|
+
if ($quote eq "'") {
|
|
87
|
+
$quote = '' if $char eq "'";
|
|
88
|
+
next;
|
|
89
|
+
}
|
|
90
|
+
if ($char eq '\\') {
|
|
91
|
+
$i++;
|
|
92
|
+
next;
|
|
93
|
+
}
|
|
94
|
+
if ($quote eq '"' && $char eq '"') {
|
|
95
|
+
$quote = '';
|
|
96
|
+
next;
|
|
97
|
+
}
|
|
98
|
+
if ($char eq "'" && $quote eq '') {
|
|
99
|
+
$quote = "'";
|
|
100
|
+
next;
|
|
101
|
+
}
|
|
102
|
+
if ($char eq '"' && $quote eq '') {
|
|
103
|
+
$quote = '"';
|
|
104
|
+
next;
|
|
105
|
+
}
|
|
106
|
+
if ($char eq '#' && $quote eq '' && ($i == 0 || substr($line, $i - 1, 1) =~ /[\s;|&()]/)) {
|
|
107
|
+
last;
|
|
108
|
+
}
|
|
109
|
+
if ($char eq '$' && substr($line, $i + 1, 1) eq '(') {
|
|
110
|
+
push @frames, { depth => 1, quote => $quote };
|
|
111
|
+
$quote = '';
|
|
112
|
+
$i++;
|
|
113
|
+
next;
|
|
114
|
+
}
|
|
115
|
+
if (@frames && $quote eq '' && $char eq '(') {
|
|
116
|
+
$frames[-1]{depth}++;
|
|
117
|
+
next;
|
|
118
|
+
}
|
|
119
|
+
if (@frames && $quote eq '' && $char eq ')') {
|
|
120
|
+
$frames[-1]{depth}--;
|
|
121
|
+
if ($frames[-1]{depth} == 0) {
|
|
122
|
+
my $frame = pop @frames;
|
|
123
|
+
$quote = $frame->{quote};
|
|
124
|
+
}
|
|
125
|
+
next;
|
|
126
|
+
}
|
|
127
|
+
next unless $quote eq '' && $char eq '<' && substr($line, $i + 1, 1) eq '<';
|
|
128
|
+
if (@frames) {
|
|
129
|
+
print STDERR "$path:$line_number\n";
|
|
130
|
+
exit 1;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
my $j = $i + 2;
|
|
134
|
+
my $strip_tabs = substr($line, $j, 1) eq '-';
|
|
135
|
+
$j++ if $strip_tabs;
|
|
136
|
+
$j++ while substr($line, $j, 1) =~ /[ \t]/;
|
|
137
|
+
my $delimiter = '';
|
|
138
|
+
my $delimiter_quote = '';
|
|
139
|
+
for (; $j < $length; $j++) {
|
|
140
|
+
my $token = substr($line, $j, 1);
|
|
141
|
+
if ($delimiter_quote) {
|
|
142
|
+
if ($token eq $delimiter_quote) {
|
|
143
|
+
$delimiter_quote = '';
|
|
144
|
+
} elsif ($token eq '\\' && $delimiter_quote eq '"') {
|
|
145
|
+
$j++;
|
|
146
|
+
$delimiter .= substr($line, $j, 1);
|
|
147
|
+
} else {
|
|
148
|
+
$delimiter .= $token;
|
|
149
|
+
}
|
|
150
|
+
next;
|
|
151
|
+
}
|
|
152
|
+
if ($token eq "'" || $token eq '"') {
|
|
153
|
+
$delimiter_quote = $token;
|
|
154
|
+
next;
|
|
155
|
+
}
|
|
156
|
+
if ($token eq '\\') {
|
|
157
|
+
$j++;
|
|
158
|
+
$delimiter .= substr($line, $j, 1);
|
|
159
|
+
next;
|
|
160
|
+
}
|
|
161
|
+
last if $token =~ /[\s;|&()<>]/;
|
|
162
|
+
$delimiter .= $token;
|
|
163
|
+
}
|
|
164
|
+
push @heredocs, { delimiter => $delimiter, strip_tabs => $strip_tabs };
|
|
165
|
+
$i = $j - 1;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
exit 0;
|
|
170
|
+
PERL
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
test_help_includes_entire_header() {
|
|
174
|
+
local help
|
|
175
|
+
help=$("$ROOT/bin/fm-brief.sh" --help)
|
|
176
|
+
assert_contains "$help" "Refuses to overwrite an existing brief." "fm-brief.sh --help omitted its header terminator"
|
|
177
|
+
pass "fm-brief.sh: --help renders the complete header"
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
# Registry with one project per delivery mode. fm-brief.sh no longer reads it -
|
|
181
|
+
# the ship mode arrives as an explicit flag - so this fixture exists to prove the
|
|
182
|
+
# scaffold ignores the registered posture (test_ship_mode_is_explicit_not_registry).
|
|
183
|
+
write_registry() {
|
|
184
|
+
local home=$1
|
|
185
|
+
mkdir -p "$home/data"
|
|
186
|
+
cat > "$home/data/projects.md" <<'EOF'
|
|
187
|
+
- direct-proj [direct-PR] - fixture for direct-PR mode (added 2026-07-01)
|
|
188
|
+
- local-proj [local-only] - fixture for local-only mode (added 2026-07-01)
|
|
189
|
+
EOF
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# fm-brief.sh must exit 0 and produce a brief with no unreplaced shell
|
|
193
|
+
# metacharacter corruption for every ship delivery mode. This also guards
|
|
194
|
+
# against any *new* unescaped apostrophe or unbalanced quote later added to
|
|
195
|
+
# one of these DOD blocks, since a broken heredoc corrupts or empties the
|
|
196
|
+
# generated brief content, not just the script's own syntax.
|
|
197
|
+
test_ship_modes_generate_clean_briefs() {
|
|
198
|
+
local home id mode brief status
|
|
199
|
+
home="$TMP_ROOT/ship-home"
|
|
200
|
+
write_registry "$home"
|
|
201
|
+
|
|
202
|
+
for id_mode in "brief-nomistakes-a1:no-mistakes" "brief-directpr-a2:direct-PR" "brief-localonly-a3:local-only"; do
|
|
203
|
+
id=${id_mode%%:*}
|
|
204
|
+
mode=${id_mode##*:}
|
|
205
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" some-proj --mode "$mode" >/dev/null 2>&1; status=$?
|
|
206
|
+
expect_code 0 "$status" "fm-brief.sh $id --mode $mode should exit 0"
|
|
207
|
+
brief="$home/data/$id/brief.md"
|
|
208
|
+
assert_present "$brief" "$id: brief was not scaffolded"
|
|
209
|
+
assert_grep "# Definition of done" "$brief" "$id: brief missing Definition of done section"
|
|
210
|
+
grep -qx "Delivery contract: mode=$mode" "$brief" \
|
|
211
|
+
|| fail "$id: brief did not record its machine-readable delivery contract line"
|
|
212
|
+
assert_grep "{TASK}" "$brief" "$id: brief missing the {TASK} placeholder"
|
|
213
|
+
assert_grep "mid-task \`working:\` line (including setup complete) is nonterminal" "$brief" \
|
|
214
|
+
"$id: brief missing nonterminal working:/setup-complete gate protection"
|
|
215
|
+
assert_no_grep "EOF" "$brief" "$id: brief leaked a heredoc EOF marker (unterminated heredoc)"
|
|
216
|
+
done
|
|
217
|
+
pass "fm-brief.sh: no-mistakes/direct-PR/local-only briefs generate cleanly"
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
# A ship task's delivery mode is firstmate's per-task decision, so a missing or
|
|
221
|
+
# unusable value must stop the scaffold instead of silently defaulting. The
|
|
222
|
+
# no-mistakes-prod-only row is the conditional registry policy: it is never a task
|
|
223
|
+
# mode, and its refusal must say to classify the task's surface first.
|
|
224
|
+
test_ship_mode_is_required_and_closed_set() {
|
|
225
|
+
local home id out status label flag expect
|
|
226
|
+
home="$TMP_ROOT/mode-required-home"
|
|
227
|
+
mkdir -p "$home/data"
|
|
228
|
+
id=0
|
|
229
|
+
while IFS='|' read -r label flag expect; do
|
|
230
|
+
[ -n "$label" ] || continue
|
|
231
|
+
id=$((id + 1))
|
|
232
|
+
# shellcheck disable=SC2086 # flag is an intentional word-split arg list (may be empty)
|
|
233
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "brief-required-$id" some-proj $flag 2>&1)
|
|
234
|
+
status=$?
|
|
235
|
+
[ "$status" -ne 0 ] || fail "$label: expected a non-zero exit"
|
|
236
|
+
assert_contains "$out" "$expect" "$label: refusal did not explain the contract"
|
|
237
|
+
assert_absent "$home/data/brief-required-$id/brief.md" "$label: refused scaffold still wrote a brief"
|
|
238
|
+
done <<'ROWS'
|
|
239
|
+
missing --mode||ship briefs require --mode
|
|
240
|
+
empty --mode value|--mode|requires a value
|
|
241
|
+
unknown mode value|--mode nope|must be one of no-mistakes, direct-PR, local-only
|
|
242
|
+
conditional policy is not a task mode|--mode no-mistakes-prod-only|classify this task's surface
|
|
243
|
+
ROWS
|
|
244
|
+
pass "fm-brief.sh: ship --mode is required and closed-set validated"
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
# The registry is the captain's standing posture, not this task's answer: the
|
|
248
|
+
# scaffold must follow the explicit flag even when the project is registered
|
|
249
|
+
# with a different mode, and must not consult the registry at all.
|
|
250
|
+
test_ship_mode_is_explicit_not_registry() {
|
|
251
|
+
local home brief
|
|
252
|
+
home="$TMP_ROOT/explicit-over-registry-home"
|
|
253
|
+
write_registry "$home"
|
|
254
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" brief-explicit-a5 direct-proj --mode no-mistakes >/dev/null 2>&1 \
|
|
255
|
+
|| fail "explicit no-mistakes brief on a direct-PR project should scaffold"
|
|
256
|
+
brief="$home/data/brief-explicit-a5/brief.md"
|
|
257
|
+
grep -qx "Delivery contract: mode=no-mistakes" "$brief" \
|
|
258
|
+
|| fail "registered direct-PR posture overrode the explicit --mode"
|
|
259
|
+
assert_grep "Firstmate will then instruct you to run /no-mistakes" "$brief" \
|
|
260
|
+
"explicit no-mistakes brief did not render the pipeline definition of done"
|
|
261
|
+
|
|
262
|
+
# An unregistered project is not a blocker either, because nothing is looked up.
|
|
263
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" brief-explicit-a6 never-registered --mode local-only >/dev/null 2>&1 \
|
|
264
|
+
|| fail "unregistered project should still scaffold from the explicit mode"
|
|
265
|
+
grep -qx "Delivery contract: mode=local-only" "$home/data/brief-explicit-a6/brief.md" \
|
|
266
|
+
|| fail "unregistered project did not honour the explicit --mode"
|
|
267
|
+
pass "fm-brief.sh: the explicit ship mode wins over the registered posture"
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
# yolo is firstmate's merge authority and never reaches the worker, and a scout
|
|
271
|
+
# or charter carries no delivery contract. Each must refuse rather than accept and
|
|
272
|
+
# discard the flag, which would look recorded but change nothing.
|
|
273
|
+
test_delivery_flags_are_refused_where_they_do_not_apply() {
|
|
274
|
+
local home out status label args expect
|
|
275
|
+
home="$TMP_ROOT/refused-flags-home"
|
|
276
|
+
mkdir -p "$home/data"
|
|
277
|
+
while IFS='|' read -r label args expect; do
|
|
278
|
+
[ -n "$label" ] || continue
|
|
279
|
+
# shellcheck disable=SC2086 # args is an intentional word-split arg list
|
|
280
|
+
out=$(FM_HOME="$home" "$ROOT/bin/fm-brief.sh" $args 2>&1)
|
|
281
|
+
status=$?
|
|
282
|
+
[ "$status" -ne 0 ] || fail "$label: expected a non-zero exit"
|
|
283
|
+
assert_contains "$out" "$expect" "$label: refusal did not explain why"
|
|
284
|
+
done <<'ROWS'
|
|
285
|
+
yolo on a ship brief|brief-refused-b1 some-proj --mode direct-PR --yolo on|--yolo is not a brief input
|
|
286
|
+
yolo=value form on a ship brief|brief-refused-b2 some-proj --mode direct-PR --yolo=off|--yolo is not a brief input
|
|
287
|
+
mode on a scout brief|brief-refused-b3 some-proj --scout --mode direct-PR|--mode applies only to ship briefs
|
|
288
|
+
mode on a secondmate charter|brief-refused-b4 --secondmate --no-projects --mode no-mistakes|--mode applies only to ship briefs
|
|
289
|
+
ROWS
|
|
290
|
+
pass "fm-brief.sh: --yolo and scout/secondmate --mode are refused, never silently dropped"
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
test_faster_paths_use_configured_authority_without_stacked_review() {
|
|
294
|
+
local home id brief
|
|
295
|
+
home="$TMP_ROOT/configured-authority-home"
|
|
296
|
+
write_registry "$home"
|
|
297
|
+
id="brief-direct-authority-a4"
|
|
298
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" direct-proj --mode direct-PR >/dev/null 2>&1
|
|
299
|
+
brief="$home/data/$id/brief.md"
|
|
300
|
+
assert_grep "The configured merge authority decides whether to merge the PR; firstmate relays the outcome." "$brief" \
|
|
301
|
+
"direct-PR brief lost configured merge authority"
|
|
302
|
+
assert_no_grep "The captain reviews and merges the PR" "$brief" \
|
|
303
|
+
"direct-PR brief hard-coded captain-only authority"
|
|
304
|
+
id="brief-local-authority-a4"
|
|
305
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" local-proj --mode local-only >/dev/null 2>&1
|
|
306
|
+
brief="$home/data/$id/brief.md"
|
|
307
|
+
assert_grep "The configured merge authority approves the ready branch, then firstmate merges it into local \`main\` through the guarded fast-forward path." "$brief" \
|
|
308
|
+
"local-only brief lost configured merge authority and guarded landing"
|
|
309
|
+
assert_no_grep "The captain approves the ready branch" "$brief" \
|
|
310
|
+
"local-only brief hard-coded captain-only authority"
|
|
311
|
+
assert_no_grep "Firstmate then reviews your branch diff" "$brief" \
|
|
312
|
+
"local-only brief retained a personal review stacked on the selected delivery path"
|
|
313
|
+
assert_no_grep "make \`--intent\` preserve all relevant content from this brief" "$home/data/$id/brief.md" \
|
|
314
|
+
"local-only brief must not include the no-mistakes --intent contract"
|
|
315
|
+
id="brief-direct-intent-a4"
|
|
316
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" direct-proj --mode direct-PR >/dev/null 2>&1
|
|
317
|
+
assert_no_grep "make \`--intent\` preserve all relevant content from this brief" "$home/data/$id/brief.md" \
|
|
318
|
+
"direct-PR brief must not include the no-mistakes --intent contract"
|
|
319
|
+
pass "fm-brief.sh: faster paths use configured authority without stacked review"
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
# Pin the specific line the bug lived on: the no-mistakes DOD's no-mistakes
|
|
323
|
+
# reference must render as plain prose with no dangling apostrophe artifact.
|
|
324
|
+
test_no_mistakes_dod_wording() {
|
|
325
|
+
local home id brief
|
|
326
|
+
home="$TMP_ROOT/wording-home"
|
|
327
|
+
mkdir -p "$home/data"
|
|
328
|
+
id="brief-wording-b1"
|
|
329
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" some-proj --mode no-mistakes >/dev/null 2>&1
|
|
330
|
+
brief="$home/data/$id/brief.md"
|
|
331
|
+
assert_present "$brief" "brief was not scaffolded"
|
|
332
|
+
assert_grep "no-mistakes itself provides for the mechanics" "$brief" \
|
|
333
|
+
"no-mistakes DOD lost its guidance-reference sentence"
|
|
334
|
+
# shellcheck disable=SC2016 # single quotes are deliberate: the backticks must stay literal
|
|
335
|
+
assert_grep '`no-mistakes axi run --help`' "$brief" \
|
|
336
|
+
"no-mistakes DOD must render literal backticks around the help command"
|
|
337
|
+
# shellcheck disable=SC2016 # single quotes are deliberate: the backticks must stay literal
|
|
338
|
+
assert_grep '`help`' "$brief" \
|
|
339
|
+
"no-mistakes DOD must render literal backticks around help"
|
|
340
|
+
assert_grep "make \`--intent\` preserve all relevant content from this brief" "$brief" \
|
|
341
|
+
"no-mistakes DOD must require --intent to retain the accepted task contract"
|
|
342
|
+
assert_grep "carrying only each requirement's current accepted form" "$brief" \
|
|
343
|
+
"no-mistakes DOD must replace superseded requirements with their current accepted form"
|
|
344
|
+
assert_grep "retain direct requirements instead of substituting a diff summary" "$brief" \
|
|
345
|
+
"no-mistakes DOD must keep direct requirements and exclude generic scaffold boilerplate from --intent"
|
|
346
|
+
assert_grep "exclude generic operational, status, delivery, and other scaffold boilerplate unless it is task-specific" "$brief" \
|
|
347
|
+
"no-mistakes DOD must exclude non-task-specific scaffold boilerplate from --intent"
|
|
348
|
+
# Apostrophe prose in the DOD is structurally safe (no `$(...)` wrapper around
|
|
349
|
+
# the heredoc), so it renders verbatim instead of being reworded or escaped
|
|
350
|
+
# away. test_no_heredoc_in_command_substitution guards the structure that makes
|
|
351
|
+
# it safe.
|
|
352
|
+
assert_grep "carrying only each requirement's current accepted form" "$brief" \
|
|
353
|
+
"no-mistakes DOD lost the apostrophe prose that the structural fix makes parse-safe"
|
|
354
|
+
|
|
355
|
+
# The --yes ban is a fleet-wide prohibition, not a preference, and it must not
|
|
356
|
+
# claim an enforcement the tool does not provide: this is instruction only.
|
|
357
|
+
assert_grep "NEVER pass \`--yes\` (or \`-y\`) to \`no-mistakes axi run\` or \`no-mistakes axi respond\`. It is banned fleet-wide." "$brief" \
|
|
358
|
+
"no-mistakes DOD must state the --yes ban as a prohibition"
|
|
359
|
+
assert_grep "answering your own ask-user finding is a hard rule violation" "$brief" \
|
|
360
|
+
"no-mistakes DOD must say why --yes is banned"
|
|
361
|
+
assert_no_grep "Avoid \`--yes\`" "$brief" \
|
|
362
|
+
"no-mistakes DOD still states the --yes ban as a preference"
|
|
363
|
+
assert_no_grep "no-mistakes refuses" "$brief" \
|
|
364
|
+
"no-mistakes DOD must not claim the tool itself refuses --yes"
|
|
365
|
+
pass "fm-brief.sh: no-mistakes DOD keeps its apostrophe prose and bans --yes outright"
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
test_ship_project_memory_wording() {
|
|
369
|
+
local home id brief
|
|
370
|
+
home="$TMP_ROOT/project-memory-home"
|
|
371
|
+
mkdir -p "$home/data"
|
|
372
|
+
id="brief-memory-c1"
|
|
373
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" some-proj --mode no-mistakes >/dev/null 2>&1
|
|
374
|
+
brief="$home/data/$id/brief.md"
|
|
375
|
+
assert_present "$brief" "brief was not scaffolded"
|
|
376
|
+
assert_grep "Record only project knowledge useful to almost every future session." "$brief" \
|
|
377
|
+
"project-memory contract lost the durable-knowledge bar"
|
|
378
|
+
assert_grep "prefer a pointer to the authoritative file, command, or doc over copying the detail" "$brief" \
|
|
379
|
+
"project-memory contract lost pointer-over-copy guidance"
|
|
380
|
+
assert_grep "lacks \`## Maintaining this file\`, add that short self-governance section" "$brief" \
|
|
381
|
+
"project-memory contract lost the self-governance add-in-same-pass rule"
|
|
382
|
+
pass "fm-brief.sh: ship project-memory wording carries the AGENTS.md authoring bar"
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
test_herdr_lab_contract_is_explicit_and_complete() {
|
|
386
|
+
local home id brief
|
|
387
|
+
home="$TMP_ROOT/herdr-lab-home"
|
|
388
|
+
mkdir -p "$home/data"
|
|
389
|
+
id="brief-herdr-lab-d1"
|
|
390
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" firstmate --mode no-mistakes --herdr-lab >/dev/null 2>&1
|
|
391
|
+
brief="$home/data/$id/brief.md"
|
|
392
|
+
assert_present "$brief" "Herdr lab brief was not scaffolded"
|
|
393
|
+
assert_grep "# Herdr isolation - HARD SAFETY CONTRACT" "$brief" \
|
|
394
|
+
"Herdr lab brief missing its hard safety contract"
|
|
395
|
+
assert_grep "HERDR_LAB_HELPER='$ROOT/bin/fm-herdr-lab.sh'" "$brief" \
|
|
396
|
+
"Herdr lab brief must bind the absolute Firstmate helper path"
|
|
397
|
+
assert_grep "HERDR_LAB_SESSION=\$(\"\$HERDR_LAB_HELPER\" name $id)" "$brief" \
|
|
398
|
+
"Herdr lab brief missing helper-owned session naming"
|
|
399
|
+
assert_grep "\"\$HERDR_LAB_HELPER\" provision \"\$HERDR_LAB_SESSION\"" "$brief" \
|
|
400
|
+
"Herdr lab brief missing helper-owned provisioning"
|
|
401
|
+
assert_grep "\"\$HERDR_LAB_HELPER\" teardown \"\$HERDR_LAB_SESSION\"" "$brief" \
|
|
402
|
+
"Herdr lab brief missing helper-owned teardown"
|
|
403
|
+
assert_grep "required trailing \`--session \"\$HERDR_LAB_SESSION\"\`" "$brief" \
|
|
404
|
+
"Herdr lab brief missing the per-call trailing session contract"
|
|
405
|
+
assert_grep "direct \`herdr server stop\`" "$brief" \
|
|
406
|
+
"Herdr lab brief missing the forbidden server-global command list"
|
|
407
|
+
assert_grep "records the live default session before provisioning" "$brief" \
|
|
408
|
+
"Herdr lab brief missing the before tripwire"
|
|
409
|
+
assert_grep "verifies the identical fleet state after teardown" "$brief" \
|
|
410
|
+
"Herdr lab brief missing the after tripwire"
|
|
411
|
+
assert_no_grep "Herdr lifecycle declaration - NOT ENABLED" "$brief" \
|
|
412
|
+
"Herdr lab brief retained the unguarded declaration"
|
|
413
|
+
pass "fm-brief.sh: --herdr-lab emits the complete hard safety contract"
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
test_herdr_lab_contract_quotes_foreign_firstmate_path() {
|
|
417
|
+
local home id brief foreign_root helper
|
|
418
|
+
home="$TMP_ROOT/herdr-lab-foreign-home"
|
|
419
|
+
foreign_root="$TMP_ROOT/firstmate helper's root"
|
|
420
|
+
mkdir -p "$home/data"
|
|
421
|
+
id="brief-herdr-lab-foreign-d2"
|
|
422
|
+
helper=$(printf '%s' "$foreign_root/bin/fm-herdr-lab.sh" | sed "s/'/'\\\\''/g")
|
|
423
|
+
helper="'$helper'"
|
|
424
|
+
FM_HOME="$home" FM_ROOT_OVERRIDE="$foreign_root" "$ROOT/bin/fm-brief.sh" "$id" foreign --scout --herdr-lab >/dev/null 2>&1
|
|
425
|
+
brief="$home/data/$id/brief.md"
|
|
426
|
+
assert_grep "HERDR_LAB_HELPER=$helper" "$brief" \
|
|
427
|
+
"Herdr lab brief must shell-quote an absolute Firstmate helper path"
|
|
428
|
+
assert_no_grep "bin/fm-herdr-lab.sh name $id" "$brief" \
|
|
429
|
+
"Herdr lab brief must not invoke a worktree-relative helper"
|
|
430
|
+
pass "fm-brief.sh: --herdr-lab uses its quoted Firstmate-owned helper path"
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
test_herdr_lab_omission_is_loud_for_ship_and_scout() {
|
|
434
|
+
local home id brief
|
|
435
|
+
home="$TMP_ROOT/herdr-gate-home"
|
|
436
|
+
mkdir -p "$home/data"
|
|
437
|
+
for kind in ship scout; do
|
|
438
|
+
id="brief-herdr-gate-$kind"
|
|
439
|
+
if [ "$kind" = scout ]; then
|
|
440
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" firstmate --scout >/dev/null 2>&1
|
|
441
|
+
else
|
|
442
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" firstmate --mode no-mistakes >/dev/null 2>&1
|
|
443
|
+
fi
|
|
444
|
+
brief="$home/data/$id/brief.md"
|
|
445
|
+
assert_grep "# Herdr lifecycle declaration - NOT ENABLED" "$brief" \
|
|
446
|
+
"$kind brief silently omitted the Herdr declaration"
|
|
447
|
+
assert_grep "regenerate the brief with \`--herdr-lab\` before dispatch" "$brief" \
|
|
448
|
+
"$kind brief missing the fail-visible regeneration instruction"
|
|
449
|
+
done
|
|
450
|
+
pass "fm-brief.sh: ship and scout scaffolds make omitted Herdr intent fail-visible"
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
# Regression (issue #2575): AGENTS.md section 11 and this script's own help tell
|
|
454
|
+
# firstmate to replace EVERY `{TASK}` placeholder. The unguarded Herdr gate used
|
|
455
|
+
# to quote `{TASK}` in its own prose, so that documented global replace spliced
|
|
456
|
+
# the whole task body into the middle of the gate's sentence - silently
|
|
457
|
+
# destroying the one contract that exists precisely because the scaffold cannot
|
|
458
|
+
# see the task text. The placeholder must exist only at the genuine fill site,
|
|
459
|
+
# so the documented fill leaves the gate intact and the body appears once.
|
|
460
|
+
test_documented_global_replace_leaves_the_herdr_gate_intact() {
|
|
461
|
+
local home id brief kind count content filled body
|
|
462
|
+
home="$TMP_ROOT/task-fill-site-home"
|
|
463
|
+
mkdir -p "$home/data"
|
|
464
|
+
body='Restart the herdr session, then profile it'
|
|
465
|
+
for kind in ship scout; do
|
|
466
|
+
id="brief-fill-site-$kind"
|
|
467
|
+
if [ "$kind" = scout ]; then
|
|
468
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" firstmate --scout >/dev/null 2>&1
|
|
469
|
+
else
|
|
470
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" "$id" firstmate --mode no-mistakes >/dev/null 2>&1
|
|
471
|
+
fi
|
|
472
|
+
brief="$home/data/$id/brief.md"
|
|
473
|
+
assert_present "$brief" "$kind brief was not scaffolded"
|
|
474
|
+
count=$(grep -c -F '{TASK}' "$brief")
|
|
475
|
+
[ "$count" = 1 ] \
|
|
476
|
+
|| fail "$kind brief must carry exactly one {TASK} fill site, found $count"
|
|
477
|
+
content=$(cat "$brief")
|
|
478
|
+
filled=${content//'{TASK}'/$body}
|
|
479
|
+
count=$(printf '%s\n' "$filled" | grep -c -F "$body")
|
|
480
|
+
[ "$count" = 1 ] \
|
|
481
|
+
|| fail "$kind brief: the documented global {TASK} replace duplicated the task body $count times"
|
|
482
|
+
printf '%s\n' "$filled" | grep -qF 'this scaffold cannot inspect the task text' \
|
|
483
|
+
|| fail "$kind brief: the Herdr safety gate did not survive the documented global replace"
|
|
484
|
+
done
|
|
485
|
+
pass "fm-brief.sh: the documented {TASK} fill cannot corrupt the Herdr safety gate"
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
test_secondmate_no_projects_charter() {
|
|
489
|
+
local home brief status
|
|
490
|
+
home="$TMP_ROOT/no-projects-home"
|
|
491
|
+
mkdir -p "$home/data"
|
|
492
|
+
|
|
493
|
+
# The deliberate --no-projects signal scaffolds a valid project-less charter for
|
|
494
|
+
# a domain whose subject is the firstmate repo itself (no clones needed).
|
|
495
|
+
FM_HOME="$home" FM_SECONDMATE_CHARTER='firstmate self-development' \
|
|
496
|
+
FM_SECONDMATE_SCOPE='firstmate repo work' \
|
|
497
|
+
"$ROOT/bin/fm-brief.sh" fdev --secondmate --no-projects >/dev/null 2>&1; status=$?
|
|
498
|
+
expect_code 0 "$status" "--no-projects secondmate brief should exit 0"
|
|
499
|
+
brief="$home/data/fdev/brief.md"
|
|
500
|
+
assert_present "$brief" "project-less charter was not scaffolded"
|
|
501
|
+
assert_grep "# Project clones" "$brief" "project-less charter dropped the Project clones heading"
|
|
502
|
+
assert_grep "None. This is a project-less domain" "$brief" \
|
|
503
|
+
"project-less charter did not render a sensible no-clones note"
|
|
504
|
+
assert_grep "its crews take pooled worktrees of that repo" "$brief" \
|
|
505
|
+
"project-less charter operating model lost the pooled-worktree note"
|
|
506
|
+
assert_no_grep "The projects above are local clones" "$brief" \
|
|
507
|
+
"project-less charter kept the with-projects operating-model line"
|
|
508
|
+
assert_grep 'working [key=<work-slug>]' "$brief" \
|
|
509
|
+
"secondmate charter did not key material routed-work phases"
|
|
510
|
+
assert_grep 'resolved [key=<work-slug>]' "$brief" \
|
|
511
|
+
"secondmate charter did not close a quietly ended routed-work phase"
|
|
512
|
+
assert_grep 'use the same key on its later' "$brief" \
|
|
513
|
+
"secondmate charter did not supersede working phases with later states"
|
|
514
|
+
if grep -nE '^-[[:space:]]*$' "$brief" >/dev/null; then
|
|
515
|
+
fail "project-less charter left a stray empty project bullet"
|
|
516
|
+
fi
|
|
517
|
+
|
|
518
|
+
# Accidental omission (no projects, no signal) still fails loudly, writing nothing.
|
|
519
|
+
FM_HOME="$home" FM_SECONDMATE_CHARTER='x' "$ROOT/bin/fm-brief.sh" oops --secondmate >/dev/null 2>&1; status=$?
|
|
520
|
+
expect_code 1 "$status" "secondmate brief with no projects and no --no-projects must fail"
|
|
521
|
+
assert_absent "$home/data/oops/brief.md" "loud-failure secondmate brief still wrote a file"
|
|
522
|
+
|
|
523
|
+
# --no-projects is mutually exclusive with a project list.
|
|
524
|
+
FM_HOME="$home" FM_SECONDMATE_CHARTER='x' "$ROOT/bin/fm-brief.sh" oops2 --secondmate --no-projects alpha >/dev/null 2>&1; status=$?
|
|
525
|
+
expect_code 1 "$status" "--no-projects combined with a project list must fail"
|
|
526
|
+
|
|
527
|
+
# --no-projects applies only to secondmate charters, never a ship/scout brief.
|
|
528
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" oops3 somerepo --no-projects >/dev/null 2>&1; status=$?
|
|
529
|
+
expect_code 1 "$status" "--no-projects on a ship brief must fail"
|
|
530
|
+
|
|
531
|
+
pass "fm-brief.sh: --no-projects scaffolds a project-less charter and guards misuse"
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
test_secondmate_marked_request_reporting_contract() {
|
|
535
|
+
local home brief
|
|
536
|
+
home="$TMP_ROOT/marked-request-reporting-home"
|
|
537
|
+
mkdir -p "$home/data"
|
|
538
|
+
FM_HOME="$home" FM_CLASSIFY_PAUSED_VERB=paused \
|
|
539
|
+
FM_SECONDMATE_CHARTER='Handle routed domain work.' \
|
|
540
|
+
"$ROOT/bin/fm-brief.sh" marked-request-reporting --secondmate --no-projects >/dev/null 2>&1
|
|
541
|
+
brief="$home/data/marked-request-reporting/brief.md"
|
|
542
|
+
|
|
543
|
+
assert_grep 'A marked request requires one correlated answer after the work' "$brief" \
|
|
544
|
+
"secondmate charter did not require the correlated answer after the work"
|
|
545
|
+
assert_grep 'does not require a separate receipt or start acknowledgement' "$brief" \
|
|
546
|
+
"secondmate charter did not reject a separate receipt/start acknowledgement"
|
|
547
|
+
assert_grep "Never append \`working:\` merely to acknowledge receipt or announce that a marked request has started." "$brief" \
|
|
548
|
+
"secondmate charter did not forbid a generic working acknowledgement"
|
|
549
|
+
assert_no_grep "Give every routed-work phase a stable key: open it with \`working" "$brief" \
|
|
550
|
+
"secondmate charter retained the unconditional working opener"
|
|
551
|
+
assert_grep 'When a routed-work phase has a supervisor-actionable material change worth reporting under the rule above' "$brief" \
|
|
552
|
+
"secondmate charter did not limit keyed phases to reportable material changes"
|
|
553
|
+
assert_grep "If its first reportable event is \`working [key=<work-slug>]: {material phase}\`" "$brief" \
|
|
554
|
+
"secondmate charter lost keyed working syntax for a reportable material phase"
|
|
555
|
+
assert_grep "use the same key on its later \`paused\`, \`done\`, \`failed\`, \`needs-decision\`, or \`blocked\` event" "$brief" \
|
|
556
|
+
"secondmate charter lost same-key closure for a reportable material phase"
|
|
557
|
+
assert_grep 'resolved [key=<work-slug>]' "$brief" \
|
|
558
|
+
"secondmate charter lost resolved closure for a keyed material phase"
|
|
559
|
+
|
|
560
|
+
assert_grep 'include that exact token in your parent status reply' "$brief" \
|
|
561
|
+
"secondmate charter lost correlated parent results"
|
|
562
|
+
assert_grep 'For a terse result, a status line is the whole answer.' "$brief" \
|
|
563
|
+
"secondmate charter lost terse result reporting"
|
|
564
|
+
assert_grep 'append a status line that points to that doc' "$brief" \
|
|
565
|
+
"secondmate charter lost detailed document pointers"
|
|
566
|
+
assert_grep 'Report only true captain-relevant outcomes or a declared external wait' "$brief" \
|
|
567
|
+
"secondmate charter lost declared external waits"
|
|
568
|
+
assert_grep 'a captain decision, a real blocker, a failure, work ready for review, or work you landed' "$brief" \
|
|
569
|
+
"secondmate charter lost decisions, blockers, failures, ready outcomes, or landed work"
|
|
570
|
+
# Under standing merge authority nothing is ever "ready for review", so the
|
|
571
|
+
# landed merge is the trigger a charter without this line silently omits.
|
|
572
|
+
assert_grep 'a merge you performed yourself under standing merge authority and one the captain merged on the forge' "$brief" \
|
|
573
|
+
"secondmate charter did not name a landed merge as a reporting trigger"
|
|
574
|
+
assert_grep 'States: working, needs-decision, blocked, paused, done, failed.' "$brief" \
|
|
575
|
+
"secondmate charter changed the preserved status vocabulary"
|
|
576
|
+
pass "fm-brief.sh: marked requests avoid generic acknowledgements and preserve material reporting"
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
test_secondmate_directory_paths_are_absolute_and_output_is_stable() {
|
|
580
|
+
local root home data_override state_override brief baseline err status
|
|
581
|
+
root="$TMP_ROOT/relative-directory-inputs"
|
|
582
|
+
mkdir -p "$root"
|
|
583
|
+
root=$(cd "$root" && pwd -P)
|
|
584
|
+
home="$root/home"
|
|
585
|
+
data_override="$root/data-override"
|
|
586
|
+
state_override="$root/state-override"
|
|
587
|
+
mkdir -p "$home/data" "$home/state" "$data_override" "$state_override" \
|
|
588
|
+
"$root/cdpath/home/data" "$root/cdpath/home/state" \
|
|
589
|
+
"$root/cdpath/data-override" "$root/cdpath/state-override"
|
|
590
|
+
|
|
591
|
+
brief="$home/data/relative-home/brief.md"
|
|
592
|
+
FM_HOME="$home" FM_SECONDMATE_CHARTER=x \
|
|
593
|
+
"$ROOT/bin/fm-brief.sh" relative-home --secondmate --no-projects >/dev/null 2>&1
|
|
594
|
+
baseline="$root/absolute-home-charter"
|
|
595
|
+
cp "$brief" "$baseline"
|
|
596
|
+
rm -f "$brief"
|
|
597
|
+
(
|
|
598
|
+
cd "$root" || exit 1
|
|
599
|
+
CDPATH="$root/cdpath" FM_HOME=home FM_SECONDMATE_CHARTER=x \
|
|
600
|
+
"$ROOT/bin/fm-brief.sh" relative-home --secondmate --no-projects >/dev/null 2>&1
|
|
601
|
+
)
|
|
602
|
+
cmp -s "$baseline" "$brief" \
|
|
603
|
+
|| fail "relative FM_HOME changed charter bytes compared with the same absolute home"
|
|
604
|
+
assert_grep ">> '$home/state/relative-home.status'" "$brief" \
|
|
605
|
+
"relative FM_HOME did not render an absolute secondmate status path"
|
|
606
|
+
|
|
607
|
+
brief="$home/data/relative-state/brief.md"
|
|
608
|
+
FM_HOME="$home" FM_STATE_OVERRIDE="$state_override" FM_SECONDMATE_CHARTER=x \
|
|
609
|
+
"$ROOT/bin/fm-brief.sh" relative-state --secondmate --no-projects >/dev/null 2>&1
|
|
610
|
+
baseline="$root/absolute-state-charter"
|
|
611
|
+
cp "$brief" "$baseline"
|
|
612
|
+
rm -f "$brief"
|
|
613
|
+
(
|
|
614
|
+
cd "$root" || exit 1
|
|
615
|
+
CDPATH="$root/cdpath" FM_HOME="$home" FM_STATE_OVERRIDE=state-override FM_SECONDMATE_CHARTER=x \
|
|
616
|
+
"$ROOT/bin/fm-brief.sh" relative-state --secondmate --no-projects >/dev/null 2>&1
|
|
617
|
+
)
|
|
618
|
+
cmp -s "$baseline" "$brief" \
|
|
619
|
+
|| fail "relative FM_STATE_OVERRIDE changed charter bytes compared with the same absolute state directory"
|
|
620
|
+
assert_grep ">> '$state_override/relative-state.status'" "$brief" \
|
|
621
|
+
"relative FM_STATE_OVERRIDE did not render an absolute secondmate status path"
|
|
622
|
+
|
|
623
|
+
brief="$data_override/relative-data/brief.md"
|
|
624
|
+
FM_HOME="$home" FM_DATA_OVERRIDE="$data_override" FM_SECONDMATE_CHARTER=x \
|
|
625
|
+
"$ROOT/bin/fm-brief.sh" relative-data --secondmate --no-projects >/dev/null 2>&1
|
|
626
|
+
baseline="$root/absolute-data-charter"
|
|
627
|
+
cp "$brief" "$baseline"
|
|
628
|
+
rm -f "$brief"
|
|
629
|
+
(
|
|
630
|
+
cd "$root" || exit 1
|
|
631
|
+
CDPATH="$root/cdpath" FM_HOME="$home" FM_DATA_OVERRIDE=data-override FM_SECONDMATE_CHARTER=x \
|
|
632
|
+
"$ROOT/bin/fm-brief.sh" relative-data --secondmate --no-projects >/dev/null 2>&1
|
|
633
|
+
)
|
|
634
|
+
cmp -s "$baseline" "$brief" \
|
|
635
|
+
|| fail "relative FM_DATA_OVERRIDE changed charter bytes compared with the same absolute data directory"
|
|
636
|
+
assert_grep ">> '$home/state/relative-data.status'" "$brief" \
|
|
637
|
+
"relative FM_DATA_OVERRIDE changed the absolute default status path"
|
|
638
|
+
|
|
639
|
+
err="$root/unresolved.err"
|
|
640
|
+
(
|
|
641
|
+
cd "$root" || exit 1
|
|
642
|
+
FM_HOME=missing-home FM_SECONDMATE_CHARTER=x \
|
|
643
|
+
"$ROOT/bin/fm-brief.sh" unresolved-home --secondmate --no-projects >/dev/null 2>"$err"
|
|
644
|
+
); status=$?
|
|
645
|
+
expect_code 1 "$status" "an unresolved relative FM_HOME must fail"
|
|
646
|
+
assert_grep "FM_HOME directory cannot be resolved: missing-home" "$err" \
|
|
647
|
+
"unresolved relative FM_HOME did not fail loudly"
|
|
648
|
+
|
|
649
|
+
(
|
|
650
|
+
cd "$root" || exit 1
|
|
651
|
+
FM_HOME="$home" FM_STATE_OVERRIDE=missing-state FM_SECONDMATE_CHARTER=x \
|
|
652
|
+
"$ROOT/bin/fm-brief.sh" unresolved-state --secondmate --no-projects >/dev/null 2>"$err"
|
|
653
|
+
); status=$?
|
|
654
|
+
expect_code 1 "$status" "an unresolved relative FM_STATE_OVERRIDE must fail"
|
|
655
|
+
assert_grep "FM_STATE_OVERRIDE directory cannot be resolved: missing-state" "$err" \
|
|
656
|
+
"unresolved relative FM_STATE_OVERRIDE did not fail loudly"
|
|
657
|
+
|
|
658
|
+
(
|
|
659
|
+
cd "$root" || exit 1
|
|
660
|
+
FM_HOME="$home" FM_DATA_OVERRIDE=missing-data FM_SECONDMATE_CHARTER=x \
|
|
661
|
+
"$ROOT/bin/fm-brief.sh" unresolved-data --secondmate --no-projects >/dev/null 2>"$err"
|
|
662
|
+
); status=$?
|
|
663
|
+
expect_code 1 "$status" "an unresolved relative FM_DATA_OVERRIDE must fail"
|
|
664
|
+
assert_grep "FM_DATA_OVERRIDE directory cannot be resolved: missing-data" "$err" \
|
|
665
|
+
"unresolved relative FM_DATA_OVERRIDE did not fail loudly"
|
|
666
|
+
|
|
667
|
+
pass "fm-brief.sh: relative directory inputs ignore CDPATH, render stable absolute charter paths, or fail loudly"
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
test_herdr_lab_contract_applies_to_scouts_but_not_secondmates() {
|
|
671
|
+
local home brief status=0
|
|
672
|
+
home="$TMP_ROOT/herdr-kind-home"
|
|
673
|
+
mkdir -p "$home/data"
|
|
674
|
+
FM_HOME="$home" "$ROOT/bin/fm-brief.sh" herdr-scout firstmate --scout --herdr-lab >/dev/null 2>&1
|
|
675
|
+
brief="$home/data/herdr-scout/brief.md"
|
|
676
|
+
assert_grep "# Herdr isolation - HARD SAFETY CONTRACT" "$brief" \
|
|
677
|
+
"scout --herdr-lab brief missing the contract"
|
|
678
|
+
|
|
679
|
+
FM_HOME="$home" FM_SECONDMATE_CHARTER=ops "$ROOT/bin/fm-brief.sh" herdr-secondmate --secondmate firstmate --herdr-lab >/dev/null 2>&1 || status=$?
|
|
680
|
+
expect_code 1 "$status" "secondmate --herdr-lab must be rejected"
|
|
681
|
+
assert_absent "$home/data/herdr-secondmate/brief.md" \
|
|
682
|
+
"rejected secondmate --herdr-lab still wrote a brief"
|
|
683
|
+
pass "fm-brief.sh: Herdr lab contract covers scouts and rejects secondmate misuse"
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
test_pause_verb_override_renders_all_brief_scaffolds() {
|
|
687
|
+
local home kind id brief
|
|
688
|
+
home="$TMP_ROOT/pause-verb-home"
|
|
689
|
+
mkdir -p "$home/data"
|
|
690
|
+
|
|
691
|
+
for kind in ship scout secondmate; do
|
|
692
|
+
id="brief-pause-verb-$kind"
|
|
693
|
+
case "$kind" in
|
|
694
|
+
ship)
|
|
695
|
+
FM_HOME="$home" FM_CLASSIFY_PAUSED_VERB=awaiting \
|
|
696
|
+
"$ROOT/bin/fm-brief.sh" "$id" firstmate --mode no-mistakes >/dev/null 2>&1
|
|
697
|
+
;;
|
|
698
|
+
scout)
|
|
699
|
+
FM_HOME="$home" FM_CLASSIFY_PAUSED_VERB=awaiting \
|
|
700
|
+
"$ROOT/bin/fm-brief.sh" "$id" firstmate --scout >/dev/null 2>&1
|
|
701
|
+
;;
|
|
702
|
+
secondmate)
|
|
703
|
+
FM_HOME="$home" FM_CLASSIFY_PAUSED_VERB=awaiting \
|
|
704
|
+
"$ROOT/bin/fm-brief.sh" "$id" --secondmate --no-projects >/dev/null 2>&1
|
|
705
|
+
;;
|
|
706
|
+
esac
|
|
707
|
+
brief="$home/data/$id/brief.md"
|
|
708
|
+
assert_grep "States: working, needs-decision, blocked, awaiting, done, failed." "$brief" \
|
|
709
|
+
"$kind brief did not render the configured pause verb in its states list"
|
|
710
|
+
# shellcheck disable=SC2016 # Literal backticks and braces must remain unexpanded.
|
|
711
|
+
assert_grep 'Use `awaiting: {why}`' "$brief" \
|
|
712
|
+
"$kind brief did not instruct the configured pause status"
|
|
713
|
+
# shellcheck disable=SC2016 # Literal backticks and braces must remain unexpanded.
|
|
714
|
+
assert_no_grep '`paused: {why}`' "$brief" \
|
|
715
|
+
"$kind brief still instructs the default paused status"
|
|
716
|
+
assert_grep 'a blocker or wait clears' "$brief" \
|
|
717
|
+
"$kind brief did not require durable resolution when a blocker clears"
|
|
718
|
+
assert_grep 'even when the answer is what started that work' "$brief" \
|
|
719
|
+
"$kind brief did not warn that an answer-started done/working never closes a decision"
|
|
720
|
+
done
|
|
721
|
+
pass "fm-brief.sh: custom pause verb renders in every scaffold"
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
test_scout_and_secondmate_load_decision_hold_policy() {
|
|
725
|
+
local home scout charter
|
|
726
|
+
home="$TMP_ROOT/decision-policy-home"
|
|
727
|
+
mkdir -p "$home/data"
|
|
728
|
+
FM_HOME="$home" FM_ROOT_OVERRIDE="$ROOT" \
|
|
729
|
+
"$ROOT/bin/fm-brief.sh" sample-investigation sample --scout >/dev/null 2>&1
|
|
730
|
+
scout="$home/data/sample-investigation/brief.md"
|
|
731
|
+
assert_grep "$ROOT/.agents/skills/captain-hold-lifecycle/SKILL.md" "$scout" \
|
|
732
|
+
"scout brief did not load the captain-call policy before done"
|
|
733
|
+
assert_grep "pass its shared completion gate for the report and any visual review" "$scout" \
|
|
734
|
+
"scout brief did not cross-reference visual-review completion"
|
|
735
|
+
FM_HOME="$home" FM_ROOT_OVERRIDE="$ROOT" FM_SECONDMATE_CHARTER='sample reviews' \
|
|
736
|
+
"$ROOT/bin/fm-brief.sh" sample-mate --secondmate --no-projects >/dev/null 2>&1
|
|
737
|
+
charter="$home/data/sample-mate/brief.md"
|
|
738
|
+
assert_grep "load \`captain-hold-lifecycle\`" "$charter" \
|
|
739
|
+
"secondmate charter did not load the shared captain-call policy for detailed investigations"
|
|
740
|
+
pass "fm-brief.sh: investigation and visual-review completions load the shared decision policy"
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
# Scout and secondmate paths still scaffold well-formed briefs.
|
|
744
|
+
test_scout_and_secondmate_scaffold() {
|
|
745
|
+
local brief
|
|
746
|
+
FM_HOME="$BRIEF_HOME" "$ROOT/bin/fm-brief.sh" brief-scout-q6 alpha --scout >/dev/null 2>&1 \
|
|
747
|
+
|| fail "fm-brief.sh scout scaffold exited non-zero"
|
|
748
|
+
brief="$BRIEF_HOME/data/brief-scout-q6/brief.md"
|
|
749
|
+
assert_present "$brief" "scout brief was not scaffolded"
|
|
750
|
+
assert_grep "SCOUT task" "$brief" "scout brief must declare itself a scout task"
|
|
751
|
+
assert_grep "report.md" "$brief" "scout brief must point at the report deliverable"
|
|
752
|
+
assert_grep "you may host the Lavish review loop yourself" "$brief" \
|
|
753
|
+
"scout brief must mention the option to host a Lavish review loop"
|
|
754
|
+
|
|
755
|
+
FM_SECONDMATE_CHARTER='Supervise the alpha domain.' \
|
|
756
|
+
FM_HOME="$BRIEF_HOME" "$ROOT/bin/fm-brief.sh" brief-sm-q6 --secondmate alpha >/dev/null 2>&1 \
|
|
757
|
+
|| fail "fm-brief.sh secondmate scaffold exited non-zero"
|
|
758
|
+
brief="$BRIEF_HOME/data/brief-sm-q6/brief.md"
|
|
759
|
+
assert_present "$brief" "secondmate charter was not scaffolded"
|
|
760
|
+
assert_grep "persistent second mate" "$brief" \
|
|
761
|
+
"secondmate charter must declare its role"
|
|
762
|
+
pass "fm-brief: scout and secondmate code paths still scaffold well-formed briefs"
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
test_script_parses
|
|
766
|
+
test_no_heredoc_in_command_substitution
|
|
767
|
+
test_help_includes_entire_header
|
|
768
|
+
test_ship_modes_generate_clean_briefs
|
|
769
|
+
test_ship_mode_is_required_and_closed_set
|
|
770
|
+
test_ship_mode_is_explicit_not_registry
|
|
771
|
+
test_delivery_flags_are_refused_where_they_do_not_apply
|
|
772
|
+
test_faster_paths_use_configured_authority_without_stacked_review
|
|
773
|
+
test_no_mistakes_dod_wording
|
|
774
|
+
test_ship_project_memory_wording
|
|
775
|
+
test_herdr_lab_contract_is_explicit_and_complete
|
|
776
|
+
test_herdr_lab_contract_quotes_foreign_firstmate_path
|
|
777
|
+
test_herdr_lab_omission_is_loud_for_ship_and_scout
|
|
778
|
+
test_documented_global_replace_leaves_the_herdr_gate_intact
|
|
779
|
+
test_herdr_lab_contract_applies_to_scouts_but_not_secondmates
|
|
780
|
+
test_secondmate_no_projects_charter
|
|
781
|
+
test_secondmate_marked_request_reporting_contract
|
|
782
|
+
test_secondmate_directory_paths_are_absolute_and_output_is_stable
|
|
783
|
+
test_pause_verb_override_renders_all_brief_scaffolds
|
|
784
|
+
test_scout_and_secondmate_load_decision_hold_policy
|
|
785
|
+
test_scout_and_secondmate_scaffold
|