Skip to content

feat: add opt-in session launch restrictions - #29

Merged
MrGTV-love merged 37 commits into
mainfrom
fm/fm-session-launch-runtime-restriction
Oct 7, 2026
Merged

MrGTV-love merged 37 commits into
mainfrom
fm/fm-session-launch-runtime-restriction

Conversation

@MrGTV-love

@MrGTV-love MrGTV-love commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Intent

please do not invoke codex sessions. invoke only tc run or omp sessions please.

The rationale is that there are two GPT accounts and omp can switch between them; direct Codex sessions burn credits.

why is native claude required?

why not use tc run?

tc run is operational

firstmate, the official firstmate repo has updated and we should pull it. also the latest no-mistakes repo has updated and we should pull it as well

Proceed as recommended. Merge the official changes

The approved recommendation is to merge official changes into integration branches, preserving fork and private changes, and validate before updating running copies.

Scott is working on observiablity and needs that to complete. He is waiting on it.

why has that update not installed yet?

It has been the same status for several hours.

Regarding whether upstream installation truly depends on custom launch/recovery repairs:

I strongly suspect not.

are we pulling the latest upstream repo?

What Changed

  • Add config/session-launch-policy=omp-or-tc to restrict worker and secondmate launches to the canonical omp adapter, rejecting standalone Codex, other runtimes, and opaque raw commands. Native tc run support remains unimplemented; absent configuration preserves existing behavior.
  • Inherit the policy into local and remote secondmate homes and verify policy-owning tooling against the authoritative code before admitting launches or replacements.
  • Enforce policy checks during manual and automatic recovery before endpoint removal or recovery-attempt accounting, with durable generation-scoped refusal notifications. Update dispatch, provisioning, and recovery guidance and add regression coverage for launch restrictions, inheritance, and refusal receipts.

Risk Assessment

⚠️ Medium: The opt-in restriction is bounded and no new merge-blocking defect was substantiated, but its cross-cutting admission, inheritance, and recovery changes retain operational complexity and previously accepted edge cases.

Testing

Commit-diff and tool-availability checks were followed by isolated live CLI, Herdr, actual omp launch/recovery, session-end, and remote admission scenarios; after correcting lab provisioning, readiness, and direct-relaunch fixture assumptions, all scenarios passed, evidence was saved, and disposable worktree fixtures and lab sessions were removed. No Codex session, full test suite, linter, formatter, static analyzer, installation, or other pipeline phase was invoked.

  • Live validation: ✅ go - 10 of 10 scenarios driven live against the product
Scenario Result Live Evidence
Request Codex for a fresh ship, scout, batch, or secondmate and receive refusal before launch resources are created ✅ pass live launch-refusals.json: public spawn commands returned policy refusal; state and projects directories remained empty.
Attempt to bypass the restriction with Claude or opaque omp/tc commands and receive a clear refusal ✅ pass live launch-refusals.json: Claude, omp --model anything, and tc run requests were refused.
Provide malformed or dangling policy configuration and have an otherwise permitted omp launch fail closed ✅ pass live launch-refusals.json: empty, unknown, whitespace-altered, extra-newline, and dangling-symlink policies produced configuration errors without launch resources.
Launch canonical omp under inherited policy using the openai-codex provider and receive a real model response ✅ pass live recovery-proof.json and omp-recovery-terminal.txt: actual omp registration, inherited policy, GPT-6.1-Sol session, and LIVE_RECOVERY_OMP_OK response.
Request fresh or direct Codex/raw-command launch while only the guarded child retains the restriction and preserve the child policy and work ✅ pass live recovery-live.json covers fresh admission; recovery-proof.json covers direct admission after the actual omp agent was stopped.
Request a forbidden or tooling-incompatible manual replacement and leave the existing omp agent running ✅ pass live recovery-proof.json: parent-policy, retained-child Codex, and outdated-child-tooling refusals; protected state remained unchanged and native inventory still reported omp.
Automatically recover a dead secondmate endpoint, refuse Codex without attempts or endpoint removal, then immediately recover with omp after repair ✅ pass live automatic-recovery-proof.json: real dead-endpoint classification, surviving pane after refusals, quiet repeated refusal, and one attempt/relaunched pair only after selecting omp; omp-recovery-terminal…
Recover persisted ended ship/scout records naming Codex and refuse without consuming recovery accounting or translating their model onto omp ✅ pass live session-end-proof.json: real busy-event producer and recovery consumer returned skip/refusal for both kinds, retained protected task data, created no attempt or handled-generation records, and queued…
Request forbidden remote replacement and refuse at initiating and destination admission boundaries ✅ pass live remote-admission-proof.json: initiating relaunch refused before transport/staging; destination launch refused before creating parent-route endpoint state.
Receive identical remote policy bytes with incompatible tooling, repair the owner, and remove the policy without overwriting legacy tooling ✅ pass live remote-admission-proof.json: real receiver rejected identical-byte retries with outdated tooling, reported unchanged after restoration, then removed the policy while preserving the intentionally diver…
Evidence: Fresh-launch and malformed-policy refusal transcripts

Source: Fresh-launch and malformed-policy refusal transcripts

{
  "runs": [
    {
      "command": "bin/fm-lab-home.sh create ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home",
      "exit": 0,
      "output": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\n"
    },
    {
      "command": "bin/fm-spawn.sh denied-ship ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --mode local-only --yolo off --harness codex",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy=omp-or-tc refuses launch 'codex'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "bin/fm-spawn.sh denied-scout ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy=omp-or-tc refuses launch 'codex'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "bin/fm-spawn.sh denied-mate ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/child --secondmate",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy=omp-or-tc refuses launch 'codex'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "bin/fm-spawn.sh one=~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project two=~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness codex",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy=omp-or-tc refuses launch 'codex'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "bin/fm-spawn.sh denied-claude ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness claude",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy=omp-or-tc refuses launch 'claude'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "bin/fm-spawn.sh denied-raw ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness omp --model anything",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy=omp-or-tc refuses launch 'omp --model anything'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "bin/fm-spawn.sh denied-tc ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness tc run",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy=omp-or-tc refuses launch 'tc run'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "bin/fm-spawn.sh malformed-empty ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness omp",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy must contain exactly omp-or-tc (with an optional trailing newline)\n"
    },
    {
      "command": "bin/fm-spawn.sh malformed-trailing-space ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness omp",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy must contain exactly omp-or-tc (with an optional trailing newline)\n"
    },
    {
      "command": "bin/fm-spawn.sh malformed-extra-newline ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness omp",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy must contain exactly omp-or-tc (with an optional trailing newline)\n"
    },
    {
      "command": "bin/fm-spawn.sh malformed-unknown ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness omp",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy must contain exactly omp-or-tc (with an optional trailing newline)\n"
    },
    {
      "command": "bin/fm-spawn.sh dangling-policy ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/project --scout --harness omp",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-policy-dx8oxayg/home\nerror: config/session-launch-policy must be a readable regular file containing omp-or-tc\n"
    }
  ],
  "results": [
    {
      "name": "explicit-ship-codex",
      "pass": true
    },
    {
      "name": "configured-scout-codex",
      "pass": true
    },
    {
      "name": "configured-secondmate-codex",
      "pass": true
    },
    {
      "name": "batch-codex",
      "pass": true
    },
    {
      "name": "claude-proxy-not-native",
      "pass": true
    },
    {
      "name": "opaque-omp-command",
      "pass": true
    },
    {
      "name": "opaque-tc-command",
      "pass": true
    },
    {
      "name": "malformed-empty",
      "pass": true
    },
    {
      "name": "malformed-trailing-space",
      "pass": true
    },
    {
      "name": "malformed-extra-newline",
      "pass": true
    },
    {
      "name": "malformed-unknown",
      "pass": true
    },
    {
      "name": "dangling-policy",
      "pass": true
    }
  ],
  "persisted_state": [],
  "projects": []
}
Evidence: Fresh retained-child policy refusal

Source: Fresh retained-child policy refusal

{
  "results": [
    {
      "scenario": "fresh-retained-codex",
      "pass": true
    },
    {
      "scenario": "fresh-retained-omp --model anything",
      "pass": true
    }
  ],
  "runs": [
    {
      "command": "bin/fm-lab-home.sh create ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/home",
      "exit": 0,
      "output": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/home\n"
    },
    {
      "command": "git init -b lab-preserved ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child",
      "exit": 0,
      "output": "Initialized empty Git repository in ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child/.git/\n"
    },
    {
      "command": "git -C ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child add bin .omp AGENTS.md .gitignore",
      "exit": 0,
      "output": ""
    },
    {
      "command": "git -C ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child -c user.name=Lab -c user.email=lab@example.invalid commit -q -m disposable fixture",
      "exit": 0,
      "output": ""
    },
    {
      "command": "bin/fm-herdr-lab.sh name recovery",
      "exit": 0,
      "output": "fm-lab-recovery-99939-13918\n"
    },
    {
      "command": "bin/fm-herdr-lab.sh provision fm-lab-recovery-99939-13918",
      "exit": 0,
      "output": ""
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/code/bin/fm-spawn.sh policy-live-98343 ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child --secondmate --harness codex",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/home\nwarning: secondmate policy-live-98343 sync skipped before launch: primary default-branch commit cannot be resolved\nfm-config-inherit: warning: skipped session-launch-policy for ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child/config: destination does not allow inherited item (not gitignored or guard failed)\nerror: config/session-launch-policy=omp-or-tc refuses launch 'codex'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/code/bin/fm-spawn.sh policy-live-98343 ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child --secondmate --harness omp --model anything",
      "exit": 1,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/home\nwarning: secondmate policy-live-98343 sync skipped before launch: primary default-branch commit cannot be resolved\nfm-config-inherit: warning: skipped session-launch-policy for ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child/config: destination does not allow inherited item (not gitignored or guard failed)\nerror: config/session-launch-policy=omp-or-tc refuses launch 'omp'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native launcher, not plain claude or a proxy wrapper\nhelp: select an explicit allowed dispatch profile; for recovery use bin/fm-control.sh <id> relaunch --harness omp --model <omp-model-id> --effort <level> --note \"<progress>\"; no previous agent or work needs to be discarded\n"
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/code/bin/fm-spawn.sh policy-live-98343 ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child --secondmate",
      "exit": 0,
      "output": "fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/home\nwarning: secondmate policy-live-98343 sync skipped before launch: primary default-branch commit cannot be resolved\nspawned policy-live-98343 harness=omp kind=secondmate mode=secondmate yolo=off window=fm-lab-recovery-99939-13918:w1:p2 worktree=~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/child\n"
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/code/bin/fm-peek.sh policy-live-98343",
      "exit": 0,
      "output": "\u25cf\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\u25cf  WATCHER DOWN - SUPERVISION IS OFF\n\u25cf  1 task(s) in flight, but no watcher has a fresh beacon (last beat: never, grace 300s).\n\u25cf  Trust the emitted supervision protocol for this harness; do not use shell & for watcher repair.\n\u25cf  This is a supervision warning only; the guarded operation WILL still run.\n\u25cf  repair a missing or failed watcher cycle with the omp tool fm_watch_arm_omp, or restart omp inside this home so ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/code/.omp/extensions/fm-primary-turnend-guard.ts and ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-recovery-qh8tlo52/code/.omp/extensions/fm-primary-omp-watch.ts auto-load from .omp/extensions/ (use -e with both paths only when starting omp from another directory).\n\u25cf\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\nexport GOTMPDIR=/tmp/fm-policy-live-98343/gotmp\nexport COMPACT_ADVISER_DISABLE=1\n. '/tmp/fm-policy-live-98343+78be1fe1ce471c0dc13736192712bee03020164a56ace71ca94435f3d565ee8b/launch.s1791390151.5945.14\n959.sh'"
    },
    {
      "command": "bin/fm-herdr-lab.sh teardown fm-lab-recovery-99939-13918",
      "exit": 0,
      "output": ""
    }
  ]
}
Evidence: Actual recovered omp session and model reply

Source: Actual recovered omp session and model reply

●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
●  WATCHER DOWN - SUPERVISION IS OFF
●  1 task(s) in flight, but no watcher has a fresh beacon (last beat: never, grace 300s).
●  Trust the emitted supervision protocol for this harness; do not use shell & for watcher repair.
●  This is a supervision warning only; the guarded operation WILL still run.
●  repair a missing or failed watcher cycle with the omp tool fm_watch_arm_omp, or restart omp inside this home so ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-auto-693wcttm/code/.omp/extensions/fm-primary-turnend-guard.ts and ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-auto-693wcttm/code/.omp/extensions/fm-primary-omp-watch.ts auto-load from .omp/extensions/ (use -e with both paths only when starting omp from another directory).
●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

                                            ████████████
                                               ██  ██       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               ██  ██       ▀▄▄▀ █ █ █ █▄▄▀
                                               ▒▒  ██                  █
                                                   ██       v18.7.0

                                        Tip: You can /btw to ask a side question

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Update Available
 New version 18.8.0 is available. Run: omp update
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


 FIRSTMATE_OP: v1 launch-brief: Disposable runtime check: reply exactly LIVE_RECOVERY_OMP_OK. Do not invoke tools,
 change files, start sessions, or administer any lifecycle. Then wait.


 LIVE_RECOVERY_OMP_OK

❯
 π · ◔ GPT-6.1-Sol 👁 · 📁 …M9EXJMYFQW/.fm-live-auto-693wcttm/child · ⑂ lab-preserved *1 ?4 · ◫ 7.2%/272K ⟲ · S0.04
Evidence: Ship and scout session-end refusal proof

Source: Ship and scout session-end refusal proof

{
  "results": [
    {
      "scenario": "ship-session-end-recorded-codex-refused-without-accounting",
      "pass": true
    },
    {
      "scenario": "scout-session-end-recorded-codex-refused-without-accounting",
      "pass": true
    }
  ],
  "runs": [
    {
      "command": "bin/fm-lab-home.sh create ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/home",
      "exit": 0,
      "output": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/home\n"
    },
    {
      "command": "git init -b lab-preserved ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child",
      "exit": 0,
      "output": "Initialized empty Git repository in ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child/.git/\n"
    },
    {
      "command": "git -C ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child add bin .omp AGENTS.md .gitignore",
      "exit": 0,
      "output": ""
    },
    {
      "command": "git -C ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child -c user.name=Lab -c user.email=lab@example.invalid commit -q -m disposable fixture",
      "exit": 0,
      "output": ""
    },
    {
      "command": "bin/fm-herdr-lab.sh name sessionend",
      "exit": 0,
      "output": "fm-lab-sessionend-13752-21026\n"
    },
    {
      "command": "bin/fm-herdr-lab.sh provision fm-lab-sessionend-13752-21026",
      "exit": 0,
      "output": ""
    },
    {
      "command": "bin/fm-herdr-lab.sh run fm-lab-sessionend-13752-21026 workspace create --cwd ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child --label session-end-fixture --no-focus",
      "exit": 0,
      "output": "{\"id\":\"cli:workspace:create\",\"result\":{\"root_pane\":{\"agent_status\":\"unknown\",\"cwd\":\"~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child\",\"focused\":true,\"foreground_cwd\":\"~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child\",\"pane_id\":\"w1:p1\",\"revision\":0,\"scroll\":{\"max_offset_from_bottom\":0,\"offset_from_bottom\":0,\"viewport_rows\":40},\"tab_id\":\"w1:t1\",\"terminal_id\":\"term_65d429fbb54d31\",\"workspace_id\":\"w1\"},\"tab\":{\"agent_status\":\"unknown\",\"focused\":true,\"label\":\"1\",\"number\":1,\"pane_count\":1,\"tab_id\":\"w1:t1\",\"workspace_id\":\"w1\"},\"type\":\"workspace_created\",\"workspace\":{\"active_tab_id\":\"w1:t1\",\"agent_status\":\"unknown\",\"focused\":true,\"label\":\"session-end-fixture\",\"number\":1,\"pane_count\":1,\"tab_count\":1,\"workspace_id\":\"w1\"}}}\n"
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code/bin/fm-busy-event.sh arm ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/home/state session-end-ship",
      "exit": 0,
      "output": "g1791390591.19140.12137\n"
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code/bin/fm-busy-event.sh apply ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/home/state session-end-ship idle --gen g1791390591.19140.12137 --source codex --event session-end",
      "exit": 0,
      "output": ""
    },
    {
      "command": "bash -c set -u\n. \"$1/bin/fm-session-end-relaunch-lib.sh\"\nfm_session_end_bounds 300 || exit 2\nfm_session_end_relaunch_consider \"$FM_HOME/state\" \"$2\" || exit 3\nprintf 'ACTION=%s REASON=%s\\n' \"$FM_SESSION_END_ACTION\" \"$FM_SESSION_END_REASON\"\n session-end-live-driver ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code session-end-ship",
      "exit": 0,
      "output": "ACTION=skip REASON=check: session-end-ship auto-relaunch refused after session-end: error: config/session-launch-policy=omp-or-tc refuses launch 'codex'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native lau\n"
    },
    {
      "command": "bash -c set -u\n. \"$1/bin/fm-session-end-relaunch-lib.sh\"\nfm_session_end_bounds 300 || exit 2\nfm_session_end_relaunch_consider \"$FM_HOME/state\" \"$2\" || exit 3\nprintf 'ACTION=%s REASON=%s\\n' \"$FM_SESSION_END_ACTION\" \"$FM_SESSION_END_REASON\"\n session-end-live-driver ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code session-end-ship",
      "exit": 0,
      "output": "ACTION=skip REASON=\n"
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code/bin/fm-busy-event.sh arm ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/home/state session-end-scout",
      "exit": 0,
      "output": "g1791390592.23236.22038\n"
    },
    {
      "command": "~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code/bin/fm-busy-event.sh apply ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/home/state session-end-scout idle --gen g1791390592.23236.22038 --source codex --event session-end",
      "exit": 0,
      "output": ""
    },
    {
      "command": "bash -c set -u\n. \"$1/bin/fm-session-end-relaunch-lib.sh\"\nfm_session_end_bounds 300 || exit 2\nfm_session_end_relaunch_consider \"$FM_HOME/state\" \"$2\" || exit 3\nprintf 'ACTION=%s REASON=%s\\n' \"$FM_SESSION_END_ACTION\" \"$FM_SESSION_END_REASON\"\n session-end-live-driver ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code session-end-scout",
      "exit": 0,
      "output": "ACTION=skip REASON=check: session-end-scout auto-relaunch refused after session-end: error: config/session-launch-policy=omp-or-tc refuses launch 'codex'; only the canonical omp adapter is currently supported under this policy; tc run requires a verified native lau\n"
    },
    {
      "command": "bash -c set -u\n. \"$1/bin/fm-session-end-relaunch-lib.sh\"\nfm_session_end_bounds 300 || exit 2\nfm_session_end_relaunch_consider \"$FM_HOME/state\" \"$2\" || exit 3\nprintf 'ACTION=%s REASON=%s\\n' \"$FM_SESSION_END_ACTION\" \"$FM_SESSION_END_REASON\"\n session-end-live-driver ~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/code session-end-scout",
      "exit": 0,
      "output": "ACTION=skip REASON=\n"
    },
    {
      "command": "bin/fm-herdr-lab.sh run fm-lab-sessionend-13752-21026 pane get w1:p1",
      "exit": 0,
      "output": "{\"id\":\"cli:pane:get\",\"result\":{\"pane\":{\"agent_status\":\"unknown\",\"cwd\":\"~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child\",\"focused\":true,\"foreground_cwd\":\"~/.no-mistakes/worktrees/32d18ed9638d/01M4BJ2A79FRTFKKM9EXJMYFQW/.fm-live-sessionend-a5ynbmmh/child\",\"pane_id\":\"w1:p1\",\"revision\":0,\"scroll\":{\"max_offset_from_bottom\":0,\"offset_from_bottom\":0,\"viewport_rows\":40},\"tab_id\":\"w1:t1\",\"terminal_id\":\"term_65d429fbb54d31\",\"workspace_id\":\"w1\"},\"type\":\"pane_info\"}}\n"
    },
    {
      "command": "bin/fm-herdr-lab.sh teardown fm-lab-sessionend-13752-21026",
      "exit": 0,
      "output": ""
    }
  ]
}

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - medium risk

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 10 of 10 scenarios driven live against the product
Scenario Result Live Evidence
Request Codex for a fresh ship, scout, batch, or secondmate and receive refusal before launch resources are created ✅ pass live launch-refusals.json: public spawn commands returned policy refusal; state and projects directories remained empty.
Attempt to bypass the restriction with Claude or opaque omp/tc commands and receive a clear refusal ✅ pass live launch-refusals.json: Claude, omp --model anything, and tc run requests were refused.
Provide malformed or dangling policy configuration and have an otherwise permitted omp launch fail closed ✅ pass live launch-refusals.json: empty, unknown, whitespace-altered, extra-newline, and dangling-symlink policies produced configuration errors without launch resources.
Launch canonical omp under inherited policy using the openai-codex provider and receive a real model response ✅ pass live recovery-proof.json and omp-recovery-terminal.txt: actual omp registration, inherited policy, GPT-6.1-Sol session, and LIVE_RECOVERY_OMP_OK response.
Request fresh or direct Codex/raw-command launch while only the guarded child retains the restriction and preserve the child policy and work ✅ pass live recovery-live.json covers fresh admission; recovery-proof.json covers direct admission after the actual omp agent was stopped.
Request a forbidden or tooling-incompatible manual replacement and leave the existing omp agent running ✅ pass live recovery-proof.json: parent-policy, retained-child Codex, and outdated-child-tooling refusals; protected state remained unchanged and native inventory still reported omp.
Automatically recover a dead secondmate endpoint, refuse Codex without attempts or endpoint removal, then immediately recover with omp after repair ✅ pass live automatic-recovery-proof.json: real dead-endpoint classification, surviving pane after refusals, quiet repeated refusal, and one attempt/relaunched pair only after selecting omp; omp-recovery-terminal…
Recover persisted ended ship/scout records naming Codex and refuse without consuming recovery accounting or translating their model onto omp ✅ pass live session-end-proof.json: real busy-event producer and recovery consumer returned skip/refusal for both kinds, retained protected task data, created no attempt or handled-generation records, and queued…
Request forbidden remote replacement and refuse at initiating and destination admission boundaries ✅ pass live remote-admission-proof.json: initiating relaunch refused before transport/staging; destination launch refused before creating parent-route endpoint state.
Receive identical remote policy bytes with incompatible tooling, repair the owner, and remove the policy without overwriting legacy tooling ✅ pass live remote-admission-proof.json: real receiver rejected identical-byte retries with outdated tooling, reported unchanged after restoration, then removed the policy while preserving the intentionally diver…
  • Inspected git diff --stat fe1570232a91db1a9bfa482b90005df1eac77475 ace9c5a1b00da77007388a8fa864c34be6a5a824 and the scoped launch/recovery implementation diff; checked runtime tools with command -v.
  • Drove bin/fm-spawn.sh through explicit ship, configured scout, configured secondmate, batch, Claude, opaque omp, and tc run refusal requests in a disposable marked FM_HOME; verified no task records or project resources were created.
  • Requested canonical omp launches with empty, unknown, trailing-space, extra-newline, and dangling-symlink policy files; verified fail-closed CLI diagnostics.
  • Used bin/fm-herdr-lab.sh name, provision, run, and teardown for named non-default sessions, routing product backend operations through the lab helper.
  • Launched actual omp secondmates with openai-codex/gpt-6.1-sol and low effort; observed model replies through fm-peek.sh and real omp registration through Herdr agent list.
  • Drove fm-control.sh &lt;id&gt; relaunch --harness codex and configured relaunch against a running omp secondmate; verified refusal, preserved metadata/work/policy, no relaunch checkpoint, and a surviving omp agent.
  • Drove fresh and agent-free direct fm-spawn.sh --relaunch requests for Codex and opaque omp commands against a guarded retained child policy with no primary policy.
  • Exercised fm_secondmate_liveness_probe and fm_secondmate_liveness_relaunch against real agent-free Herdr endpoints; checked refusal deduplication, endpoint preservation, untouched attempt accounting, and immediate actual omp recovery after profile repair.
  • Used fm-busy-event.sh arm and apply ... --event session-end, then the production session-end recovery consumer, for persisted ship/scout records naming Codex against a real agent-free Herdr pane.
  • Drove fm-remote-secondmate-relaunch.sh remote-policy codex default default, destination fm-remote-secondmate-control.sh launch remote-policy codex - - herdr, and the real fm-remote-inherit.sh put/absent protocol consumer.
  • Captured CLI transcripts, native agent inventory, terminal output, and complete command history; tore down all provisioned lab sessions and confirmed no .fm-live-* fixtures remained in the worktree.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@MrGTV-love
MrGTV-love force-pushed the fm/fm-session-launch-runtime-restriction branch from 2cc0228 to 0c8cf0c Compare October 6, 2026 23:02
@MrGTV-love
MrGTV-love force-pushed the fm/fm-session-launch-runtime-restriction branch from 0c8cf0c to 6d0c03d Compare October 7, 2026 00:04
@MrGTV-love MrGTV-love changed the title feat: add opt-in session launch runtime restrictions feat: add opt-in runtime restrictions for session launches Oct 7, 2026
@MrGTV-love MrGTV-love changed the title feat: add opt-in runtime restrictions for session launches feat: add opt-in session launch restrictions Oct 7, 2026
@MrGTV-love
MrGTV-love force-pushed the fm/fm-session-launch-runtime-restriction branch from fb2f486 to 1bedc97 Compare October 7, 2026 04:59
@MrGTV-love MrGTV-love changed the title feat: add opt-in session launch restrictions feat: add opt-in session runtime restrictions Oct 7, 2026
…e3bbdf3c4fe001d19afde5c592716: 19 checks pass and the two reported behavior jobs fail. The prior DNS failure required no product, credential, or configuration change. Scanned both complete job logs and verdict ledgers; both CI failures are test defects. Updated tests/fm-supervision-instructions.test.sh to remove prose-heading extraction and incidental wording assertions while retaining executable renderer state, block preservation, tag/placeholder filtering, and command ownership coverage. Updated tests/fm-remote-transport-lanes.test.sh to include the policy library and its verified transitive dependencies. Production policy, default-off compatibility, protections, ownership, and truthful documentation remain unchanged. Verification: all 12 supervision checks pass; canonical lint passes for both changed tests with pinned ShellCheck 0.11.0. A focused executable smoke using the corrected remote dependency set proved fm-on → worker → control state returns missing with open stdin and that --stdin preserves payload bytes; the throwaway script was removed. The full remote test was attempted twice but stopped before the corrected scenario at its existing cross-home timing assertion (4s and 7s against a 3s bound); that assertion was not weakened. Provider CI is not yet green and is not waived. Return these changes to the SAME outer run for its owned revalidation, publication, and CI provider retry; no pipeline control or push was performed
@MrGTV-love
MrGTV-love force-pushed the fm/fm-session-launch-runtime-restriction branch from 1bedc97 to be616b8 Compare October 7, 2026 13:26
@MrGTV-love MrGTV-love changed the title feat: add opt-in session runtime restrictions feat: add opt-in worker and secondmate session launch restrictions Oct 7, 2026
The secondmate recovery admission called fm-harness.sh through FM_ROOT/bin, which a home whose bin directory is a partial copy does not have, so recovery refused a respawn it should have admitted. Use the library's own directory, as its other sourcing does.
@MrGTV-love MrGTV-love changed the title feat: add opt-in worker and secondmate session launch restrictions feat: add opt-in session launch restrictions Oct 7, 2026
…ree checks. Behavior portable parallel 1 failed because its runner regression invokes the same duration-hint guard as Test coverage guard. Added successful CI-derived measurements for all three new policy tests and documented their provenance; coverage now passes with 31/214 unmeasured scripts, below the unchanged 15% limit. For Lint 1, removed duplicate inheritance imports from spawn, control, and remote relaunch, and applied the existing canonical-owner analysis boundary to the policy library's lazy wake import. Runtime admission behavior and CI resource limits remain unchanged. Verification passed: coverage guard; complete fm-test-run regression; complete launch-policy, inheritance, receipt, and remote-relaunch regressions; executable lazy-notification/deduplication smoke; cold full source-aware ShellCheck 0.11.0 for all six relevant roots; documentation audience check. Linux bounded lint passed for control, remote relaunch, policy, and wake owners. Spawn's Linux memory-envelope result remains unverified: the available 7.75 GiB Docker VM, shared with unrelated services, killed the analyzer. Spawn passed cold macOS lint. Shorter initial regression runs timed out; subsequent complete runs passed. Temporary verification files were removed. No real agent sessions, pipeline controls, pushes, or remote CI reruns were invoked
@MrGTV-love
MrGTV-love merged commit efe40d1 into main Oct 7, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant