@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,631 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Opt-in live guard for the Claude, Codex exec, and Pi RUN-tier session-open adapters.
|
|
3
|
+
# Cursor's source-free RUN-tier transport is covered with its stop-hook park by
|
|
4
|
+
# tests/fm-cursor-primary-live-e2e.test.sh.
|
|
5
|
+
#
|
|
6
|
+
# Three facts in this area come from the vendor, not from Firstmate, so a stub
|
|
7
|
+
# can only confirm the assumption already written into the stub:
|
|
8
|
+
#
|
|
9
|
+
# (a) the harness tells the hook WHICH session open this is, well enough that
|
|
10
|
+
# a context-preserving reopen is never mistaken for a context reset,
|
|
11
|
+
# (b) hook stdout actually reaches model context on a context-RESET open
|
|
12
|
+
# (clear/compact), not only on a cold startup, and
|
|
13
|
+
# (c) a worker the hook detaches SURVIVES the hook returning. Session start
|
|
14
|
+
# moved every external-network call into such a worker
|
|
15
|
+
# (bin/fm-startup-network.sh), so a harness that reaps the hook's process
|
|
16
|
+
# tree would silently stop running the sweeps entirely. Whether it does is
|
|
17
|
+
# a vendor behavior no portable test can see.
|
|
18
|
+
#
|
|
19
|
+
# docs/sessionstart-nudge.md owns the routing facts (a) and (b) feed, and
|
|
20
|
+
# tests/fm-sessionstart-nudge.test.sh pins that routing portably with real
|
|
21
|
+
# processes and no harness. This guard covers only what CI cannot see.
|
|
22
|
+
#
|
|
23
|
+
# It swaps a RECORDER in for bin/fm-sessionstart-run.sh inside a throwaway lab
|
|
24
|
+
# checkout, so nothing here touches a real home, lock, or fleet. The recorder
|
|
25
|
+
# logs the source the harness supplied and prints a source-stamped token; the
|
|
26
|
+
# model is then asked to quote that token back, which is the only way to prove
|
|
27
|
+
# the stdout genuinely landed in context rather than merely being produced.
|
|
28
|
+
# The token index advances on every open, so a stale earlier token can never
|
|
29
|
+
# satisfy a later assertion and no case can go quietly vacuous.
|
|
30
|
+
#
|
|
31
|
+
# Run it after every harness upgrade and before trusting refreshed evidence in
|
|
32
|
+
# docs/verification/supervision.md:
|
|
33
|
+
#
|
|
34
|
+
# FM_SESSIONSTART_HOOK_LIVE_E2E=1 tests/fm-sessionstart-hook-live-e2e.test.sh
|
|
35
|
+
#
|
|
36
|
+
# That mode costs real model turns on every installed adapter in this suite.
|
|
37
|
+
# The Pi `/new` provider-prerequisite regression has a separate offline mode
|
|
38
|
+
# using a deterministic local provider and no user credentials:
|
|
39
|
+
#
|
|
40
|
+
# FM_PI_SESSIONSTART_RACE_LIVE_E2E=1 tests/fm-sessionstart-hook-live-e2e.test.sh
|
|
41
|
+
set -u
|
|
42
|
+
|
|
43
|
+
if [ "${FM_SESSIONSTART_HOOK_LIVE_E2E:-0}" != 1 ] && \
|
|
44
|
+
[ "${FM_PI_SESSIONSTART_RACE_LIVE_E2E:-0}" != 1 ]; then
|
|
45
|
+
echo "skip: set FM_SESSIONSTART_HOOK_LIVE_E2E=1 for the cross-harness guard or FM_PI_SESSIONSTART_RACE_LIVE_E2E=1 for the offline Pi /new race regression"
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
50
|
+
unset NO_MISTAKES_GATE
|
|
51
|
+
|
|
52
|
+
fail() {
|
|
53
|
+
printf 'not ok - %s\n' "$1" >&2
|
|
54
|
+
exit 1
|
|
55
|
+
}
|
|
56
|
+
pass() { printf 'ok - %s\n' "$1"; }
|
|
57
|
+
note() { printf '# %s\n' "$1"; }
|
|
58
|
+
|
|
59
|
+
command -v tmux >/dev/null 2>&1 || fail "tmux not found; the context-reset checks drive real interactive harnesses"
|
|
60
|
+
|
|
61
|
+
# Outside the repo on purpose: each lab is its own git repo, and nesting one
|
|
62
|
+
# inside the checkout would show up as an embedded repository in a working tree
|
|
63
|
+
# a maintainer may be committing from while this guard runs.
|
|
64
|
+
LAB="${TMPDIR:-/tmp}/fm-sessionstart-hook-live-e2e.$$"
|
|
65
|
+
SOCKET="fm-ss-hook-$$"
|
|
66
|
+
CHECKED=0
|
|
67
|
+
ABSENT=
|
|
68
|
+
|
|
69
|
+
cleanup() {
|
|
70
|
+
tmux -L "$SOCKET" kill-server >/dev/null 2>&1 || true
|
|
71
|
+
rm -rf "$LAB"
|
|
72
|
+
}
|
|
73
|
+
trap cleanup EXIT INT TERM
|
|
74
|
+
|
|
75
|
+
capture() { tmux -L "$SOCKET" capture-pane -p -t "$1" -S -400 2>/dev/null || true; }
|
|
76
|
+
|
|
77
|
+
wait_for_text() { # <session> <text> [attempts]
|
|
78
|
+
local session=$1 expected=$2 attempts=${3:-90} i=0
|
|
79
|
+
while [ "$i" -lt "$attempts" ]; do
|
|
80
|
+
capture "$session" | grep -Fq "$expected" && return 0
|
|
81
|
+
sleep 2
|
|
82
|
+
i=$((i + 1))
|
|
83
|
+
done
|
|
84
|
+
return 1
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
send_line() { # <session> <text>
|
|
88
|
+
tmux -L "$SOCKET" send-keys -t "$1" -l "$2"
|
|
89
|
+
sleep 2
|
|
90
|
+
tmux -L "$SOCKET" send-keys -t "$1" Enter
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
ASK='Reply with exactly the FMHOOKTOKEN value from your session-start context and nothing else.'
|
|
94
|
+
LIVE_NONCE=$(od -An -N12 -tx1 /dev/urandom | tr -d ' \n')
|
|
95
|
+
|
|
96
|
+
# --- lab ---------------------------------------------------------------------
|
|
97
|
+
#
|
|
98
|
+
# A Firstmate-shaped checkout carrying the harness's own TRACKED registration,
|
|
99
|
+
# with the wrapper replaced by a recorder, so a registration that stops firing
|
|
100
|
+
# fails this guard. The other hook scripts the tracked configs reference get
|
|
101
|
+
# no-op stubs: only the session-open registration is under test here, and a
|
|
102
|
+
# missing turn-end guard would otherwise spray unrelated errors into the pane.
|
|
103
|
+
make_lab() { # <harness> -> echoes lab dir
|
|
104
|
+
local harness=$1
|
|
105
|
+
local lab="$LAB/$harness" stub
|
|
106
|
+
mkdir -p "$lab/bin" "$lab/state"
|
|
107
|
+
git init -q -b main "$lab"
|
|
108
|
+
git -C "$lab" config user.email fmtest@example.invalid
|
|
109
|
+
git -C "$lab" config user.name fmtest
|
|
110
|
+
printf '# Firstmate lab\n' > "$lab/AGENTS.md"
|
|
111
|
+
git -C "$lab" add -A >/dev/null 2>&1 || true
|
|
112
|
+
git -C "$lab" commit -q -m init >/dev/null 2>&1 || true
|
|
113
|
+
|
|
114
|
+
for stub in fm-turnend-guard.sh fm-claude-stop-autoarm.sh fm-arm-pretool-check.sh \
|
|
115
|
+
fm-cd-pretool-check.sh fm-subagent-pretool-check.sh; do
|
|
116
|
+
printf '#!/usr/bin/env bash\nexit 0\n' > "$lab/bin/$stub"
|
|
117
|
+
chmod +x "$lab/bin/$stub"
|
|
118
|
+
done
|
|
119
|
+
|
|
120
|
+
# The REAL deferred-network stage plus the two libraries it sources, so fact
|
|
121
|
+
# (c) is proven against the actual detach this ship relies on rather than a
|
|
122
|
+
# re-creation of it. Its bootstrap child is a stub: what is under test here is
|
|
123
|
+
# survival across the hook boundary, not the sweeps, which
|
|
124
|
+
# tests/fm-bootstrap.test.sh already owns.
|
|
125
|
+
ln -sf "$ROOT/bin/fm-startup-network.sh" "$lab/bin/fm-startup-network.sh"
|
|
126
|
+
ln -sf "$ROOT/bin/fm-timeout-lib.sh" "$lab/bin/fm-timeout-lib.sh"
|
|
127
|
+
ln -sf "$ROOT/bin/fm-wake-lib.sh" "$lab/bin/fm-wake-lib.sh"
|
|
128
|
+
ln -sf "$ROOT/bin/fm-session-lock-lib.sh" "$lab/bin/fm-session-lock-lib.sh"
|
|
129
|
+
cat > "$lab/bin/fm-bootstrap.sh" <<'SH'
|
|
130
|
+
#!/usr/bin/env bash
|
|
131
|
+
# Outlives the hook on purpose: the marker can only appear if the worker was
|
|
132
|
+
# still running well after the harness finished with its session-open hook.
|
|
133
|
+
set -u
|
|
134
|
+
sleep 6
|
|
135
|
+
printf 'detached worker survived the hook\n' > "${FM_LIVE_DETACH_MARKER:?}"
|
|
136
|
+
exit 0
|
|
137
|
+
SH
|
|
138
|
+
chmod +x "$lab/bin/fm-bootstrap.sh"
|
|
139
|
+
|
|
140
|
+
cat > "$lab/bin/fm-sessionstart-run.sh" <<'SH'
|
|
141
|
+
#!/usr/bin/env bash
|
|
142
|
+
# Recorder standing in for the real wrapper: logs the source the harness
|
|
143
|
+
# supplied and prints a source-stamped token for the model to quote back.
|
|
144
|
+
set -u
|
|
145
|
+
record=${FM_LIVE_RECORD:?}
|
|
146
|
+
source=
|
|
147
|
+
while [ $# -gt 0 ]; do
|
|
148
|
+
case "$1" in
|
|
149
|
+
--source) source=${2:-}; shift 2 || exit 0 ;;
|
|
150
|
+
*) shift ;;
|
|
151
|
+
esac
|
|
152
|
+
done
|
|
153
|
+
if [ -z "$source" ]; then
|
|
154
|
+
source=$(cat 2>/dev/null | awk '
|
|
155
|
+
BEGIN { RS = "\"" }
|
|
156
|
+
seen == 2 { print; exit }
|
|
157
|
+
seen == 1 && $0 ~ /^[[:space:]]*:[[:space:]]*$/ { seen = 2; next }
|
|
158
|
+
seen == 1 { seen = 0 }
|
|
159
|
+
$0 == "source" { seen = 1 }
|
|
160
|
+
')
|
|
161
|
+
fi
|
|
162
|
+
[ -n "$source" ] || source=none
|
|
163
|
+
printf '%s\n' "$source" >> "$record"
|
|
164
|
+
# Exactly what bin/fm-session-start.sh does after taking the lock.
|
|
165
|
+
if [ -n "${FM_LIVE_DETACH_MARKER:-}" ]; then
|
|
166
|
+
"$(dirname "$0")/fm-startup-network.sh" start --locked 0 --harvest-pid $$ >/dev/null 2>&1 || true
|
|
167
|
+
fi
|
|
168
|
+
printf 'FMHOOKTOKEN-%s-%s-%s\n' "$source" "$(grep -c . "$record" | tr -d ' ')" "${FM_LIVE_NONCE:?}"
|
|
169
|
+
exit 0
|
|
170
|
+
SH
|
|
171
|
+
chmod +x "$lab/bin/fm-sessionstart-run.sh"
|
|
172
|
+
|
|
173
|
+
case "$harness" in
|
|
174
|
+
claude) mkdir -p "$lab/.claude"; cp "$ROOT/.claude/settings.json" "$lab/.claude/settings.json" ;;
|
|
175
|
+
codex) mkdir -p "$lab/.codex"; cp "$ROOT/.codex/hooks.json" "$lab/.codex/hooks.json" ;;
|
|
176
|
+
pi)
|
|
177
|
+
mkdir -p "$lab/.pi/extensions/lib"
|
|
178
|
+
cp "$ROOT/.pi/extensions/fm-primary-turnend-guard.ts" "$lab/.pi/extensions/"
|
|
179
|
+
cp "$ROOT/.pi/extensions/lib/fm-operational-input.ts" \
|
|
180
|
+
"$ROOT/.pi/extensions/lib/fm-sessionstart-supervisor.mjs" "$lab/.pi/extensions/lib/"
|
|
181
|
+
cp "$ROOT/bin/fm-operational-input.sh" "$lab/bin/"
|
|
182
|
+
printf '%s\n' '{"compaction":{"keepRecentTokens":200}}' > "$lab/.pi/settings.json"
|
|
183
|
+
;;
|
|
184
|
+
esac
|
|
185
|
+
printf '%s\n' "$lab"
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
# --- (a) cold open and context-preserving reopen ------------------------------
|
|
189
|
+
#
|
|
190
|
+
# Both run headless, because a cold open and a resume are whole processes and
|
|
191
|
+
# need no TUI driving. The expected resume source is passed per harness rather
|
|
192
|
+
# than assumed uniform: the harnesses genuinely disagree, and what matters is
|
|
193
|
+
# only that a reopen is never reported as a context RESET, which would make the
|
|
194
|
+
# run tier skip sweeps it never ran.
|
|
195
|
+
probe_process_opens() { # <harness> <version> <lab> <expect-resume> <cold-argv...> -- <resume-argv...>
|
|
196
|
+
local harness=$1 version=$2 lab=$3 expect_resume=$4
|
|
197
|
+
shift 4
|
|
198
|
+
local record="$lab/record" cold=() resume=() seen_sep=0 arg out source
|
|
199
|
+
local marker="$lab/detach-marker" waited
|
|
200
|
+
for arg in "$@"; do
|
|
201
|
+
if [ "$arg" = -- ] && [ "$seen_sep" -eq 0 ]; then seen_sep=1; continue; fi
|
|
202
|
+
if [ "$seen_sep" -eq 0 ]; then cold+=("$arg"); else resume+=("$arg"); fi
|
|
203
|
+
done
|
|
204
|
+
|
|
205
|
+
: > "$record"
|
|
206
|
+
rm -f "$marker" "$lab/state/.startup-network."*
|
|
207
|
+
out=$( cd "$lab" && FM_LIVE_RECORD="$record" FM_LIVE_NONCE="$LIVE_NONCE" FM_ROOT_OVERRIDE="$lab" FM_HOME="$lab" \
|
|
208
|
+
FM_LIVE_DETACH_MARKER="$marker" \
|
|
209
|
+
"${cold[@]}" "$ASK" < /dev/null 2>&1 )
|
|
210
|
+
source=$(head -n 1 "$record")
|
|
211
|
+
[ -n "$source" ] \
|
|
212
|
+
|| fail "$harness $version: the tracked session-open registration never invoked the wrapper on a cold open"
|
|
213
|
+
case "$source" in
|
|
214
|
+
startup|new) : ;;
|
|
215
|
+
*) fail "$harness $version: a cold open reported source '$source', which the run tier cannot classify as a startup" ;;
|
|
216
|
+
esac
|
|
217
|
+
printf '%s' "$out" | grep -Fq "FMHOOKTOKEN-$source-1-$LIVE_NONCE" \
|
|
218
|
+
|| { printf '# cold-open model reply: %s\n' "$out" >&2; fail "$harness $version: hook stdout did not reach model context on a cold open"; }
|
|
219
|
+
pass "$harness $version: a cold open reports source '$source' and its hook stdout reaches model context"
|
|
220
|
+
|
|
221
|
+
# (c) The harness process is gone; the worker it detached must not be. The
|
|
222
|
+
# marker is written 6s after the hook returned, so it can only exist if the
|
|
223
|
+
# worker outlived the whole session-open boundary.
|
|
224
|
+
waited=0
|
|
225
|
+
while [ ! -s "$marker" ] && [ "$waited" -lt 30 ]; do sleep 1; waited=$((waited + 1)); done
|
|
226
|
+
[ -s "$marker" ] \
|
|
227
|
+
|| fail "$harness $version: the session-open hook's detached worker did not survive the hook, so session start's deferred network checks would never run on this harness"
|
|
228
|
+
pass "$harness $version: a worker detached by the session-open hook outlives it, so the deferred network checks still run"
|
|
229
|
+
|
|
230
|
+
: > "$record"
|
|
231
|
+
( cd "$lab" && FM_LIVE_RECORD="$record" FM_LIVE_NONCE="$LIVE_NONCE" FM_ROOT_OVERRIDE="$lab" FM_HOME="$lab" \
|
|
232
|
+
"${resume[@]}" 'Say only OK.' < /dev/null >/dev/null 2>&1 ) || true
|
|
233
|
+
source=$(head -n 1 "$record")
|
|
234
|
+
[ -n "$source" ] \
|
|
235
|
+
|| fail "$harness $version: a context-preserving reopen invoked no session-open hook at all"
|
|
236
|
+
case "$source" in
|
|
237
|
+
clear|compact)
|
|
238
|
+
fail "$harness $version: a context-preserving reopen reported source '$source', so the run tier would skip sweeps that never ran"
|
|
239
|
+
;;
|
|
240
|
+
esac
|
|
241
|
+
[ "$source" = "$expect_resume" ] \
|
|
242
|
+
|| fail "$harness $version: a context-preserving reopen reported source '$source', not the recorded '$expect_resume'; refresh docs/verification/supervision.md before trusting the routing"
|
|
243
|
+
pass "$harness $version: a context-preserving reopen reports source '$source', which the run tier routes without a re-emit"
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
# --- (b) context-reset opens --------------------------------------------------
|
|
247
|
+
#
|
|
248
|
+
# Only reachable through the TUI, so this one drives a real pane.
|
|
249
|
+
probe_context_reset() { # <harness> <version> <lab> <clear-command> <launch-argv...>
|
|
250
|
+
local harness=$1 version=$2 lab=$3 clear_cmd=$4
|
|
251
|
+
shift 4
|
|
252
|
+
local record="$lab/record" session="fmss-$harness" reset n compact_seed compact_reply
|
|
253
|
+
: > "$record"
|
|
254
|
+
tmux -L "$SOCKET" new-session -d -s "$session" -c "$lab" -x 200 -y 50 \
|
|
255
|
+
-e FM_LIVE_RECORD="$record" -e FM_ROOT_OVERRIDE="$lab" -e FM_HOME="$lab" \
|
|
256
|
+
-e FM_LIVE_NONCE="$LIVE_NONCE" \
|
|
257
|
+
"$*" \
|
|
258
|
+
|| fail "$harness $version: could not start an interactive lab session"
|
|
259
|
+
|
|
260
|
+
# Every run-tier TUI asks whether it trusts a folder it has not seen, and the
|
|
261
|
+
# session-open hook only fires once that is answered. Each harness's default
|
|
262
|
+
# selection IS the trusting one, so a bare Enter clears it; the loop keeps
|
|
263
|
+
# waiting for the recorded open either way, so a harness that stops prompting
|
|
264
|
+
# costs nothing. harness-adapters owns trust handling outside tests.
|
|
265
|
+
n=0
|
|
266
|
+
while [ "$n" -lt 60 ] && ! grep -q . "$record" 2>/dev/null; do
|
|
267
|
+
if capture "$session" | grep -qiE 'trust (this|the|parent)?[[:space:]]*(folder|project)'; then
|
|
268
|
+
tmux -L "$SOCKET" send-keys -t "$session" Enter
|
|
269
|
+
sleep 5
|
|
270
|
+
fi
|
|
271
|
+
sleep 2
|
|
272
|
+
n=$((n + 1))
|
|
273
|
+
done
|
|
274
|
+
grep -q . "$record" 2>/dev/null \
|
|
275
|
+
|| { capture "$session" >&2; fail "$harness $version: the interactive session fired no session-open hook"; }
|
|
276
|
+
sleep 10
|
|
277
|
+
|
|
278
|
+
send_line "$session" "$ASK"
|
|
279
|
+
wait_for_text "$session" "FMHOOKTOKEN-$(head -n 1 "$record")-1-$LIVE_NONCE" \
|
|
280
|
+
|| { capture "$session" >&2; fail "$harness $version: hook stdout did not reach interactive model context"; }
|
|
281
|
+
|
|
282
|
+
send_line "$session" "$clear_cmd"
|
|
283
|
+
n=0
|
|
284
|
+
while [ "$n" -lt 20 ] && [ -z "$(sed -n '2p' "$record")" ]; do sleep 2; n=$((n + 1)); done
|
|
285
|
+
reset=$(sed -n '2p' "$record")
|
|
286
|
+
[ -n "$reset" ] \
|
|
287
|
+
|| { capture "$session" >&2; fail "$harness $version: '$clear_cmd' fired no session-open event, so a context reset leaves the session blind"; }
|
|
288
|
+
case "$reset" in
|
|
289
|
+
clear|compact|new) : ;;
|
|
290
|
+
*) fail "$harness $version: '$clear_cmd' reported source '$reset', which the run tier would treat as a cold startup" ;;
|
|
291
|
+
esac
|
|
292
|
+
send_line "$session" "$ASK"
|
|
293
|
+
wait_for_text "$session" "FMHOOKTOKEN-$reset-2-$LIVE_NONCE" \
|
|
294
|
+
|| { capture "$session" >&2; fail "$harness $version: hook stdout did not reach model context after '$clear_cmd'"; }
|
|
295
|
+
pass "$harness $version: '$clear_cmd' reports source '$reset' and re-injects hook stdout into model context"
|
|
296
|
+
|
|
297
|
+
if [ "$harness" = pi ]; then
|
|
298
|
+
compact_seed="seed-$session-$$"
|
|
299
|
+
compact_reply="FMCOMPACTDONE-$compact_seed"
|
|
300
|
+
printf '%s\n' "$compact_seed" > "$lab/compact-seed.txt"
|
|
301
|
+
send_line "$session" "Read compact-seed.txt, then write at least 1800 words of substantial varied prose. End the final assistant response with FMCOMPACTDONE- immediately followed by the seed, with no space."
|
|
302
|
+
wait_for_text "$session" "$compact_reply" 300 \
|
|
303
|
+
|| { capture "$session" >&2; fail "$harness $version: the substantial pre-compaction assistant turn did not complete"; }
|
|
304
|
+
sleep 5
|
|
305
|
+
else
|
|
306
|
+
for n in 1 2 3 4 5; do
|
|
307
|
+
send_line "$session" "Say only ping$n."
|
|
308
|
+
wait_for_text "$session" "ping$n" 30 >/dev/null 2>&1 || true
|
|
309
|
+
done
|
|
310
|
+
fi
|
|
311
|
+
send_line "$session" /compact
|
|
312
|
+
n=0
|
|
313
|
+
while [ "$n" -lt 40 ] && ! grep -qx compact "$record"; do sleep 3; n=$((n + 1)); done
|
|
314
|
+
if grep -qx compact "$record"; then
|
|
315
|
+
send_line "$session" "$ASK"
|
|
316
|
+
wait_for_text "$session" "FMHOOKTOKEN-compact-$(grep -c . "$record" | tr -d ' ')-$LIVE_NONCE" \
|
|
317
|
+
|| { capture "$session" >&2; fail "$harness $version: hook stdout did not reach model context after a compaction"; }
|
|
318
|
+
pass "$harness $version: a compaction reports source 'compact' and re-injects hook stdout into model context"
|
|
319
|
+
elif [ "$harness" = pi ]; then
|
|
320
|
+
capture "$session" >&2
|
|
321
|
+
fail "$harness $version: /compact did not raise session_compact after a completed substantial turn with keepRecentTokens=200"
|
|
322
|
+
else
|
|
323
|
+
note "$harness $version: compaction was NOT reached in this lab (recorded: $(tr '\n' ' ' < "$record")); its compact evidence was not refreshed"
|
|
324
|
+
fi
|
|
325
|
+
|
|
326
|
+
tmux -L "$SOCKET" kill-session -t "$session" >/dev/null 2>&1 || true
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
# --- real Pi provider prerequisite -------------------------------------------
|
|
330
|
+
#
|
|
331
|
+
# This is the end-user `/new` path, not an SDK simulation. A barrier holds the
|
|
332
|
+
# native clear digest open while the first prompt is submitted. The local
|
|
333
|
+
# provider would deterministically request the manual startup command if that
|
|
334
|
+
# first payload lacked native context, reproducing the historical duplicate.
|
|
335
|
+
# The fixed path must make no provider call before release and must expose one
|
|
336
|
+
# native message on the first call. A second case proves the already-complete
|
|
337
|
+
# path reaches the same result.
|
|
338
|
+
probe_pi_sessionstart_prerequisite() {
|
|
339
|
+
local version lab project home config sessions session=pi-race
|
|
340
|
+
local pane i session_file first_line second_line
|
|
341
|
+
command -v pi >/dev/null 2>&1 || fail "pi not found for the offline /new provider-prerequisite regression"
|
|
342
|
+
version=$(pi --version 2>/dev/null | head -n 1)
|
|
343
|
+
[ -n "$version" ] || version=unknown
|
|
344
|
+
lab="$LAB/pi-race"
|
|
345
|
+
project="$lab/project"
|
|
346
|
+
home="$lab/home"
|
|
347
|
+
config="$lab/config"
|
|
348
|
+
sessions="$lab/sessions"
|
|
349
|
+
mkdir -p "$project/.pi/extensions/lib" "$project/bin" "$home/state" "$config" "$sessions"
|
|
350
|
+
git init -q -b main "$project"
|
|
351
|
+
git -C "$project" config user.email fmtest@example.invalid
|
|
352
|
+
git -C "$project" config user.name fmtest
|
|
353
|
+
printf '# Offline Pi startup-prerequisite lab\n' > "$project/AGENTS.md"
|
|
354
|
+
cp "$ROOT/.pi/extensions/fm-primary-turnend-guard.ts" "$project/.pi/extensions/"
|
|
355
|
+
cp "$ROOT/.pi/extensions/lib/fm-operational-input.ts" \
|
|
356
|
+
"$ROOT/.pi/extensions/lib/fm-sessionstart-supervisor.mjs" "$project/.pi/extensions/lib/"
|
|
357
|
+
cp "$ROOT/bin/fm-operational-input.sh" "$project/bin/"
|
|
358
|
+
cat > "$project/bin/fm-turnend-guard.sh" <<'SH'
|
|
359
|
+
#!/usr/bin/env bash
|
|
360
|
+
exit 0
|
|
361
|
+
SH
|
|
362
|
+
cat > "$project/bin/fm-sessionstart-run.sh" <<'SH'
|
|
363
|
+
#!/usr/bin/env bash
|
|
364
|
+
set -u
|
|
365
|
+
state=${FM_HOME:?}/state
|
|
366
|
+
source_name=
|
|
367
|
+
while [ $# -gt 0 ]; do
|
|
368
|
+
case "$1" in
|
|
369
|
+
--source) source_name=${2:-}; shift 2 ;;
|
|
370
|
+
*) shift ;;
|
|
371
|
+
esac
|
|
372
|
+
done
|
|
373
|
+
if [ "$source_name" != clear ]; then
|
|
374
|
+
printf 'INITIAL_STARTUP source=%s\n' "$source_name"
|
|
375
|
+
exit 0
|
|
376
|
+
fi
|
|
377
|
+
count=$(( $(grep -c '^clear-start:' "$state/events" 2>/dev/null || true) + 1 ))
|
|
378
|
+
printf 'clear-start:%s:%s\n' "$count" "$$" >> "$state/events"
|
|
379
|
+
: > "$state/native-started-$count"
|
|
380
|
+
while [ ! -f "$state/release-native-$count" ]; do sleep 0.02; done
|
|
381
|
+
printf 'RACE_NATIVE generation=%s\n' "$count"
|
|
382
|
+
: > "$state/native-completed-$count"
|
|
383
|
+
printf 'clear-complete:%s:%s\n' "$count" "$$" >> "$state/events"
|
|
384
|
+
SH
|
|
385
|
+
cat > "$project/bin/fm-session-start.sh" <<'SH'
|
|
386
|
+
#!/usr/bin/env bash
|
|
387
|
+
set -u
|
|
388
|
+
state=${FM_HOME:?}/state
|
|
389
|
+
: > "$state/manual-started"
|
|
390
|
+
printf 'RACE_MANUAL\n'
|
|
391
|
+
SH
|
|
392
|
+
cat > "$project/.pi/extensions/race-local-provider.ts" <<'TS'
|
|
393
|
+
import { appendFileSync } from "node:fs";
|
|
394
|
+
import {
|
|
395
|
+
type AssistantMessage,
|
|
396
|
+
createAssistantMessageEventStream,
|
|
397
|
+
} from "@earendil-works/pi-ai";
|
|
398
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
399
|
+
|
|
400
|
+
function textOf(content: unknown): string {
|
|
401
|
+
if (typeof content === "string") return content;
|
|
402
|
+
if (!Array.isArray(content)) return "";
|
|
403
|
+
return content
|
|
404
|
+
.filter((item): item is { type: "text"; text: string } =>
|
|
405
|
+
typeof item === "object" && item !== null &&
|
|
406
|
+
(item as { type?: unknown }).type === "text" &&
|
|
407
|
+
typeof (item as { text?: unknown }).text === "string")
|
|
408
|
+
.map((item) => item.text)
|
|
409
|
+
.join("\n");
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function assistant(model: { api: string; provider: string; id: string }): AssistantMessage {
|
|
413
|
+
return {
|
|
414
|
+
role: "assistant",
|
|
415
|
+
content: [],
|
|
416
|
+
api: model.api,
|
|
417
|
+
provider: model.provider,
|
|
418
|
+
model: model.id,
|
|
419
|
+
usage: {
|
|
420
|
+
input: 0,
|
|
421
|
+
output: 0,
|
|
422
|
+
cacheRead: 0,
|
|
423
|
+
cacheWrite: 0,
|
|
424
|
+
totalTokens: 0,
|
|
425
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
426
|
+
},
|
|
427
|
+
stopReason: "stop",
|
|
428
|
+
timestamp: Date.now(),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export default function (pi: ExtensionAPI): void {
|
|
433
|
+
pi.registerProvider("race-local", {
|
|
434
|
+
baseUrl: "http://127.0.0.1/unused",
|
|
435
|
+
apiKey: "offline-test-only",
|
|
436
|
+
api: "race-local-api",
|
|
437
|
+
models: [{
|
|
438
|
+
id: "deterministic",
|
|
439
|
+
name: "Deterministic startup prerequisite provider",
|
|
440
|
+
reasoning: false,
|
|
441
|
+
input: ["text"],
|
|
442
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
443
|
+
contextWindow: 16384,
|
|
444
|
+
maxTokens: 128,
|
|
445
|
+
}],
|
|
446
|
+
streamSimple(model, context) {
|
|
447
|
+
const stream = createAssistantMessageEventStream();
|
|
448
|
+
const texts = context.messages.map((message) => textOf(message.content));
|
|
449
|
+
const all = texts.join("\n");
|
|
450
|
+
const prompt = all.includes("IMMEDIATE_RACE_PROMPT")
|
|
451
|
+
? "immediate"
|
|
452
|
+
: all.includes("PROVEN_RACE_PROMPT")
|
|
453
|
+
? "proven"
|
|
454
|
+
: "other";
|
|
455
|
+
const nativeCount = texts.filter((text) => text.includes("RACE_NATIVE generation=")).length;
|
|
456
|
+
const manual = all.includes("RACE_MANUAL");
|
|
457
|
+
if (prompt !== "other") {
|
|
458
|
+
appendFileSync(
|
|
459
|
+
`${process.env.FM_HOME}/state/provider-calls`,
|
|
460
|
+
`prompt=${prompt} native_count=${nativeCount} manual=${manual}\n`,
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
const output = assistant(model);
|
|
464
|
+
queueMicrotask(() => {
|
|
465
|
+
stream.push({ type: "start", partial: output });
|
|
466
|
+
if (prompt !== "other" && nativeCount === 0 && !manual) {
|
|
467
|
+
output.stopReason = "toolUse";
|
|
468
|
+
const toolCall = {
|
|
469
|
+
type: "toolCall" as const,
|
|
470
|
+
id: `manual-${Date.now()}`,
|
|
471
|
+
name: "bash",
|
|
472
|
+
arguments: { command: "bin/fm-session-start.sh" },
|
|
473
|
+
};
|
|
474
|
+
output.content.push(toolCall);
|
|
475
|
+
stream.push({ type: "toolcall_start", contentIndex: 0, partial: output });
|
|
476
|
+
stream.push({
|
|
477
|
+
type: "toolcall_delta",
|
|
478
|
+
contentIndex: 0,
|
|
479
|
+
delta: JSON.stringify(toolCall.arguments),
|
|
480
|
+
partial: output,
|
|
481
|
+
});
|
|
482
|
+
stream.push({ type: "toolcall_end", contentIndex: 0, toolCall, partial: output });
|
|
483
|
+
stream.push({ type: "done", reason: "toolUse", message: output });
|
|
484
|
+
stream.end();
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
const responseText = `RACE_RESULT prompt=${prompt} native_count=${nativeCount} manual=${manual}`;
|
|
488
|
+
const block = { type: "text" as const, text: responseText };
|
|
489
|
+
output.content.push(block);
|
|
490
|
+
stream.push({ type: "text_start", contentIndex: 0, partial: output });
|
|
491
|
+
stream.push({ type: "text_delta", contentIndex: 0, delta: responseText, partial: output });
|
|
492
|
+
stream.push({ type: "text_end", contentIndex: 0, content: responseText, partial: output });
|
|
493
|
+
stream.push({ type: "done", reason: "stop", message: output });
|
|
494
|
+
stream.end();
|
|
495
|
+
});
|
|
496
|
+
return stream;
|
|
497
|
+
},
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
TS
|
|
501
|
+
chmod +x "$project/bin/"*.sh
|
|
502
|
+
git -C "$project" add -A
|
|
503
|
+
git -C "$project" commit -q -m init
|
|
504
|
+
|
|
505
|
+
tmux -L "$SOCKET" new-session -d -s "$session" -c "$project" -x 180 -y 50 \
|
|
506
|
+
"env FM_HOME='$home' FM_ROOT_OVERRIDE='$project' PI_CODING_AGENT_DIR='$config' PI_OFFLINE=1 pi --approve --session-dir '$sessions' --no-context-files --no-skills --no-prompt-templates --tools bash --model race-local/deterministic; rc=\$?; printf '\nPI_EXIT=%s\n' \"\$rc\"; sleep 60" \
|
|
507
|
+
|| fail "Pi $version: could not start the offline /new lab"
|
|
508
|
+
i=0
|
|
509
|
+
while [ "$i" -lt 200 ]; do
|
|
510
|
+
pane=$(capture "$session")
|
|
511
|
+
printf '%s\n' "$pane" | grep -Fq 'race-local-provider.ts' && \
|
|
512
|
+
printf '%s\n' "$pane" | grep -Fq 'deterministic' && break
|
|
513
|
+
sleep 0.05
|
|
514
|
+
i=$((i + 1))
|
|
515
|
+
done
|
|
516
|
+
printf '%s\n' "$pane" | grep -Fq 'deterministic' \
|
|
517
|
+
|| { printf '%s\n' "$pane" >&2; fail "Pi $version: offline local provider did not reach the ready composer"; }
|
|
518
|
+
|
|
519
|
+
tmux -L "$SOCKET" send-keys -t "$session" -l /new
|
|
520
|
+
tmux -L "$SOCKET" send-keys -t "$session" Enter
|
|
521
|
+
i=0
|
|
522
|
+
while [ "$i" -lt 500 ] && [ ! -f "$home/state/native-started-1" ]; do sleep 0.01; i=$((i + 1)); done
|
|
523
|
+
[ -f "$home/state/native-started-1" ] \
|
|
524
|
+
|| { capture "$session" >&2; fail "Pi $version: immediate /new native generation never started"; }
|
|
525
|
+
tmux -L "$SOCKET" send-keys -t "$session" -l IMMEDIATE_RACE_PROMPT
|
|
526
|
+
tmux -L "$SOCKET" send-keys -t "$session" Enter
|
|
527
|
+
sleep 0.5
|
|
528
|
+
[ ! -s "$home/state/provider-calls" ] \
|
|
529
|
+
|| fail "Pi $version: the immediate first provider call escaped before native startup settled"
|
|
530
|
+
[ ! -f "$home/state/manual-started" ] \
|
|
531
|
+
|| fail "Pi $version: manual startup ran concurrently with the native generation"
|
|
532
|
+
: > "$home/state/release-native-1"
|
|
533
|
+
i=0
|
|
534
|
+
while [ "$i" -lt 1000 ] && ! grep -Fq 'prompt=immediate native_count=1 manual=false' "$home/state/provider-calls" 2>/dev/null; do
|
|
535
|
+
sleep 0.01
|
|
536
|
+
i=$((i + 1))
|
|
537
|
+
done
|
|
538
|
+
grep -Fqx 'prompt=immediate native_count=1 manual=false' "$home/state/provider-calls" \
|
|
539
|
+
|| { capture "$session" >&2; fail "Pi $version: immediate first payload lacked exactly one native startup context"; }
|
|
540
|
+
wait_for_text "$session" 'RACE_RESULT prompt=immediate native_count=1 manual=false' 60 \
|
|
541
|
+
|| fail "Pi $version: immediate local-provider turn did not settle"
|
|
542
|
+
session_file=$(find "$sessions" -type f -name '*.jsonl' -exec grep -l IMMEDIATE_RACE_PROMPT {} + 2>/dev/null | head -1 || true)
|
|
543
|
+
[ -n "$session_file" ] || fail "Pi $version: immediate /new session file was not found"
|
|
544
|
+
[ "$(grep -Fc 'RACE_NATIVE generation=1' "$session_file")" -eq 1 ] \
|
|
545
|
+
|| fail "Pi $version: immediate generation persisted other than one native startup context"
|
|
546
|
+
[ "$(grep -c '^clear-start:1:' "$home/state/events")" -eq 1 ] \
|
|
547
|
+
|| fail "Pi $version: immediate generation executed native startup other than once"
|
|
548
|
+
[ ! -f "$home/state/manual-started" ] \
|
|
549
|
+
|| fail "Pi $version: immediate fixed path still executed manual startup"
|
|
550
|
+
|
|
551
|
+
tmux -L "$SOCKET" send-keys -t "$session" -l /new
|
|
552
|
+
tmux -L "$SOCKET" send-keys -t "$session" Enter
|
|
553
|
+
i=0
|
|
554
|
+
while [ "$i" -lt 500 ] && [ ! -f "$home/state/native-started-2" ]; do sleep 0.01; i=$((i + 1)); done
|
|
555
|
+
[ -f "$home/state/native-started-2" ] \
|
|
556
|
+
|| { capture "$session" >&2; fail "Pi $version: proven /new native generation never started"; }
|
|
557
|
+
: > "$home/state/release-native-2"
|
|
558
|
+
i=0
|
|
559
|
+
while [ "$i" -lt 500 ] && [ ! -f "$home/state/native-completed-2" ]; do sleep 0.01; i=$((i + 1)); done
|
|
560
|
+
[ -f "$home/state/native-completed-2" ] || fail "Pi $version: proven native generation did not complete"
|
|
561
|
+
tmux -L "$SOCKET" send-keys -t "$session" -l PROVEN_RACE_PROMPT
|
|
562
|
+
tmux -L "$SOCKET" send-keys -t "$session" Enter
|
|
563
|
+
wait_for_text "$session" 'RACE_RESULT prompt=proven native_count=1 manual=false' 60 \
|
|
564
|
+
|| fail "Pi $version: proven completed-before-prompt path lacked exactly one native context"
|
|
565
|
+
first_line=$(sed -n '1p' "$home/state/provider-calls")
|
|
566
|
+
second_line=$(sed -n '2p' "$home/state/provider-calls")
|
|
567
|
+
[ "$first_line" = 'prompt=immediate native_count=1 manual=false' ] \
|
|
568
|
+
|| fail "Pi $version: immediate provider evidence changed unexpectedly: $first_line"
|
|
569
|
+
[ "$second_line" = 'prompt=proven native_count=1 manual=false' ] \
|
|
570
|
+
|| fail "Pi $version: proven provider evidence changed unexpectedly: $second_line"
|
|
571
|
+
[ "$(grep -c '^clear-start:' "$home/state/events")" -eq 2 ] \
|
|
572
|
+
|| fail "Pi $version: two /new generations did not execute native startup exactly once each"
|
|
573
|
+
[ ! -f "$home/state/manual-started" ] \
|
|
574
|
+
|| fail "Pi $version: proven fixed path executed manual startup"
|
|
575
|
+
|
|
576
|
+
tmux -L "$SOCKET" send-keys -t "$session" -l /quit
|
|
577
|
+
tmux -L "$SOCKET" send-keys -t "$session" Enter
|
|
578
|
+
wait_for_text "$session" 'PI_EXIT=0' 30 || fail "Pi $version: offline /new lab did not exit cleanly"
|
|
579
|
+
pass "Pi $version: immediate and completed-before-prompt /new paths each made one first provider call with exactly one native startup context and no manual execution"
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if [ "${FM_PI_SESSIONSTART_RACE_LIVE_E2E:-0}" = 1 ]; then
|
|
583
|
+
probe_pi_sessionstart_prerequisite
|
|
584
|
+
if [ "${FM_SESSIONSTART_HOOK_LIVE_E2E:-0}" != 1 ]; then
|
|
585
|
+
echo "# fm-sessionstart-hook-live-e2e.test.sh: offline Pi /new race assertions passed"
|
|
586
|
+
exit 0
|
|
587
|
+
fi
|
|
588
|
+
fi
|
|
589
|
+
|
|
590
|
+
# --- per-harness drivers ------------------------------------------------------
|
|
591
|
+
|
|
592
|
+
for harness in claude codex pi; do
|
|
593
|
+
if ! command -v "$harness" >/dev/null 2>&1; then
|
|
594
|
+
ABSENT="$ABSENT $harness"
|
|
595
|
+
note "$harness: not installed on this host, so its run-tier evidence was NOT refreshed"
|
|
596
|
+
continue
|
|
597
|
+
fi
|
|
598
|
+
version=$("$harness" --version 2>/dev/null | head -n 1)
|
|
599
|
+
[ -n "$version" ] || version=unknown
|
|
600
|
+
lab=$(make_lab "$harness")
|
|
601
|
+
|
|
602
|
+
case "$harness" in
|
|
603
|
+
claude)
|
|
604
|
+
probe_process_opens claude "$version" "$lab" resume \
|
|
605
|
+
claude -p --permission-mode bypassPermissions \
|
|
606
|
+
-- claude --continue -p --permission-mode bypassPermissions
|
|
607
|
+
probe_context_reset claude "$version" "$lab" /clear \
|
|
608
|
+
claude --permission-mode bypassPermissions
|
|
609
|
+
;;
|
|
610
|
+
codex)
|
|
611
|
+
probe_process_opens codex "$version" "$lab" resume \
|
|
612
|
+
codex exec --dangerously-bypass-hook-trust --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check \
|
|
613
|
+
-- codex exec resume --last --dangerously-bypass-hook-trust --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check
|
|
614
|
+
note "codex $version: codex exec run-tier evidence refreshed; the interactive TUI remains uncovered because tracked project hooks provide no session-open or re-emit channel there"
|
|
615
|
+
;;
|
|
616
|
+
pi)
|
|
617
|
+
probe_process_opens pi "$version" "$lab" resume \
|
|
618
|
+
pi -p -e "$lab/.pi/extensions/fm-primary-turnend-guard.ts" --no-context-files --no-tools \
|
|
619
|
+
-- pi -p -c -e "$lab/.pi/extensions/fm-primary-turnend-guard.ts" --no-context-files --no-tools
|
|
620
|
+
probe_context_reset pi "$version" "$lab" /new \
|
|
621
|
+
pi -e "$lab/.pi/extensions/fm-primary-turnend-guard.ts" --no-context-files
|
|
622
|
+
;;
|
|
623
|
+
esac
|
|
624
|
+
CHECKED=$((CHECKED + 1))
|
|
625
|
+
done
|
|
626
|
+
|
|
627
|
+
[ "$CHECKED" -gt 0 ] \
|
|
628
|
+
|| fail "no run-tier harness was installed, so this guard verified nothing; install claude, codex, or pi before trusting its evidence"
|
|
629
|
+
[ -z "$ABSENT" ] \
|
|
630
|
+
|| note "run-tier evidence was refreshed for $CHECKED harness(es); still missing:$ABSENT"
|
|
631
|
+
echo "# fm-sessionstart-hook-live-e2e.test.sh: all live assertions passed"
|