@zerwiz/ymir 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +291 -0
- package/.agents/agents/bragi-marketer.md +111 -0
- package/.agents/agents/brokk.md +352 -0
- package/.agents/agents/forseti-reviewer.md +93 -0
- package/.agents/agents/frigg-consent.md +77 -0
- package/.agents/agents/groa-update.md +77 -0
- package/.agents/agents/hnoss-designer.md +69 -0
- package/.agents/agents/huginn-researcher.md +99 -0
- package/.agents/agents/jord-projects.md +78 -0
- package/.agents/agents/kvasir-scout.md +91 -0
- package/.agents/agents/mimir-planner.md +92 -0
- package/.agents/agents/muninn-stow.md +77 -0
- package/.agents/agents/saga-bearings.md +78 -0
- package/.agents/agents/sindri-developer.md +114 -0
- package/.agents/agents/snotra-documenter.md +105 -0
- package/.agents/agents/syn-recovery.md +78 -0
- package/.agents/agents/tyr-check.md +78 -0
- package/.agents/agents/urdh-hold.md +77 -0
- package/.agents/agents/volundr-smith.md +80 -0
- package/.agents/agents/vor-diagnostics.md +77 -0
- package/.agents/assets/agents/naming.md +50 -0
- package/.agents/assets/agents/registry.md +93 -0
- package/.agents/assets/agents/runtime.md +36 -0
- package/.agents/assets/agents/toon-tasks-cli.md +42 -0
- package/.agents/assets/templates/company_entity.template.md +37 -0
- package/.agents/backend/backends/cmux.sh +649 -0
- package/.agents/backend/backends/herdr-eventwait.py +157 -0
- package/.agents/backend/backends/herdr-workspace-move.py +114 -0
- package/.agents/backend/backends/herdr.sh +3386 -0
- package/.agents/backend/backends/orca.sh +290 -0
- package/.agents/backend/backends/tmux.sh +357 -0
- package/.agents/backend/backends/zellij.sh +700 -0
- package/.agents/backend/fm-afk-launch.sh +654 -0
- package/.agents/backend/fm-afk-return.sh +241 -0
- package/.agents/backend/fm-afk-start.sh +172 -0
- package/.agents/backend/fm-arm-command-policy.mjs +960 -0
- package/.agents/backend/fm-arm-pretool-check.sh +200 -0
- package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
- package/.agents/backend/fm-backend.sh +981 -0
- package/.agents/backend/fm-backlog-handoff.sh +909 -0
- package/.agents/backend/fm-backlog-receive.sh +187 -0
- package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
- package/.agents/backend/fm-bearings-board.sh +204 -0
- package/.agents/backend/fm-bearings-snapshot.sh +546 -0
- package/.agents/backend/fm-bootstrap.sh +1568 -0
- package/.agents/backend/fm-branch-outcome.sh +203 -0
- package/.agents/backend/fm-branch-prompt.sh +101 -0
- package/.agents/backend/fm-brief.sh +452 -0
- package/.agents/backend/fm-busy-event.sh +234 -0
- package/.agents/backend/fm-busy-lib.sh +986 -0
- package/.agents/backend/fm-captain-hold.sh +1001 -0
- package/.agents/backend/fm-cd-command-policy.mjs +153 -0
- package/.agents/backend/fm-cd-pretool-check.sh +190 -0
- package/.agents/backend/fm-check-lib.sh +74 -0
- package/.agents/backend/fm-check-register.sh +42 -0
- package/.agents/backend/fm-check-unregister.sh +52 -0
- package/.agents/backend/fm-classify-lib.sh +1770 -0
- package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
- package/.agents/backend/fm-composer-lib.sh +1416 -0
- package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
- package/.agents/backend/fm-config-push.sh +254 -0
- package/.agents/backend/fm-control-lib.sh +251 -0
- package/.agents/backend/fm-control.sh +878 -0
- package/.agents/backend/fm-crew-state.sh +625 -0
- package/.agents/backend/fm-cursor-lib.sh +243 -0
- package/.agents/backend/fm-decision-hold.sh +232 -0
- package/.agents/backend/fm-doc-audience-check.sh +269 -0
- package/.agents/backend/fm-dod-lib.sh +67 -0
- package/.agents/backend/fm-ensure-agents-md.sh +253 -0
- package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
- package/.agents/backend/fm-extension.mjs +2577 -0
- package/.agents/backend/fm-extension.sh +16 -0
- package/.agents/backend/fm-ff-lib.sh +420 -0
- package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
- package/.agents/backend/fm-fleet-sync.sh +458 -0
- package/.agents/backend/fm-fleet-view.sh +96 -0
- package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
- package/.agents/backend/fm-guard.sh +242 -0
- package/.agents/backend/fm-harness.sh +195 -0
- package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
- package/.agents/backend/fm-herdr-lab.sh +346 -0
- package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
- package/.agents/backend/fm-home-seed.sh +984 -0
- package/.agents/backend/fm-home-summary-refresh.sh +255 -0
- package/.agents/backend/fm-hook-host-lib.sh +36 -0
- package/.agents/backend/fm-inactive-reconcile.sh +531 -0
- package/.agents/backend/fm-inbox.sh +399 -0
- package/.agents/backend/fm-install-actionlint.sh +84 -0
- package/.agents/backend/fm-install-herdr.sh +96 -0
- package/.agents/backend/fm-install-shellcheck.sh +84 -0
- package/.agents/backend/fm-install-treehouse.sh +95 -0
- package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
- package/.agents/backend/fm-lease-lib.sh +218 -0
- package/.agents/backend/fm-lease.sh +189 -0
- package/.agents/backend/fm-line-cap-lib.sh +51 -0
- package/.agents/backend/fm-lint-workflows.sh +137 -0
- package/.agents/backend/fm-lint.sh +591 -0
- package/.agents/backend/fm-lock-lib.sh +104 -0
- package/.agents/backend/fm-lock.sh +107 -0
- package/.agents/backend/fm-marker-lib.sh +12 -0
- package/.agents/backend/fm-merge-local.sh +74 -0
- package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
- package/.agents/backend/fm-nm-run-lib.sh +124 -0
- package/.agents/backend/fm-on.sh +125 -0
- package/.agents/backend/fm-operational-input.sh +253 -0
- package/.agents/backend/fm-peek.sh +46 -0
- package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
- package/.agents/backend/fm-pr-check.sh +135 -0
- package/.agents/backend/fm-pr-lib.sh +1016 -0
- package/.agents/backend/fm-pr-merge.sh +707 -0
- package/.agents/backend/fm-pr-poll.sh +110 -0
- package/.agents/backend/fm-primary-scope-lib.sh +33 -0
- package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
- package/.agents/backend/fm-procevent-lavish.sh +628 -0
- package/.agents/backend/fm-procevent-lib.sh +892 -0
- package/.agents/backend/fm-procevent-quota.sh +290 -0
- package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
- package/.agents/backend/fm-procevent-when.sh +504 -0
- package/.agents/backend/fm-procevent.sh +1466 -0
- package/.agents/backend/fm-project-mode.sh +92 -0
- package/.agents/backend/fm-project-origin-lib.sh +180 -0
- package/.agents/backend/fm-promote.sh +282 -0
- package/.agents/backend/fm-public-followup-emit.sh +260 -0
- package/.agents/backend/fm-public-followup-lib.sh +398 -0
- package/.agents/backend/fm-public-followup.sh +1330 -0
- package/.agents/backend/fm-push-transition-lib.sh +168 -0
- package/.agents/backend/fm-quota-axi-lib.sh +93 -0
- package/.agents/backend/fm-quota-choose.sh +384 -0
- package/.agents/backend/fm-remote-delta-read.sh +189 -0
- package/.agents/backend/fm-remote-doctor.sh +800 -0
- package/.agents/backend/fm-remote-entrypoint.sh +193 -0
- package/.agents/backend/fm-remote-file.sh +234 -0
- package/.agents/backend/fm-remote-home-provision.sh +259 -0
- package/.agents/backend/fm-remote-home-seed.sh +259 -0
- package/.agents/backend/fm-remote-inherit-push.sh +90 -0
- package/.agents/backend/fm-remote-inherit.sh +179 -0
- package/.agents/backend/fm-remote-job-lib.sh +1241 -0
- package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
- package/.agents/backend/fm-remote-job-worker.sh +1124 -0
- package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
- package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
- package/.agents/backend/fm-review-diff.sh +158 -0
- package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
- package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
- package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
- package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
- package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
- package/.agents/backend/fm-secondmate-report.sh +88 -0
- package/.agents/backend/fm-send.sh +1059 -0
- package/.agents/backend/fm-session-lock-lib.sh +176 -0
- package/.agents/backend/fm-session-start.sh +970 -0
- package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
- package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
- package/.agents/backend/fm-sessionstart-run.sh +145 -0
- package/.agents/backend/fm-spawn.sh +3153 -0
- package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
- package/.agents/backend/fm-startup-memory-budget.sh +94 -0
- package/.agents/backend/fm-startup-network.sh +642 -0
- package/.agents/backend/fm-stow-cascade.sh +251 -0
- package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
- package/.agents/backend/fm-supervise-daemon.sh +1732 -0
- package/.agents/backend/fm-supervision-instructions.sh +215 -0
- package/.agents/backend/fm-supervision-lib.sh +90 -0
- package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
- package/.agents/backend/fm-tangle-lib.sh +53 -0
- package/.agents/backend/fm-task-inbox-lib.sh +402 -0
- package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
- package/.agents/backend/fm-teardown.sh +2922 -0
- package/.agents/backend/fm-test-isolation-proof.sh +588 -0
- package/.agents/backend/fm-test-run.sh +2191 -0
- package/.agents/backend/fm-timeout-lib.sh +141 -0
- package/.agents/backend/fm-timing-lib.sh +179 -0
- package/.agents/backend/fm-tmux-lib.sh +291 -0
- package/.agents/backend/fm-tool-update-check.sh +898 -0
- package/.agents/backend/fm-trace-context-lib.sh +227 -0
- package/.agents/backend/fm-transition-lib.sh +103 -0
- package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
- package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
- package/.agents/backend/fm-turnend-guard.sh +432 -0
- package/.agents/backend/fm-update.sh +110 -0
- package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
- package/.agents/backend/fm-voice-client.py +1373 -0
- package/.agents/backend/fm-voice-relay.py +1256 -0
- package/.agents/backend/fm-wake-drain.sh +592 -0
- package/.agents/backend/fm-wake-grant.sh +127 -0
- package/.agents/backend/fm-wake-lib.sh +1849 -0
- package/.agents/backend/fm-watch-arm.sh +602 -0
- package/.agents/backend/fm-watch-checkpoint.sh +109 -0
- package/.agents/backend/fm-watch.sh +1962 -0
- package/.agents/backend/fm-x-dismiss.sh +116 -0
- package/.agents/backend/fm-x-followup.sh +286 -0
- package/.agents/backend/fm-x-lib.sh +1000 -0
- package/.agents/backend/fm-x-link.sh +234 -0
- package/.agents/backend/fm-x-poll.sh +185 -0
- package/.agents/backend/fm-x-reply.sh +385 -0
- package/.agents/backend/fm_voice_frame.py +166 -0
- package/.agents/backend/fm_voice_records.py +574 -0
- package/.agents/backend/model-bridge.py +290 -0
- package/.agents/backend/opencode-go-bridge.py +30 -0
- package/.agents/bus/README.md +12 -0
- package/.agents/bus/messages.json +1 -0
- package/.agents/config/agents.machine.example.yaml +16 -0
- package/.agents/config/agents.yaml +50 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +9 -0
- package/.agents/config/eindri-dispatch.json +67 -0
- package/.agents/config/eindri-harness +1 -0
- package/.agents/config/startup-memory-budget +1 -0
- package/.agents/config/tailscale-sync.yaml +27 -0
- package/.agents/filebrowser/.filebrowser.json +6 -0
- package/.agents/filebrowser/README.md +11 -0
- package/.agents/gateway/README.md +12 -0
- package/.agents/github/README.md +15 -0
- package/.agents/github/webhooks/.gitkeep +0 -0
- package/.agents/github/workflows/.gitkeep +0 -0
- package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
- package/.agents/harness/opencode/plugins/package.json +4 -0
- package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
- package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
- package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
- package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
- package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
- package/.agents/memory/README.md +46 -0
- package/.agents/memory/kaia.engram +0 -0
- package/.agents/memory/kaia.engram-shm +0 -0
- package/.agents/memory/kaia.engram-wal +0 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/memory/well/episodes.jsonl +367 -0
- package/.agents/memory/well/workspace.jsonl +27 -0
- package/.agents/migrations/0001-hodd-layout.sh +38 -0
- package/.agents/migrations/0002-a2a-mcp.sh +27 -0
- package/.agents/migrations/0003-private-data-separation.sh +111 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/sandbox/Dockerfile.utgard +19 -0
- package/.agents/sandbox/README.md +14 -0
- package/.agents/sandbox/utgard.config.json +14 -0
- package/.agents/skills/README.md +59 -0
- package/.agents/skills/bragi-marketing/README.md +3 -0
- package/.agents/skills/bragi-marketing/SKILL.md +82 -0
- package/.agents/skills/eindri-homes/README.md +3 -0
- package/.agents/skills/eindri-homes/SKILL.md +291 -0
- package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
- package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
- package/.agents/skills/frigg-consent/README.md +3 -0
- package/.agents/skills/frigg-consent/SKILL.md +56 -0
- package/.agents/skills/galdr-ymirsystem/README.md +3 -0
- package/.agents/skills/galdr-ymirsystem/SKILL.md +158 -0
- package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
- package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +673 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
- package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +496 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
- package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +161 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +96 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
- package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
- package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
- package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
- package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
- package/.agents/skills/galdr-ymirsystem/assets/smidja.md +175 -0
- package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
- package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
- package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
- package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +360 -0
- package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
- package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
- package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
- package/.agents/skills/gjallarhorn-relay/README.md +3 -0
- package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
- package/.agents/skills/groa-update/SKILL.md +70 -0
- package/.agents/skills/hamr-adapters/README.md +3 -0
- package/.agents/skills/hamr-adapters/SKILL.md +123 -0
- package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
- package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
- package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
- package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
- package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
- package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
- package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
- package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
- package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
- package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
- package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
- package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
- package/.agents/skills/herdr-panes/README.md +3 -0
- package/.agents/skills/herdr-panes/SKILL.md +92 -0
- package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
- package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
- package/.agents/skills/hnoss-design/DESIGN.md +19 -0
- package/.agents/skills/hnoss-design/README.md +3 -0
- package/.agents/skills/hnoss-design/SKILL.md +83 -0
- package/.agents/skills/hvild-afk/README.md +3 -0
- package/.agents/skills/hvild-afk/SKILL.md +241 -0
- package/.agents/skills/jord-projects/README.md +3 -0
- package/.agents/skills/jord-projects/SKILL.md +92 -0
- package/.agents/skills/lifecycle/SKILL.md +56 -0
- package/.agents/skills/lifecycle/smoke_test.sh +52 -0
- package/.agents/skills/lifecycle/start.sh +21 -0
- package/.agents/skills/lifecycle/status.sh +35 -0
- package/.agents/skills/lifecycle/stop.sh +16 -0
- package/.agents/skills/muninn-stow/README.md +3 -0
- package/.agents/skills/muninn-stow/SKILL.md +309 -0
- package/.agents/skills/no-mistakes/SKILL.md +379 -0
- package/.agents/skills/nornir-schedule/README.md +3 -0
- package/.agents/skills/nornir-schedule/SKILL.md +25 -0
- package/.agents/skills/nornir-schedule/assets/events.md +137 -0
- package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
- package/.agents/skills/nsr-compliance/README.md +3 -0
- package/.agents/skills/nsr-compliance/SKILL.md +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/pr-ops/README.md +3 -0
- package/.agents/skills/pr-ops/SKILL.md +109 -0
- package/.agents/skills/ratatoskr-a2a/README.md +3 -0
- package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
- package/.agents/skills/rules-check-drift/SKILL.md +81 -0
- package/.agents/skills/saga-bearings/README.md +3 -0
- package/.agents/skills/saga-bearings/SKILL.md +26 -0
- package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
- package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
- package/.agents/skills/saga-bearings/assets/recap.md +56 -0
- package/.agents/skills/syn-recovery/README.md +3 -0
- package/.agents/skills/syn-recovery/SKILL.md +54 -0
- package/.agents/skills/tyr-check/README.md +3 -0
- package/.agents/skills/tyr-check/SKILL.md +218 -0
- package/.agents/skills/urdh-hold/README.md +3 -0
- package/.agents/skills/urdh-hold/SKILL.md +25 -0
- package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
- package/.agents/skills/urdh-hold/assets/hold.md +54 -0
- package/.agents/skills/vor-diagnostics/README.md +3 -0
- package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
- package/.agents/skills/ymir-host/README.md +3 -0
- package/.agents/skills/ymir-host/SKILL.md +34 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
- package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
- package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
- package/.agents/skills/ymir-host/assets/update.md +64 -0
- package/.agents/tests/assets/board-render-harness.mjs +117 -0
- package/.agents/tests/cmux-test-safety.sh +51 -0
- package/.agents/tests/fixtures.sh +291 -0
- package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
- package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
- package/.agents/tests/fm-afk-launch.test.sh +961 -0
- package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
- package/.agents/tests/fm-afk-return.test.sh +283 -0
- package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
- package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
- package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
- package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
- package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
- package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
- package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
- package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
- package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
- package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
- package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
- package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
- package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
- package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
- package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
- package/.agents/tests/fm-backend-orca.test.sh +1357 -0
- package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
- package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
- package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
- package/.agents/tests/fm-backend.test.sh +1142 -0
- package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
- package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
- package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
- package/.agents/tests/fm-bearings-board.test.sh +414 -0
- package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
- package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
- package/.agents/tests/fm-bootstrap.test.sh +1178 -0
- package/.agents/tests/fm-branch-supervision.test.sh +552 -0
- package/.agents/tests/fm-brief.test.sh +785 -0
- package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
- package/.agents/tests/fm-busy-state.test.sh +465 -0
- package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
- package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
- package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
- package/.agents/tests/fm-check-unregister.test.sh +198 -0
- package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
- package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
- package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
- package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
- package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
- package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
- package/.agents/tests/fm-composer-ghost.test.sh +716 -0
- package/.agents/tests/fm-composer-lib.test.sh +666 -0
- package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
- package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
- package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
- package/.agents/tests/fm-control.test.sh +910 -0
- package/.agents/tests/fm-crew-state.test.sh +1610 -0
- package/.agents/tests/fm-cursor-harness.test.sh +404 -0
- package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
- package/.agents/tests/fm-cursor-primary.test.sh +708 -0
- package/.agents/tests/fm-daemon.test.sh +2740 -0
- package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
- package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
- package/.agents/tests/fm-extension-binding.test.sh +2187 -0
- package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
- package/.agents/tests/fm-fleet-sync.test.sh +721 -0
- package/.agents/tests/fm-gate-refuse.test.sh +356 -0
- package/.agents/tests/fm-gitignore-config.test.sh +89 -0
- package/.agents/tests/fm-gotmp.test.sh +230 -0
- package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
- package/.agents/tests/fm-grok-harness.test.sh +117 -0
- package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
- package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
- package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
- package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
- package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
- package/.agents/tests/fm-herdr-lab.test.sh +243 -0
- package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
- package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
- package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
- package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
- package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
- package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
- package/.agents/tests/fm-kimi-harness.test.sh +687 -0
- package/.agents/tests/fm-lint-workflows.test.sh +532 -0
- package/.agents/tests/fm-lint.test.sh +1023 -0
- package/.agents/tests/fm-muse-harness.test.sh +932 -0
- package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
- package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
- package/.agents/tests/fm-on.test.sh +507 -0
- package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
- package/.agents/tests/fm-operational-input.test.sh +160 -0
- package/.agents/tests/fm-peek-remote.test.sh +110 -0
- package/.agents/tests/fm-pending-reply.test.sh +1288 -0
- package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
- package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
- package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
- package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
- package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
- package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
- package/.agents/tests/fm-pr-merge.test.sh +2135 -0
- package/.agents/tests/fm-procevent-quota.test.sh +225 -0
- package/.agents/tests/fm-procevent-when.test.sh +406 -0
- package/.agents/tests/fm-procevent.test.sh +1745 -0
- package/.agents/tests/fm-project-origin.test.sh +110 -0
- package/.agents/tests/fm-public-followup.test.sh +2272 -0
- package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
- package/.agents/tests/fm-quota-choose.test.sh +626 -0
- package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
- package/.agents/tests/fm-remote-doctor.test.sh +625 -0
- package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
- package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
- package/.agents/tests/fm-remote-job.test.sh +768 -0
- package/.agents/tests/fm-remote-reply.test.sh +520 -0
- package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
- package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
- package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
- package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
- package/.agents/tests/fm-review-diff.test.sh +176 -0
- package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
- package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
- package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
- package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
- package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
- package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
- package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
- package/.agents/tests/fm-send-inbox.test.sh +352 -0
- package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
- package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
- package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
- package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
- package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
- package/.agents/tests/fm-send-settle.test.sh +147 -0
- package/.agents/tests/fm-send-strict.test.sh +241 -0
- package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
- package/.agents/tests/fm-session-start.test.sh +2515 -0
- package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
- package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
- package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
- package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
- package/.agents/tests/fm-spawn-batch.test.sh +148 -0
- package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
- package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
- package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
- package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
- package/.agents/tests/fm-startup-network.test.sh +712 -0
- package/.agents/tests/fm-stow-cascade.test.sh +370 -0
- package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
- package/.agents/tests/fm-supervision-events.test.sh +156 -0
- package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
- package/.agents/tests/fm-tangle-guard.test.sh +277 -0
- package/.agents/tests/fm-task-delivery.test.sh +420 -0
- package/.agents/tests/fm-task-inbox.test.sh +513 -0
- package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
- package/.agents/tests/fm-teardown.test.sh +2665 -0
- package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
- package/.agents/tests/fm-test-fixtures.test.sh +132 -0
- package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
- package/.agents/tests/fm-test-run.test.sh +1196 -0
- package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
- package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
- package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
- package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
- package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
- package/.agents/tests/fm-transition-lib.test.sh +54 -0
- package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
- package/.agents/tests/fm-update.test.sh +304 -0
- package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
- package/.agents/tests/fm-voice-relay.test.sh +4741 -0
- package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
- package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
- package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
- package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
- package/.agents/tests/fm-wake-queue.test.sh +1224 -0
- package/.agents/tests/fm-watch-arm.test.sh +821 -0
- package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
- package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
- package/.agents/tests/fm-watch-triage.test.sh +3889 -0
- package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
- package/.agents/tests/fm-x-mode.test.sh +3042 -0
- package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
- package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
- package/.agents/tests/herdr-test-safety.sh +42 -0
- package/.agents/tests/lib.sh +315 -0
- package/.agents/tests/remote-herdr-fixture.sh +125 -0
- package/.agents/tests/secondmate-helpers.sh +193 -0
- package/.agents/tests/smoke.test.sh +93 -0
- package/.agents/tests/wake-helpers.sh +338 -0
- package/.agents/tests/zellij-test-safety.sh +60 -0
- package/.agents/tools/README.md +10 -0
- package/.agents/tools/bin/tasks-cli +267 -0
- package/.agents/tools/tasks-cli.ts +216 -0
- package/AGENTS.md +454 -0
- package/CHANGELOG.md +881 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +113 -59
- package/RULES/01-domains.md +51 -0
- package/RULES/02-agents.md +78 -0
- package/RULES/03-houses.md +61 -0
- package/RULES/04-hoard.md +65 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +58 -0
- package/RULES/07-config.md +45 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/README.md +20 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +98 -0
- package/bin/a2a-serve.py +103 -0
- package/bin/a2a-serve.sh +8 -0
- package/bin/a2a-talk.sh +50 -0
- package/bin/a2abridge-ensure.sh +108 -0
- package/bin/agent-run.sh +43 -0
- package/bin/agents-config.sh +233 -0
- package/bin/apodex-smoke-test.sh +92 -0
- package/bin/bifrost-bridge.sh +112 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +107 -0
- package/bin/bootstrap-windows.ps1 +112 -0
- package/bin/branch-guard.sh +64 -0
- package/bin/brokk +73 -0
- package/bin/brokk-classify-lib.sh +1770 -0
- package/bin/brokk-lease-lib.sh +222 -0
- package/bin/brokk-lease.sh +193 -0
- package/bin/brokk-lint.sh +65 -0
- package/bin/brokk-send.sh +38 -0
- package/bin/brokk-update.sh +9 -0
- package/bin/brokk-wake-grant.sh +127 -0
- package/bin/brokk-wake-lib.sh +1849 -0
- package/bin/changelog-guard.sh +165 -0
- package/bin/crash-sense.sh +160 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +207 -0
- package/bin/eindri-acclaim.sh +34 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seen.sh +41 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +85 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +112 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/fleet-apply.sh +68 -0
- package/bin/github-deploy.sh +81 -0
- package/bin/gjallarhorn-expose.sh +102 -0
- package/bin/gjallarhorn-notify.sh +58 -0
- package/bin/gjallarhorn-purge.sh +54 -0
- package/bin/gjallarhorn-tunnel.sh +72 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +122 -0
- package/bin/hall-snapshot.sh +92 -0
- package/bin/hamr-harness.sh +246 -0
- package/bin/heimdall-ssh-keys.sh +374 -0
- package/bin/herdr-agents.py +44 -0
- package/bin/herdr-ensure.sh +104 -0
- package/bin/herdr-run.sh +431 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hoard-lib.sh +25 -0
- package/bin/hodd.sh +78 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +108 -0
- package/bin/local-model-lock.sh +51 -0
- package/bin/mimir-bridge.py +226 -0
- package/bin/mimir-bridge.sh +87 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +59 -0
- package/bin/mjollnir.sh +85 -0
- package/bin/model-hardware.sh +82 -0
- package/bin/model-resolve.sh +147 -0
- package/bin/models-detect.sh +178 -0
- package/bin/nornir-cron-start.sh +162 -0
- package/bin/nornir-job-daily-briefing.sh +191 -0
- package/bin/nornir-job-git-sync.sh +152 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +148 -0
- package/bin/omarchy-plugins.sh +174 -0
- package/bin/omarchy-sense.sh +149 -0
- package/bin/perm-guard.sh +30 -0
- package/bin/pi-agent.sh +68 -0
- package/bin/pi-ensure.sh +77 -0
- package/bin/pi-local.sh +37 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +38 -0
- package/bin/project-git.sh +55 -0
- package/bin/public-guard.sh +70 -0
- package/bin/ratatoskr.sh +49 -0
- package/bin/realm-lib.sh +32 -0
- package/bin/repo-scrub.sh +62 -0
- package/bin/rodd-operational-input.sh +250 -0
- package/bin/runes-append.sh +198 -0
- package/bin/saga-session-start.sh +172 -0
- package/bin/saga-sessionstart-run.sh +79 -0
- package/bin/saga-wake-drain.sh +41 -0
- package/bin/secret-guard.sh +63 -0
- package/bin/sessrumnir-ensure.sh +100 -0
- package/bin/sessrumnir-sync.sh +237 -0
- package/bin/sessrumnir.sh +91 -0
- package/bin/skillopt-setup.sh +76 -0
- package/bin/skuld-branch-outcome.sh +203 -0
- package/bin/skuld-branch-prompt.sh +101 -0
- package/bin/smidja-bootstrap.sh +90 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +76 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +190 -0
- package/bin/telegram-bot.sh +69 -0
- package/bin/toolchain.sh +74 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +260 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +47 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +150 -0
- package/bin/wyrd-db.sh +47 -0
- package/bin/yggdrasil.sh +152 -0
- package/bin/ymir-edit.sh +145 -0
- package/bin/ymir-install.sh +641 -0
- package/bin/ymir-invite.sh +93 -0
- package/bin/ymir-isolation.sh +88 -0
- package/bin/ymir-migrate.sh +61 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +97 -0
- package/bin/ymir-setup-auth.sh +108 -0
- package/bin/ymir-validate.sh +173 -0
- package/bin/ymir.js +74 -16
- package/docs/Architecture.md +339 -0
- package/docs/design.md +351 -0
- package/docs/installations/README.md +63 -0
- package/docs/installations/ymir-home.md +93 -0
- package/docs/integration.md +105 -0
- package/docs/lore.md +1056 -0
- package/docs/research/agent-harnesses.md +290 -0
- package/docs/runbooks/README.md +19 -0
- package/docs/runbooks/a2a.md +91 -0
- package/docs/runbooks/agent-permissions.md +99 -0
- package/docs/runbooks/agents.md +57 -0
- package/docs/runbooks/models.md +69 -0
- package/docs/runbooks/realm-onboarding.md +60 -0
- package/docs/runbooks/secrets-and-hoard.md +60 -0
- package/docs/runbooks/updates-and-migrations.md +110 -0
- package/docs/runbooks/worktrees-isolation.md +72 -0
- package/docs/session-start.md +105 -0
- package/docs/skillopt-integration.md +321 -0
- package/docs/sync-system.md +66 -0
- package/docs/workspaces.md +104 -0
- package/docs/ymir-rut.md +260 -0
- package/package.json +44 -14
- package/packaging/build.sh +74 -0
- package/packaging/macos/Ymir Installer.command +43 -0
- package/packaging/windows/ymir-setup.nsi +74 -0
- package/scripts/README.md +22 -0
- package/scripts/electron.sh +210 -0
- package/scripts/start.sh +167 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/fm-classify-decision-key.test.sh - decision-key position tolerance in
|
|
3
|
+
# the open-decisions fold (bin/fm-classify-lib.sh). A "[key=<slug>]" token is
|
|
4
|
+
# documented between the verb and the colon (needs-decision [key=x]: note), but
|
|
5
|
+
# workers commonly write the colon first (needs-decision: [key=x] note); that
|
|
6
|
+
# stated key must be honored, never silently folded into the shared "default"
|
|
7
|
+
# bucket where an answer can close the wrong record (issue #2109). Also covers
|
|
8
|
+
# status_line_verb's bracket-tag stripping: a remote secondmate reply prepends
|
|
9
|
+
# a "[corr=...]" correlation tag before (or without) "[key=...]", and every
|
|
10
|
+
# such tag before the colon must be stripped so the leading word is the bare
|
|
11
|
+
# verb, regardless of order or count. These tests drive the REAL
|
|
12
|
+
# status_line_verb / status_open_decisions / status_open_decisions_incremental
|
|
13
|
+
# functions over crafted status files and assert their folded output, never the
|
|
14
|
+
# fold's own source text. Also covers status_key_closing_verb, which reports how
|
|
15
|
+
# the status side currently reads one key so a consumer can tell a settled key
|
|
16
|
+
# from one handed to a durable captain-held task (bin/fm-captain-hold.sh
|
|
17
|
+
# diverged). Cross-drain cursor persistence and the incremental
|
|
18
|
+
# cost bound live in tests/fm-wake-drain-open-decisions-cursor.test.sh; the
|
|
19
|
+
# drain wiring lives in tests/fm-wake-drain-open-decisions.test.sh.
|
|
20
|
+
set -u
|
|
21
|
+
|
|
22
|
+
# shellcheck source=tests/lib.sh
|
|
23
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
24
|
+
|
|
25
|
+
# shellcheck source=bin/fm-classify-lib.sh
|
|
26
|
+
. "$ROOT/bin/fm-classify-lib.sh"
|
|
27
|
+
|
|
28
|
+
TMP_ROOT=$(fm_test_tmproot fm-classify-decision-key-tests)
|
|
29
|
+
|
|
30
|
+
# Fresh per-case dir so each case's incremental cursor sidecar cannot leak into
|
|
31
|
+
# another case.
|
|
32
|
+
case_dir() { # <name>
|
|
33
|
+
local d="$TMP_ROOT/$1"
|
|
34
|
+
mkdir -p "$d"
|
|
35
|
+
printf '%s' "$d"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Assert the whole-file fold of <status-file> equals <expected>, and that the
|
|
39
|
+
# incremental fold agrees with it on the exact same input - the two consumption
|
|
40
|
+
# strategies must never diverge on what is open.
|
|
41
|
+
assert_fold() { # <status-file> <expected> <label>
|
|
42
|
+
local f=$1 expected=$2 label=$3 full incr
|
|
43
|
+
full=$(status_open_decisions "$f")
|
|
44
|
+
incr=$(status_open_decisions_incremental "$f")
|
|
45
|
+
[ "$full" = "$expected" ] \
|
|
46
|
+
|| fail "$label: full fold mismatch: got '$full' want '$expected'"
|
|
47
|
+
[ "$incr" = "$full" ] \
|
|
48
|
+
|| fail "$label: incremental fold diverged from the full fold: got '$incr' want '$full'"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
test_stated_key_is_honored_in_both_positions() {
|
|
52
|
+
local dir before after expected
|
|
53
|
+
dir=$(case_dir positions)
|
|
54
|
+
printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$dir/before.status"
|
|
55
|
+
printf 'needs-decision: [key=api-shape] pick REST or RPC\n' > "$dir/after.status"
|
|
56
|
+
expected=$(printf 'api-shape\tneeds-decision\tpick REST or RPC\n')
|
|
57
|
+
|
|
58
|
+
assert_fold "$dir/before.status" "$expected" "documented before-colon form"
|
|
59
|
+
assert_fold "$dir/after.status" "$expected" "colon-first form"
|
|
60
|
+
|
|
61
|
+
# Equivalence is byte-for-byte: both positions yield the same key AND the
|
|
62
|
+
# same note (a consumed note-head token is key metadata, not note text).
|
|
63
|
+
before=$(status_open_decisions "$dir/before.status")
|
|
64
|
+
after=$(status_open_decisions "$dir/after.status")
|
|
65
|
+
[ "$before" = "$after" ] \
|
|
66
|
+
|| fail "the two key positions folded to different records: '$before' vs '$after'"
|
|
67
|
+
pass "a stated [key=X] opens X whether it precedes or follows the verb colon"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
test_bare_keyless_line_still_folds_to_default() {
|
|
71
|
+
local dir
|
|
72
|
+
dir=$(case_dir keyless)
|
|
73
|
+
printf 'needs-decision: which color\n' > "$dir/bare.status"
|
|
74
|
+
assert_fold "$dir/bare.status" "$(printf 'default\tneeds-decision\twhich color\n')" \
|
|
75
|
+
"bare keyless line"
|
|
76
|
+
|
|
77
|
+
# And a bare keyless resolution still closes it - the historical
|
|
78
|
+
# one-open-decision-per-task behavior is unchanged.
|
|
79
|
+
printf 'resolved: went with blue\n' >> "$dir/bare.status"
|
|
80
|
+
assert_fold "$dir/bare.status" "" "bare keyless resolution"
|
|
81
|
+
pass "a keyless needs-decision still opens and closes the default key"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
test_resolution_closes_across_positions() {
|
|
85
|
+
local dir
|
|
86
|
+
dir=$(case_dir cross-close)
|
|
87
|
+
# Opened colon-first, closed in the documented form (what fm-send's
|
|
88
|
+
# --resolve-key writes): the exact failure from issue #2109.
|
|
89
|
+
printf 'needs-decision: [key=seam-max-bound] pick the bound\n' > "$dir/a.status"
|
|
90
|
+
printf 'resolved [key=seam-max-bound]: answered: use 4\n' >> "$dir/a.status"
|
|
91
|
+
assert_fold "$dir/a.status" "" "documented resolution closing a colon-first open"
|
|
92
|
+
|
|
93
|
+
# And the mirror: opened documented, closed colon-first.
|
|
94
|
+
printf 'needs-decision [key=seam-max-bound]: pick the bound\n' > "$dir/b.status"
|
|
95
|
+
printf 'resolved: [key=seam-max-bound] answered: use 4\n' >> "$dir/b.status"
|
|
96
|
+
assert_fold "$dir/b.status" "" "colon-first resolution closing a documented open"
|
|
97
|
+
pass "a resolution closes its decision regardless of either line's key position"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
test_blocked_is_position_tolerant_like_needs_decision() {
|
|
101
|
+
local dir expected
|
|
102
|
+
dir=$(case_dir blocked)
|
|
103
|
+
expected=$(printf 'creds\tblocked\twaiting on the deploy token\n')
|
|
104
|
+
printf 'blocked [key=creds]: waiting on the deploy token\n' > "$dir/before.status"
|
|
105
|
+
printf 'blocked: [key=creds] waiting on the deploy token\n' > "$dir/after.status"
|
|
106
|
+
assert_fold "$dir/before.status" "$expected" "documented blocked form"
|
|
107
|
+
assert_fold "$dir/after.status" "$expected" "colon-first blocked form"
|
|
108
|
+
pass "blocked [key=X] opens X in both key positions"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
test_two_colon_form_decisions_stay_distinct() {
|
|
112
|
+
local dir expected
|
|
113
|
+
dir=$(case_dir distinct)
|
|
114
|
+
# The concrete hazard behind the silent collapse: two colon-form decisions on
|
|
115
|
+
# one task used to share the default bucket, so answering one could close the
|
|
116
|
+
# other. They must stay independently open and independently closable.
|
|
117
|
+
printf 'needs-decision: [key=alpha] first question\n' > "$dir/t.status"
|
|
118
|
+
printf 'needs-decision: [key=beta] second question\n' >> "$dir/t.status"
|
|
119
|
+
expected=$(printf 'alpha\tneeds-decision\tfirst question\nbeta\tneeds-decision\tsecond question\n')
|
|
120
|
+
assert_fold "$dir/t.status" "$expected" "two colon-form decisions"
|
|
121
|
+
|
|
122
|
+
printf 'resolved [key=alpha]: answered: yes\n' >> "$dir/t.status"
|
|
123
|
+
assert_fold "$dir/t.status" "$(printf 'beta\tneeds-decision\tsecond question\n')" \
|
|
124
|
+
"closing one of two colon-form decisions"
|
|
125
|
+
pass "two colon-form keyed decisions never collapse into one shared bucket"
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
test_mid_note_prose_mention_is_not_a_stated_key() {
|
|
129
|
+
local dir
|
|
130
|
+
dir=$(case_dir prose)
|
|
131
|
+
# Only a token at the head of the note states a key; a summary merely
|
|
132
|
+
# mentioning "[key=x]" deeper in must neither open nor close that key.
|
|
133
|
+
printf 'needs-decision: pick a [key=red] or [key=blue] theme\n' > "$dir/t.status"
|
|
134
|
+
assert_fold "$dir/t.status" \
|
|
135
|
+
"$(printf 'default\tneeds-decision\tpick a [key=red] or [key=blue] theme\n')" \
|
|
136
|
+
"mid-note prose mention"
|
|
137
|
+
|
|
138
|
+
printf 'needs-decision [key=red]: which shade\n' >> "$dir/t.status"
|
|
139
|
+
printf 'working: still thinking about [key=red] here\n' >> "$dir/t.status"
|
|
140
|
+
assert_fold "$dir/t.status" \
|
|
141
|
+
"$(printf 'default\tneeds-decision\tpick a [key=red] or [key=blue] theme\nred\tneeds-decision\twhich shade\n')" \
|
|
142
|
+
"prose mention leaves the open set untouched"
|
|
143
|
+
pass "a [key=x] mentioned mid-note is prose, never an opened or closed key"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
test_malformed_stated_key_never_collapses_to_default() {
|
|
147
|
+
local dir
|
|
148
|
+
dir=$(case_dir malformed)
|
|
149
|
+
# A stated-but-invalid slug is rejected in BOTH positions - identically,
|
|
150
|
+
# and never rewritten into the shared default bucket.
|
|
151
|
+
printf 'needs-decision [key=bad key]: before-colon malformed\n' > "$dir/before.status"
|
|
152
|
+
printf 'needs-decision: [key=bad key] colon-first malformed\n' > "$dir/after.status"
|
|
153
|
+
assert_fold "$dir/before.status" "" "malformed before-colon key"
|
|
154
|
+
assert_fold "$dir/after.status" "" "malformed colon-first key"
|
|
155
|
+
pass "a malformed stated key is rejected in both positions, never folded as default"
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
# A remote secondmate reply routinely prepends a "[corr=<hex>]" correlation
|
|
159
|
+
# tag ahead of "[key=...]" (issue: a remote reply's "needs-decision
|
|
160
|
+
# [corr=d448ea86afa4bf67] [key=x]: ..." folded to no open decision at all,
|
|
161
|
+
# because the verb parser only stripped a leading "[key=...]" token and left
|
|
162
|
+
# the corr tag glued onto the returned verb word). These cases drive the real
|
|
163
|
+
# status_line_verb directly, over every bracket-tag shape that precedes the
|
|
164
|
+
# colon, to pin the general fix: strip EVERY "[name=value]" tag there, not
|
|
165
|
+
# just "[key=...]", regardless of order or count.
|
|
166
|
+
test_status_line_verb_strips_every_bracket_tag_before_colon() {
|
|
167
|
+
local v
|
|
168
|
+
|
|
169
|
+
v=$(status_line_verb 'needs-decision [corr=d448ea86afa4bf67] [key=loan-installment-cadence-amount]: fill in the terms')
|
|
170
|
+
[ "$v" = "needs-decision" ] || fail "corr-then-key tag order: got '$v'"
|
|
171
|
+
|
|
172
|
+
v=$(status_line_verb 'needs-decision [key=loan-installment-cadence-amount] [corr=d448ea86afa4bf67]: fill in the terms')
|
|
173
|
+
[ "$v" = "needs-decision" ] || fail "key-then-corr tag order: got '$v'"
|
|
174
|
+
|
|
175
|
+
v=$(status_line_verb 'needs-decision [corr=d448ea86afa4bf67]: fill in the terms')
|
|
176
|
+
[ "$v" = "needs-decision" ] || fail "corr-only tag: got '$v'"
|
|
177
|
+
|
|
178
|
+
v=$(status_line_verb 'blocked [corr=aaaa1111bbbb2222] [key=creds]: waiting on the deploy token')
|
|
179
|
+
[ "$v" = "blocked" ] || fail "blocked with corr+key: got '$v'"
|
|
180
|
+
|
|
181
|
+
v=$(status_line_verb 'resolved [corr=aaaa1111bbbb2222] [key=creds]: answered: rotated')
|
|
182
|
+
[ "$v" = "resolved" ] || fail "resolved with corr+key: got '$v'"
|
|
183
|
+
|
|
184
|
+
pass "status_line_verb strips every bracket tag before the colon, in any order, and recovers the bare verb"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
test_corr_and_key_tags_open_and_close_under_the_stated_key() {
|
|
188
|
+
local dir expected
|
|
189
|
+
dir=$(case_dir corr-and-key)
|
|
190
|
+
printf 'needs-decision [corr=d448ea86afa4bf67] [key=loan-installment-cadence-amount]: pick the cadence\n' \
|
|
191
|
+
> "$dir/t.status"
|
|
192
|
+
expected=$(printf 'loan-installment-cadence-amount\tneeds-decision\tpick the cadence\n')
|
|
193
|
+
assert_fold "$dir/t.status" "$expected" "corr-then-key opens under the stated key"
|
|
194
|
+
|
|
195
|
+
printf 'resolved [corr=d448ea86afa4bf67] [key=loan-installment-cadence-amount]: answered: monthly\n' \
|
|
196
|
+
>> "$dir/t.status"
|
|
197
|
+
assert_fold "$dir/t.status" "" "corr-then-key resolution closes the same stated key"
|
|
198
|
+
pass "a [corr=...] tag ahead of [key=...] no longer swallows the verb: opens and closes under the stated key"
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
test_corr_only_tag_opens_as_default_like_a_bare_line() {
|
|
202
|
+
local dir bare corred
|
|
203
|
+
dir=$(case_dir corr-only)
|
|
204
|
+
printf 'needs-decision: which vendor\n' > "$dir/bare.status"
|
|
205
|
+
printf 'needs-decision [corr=d448ea86afa4bf67]: which vendor\n' > "$dir/corred.status"
|
|
206
|
+
|
|
207
|
+
bare=$(status_open_decisions "$dir/bare.status")
|
|
208
|
+
corred=$(status_open_decisions "$dir/corred.status")
|
|
209
|
+
[ "$corred" = "$bare" ] \
|
|
210
|
+
|| fail "a corr-only tag folded differently than the bare line: '$corred' vs '$bare'"
|
|
211
|
+
assert_fold "$dir/corred.status" "$(printf 'default\tneeds-decision\twhich vendor\n')" "corr-only tag"
|
|
212
|
+
pass "a [corr=...] tag with no stated key opens under 'default', exactly like a bare needs-decision line"
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
test_key_only_before_colon_still_opens_no_regression() {
|
|
216
|
+
local dir
|
|
217
|
+
dir=$(case_dir key-only-no-corr)
|
|
218
|
+
printf 'needs-decision [key=loan-installment-cadence-amount]: pick the cadence\n' > "$dir/t.status"
|
|
219
|
+
assert_fold "$dir/t.status" \
|
|
220
|
+
"$(printf 'loan-installment-cadence-amount\tneeds-decision\tpick the cadence\n')" \
|
|
221
|
+
"key-only before colon, no corr tag"
|
|
222
|
+
pass "a [key=x] tag alone (no corr tag) still opens x - no regression from the tag-stripping fix"
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
test_blocked_and_resolved_are_tag_order_independent() {
|
|
226
|
+
local dir
|
|
227
|
+
dir=$(case_dir blocked-tag-order)
|
|
228
|
+
printf 'blocked [corr=aaaa1111bbbb2222] [key=creds]: waiting on the deploy token\n' > "$dir/a.status"
|
|
229
|
+
assert_fold "$dir/a.status" "$(printf 'creds\tblocked\twaiting on the deploy token\n')" \
|
|
230
|
+
"blocked corr-then-key"
|
|
231
|
+
|
|
232
|
+
printf 'blocked [key=creds] [corr=aaaa1111bbbb2222]: waiting on the deploy token\n' > "$dir/b.status"
|
|
233
|
+
assert_fold "$dir/b.status" "$(printf 'creds\tblocked\twaiting on the deploy token\n')" \
|
|
234
|
+
"blocked key-then-corr"
|
|
235
|
+
|
|
236
|
+
printf 'blocked [corr=aaaa1111bbbb2222] [key=creds]: waiting on the deploy token\n' > "$dir/c.status"
|
|
237
|
+
printf 'resolved [corr=aaaa1111bbbb2222] [key=creds]: answered: rotated\n' >> "$dir/c.status"
|
|
238
|
+
assert_fold "$dir/c.status" "" "blocked/resolved corr+key close together regardless of tag order"
|
|
239
|
+
pass "blocked/resolved parse their bare verb with any bracket-tag order preceding the colon"
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
test_incremental_agrees_with_full_fold_across_appends() {
|
|
243
|
+
local dir f expected
|
|
244
|
+
dir=$(case_dir incremental)
|
|
245
|
+
f="$dir/t.status"
|
|
246
|
+
# assert_fold already pins incremental==full per snapshot; this case pins the
|
|
247
|
+
# agreement ACROSS appends, where the incremental path folds only the new
|
|
248
|
+
# bytes on top of its persisted open set while the full fold re-reads
|
|
249
|
+
# everything from scratch.
|
|
250
|
+
printf 'needs-decision: [key=seam-max-bound] pick the bound\n' > "$f"
|
|
251
|
+
expected=$(printf 'seam-max-bound\tneeds-decision\tpick the bound\n')
|
|
252
|
+
assert_fold "$f" "$expected" "colon-first open, first read"
|
|
253
|
+
|
|
254
|
+
printf 'working: routine progress note\n' >> "$f"
|
|
255
|
+
printf 'needs-decision: [key=other] a second colon-form question\n' >> "$f"
|
|
256
|
+
expected=$(printf 'seam-max-bound\tneeds-decision\tpick the bound\nother\tneeds-decision\ta second colon-form question\n')
|
|
257
|
+
assert_fold "$f" "$expected" "colon-first opens buried under later appends"
|
|
258
|
+
|
|
259
|
+
printf 'resolved [key=seam-max-bound]: answered: use 4\n' >> "$f"
|
|
260
|
+
printf 'resolved: [key=other] cleared on its own\n' >> "$f"
|
|
261
|
+
assert_fold "$f" "" "cross-position resolutions close both"
|
|
262
|
+
pass "the incremental fold matches the full fold across appends in both key positions"
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
test_stated_key_is_honored_in_both_positions
|
|
266
|
+
test_bare_keyless_line_still_folds_to_default
|
|
267
|
+
test_resolution_closes_across_positions
|
|
268
|
+
test_blocked_is_position_tolerant_like_needs_decision
|
|
269
|
+
test_two_colon_form_decisions_stay_distinct
|
|
270
|
+
test_mid_note_prose_mention_is_not_a_stated_key
|
|
271
|
+
test_malformed_stated_key_never_collapses_to_default
|
|
272
|
+
test_status_line_verb_strips_every_bracket_tag_before_colon
|
|
273
|
+
test_corr_and_key_tags_open_and_close_under_the_stated_key
|
|
274
|
+
test_corr_only_tag_opens_as_default_like_a_bare_line
|
|
275
|
+
test_key_only_before_colon_still_opens_no_regression
|
|
276
|
+
test_blocked_and_resolved_are_tag_order_independent
|
|
277
|
+
test_incremental_agrees_with_full_fold_across_appends
|
|
278
|
+
|
|
279
|
+
# status_key_closing_verb reports HOW the status side currently reads one key,
|
|
280
|
+
# which is what lets a consumer tell a settled key from a key handed to a
|
|
281
|
+
# durable captain-held task. The two closing verbs must stay distinguishable:
|
|
282
|
+
# `resolved` claims the question is settled outright, while `captain-held` is
|
|
283
|
+
# the verified transfer to that task, so treating them alike would either lose
|
|
284
|
+
# the record-divergence signal or invent one on every correct transfer.
|
|
285
|
+
test_closing_verb_separates_resolution_from_durable_transfer() {
|
|
286
|
+
local dir f
|
|
287
|
+
dir=$(case_dir closing-verb)
|
|
288
|
+
f="$dir/a.status"
|
|
289
|
+
cat > "$f" <<'EOF'
|
|
290
|
+
working: started
|
|
291
|
+
needs-decision [key=route]: north or south
|
|
292
|
+
resolved [key=route]: answered: north
|
|
293
|
+
needs-decision [key=access]: open or restricted
|
|
294
|
+
captain-held [key=access]: tracked by sample-access-call
|
|
295
|
+
blocked [key=creds]: need the deploy token
|
|
296
|
+
done: everything else shipped
|
|
297
|
+
EOF
|
|
298
|
+
[ "$(status_key_closing_verb "$f" route)" = resolved ] \
|
|
299
|
+
|| fail "a resolved key did not report the resolve verb: '$(status_key_closing_verb "$f" route)'"
|
|
300
|
+
[ "$(status_key_closing_verb "$f" access)" = captain-held ] \
|
|
301
|
+
|| fail "a durable-transfer close reported the wrong verb: '$(status_key_closing_verb "$f" access)'"
|
|
302
|
+
[ "$(status_key_closing_verb "$f" creds)" = blocked ] \
|
|
303
|
+
|| fail "a still-open key must report its opening verb: '$(status_key_closing_verb "$f" creds)'"
|
|
304
|
+
[ -z "$(status_key_closing_verb "$f" never-mentioned)" ] \
|
|
305
|
+
|| fail "a key with no transition line reported a verb"
|
|
306
|
+
[ -z "$(status_key_closing_verb "$dir/absent.status" route)" ] \
|
|
307
|
+
|| fail "an absent status file reported a verb"
|
|
308
|
+
pass "status_key_closing_verb separates resolution, durable transfer, and still-open"
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
# The reported verb is the LAST transition, read through the same fold rule as
|
|
312
|
+
# everything else: the colon-first key position counts, a re-opened key reports
|
|
313
|
+
# open again, and a prose mention is never a transition.
|
|
314
|
+
test_closing_verb_tracks_the_last_transition_in_both_positions() {
|
|
315
|
+
local dir f
|
|
316
|
+
dir=$(case_dir closing-verb-last)
|
|
317
|
+
f="$dir/a.status"
|
|
318
|
+
cat > "$f" <<'EOF'
|
|
319
|
+
needs-decision: [key=route] colon-first open
|
|
320
|
+
resolved: [key=route] colon-first close
|
|
321
|
+
EOF
|
|
322
|
+
[ "$(status_key_closing_verb "$f" route)" = resolved ] \
|
|
323
|
+
|| fail "a colon-first resolution was not seen: '$(status_key_closing_verb "$f" route)'"
|
|
324
|
+
|
|
325
|
+
printf 'needs-decision [key=route]: re-opened after a bad answer\n' >> "$f"
|
|
326
|
+
[ "$(status_key_closing_verb "$f" route)" = needs-decision ] \
|
|
327
|
+
|| fail "a re-opened key still reported closed: '$(status_key_closing_verb "$f" route)'"
|
|
328
|
+
|
|
329
|
+
printf 'resolved [key=route]: answered: south after all\n' >> "$f"
|
|
330
|
+
[ "$(status_key_closing_verb "$f" route)" = resolved ] \
|
|
331
|
+
|| fail "the last of several transitions was not reported: '$(status_key_closing_verb "$f" route)'"
|
|
332
|
+
|
|
333
|
+
printf 'working: a later append that only mentions [key=route] as prose\n' >> "$f"
|
|
334
|
+
[ "$(status_key_closing_verb "$f" route)" = resolved ] \
|
|
335
|
+
|| fail "a prose mention changed the reported verb: '$(status_key_closing_verb "$f" route)'"
|
|
336
|
+
pass "status_key_closing_verb reports the last real transition, in either key position"
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
test_closing_verb_separates_resolution_from_durable_transfer
|
|
340
|
+
test_closing_verb_tracks_the_last_transition_in_both_positions
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Opt-in credentialed Claude live regression for the Stop-owned auto-arm
|
|
3
|
+
# (bin/fm-claude-stop-autoarm.sh + bin/fm-turnend-guard.sh --claude).
|
|
4
|
+
# Proves, against the real installed Claude Code and the real tracked hook
|
|
5
|
+
# registration: a fresh session with in-flight work, no watcher, and a stale
|
|
6
|
+
# session lock can run fm-session-start.sh first; session start reclaims the
|
|
7
|
+
# dead owner; at least two tokenless auto-arm and rewake cycles then complete
|
|
8
|
+
# with zero model-issued arm commands; and the cooperative guard consumes no
|
|
9
|
+
# forced continuation while the hook's launch is healthy.
|
|
10
|
+
# The project and FM_HOME are isolated; Claude keeps using its existing managed
|
|
11
|
+
# authentication. No live fleet home, worktree, or session is touched.
|
|
12
|
+
# shellcheck disable=SC2016 # the model, not this test shell, reads the prompt text
|
|
13
|
+
set -u
|
|
14
|
+
|
|
15
|
+
if [ "${FM_CLAUDE_LIVE_E2E:-0}" != 1 ]; then
|
|
16
|
+
echo "skip: set FM_CLAUDE_LIVE_E2E=1 to run the Claude Stop auto-arm regression"
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
21
|
+
|
|
22
|
+
fail() {
|
|
23
|
+
printf 'not ok - %s\n' "$1" >&2
|
|
24
|
+
exit 1
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
command -v claude >/dev/null 2>&1 || fail "claude not found"
|
|
28
|
+
|
|
29
|
+
LAB="$ROOT/.claude-autoarm-live-e2e.$$"
|
|
30
|
+
PROJECT="$LAB/project"
|
|
31
|
+
HOME_DIR="$LAB/fmhome"
|
|
32
|
+
LIVE_OWNER_HOME="$LAB/live-owner-home"
|
|
33
|
+
TRANSCRIPT="$LAB/claude.jsonl"
|
|
34
|
+
CLAUDE_VERSION=$(claude --version)
|
|
35
|
+
|
|
36
|
+
cleanup() {
|
|
37
|
+
rm -rf "$LAB"
|
|
38
|
+
}
|
|
39
|
+
trap cleanup EXIT
|
|
40
|
+
|
|
41
|
+
mkdir -p "$LAB"
|
|
42
|
+
# git clone of this worktree carries only committed state, so copy the
|
|
43
|
+
# working-tree surfaces under test (same pattern as the continuity live E2E).
|
|
44
|
+
git clone -q "$ROOT" "$PROJECT"
|
|
45
|
+
cp -R "$ROOT/bin/." "$PROJECT/bin/"
|
|
46
|
+
cp "$ROOT/.claude/settings.json" "$PROJECT/.claude/settings.json"
|
|
47
|
+
# The lab keeps the real tracked .claude/settings.json SessionStart nudge,
|
|
48
|
+
# Stop guard, and asyncRewake auto-arm registration.
|
|
49
|
+
# The only local hook records model-issued Bash calls without acquiring the
|
|
50
|
+
# session lock or otherwise changing lifecycle behavior.
|
|
51
|
+
cat > "$PROJECT/.claude/settings.local.json" <<'JSON'
|
|
52
|
+
{
|
|
53
|
+
"hooks": {
|
|
54
|
+
"PreToolUse": [
|
|
55
|
+
{
|
|
56
|
+
"matcher": "Bash",
|
|
57
|
+
"hooks": [
|
|
58
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/bin/tool-logger.sh" }
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
JSON
|
|
65
|
+
|
|
66
|
+
cat > "$PROJECT/bin/tool-logger.sh" <<'SH'
|
|
67
|
+
#!/usr/bin/env bash
|
|
68
|
+
P=$(cat 2>/dev/null || true)
|
|
69
|
+
printf '%s\n' "$P" | jq -r '.tool_input.command // "unknown"' >> "$FM_HOME/state/tool-calls.log" 2>/dev/null
|
|
70
|
+
exit 0
|
|
71
|
+
SH
|
|
72
|
+
chmod +x "$PROJECT/bin/tool-logger.sh"
|
|
73
|
+
|
|
74
|
+
mkdir -p "$HOME_DIR/state" "$HOME_DIR/config" "$HOME_DIR/data"
|
|
75
|
+
printf 'project=fixture\nwindow=fixture\nbackend=tmux\n' > "$HOME_DIR/state/task.meta"
|
|
76
|
+
# A numeric pid above the supported OS pid range is a demonstrably dead prior
|
|
77
|
+
# harness owner under fm_harness_pid_alive, matching the reproduced incident.
|
|
78
|
+
printf '9999999\n' > "$HOME_DIR/state/.lock"
|
|
79
|
+
|
|
80
|
+
# Rapid-death arm fixture: started plus an immediate actionable reason, the
|
|
81
|
+
# exact spent-Stop edge shape. Runs 1-2 close actionable; run 3 closes clean so
|
|
82
|
+
# a misbehaving session can never loop forever.
|
|
83
|
+
cat > "$PROJECT/bin/fm-watch-arm.sh" <<'SH'
|
|
84
|
+
#!/usr/bin/env bash
|
|
85
|
+
N=$(cat "$FM_HOME/state/arm-count" 2>/dev/null || echo 0); N=$((N+1)); echo "$N" > "$FM_HOME/state/arm-count"
|
|
86
|
+
echo "arm-run=$N pid=$$" >> "$FM_HOME/state/arm-ran"
|
|
87
|
+
if [ "$N" -ge 3 ]; then
|
|
88
|
+
rm -f "$FM_HOME/state/task.meta"
|
|
89
|
+
printf 'watcher: attached pid=%s (beacon 2s)\n' "$$"
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
printf 'watcher: started pid=%s (beacon fresh)\n' "$$"
|
|
93
|
+
printf 'stale: fixture-rapid-%s\n' "$N"
|
|
94
|
+
exit 0
|
|
95
|
+
SH
|
|
96
|
+
# Drain fixture: session start invokes it once, then the model invokes it once
|
|
97
|
+
# per rewake. The third total drain ends the in-flight need after two complete
|
|
98
|
+
# Stop-owned cycles.
|
|
99
|
+
cat > "$PROJECT/bin/fm-wake-drain.sh" <<'SH'
|
|
100
|
+
#!/usr/bin/env bash
|
|
101
|
+
N=$(cat "$FM_HOME/state/drain-count" 2>/dev/null || echo 0); N=$((N+1)); echo "$N" > "$FM_HOME/state/drain-count"
|
|
102
|
+
echo "drain-run=$N" >> "$FM_HOME/state/drain-ran"
|
|
103
|
+
if [ "$N" -ge 3 ]; then
|
|
104
|
+
rm -f "$FM_HOME/state/task.meta"
|
|
105
|
+
fi
|
|
106
|
+
printf 'stale: fixture-rapid drained\n'
|
|
107
|
+
SH
|
|
108
|
+
chmod +x "$PROJECT/bin/fm-watch-arm.sh" "$PROJECT/bin/fm-wake-drain.sh"
|
|
109
|
+
|
|
110
|
+
PROMPT='Run exactly `bin/fm-session-start.sh` with Bash as your first tool call. After reading its complete digest, reply with exactly CYCLE0 and stop. Whenever a Stop hook feedback message wakes you, run exactly `bin/fm-wake-drain.sh` once with Bash, then reply with exactly ACK and stop. Never run bin/fm-watch-arm.sh or any other arm command, and never use any other tool.'
|
|
111
|
+
|
|
112
|
+
(
|
|
113
|
+
cd "$PROJECT" || exit 1
|
|
114
|
+
FM_HOME="$HOME_DIR" CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false \
|
|
115
|
+
claude -p "$PROMPT" --dangerously-skip-permissions --effort low --output-format stream-json --verbose
|
|
116
|
+
) > "$TRANSCRIPT" 2>&1 || fail "Claude credentialed auto-arm session failed: $(tail -20 "$TRANSCRIPT")"
|
|
117
|
+
|
|
118
|
+
ARM_RUNS=$(wc -l < "$HOME_DIR/state/arm-ran" 2>/dev/null | tr -d ' ')
|
|
119
|
+
[ "$ARM_RUNS" = 2 ] || fail "expected exactly 2 hook-owned arm cycles, got $ARM_RUNS: $(cat "$HOME_DIR/state/arm-ran" 2>/dev/null)"
|
|
120
|
+
DRAIN_RUNS=$(wc -l < "$HOME_DIR/state/drain-ran" 2>/dev/null | tr -d ' ')
|
|
121
|
+
[ "$DRAIN_RUNS" = 3 ] || fail "expected one session-start drain plus two model wake drains, got $DRAIN_RUNS drains"
|
|
122
|
+
REWAKES=$(grep -c 'Stop hook feedback' "$TRANSCRIPT" 2>/dev/null || true)
|
|
123
|
+
[ "$REWAKES" -ge 2 ] || fail "expected at least 2 exit-2 rewake deliveries, got $REWAKES"
|
|
124
|
+
grep -q 'stale: fixture-rapid-1' "$TRANSCRIPT" || fail "first rapid rewake reason missing from the transcript"
|
|
125
|
+
grep -q 'stale: fixture-rapid-2' "$TRANSCRIPT" || fail "second rapid rewake reason missing from the transcript"
|
|
126
|
+
[ "$(sed -n '1p' "$HOME_DIR/state/tool-calls.log" 2>/dev/null)" = 'bin/fm-session-start.sh' ] \
|
|
127
|
+
|| fail "fresh Claude session did not run session start first: $(cat "$HOME_DIR/state/tool-calls.log" 2>/dev/null)"
|
|
128
|
+
[ "$(cat "$HOME_DIR/state/.lock" 2>/dev/null)" != 9999999 ] \
|
|
129
|
+
|| fail "session start did not reclaim the stale dead-owner lock"
|
|
130
|
+
if [ -f "$HOME_DIR/state/tool-calls.log" ]; then
|
|
131
|
+
! grep -q 'fm-watch-arm.sh' "$HOME_DIR/state/tool-calls.log" \
|
|
132
|
+
|| fail "model issued an arm command despite Stop-owned continuity: $(cat "$HOME_DIR/state/tool-calls.log")"
|
|
133
|
+
! grep -q '&' "$HOME_DIR/state/tool-calls.log" \
|
|
134
|
+
|| fail "model used a shell ampersand: $(cat "$HOME_DIR/state/tool-calls.log")"
|
|
135
|
+
fi
|
|
136
|
+
! grep -q 'TURN WOULD END BLIND' "$TRANSCRIPT" \
|
|
137
|
+
|| fail "cooperative guard consumed a forced continuation while the auto-arm launch was healthy"
|
|
138
|
+
[ "$(sed -n 's/^.*outcome=\([a-z][a-z]*\) .*$/\1/p' "$HOME_DIR/state/.claude-autoarm-epoch" 2>/dev/null)" = rewake ] \
|
|
139
|
+
|| fail "auto-arm epoch ledger must record the rewake outcome"
|
|
140
|
+
[ ! -e "$HOME_DIR/state/.claude-autoarm.lock" ] || fail "auto-arm owner lock was left behind"
|
|
141
|
+
|
|
142
|
+
# Live-owner negative control: a separate supported-harness process owns a
|
|
143
|
+
# second isolated home while another Stop hook fires from the same primary
|
|
144
|
+
# project. The competing hook must not replace the session lock, arm, write an
|
|
145
|
+
# epoch, or rewake.
|
|
146
|
+
FAKE_CLAUDE="$LAB/claude"
|
|
147
|
+
ln -s /bin/bash "$FAKE_CLAUDE"
|
|
148
|
+
mkdir -p "$LIVE_OWNER_HOME/state" "$LIVE_OWNER_HOME/config"
|
|
149
|
+
printf 'project=fixture\n' > "$LIVE_OWNER_HOME/state/task.meta"
|
|
150
|
+
"$FAKE_CLAUDE" -c 'sleep 3; :' &
|
|
151
|
+
LIVE_OWNER_PID=$!
|
|
152
|
+
printf '%s\n' "$LIVE_OWNER_PID" > "$LIVE_OWNER_HOME/state/.lock"
|
|
153
|
+
LIVE_OWNER_RC=0
|
|
154
|
+
printf '%s\n' '{"session_id":"live-owner-control"}' \
|
|
155
|
+
| FM_HOME="$LIVE_OWNER_HOME" FM_ROOT_OVERRIDE="$PROJECT" "$FAKE_CLAUDE" -c '"$FM_ROOT_OVERRIDE/bin/fm-claude-stop-autoarm.sh"' \
|
|
156
|
+
>"$LAB/live-owner.out" 2>"$LAB/live-owner.err" || LIVE_OWNER_RC=$?
|
|
157
|
+
[ "$LIVE_OWNER_RC" -eq 0 ] || fail "competing Stop hook returned $LIVE_OWNER_RC while another live session owned the home"
|
|
158
|
+
[ "$(cat "$LIVE_OWNER_HOME/state/.lock")" = "$LIVE_OWNER_PID" ] || fail "competing Stop hook replaced the live session owner"
|
|
159
|
+
[ ! -e "$LIVE_OWNER_HOME/state/arm-ran" ] || fail "competing Stop hook armed while another live session owned the home"
|
|
160
|
+
[ ! -e "$LIVE_OWNER_HOME/state/.claude-autoarm-epoch" ] || fail "competing Stop hook wrote an epoch while another live session owned the home"
|
|
161
|
+
[ ! -s "$LAB/live-owner.out" ] && [ ! -s "$LAB/live-owner.err" ] || fail "competing Stop hook produced a rewake while another live session owned the home"
|
|
162
|
+
wait "$LIVE_OWNER_PID"
|
|
163
|
+
|
|
164
|
+
printf 'ok - Claude %s live E2E reclaimed a stale session lock through session start, completed two tokenless Stop-owned rewake cycles, and preserved the competing-live-owner boundary\n' "$CLAUDE_VERSION"
|