Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save arikon/a4afbc0cd2cdcf5f33b2509f3332bba8 to your computer and use it in GitHub Desktop.

Select an option

Save arikon/a4afbc0cd2cdcf5f33b2509f3332bba8 to your computer and use it in GitHub Desktop.
OMX #3354 native Ultragoal receipt transport v3 with Codex CLI acceptance and session-race hardening
diff --git a/docs/codex-native-hooks.md b/docs/codex-native-hooks.md
index 75f72bcc..e2932e93 100644
--- a/docs/codex-native-hooks.md
+++ b/docs/codex-native-hooks.md
@@ -101,6 +101,30 @@ uninspected script fail closed. For statically inspectable source, ordinary arra
object reads and benign reflection do not become mutation authority through broad
raw-command matching.
+Codex Desktop may run two live user chats in the same workspace while the
+compatibility `session.json` pointer names only one of them. For an exact
+identityless payload with an exact `session_id`, the hook may recover Main-root
+identity from the unique matching live rollout under
+`$CODEX_HOME/sessions`. The first `session_meta` record must bind that exact id
+and canonical cwd, declare `thread_source: "user"`, `source: "vscode"` or
+`source: "exec"`, and
+`originator: "Codex Desktop"`, and contain no subagent source. The rollout must
+be a regular, unlinked, non-group/world-writable file with a bounded first
+record. Identity and capability come from one pinned per-dispatch snapshot;
+post-read device, inode, mode, link-count, size, mtime, and ctime must remain
+unchanged. Conflicting snake/camel aliases, archived, ambiguous, malformed,
+linked, writable, child, mutated, or spoofed rollouts fail closed and do not
+weaken tracker or child-provenance checks.
+
+The hook payload may omit `thread_id`/`threadId`. If either alias is present,
+every present alias must be a non-empty string and all values must reduce to the
+exact root `session_id`; malformed, empty, null, numeric, or conflicting claims
+fail closed. UserPromptSubmit and PreToolUse additionally require one valid
+payload turn claim matching the latest complete `turn_context` record and its
+canonical cwd. An unterminated final JSONL record invalidates turn authority and
+typed-spawn capability instead of falling back to an older context. Stop remains
+turn-independent only on the stale-dead, exact-cwd, session-scoped path.
+
Official Team worker roots may omit both `agent_id` and legacy `thread_id`.
After Main-root exclusion, OMX preserves their established exemption only when
the Team environment agrees with the durable worker identity, Team config, and
@@ -120,8 +144,20 @@ while the Conductor boundary is active.
Planning boundaries (`ralplan`, `deep-interview`) remain fail-closed for mutation
transports: only their documented planning artifact paths and non-deactivating
-state operations are allowed. No assignment-backed grant, prompt-derived scope,
-or child-write allowance exists in this Option C implementation.
+state operations are allowed. They do not accept an Ultragoal assignment-backed
+grant, prompt-derived scope, or child-write allowance.
+
+Standalone Ultragoal on a native Codex surface outside tmux has three configured
+backends: `off`, `host`, and `local-experimental`. `off` preserves the no-owner
+activation block. `host` is the production-safe integration point, but it fails
+closed because Codex does not currently expose a documented host-issued native
+executor receipt API. `local-experimental` requires an ordered bootstrap:
+typed executor spawn, root authorization through
+`omx ultragoal native-bootstrap authorize`, then activation. The assignment is
+a short-lived same-user guardrail, not host authentication or an ADR 3212
+hostile-child boundary. See
+[`native-subagent-assignments.md`](native-subagent-assignments.md) for exact
+configuration, lifecycle, reconciliation, and recovery behavior.
### Exact direct-cancel recovery exception
diff --git a/docs/native-subagent-assignments.md b/docs/native-subagent-assignments.md
new file mode 100644
index 00000000..64651a4b
--- /dev/null
+++ b/docs/native-subagent-assignments.md
@@ -0,0 +1,253 @@
+# Native subagent assignments
+
+The Codex native hook keeps typed native children read-only unless the active
+root Conductor establishes an exact, session-scoped assignment. This transport
+does not grant Team-worker identity or authority.
+
+## Backends
+
+Configure the transport in `~/.omx/config.json`:
+
+```json
+{
+ "nativeUltragoal": {
+ "backend": "local-experimental",
+ "assignmentTtlSeconds": 900
+ }
+}
+```
+
+`assignmentTtlSeconds` accepts an integer from 30 through 3600 and defaults to
+900. `OMX_NATIVE_ULTRAGOAL_BACKEND` overrides the configured backend. The
+override is fail-closed: a present non-empty invalid value resolves to `off`
+instead of falling back to a configured authority backend. The
+legacy `OMX_NATIVE_SUBAGENT_ASSIGNMENTS=on` setting maps to
+`local-experimental` only when neither the new environment override nor an
+explicit configured backend is present.
+
+The available backends are:
+
+- `off` (default): native Ultragoal activation outside tmux remains blocked
+ because no authorized executor is available.
+- `host`: reserved for a documented, unforgeable receipt issued by the Codex
+ host. OMX has no such host receipt API today, so this backend fails closed
+ with `OMX-ULTRAGOAL-HOST-RECEIPT-UNAVAILABLE`.
+- `local-experimental`: enables short-lived local assignments after OMX checks
+ the native tracker. This is a bounded same-user workflow guardrail, not host
+ authentication and not an ADR 3212 hostile-child boundary.
+
+## Ordered bootstrap
+
+On Codex native surfaces outside tmux, a fresh standalone `$ultragoal`
+activation stays inactive until the executor assignment is ready. Use this
+order:
+
+1. Invoke `$ultragoal`. The hook verifies typed `spawn_agent` support, creates
+ a session bootstrap, and returns `OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED` without
+ activating Conductor mode.
+2. Spawn one direct native child with `agent_type: "executor"`, instructing it
+ to wait without tool calls for a follow-up after activation. When the native
+ API returns only its stable `agent_path`, retain that exact path; OMX can
+ resolve the canonical child ID from the live rollout receipt.
+3. Authorize only the required paths and actions:
+
+ ```sh
+ omx ultragoal native-bootstrap authorize \
+ --session-id <session-id> \
+ --root-thread-id <root-thread-id> \
+ --bootstrap-generation <generation-from-bootstrap-required> \
+ --child-path /root/<typed-executor-agent-path> \
+ --path-prefix <repo-relative-path> \
+ --json
+ ```
+
+ Repeat `--path-prefix` for additional scopes. Add `--path-write-only` to
+ omit `bash-write`. Use `--ttl-seconds <30-3600>` only when the configured
+ TTL is unsuitable. Every `native-bootstrap` action requires an explicit
+ `--session-id` equal to the canonical current runtime session; pointer-only
+ or cross-session commands fail closed. `--bootstrap-generation` is the exact
+ generation printed by the bootstrap-required response; stale commands cannot
+ authorize a replacement generation. `--child-id` remains available when the
+ native API exposes the canonical ID directly. Exactly one of `--child-id`
+ and `--child-path` is accepted.
+4. Retry the canonical Ultragoal activation. `PreToolUse` moves the receipt to
+ `activating`; only a successful activation `PostToolUse` publishes `active`.
+ The hook proceeds only after the
+ bootstrap generation, assignment, tracker session, root thread, exact child
+ ID, direct parent, role, status, lifetime, and path scope all validate. Then
+ start the authorized executor work with `followup_task` for the retained
+ agent path.
+
+The child remains read-only until activation is confirmed. A crash before the
+activation tool runs leaves `ready`; a rejected or interrupted activation leaves
+`activating`. Both are safe and retryable while the assignment and tracked
+executor remain valid. If the receipt is revoked, expires, or loses tracker
+authority before confirmation, the hook revokes the grant and terminalizes the
+new Ultragoal state as `failed` instead of leaving Conductor active without an
+executor.
+
+## Location
+
+The bootstrap for root session `<session-id>` is stored at:
+
+```text
+.omx/state/sessions/<session-id>/native-ultragoal-bootstrap.json
+```
+
+The assignment for child `<child-agent-id>` is stored at:
+
+```text
+.omx/state/sessions/<session-id>/native-assignments/<encodeURIComponent(child-agent-id)>.json
+```
+
+`omx ultragoal native-bootstrap authorize` is the supported writer. The native
+hook rejects the canonical command when a tracked child invokes it and rejects
+child writes to bootstrap or `native-assignments` paths, even when ordinary
+path scope would otherwise match. This is still a same-user experimental
+boundary: the CLI cannot authenticate an arbitrary local OS process as
+Main-root without a host-issued receipt.
+
+## Active assignment schema
+
+The JSON object must contain exactly these keys:
+
+```json
+{
+ "schema_version": 1,
+ "kind": "native-subagent-assignment",
+ "lifecycle": "active",
+ "root_session_id": "exact-root-session-id",
+ "root_thread_id": "exact-root-thread-id",
+ "child_agent_id": "exact-canonical-child-agent-id",
+ "agent_type": "executor",
+ "allowed_actions": ["path-write", "bash-write"],
+ "path_prefixes": ["tmp/native-probe"],
+ "issued_at": "2026-07-23T20:00:00.000Z",
+ "expires_at": "2026-07-23T20:10:00.000Z",
+ "bootstrap_generation": "exact-bootstrap-generation"
+}
+```
+
+The hook checks the root session and leader thread against the active session.
+A directly attested child must be `kind: "subagent"`, carry `mode: "executor"`,
+`provenance_kind: "native_subagent"`, and exact `direct_child_parent_id` /
+`direct_child_root_id` bindings to Main-root. With the `local-experimental`
+backend only, Codex App v2 may instead use the unique live child rollout
+`session_meta` as assignment-local evidence when SessionStart did not persist a
+direct-child attestation. The tracker must still contain the exact root session
+and Main-root leader binding. The receipt must be under the live `sessions`
+tree, fall within the current bootstrap lifetime without a future timestamp,
+and bind the exact child, root session, direct parent, canonical cwd, depth `1`,
+and `executor` role.
+Archived, stale, ambiguous, writable, linked, malformed, or oversized receipts
+fail closed. This fallback creates only a descriptive tracker entry; it does not
+grant persisted reopen authority or synthesize child availability.
+
+`--child-path` is a receipt lookup transport, never an authority claim. OMX
+scans only the live `CODEX_HOME/sessions` tree and requires one safe unique
+rollout whose `session_meta` binds the exact path, canonical child UUID,
+session/root alias, direct root parent, depth `1`, `executor` role, canonical
+workspace cwd, and timestamp within the current bootstrap window. The rollout
+filename must end in that same child UUID. Missing, duplicate, stale, foreign,
+wrong-role, wrong-depth, wrong-cwd, group/other-writable, symlinked, or
+hard-linked candidates fail closed. The resolved UUID is then passed through
+the same assignment and activation validation as an explicit `--child-id`;
+the path itself is never persisted as child authority.
+
+For the independent Codex Desktop root chat itself, the same safe live-rollout
+boundary may also supply missing typed-spawn capability evidence from the latest
+bounded `turn_context`. Its exact current `turn_id` and canonical cwd must match
+the hook payload, with `multi_agent_mode: "explicitRequestOnly"` and
+`multi_agent_version: "v2"`. `session_meta.dynamic_tools` is not capability
+authority. All snake/camel aliases must reduce to one non-empty value, and the
+same pinned per-dispatch transcript snapshot supplies both root identity and
+capability. This fallback does not accept archived, ambiguous, or concurrently
+mutated rollouts and never supplies child provenance. Session-scoped prompt
+handling uses that exact root id, so an inactive terminal marker belonging to a
+different live workspace chat is not reused by the bootstrap guard.
+
+Any tracker contradiction remains an unconditional veto: revoked reopen
+authority, completion, a non-available explicit status, a non-`executor` role,
+or foreign parent/root evidence cannot be repaired by transcript fallback.
+The live tool payload must independently provide one unambiguous top-level
+`executor` role through the native `agent_role`/`agent_type` aliases.
+Nested-only role evidence or conflicting aliases cannot authorize an assignment.
+The filename must encode that same canonical child ID, and
+`bootstrap_generation` must match the current session bootstrap.
+
+Assignments are fail-closed when unreadable, malformed, expired, issued too far
+in the future, longer than 24 hours, symlinked, hard-linked, larger than 64 KiB,
+or writable by group/other. Unknown keys, duplicate actions or prefixes,
+ambiguous paths, symlink traversal, `.omx`, and `.git` scopes are rejected.
+Deleting the file or changing `lifecycle` away from `active` revokes the grant.
+
+## Lifecycle, revocation, and recovery
+
+Inspect and reconcile the current bootstrap with:
+
+```sh
+omx ultragoal native-bootstrap status --session-id <session-id> --json
+```
+
+Status reconciliation returns readiness only while the exact assignment and
+its direct tracker attestation or generation-bound live App receipt remain
+valid. An expired assignment cannot authorize a mutation. Reconciliation
+revokes an active assignment when the child evidence is missing, archived,
+stale, completed, unavailable, foreign to the root, or has the wrong role.
+Fresh activation also reconciles before it proceeds.
+
+All lifecycle mutations for one session are serialized by a session-scoped
+lock. Activation revalidates tracker authority, generation, file identity,
+schema, scope, and expiry under that lock and returns a positive receipt before
+the hook permits state activation. Concurrent revoke cannot be overwritten by
+a stale authorize or activation write. Revoked and expired generations require
+an explicit new bootstrap before another authorization; authorization never
+rotates a generation implicitly. An already-active receipt is idempotently
+revalidated so a rejected or interrupted state write can be retried safely.
+
+Explicitly revoke the bootstrap and its assignment with:
+
+```sh
+omx ultragoal native-bootstrap revoke \
+ --session-id <session-id> \
+ --child-id <child-agent-id> \
+ --reason <reason> \
+ --json
+```
+
+`--child-id` is optional when the bootstrap already records the child. After
+revocation, expiry, or tracker invalidation, the child returns to the normal
+read-only policy. Re-run `authorize` with the explicit current `--session-id`,
+root thread, and a live strictly tracked executor to renew or replace the lease;
+when standalone Ultragoal state is still active, the CLI restores bootstrap
+status to `active` only after revalidation. Terminal `Stop`, exact root
+cancellation, and a new fresh run revoke or rotate the old generation. An
+assignment from an older generation cannot be reused.
+
+## Actions
+
+- `path-write`: direct file-edit tools within `path_prefixes`.
+- `bash-write`: one statically analyzable shell mutation within
+ `path_prefixes`.
+
+Assignments never authorize VCS, PR, network, deployment, state, orchestration,
+goal, assignment, or Team-worker operations. A `"."` prefix still excludes
+`.git` and `.omx`. Shell substitution,
+unresolved arithmetic, dynamic nested execution, unsafe heredocs, unsafe
+nameref/allexport state, arbitrary PATH mutation, unresolved interpreter
+writes, and path/symlink escapes remain blocked.
+
+Without a valid assignment, typed native children continue to receive
+`OWNER_CONFIRMATION_REQUIRED`.
+
+## Root orchestration transports
+
+An active, session-bound Main-root Conductor may write the existing bounded
+metadata roots, including `.omx/state`, `.omx/ultragoal`, `.omx/ralph`,
+`.omx/team`, `.omx/mailbox`, `.omx/handoff`, `.omx/handoffs`, `.omx/goals`,
+`.omx/notepad`, `.omx/wiki`, and `.beads`.
+
+The hook structurally recognizes canonical `omx state read`, `omx state write`,
+`omx state clear`, and `omx ultragoal checkpoint` commands before generic shell
+mutation analysis. Exact session/cwd/mode binding and all existing injection,
+PATH, symlink, and protected-state-gate checks still apply.
diff --git a/plugins/oh-my-codex/skills/code-review/SKILL.md b/plugins/oh-my-codex/skills/code-review/SKILL.md
index 06bb78da..c28800e9 100644
--- a/plugins/oh-my-codex/skills/code-review/SKILL.md
+++ b/plugins/oh-my-codex/skills/code-review/SKILL.md
@@ -33,6 +33,7 @@ Delegates to the `code-reviewer` and `architect` agents in parallel for a two-la
- **`architect` lane** - owns the devil's-advocate / design-tradeoff perspective
- Both lanes run in parallel on a clean context with explicit scope and artifacts, and produce distinct outputs before final synthesis
- If either lane cannot be launched or does not return evidence, report `independent review unavailable`; do **not** substitute the current/authoring lane, and do **not** approve or mark the review merge-ready.
+ - Inside an active Conductor workflow, collect evidence through native read-only tools. If a Bash fallback is necessary on macOS, use root-owned absolute readers such as `/bin/cat`, `/usr/bin/find ... -print`, `/usr/bin/sed` with a read-only program, or `/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .`. Do not use a bare Homebrew/NVM command such as `rg`: a user-writable `PATH` entry cannot provide fail-closed executable identity.
3. **Review Categories**
- **Security** - Hardcoded secrets, injection risks, XSS, CSRF
@@ -98,6 +99,8 @@ Review code changes for quality, security, and maintainability.
This is the code/spec/security lane. Do not absorb architectural ownership.
+Conductor read-only constraint: prefer native read tools. If Bash is necessary on macOS, use only root-owned absolute readers such as `/bin/cat`, `/usr/bin/find ... -print`, read-only `/usr/bin/sed`, or `/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .`. Never use bare/Homebrew `rg`, `nl`, unsafe Git forms, shell chaining, or memory lookup. If the leader supplied sufficient empty-diff evidence, review that evidence directly without extra tool calls.
+
Scope: [git diff or specific files]
Review Checklist:
@@ -121,6 +124,8 @@ task(
Review the same code changes from the architecture/tradeoff perspective.
+Conductor read-only constraint: prefer native read tools. If Bash is necessary on macOS, use only root-owned absolute readers such as `/bin/cat`, `/usr/bin/find ... -print`, read-only `/usr/bin/sed`, or `/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .`. Never use bare/Homebrew `rg`, `nl`, unsafe Git forms, shell chaining, or memory lookup. If the leader supplied sufficient empty-diff evidence, review that evidence directly without extra tool calls.
+
Scope: [git diff or specific files]
Focus:
diff --git a/plugins/oh-my-codex/skills/ultragoal/SKILL.md b/plugins/oh-my-codex/skills/ultragoal/SKILL.md
index 3a22a0ed..e7ea2443 100644
--- a/plugins/oh-my-codex/skills/ultragoal/SKILL.md
+++ b/plugins/oh-my-codex/skills/ultragoal/SKILL.md
@@ -22,8 +22,9 @@ Existing aggregate plans with the legacy enumerated objective are migrated to th
Ultragoal is both a tracked workflow skill and the Autopilot durable-implementation child phase. Keep the phase/HUD contract explicit at workflow boundaries:
-- **Standalone `$ultragoal` activation**: ensure `.omx/state[/sessions/<session>]/ultragoal-state.json` exists with `mode:"ultragoal"`, `active:true`, and a non-empty `current_phase` such as `planning` before or while goals are created. This state is a lightweight HUD/runtime declaration; `.omx/ultragoal/goals.json` and `ledger.jsonl` remain the durable goal source of truth.
+- **Standalone `$ultragoal` activation**: route the write with `mode:"ultragoal"` and ensure `.omx/state[/sessions/<session>]/ultragoal-state.json` exists with `active:true` and a non-empty `current_phase` such as `planning` before or while goals are created. The state backend may omit the routing-only `mode` field from the persisted JSON; the canonical filename supplies that identity, while a present conflicting `mode` is invalid. This state is a lightweight HUD/runtime declaration; `.omx/ultragoal/goals.json` and `ledger.jsonl` remain the durable goal source of truth.
- **During execution**: update `current_phase` to the smallest accurate phase (`planning`, `executing`, `verifying`, `reviewing`, `checkpointing`, or `blocked`) when the visible workflow phase changes.
+- **Codex App outside tmux**: `nativeUltragoal.backend` defaults to `off`. `host` remains fail-closed until Codex exposes a documented host-issued native executor receipt API. `local-experimental` is an explicit same-user guardrail, not host authentication or an ADR 3212 hostile-child boundary. When typed `spawn_agent` support is advertised, keep Ultragoal inactive while Main-root follows the ordered bootstrap: invoke `$ultragoal`; spawn one exact typed `executor` instructed to wait without tool calls for a post-activation follow-up; retain its returned `agent_path`; run `omx ultragoal native-bootstrap authorize --session-id <session-id> --root-thread-id <root-thread-id> --bootstrap-generation <generation> --child-path <agent-path> --path-prefix <repo-relative-path> --json`; retry the canonical Ultragoal activation; then start the authorized work with `followup_task`. Use `--child-id` only when the host directly exposes the canonical child ID. Keep paths/actions minimal; use `omx ultragoal native-bootstrap status` to reconcile/recover and `omx ultragoal native-bootstrap revoke` when the executor is no longer needed. Follow `docs/native-subagent-assignments.md` for configuration and lifecycle details.
- **Inside active Autopilot**: keep `mode:"autopilot"` active and set the supervised phase to `current_phase:"ultragoal"`; do not start a peer Autopilot replacement. Ultragoal's own mode state may still exist as child-phase detail, but Autopilot owns the parent phase.
- **On handoff to code-review**: persist implementation/test/ledger evidence under Autopilot `handoff_artifacts.ultragoal`, then set Autopilot `current_phase:"code-review"`.
- **On completion/blocker**: set standalone Ultragoal `active:false,current_phase:"complete"` only when all durable goals are complete; otherwise keep it active with a blocker/review-blocked phase and ledger evidence.
diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md
index 06bb78da..c28800e9 100644
--- a/skills/code-review/SKILL.md
+++ b/skills/code-review/SKILL.md
@@ -33,6 +33,7 @@ Delegates to the `code-reviewer` and `architect` agents in parallel for a two-la
- **`architect` lane** - owns the devil's-advocate / design-tradeoff perspective
- Both lanes run in parallel on a clean context with explicit scope and artifacts, and produce distinct outputs before final synthesis
- If either lane cannot be launched or does not return evidence, report `independent review unavailable`; do **not** substitute the current/authoring lane, and do **not** approve or mark the review merge-ready.
+ - Inside an active Conductor workflow, collect evidence through native read-only tools. If a Bash fallback is necessary on macOS, use root-owned absolute readers such as `/bin/cat`, `/usr/bin/find ... -print`, `/usr/bin/sed` with a read-only program, or `/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .`. Do not use a bare Homebrew/NVM command such as `rg`: a user-writable `PATH` entry cannot provide fail-closed executable identity.
3. **Review Categories**
- **Security** - Hardcoded secrets, injection risks, XSS, CSRF
@@ -98,6 +99,8 @@ Review code changes for quality, security, and maintainability.
This is the code/spec/security lane. Do not absorb architectural ownership.
+Conductor read-only constraint: prefer native read tools. If Bash is necessary on macOS, use only root-owned absolute readers such as `/bin/cat`, `/usr/bin/find ... -print`, read-only `/usr/bin/sed`, or `/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .`. Never use bare/Homebrew `rg`, `nl`, unsafe Git forms, shell chaining, or memory lookup. If the leader supplied sufficient empty-diff evidence, review that evidence directly without extra tool calls.
+
Scope: [git diff or specific files]
Review Checklist:
@@ -121,6 +124,8 @@ task(
Review the same code changes from the architecture/tradeoff perspective.
+Conductor read-only constraint: prefer native read tools. If Bash is necessary on macOS, use only root-owned absolute readers such as `/bin/cat`, `/usr/bin/find ... -print`, read-only `/usr/bin/sed`, or `/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .`. Never use bare/Homebrew `rg`, `nl`, unsafe Git forms, shell chaining, or memory lookup. If the leader supplied sufficient empty-diff evidence, review that evidence directly without extra tool calls.
+
Scope: [git diff or specific files]
Focus:
diff --git a/skills/ultragoal/SKILL.md b/skills/ultragoal/SKILL.md
index 3a22a0ed..e7ea2443 100644
--- a/skills/ultragoal/SKILL.md
+++ b/skills/ultragoal/SKILL.md
@@ -22,8 +22,9 @@ Existing aggregate plans with the legacy enumerated objective are migrated to th
Ultragoal is both a tracked workflow skill and the Autopilot durable-implementation child phase. Keep the phase/HUD contract explicit at workflow boundaries:
-- **Standalone `$ultragoal` activation**: ensure `.omx/state[/sessions/<session>]/ultragoal-state.json` exists with `mode:"ultragoal"`, `active:true`, and a non-empty `current_phase` such as `planning` before or while goals are created. This state is a lightweight HUD/runtime declaration; `.omx/ultragoal/goals.json` and `ledger.jsonl` remain the durable goal source of truth.
+- **Standalone `$ultragoal` activation**: route the write with `mode:"ultragoal"` and ensure `.omx/state[/sessions/<session>]/ultragoal-state.json` exists with `active:true` and a non-empty `current_phase` such as `planning` before or while goals are created. The state backend may omit the routing-only `mode` field from the persisted JSON; the canonical filename supplies that identity, while a present conflicting `mode` is invalid. This state is a lightweight HUD/runtime declaration; `.omx/ultragoal/goals.json` and `ledger.jsonl` remain the durable goal source of truth.
- **During execution**: update `current_phase` to the smallest accurate phase (`planning`, `executing`, `verifying`, `reviewing`, `checkpointing`, or `blocked`) when the visible workflow phase changes.
+- **Codex App outside tmux**: `nativeUltragoal.backend` defaults to `off`. `host` remains fail-closed until Codex exposes a documented host-issued native executor receipt API. `local-experimental` is an explicit same-user guardrail, not host authentication or an ADR 3212 hostile-child boundary. When typed `spawn_agent` support is advertised, keep Ultragoal inactive while Main-root follows the ordered bootstrap: invoke `$ultragoal`; spawn one exact typed `executor` instructed to wait without tool calls for a post-activation follow-up; retain its returned `agent_path`; run `omx ultragoal native-bootstrap authorize --session-id <session-id> --root-thread-id <root-thread-id> --bootstrap-generation <generation> --child-path <agent-path> --path-prefix <repo-relative-path> --json`; retry the canonical Ultragoal activation; then start the authorized work with `followup_task`. Use `--child-id` only when the host directly exposes the canonical child ID. Keep paths/actions minimal; use `omx ultragoal native-bootstrap status` to reconcile/recover and `omx ultragoal native-bootstrap revoke` when the executor is no longer needed. Follow `docs/native-subagent-assignments.md` for configuration and lifecycle details.
- **Inside active Autopilot**: keep `mode:"autopilot"` active and set the supervised phase to `current_phase:"ultragoal"`; do not start a peer Autopilot replacement. Ultragoal's own mode state may still exist as child-phase detail, but Autopilot owns the parent phase.
- **On handoff to code-review**: persist implementation/test/ledger evidence under Autopilot `handoff_artifacts.ultragoal`, then set Autopilot `current_phase:"code-review"`.
- **On completion/blocker**: set standalone Ultragoal `active:false,current_phase:"complete"` only when all durable goals are complete; otherwise keep it active with a blocker/review-blocked phase and ledger evidence.
diff --git a/src/cli/__tests__/state.test.ts b/src/cli/__tests__/state.test.ts
index 9cd8028d..b3cb8b08 100644
--- a/src/cli/__tests__/state.test.ts
+++ b/src/cli/__tests__/state.test.ts
@@ -1,10 +1,105 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
-import { mkdtemp, rm, writeFile } from 'node:fs/promises';
+import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { stateCommand } from '../state.js';
+import { __setWritableStateScopeTestHooksForTests } from '../../mcp/state-paths.js';
+import { recordNativeSubagentAuthorityObservation } from '../../subagents/tracker.js';
+import {
+ beginNativeUltragoalBootstrap,
+ findReadyLocalNativeExecutorAssignment,
+ issueLocalNativeExecutorAssignment,
+ markNativeUltragoalBootstrapActive,
+ NATIVE_ULTRAGOAL_BOOTSTRAP_FILE,
+ prepareNativeUltragoalBootstrapActivation,
+ readNativeUltragoalBootstrap,
+ revokeLocalNativeExecutorAssignment,
+} from '../../ultragoal/native-bootstrap.js';
+
+async function withNativeUltragoalActivationFixture<T>(
+ run: (fixture: { cwd: string; stateDir: string; sessionId: string; childAgentId: string }) => Promise<T>,
+ options: { activating?: boolean; pointerLiveness?: 'identity-indeterminate' | 'stale-dead' } = {},
+): Promise<T> {
+ const temporaryCwd = await mkdtemp(join(tmpdir(), 'omx-state-native-activation-'));
+ const previousCwd = process.cwd();
+ const envNames = [
+ 'CODEX_THREAD_ID',
+ 'CODEX_SESSION_ID',
+ 'SESSION_ID',
+ 'OMX_SESSION_ID',
+ 'OMX_TEAM_WORKER',
+ 'OMX_TEAM_INTERNAL_WORKER',
+ ] as const;
+ const previousEnv = Object.fromEntries(envNames.map((name) => [name, process.env[name]]));
+ const previousExitCode = process.exitCode;
+ try {
+ process.chdir(temporaryCwd);
+ const cwd = process.cwd();
+ for (const name of envNames) delete process.env[name];
+ const sessionId = 'native-activation-root';
+ const childAgentId = 'native-activation-child';
+ process.env.CODEX_THREAD_ID = sessionId;
+ const stateDir = join(cwd, '.omx', 'state');
+ await mkdir(stateDir, { recursive: true });
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId: sessionId,
+ backend: 'local-experimental',
+ ttlSeconds: 300,
+ });
+ recordNativeSubagentAuthorityObservation(cwd, {
+ sessionIds: [sessionId],
+ childThreadId: childAgentId,
+ parentThreadId: sessionId,
+ rootNativeSessionId: sessionId,
+ authorityEvidence: 'valid',
+ mode: 'executor',
+ });
+ await issueLocalNativeExecutorAssignment({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId: sessionId,
+ childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 300,
+ });
+ if (options.activating !== false) {
+ const prepared = await prepareNativeUltragoalBootstrapActivation({
+ cwd,
+ stateDir,
+ sessionId,
+ childAgentId,
+ });
+ assert.equal(prepared.ok, true);
+ }
+ await writeFile(join(stateDir, 'session.json'), JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ ...(options.pointerLiveness === 'stale-dead'
+ ? { pid: 2_147_483_647 }
+ : { pid_start_ticks: 1 }),
+ }));
+ process.exitCode = undefined;
+ return await run({ cwd, stateDir, sessionId, childAgentId });
+ } finally {
+ process.chdir(previousCwd);
+ process.exitCode = previousExitCode;
+ for (const name of envNames) {
+ const value = previousEnv[name];
+ if (typeof value === 'string') process.env[name] = value;
+ else delete process.env[name];
+ }
+ await rm(temporaryCwd, { recursive: true, force: true });
+ }
+}
describe('stateCommand', () => {
it('prints help for empty args', async () => {
@@ -226,4 +321,355 @@ describe('stateCommand', () => {
},
);
});
+
+ it('binds canonical native Ultragoal activation to exact indeterminate and stale root sessions', async () => {
+ for (const pointerLiveness of ['identity-indeterminate', 'stale-dead'] as const) {
+ await withNativeUltragoalActivationFixture(async ({ stateDir, sessionId }) => {
+ const stdout: string[] = [];
+ const stderr: string[] = [];
+ await stateCommand([
+ 'write',
+ '--input',
+ JSON.stringify({ mode: 'ultragoal', active: true, current_phase: 'planning' }),
+ '--json',
+ ], {
+ stdout: (line) => stdout.push(line),
+ stderr: (line) => stderr.push(line),
+ });
+
+ assert.equal(process.exitCode, undefined);
+ assert.deepEqual(stderr, []);
+ assert.equal(stdout.length, 1);
+ const state = JSON.parse(await readFile(
+ join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'),
+ 'utf-8',
+ )) as Record<string, unknown>;
+ assert.equal(state.active, true);
+ assert.equal(state.current_phase, 'planning');
+ }, { pointerLiveness });
+ }
+ });
+
+ it('allows an exact active-session planning to executing update after bootstrap activation', async () => {
+ await withNativeUltragoalActivationFixture(async ({ cwd, stateDir, sessionId, childAgentId }) => {
+ const write = async (payload: Record<string, unknown>): Promise<string[]> => {
+ process.exitCode = undefined;
+ const stderr: string[] = [];
+ await stateCommand(['write', '--input', JSON.stringify(payload), '--json'], {
+ stdout: () => undefined,
+ stderr: (line) => stderr.push(line),
+ });
+ return stderr;
+ };
+
+ assert.deepEqual(await write({
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'planning',
+ }), []);
+ assert.equal((await markNativeUltragoalBootstrapActive({
+ cwd,
+ stateDir,
+ sessionId,
+ childAgentId,
+ })).ok, true);
+
+ assert.deepEqual(await write({
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'executing',
+ session_id: sessionId,
+ }), []);
+ const state = JSON.parse(await readFile(
+ join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'),
+ 'utf-8',
+ )) as Record<string, unknown>;
+ assert.equal(state.active, true);
+ assert.equal(state.current_phase, 'executing');
+
+ const foreignSessionId = 'foreign-active-update';
+ const foreignError = await write({
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'executing',
+ session_id: foreignSessionId,
+ });
+ assert.equal(process.exitCode, 1);
+ assert.match(foreignError.join('\n'), /native_ultragoal_activation_receipt_invalid/);
+ await assert.rejects(
+ readFile(join(stateDir, 'sessions', foreignSessionId, 'ultragoal-state.json')),
+ /ENOENT/,
+ );
+ });
+ });
+
+ it('binds the exact terminal write to a completed aggregate checkpoint and revoked executor', async () => {
+ await withNativeUltragoalActivationFixture(async ({ cwd, stateDir, sessionId, childAgentId }) => {
+ const write = async (payload: Record<string, unknown>): Promise<string[]> => {
+ process.exitCode = undefined;
+ const stderr: string[] = [];
+ await stateCommand(['write', '--input', JSON.stringify(payload), '--json'], {
+ stdout: () => undefined,
+ stderr: (line) => stderr.push(line),
+ });
+ return stderr;
+ };
+ assert.deepEqual(await write({ mode: 'ultragoal', active: true, current_phase: 'planning' }), []);
+ assert.equal((await markNativeUltragoalBootstrapActive({
+ cwd,
+ stateDir,
+ sessionId,
+ childAgentId,
+ })).ok, true);
+ assert.deepEqual(await write({ mode: 'ultragoal', active: true, current_phase: 'checkpointing' }), []);
+ await mkdir(join(cwd, '.omx', 'ultragoal'), { recursive: true });
+ await writeFile(join(cwd, '.omx', 'ultragoal', 'goals.json'), JSON.stringify({
+ version: 1,
+ goals: [{ id: 'G001-terminal', status: 'complete' }],
+ aggregateCompletion: { status: 'complete', evidence: 'проверки пройдены' },
+ }));
+
+ const terminal = { mode: 'ultragoal', active: false, current_phase: 'complete' };
+ assert.match((await write(terminal)).join('\n'), /native_ultragoal_terminal_receipt_invalid/);
+ await revokeLocalNativeExecutorAssignment({ stateDir, sessionId, reason: 'aggregate_complete' });
+ assert.equal((await readNativeUltragoalBootstrap(stateDir, sessionId))?.status, 'revoked');
+ assert.equal(await findReadyLocalNativeExecutorAssignment({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId: sessionId,
+ }), null);
+ let mutated = false;
+ __setWritableStateScopeTestHooksForTests({
+ beforeScopeRevalidation: async () => {
+ if (mutated) return;
+ mutated = true;
+ await writeFile(join(cwd, '.omx', 'ultragoal', 'goals.json'), JSON.stringify({
+ version: 1,
+ goals: [{ id: 'G001-terminal', status: 'in_progress' }],
+ aggregateCompletion: { status: 'complete' },
+ }));
+ },
+ });
+ try {
+ assert.match((await write(terminal)).join('\n'), /native_ultragoal_terminal_receipt_invalid/);
+ assert.equal((JSON.parse(await readFile(
+ join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'),
+ 'utf-8',
+ )) as Record<string, unknown>).current_phase, 'checkpointing');
+ } finally {
+ __setWritableStateScopeTestHooksForTests({});
+ }
+ await writeFile(join(cwd, '.omx', 'ultragoal', 'goals.json'), JSON.stringify({
+ version: 1,
+ goals: [{ id: 'G001-terminal', status: 'complete' }],
+ aggregateCompletion: { status: 'complete', evidence: 'проверки пройдены' },
+ }));
+ assert.deepEqual(await write(terminal), []);
+ const state = JSON.parse(await readFile(
+ join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'),
+ 'utf-8',
+ )) as Record<string, unknown>;
+ assert.equal(state.active, false);
+ assert.equal(state.current_phase, 'complete');
+ });
+ });
+
+ it('does not authorize arbitrary state fields through the native activation fallback', async () => {
+ await withNativeUltragoalActivationFixture(async ({ stateDir, sessionId }) => {
+ const stderr: string[] = [];
+ await stateCommand([
+ 'write',
+ '--input',
+ JSON.stringify({
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'planning',
+ state: { arbitrary: true },
+ }),
+ '--json',
+ ], {
+ stdout: () => undefined,
+ stderr: (line) => stderr.push(line),
+ });
+
+ assert.equal(process.exitCode, 1);
+ assert.match(stderr.join('\n'), /native_ultragoal_activation_receipt_invalid/);
+ await assert.rejects(
+ readFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json')),
+ /ENOENT/,
+ );
+ });
+ });
+
+ it('requires an activating bootstrap with a valid ready assignment', async () => {
+ await withNativeUltragoalActivationFixture(async ({ stateDir, sessionId }) => {
+ const stderr: string[] = [];
+ await stateCommand([
+ 'write',
+ '--input',
+ JSON.stringify({ mode: 'ultragoal', active: true, current_phase: 'planning' }),
+ '--json',
+ ], {
+ stdout: () => undefined,
+ stderr: (line) => stderr.push(line),
+ });
+
+ assert.equal(process.exitCode, 1);
+ assert.match(stderr.join('\n'), /native_ultragoal_activation_receipt_invalid/);
+ await assert.rejects(
+ readFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json')),
+ /ENOENT/,
+ );
+ }, { activating: false });
+ });
+
+ it('rejects mismatched root-thread and Team-worker activation fallback identities', async () => {
+ for (const configure of [
+ () => { process.env.CODEX_THREAD_ID = 'foreign-root-thread'; },
+ () => { process.env.OMX_TEAM_WORKER = 'native-team/worker-1'; },
+ ]) {
+ await withNativeUltragoalActivationFixture(async ({ stateDir, sessionId }) => {
+ configure();
+ const stderr: string[] = [];
+ await stateCommand([
+ 'write',
+ '--input',
+ JSON.stringify({ mode: 'ultragoal', active: true, current_phase: 'planning' }),
+ '--json',
+ ], {
+ stdout: () => undefined,
+ stderr: (line) => stderr.push(line),
+ });
+
+ assert.equal(process.exitCode, 1);
+ assert.match(stderr.join('\n'), /native_ultragoal_activation_receipt_invalid/);
+ await assert.rejects(
+ readFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json')),
+ /ENOENT/,
+ );
+ });
+ }
+ });
+
+ it('never lets a foreign explicit session_id bypass native activation verification', async () => {
+ await withNativeUltragoalActivationFixture(async ({ stateDir }) => {
+ const foreignSessionId = 'foreign-explicit-session';
+ const payloads = [
+ {
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'planning',
+ session_id: foreignSessionId,
+ },
+ {
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'planning',
+ session_id: foreignSessionId,
+ extra: 'bypass-attempt',
+ },
+ {
+ mode: 'ultragoal',
+ session_id: foreignSessionId,
+ state: { active: true, current_phase: 'planning' },
+ },
+ {
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'executing',
+ session_id: foreignSessionId,
+ },
+ {
+ mode: 'ultragoal',
+ session_id: foreignSessionId,
+ state: { active: true, currentPhase: 'executing' },
+ },
+ ];
+ for (const payload of payloads) {
+ process.exitCode = undefined;
+ const stderr: string[] = [];
+ await stateCommand([
+ 'write',
+ '--input',
+ JSON.stringify(payload),
+ '--json',
+ ], {
+ stdout: () => undefined,
+ stderr: (line) => stderr.push(line),
+ });
+
+ assert.equal(process.exitCode, 1);
+ assert.match(stderr.join('\n'), /native_ultragoal_activation_receipt_invalid/);
+ }
+ await assert.rejects(
+ readFile(join(stateDir, 'sessions', foreignSessionId, 'ultragoal-state.json')),
+ /ENOENT/,
+ );
+ });
+ });
+
+ it('preserves existing explicit-session behavior for non-activation writes', async () => {
+ const input = {
+ mode: 'ultragoal',
+ active: false,
+ current_phase: 'complete',
+ session_id: 'existing-explicit-session',
+ };
+ let captured: Record<string, unknown> | undefined;
+ await stateCommand(['write', '--input', JSON.stringify(input), '--json'], {
+ stdout: () => undefined,
+ stderr: () => undefined,
+ execute: async (_operation, rawInput) => {
+ captured = rawInput;
+ return { payload: { success: true } };
+ },
+ });
+ assert.deepEqual(captured, input);
+ });
+
+ it('revalidates revoke and expiry races under the native lifecycle lock before commit', async () => {
+ for (const mutation of ['revoke', 'expire'] as const) {
+ await withNativeUltragoalActivationFixture(async ({ stateDir, sessionId }) => {
+ const bootstrapPath = join(
+ stateDir,
+ 'sessions',
+ sessionId,
+ NATIVE_ULTRAGOAL_BOOTSTRAP_FILE,
+ );
+ let mutated = false;
+ __setWritableStateScopeTestHooksForTests({
+ beforeScopeRevalidation: async () => {
+ if (mutated) return;
+ mutated = true;
+ const bootstrap = JSON.parse(await readFile(bootstrapPath, 'utf-8')) as Record<string, unknown>;
+ await writeFile(bootstrapPath, JSON.stringify(mutation === 'revoke'
+ ? { ...bootstrap, status: 'revoked' }
+ : { ...bootstrap, expires_at: '2000-01-01T00:00:00.000Z' }));
+ },
+ });
+ try {
+ const stderr: string[] = [];
+ await stateCommand([
+ 'write',
+ '--input',
+ JSON.stringify({ mode: 'ultragoal', active: true, current_phase: 'planning' }),
+ '--json',
+ ], {
+ stdout: () => undefined,
+ stderr: (line) => stderr.push(line),
+ });
+
+ assert.equal(process.exitCode, 1);
+ assert.match(stderr.join('\n'), /native_ultragoal_activation_receipt_invalid/);
+ await assert.rejects(
+ readFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json')),
+ /ENOENT/,
+ );
+ } finally {
+ __setWritableStateScopeTestHooksForTests({});
+ }
+ });
+ }
+ });
});
diff --git a/src/cli/__tests__/ultragoal.test.ts b/src/cli/__tests__/ultragoal.test.ts
index 74c6d1f2..72cbb3a9 100644
--- a/src/cli/__tests__/ultragoal.test.ts
+++ b/src/cli/__tests__/ultragoal.test.ts
@@ -14,6 +14,10 @@ import {
NATIVE_SUBAGENT_ROLE_ROUTING_MARKER_FILE,
writeRoleRoutingMarker,
} from '../../subagents/role-routing-marker.js';
+import {
+ beginNativeUltragoalBootstrap,
+ nativeExecutorAssignmentPath,
+} from '../../ultragoal/native-bootstrap.js';
import { ultragoalCommand, ULTRAGOAL_HELP } from '../ultragoal.js';
async function withCwd<T>(run: (cwd: string) => Promise<T>): Promise<T> {
@@ -67,6 +71,33 @@ async function capture(run: () => Promise<void>): Promise<{ stdout: string[]; st
}
}
+async function withNativeBootstrapEnv(
+ values: Partial<Record<'CODEX_HOME' | 'CODEX_THREAD_ID' | 'CODEX_SESSION_ID' | 'SESSION_ID' | 'OMX_SESSION_ID' | 'OMX_TEAM_WORKER' | 'OMX_TEAM_INTERNAL_WORKER', string>>,
+ run: () => Promise<void>,
+): Promise<void> {
+ const names = [
+ 'CODEX_HOME',
+ 'CODEX_THREAD_ID',
+ 'CODEX_SESSION_ID',
+ 'SESSION_ID',
+ 'OMX_SESSION_ID',
+ 'OMX_TEAM_WORKER',
+ 'OMX_TEAM_INTERNAL_WORKER',
+ ] as const;
+ const previous = Object.fromEntries(names.map((name) => [name, process.env[name]]));
+ try {
+ for (const name of names) delete process.env[name];
+ for (const [name, value] of Object.entries(values)) process.env[name] = value;
+ await run();
+ } finally {
+ for (const name of names) {
+ const value = previous[name];
+ if (typeof value === 'string') process.env[name] = value;
+ else delete process.env[name];
+ }
+ }
+}
+
describe('cli/ultragoal', () => {
it('does not create durable artifacts when OMX_SESSION_ID is unbound', async () => {
await withCwd(async (cwd) => {
@@ -144,6 +175,7 @@ describe('cli/ultragoal', () => {
['next'],
['start-next'],
['checkpoint', '--goal-id', 'G001-first', '--status', 'complete', '--evidence', 'worker evidence'],
+ ['native-bootstrap', 'revoke', '--session-id', 'worker-session'],
];
const envCases: Array<[string, string]> = [
['OMX_TEAM_WORKER', 'display-team/worker-1'],
@@ -214,6 +246,337 @@ describe('cli/ultragoal', () => {
assert.match(ULTRAGOAL_HELP, /quality-gate-json/);
assert.match(ULTRAGOAL_HELP, /ai-slop-cleaner/);
assert.match(ULTRAGOAL_HELP, /code-review/);
+ assert.match(ULTRAGOAL_HELP, /native-bootstrap <authorize\|status\|revoke>/);
+ assert.match(ULTRAGOAL_HELP, /--child-id <id> \| --child-path <agent-path>/);
+ });
+
+ it('authorizes, reports, and revokes an experimental native executor bootstrap', async () => {
+ await withCwd(async (cwd) => {
+ const previousBackend = process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = 'local-experimental';
+ const stateDir = join(cwd, '.omx', 'state');
+ const sessionId = 'native-cli-session';
+ const rootThreadId = 'native-cli-root';
+ const childAgentId = '019faf84-1111-7000-8000-000000000001';
+ const childAgentPath = '/root/native_cli_executor';
+ const codexHome = join(cwd, 'codex-home');
+ try {
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), `${JSON.stringify({
+ session_id: sessionId,
+ native_session_id: rootThreadId,
+ cwd,
+ })}\n`);
+ await writeFile(join(stateDir, 'subagent-tracking.json'), `${JSON.stringify({
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: rootThreadId,
+ updated_at: new Date().toISOString(),
+ threads: {
+ [rootThreadId]: {
+ thread_id: rootThreadId,
+ kind: 'leader',
+ first_seen_at: new Date().toISOString(),
+ last_seen_at: new Date().toISOString(),
+ turn_count: 1,
+ },
+ [childAgentId]: {
+ thread_id: childAgentId,
+ kind: 'subagent',
+ first_seen_at: new Date().toISOString(),
+ last_seen_at: new Date().toISOString(),
+ turn_count: 1,
+ mode: 'executor',
+ status: 'available',
+ provenance_kind: 'native_subagent',
+ direct_child_parent_id: rootThreadId,
+ direct_child_root_id: rootThreadId,
+ },
+ },
+ },
+ },
+ }, null, 2)}\n`);
+ const initialBootstrap = await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ });
+ const rolloutDir = join(codexHome, 'sessions', '2026', '07', '29');
+ await mkdir(rolloutDir, { recursive: true });
+ await writeFile(join(rolloutDir, `rollout-test-${childAgentId}.jsonl`), `${JSON.stringify({
+ timestamp: initialBootstrap.created_at,
+ type: 'session_meta',
+ payload: {
+ id: childAgentId,
+ session_id: sessionId,
+ cwd,
+ source: {
+ subagent: {
+ thread_spawn: {
+ parent_thread_id: rootThreadId,
+ depth: 1,
+ agent_path: childAgentPath,
+ agent_role: 'executor',
+ },
+ },
+ },
+ },
+ })}\n`);
+
+ await withNativeBootstrapEnv({ CODEX_HOME: codexHome, CODEX_THREAD_ID: rootThreadId }, async () => {
+ const crossSession = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', 'foreign-session', '--json',
+ ]));
+ assert.equal(crossSession.exitCode, 1);
+ assert.match(crossSession.stderr.join('\n'), /does not match the canonical current runtime session/);
+ const omittedSession = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--json',
+ ]));
+ assert.equal(omittedSession.exitCode, 1);
+ assert.match(omittedSession.stderr.join('\n'), /require an explicit --session-id/);
+
+ const missingChild = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'authorize',
+ '--session-id', sessionId,
+ '--root-thread-id', rootThreadId,
+ '--bootstrap-generation', initialBootstrap.generation,
+ '--path-prefix', 'src',
+ ]));
+ assert.equal(missingChild.exitCode, 1);
+ assert.match(missingChild.stderr.join('\n'), /exactly one of --child-id or --child-path/);
+
+ const conflictingChild = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'authorize',
+ '--session-id', sessionId,
+ '--root-thread-id', rootThreadId,
+ '--child-id', childAgentId,
+ '--child-path', childAgentPath,
+ '--bootstrap-generation', initialBootstrap.generation,
+ '--path-prefix', 'src',
+ ]));
+ assert.equal(conflictingChild.exitCode, 1);
+ assert.match(conflictingChild.stderr.join('\n'), /exactly one of --child-id or --child-path/);
+
+ const authorized = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'authorize',
+ '--session-id', sessionId,
+ '--root-thread-id', rootThreadId,
+ '--child-path', childAgentPath,
+ '--bootstrap-generation', initialBootstrap.generation,
+ '--path-prefix', 'src',
+ '--json',
+ ]));
+ assert.equal(authorized.exitCode, undefined, authorized.stderr.join('\n'));
+ assert.equal(JSON.parse(authorized.stdout.join('\n')).assignment.child_agent_id, childAgentId);
+ assert.equal(existsSync(nativeExecutorAssignmentPath(stateDir, sessionId, childAgentId)), true);
+
+ const status = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+ const statusPayload = JSON.parse(status.stdout.join('\n')) as {
+ bootstrap: { status: string };
+ readiness: { ready: boolean };
+ };
+ assert.equal(statusPayload.bootstrap.status, 'ready');
+ assert.equal(statusPayload.readiness.ready, true);
+
+ const revoked = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'revoke', '--session-id', sessionId, '--json',
+ ]));
+ assert.equal(revoked.exitCode, undefined);
+ assert.equal(JSON.parse(revoked.stdout.join('\n')).status, 'revoked');
+
+ await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
+ await writeFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'), `${JSON.stringify({
+ mode: 'ultragoal',
+ active: true,
+ current_phase: 'executing',
+ session_id: sessionId,
+ })}\n`);
+ const recoveryBootstrap = await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ });
+ const recovered = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'authorize',
+ '--session-id', sessionId,
+ '--root-thread-id', rootThreadId,
+ '--child-id', childAgentId,
+ '--bootstrap-generation', recoveryBootstrap.generation,
+ '--path-prefix', 'src',
+ '--json',
+ ]));
+ assert.equal(recovered.exitCode, undefined);
+ const recoveredStatus = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+ assert.equal(JSON.parse(recoveredStatus.stdout.join('\n')).bootstrap.status, 'active');
+ });
+ } finally {
+ if (typeof previousBackend === 'string') process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = previousBackend;
+ else delete process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ }
+ });
+ });
+
+ it('uses an exact CODEX_THREAD_ID binding for native-bootstrap with an identity-indeterminate pointer', async () => {
+ await withCwd(async () => {
+ const sessionId = 'native-bootstrap-indeterminate';
+ const runtimeCwd = process.cwd();
+ const stateDir = join(runtimeCwd, '.omx', 'state');
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), `${JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd: runtimeCwd,
+ state_root: stateDir,
+ pid_start_ticks: 1,
+ })}\n`);
+
+ await withNativeBootstrapEnv({ CODEX_THREAD_ID: sessionId }, async () => {
+ const result = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+
+ assert.equal(result.exitCode, undefined, result.stderr.join('\n'));
+ assert.equal(JSON.parse(result.stdout.join('\n')).bootstrap, null);
+ });
+ });
+ });
+
+ it('rejects the native-bootstrap fallback when CODEX_THREAD_ID does not match', async () => {
+ await withCwd(async () => {
+ const sessionId = 'native-bootstrap-thread-owner';
+ const runtimeCwd = process.cwd();
+ const stateDir = join(runtimeCwd, '.omx', 'state');
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), `${JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd: runtimeCwd,
+ state_root: stateDir,
+ pid_start_ticks: 1,
+ })}\n`);
+
+ await withNativeBootstrapEnv({ CODEX_THREAD_ID: 'native-bootstrap-child-thread' }, async () => {
+ const result = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+
+ assert.equal(result.exitCode, 1);
+ assert.match(result.stderr.join('\n'), /canonical current runtime session/);
+ });
+ });
+ });
+
+ it('rejects the native-bootstrap fallback when CODEX_THREAD_ID is absent', async () => {
+ await withCwd(async () => {
+ const sessionId = 'native-bootstrap-missing-thread';
+ const runtimeCwd = process.cwd();
+ const stateDir = join(runtimeCwd, '.omx', 'state');
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), `${JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd: runtimeCwd,
+ state_root: stateDir,
+ pid_start_ticks: 1,
+ })}\n`);
+
+ await withNativeBootstrapEnv({}, async () => {
+ const result = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+
+ assert.equal(result.exitCode, 1);
+ assert.match(result.stderr.join('\n'), /canonical current runtime session/);
+ });
+ });
+ });
+
+ it('rejects the native-bootstrap fallback when native_session_id does not match', async () => {
+ await withCwd(async () => {
+ const sessionId = 'native-bootstrap-native-owner';
+ const runtimeCwd = process.cwd();
+ const stateDir = join(runtimeCwd, '.omx', 'state');
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), `${JSON.stringify({
+ session_id: sessionId,
+ native_session_id: 'foreign-native-session',
+ cwd: runtimeCwd,
+ state_root: stateDir,
+ pid_start_ticks: 1,
+ })}\n`);
+
+ await withNativeBootstrapEnv({ CODEX_THREAD_ID: sessionId }, async () => {
+ const result = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+
+ assert.equal(result.exitCode, 1);
+ assert.match(result.stderr.join('\n'), /canonical current runtime session/);
+ });
+ });
+ });
+
+ it('rejects the native-bootstrap fallback when the pointer cwd does not match exactly', async () => {
+ await withCwd(async () => {
+ const sessionId = 'native-bootstrap-cwd-owner';
+ const runtimeCwd = process.cwd();
+ const stateDir = join(runtimeCwd, '.omx', 'state');
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), `${JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd: join(runtimeCwd, 'nested'),
+ state_root: stateDir,
+ })}\n`);
+
+ await withNativeBootstrapEnv({ CODEX_THREAD_ID: sessionId }, async () => {
+ const result = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+
+ assert.equal(result.exitCode, 1);
+ assert.match(result.stderr.join('\n'), /canonical current runtime session/);
+ });
+ });
+ });
+
+ it('rejects the native-bootstrap fallback from a Team worker identity', async () => {
+ await withCwd(async () => {
+ const sessionId = 'native-bootstrap-team-owner';
+ const runtimeCwd = process.cwd();
+ const stateDir = join(runtimeCwd, '.omx', 'state');
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), `${JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd: runtimeCwd,
+ state_root: stateDir,
+ })}\n`);
+
+ await withNativeBootstrapEnv({
+ CODEX_THREAD_ID: sessionId,
+ OMX_TEAM_WORKER: 'native-team/worker-1',
+ }, async () => {
+ const result = await capture(() => ultragoalCommand([
+ 'native-bootstrap', 'status', '--session-id', sessionId, '--json',
+ ]));
+
+ assert.equal(result.exitCode, 1);
+ assert.match(result.stderr.join('\n'), /leader-owned/i);
+ });
+ });
});
it('creates and starts goals through the command surface', async () => {
diff --git a/src/cli/state.ts b/src/cli/state.ts
index 79298ade..508f0d11 100644
--- a/src/cli/state.ts
+++ b/src/cli/state.ts
@@ -1,6 +1,16 @@
-import { readFile } from 'node:fs/promises';
+import { constants as fsConstants } from 'node:fs';
+import { lstat, open, readFile } from 'node:fs/promises';
+import { join } from 'node:path';
+import { classifySessionStateLiveness, isSessionStateAuthoritativeForCwd, type SessionState } from '../hooks/session.js';
+import { getBaseStateDirWithSource, normalizeSessionId, resolveWorkingDirectoryForState } from '../mcp/state-paths.js';
import { executeStateOperation, type StateOperationName } from '../state/operations.js';
+import {
+ findReadyLocalNativeExecutorAssignment,
+ readNativeUltragoalBootstrap,
+ withNativeUltragoalActivationAuthorization,
+} from '../ultragoal/native-bootstrap.js';
+import { sameFilePath } from '../utils/paths.js';
const STATE_HELP = `Usage: omx state <read|write|clear|list-active|get-status> [--input <json> | --input-file <path>] [--mode <mode>] [--json]
@@ -64,6 +74,242 @@ function parseStateInputJson(
return { ...(parsed as Record<string, unknown>) };
}
+async function readSafeSelectedSessionPointer(path: string): Promise<SessionState | null> {
+ const metadata = await lstat(path).catch(() => null);
+ if (
+ !metadata
+ || !metadata.isFile()
+ || metadata.isSymbolicLink()
+ || metadata.nlink !== 1
+ || (metadata.mode & 0o022) !== 0
+ || metadata.size > 64 * 1024
+ ) return null;
+
+ const handle = await open(path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0)).catch(() => null);
+ if (!handle) return null;
+ try {
+ const openedMetadata = await handle.stat();
+ if (
+ !openedMetadata.isFile()
+ || openedMetadata.dev !== metadata.dev
+ || openedMetadata.ino !== metadata.ino
+ || openedMetadata.nlink !== 1
+ || (openedMetadata.mode & 0o022) !== 0
+ || openedMetadata.size > 64 * 1024
+ ) return null;
+ const contents = await handle.readFile('utf-8');
+ const finalMetadata = await handle.stat();
+ if (
+ finalMetadata.dev !== openedMetadata.dev
+ || finalMetadata.ino !== openedMetadata.ino
+ || finalMetadata.nlink !== 1
+ || (finalMetadata.mode & 0o022) !== 0
+ || finalMetadata.size !== openedMetadata.size
+ || finalMetadata.mtimeMs !== openedMetadata.mtimeMs
+ || finalMetadata.ctimeMs !== openedMetadata.ctimeMs
+ ) return null;
+ const parsed = JSON.parse(contents) as unknown;
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
+ ? parsed as SessionState
+ : null;
+ } catch {
+ return null;
+ } finally {
+ await handle.close().catch(() => {});
+ }
+}
+
+async function readSafeJsonRecord(path: string): Promise<Record<string, unknown> | null> {
+ const value = await readSafeSelectedSessionPointer(path);
+ return value as Record<string, unknown> | null;
+}
+
+function isCanonicalNativeUltragoalActivation(input: Record<string, unknown>): boolean {
+ const keys = Object.keys(input).sort().join(',');
+ return (keys === 'active,current_phase,mode' || keys === 'active,current_phase,mode,session_id')
+ && typeof input.current_phase === 'string'
+ && isNativeUltragoalActivationIntent(input);
+}
+
+function isNativeUltragoalActivationIntent(input: Record<string, unknown>): boolean {
+ const nested = input.state && typeof input.state === 'object' && !Array.isArray(input.state)
+ ? input.state as Record<string, unknown>
+ : {};
+ const active = Object.prototype.hasOwnProperty.call(nested, 'active')
+ ? nested.active
+ : input.active;
+ const phase = nested.current_phase
+ ?? nested.currentPhase
+ ?? input.current_phase
+ ?? input.currentPhase;
+ const normalizedPhase = typeof phase === 'string' ? phase.trim().toLowerCase() : '';
+ return input.mode === 'ultragoal'
+ && active === true
+ && normalizedPhase !== ''
+ && !['complete', 'completed', 'cancelled', 'canceled', 'failed', 'cleared'].includes(normalizedPhase);
+}
+
+function isCanonicalNativeUltragoalTerminalIntent(input: Record<string, unknown>): boolean {
+ const keys = Object.keys(input).sort().join(',');
+ return keys === 'active,current_phase,mode'
+ && input.mode === 'ultragoal'
+ && input.active === false
+ && input.current_phase === 'complete';
+}
+
+function hasTeamWorkerIdentity(): boolean {
+ return Boolean(process.env.OMX_TEAM_WORKER?.trim() || process.env.OMX_TEAM_INTERNAL_WORKER?.trim());
+}
+
+async function sessionHasActiveUltragoalState(
+ stateDir: string,
+ sessionId: string,
+): Promise<boolean> {
+ try {
+ const state = JSON.parse(await readFile(
+ join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'),
+ 'utf-8',
+ )) as Record<string, unknown>;
+ const phase = typeof state.current_phase === 'string' ? state.current_phase.trim().toLowerCase() : '';
+ return state.active === true
+ && phase !== ''
+ && !['complete', 'completed', 'cancelled', 'canceled', 'failed', 'cleared'].includes(phase);
+ } catch {
+ return false;
+ }
+}
+
+async function resolveNativeUltragoalActivationSession(
+ input: Record<string, unknown>,
+): Promise<{
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ childAgentId: string;
+ bootstrapStatus: 'activating' | 'active';
+} | null> {
+ if (!isCanonicalNativeUltragoalActivation(input) || hasTeamWorkerIdentity()) return null;
+ const threadId = process.env.CODEX_THREAD_ID;
+ if (!threadId || normalizeSessionId(threadId) !== threadId) return null;
+ if (
+ Object.prototype.hasOwnProperty.call(input, 'session_id')
+ && input.session_id !== threadId
+ ) return null;
+
+ const cwd = resolveWorkingDirectoryForState();
+ const { baseStateDir } = getBaseStateDirWithSource(cwd);
+ const pointer = await readSafeSelectedSessionPointer(join(baseStateDir, 'session.json'));
+ if (
+ !pointer
+ || pointer.session_id !== threadId
+ || normalizeSessionId(pointer.session_id) !== threadId
+ || pointer.native_session_id !== threadId
+ || normalizeSessionId(pointer.native_session_id) !== threadId
+ || !isSessionStateAuthoritativeForCwd(pointer, cwd)
+ || !['identity-indeterminate', 'stale-dead'].includes(classifySessionStateLiveness(pointer))
+ ) return null;
+ const pointerStateRoot = typeof pointer.state_root === 'string'
+ ? pointer.state_root
+ : join(cwd, '.omx', 'state');
+ if (!sameFilePath(pointerStateRoot, baseStateDir)) return null;
+
+ const existingActiveState = await sessionHasActiveUltragoalState(baseStateDir, threadId);
+ const bootstrapStatus = existingActiveState ? 'active' : 'activating';
+ if (bootstrapStatus === 'activating' && input.current_phase !== 'planning') return null;
+ const bootstrapBefore = await readNativeUltragoalBootstrap(baseStateDir, threadId);
+ if (
+ !bootstrapBefore
+ || bootstrapBefore.status !== bootstrapStatus
+ || bootstrapBefore.session_id !== threadId
+ || bootstrapBefore.root_thread_id !== threadId
+ || !bootstrapBefore.child_agent_id
+ ) return null;
+ const assignment = await findReadyLocalNativeExecutorAssignment({
+ cwd,
+ stateDir: baseStateDir,
+ sessionId: threadId,
+ rootThreadId: threadId,
+ });
+ if (!assignment || assignment.child_agent_id !== bootstrapBefore.child_agent_id) return null;
+ const bootstrapAfter = await readNativeUltragoalBootstrap(baseStateDir, threadId);
+ if (
+ !bootstrapAfter
+ || bootstrapAfter.status !== bootstrapStatus
+ || bootstrapAfter.generation !== bootstrapBefore.generation
+ || bootstrapAfter.child_agent_id !== bootstrapBefore.child_agent_id
+ ) return null;
+ return {
+ cwd,
+ stateDir: baseStateDir,
+ sessionId: threadId,
+ childAgentId: assignment.child_agent_id,
+ bootstrapStatus,
+ };
+}
+
+async function resolveNativeUltragoalTerminalSession(
+ input: Record<string, unknown>,
+ allowPersistedTerminal = false,
+): Promise<{ sessionId: string } | null> {
+ if (!isCanonicalNativeUltragoalTerminalIntent(input) || hasTeamWorkerIdentity()) return null;
+ const threadId = process.env.CODEX_THREAD_ID;
+ if (!threadId || normalizeSessionId(threadId) !== threadId) return null;
+
+ const cwd = resolveWorkingDirectoryForState();
+ const { baseStateDir } = getBaseStateDirWithSource(cwd);
+ const pointer = await readSafeSelectedSessionPointer(join(baseStateDir, 'session.json'));
+ if (
+ !pointer
+ || pointer.session_id !== threadId
+ || pointer.native_session_id !== threadId
+ || !isSessionStateAuthoritativeForCwd(pointer, cwd)
+ || !['usable', 'identity-indeterminate'].includes(classifySessionStateLiveness(pointer))
+ ) return null;
+ const pointerStateRoot = typeof pointer.state_root === 'string'
+ ? pointer.state_root
+ : join(cwd, '.omx', 'state');
+ if (!sameFilePath(pointerStateRoot, baseStateDir)) return null;
+
+ const state = await readSafeJsonRecord(join(baseStateDir, 'sessions', threadId, 'ultragoal-state.json'));
+ const persistedStateIsAuthorized = Boolean(
+ state
+ && (
+ (state.active === true && state.current_phase === 'checkpointing')
+ || (allowPersistedTerminal && state.active === false && state.current_phase === 'complete')
+ )
+ && (typeof state.session_id !== 'string' || state.session_id === threadId),
+ );
+ if (!persistedStateIsAuthorized) return null;
+ const plan = await readSafeJsonRecord(join(cwd, '.omx', 'ultragoal', 'goals.json'));
+ const goals = Array.isArray(plan?.goals) ? plan.goals : [];
+ const aggregateCompletion = plan?.aggregateCompletion && typeof plan.aggregateCompletion === 'object'
+ && !Array.isArray(plan.aggregateCompletion)
+ ? plan.aggregateCompletion as Record<string, unknown>
+ : null;
+ if (
+ goals.length === 0
+ || goals.some((goal) => !goal || typeof goal !== 'object' || Array.isArray(goal)
+ || (goal as Record<string, unknown>).status !== 'complete')
+ || aggregateCompletion?.status !== 'complete'
+ ) return null;
+
+ const bootstrap = await readNativeUltragoalBootstrap(baseStateDir, threadId);
+ if (
+ !bootstrap
+ || bootstrap.status !== 'revoked'
+ || bootstrap.session_id !== threadId
+ || bootstrap.root_thread_id !== threadId
+ || !bootstrap.child_agent_id
+ ) return null;
+ const assignment = await findReadyLocalNativeExecutorAssignment({
+ cwd,
+ stateDir: baseStateDir,
+ sessionId: threadId,
+ rootThreadId: threadId,
+ });
+ return assignment ? null : { sessionId: threadId };
+}
+
export async function stateCommand(
args: string[],
deps: StateCommandDependencies = {},
@@ -164,7 +410,57 @@ export async function stateCommand(
input = { ...input, mode: modeValue };
}
- const result = await execute(operation, input);
+ let result;
+ if (operation === 'state_write' && isNativeUltragoalActivationIntent(input)) {
+ const authorization = await resolveNativeUltragoalActivationSession(input);
+ if (!authorization) {
+ result = {
+ payload: { error: 'native_ultragoal_activation_receipt_invalid' },
+ isError: true,
+ };
+ } else {
+ const activation = await withNativeUltragoalActivationAuthorization(
+ authorization,
+ async (assertNativeAuthorized) => {
+ const assertAuthorized = async (): Promise<void> => {
+ await assertNativeAuthorized();
+ if (
+ authorization.bootstrapStatus === 'active'
+ && !await sessionHasActiveUltragoalState(authorization.stateDir, authorization.sessionId)
+ ) throw new Error('native_ultragoal_activation_receipt_invalid');
+ };
+ await assertAuthorized();
+ return execute(operation, {
+ ...input,
+ session_id: authorization.sessionId,
+ }, {
+ beforeStateWriteCommit: assertAuthorized,
+ });
+ },
+ );
+ result = activation.ok
+ ? activation.value
+ : {
+ payload: { error: 'native_ultragoal_activation_receipt_invalid' },
+ isError: true,
+ };
+ }
+ } else if (operation === 'state_write' && isCanonicalNativeUltragoalTerminalIntent(input)) {
+ const authorization = await resolveNativeUltragoalTerminalSession(input);
+ let terminalStateCommitObserved = false;
+ result = authorization
+ ? await execute(operation, { ...input, session_id: authorization.sessionId }, {
+ beforeStateWriteCommit: async () => {
+ if (!await resolveNativeUltragoalTerminalSession(input, terminalStateCommitObserved)) {
+ throw new Error('native_ultragoal_terminal_receipt_invalid');
+ }
+ terminalStateCommitObserved = true;
+ },
+ })
+ : { payload: { error: 'native_ultragoal_terminal_receipt_invalid' }, isError: true };
+ } else {
+ result = await execute(operation, input);
+ }
const body = JSON.stringify(result.payload, null, json ? 0 : 2);
if (result.isError) {
diff --git a/src/cli/ultragoal.ts b/src/cli/ultragoal.ts
index 64d2e356..38b034a2 100644
--- a/src/cli/ultragoal.ts
+++ b/src/cli/ultragoal.ts
@@ -11,8 +11,11 @@ import {
NATIVE_SUBAGENT_SUPPORT_BLOCKER_FILE,
resolveNativeSubagentSupportStatus,
} from '../leader/contract.js';
-import { resolveRuntimeStateScope } from '../mcp/state-paths.js';
+import { isSessionStateAuthoritativeForCwd, type SessionState } from '../hooks/session.js';
+import { normalizeSessionId, resolveRuntimeStateScope } from '../mcp/state-paths.js';
+import { resolveNativeUltragoalConfig } from '../config/native-ultragoal.js';
import { readRoleRoutingMarker } from '../subagents/role-routing-marker.js';
+import { sameFilePath } from '../utils/paths.js';
import {
addUltragoalGoal,
buildCodexGoalInstruction,
@@ -33,6 +36,32 @@ import {
ULTRAGOAL_STEERING_SOURCES,
UltragoalError,
} from '../ultragoal/artifacts.js';
+import {
+ issueLocalNativeExecutorAssignment,
+ markNativeUltragoalBootstrapActive,
+ prepareNativeUltragoalBootstrapActivation,
+ readNativeUltragoalBootstrap,
+ reconcileLocalNativeExecutorAssignments,
+ resolveLocalNativeExecutorChildReceipt,
+ revokeLocalNativeExecutorAssignment,
+} from '../ultragoal/native-bootstrap.js';
+
+async function sessionHasActiveStandaloneUltragoal(stateDir: string, sessionId: string): Promise<boolean> {
+ try {
+ const parsed = JSON.parse(await readFile(
+ join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'),
+ 'utf-8',
+ )) as Record<string, unknown>;
+ const phase = String(parsed.current_phase ?? parsed.currentPhase ?? '').trim().toLowerCase();
+ return parsed.mode === 'ultragoal'
+ && parsed.active === true
+ && parsed.session_id === sessionId
+ && phase !== ''
+ && !['complete', 'completed', 'cancelled', 'failed'].includes(phase);
+ } catch {
+ return false;
+ }
+}
export const ULTRAGOAL_HELP = `omx ultragoal - Durable repo-native multi-goal workflow over Codex goal mode
@@ -46,6 +75,8 @@ Usage:
omx ultragoal steer --directive-json <json-or-path> [--json]
omx ultragoal checkpoint --goal-id <id> --status <complete|failed|blocked> [--evidence <text>] [--codex-goal-json <json-or-path>] [--quality-gate-json <json-or-path>] [--json]
omx ultragoal status [--codex-goal-json <json-or-path>] [--json]
+ omx ultragoal native-bootstrap <authorize|status|revoke> [options] [--json]
+ omx ultragoal native-bootstrap authorize --session-id <id> --root-thread-id <id> (--child-id <id> | --child-path <agent-path>) --bootstrap-generation <id> --path-prefix <path> [--json]
Aliases:
create -> create-goals, complete|next|start-next -> complete-goals
@@ -336,6 +367,7 @@ const ULTRAGOAL_MUTATING_COMMANDS = new Set([
'next',
'start-next',
'checkpoint',
+ 'native-bootstrap',
]);
function readTeamWorkerIdentity(env: NodeJS.ProcessEnv = process.env): string | null {
@@ -345,6 +377,37 @@ function readTeamWorkerIdentity(env: NodeJS.ProcessEnv = process.env): string |
return internalIdentity || null;
}
+async function resolveNativeBootstrapRuntimeScope(cwd: string, requestedSessionId: string) {
+ const scope = await resolveRuntimeStateScope(cwd);
+ if (scope.sessionId || readTeamWorkerIdentity()) return scope;
+
+ const codexThreadId = process.env.CODEX_THREAD_ID;
+ if (
+ codexThreadId !== requestedSessionId
+ || normalizeSessionId(codexThreadId) !== requestedSessionId
+ ) return scope;
+
+ const pointer = await readJsonIfExists<Record<string, unknown>>(join(scope.baseStateDir, 'session.json'));
+ if (
+ !pointer
+ || Array.isArray(pointer)
+ || pointer.session_id !== requestedSessionId
+ || normalizeSessionId(pointer.session_id) !== requestedSessionId
+ || pointer.native_session_id !== requestedSessionId
+ || normalizeSessionId(pointer.native_session_id) !== requestedSessionId
+ || !isSessionStateAuthoritativeForCwd(pointer as unknown as SessionState, scope.cwd)
+ ) {
+ return scope;
+ }
+
+ const pointerStateRoot = typeof pointer.state_root === 'string'
+ ? pointer.state_root
+ : join(scope.cwd, '.omx', 'state');
+ if (!sameFilePath(pointerStateRoot, scope.baseStateDir)) return scope;
+
+ return resolveRuntimeStateScope(cwd, requestedSessionId);
+}
+
function assertUltragoalMutationAllowedFromCurrentProcess(command: string): void {
if (!ULTRAGOAL_MUTATING_COMMANDS.has(command)) return;
const workerIdentity = readTeamWorkerIdentity();
@@ -374,6 +437,133 @@ export async function ultragoalCommand(args: string[], deps: UltragoalCommandDep
assertUltragoalMutationAllowedFromCurrentProcess(command);
+ if (command === 'native-bootstrap') {
+ const action = rest[0] ?? 'status';
+ const actionArgs = rest.slice(1);
+ const config = resolveNativeUltragoalConfig();
+ const requestedSessionId = readValue(actionArgs, '--session-id');
+ if (!requestedSessionId) {
+ throw new UltragoalError('Native bootstrap commands require an explicit --session-id.');
+ }
+ const scope = await resolveNativeBootstrapRuntimeScope(cwd, requestedSessionId);
+ if (!scope.sessionId) {
+ throw new UltragoalError('Native bootstrap requires a canonical current runtime session.');
+ }
+ if (requestedSessionId !== scope.sessionId) {
+ throw new UltragoalError('Requested --session-id does not match the canonical current runtime session.');
+ }
+ const sessionId = scope.sessionId;
+ const rootThreadId = readValue(actionArgs, '--root-thread-id');
+
+ if (action === 'authorize') {
+ if (config.backend !== 'local-experimental') {
+ throw new UltragoalError('native-bootstrap authorize requires nativeUltragoal.backend="local-experimental".');
+ }
+ const requestedChildAgentId = readValue(actionArgs, '--child-id');
+ const childAgentPath = readValue(actionArgs, '--child-path');
+ const bootstrapGeneration = readValue(actionArgs, '--bootstrap-generation');
+ const pathPrefixes = readRepeated(actionArgs, '--path-prefix');
+ if (!rootThreadId) throw new UltragoalError('Missing --root-thread-id.');
+ if (Boolean(requestedChildAgentId) === Boolean(childAgentPath)) {
+ throw new UltragoalError('Pass exactly one of --child-id or --child-path.');
+ }
+ if (!bootstrapGeneration) throw new UltragoalError('Missing --bootstrap-generation.');
+ if (pathPrefixes.length === 0) throw new UltragoalError('Pass at least one --path-prefix.');
+ let childAgentId = requestedChildAgentId;
+ if (childAgentPath) {
+ const receiptBootstrap = await readNativeUltragoalBootstrap(scope.baseStateDir, sessionId);
+ if (
+ !receiptBootstrap
+ || receiptBootstrap.generation !== bootstrapGeneration
+ || receiptBootstrap.root_thread_id !== rootThreadId
+ ) throw new UltragoalError('child_transcript_receipt_unbound');
+ const resolvedChild = await resolveLocalNativeExecutorChildReceipt({
+ cwd: scope.cwd,
+ sessionId,
+ rootThreadId,
+ agentPath: childAgentPath,
+ receiptNotBefore: receiptBootstrap.created_at,
+ receiptNotAfter: receiptBootstrap.expires_at,
+ });
+ if (!resolvedChild.ok) throw new UltragoalError(resolvedChild.reason);
+ childAgentId = resolvedChild.childAgentId;
+ }
+ if (!childAgentId) throw new UltragoalError('Unable to resolve native executor child identity.');
+ const ttlRaw = readValue(actionArgs, '--ttl-seconds');
+ const ttlSeconds = ttlRaw === undefined ? config.assignmentTtlSeconds : Number(ttlRaw);
+ try {
+ const assignment = await issueLocalNativeExecutorAssignment({
+ cwd: scope.cwd,
+ stateDir: scope.baseStateDir,
+ sessionId,
+ rootThreadId,
+ childAgentId,
+ expectedGeneration: bootstrapGeneration,
+ pathPrefixes,
+ ttlSeconds,
+ allowedActions: hasFlag(actionArgs, '--path-write-only')
+ ? ['path-write']
+ : ['path-write', 'bash-write'],
+ });
+ if (await sessionHasActiveStandaloneUltragoal(scope.baseStateDir, sessionId)) {
+ const currentBootstrap = await readNativeUltragoalBootstrap(scope.baseStateDir, sessionId);
+ if (currentBootstrap?.status !== 'active') {
+ const prepared = await prepareNativeUltragoalBootstrapActivation({
+ cwd: scope.cwd,
+ stateDir: scope.baseStateDir,
+ sessionId,
+ childAgentId,
+ });
+ if (!prepared.ok) throw new UltragoalError('native_ultragoal_activation_receipt_invalid');
+ const confirmed = await markNativeUltragoalBootstrapActive({
+ cwd: scope.cwd,
+ stateDir: scope.baseStateDir,
+ sessionId,
+ childAgentId,
+ });
+ if (!confirmed.ok) throw new UltragoalError('native_ultragoal_activation_receipt_invalid');
+ }
+ }
+ if (json) printJson({ ok: true, backend: config.backend, assignment });
+ else console.log(`native Ultragoal executor authorized: ${assignment.child_agent_id}`);
+ } catch (error) {
+ throw new UltragoalError(error instanceof Error ? error.message : String(error));
+ }
+ return;
+ }
+
+ if (action === 'revoke') {
+ await revokeLocalNativeExecutorAssignment({
+ stateDir: scope.baseStateDir,
+ sessionId,
+ childAgentId: readValue(actionArgs, '--child-id'),
+ reason: readValue(actionArgs, '--reason') ?? 'root_requested_revoke',
+ });
+ if (json) printJson({ ok: true, sessionId, status: 'revoked' });
+ else console.log(`native Ultragoal bootstrap revoked: ${sessionId}`);
+ return;
+ }
+
+ if (action === 'status') {
+ const bootstrap = await readNativeUltragoalBootstrap(scope.baseStateDir, sessionId);
+ const readiness = bootstrap?.root_thread_id
+ ? await reconcileLocalNativeExecutorAssignments({
+ cwd: scope.cwd,
+ stateDir: scope.baseStateDir,
+ sessionId,
+ rootThreadId: bootstrap.root_thread_id,
+ })
+ : { ready: false };
+ if (json) printJson({ backend: config.backend, bootstrap, readiness });
+ else console.log(bootstrap
+ ? `native Ultragoal bootstrap: ${bootstrap.status}${readiness.ready ? ' (ready)' : ''}`
+ : 'native Ultragoal bootstrap: absent');
+ return;
+ }
+
+ throw new UltragoalError('Invalid native-bootstrap action; expected authorize, status, or revoke.');
+ }
+
if (command === 'create' || command === 'create-goals') {
const briefFile = readValue(rest, '--brief-file');
const brief = readValue(rest, '--brief')
diff --git a/src/config/__tests__/native-ultragoal.test.ts b/src/config/__tests__/native-ultragoal.test.ts
new file mode 100644
index 00000000..e4bb6532
--- /dev/null
+++ b/src/config/__tests__/native-ultragoal.test.ts
@@ -0,0 +1,95 @@
+import assert from 'node:assert/strict';
+import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
+import { tmpdir } from 'node:os';
+import { join } from 'node:path';
+import { describe, it } from 'node:test';
+import { resolveNativeUltragoalConfig } from '../native-ultragoal.js';
+
+describe('native Ultragoal config', () => {
+ it('defaults off and reads the explicit global config', async () => {
+ const homeDir = await mkdtemp(join(tmpdir(), 'omx-native-ultragoal-config-'));
+ try {
+ assert.deepEqual(resolveNativeUltragoalConfig({ homeDir, env: {} }), {
+ backend: 'off',
+ assignmentTtlSeconds: 900,
+ source: 'default',
+ });
+ await mkdir(join(homeDir, '.omx'), { recursive: true });
+ await writeFile(join(homeDir, '.omx', 'config.json'), JSON.stringify({
+ nativeUltragoal: {
+ backend: 'local-experimental',
+ assignmentTtlSeconds: 300,
+ },
+ }));
+ assert.deepEqual(resolveNativeUltragoalConfig({ homeDir, env: {} }), {
+ backend: 'local-experimental',
+ assignmentTtlSeconds: 300,
+ source: 'config',
+ });
+ } finally {
+ await rm(homeDir, { recursive: true, force: true });
+ }
+ });
+
+ it('keeps invalid config fail-closed and preserves explicit env precedence', async () => {
+ const homeDir = await mkdtemp(join(tmpdir(), 'omx-native-ultragoal-config-invalid-'));
+ try {
+ await mkdir(join(homeDir, '.omx'), { recursive: true });
+ await writeFile(join(homeDir, '.omx', 'config.json'), JSON.stringify({
+ nativeUltragoal: { backend: 'local', assignmentTtlSeconds: 1 },
+ }));
+ assert.equal(resolveNativeUltragoalConfig({ homeDir, env: {} }).backend, 'off');
+ assert.deepEqual(resolveNativeUltragoalConfig({
+ homeDir,
+ env: { OMX_NATIVE_ULTRAGOAL_BACKEND: 'host' },
+ }), {
+ backend: 'host',
+ assignmentTtlSeconds: 900,
+ source: 'env',
+ });
+ assert.equal(resolveNativeUltragoalConfig({
+ homeDir,
+ env: { OMX_NATIVE_SUBAGENT_ASSIGNMENTS: 'on' },
+ }).backend, 'off');
+ await writeFile(join(homeDir, '.omx', 'config.json'), '{ malformed');
+ assert.deepEqual(resolveNativeUltragoalConfig({
+ homeDir,
+ env: { OMX_NATIVE_SUBAGENT_ASSIGNMENTS: 'on' },
+ }), {
+ backend: 'off',
+ assignmentTtlSeconds: 900,
+ source: 'config',
+ });
+ } finally {
+ await rm(homeDir, { recursive: true, force: true });
+ }
+ });
+
+ it('keeps explicit new config ahead of the legacy assignment opt-in', async () => {
+ const homeDir = await mkdtemp(join(tmpdir(), 'omx-native-ultragoal-config-legacy-'));
+ try {
+ await mkdir(join(homeDir, '.omx'), { recursive: true });
+ await writeFile(join(homeDir, '.omx', 'config.json'), JSON.stringify({
+ nativeUltragoal: { backend: 'host', assignmentTtlSeconds: 120 },
+ }));
+ assert.deepEqual(resolveNativeUltragoalConfig({
+ homeDir,
+ env: { OMX_NATIVE_SUBAGENT_ASSIGNMENTS: 'on' },
+ }), {
+ backend: 'host',
+ assignmentTtlSeconds: 120,
+ source: 'config',
+ });
+ assert.deepEqual(resolveNativeUltragoalConfig({
+ homeDir,
+ env: { OMX_NATIVE_ULTRAGOAL_BACKEND: 'local' },
+ }), {
+ backend: 'off',
+ assignmentTtlSeconds: 120,
+ source: 'env',
+ });
+ } finally {
+ await rm(homeDir, { recursive: true, force: true });
+ }
+ });
+});
diff --git a/src/config/native-ultragoal.ts b/src/config/native-ultragoal.ts
new file mode 100644
index 00000000..83da9374
--- /dev/null
+++ b/src/config/native-ultragoal.ts
@@ -0,0 +1,125 @@
+import { existsSync, readFileSync } from 'node:fs';
+import { homedir } from 'node:os';
+import { join } from 'node:path';
+
+export type NativeUltragoalBackend = 'off' | 'host' | 'local-experimental';
+
+export interface NativeUltragoalRuntimeConfig {
+ backend: NativeUltragoalBackend;
+ assignmentTtlSeconds: number;
+ source: 'default' | 'config' | 'env' | 'legacy-env';
+}
+
+interface NativeUltragoalConfigFile {
+ nativeUltragoal?: {
+ backend?: unknown;
+ assignmentTtlSeconds?: unknown;
+ };
+}
+
+const DEFAULT_ASSIGNMENT_TTL_SECONDS = 15 * 60;
+const MIN_ASSIGNMENT_TTL_SECONDS = 30;
+const MAX_ASSIGNMENT_TTL_SECONDS = 60 * 60;
+
+function normalizeBackend(value: unknown): NativeUltragoalBackend | null {
+ if (typeof value !== 'string') return null;
+ const normalized = value.trim().toLowerCase();
+ if (normalized === 'off' || normalized === 'host' || normalized === 'local-experimental') return normalized;
+ return null;
+}
+
+function normalizeAssignmentTtlSeconds(value: unknown): number | null {
+ if (typeof value !== 'number' || !Number.isInteger(value)) return null;
+ if (value < MIN_ASSIGNMENT_TTL_SECONDS || value > MAX_ASSIGNMENT_TTL_SECONDS) return null;
+ return value;
+}
+
+function readConfigFile(homeDir: string):
+ | { status: 'absent' }
+ | { status: 'invalid' }
+ | { status: 'valid'; value: NativeUltragoalConfigFile } {
+ const path = join(homeDir, '.omx', 'config.json');
+ if (!existsSync(path)) return { status: 'absent' };
+ try {
+ const parsed = JSON.parse(readFileSync(path, 'utf-8')) as unknown;
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
+ ? { status: 'valid', value: parsed as NativeUltragoalConfigFile }
+ : { status: 'invalid' };
+ } catch {
+ return { status: 'invalid' };
+ }
+}
+
+export function resolveNativeUltragoalConfig(options: {
+ homeDir?: string;
+ env?: NodeJS.ProcessEnv;
+} = {}): NativeUltragoalRuntimeConfig {
+ const env = options.env ?? process.env;
+ const configResult = readConfigFile(options.homeDir ?? homedir());
+ const config = configResult.status === 'valid' ? configResult.value : null;
+ const hasExplicitConfiguredBackend = config?.nativeUltragoal?.backend !== undefined;
+ const configuredBackend = normalizeBackend(config?.nativeUltragoal?.backend);
+ const assignmentTtlSeconds = normalizeAssignmentTtlSeconds(
+ config?.nativeUltragoal?.assignmentTtlSeconds,
+ ) ?? DEFAULT_ASSIGNMENT_TTL_SECONDS;
+ const rawEnvBackend = env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ const explicitEnvBackend = normalizeBackend(rawEnvBackend);
+ if (explicitEnvBackend) {
+ return {
+ backend: explicitEnvBackend,
+ assignmentTtlSeconds,
+ source: 'env',
+ };
+ }
+ if (typeof rawEnvBackend === 'string' && rawEnvBackend.trim() !== '') {
+ return {
+ backend: 'off',
+ assignmentTtlSeconds,
+ source: 'env',
+ };
+ }
+
+ if (configResult.status === 'invalid') {
+ return {
+ backend: 'off',
+ assignmentTtlSeconds,
+ source: 'config',
+ };
+ }
+
+ if (configuredBackend) {
+ return {
+ backend: configuredBackend,
+ assignmentTtlSeconds,
+ source: 'config',
+ };
+ }
+
+ if (hasExplicitConfiguredBackend) {
+ return {
+ backend: 'off',
+ assignmentTtlSeconds,
+ source: 'config',
+ };
+ }
+
+ if (String(env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS ?? '').trim().toLowerCase() === 'on') {
+ return {
+ backend: 'local-experimental',
+ assignmentTtlSeconds,
+ source: 'legacy-env',
+ };
+ }
+
+ return {
+ backend: 'off',
+ assignmentTtlSeconds,
+ source: 'default',
+ };
+}
+
+export function nativeUltragoalBackendIsLocalExperimental(
+ options: Parameters<typeof resolveNativeUltragoalConfig>[0] = {},
+): boolean {
+ return resolveNativeUltragoalConfig(options).backend === 'local-experimental';
+}
diff --git a/src/hooks/__tests__/notify-hook-auto-nudge.test.ts b/src/hooks/__tests__/notify-hook-auto-nudge.test.ts
index 44fd9f87..d50bfccf 100644
--- a/src/hooks/__tests__/notify-hook-auto-nudge.test.ts
+++ b/src/hooks/__tests__/notify-hook-auto-nudge.test.ts
@@ -2383,6 +2383,120 @@ exit 0
});
});
+ it('does not reactivate completed ultragoal from the same completed-turn input replay', async () => {
+ await withTempWorkingDir(async (cwd) => {
+ const omxDir = join(cwd, '.omx');
+ const stateDir = join(omxDir, 'state');
+ const logsDir = join(omxDir, 'logs');
+ const codexHome = join(cwd, 'codex-home');
+ const fakeBinDir = join(cwd, 'fake-bin');
+ const sessionStateDir = join(stateDir, 'sessions', 'sess-managed');
+ const terminalCompletedAt = '2026-07-30T00:06:49.168Z';
+
+ await mkdir(logsDir, { recursive: true });
+ await mkdir(sessionStateDir, { recursive: true });
+ await mkdir(codexHome, { recursive: true });
+ await mkdir(fakeBinDir, { recursive: true });
+
+ await writeJson(join(codexHome, '.omx-config.json'), {
+ autoNudge: { enabled: true, delaySec: 0, stallMs: 0 },
+ });
+ await writeManagedSessionState(stateDir, cwd);
+ await writeJson(join(sessionStateDir, 'ultragoal-state.json'), {
+ active: false,
+ current_phase: 'complete',
+ run_outcome: 'finished',
+ completed_at: terminalCompletedAt,
+ });
+ await writeJson(join(stateDir, 'native-stop-state.json'), {
+ sessions: {
+ 'sess-managed': {
+ ordinary_no_progress_guard: {
+ last_turn_id: 'turn-ultragoal-complete',
+ last_thread_id: null,
+ },
+ },
+ },
+ });
+
+ await writeFile(join(fakeBinDir, 'tmux'), buildFakeTmux(join(cwd, 'tmux.log')));
+ await chmod(join(fakeBinDir, 'tmux'), 0o755);
+
+ const result = runNotifyHook(cwd, fakeBinDir, codexHome, {
+ type: 'agent-turn-complete',
+ 'thread-id': 'thread-ultragoal-complete',
+ 'turn-id': 'turn-ultragoal-complete',
+ 'input-messages': ['$ultragoal Выполни полный native acceptance.'],
+ 'last-assistant-message': 'Native Ultragoal acceptance завершён до terminal completion.',
+ });
+ assert.equal(result.status, 0, `hook failed: ${result.stderr || result.stdout}`);
+
+ const ultragoalState = JSON.parse(await readFile(join(sessionStateDir, 'ultragoal-state.json'), 'utf-8')) as {
+ mode?: string;
+ active: boolean;
+ current_phase: string;
+ started_at?: string;
+ completed_at?: string;
+ run_outcome?: string;
+ };
+ assert.equal(ultragoalState.mode, undefined, 'notify must preserve the CLI state-file shape without reseeding mode');
+ assert.equal(ultragoalState.active, false);
+ assert.equal(ultragoalState.current_phase, 'complete');
+ assert.equal(ultragoalState.run_outcome, 'finished');
+ assert.equal(ultragoalState.completed_at, terminalCompletedAt);
+ assert.equal(ultragoalState.started_at, undefined, 'notify must not create a new planning run');
+ });
+ });
+
+ it('allows a later ultragoal prompt after completed state to reach normal activation', async () => {
+ await withTempWorkingDir(async (cwd) => {
+ const stateDir = join(cwd, '.omx', 'state');
+ const sessionId = 'sess-ultragoal-restart';
+ const sessionStateDir = join(stateDir, 'sessions', sessionId);
+ await mkdir(sessionStateDir, { recursive: true });
+ await writeJson(join(sessionStateDir, 'ultragoal-state.json'), {
+ mode: 'ultragoal',
+ active: false,
+ current_phase: 'complete',
+ completed_at: '2026-07-30T00:06:49.168Z',
+ session_id: sessionId,
+ });
+ await writeJson(join(stateDir, 'native-stop-state.json'), {
+ sessions: {
+ [sessionId]: {
+ ordinary_no_progress_guard: {
+ last_turn_id: 'turn-ultragoal-complete',
+ },
+ },
+ },
+ });
+
+ let writerCalls = 0;
+ const result = await recordNotifySkillActivation({
+ stateDir,
+ sourceCwd: cwd,
+ text: '$ultragoal Запусти следующую задачу.',
+ sessionId,
+ threadId: 'thread-ultragoal-complete',
+ turnId: 'turn-ultragoal-restart',
+ payload: {
+ type: 'agent-turn-complete',
+ 'thread-id': 'thread-ultragoal-complete',
+ 'turn-id': 'turn-ultragoal-restart',
+ 'last-assistant-message': 'Starting the next Ultragoal run.',
+ },
+ }, {
+ recordSkillActivation: async () => {
+ writerCalls += 1;
+ return null;
+ },
+ });
+
+ assert.equal(result, null);
+ assert.equal(writerCalls, 1, 'a different turn must not be mistaken for terminal replay');
+ });
+ });
+
it('fails a later fresh autopilot prompt after completed autopilot state when receipt verification is unavailable', async () => {
await withTempWorkingDir(async (cwd) => {
const omxDir = join(cwd, '.omx');
diff --git a/src/mcp/__tests__/state-paths.test.ts b/src/mcp/__tests__/state-paths.test.ts
index cd01715c..863a644b 100644
--- a/src/mcp/__tests__/state-paths.test.ts
+++ b/src/mcp/__tests__/state-paths.test.ts
@@ -43,7 +43,9 @@ const isolatedEnvKeys = [
'OMX_ROOT',
'OMX_STATE_ROOT',
'OMX_TEAM_STATE_ROOT',
+ 'OMX_TEAM_WORKER',
'OMX_SESSION_ID',
+ 'CODEX_THREAD_ID',
'CODEX_SESSION_ID',
'SESSION_ID',
'TMUX',
@@ -1063,6 +1065,144 @@ describe('state paths', () => {
await rm(wd, { recursive: true, force: true });
}
});
+ it('recovers an App-native identity-indeterminate pointer from an exact host CODEX_THREAD_ID', async () => {
+ const wd = await mkRealTemp('omx-writable-indeterminate-codex-root-');
+ __setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
+ try {
+ const stateDir = getBaseStateDir(wd);
+ const sessionId = '019faf7d-ffbb-70d2-b58f-9bb83e752007';
+ const nativeRootId = sessionId;
+ await mkdir(stateDir, { recursive: true });
+ const pointerBody = JSON.stringify({
+ session_id: sessionId,
+ native_session_id: nativeRootId,
+ cwd: wd,
+ pid: 8388607,
+ });
+ await writeFile(join(stateDir, 'session.json'), pointerBody);
+ process.env.CODEX_THREAD_ID = nativeRootId;
+
+ await assert.rejects(
+ () => resolveWritableStateScope(wd),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ );
+ await assert.rejects(
+ () => resolveWritableStateScope(wd, undefined, { nativeUltragoalBackend: 'host' }),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ );
+ assert.deepEqual(await resolveWritableStateScope(wd, undefined, {
+ nativeUltragoalBackend: 'local-experimental',
+ }), {
+ source: 'session',
+ sessionId,
+ stateDir: join(stateDir, 'sessions', sessionId),
+ });
+ assert.equal(await readFile(join(stateDir, 'session.json'), 'utf8'), pointerBody);
+ } finally {
+ __resetSessionPointerTransactionDependenciesForTests();
+ await rm(wd, { recursive: true, force: true });
+ }
+ });
+
+ it('uses session_id as the App-native root only when native_session_id is absent', async () => {
+ const wd = await mkRealTemp('omx-writable-indeterminate-codex-session-');
+ __setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
+ try {
+ const stateDir = getBaseStateDir(wd);
+ const sessionId = '019faf7e-0002-7000-8000-000000000002';
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), JSON.stringify({
+ session_id: sessionId,
+ cwd: wd,
+ pid: 8388607,
+ }));
+ process.env.CODEX_THREAD_ID = sessionId;
+ assert.equal((await resolveWritableStateScope(wd, undefined, {
+ nativeUltragoalBackend: 'local-experimental',
+ })).sessionId, sessionId);
+
+ await writeFile(join(stateDir, 'session.json'), JSON.stringify({
+ session_id: sessionId,
+ native_session_id: '',
+ cwd: wd,
+ pid: 8388607,
+ }));
+ await assert.rejects(
+ () => resolveWritableStateScope(wd, undefined, { nativeUltragoalBackend: 'local-experimental' }),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ );
+ } finally {
+ __resetSessionPointerTransactionDependenciesForTests();
+ await rm(wd, { recursive: true, force: true });
+ }
+ });
+
+ it('rejects child, malformed, conflicting, override, and non-exact-cwd native claims', async () => {
+ const wd = await mkRealTemp('omx-writable-indeterminate-codex-deny-');
+ __setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
+ try {
+ const stateDir = getBaseStateDir(wd);
+ const sessionId = '019faf7e-0003-7000-8000-000000000003';
+ const nativeRootId = sessionId;
+ const childId = '019faf7e-0005-7000-8000-000000000005';
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), JSON.stringify({
+ session_id: sessionId,
+ native_session_id: nativeRootId,
+ cwd: wd,
+ pid: 8388607,
+ }));
+
+ for (const claim of [childId, 'not-a-uuid', nativeRootId.toUpperCase()]) {
+ process.env.CODEX_THREAD_ID = claim;
+ await assert.rejects(
+ () => resolveWritableStateScope(wd, undefined, { nativeUltragoalBackend: 'local-experimental' }),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ claim,
+ );
+ }
+
+ process.env.CODEX_THREAD_ID = nativeRootId;
+ process.env.OMX_SESSION_ID = childId;
+ await assert.rejects(
+ () => resolveWritableStateScope(wd, undefined, { nativeUltragoalBackend: 'local-experimental' }),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ );
+ delete process.env.OMX_SESSION_ID;
+
+ process.env.OMX_ROOT = wd;
+ await assert.rejects(
+ () => resolveWritableStateScope(wd, undefined, { nativeUltragoalBackend: 'local-experimental' }),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ );
+ delete process.env.OMX_ROOT;
+
+ process.env.OMX_TEAM_WORKER = 'team/worker-1';
+ await assert.rejects(
+ () => resolveWritableStateScope(wd, undefined, { nativeUltragoalBackend: 'local-experimental' }),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ );
+ delete process.env.OMX_TEAM_WORKER;
+
+ const nested = join(wd, 'nested');
+ const nestedStateDir = join(nested, '.omx', 'state');
+ await mkdir(nestedStateDir, { recursive: true });
+ await writeFile(join(nestedStateDir, 'session.json'), JSON.stringify({
+ session_id: sessionId,
+ native_session_id: nativeRootId,
+ cwd: wd,
+ state_root: nestedStateDir,
+ pid: 8388607,
+ }));
+ await assert.rejects(
+ () => resolveWritableStateScope(nested, undefined, { nativeUltragoalBackend: 'local-experimental' }),
+ (error: unknown) => (error as Error).message === WRITABLE_STATE_SCOPE_ERRORS.unusableSession,
+ );
+ } finally {
+ __resetSessionPointerTransactionDependenciesForTests();
+ await rm(wd, { recursive: true, force: true });
+ }
+ });
it('fails closed for an identity-indeterminate pointer even with an env binding', async () => {
const wd = await mkRealTemp('omx-writable-indeterminate-env-');
__setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
@@ -1194,21 +1334,22 @@ describe('writable state scope recovery and revalidation', () => {
const stateDir = getBaseStateDir(wd);
const sessionPath = join(stateDir, 'session.json');
await mkdir(stateDir, { recursive: true });
- await writeFile(sessionPath, JSON.stringify({ session_id: 'sess-indeterminate', cwd: wd, pid: 8388607 }));
- process.env.OMX_SESSION_ID = 'sess-indeterminate';
+ const sessionId = '019faf7e-0006-7000-8000-000000000006';
+ await writeFile(sessionPath, JSON.stringify({ session_id: sessionId, native_session_id: sessionId, cwd: wd, pid: 8388607 }));
+ process.env.CODEX_THREAD_ID = sessionId;
__setWritableStateScopeTestHooksForTests({
beforeRecoveryReread: async () => {
- await writeFile(sessionPath, JSON.stringify({ session_id: 'sess-indeterminate', cwd: wd, pid: 9999999 }));
+ await writeFile(sessionPath, JSON.stringify({ session_id: sessionId, native_session_id: sessionId, cwd: wd, pid: 9999999 }));
},
});
await assert.rejects(
- () => resolveWritableStateScope(wd),
+ () => resolveWritableStateScope(wd, undefined, { nativeUltragoalBackend: 'local-experimental' }),
(error: unknown) => {
assert.equal((error as Error).message, WRITABLE_STATE_SCOPE_ERRORS.unusableSession);
return true;
},
);
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-indeterminate')), false);
+ assert.equal(existsSync(join(stateDir, 'sessions', sessionId)), false);
} finally {
__setWritableStateScopeTestHooksForTests({});
__resetSessionPointerTransactionDependenciesForTests();
diff --git a/src/mcp/state-paths.ts b/src/mcp/state-paths.ts
index 1e0c6395..94d9205c 100644
--- a/src/mcp/state-paths.ts
+++ b/src/mcp/state-paths.ts
@@ -17,6 +17,8 @@ const OMX_ROOT_ENV = 'OMX_ROOT';
const OMX_STATE_ROOT_ENV = 'OMX_STATE_ROOT';
const OMX_TEAM_STATE_ROOT_ENV = 'OMX_TEAM_STATE_ROOT';
const OMX_SESSION_ID_ENV = 'OMX_SESSION_ID';
+const CODEX_THREAD_ID_ENV = 'CODEX_THREAD_ID';
+const CANONICAL_CODEX_THREAD_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
export const WRITABLE_STATE_SCOPE_ERRORS = {
unusableSession: 'Cannot resolve writable state scope: session.json is present but unusable.',
@@ -595,6 +597,10 @@ export interface WritableStateScopeTestHooks {
onRecoveryStabilityReread?: (event: Readonly<{ ordinal: number; raw: string | undefined }>) => void;
}
+export interface WritableStateScopeOptions {
+ nativeUltragoalBackend?: 'off' | 'host' | 'local-experimental';
+}
+
let selectedPointerRecoveryHookForTests: (() => Promise<void>) | undefined;
let writableScopeRevalidationHookForTests: WritableStateScopeTestHooks['beforeScopeRevalidation'];
let selectedDecisionSnapshotReadHookForTests: WritableStateScopeTestHooks['onSelectedDecisionSnapshotRead'];
@@ -625,6 +631,7 @@ export function __setWritableStateScopeTestHooksForTests(hooks: WritableStateSco
export async function resolveWritableStateScope(
workingDirectory?: string,
explicitSessionId?: string,
+ options: WritableStateScopeOptions = {},
): Promise<ResolvedStateScope> {
const cwd = resolveWorkingDirectoryForState(workingDirectory);
const baseStateDir = getBaseStateDir(cwd);
@@ -656,13 +663,55 @@ export async function resolveWritableStateScope(
raw: snapshot.raw,
});
}
- if (snapshot && envSessionId) {
+ if (snapshot) {
const canonicalPointerSessionId = normalizeSessionId(snapshot.state.session_id);
+ const rawOmxSessionId = process.env[OMX_SESSION_ID_ENV];
+ const explicitOmxSessionIdPresent = typeof rawOmxSessionId === 'string' && rawOmxSessionId.trim() !== '';
+ const outsideTmux = !(process.env.TMUX?.trim());
+ const rawCodexThreadId = process.env[CODEX_THREAD_ID_ENV];
+ const codexThreadClaimPresent = typeof rawCodexThreadId === 'string' && rawCodexThreadId.trim() !== '';
+ const codexThreadId = typeof rawCodexThreadId === 'string'
+ && CANONICAL_CODEX_THREAD_ID_PATTERN.test(rawCodexThreadId.trim())
+ ? rawCodexThreadId.trim()
+ : undefined;
+ const pointerSessionIsCanonicalCodexThread = typeof snapshot.state.session_id === 'string'
+ && CANONICAL_CODEX_THREAD_ID_PATTERN.test(snapshot.state.session_id.trim());
+ const pointerHasNativeSessionId = Object.prototype.hasOwnProperty.call(snapshot.state, 'native_session_id');
+ const nativeRootThreadId = pointerHasNativeSessionId
+ ? (typeof snapshot.state.native_session_id === 'string'
+ && snapshot.state.native_session_id.trim() === canonicalPointerSessionId
+ ? snapshot.state.native_session_id.trim()
+ : undefined)
+ : canonicalPointerSessionId;
+ const hasStateRootOverride = [OMX_TEAM_STATE_ROOT_ENV, OMX_ROOT_ENV, OMX_STATE_ROOT_ENV]
+ .some((key) => typeof process.env[key] === 'string' && process.env[key]!.trim() !== '');
+ const exactCodexNativeRecovery = Boolean(
+ liveness === 'identity-indeterminate'
+ && options.nativeUltragoalBackend === 'local-experimental'
+ && outsideTmux
+ && !(process.env.OMX_TEAM_WORKER?.trim())
+ && codexThreadClaimPresent
+ && codexThreadId
+ && nativeRootThreadId
+ && canonicalPointerSessionId
+ && pointerSessionIsCanonicalCodexThread
+ && codexThreadId === canonicalPointerSessionId
+ && nativeRootThreadId === canonicalPointerSessionId
+ && canonicalizeExistingPath(resolvePath(cwd)) === snapshot.recordedCwd
+ && !hasStateRootOverride
+ && (!explicitOmxSessionIdPresent || envSessionId === canonicalPointerSessionId),
+ );
+ const exactLegacyIndeterminateRecovery = Boolean(
+ liveness === 'identity-indeterminate'
+ && envSessionId === canonicalPointerSessionId
+ && (!outsideTmux || !codexThreadClaimPresent),
+ );
const recoveryEligible = Boolean(
canonicalPointerSessionId
&& (
- liveness === 'stale-dead'
- || (liveness === 'identity-indeterminate' && envSessionId === canonicalPointerSessionId)
+ (liveness === 'stale-dead' && envSessionId)
+ || exactLegacyIndeterminateRecovery
+ || exactCodexNativeRecovery
),
);
if (recoveryEligible) {
@@ -678,10 +727,14 @@ export async function resolveWritableStateScope(
});
}
if (reread === snapshot.raw) {
+ const recoveredSessionId = exactCodexNativeRecovery
+ ? canonicalPointerSessionId
+ : envSessionId;
+ if (!recoveredSessionId) throw new Error(WRITABLE_STATE_SCOPE_ERRORS.unusableSession);
return {
source: 'session',
- sessionId: envSessionId,
- stateDir: join(baseStateDir, 'sessions', envSessionId),
+ sessionId: recoveredSessionId,
+ stateDir: join(baseStateDir, 'sessions', recoveredSessionId),
};
}
}
diff --git a/src/scripts/__tests__/codex-native-assignment.test.ts b/src/scripts/__tests__/codex-native-assignment.test.ts
new file mode 100644
index 00000000..20c579dd
--- /dev/null
+++ b/src/scripts/__tests__/codex-native-assignment.test.ts
@@ -0,0 +1,461 @@
+import assert from "node:assert/strict";
+import { chmod, mkdir, mkdtemp, rm, symlink, writeFile } from "node:fs/promises";
+import { tmpdir } from "node:os";
+import { dirname, join, resolve } from "node:path";
+import { afterEach, beforeEach, describe, it } from "node:test";
+import { dispatchCodexNativeHook } from "../codex-native-hook.js";
+
+async function writeJson(path: string, value: unknown): Promise<void> {
+ await mkdir(dirname(path), { recursive: true });
+ await writeFile(path, `${JSON.stringify(value, null, 2)}\n`, "utf-8");
+}
+
+async function createActiveConductorFixture(phase = "executing"): Promise<{
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ leaderThreadId: string;
+ childAgentId: string;
+}> {
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-assignment-"));
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-native-assignment";
+ const leaderThreadId = "thread-native-assignment-leader";
+ const childAgentId = "agent-native-assignment-executor";
+ const now = new Date().toISOString();
+ const bootstrapGeneration = "bootstrap-generation-native-assignment";
+
+ await writeJson(join(stateDir, "session.json"), {
+ session_id: sessionId,
+ native_session_id: leaderThreadId,
+ cwd,
+ });
+ await writeJson(join(stateDir, "subagent-tracking.json"), {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: leaderThreadId,
+ updated_at: now,
+ threads: {
+ [leaderThreadId]: {
+ thread_id: leaderThreadId,
+ kind: "leader",
+ first_seen_at: now,
+ last_seen_at: now,
+ turn_count: 1,
+ },
+ [childAgentId]: {
+ thread_id: childAgentId,
+ kind: "subagent",
+ mode: "executor",
+ status: "available",
+ provenance_kind: "native_subagent",
+ direct_child_parent_id: leaderThreadId,
+ direct_child_root_id: leaderThreadId,
+ leader_thread_id: leaderThreadId,
+ first_seen_at: now,
+ last_seen_at: now,
+ turn_count: 1,
+ },
+ },
+ },
+ },
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ active: true,
+ skill: "ultragoal",
+ phase,
+ session_id: sessionId,
+ active_skills: [
+ { skill: "ultragoal", phase, active: true, session_id: sessionId },
+ ],
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ active: true,
+ mode: "ultragoal",
+ current_phase: phase,
+ session_id: sessionId,
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "native-ultragoal-bootstrap.json"), {
+ schema_version: 1,
+ kind: "native-ultragoal-bootstrap",
+ generation: bootstrapGeneration,
+ backend: "local-experimental",
+ status: "active",
+ session_id: sessionId,
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ created_at: now,
+ updated_at: now,
+ expires_at: new Date(Date.now() + 10 * 60_000).toISOString(),
+ });
+
+ return { cwd, stateDir, sessionId, leaderThreadId, childAgentId };
+}
+
+function preToolUse(
+ cwd: string,
+ sessionId: string,
+ identity: Record<string, unknown>,
+ toolName: string,
+ toolInput: Record<string, unknown>,
+) {
+ return dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ ...identity,
+ tool_name: toolName,
+ tool_input: toolInput,
+ }, { cwd });
+}
+
+describe("native Conductor assignment transport", () => {
+ const originalAssignmentOptIn = process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS;
+
+ beforeEach(() => {
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ });
+
+ afterEach(() => {
+ if (originalAssignmentOptIn === undefined) delete process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS;
+ else process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = originalAssignmentOptIn;
+ });
+
+ it("requires typed tracker authority and rejects missing or conflicting role evidence", async () => {
+ const fixture = await createActiveConductorFixture();
+ const { cwd, stateDir, sessionId, leaderThreadId, childAgentId } = fixture;
+ const assignmentPath = join(
+ stateDir,
+ "sessions",
+ sessionId,
+ "native-assignments",
+ `${encodeURIComponent(childAgentId)}.json`,
+ );
+ const issuedAt = new Date();
+ const expiresAt = new Date(issuedAt.getTime() + 10 * 60_000);
+ const trackingPath = join(stateDir, "subagent-tracking.json");
+ const trackedChild = {
+ thread_id: childAgentId,
+ kind: "subagent",
+ leader_thread_id: leaderThreadId,
+ first_seen_at: issuedAt.toISOString(),
+ last_seen_at: issuedAt.toISOString(),
+ turn_count: 1,
+ };
+
+ try {
+ await writeJson(assignmentPath, {
+ schema_version: 1,
+ kind: "native-subagent-assignment",
+ lifecycle: "active",
+ root_session_id: sessionId,
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ agent_type: "executor",
+ allowed_actions: ["path-write"],
+ path_prefixes: ["src/assigned"],
+ issued_at: issuedAt.toISOString(),
+ expires_at: expiresAt.toISOString(),
+ bootstrap_generation: "bootstrap-generation-native-assignment",
+ });
+ await writeJson(trackingPath, {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: leaderThreadId,
+ updated_at: issuedAt.toISOString(),
+ threads: {
+ [leaderThreadId]: { thread_id: leaderThreadId, kind: "leader" },
+ [childAgentId]: trackedChild,
+ },
+ },
+ },
+ });
+
+ const realTypedChild = await preToolUse(
+ cwd,
+ sessionId,
+ { agent_id: childAgentId, agent_type: "executor" },
+ "Write",
+ { file_path: "src/assigned/real-typed-child.txt", content: "ok\n" },
+ );
+ assert.equal(realTypedChild.outputJson?.decision, "block");
+ assert.match(String(realTypedChild.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+
+ const missingTypedRole = await preToolUse(
+ cwd,
+ sessionId,
+ {
+ agent_id: childAgentId,
+ source: { subagent: { thread_spawn: { agent_role: "executor" } } },
+ },
+ "Write",
+ { file_path: "src/assigned/missing-role.txt", content: "must-not-write\n" },
+ );
+ assert.equal(missingTypedRole.outputJson?.decision, "block");
+ assert.match(String(missingTypedRole.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+
+ const conflictingTypedAliases = await preToolUse(
+ cwd,
+ sessionId,
+ { agent_id: childAgentId, agent_role: "executor", agent_type: "writer" },
+ "Write",
+ { file_path: "src/assigned/conflicting-aliases.txt", content: "must-not-write\n" },
+ );
+ assert.equal(conflictingTypedAliases.outputJson?.decision, "block");
+ assert.match(String(conflictingTypedAliases.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+
+ await writeJson(trackingPath, {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: leaderThreadId,
+ updated_at: issuedAt.toISOString(),
+ threads: {
+ [leaderThreadId]: { thread_id: leaderThreadId, kind: "leader" },
+ [childAgentId]: { ...trackedChild, mode: "writer" },
+ },
+ },
+ },
+ });
+ const conflictingTrackerRole = await preToolUse(
+ cwd,
+ sessionId,
+ { agent_id: childAgentId, agent_role: "executor" },
+ "Write",
+ { file_path: "src/assigned/conflicting-role.txt", content: "must-not-write\n" },
+ );
+ assert.equal(conflictingTrackerRole.outputJson?.decision, "block");
+ assert.match(String(conflictingTrackerRole.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("allows only an exact live typed-child path grant and keeps all negative contracts fail-closed", async () => {
+ const fixture = await createActiveConductorFixture();
+ const { cwd, stateDir, sessionId, leaderThreadId, childAgentId } = fixture;
+ const assignmentPath = join(
+ stateDir,
+ "sessions",
+ sessionId,
+ "native-assignments",
+ `${encodeURIComponent(childAgentId)}.json`,
+ );
+ const issuedAt = new Date();
+ const expiresAt = new Date(issuedAt.getTime() + 10 * 60_000);
+
+ try {
+ await writeJson(assignmentPath, {
+ schema_version: 1,
+ kind: "native-subagent-assignment",
+ lifecycle: "active",
+ root_session_id: sessionId,
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ agent_type: "executor",
+ allowed_actions: ["path-write"],
+ path_prefixes: ["src/assigned"],
+ issued_at: issuedAt.toISOString(),
+ expires_at: expiresAt.toISOString(),
+ bootstrap_generation: "bootstrap-generation-native-assignment",
+ });
+
+ const exactChild = { agent_id: childAgentId, agent_role: "executor" };
+ const allowed = await preToolUse(
+ cwd,
+ sessionId,
+ exactChild,
+ "Write",
+ { file_path: "src/assigned/result.txt", content: "ok\n" },
+ );
+ assert.equal(allowed.outputJson, null);
+
+ for (const [name, identity, filePath] of [
+ ["outside-scope", exactChild, "src/outside.txt"],
+ ["assignment-self-mutation", exactChild, assignmentPath],
+ ["foreign-child", { agent_id: "agent-native-assignment-foreign", agent_role: "executor" }, "src/assigned/result.txt"],
+ ["role-mismatch", { agent_id: childAgentId, agent_role: "writer" }, "src/assigned/result.txt"],
+ ["ungranted-writer", { agent_id: "agent-native-assignment-writer", agent_role: "writer" }, "src/assigned/result.txt"],
+ ] as const) {
+ const denied = await preToolUse(
+ cwd,
+ sessionId,
+ identity,
+ "Write",
+ { file_path: filePath, content: `${name}\n` },
+ );
+ assert.equal(denied.outputJson?.decision, "block", name);
+ assert.match(String(denied.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/, name);
+ }
+
+ await writeJson(assignmentPath, {
+ schema_version: 1,
+ kind: "native-subagent-assignment",
+ lifecycle: "active",
+ root_session_id: "foreign-session",
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ agent_type: "executor",
+ allowed_actions: ["path-write"],
+ path_prefixes: ["src/assigned"],
+ issued_at: issuedAt.toISOString(),
+ expires_at: expiresAt.toISOString(),
+ bootstrap_generation: "bootstrap-generation-native-assignment",
+ unexpected_scope_expansion: true,
+ });
+ const malformed = await preToolUse(
+ cwd,
+ sessionId,
+ exactChild,
+ "Write",
+ { file_path: "src/assigned/malformed.txt", content: "malformed\n" },
+ );
+ assert.equal(malformed.outputJson?.decision, "block");
+ assert.match(String(malformed.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+
+ await mkdir(join(cwd, "src", "assigned"), { recursive: true });
+ const escapedTarget = await mkdtemp(join(tmpdir(), "omx-native-assignment-escape-"));
+ await symlink(escapedTarget, join(cwd, "src", "assigned", "link"));
+ await writeJson(assignmentPath, {
+ schema_version: 1,
+ kind: "native-subagent-assignment",
+ lifecycle: "active",
+ root_session_id: sessionId,
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ agent_type: "executor",
+ allowed_actions: ["path-write", "bash-write"],
+ path_prefixes: ["src/assigned"],
+ issued_at: issuedAt.toISOString(),
+ expires_at: expiresAt.toISOString(),
+ bootstrap_generation: "bootstrap-generation-native-assignment",
+ });
+ const allowedBash = await preToolUse(
+ cwd,
+ sessionId,
+ exactChild,
+ "Bash",
+ { command: "printf ok > src/assigned/bash.txt" },
+ );
+ assert.equal(allowedBash.outputJson, null);
+ for (const [name, command] of [
+ ["bash-outside-scope", "printf no > src/outside-bash.txt"],
+ ["bash-symlink-escape", "printf no > src/assigned/link/escaped.txt"],
+ ["bash-substitution-poison", "printf \"$(printf no)\" > src/assigned/poison.txt"],
+ ] as const) {
+ const denied = await preToolUse(cwd, sessionId, exactChild, "Bash", { command });
+ assert.equal(denied.outputJson?.decision, "block", name);
+ assert.match(String(denied.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/, name);
+ }
+ await rm(escapedTarget, { recursive: true, force: true });
+
+ await writeJson(assignmentPath, {
+ schema_version: 1,
+ kind: "native-subagent-assignment",
+ lifecycle: "active",
+ root_session_id: sessionId,
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ agent_type: "executor",
+ allowed_actions: ["path-write"],
+ path_prefixes: ["src/assigned"],
+ issued_at: new Date(issuedAt.getTime() - 20 * 60_000).toISOString(),
+ expires_at: new Date(issuedAt.getTime() - 10 * 60_000).toISOString(),
+ });
+ const stale = await preToolUse(
+ cwd,
+ sessionId,
+ exactChild,
+ "Write",
+ { file_path: "src/assigned/stale.txt", content: "stale\n" },
+ );
+ assert.equal(stale.outputJson?.decision, "block");
+ assert.match(String(stale.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+
+ await writeJson(assignmentPath, {
+ schema_version: 1,
+ kind: "native-subagent-assignment",
+ lifecycle: "active",
+ root_session_id: sessionId,
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ agent_type: "executor",
+ allowed_actions: ["path-write", "bash-write"],
+ path_prefixes: ["."],
+ issued_at: issuedAt.toISOString(),
+ expires_at: expiresAt.toISOString(),
+ bootstrap_generation: "bootstrap-generation-native-assignment",
+ });
+ for (const [name, toolName, toolInput] of [
+ ["git-path", "Write", { file_path: ".git/config", content: "must-not-write\n" }],
+ ["omx-goal-path", "Write", { file_path: ".omx/ultragoal/goals.json", content: "{}\n" }],
+ ["git-bash", "Bash", { command: "printf no > .git/config" }],
+ ["omx-goal-bash", "Bash", { command: "printf no > .omx/ultragoal/goals.json" }],
+ ] as const) {
+ const denied = await preToolUse(cwd, sessionId, exactChild, toolName, toolInput);
+ assert.equal(denied.outputJson?.decision, "block", name);
+ assert.match(String(denied.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/, name);
+ }
+
+ await writeJson(assignmentPath, {
+ schema_version: 1,
+ kind: "native-subagent-assignment",
+ lifecycle: "active",
+ root_session_id: sessionId,
+ root_thread_id: leaderThreadId,
+ child_agent_id: childAgentId,
+ agent_type: "executor",
+ allowed_actions: ["path-write"],
+ path_prefixes: ["src/assigned"],
+ issued_at: issuedAt.toISOString(),
+ expires_at: expiresAt.toISOString(),
+ });
+ await chmod(assignmentPath, 0o666);
+ const writableByOthers = await preToolUse(
+ cwd,
+ sessionId,
+ exactChild,
+ "Write",
+ { file_path: "src/assigned/world-writable-grant.txt", content: "must-not-write\n" },
+ );
+ assert.equal(writableByOthers.outputJson?.decision, "block");
+ assert.match(String(writableByOthers.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("allows only Main-root to issue an assignment in the exact active session scope", async () => {
+ const fixture = await createActiveConductorFixture();
+ const { cwd, sessionId, leaderThreadId } = fixture;
+
+ try {
+ const root = { agent_id: leaderThreadId, thread_id: leaderThreadId };
+
+ const rootAssignment = await preToolUse(cwd, sessionId, root, "Write", {
+ file_path: `.omx/state/sessions/${sessionId}/native-assignments/root-created.json`,
+ content: "{}\n",
+ });
+ assert.equal(rootAssignment.outputJson, null, "root-assignment-create");
+ const foreignSessionAssignment = await preToolUse(cwd, sessionId, root, "Write", {
+ file_path: ".omx/state/sessions/foreign-session/native-assignments/root-created.json",
+ content: "{}\n",
+ });
+ assert.equal(foreignSessionAssignment.outputJson?.decision, "block", "foreign-session-assignment");
+ const protectedGate = await preToolUse(cwd, sessionId, root, "Write", {
+ file_path: `.omx/state/sessions/${sessionId}/ultragoal-state.json`,
+ content: "{}\n",
+ });
+ assert.equal(protectedGate.outputJson?.decision, "block", "protected-state-gate");
+
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+});
diff --git a/src/scripts/__tests__/codex-native-hook.test.ts b/src/scripts/__tests__/codex-native-hook.test.ts
index 59ae97fc..13d782dc 100644
--- a/src/scripts/__tests__/codex-native-hook.test.ts
+++ b/src/scripts/__tests__/codex-native-hook.test.ts
@@ -33684,6 +33684,125 @@ PY`,
}
});
+ it("allows only exact leader-owned Ultragoal metadata CLI commands", async () => withCleanAmbientNodeRuntimeEnvironment(async () => {
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-ultragoal-leader-metadata-"));
+ const originalPath = process.env.PATH;
+ const originalOmxEnvironment = Object.fromEntries(
+ Object.entries(process.env).filter(([name]) => /^(?:OMX|GJC)_/.test(name)),
+ );
+ try {
+ for (const name of Object.keys(process.env)) {
+ if (/^(?:OMX|GJC)_/.test(name)) delete process.env[name];
+ }
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-ultragoal-leader-metadata";
+ const leaderThreadId = "thread-ultragoal-leader-metadata";
+ await mkdir(join(stateDir, "sessions", sessionId), { recursive: true });
+ await writeCanonicalLeaderFixture(stateDir, sessionId, leaderThreadId, cwd);
+ await writeSessionSkillActiveState(stateDir, sessionId, "ultragoal", "planning");
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ active: true,
+ mode: "ultragoal",
+ current_phase: "planning",
+ session_id: sessionId,
+ });
+ const trustedPackageBin = join(cwd, "node_modules", ".bin", "omx");
+ await mkdir(dirname(trustedPackageBin), { recursive: true });
+ await symlink(realpathSync(resolve(process.cwd(), "dist", "cli", "omx.js")), trustedPackageBin);
+ const lookalikeOmx = join(cwd, "lookalike", "bin", "omx");
+ await mkdir(dirname(lookalikeOmx), { recursive: true });
+ await writeFile(lookalikeOmx, "#!/bin/sh\nexit 0\n", "utf-8");
+ await chmod(lookalikeOmx, 0o755);
+ process.env.PATH = `${dirname(trustedPackageBin)}:${dirname(process.execPath)}:/usr/bin:/bin`;
+ process.env.OMX_ROOT = cwd;
+
+ const dispatchBash = (command: string, child = false) => dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: child ? "thread-ultragoal-metadata-child" : leaderThreadId,
+ agent_id: child ? "thread-ultragoal-metadata-child" : leaderThreadId,
+ ...(child ? { agent_role: "executor" } : {}),
+ tool_name: "Bash",
+ tool_input: { command },
+ }, { cwd });
+
+ for (const command of [
+ "omx ultragoal create-goals --brief 'Ship the scoped change' --goal 'Implement::Make the change' --goal 'Verify::Run tests' --codex-goal-mode per-story --json",
+ `${trustedPackageBin} ultragoal create-goals --brief 'Ship the scoped change through the installed CLI' --json`,
+ "omx ultragoal create --brief='Ship the scoped change' --json",
+ "omx ultragoal complete-goals --retry-failed --json",
+ "omx ultragoal complete --json",
+ "omx ultragoal next",
+ "omx ultragoal start-next --retry-failed",
+ "omx ultragoal status --codex-goal-json .omx/ultragoal/codex-goal.json --json",
+ "omx ultragoal steer --kind annotate_ledger --evidence 'executor and verification completed' --rationale 'make completed chronology durable before review' --json",
+ "omx ultragoal steer --kind=annotate_ledger --target-goal-id G001-safe --evidence 'executor and verification completed' --rationale 'make completed chronology durable before review' --json",
+ 'omx ultragoal steer --kind annotate_ledger --evidence "planning activated; stdout UTF-8 JSON string was ?? prompt.txt followed by newline; exit code was 0" --rationale "make evidence durable before review" --json',
+ 'omx ultragoal steer --kind annotate_ledger --evidence "stdout UTF-8 JSON string \\"?? prompt.txt\\\\n\\" with exit code 0" --rationale "make evidence durable before review" --json',
+ "omx ultragoal checkpoint --goal-id G001-safe --status complete --evidence 'tests and reviews passed' --codex-goal-json .omx/ultragoal/codex-goal.json --quality-gate-json .omx/ultragoal/quality-gate.json --json",
+ "omx ultragoal checkpoint --goal-id G001-safe --status failed --evidence 'executor command was blocked' --json",
+ ]) {
+ const result = await dispatchBash(command);
+ assert.equal(result.outputJson, null, command);
+ }
+
+ const child = await dispatchBash("omx ultragoal create-goals --brief 'Child must not create' --json", true);
+ assert.equal(child.outputJson?.decision, "block");
+ assert.match(String(child.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+
+ for (const command of [
+ "omx ultragoal create-goals --brief 'Forced overwrite' --force --json",
+ "omx ultragoal create-goals --brief-file plan.md --json",
+ "omx ultragoal create-goals positional-brief --json",
+ "omx ultragoal create-goals --brief 'Unknown option' --unknown --json",
+ "omx ultragoal create-goals --brief legit --goal --force --json",
+ "omx ultragoal create-goals --brief --force --json",
+ "omx ultragoal create-goals --brief legit --codex-goal-mode --force --json",
+ "omx ultragoal create-goals --brief \"$(touch src/pwned.ts)\" --json",
+ "omx ultragoal create-goals --brief 'Chained' --json; touch src/pwned.ts",
+ "PATH=/usr/bin:/bin omx ultragoal create-goals --brief 'Prefixed' --json",
+ "./omx ultragoal create-goals --brief 'Impostor' --json",
+ `${lookalikeOmx} ultragoal create-goals --brief 'Absolute impostor' --json`,
+ "omx ultragoal complete-goals --force --json",
+ "omx ultragoal complete-goals --retry-failed=1 --json",
+ "omx ultragoal status --codex-goal-json --json",
+ "omx ultragoal status --codex-goal-json $(touch src/pwned.ts) --json",
+ "omx ultragoal steer --kind add_subgoal --evidence evidence --rationale rationale --json",
+ "omx ultragoal steer --kind annotate_ledger --evidence evidence --json",
+ "omx ultragoal steer --kind annotate_ledger --evidence \"$(touch src/pwned.ts)\" --rationale rationale --json",
+ "omx ultragoal steer --kind annotate_ledger --evidence ?? --rationale rationale --json",
+ "omx ultragoal steer --kind annotate_ledger --evidence evidence --rationale rationale --json; touch src/pwned.ts",
+ "omx ultragoal checkpoint --goal-id G001-unsafe --status complete --evidence incomplete --codex-goal-json .omx/ultragoal/codex-goal.json --json",
+ "omx ultragoal checkpoint --goal-id G001-unsafe --status failed --evidence bad --quality-gate-json .omx/ultragoal/quality-gate.json --json",
+ "omx ultragoal checkpoint --goal-id G001-unsafe --status unexpected --evidence bad --json",
+ ]) {
+ const result = await dispatchBash(command);
+ assert.equal(result.outputJson?.decision, "block", command);
+ assert.match(String(result.outputJson?.reason ?? ""), /Main-root Conductor mode is active/, command);
+ }
+
+ const rawWrite = await dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: leaderThreadId,
+ agent_id: leaderThreadId,
+ tool_name: "Write",
+ tool_input: { file_path: "src/pwned.ts", content: "owned\n" },
+ }, { cwd });
+ assert.equal(rawWrite.outputJson?.decision, "block");
+ } finally {
+ for (const name of Object.keys(process.env)) {
+ if (/^(?:OMX|GJC)_/.test(name)) delete process.env[name];
+ }
+ Object.assign(process.env, originalOmxEnvironment);
+ if (originalPath === undefined) delete process.env.PATH;
+ else process.env.PATH = originalPath;
+ await rm(cwd, { recursive: true, force: true });
+ }
+ }));
+
it("allows the exact installed omx CLI by absolute path for Main-root read-only commands (#3333)", async () => {
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-absolute-cli-readonly-"));
const installRoot = await mkdtemp(join(tmpdir(), "omx-native-hook-user-install-"));
@@ -34391,7 +34510,7 @@ PY`,
assert.doesNotMatch(String(metadataBash.outputJson?.reason ?? ""), /Main-root/, command);
}
- const readOnlyBash = await dispatchCodexNativeHook(
+ const dispatchChildBash = (command: string) => dispatchCodexNativeHook(
{
hook_event_name: "PreToolUse",
cwd,
@@ -34399,11 +34518,36 @@ PY`,
thread_id: childThreadId,
agent_role: "executor",
tool_name: "Bash",
- tool_input: { command: "cat src/conductor-owned.ts" },
+ tool_input: { command },
},
{ cwd },
);
- assert.equal(readOnlyBash.outputJson, null);
+ const inheritedGitRuntime = Object.entries(process.env).filter(([name]) => (
+ name === "BASH_FUNC_git%%" || name.startsWith("GIT_")
+ ));
+ for (const [name] of inheritedGitRuntime) delete process.env[name];
+ try {
+ for (const command of [
+ "cat src/conductor-owned.ts",
+ "/usr/bin/sed -n '1,28{=;p;}' .omx/ultragoal/goals.json",
+ "/usr/bin/find .omx -type f -print",
+ "/usr/bin/find . -path ./.git -prune -o -path ./.omx -prune -o -type f -print",
+ "/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .",
+ ]) {
+ assert.equal((await dispatchChildBash(command)).outputJson, null, command);
+ }
+ for (const command of [
+ "rg --files -uu .omx",
+ "rg -n -i 'goal|review' .omx/ultragoal",
+ "sed -i '' -e 's/a/b/' prompt.txt",
+ "find .omx -type f -exec sh -c 'printf pwn > prompt.txt' \\;",
+ "/usr/bin/git --no-pager diff --no-ext-diff --no-textconv -- .; git reset --hard",
+ ]) {
+ assert.equal((await dispatchChildBash(command)).outputJson?.decision, "block", command);
+ }
+ } finally {
+ for (const [name, value] of inheritedGitRuntime) process.env[name] = value;
+ }
} finally {
if (originalOmxRoot === undefined) delete process.env.OMX_ROOT;
else process.env.OMX_ROOT = originalOmxRoot;
diff --git a/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts b/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts
index bc832ed9..8313fcdc 100644
--- a/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts
+++ b/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts
@@ -1,18 +1,32 @@
import assert from "node:assert/strict";
import { existsSync, readFileSync } from "node:fs";
-import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
+import { appendFile, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
-import { afterEach, describe, it } from "node:test";
-import { dispatchCodexNativeHook } from "../codex-native-hook.js";
+import { afterEach, beforeEach, describe, it } from "node:test";
+import {
+ __isAuthorizedActiveUltragoalPhaseTransitionFallbackForTests,
+ buildConductorPreToolUseWriteGuardOutput,
+ dispatchCodexNativeHook,
+} from "../codex-native-hook.js";
+import {
+ beginNativeUltragoalBootstrap,
+ findReadyLocalNativeExecutorAssignment,
+ issueLocalNativeExecutorAssignment,
+ markNativeUltragoalBootstrapActive,
+ prepareNativeUltragoalBootstrapActivation,
+ readNativeUltragoalBootstrap,
+ revokeLocalNativeExecutorAssignment,
+ validateLocalNativeExecutorIdentity,
+} from "../../ultragoal/native-bootstrap.js";
// Regression coverage for OMX #3311: on native Codex App / native-hook
// surfaces outside tmux, standalone Ultragoal must not activate an
// execution-blocking Main-root Conductor state when no authorized executor
-// will ever be reachable (Team is tmux-only; native child/descendant
-// provenance intentionally grants no write authority per #3127). The guard
-// under test refuses the *activation* write itself; it must never affect
-// already-active sessions, non-ultragoal modes, non-native launchers, or
+// will ever be reachable. Team is tmux-only; native child/descendant provenance
+// grants no write authority unless the root issues an exact scoped assignment.
+// The guard under test refuses the *activation* write itself; it must never
+// affect already-active sessions, non-ultragoal modes, non-native launchers, or
// attached-tmux transport.
async function writeJson(path: string, value: unknown): Promise<void> {
@@ -35,6 +49,8 @@ async function writeLeaderSessionFixture(
await writeJson(join(stateDir, "session.json"), {
session_id: sessionId,
native_session_id: leaderThreadId,
+ owner_codex_session_id: sessionId,
+ target_session_id: sessionId,
cwd,
});
await writeJson(join(stateDir, "subagent-tracking.json"), {
@@ -43,20 +59,89 @@ async function writeLeaderSessionFixture(
[sessionId]: {
session_id: sessionId,
leader_thread_id: leaderThreadId,
+ updated_at: "2026-07-29T16:54:54.000Z",
threads: {
- [leaderThreadId]: { thread_id: leaderThreadId, kind: "leader" },
+ [leaderThreadId]: {
+ thread_id: leaderThreadId,
+ kind: "leader",
+ first_seen_at: "2026-07-29T16:54:54.000Z",
+ last_seen_at: "2026-07-29T16:54:54.000Z",
+ turn_count: 1,
+ },
},
},
},
});
}
+function rootTranscriptRecord(
+ sessionId: string,
+ cwd: string,
+ turnId: string,
+ overrides: Record<string, unknown> = {},
+ turnOverrides: Record<string, unknown> = {},
+): string {
+ return `${JSON.stringify({
+ type: "session_meta",
+ payload: {
+ id: sessionId,
+ cwd,
+ thread_source: "user",
+ source: "vscode",
+ originator: "Codex Desktop",
+ dynamic_tools: [
+ { name: "codex_app" },
+ { name: "plugin_management" },
+ ],
+ ...overrides,
+ },
+ })}\n${JSON.stringify({
+ type: "turn_context",
+ payload: {
+ turn_id: turnId,
+ cwd,
+ collaboration_mode: { mode: "default", settings: { model: "gpt-5.6-sol" } },
+ multi_agent_mode: "explicitRequestOnly",
+ multi_agent_version: "v2",
+ ...turnOverrides,
+ },
+ })}\n`;
+}
+
+async function writeRootTranscript(codexHome: string, sessionId: string, content: string): Promise<string> {
+ const path = join(codexHome, "sessions", "2026", "07", "29", `rollout-2026-07-29T20-00-00-${sessionId}.jsonl`);
+ await mkdir(dirname(path), { recursive: true });
+ await writeFile(path, content);
+ return path;
+}
+
describe("issue-3311: standalone Ultragoal native-App outside-tmux activation guard", () => {
const originalTmux = process.env.TMUX;
+ const originalAssignmentOptIn = process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS;
+ const originalCodexHome = process.env.CODEX_HOME;
+ const originalBackend = process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ const originalCodexThreadId = process.env.CODEX_THREAD_ID;
+ const originalOmxSessionId = process.env.OMX_SESSION_ID;
+
+ beforeEach(() => {
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "off";
+ delete process.env.CODEX_THREAD_ID;
+ delete process.env.OMX_SESSION_ID;
+ });
afterEach(() => {
if (originalTmux === undefined) delete process.env.TMUX;
else process.env.TMUX = originalTmux;
+ if (originalAssignmentOptIn === undefined) delete process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS;
+ else process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = originalAssignmentOptIn;
+ if (originalCodexHome === undefined) delete process.env.CODEX_HOME;
+ else process.env.CODEX_HOME = originalCodexHome;
+ if (originalBackend === undefined) delete process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ else process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = originalBackend;
+ if (originalCodexThreadId === undefined) delete process.env.CODEX_THREAD_ID;
+ else process.env.CODEX_THREAD_ID = originalCodexThreadId;
+ if (originalOmxSessionId === undefined) delete process.env.OMX_SESSION_ID;
+ else process.env.OMX_SESSION_ID = originalOmxSessionId;
});
it("blocks fresh standalone-ultragoal Conductor activation on native App outside tmux (Bash state write)", async () => {
@@ -88,8 +173,73 @@ describe("issue-3311: standalone Ultragoal native-App outside-tmux activation gu
(result.outputJson as { hookSpecificOutput?: { additionalContext?: string } } | null)
?.hookSpecificOutput?.additionalContext || "",
);
- assert.match(context, /native child\/descendant provenance does not grant write authority/);
- assert.doesNotMatch(context, /write-assignment|assignment-backed|scoped native .*grant/i);
+ assert.match(context, /typed native spawn surface backed by scoped write assignments/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("keeps fresh activation inactive until the advertised executor is authorized", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3319-supported-bash-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-3319-supported-bash";
+ const leaderThreadId = "thread-3319-supported-bash";
+ await writeLeaderSessionFixture(stateDir, sessionId, leaderThreadId, cwd);
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: leaderThreadId,
+ agent_id: leaderThreadId,
+ source: "native",
+ available_tools: ["collaboration.spawn_agent"],
+ tool_name: "Bash",
+ tool_input: { command: `omx state write --input '${ACTIVATION_INPUT}' --json` },
+ },
+ { cwd },
+ );
+
+ assert.equal(result.outputJson?.decision, "block");
+ assert.match(String(result.outputJson?.reason ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("keeps fresh activation blocked when native subagents are advertised without typed role routing", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3319-untyped-bash-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-3319-untyped-bash";
+ const leaderThreadId = "thread-3319-untyped-bash";
+ await writeLeaderSessionFixture(stateDir, sessionId, leaderThreadId, cwd);
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: leaderThreadId,
+ agent_id: leaderThreadId,
+ source: "native",
+ capabilities: { native_subagents: true },
+ tool_name: "Bash",
+ tool_input: { command: `omx state write --input '${ACTIVATION_INPUT}' --json` },
+ },
+ { cwd },
+ );
+
+ assert.equal(result.outputJson?.decision, "block");
+ assert.match(String(result.outputJson?.reason ?? ""), /OMX-ULTRAGOAL-(?:NO-OWNER|BOOTSTRAP-REQUIRED)/);
} finally {
await rm(cwd, { recursive: true, force: true });
}
@@ -124,8 +274,7 @@ describe("issue-3311: standalone Ultragoal native-App outside-tmux activation gu
(result.outputJson as { hookSpecificOutput?: { additionalContext?: string } } | null)
?.hookSpecificOutput?.additionalContext || "",
);
- assert.match(context, /native child\/descendant provenance does not grant write authority/);
- assert.doesNotMatch(context, /write-assignment|assignment-backed|scoped native .*grant/i);
+ assert.match(context, /typed native spawn surface backed by scoped write assignments/);
} finally {
await rm(cwd, { recursive: true, force: true });
}
@@ -163,8 +312,7 @@ describe("issue-3311: standalone Ultragoal native-App outside-tmux activation gu
(result.outputJson as { hookSpecificOutput?: { additionalContext?: string } } | null)
?.hookSpecificOutput?.additionalContext || "",
);
- assert.match(context, /native child\/descendant provenance does not grant write authority/);
- assert.doesNotMatch(context, /write-assignment|assignment-backed|scoped native .*grant/i);
+ assert.match(context, /typed native spawn surface backed by scoped write assignments/);
} finally {
await rm(cwd, { recursive: true, force: true });
}
@@ -336,6 +484,130 @@ describe("issue-3311: standalone Ultragoal native-App outside-tmux activation gu
}
});
+ it("does not let a tracked native child authorize its own bootstrap assignment", async () => {
+ delete process.env.TMUX;
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-bootstrap-self-auth-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-bootstrap-self-auth";
+ const leaderThreadId = "thread-bootstrap-self-auth-root";
+ const childThreadId = "thread-bootstrap-self-auth-child";
+ await writeLeaderSessionFixture(stateDir, sessionId, leaderThreadId, cwd);
+ await writeJson(join(stateDir, "subagent-tracking.json"), {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: leaderThreadId,
+ threads: {
+ [leaderThreadId]: { thread_id: leaderThreadId, kind: "leader" },
+ [childThreadId]: {
+ thread_id: childThreadId,
+ kind: "subagent",
+ mode: "executor",
+ status: "available",
+ provenance_kind: "native_subagent",
+ direct_child_parent_id: leaderThreadId,
+ direct_child_root_id: leaderThreadId,
+ },
+ },
+ },
+ },
+ });
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: childThreadId,
+ agent_id: childThreadId,
+ agent_type: "executor",
+ source: "native",
+ tool_name: "Bash",
+ tool_input: {
+ command: `omx ultragoal native-bootstrap authorize --session-id ${sessionId} --root-thread-id ${leaderThreadId} --child-id ${childThreadId} --path-prefix src`,
+ },
+ },
+ { cwd },
+ );
+
+ assert.equal(result.outputJson?.decision, "block");
+ assert.match(String(result.outputJson?.reason ?? ""), /OWNER_CONFIRMATION_REQUIRED/);
+ assert.match(String(result.outputJson?.reason ?? ""), /root-owned/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("keeps the spawned executor read-only while the bootstrap is awaiting authorization", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-bootstrap-pending-child-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-bootstrap-pending-child";
+ const leaderThreadId = "thread-bootstrap-pending-root";
+ const childThreadId = "thread-bootstrap-pending-child";
+ await writeLeaderSessionFixture(stateDir, sessionId, leaderThreadId, cwd);
+ await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: leaderThreadId,
+ source: "native",
+ available_tools: ["collaboration.spawn_agent"],
+ prompt: "$ultragoal execute this plan",
+ },
+ { cwd },
+ );
+ await writeJson(join(stateDir, "subagent-tracking.json"), {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: leaderThreadId,
+ threads: {
+ [leaderThreadId]: { thread_id: leaderThreadId, kind: "leader" },
+ [childThreadId]: {
+ thread_id: childThreadId,
+ kind: "subagent",
+ mode: "executor",
+ status: "available",
+ provenance_kind: "native_subagent",
+ direct_child_parent_id: leaderThreadId,
+ direct_child_root_id: leaderThreadId,
+ },
+ },
+ },
+ },
+ });
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: childThreadId,
+ agent_id: childThreadId,
+ agent_type: "executor",
+ source: "native",
+ tool_name: "Write",
+ tool_input: { file_path: join(cwd, "src", "pending-write.ts"), content: "blocked" },
+ },
+ { cwd },
+ );
+
+ assert.equal(result.outputJson?.decision, "block");
+ assert.match(String(result.outputJson?.reason ?? ""), /bootstrap is not active/);
+ assert.match(String(result.outputJson?.reason ?? ""), /remain read-only/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
it("does not block autopilot-supervised ultragoal activation (mode is autopilot, not standalone ultragoal)", async () => {
delete process.env.TMUX;
const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-autopilot-"));
@@ -427,163 +699,1667 @@ describe("issue-3311: standalone Ultragoal native-App outside-tmux activation gu
}
});
- it("allows the primary '$ultragoal' UserPromptSubmit activation when attached to tmux (Team is reachable)", async () => {
- process.env.TMUX = "/tmp/tmux-3311-prompt,12345,0";
- const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-prompt-tmux-"));
+ it("keeps '$ultragoal' prompt activation inactive until the advertised executor is authorized", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3319-supported-prompt-"));
try {
await mkdir(join(cwd, ".omx", "state"), { recursive: true });
-
const result = await dispatchCodexNativeHook(
{
hook_event_name: "UserPromptSubmit",
cwd,
- session_id: "sess-3311-prompt-tmux",
- thread_id: "thread-3311-prompt-tmux",
- turn_id: "turn-3311-prompt-tmux",
+ session_id: "sess-3319-supported-prompt",
+ thread_id: "thread-3319-supported-prompt",
+ turn_id: "turn-3319-supported-prompt",
source: "native",
+ available_tools: ["collaboration.spawn_agent"],
prompt: "$ultragoal split this launch into durable goals",
},
{ cwd },
);
- assert.equal(result.skillState?.skill, "ultragoal");
- assert.equal(result.skillState?.initialized_mode, "ultragoal");
- assert.equal(result.skillState?.transition_error, undefined);
+ assert.notEqual(result.skillState?.initialized_mode, "ultragoal");
+ assert.match(String(result.skillState?.transition_error ?? result.outputJson?.reason ?? ""), /BOOTSTRAP|inactive|authorization/i);
assert.equal(
- existsSync(join(cwd, ".omx", "state", "sessions", "sess-3311-prompt-tmux", "ultragoal-state.json")),
- true,
+ existsSync(join(cwd, ".omx", "state", "sessions", "sess-3319-supported-prompt", "ultragoal-state.json")),
+ false,
);
} finally {
await rm(cwd, { recursive: true, force: true });
}
});
- it("does not re-block continuation of an already-active '$ultragoal' UserPromptSubmit session outside tmux", async () => {
+ it("recognizes the Codex App v2 multi-agent marker when tool inventory is omitted", async () => {
delete process.env.TMUX;
- const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-prompt-continue-"));
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-app-v2-prompt-"));
try {
const stateDir = join(cwd, ".omx", "state");
- const sessionId = "sess-3311-prompt-continue";
- const leaderThreadId = "thread-3311-prompt-continue";
- await writeLeaderSessionFixture(stateDir, sessionId, leaderThreadId, cwd);
- await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
- active: true,
- skill: "ultragoal",
- phase: "planning",
- session_id: sessionId,
- active_skills: [{ skill: "ultragoal", phase: "planning", active: true, session_id: sessionId }],
- });
- await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
- active: true,
- mode: "ultragoal",
- current_phase: "planning",
- session_id: sessionId,
- });
+ const sessionId = "sess-app-v2-prompt";
+ const rootThreadId = "thread-app-v2-root";
+ await writeLeaderSessionFixture(stateDir, sessionId, rootThreadId, cwd);
const result = await dispatchCodexNativeHook(
{
hook_event_name: "UserPromptSubmit",
cwd,
session_id: sessionId,
- thread_id: leaderThreadId,
- turn_id: "turn-3311-prompt-continue",
+ thread_id: rootThreadId,
source: "native",
- prompt: "$ultragoal continue with the next milestone",
+ multi_agent_mode: "explicitRequestOnly",
+ multi_agent_version: "v2",
+ prompt: "$ultragoal execute the durable plan",
},
{ cwd },
);
- assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-NO-OWNER/);
+ assert.equal(result.skillState?.active, false);
+ assert.match(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/);
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ assert.equal(bootstrap?.status, "awaiting-executor");
+ assert.equal(bootstrap?.root_thread_id, rootThreadId);
} finally {
await rm(cwd, { recursive: true, force: true });
}
});
- it("does not block the primary '$ultragoal' UserPromptSubmit activation from a non-native (CLI) launcher outside tmux", async () => {
+ it("uses an exact safe root transcript despite a competing live workspace pointer", async () => {
delete process.env.TMUX;
- const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-prompt-cli-"));
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-transcript-pointer-"));
try {
- await mkdir(join(cwd, ".omx", "state"), { recursive: true });
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "019f-root-transcript-session";
+ const turnId = "019f-root-transcript-turn";
+ const foreignSessionId = "019f-foreign-live-session";
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ await writeJson(join(stateDir, "session.json"), {
+ session_id: foreignSessionId,
+ native_session_id: foreignSessionId,
+ cwd,
+ pid: process.pid,
+ });
+ await writeJson(join(stateDir, "sessions", foreignSessionId, "skill-active-state.json"), {
+ version: 1,
+ active: false,
+ skill: "ultragoal",
+ phase: "complete",
+ session_id: foreignSessionId,
+ active_skills: [],
+ transition_error: "foreign terminal marker",
+ });
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(sessionId, cwd, turnId));
- const result = await dispatchCodexNativeHook(
- {
- hook_event_name: "UserPromptSubmit",
- cwd,
- session_id: "sess-3311-prompt-cli",
- thread_id: "thread-3311-prompt-cli",
- turn_id: "turn-3311-prompt-cli",
- source: "cli",
- prompt: "$ultragoal split this launch into durable goals",
- },
- { cwd },
- );
+ const prompt = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ prompt: "$ultragoal execute the durable plan",
+ }, { cwd });
- assert.equal(result.skillState?.initialized_mode, "ultragoal");
- assert.equal(result.skillState?.transition_error, undefined);
- } finally {
- await rm(cwd, { recursive: true, force: true });
- }
- });
+ assert.equal(prompt.skillState?.active, false);
+ assert.match(String(prompt.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/);
+ assert.doesNotMatch(JSON.stringify(prompt), /foreign terminal marker/);
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ assert.equal(bootstrap?.root_thread_id, sessionId);
+ assert.equal(bootstrap?.status, "awaiting-executor");
- // --- Autopilot-supervised child recognition must not be intercepted ---
- // #3311 repair-2: the prompt guard must refuse only a truly *standalone*
- // fresh Ultragoal activation. When Autopilot is already active and
- // supervising a child phase (e.g. ralplan), a "$ultragoal" prompt is a
- // supervised-child transition handled entirely by recordSkillActivation's
- // own isAutopilotSupervisedChildSkill branch; it must remain reachable on
- // native App outside tmux exactly as it was on the pre-#3311-fix baseline.
+ const bootstrapStatus = await dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ tool_name: "Bash",
+ tool_input: { command: "omx ultragoal native-bootstrap status --json" },
+ }, { cwd });
+ assert.equal(bootstrapStatus.outputJson, null);
- it("does not intercept Autopilot-supervised '$ultragoal' child-phase recognition on native App outside tmux", async () => {
- delete process.env.TMUX;
- const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-autopilot-supervised-"));
- try {
- const stateDir = join(cwd, ".omx", "state");
- const sessionId = "sess-3311-autopilot-supervised";
- const threadId = "thread-3311-autopilot-supervised";
- await mkdir(join(stateDir, "sessions", sessionId), { recursive: true });
await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ version: 1,
active: true,
- skill: "autopilot",
- phase: "ralplan",
+ skill: "ultragoal",
+ phase: "executing",
session_id: sessionId,
- active_skills: [{ skill: "autopilot", phase: "ralplan", active: true, session_id: sessionId }],
+ thread_id: sessionId,
+ active_skills: [{ skill: "ultragoal", active: true, phase: "executing", session_id: sessionId }],
});
- await writeJson(join(stateDir, "sessions", sessionId, "autopilot-state.json"), {
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
active: true,
- mode: "autopilot",
- current_phase: "ralplan",
+ mode: "ultragoal",
+ current_phase: "executing",
session_id: sessionId,
- state: {
- handoff_artifacts: {
- ralplan_consensus_gate: { required: true, complete: false },
- },
- },
});
+ const write = await dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ tool_name: "Edit",
+ tool_input: { file_path: "src/root-write.ts" },
+ }, { cwd });
+ assert.equal(write.outputJson?.decision, "block");
+ assert.match(String(write.outputJson?.reason ?? ""), /Main-root Conductor mode is active/);
+ for (const [name, identityClaim] of [
+ ["agent-id", { agent_id: "claimed-agent" }],
+ ["agent-id-camel", { agentId: "claimed-agent" }],
+ ["owner", { owner_codex_thread_id: sessionId }],
+ ["agent-role", { agent_role: "executor" }],
+ ["agent-role-camel", { agentRole: "executor" }],
+ ["agent-type", { agent_type: "executor" }],
+ ["agent-type-camel", { agentType: "executor" }],
+ ["thread-number", { thread_id: 42 }],
+ ["thread-empty", { thread_id: "" }],
+ ["thread-null", { thread_id: null }],
+ ] as const) {
+ const claimed = await dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: sessionId,
+ turn_id: turnId,
+ tool_name: "Edit",
+ tool_input: { file_path: "src/claimed-root-write.ts" },
+ ...identityClaim,
+ }, { cwd });
+ assert.equal(claimed.outputJson?.decision, "block", name);
+ assert.doesNotMatch(String(claimed.outputJson?.reason ?? ""), /Main-root Conductor mode is active/, name);
+ }
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
- const result = await dispatchCodexNativeHook(
- {
+ it("accepts Codex Desktop exec root transcripts and rejects unknown source or originator", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-exec-source-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const stateDir = join(cwd, ".omx", "state");
+ await writeJson(join(stateDir, "session.json"), {
+ session_id: "019f-competing-exec-source",
+ native_session_id: "019f-competing-exec-source",
+ cwd,
+ pid: process.pid,
+ });
+ for (const [name, transcriptOverrides, accepted] of [
+ ["exec", { source: "exec" }, true],
+ ["unknown", { source: "unknown" }, false],
+ ["wrong-originator", { source: "exec", originator: "Other Client" }, false],
+ ] as const) {
+ const sessionId = `019f-root-source-${name}`;
+ const turnId = `019f-root-source-${name}-turn`;
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(
+ sessionId,
+ cwd,
+ turnId,
+ transcriptOverrides,
+ ));
+ const result = await dispatchCodexNativeHook({
hook_event_name: "UserPromptSubmit",
cwd,
session_id: sessionId,
- thread_id: threadId,
- turn_id: "turn-3311-autopilot-supervised",
+ turn_id: turnId,
source: "native",
- prompt: "$ultragoal turn the approved plan into durable goals",
- },
- { cwd },
- );
+ prompt: "$ultragoal execute",
+ }, { cwd });
+ if (accepted) {
+ assert.match(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/, name);
+ assert.equal((await readNativeUltragoalBootstrap(stateDir, sessionId))?.root_thread_id, sessionId, name);
+ } else {
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/, name);
+ assert.equal(await readNativeUltragoalBootstrap(stateDir, sessionId), null, name);
+ }
+ }
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
- assert.equal(result.omxEventName, "keyword-detector");
- assert.equal(result.skillState?.active, true);
- assert.equal(result.skillState?.skill, "autopilot");
- assert.equal(result.skillState?.supervised_child_skill, "ultragoal");
- assert.equal(result.skillState?.transition_error, undefined);
- assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-NO-OWNER/);
- const message = String(
- (result.outputJson as { hookSpecificOutput?: { additionalContext?: string } } | null)
- ?.hookSpecificOutput?.additionalContext || "",
- );
- assert.doesNotMatch(message, /OMX-ULTRAGOAL-NO-OWNER/);
+ it("rejects child, spoofed, ambiguous, and archived root transcript fallbacks", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-transcript-reject-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const cases = [
+ ["child", { source: { subagent: { thread_spawn: { parent_thread_id: "parent" } } } }],
+ ["spoof", { cwd: join(cwd, "foreign") }],
+ ] as const;
+ for (const [name, overrides] of cases) {
+ const sessionId = `019f-root-${name}`;
+ const turnId = `019f-root-${name}-turn`;
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(sessionId, cwd, turnId, overrides));
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ prompt: "$ultragoal execute",
+ }, { cwd });
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/, name);
+ assert.equal(await readNativeUltragoalBootstrap(join(cwd, ".omx", "state"), sessionId), null, name);
+ }
+
+ const ambiguousId = "019f-root-ambiguous";
+ const ambiguousTurnId = "019f-root-ambiguous-turn";
+ await writeRootTranscript(process.env.CODEX_HOME, ambiguousId, rootTranscriptRecord(ambiguousId, cwd, ambiguousTurnId));
+ const duplicate = join(process.env.CODEX_HOME, "sessions", "duplicate", `rollout-copy-${ambiguousId}.jsonl`);
+ await mkdir(dirname(duplicate), { recursive: true });
+ await writeFile(duplicate, rootTranscriptRecord(ambiguousId, cwd, ambiguousTurnId));
+ const archivedId = "019f-root-archived";
+ const archivedTurnId = "019f-root-archived-turn";
+ const archived = join(process.env.CODEX_HOME, "archived_sessions", `rollout-${archivedId}.jsonl`);
+ await mkdir(dirname(archived), { recursive: true });
+ await writeFile(archived, rootTranscriptRecord(archivedId, cwd, archivedTurnId));
+
+ for (const [name, sessionId] of [["ambiguous", ambiguousId], ["archived", archivedId]] as const) {
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: sessionId,
+ turn_id: name === "ambiguous" ? ambiguousTurnId : archivedTurnId,
+ source: "native",
+ prompt: "$ultragoal execute",
+ }, { cwd });
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/, name);
+ assert.equal(await readNativeUltragoalBootstrap(join(cwd, ".omx", "state"), sessionId), null, name);
+ }
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("does not trust session_meta dynamic tools or a stale turn_context", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-turn-context-reject-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const sessionId = "019f-root-stale-context";
+ const turnId = "019f-root-current-turn";
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(
+ sessionId,
+ cwd,
+ "019f-root-stale-turn",
+ { dynamic_tools: [{ name: "collaboration.spawn_agent" }] },
+ ));
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ prompt: "$ultragoal execute",
+ }, { cwd });
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/);
+ assert.equal(await readNativeUltragoalBootstrap(join(cwd, ".omx", "state"), sessionId), null);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("requires the exact latest turn_context for root Prompt and PreTool authority", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-current-turn-reject-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const stateDir = join(cwd, ".omx", "state");
+ await writeJson(join(stateDir, "session.json"), {
+ session_id: "019f-competing-current-turn",
+ native_session_id: "019f-competing-current-turn",
+ cwd,
+ pid: process.pid,
+ });
+ for (const name of ["missing", "mismatched", "malformed-companion", "stale-latest", "partial-newer"] as const) {
+ const sessionId = `019f-root-turn-${name}`;
+ const currentTurnId = `019f-root-turn-${name}-current`;
+ let transcript = rootTranscriptRecord(sessionId, cwd, currentTurnId);
+ if (name === "stale-latest") {
+ transcript += `${JSON.stringify({
+ type: "turn_context",
+ payload: {
+ turn_id: `${currentTurnId}-newer`,
+ cwd,
+ multi_agent_mode: "explicitRequestOnly",
+ multi_agent_version: "v2",
+ },
+ })}\n`;
+ } else if (name === "partial-newer") {
+ transcript += "{\"type\":\"turn_context\",\"payload\":{";
+ }
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, transcript);
+ const turnClaim = name === "missing"
+ ? {}
+ : name === "malformed-companion"
+ ? { turn_id: currentTurnId, turnId: 42 }
+ : { turn_id: name === "mismatched" ? `${currentTurnId}-foreign` : currentTurnId };
+ const prompt = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ ...turnClaim,
+ source: "native",
+ prompt: "$ultragoal execute",
+ }, { cwd });
+ assert.doesNotMatch(String(prompt.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/, name);
+
+ await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ version: 1,
+ active: true,
+ skill: "ultragoal",
+ phase: "executing",
+ session_id: sessionId,
+ active_skills: [{ skill: "ultragoal", active: true, phase: "executing", session_id: sessionId }],
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ active: true,
+ mode: "ultragoal",
+ current_phase: "executing",
+ session_id: sessionId,
+ });
+
+ const preTool = await dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ ...turnClaim,
+ tool_name: "Edit",
+ tool_input: { file_path: "src/untrusted-root.ts" },
+ }, { cwd });
+ assert.equal(preTool.outputJson?.decision, "block", name);
+ assert.doesNotMatch(String(preTool.outputJson?.reason ?? ""), /Main-root Conductor mode is active/, name);
+ }
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("fails closed on conflicting root transcript aliases", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-alias-conflict-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const cases = [
+ ["session", { session_id: "same", sessionId: "foreign" }, {}],
+ ["session-malformed", { session_id: "same", sessionId: null }, {}],
+ ["thread-source", { threadSource: "subagent" }, {}],
+ ["thread-source-malformed", { threadSource: null }, {}],
+ ["turn", {}, { turnId: "foreign" }],
+ ["mode", {}, { multiAgentMode: "disabled" }],
+ ["version", {}, { multiAgentVersion: "disabled" }],
+ ] as const;
+ for (const [name, sessionOverrides, turnOverrides] of cases) {
+ const sessionId = `019f-root-alias-${name}`;
+ const turnId = `019f-root-alias-${name}-turn`;
+ const effectiveSessionOverrides = name.startsWith("session")
+ ? { ...sessionOverrides, session_id: sessionId }
+ : sessionOverrides;
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(
+ sessionId,
+ cwd,
+ turnId,
+ effectiveSessionOverrides,
+ turnOverrides,
+ ));
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ prompt: "$ultragoal execute",
+ }, { cwd });
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/, name);
+ assert.equal(await readNativeUltragoalBootstrap(join(cwd, ".omx", "state"), sessionId), null, name);
+ }
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("rejects a root transcript mutated after its pinned read", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-pinned-race-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const sessionId = "019f-root-pinned-race";
+ const turnId = "019f-root-pinned-race-turn";
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(sessionId, cwd, turnId));
+ let postReadCalls = 0;
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ prompt: "$ultragoal execute",
+ }, {
+ cwd,
+ rootTranscriptPostReadHook: async (path) => {
+ postReadCalls += 1;
+ await appendFile(path, `${JSON.stringify({ type: "event_msg", payload: { type: "mutation" } })}\n`);
+ },
+ });
+ assert.equal(postReadCalls, 1);
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/);
+ assert.equal(await readNativeUltragoalBootstrap(join(cwd, ".omx", "state"), sessionId), null);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("fails closed when root transcript traversal errors or exhausts its entry cap", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-scan-incomplete-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ for (const name of ["error", "cap"] as const) {
+ const sessionId = `019f-root-scan-${name}`;
+ const turnId = `019f-root-scan-${name}-turn`;
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(sessionId, cwd, turnId));
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ prompt: "$ultragoal execute",
+ }, name === "error" ? {
+ cwd,
+ rootTranscriptBeforeReadDirHook: () => {
+ throw new Error("injected_readdir_error");
+ },
+ } : {
+ cwd,
+ rootTranscriptScanMaxEntries: 1,
+ });
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/, name);
+ assert.equal(await readNativeUltragoalBootstrap(join(cwd, ".omx", "state"), sessionId), null, name);
+ }
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("authorizes an exact root Stop against an exact-cwd stale-dead pointer", async () => {
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-stop-stale-pointer-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "019f-root-stop-live";
+ const turnId = "019f-root-stop-turn";
+ await writeJson(join(stateDir, "session.json"), {
+ session_id: "019f-dead-competing-pointer",
+ native_session_id: "019f-dead-competing-pointer",
+ started_at: "2026-01-01T00:00:00.000Z",
+ cwd,
+ pid: 999_999,
+ platform: process.platform,
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ version: 1,
+ active: true,
+ skill: "autopilot",
+ phase: "executing",
+ session_id: sessionId,
+ thread_id: sessionId,
+ active_skills: [{ skill: "autopilot", active: true, phase: "executing", session_id: sessionId }],
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "autopilot-state.json"), {
+ active: true,
+ mode: "autopilot",
+ current_phase: "executing",
+ session_id: sessionId,
+ });
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(sessionId, cwd, turnId));
+
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "Stop",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ }, { cwd });
+
+ assert.equal(result.outputJson?.decision, "block");
+ assert.doesNotMatch(String(result.outputJson?.reason ?? ""), /selected session pointer is stale-dead/);
+ assert.match(String(result.outputJson?.reason ?? result.outputJson?.systemMessage ?? ""), /autopilot/i);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("keeps spoofed root Stop transcripts fail closed against a stale-dead pointer", async () => {
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-root-stop-reject-"));
+ try {
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ const stateDir = join(cwd, ".omx", "state");
+ await writeJson(join(stateDir, "session.json"), {
+ session_id: "019f-dead-stop-pointer",
+ native_session_id: "019f-dead-stop-pointer",
+ started_at: "2026-01-01T00:00:00.000Z",
+ cwd,
+ pid: 999_999,
+ platform: process.platform,
+ });
+ const cases = [
+ ["spoof", { id: "foreign-root" }, {}],
+ ["child", { source: { subagent: { thread_spawn: { parent_thread_id: "parent" } } } }, {}],
+ ["aliases", { threadSource: "subagent" }, {}],
+ ["payload-aliases", {}, { sessionId: "foreign-session" }],
+ ["payload-session-malformed", {}, { sessionId: null }],
+ ["thread-mismatch", {}, { thread_id: "foreign-thread" }],
+ ["thread-conflict", {}, { thread_id: "__SESSION__", threadId: "foreign-thread" }],
+ ["thread-number", {}, { thread_id: 42 }],
+ ["thread-empty", {}, { thread_id: "" }],
+ ["thread-null", {}, { thread_id: null }],
+ ["agent-id", {}, { agent_id: "claimed-agent" }],
+ ["agent-id-camel", {}, { agentId: "claimed-agent" }],
+ ["agent-empty", {}, { agent_id: "" }],
+ ["agent-null", {}, { agent_id: null }],
+ ["agent-object", {}, { agent_id: { id: "claimed-agent" } }],
+ ["owner", {}, { owner_codex_thread_id: "claimed-owner" }],
+ ["owner-empty", {}, { owner_codex_thread_id: "" }],
+ ["owner-null", {}, { owner_codex_thread_id: null }],
+ ["owner-object", {}, { owner_codex_thread_id: { id: "claimed-owner" } }],
+ ["agent-role", {}, { agent_role: "executor" }],
+ ["agent-role-camel", {}, { agentRole: "executor" }],
+ ["agent-role-malformed", {}, { agent_role: null }],
+ ["agent-type", {}, { agent_type: "executor" }],
+ ["agent-type-camel", {}, { agentType: "executor" }],
+ ["agent-type-malformed", {}, { agent_type: { type: "executor" } }],
+ ["cwd", { cwd: join(cwd, "foreign") }, {}],
+ ] as const;
+ for (const [name, overrides, payloadOverrides] of cases) {
+ const sessionId = `019f-root-stop-${name}`;
+ const turnId = `019f-root-stop-${name}-turn`;
+ const effectivePayloadOverrides = Object.fromEntries(
+ Object.entries(payloadOverrides).map(([key, value]) => [key, value === "__SESSION__" ? sessionId : value]),
+ );
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(sessionId, cwd, turnId, overrides));
+ const result = await dispatchCodexNativeHook({
+ hook_event_name: "Stop",
+ cwd,
+ session_id: sessionId,
+ thread_id: sessionId,
+ turn_id: turnId,
+ ...effectivePayloadOverrides,
+ }, { cwd });
+ assert.equal(result.outputJson?.decision, "block", name);
+ assert.match(String(result.outputJson?.reason ?? ""), /selected session pointer is stale-dead/, name);
+ }
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("rejects mismatched and ambiguous Codex App transcript receipts", async () => {
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-app-v2-receipt-deny-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-app-v2-receipt-deny";
+ const rootThreadId = "thread-app-v2-receipt-root";
+ const wrongRoleChildId = "thread-app-v2-wrong-role";
+ const conflictingRoleChildId = "thread-app-v2-conflicting-role";
+ const ambiguousChildId = "thread-app-v2-ambiguous";
+ const archivedChildId = "thread-app-v2-archived";
+ const futureChildId = "thread-app-v2-future";
+ const missingSessionChildId = "thread-app-v2-missing-session";
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ await writeLeaderSessionFixture(stateDir, sessionId, rootThreadId, cwd);
+
+ const receiptNotBefore = "2026-07-29T16:54:54.000Z";
+ const receiptNotAfter = "2026-07-30T16:54:54.000Z";
+ const transcript = (
+ childAgentId: string,
+ role: string,
+ timestamp = receiptNotBefore,
+ transcriptSessionId = sessionId,
+ ) => `${JSON.stringify({
+ timestamp,
+ type: "session_meta",
+ payload: {
+ id: childAgentId,
+ session_id: transcriptSessionId,
+ cwd,
+ source: {
+ subagent: {
+ thread_spawn: {
+ parent_thread_id: rootThreadId,
+ depth: 1,
+ agent_role: role,
+ },
+ },
+ },
+ },
+ })}\n`;
+ const wrongRolePath = join(process.env.CODEX_HOME, "sessions", `rollout-${wrongRoleChildId}.jsonl`);
+ await mkdir(dirname(wrongRolePath), { recursive: true });
+ await writeFile(wrongRolePath, transcript(wrongRoleChildId, "reviewer"));
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId,
+ childAgentId: wrongRoleChildId,
+ receiptNotBefore,
+ receiptNotAfter,
+ }), { ok: false, reason: "child_transcript_receipt_mismatch" });
+
+ const conflictingRolePath = join(process.env.CODEX_HOME, "sessions", `rollout-${conflictingRoleChildId}.jsonl`);
+ await writeFile(conflictingRolePath, transcript(conflictingRoleChildId, "executor"));
+ const tracking = JSON.parse(readFileSync(join(stateDir, "subagent-tracking.json"), "utf-8")) as {
+ sessions: Record<string, { threads: Record<string, Record<string, unknown>> }>;
+ };
+ tracking.sessions[sessionId]!.threads[conflictingRoleChildId] = {
+ thread_id: conflictingRoleChildId,
+ kind: "subagent",
+ mode: "reviewer",
+ first_seen_at: receiptNotBefore,
+ last_seen_at: receiptNotBefore,
+ turn_count: 1,
+ };
+ await writeJson(join(stateDir, "subagent-tracking.json"), tracking);
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId,
+ childAgentId: conflictingRoleChildId,
+ receiptNotBefore,
+ receiptNotAfter,
+ }), { ok: false, reason: "child_role_mismatch" });
+
+ const livePath = join(process.env.CODEX_HOME, "sessions", "live", `rollout-${ambiguousChildId}.jsonl`);
+ const duplicatePath = join(process.env.CODEX_HOME, "sessions", "duplicate", `rollout-${ambiguousChildId}.jsonl`);
+ await mkdir(dirname(livePath), { recursive: true });
+ await mkdir(dirname(duplicatePath), { recursive: true });
+ await writeFile(livePath, transcript(ambiguousChildId, "executor"));
+ await writeFile(duplicatePath, transcript(ambiguousChildId, "executor"));
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId,
+ childAgentId: ambiguousChildId,
+ receiptNotBefore,
+ receiptNotAfter,
+ }), { ok: false, reason: "child_transcript_receipt_ambiguous" });
+
+ const archivedPath = join(process.env.CODEX_HOME, "archived_sessions", `rollout-${archivedChildId}.jsonl`);
+ await mkdir(dirname(archivedPath), { recursive: true });
+ await writeFile(archivedPath, transcript(archivedChildId, "executor"));
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId,
+ childAgentId: archivedChildId,
+ receiptNotBefore,
+ receiptNotAfter,
+ }), { ok: false, reason: "child_transcript_receipt_missing" });
+
+ const futurePath = join(process.env.CODEX_HOME, "sessions", `rollout-${futureChildId}.jsonl`);
+ await writeFile(futurePath, transcript(futureChildId, "executor", "9999-01-01T00:00:00.000Z"));
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId,
+ childAgentId: futureChildId,
+ receiptNotBefore,
+ receiptNotAfter: "9999-12-31T23:59:59.999Z",
+ }), { ok: false, reason: "child_transcript_receipt_mismatch" });
+
+ const missingSessionPath = join(process.env.CODEX_HOME, "sessions", `rollout-${missingSessionChildId}.jsonl`);
+ await writeFile(missingSessionPath, transcript(
+ missingSessionChildId,
+ "executor",
+ receiptNotBefore,
+ "missing-session",
+ ));
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId: "missing-session",
+ rootThreadId,
+ childAgentId: missingSessionChildId,
+ receiptNotBefore,
+ receiptNotAfter,
+ }), { ok: false, reason: "leader_session_mismatch" });
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("completes prompt bootstrap through typed assignment, activation, and scoped executor write", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-bootstrap-e2e-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-bootstrap-e2e";
+ const rootThreadId = "thread-bootstrap-e2e-root";
+ const childThreadId = "thread-bootstrap-e2e-child";
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ await writeLeaderSessionFixture(stateDir, sessionId, rootThreadId, cwd);
+ const firstPrompt = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: rootThreadId,
+ source: "native",
+ available_tools: ["collaboration.spawn_agent"],
+ prompt: "$ultragoal execute the durable plan",
+ },
+ { cwd },
+ );
+ assert.equal(firstPrompt.skillState?.active, false);
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ assert.ok(bootstrap);
+
+ const childTranscriptPath = join(
+ process.env.CODEX_HOME,
+ "sessions",
+ "2026",
+ "07",
+ "29",
+ `rollout-2026-07-29T18-56-08-${childThreadId}.jsonl`,
+ );
+ await mkdir(dirname(childTranscriptPath), { recursive: true });
+ await writeFile(childTranscriptPath, `${JSON.stringify({
+ timestamp: bootstrap.created_at,
+ type: "session_meta",
+ payload: {
+ id: childThreadId,
+ session_id: sessionId,
+ cwd,
+ source: {
+ subagent: {
+ thread_spawn: {
+ parent_thread_id: rootThreadId,
+ depth: 1,
+ agent_path: "/root/ultragoal_executor",
+ agent_role: "executor",
+ },
+ },
+ },
+ },
+ })}\n`);
+ const tracking = JSON.parse(
+ readFileSync(join(stateDir, "subagent-tracking.json"), "utf-8"),
+ ) as { sessions?: Record<string, { threads?: Record<string, Record<string, unknown>> }> };
+ assert.equal(
+ tracking.sessions?.[sessionId]?.threads?.[childThreadId],
+ undefined,
+ "assignment-local transcript evidence must not grant persisted reopen authority",
+ );
+ await issueLocalNativeExecutorAssignment({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ childAgentId: childThreadId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ["src/native-flow"],
+ ttlSeconds: 300,
+ });
+ const assignedTracking = JSON.parse(
+ readFileSync(join(stateDir, "subagent-tracking.json"), "utf-8"),
+ ) as { sessions?: Record<string, { threads?: Record<string, Record<string, unknown>> }> };
+ const descriptiveChild = assignedTracking.sessions?.[sessionId]?.threads?.[childThreadId];
+ assert.equal(descriptiveChild?.mode, "executor");
+ assert.equal(descriptiveChild?.status, undefined);
+ assert.equal(descriptiveChild?.provenance_kind, undefined);
+ assert.equal(descriptiveChild?.direct_child_parent_id, undefined);
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId,
+ childAgentId: childThreadId,
+ receiptNotBefore: bootstrap.created_at,
+ receiptNotAfter: bootstrap.expires_at,
+ }), { ok: true });
+
+ const activated = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: rootThreadId,
+ source: "native",
+ available_tools: ["collaboration.spawn_agent"],
+ prompt: "$ultragoal execute the durable plan",
+ },
+ { cwd },
+ );
+ assert.equal(activated.skillState?.active, true);
+ assert.equal(activated.skillState?.initialized_mode, "ultragoal");
+ assert.equal(
+ (await findReadyLocalNativeExecutorAssignment({ cwd, stateDir, sessionId, rootThreadId }))?.child_agent_id,
+ childThreadId,
+ );
+
+ const write = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: childThreadId,
+ agent_id: childThreadId,
+ agent_type: "executor",
+ source: "native",
+ tool_name: "Write",
+ tool_input: { file_path: join(cwd, "src", "native-flow", "result.ts"), content: "ok" },
+ },
+ { cwd },
+ );
+ assert.equal(write.outputJson, null);
+
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ mode: "ultragoal",
+ active: false,
+ current_phase: "complete",
+ session_id: sessionId,
+ });
+ const terminalWrite = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: childThreadId,
+ agent_id: childThreadId,
+ agent_type: "executor",
+ source: "native",
+ tool_name: "Write",
+ tool_input: { file_path: join(cwd, "src", "native-flow", "late.ts"), content: "no" },
+ },
+ { cwd },
+ );
+ assert.equal(terminalWrite.outputJson?.decision, "block");
+ assert.equal((await readNativeUltragoalBootstrap(stateDir, sessionId))?.status, "revoked");
+ await dispatchCodexNativeHook(
+ {
+ hook_event_name: "Stop",
+ cwd,
+ session_id: sessionId,
+ thread_id: rootThreadId,
+ source: "native",
+ },
+ { cwd },
+ );
+ assert.equal((await readNativeUltragoalBootstrap(stateDir, sessionId))?.status, "revoked");
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("keeps the executor read-only until successful activation PostToolUse", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-bootstrap-two-phase-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-bootstrap-two-phase";
+ const rootThreadId = "thread-bootstrap-two-phase-root";
+ const childThreadId = "thread-bootstrap-two-phase-child";
+ await writeLeaderSessionFixture(stateDir, sessionId, rootThreadId, cwd);
+ const activationPayload = {
+ cwd,
+ session_id: sessionId,
+ thread_id: rootThreadId,
+ agent_id: rootThreadId,
+ source: "native",
+ available_tools: ["collaboration.spawn_agent"],
+ tool_name: "Bash",
+ tool_input: { command: `omx state write --input '${ACTIVATION_INPUT}' --json` },
+ };
+ await dispatchCodexNativeHook({ hook_event_name: "PreToolUse", ...activationPayload }, { cwd });
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ assert.ok(bootstrap);
+ await writeJson(join(stateDir, "subagent-tracking.json"), {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: rootThreadId,
+ updated_at: "2026-07-29T16:54:54.000Z",
+ threads: {
+ [rootThreadId]: {
+ thread_id: rootThreadId,
+ kind: "leader",
+ first_seen_at: "2026-07-29T16:54:54.000Z",
+ last_seen_at: "2026-07-29T16:54:54.000Z",
+ turn_count: 1,
+ },
+ [childThreadId]: {
+ thread_id: childThreadId,
+ kind: "subagent",
+ mode: "executor",
+ status: "available",
+ first_seen_at: "2026-07-29T16:54:54.000Z",
+ last_seen_at: "2026-07-29T16:54:54.000Z",
+ turn_count: 1,
+ provenance_kind: "native_subagent",
+ direct_child_parent_id: rootThreadId,
+ direct_child_root_id: rootThreadId,
+ },
+ },
+ },
+ },
+ });
+ await issueLocalNativeExecutorAssignment({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ childAgentId: childThreadId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ["src/native-flow"],
+ ttlSeconds: 300,
+ });
+
+ const prepared = await dispatchCodexNativeHook(
+ { hook_event_name: "PreToolUse", ...activationPayload },
+ { cwd },
+ );
+ assert.equal(prepared.outputJson, null);
+ assert.equal((await readNativeUltragoalBootstrap(stateDir, sessionId))?.status, "activating");
+ const prematureWrite = await dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: childThreadId,
+ agent_id: childThreadId,
+ agent_type: "executor",
+ source: "native",
+ tool_name: "Write",
+ tool_input: { file_path: join(cwd, "src", "native-flow", "premature.ts"), content: "no" },
+ }, { cwd });
+ assert.equal(prematureWrite.outputJson?.decision, "block");
+
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ active: true,
+ current_phase: "executing",
+ run_outcome: "continue",
+ });
+ await dispatchCodexNativeHook({ hook_event_name: "PostToolUse", ...activationPayload }, { cwd });
+ assert.equal((await readNativeUltragoalBootstrap(stateDir, sessionId))?.status, "active");
+
+ await revokeLocalNativeExecutorAssignment({
+ stateDir,
+ sessionId,
+ reason: "activation_receipt_race",
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ mode: "ultragoal",
+ active: true,
+ current_phase: "executing",
+ session_id: sessionId,
+ });
+ await dispatchCodexNativeHook({ hook_event_name: "PostToolUse", ...activationPayload }, { cwd });
+ const failedState = JSON.parse(readFileSync(
+ join(stateDir, "sessions", sessionId, "ultragoal-state.json"),
+ "utf-8",
+ )) as { active: boolean; current_phase: string; error?: string };
+ assert.equal(failedState.active, false);
+ assert.equal(failedState.current_phase, "failed");
+ assert.equal(failedState.error, "native_ultragoal_activation_receipt_invalid");
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("allows exact root phase transitions for an active session when pointer PID identity is indeterminate", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-active-phase-fallback-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-active-phase-fallback";
+ const turnId = "turn-active-phase-fallback";
+ const childThreadId = "thread-active-phase-fallback-child";
+ process.env.CODEX_HOME = join(cwd, "codex-home");
+ await writeJson(join(stateDir, "session.json"), {
+ session_id: sessionId,
+ native_session_id: sessionId,
+ owner_codex_session_id: sessionId,
+ target_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: process.pid,
+ platform: "linux",
+ });
+ await writeRootTranscript(process.env.CODEX_HOME, sessionId, rootTranscriptRecord(sessionId, cwd, turnId));
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId: sessionId,
+ backend: "local-experimental",
+ ttlSeconds: 300,
+ });
+ await writeJson(join(stateDir, "subagent-tracking.json"), {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: sessionId,
+ updated_at: bootstrap.created_at,
+ threads: {
+ [sessionId]: {
+ thread_id: sessionId,
+ kind: "leader",
+ first_seen_at: bootstrap.created_at,
+ last_seen_at: bootstrap.created_at,
+ turn_count: 1,
+ },
+ [childThreadId]: {
+ thread_id: childThreadId,
+ kind: "subagent",
+ mode: "executor",
+ status: "available",
+ first_seen_at: bootstrap.created_at,
+ last_seen_at: bootstrap.created_at,
+ turn_count: 1,
+ provenance_kind: "native_subagent",
+ direct_child_parent_id: sessionId,
+ direct_child_root_id: sessionId,
+ },
+ },
+ },
+ },
+ });
+ const childTranscriptPath = join(
+ process.env.CODEX_HOME,
+ "sessions",
+ "2026",
+ "07",
+ "29",
+ `rollout-2026-07-29T20-00-01-${childThreadId}.jsonl`,
+ );
+ await mkdir(dirname(childTranscriptPath), { recursive: true });
+ await writeFile(childTranscriptPath, `${JSON.stringify({
+ timestamp: bootstrap.created_at,
+ type: "session_meta",
+ payload: {
+ id: childThreadId,
+ session_id: sessionId,
+ cwd,
+ source: {
+ subagent: {
+ thread_spawn: {
+ parent_thread_id: sessionId,
+ depth: 1,
+ agent_path: "/root/active_phase_executor",
+ agent_role: "executor",
+ },
+ },
+ },
+ },
+ })}\n`);
+ await issueLocalNativeExecutorAssignment({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId: sessionId,
+ childAgentId: childThreadId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ["src"],
+ ttlSeconds: 300,
+ });
+ assert.equal((await prepareNativeUltragoalBootstrapActivation({
+ cwd,
+ stateDir,
+ sessionId,
+ childAgentId: childThreadId,
+ })).ok, true);
+ assert.equal((await markNativeUltragoalBootstrapActive({
+ cwd,
+ stateDir,
+ sessionId,
+ childAgentId: childThreadId,
+ })).ok, true);
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ active: true,
+ current_phase: "executing",
+ run_outcome: "continue",
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ version: 1,
+ active: true,
+ skill: "ultragoal",
+ phase: "executing",
+ session_id: sessionId,
+ thread_id: sessionId,
+ active_skills: [{ skill: "ultragoal", active: true, phase: "executing", session_id: sessionId }],
+ });
+
+ const exactPhasePayload = {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ tool_name: "Bash",
+ tool_input: {
+ command: `omx state write --input '${JSON.stringify({
+ mode: "ultragoal",
+ active: true,
+ current_phase: "verifying",
+ })}' --json`,
+ },
+ };
+ const identityIndeterminatePointer = {
+ status: "identity-indeterminate" as const,
+ state: {
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: process.pid,
+ platform: "darwin" as const,
+ started_at: bootstrap.created_at,
+ },
+ };
+ const rootTranscript = { sessionId, hasExactTurnContext: true, hasTypedNativeSpawn: true };
+ const stillBlockedWithoutFallbackPointer = await buildConductorPreToolUseWriteGuardOutput(
+ exactPhasePayload,
+ cwd,
+ stateDir,
+ sessionId,
+ cwd,
+ rootTranscript,
+ );
+ assert.equal(stillBlockedWithoutFallbackPointer?.decision, "block");
+ assert.equal(await buildConductorPreToolUseWriteGuardOutput(
+ exactPhasePayload,
+ cwd,
+ stateDir,
+ sessionId,
+ cwd,
+ rootTranscript,
+ identityIndeterminatePointer,
+ ), null);
+ assert.equal(await buildConductorPreToolUseWriteGuardOutput(
+ exactPhasePayload,
+ cwd,
+ stateDir,
+ sessionId,
+ cwd,
+ rootTranscript,
+ { ...identityIndeterminatePointer, status: "usable" as const },
+ ), null);
+
+ const dispatchPhase = async (
+ phase: string,
+ extraPayload: Record<string, unknown> = {},
+ identity: Record<string, unknown> = {},
+ ) => dispatchCodexNativeHook({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ ...identity,
+ tool_name: "Bash",
+ tool_input: {
+ command: `omx state write --input '${JSON.stringify({
+ mode: "ultragoal",
+ active: true,
+ current_phase: phase,
+ ...extraPayload,
+ })}' --json`,
+ },
+ }, { cwd });
+
+ for (const phase of ["planning", "executing", "verifying", "reviewing", "checkpointing", "blocked"]) {
+ assert.equal((await dispatchPhase(phase)).outputJson, null, `root phase ${phase} must be allowed`);
+ }
+
+ const unsafe = await dispatchPhase("verifying", { reason: "smuggled" });
+ assert.equal(unsafe.outputJson?.decision, "block");
+ assert.match(String(unsafe.outputJson?.reason ?? ""), /Main-root Conductor mode is active/);
+
+ const child = await dispatchPhase("verifying", {}, {
+ agent_id: childThreadId,
+ agent_type: "executor",
+ thread_id: childThreadId,
+ });
+ assert.equal(child.outputJson?.decision, "block");
+
+ const childGitPayload = {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ agent_id: childThreadId,
+ agent_type: "executor",
+ thread_id: childThreadId,
+ tool_name: "Bash",
+ };
+ const dispatchChildGit = (command: string) => dispatchCodexNativeHook({
+ ...childGitPayload,
+ tool_input: { command },
+ }, { cwd });
+
+ const previousGitPager = process.env.GIT_PAGER;
+ delete process.env.GIT_PAGER;
+ try {
+ const childGitStatus = await dispatchChildGit("git status --short");
+ assert.equal(childGitStatus.outputJson, null);
+
+ for (const command of [
+ "git reset --hard",
+ "git status --short; git reset --hard",
+ "git status --short$(printf x)",
+ "git status --short\ngit reset --hard",
+ ]) {
+ assert.equal((await dispatchChildGit(command)).outputJson?.decision, "block", command);
+ }
+
+ for (const [name, value] of [
+ ["BASH_FUNC_git%%", "() { printf owned > src/pwned.ts; }"],
+ ["GIT_EXTERNAL_DIFF", "/tmp/attacker-git-diff"],
+ ] as const) {
+ const previous = process.env[name];
+ process.env[name] = value;
+ try {
+ assert.equal((await dispatchChildGit("git status --short")).outputJson?.decision, "block", name);
+ } finally {
+ if (previous === undefined) delete process.env[name];
+ else process.env[name] = previous;
+ }
+ }
+ } finally {
+ if (previousGitPager === undefined) delete process.env.GIT_PAGER;
+ else process.env.GIT_PAGER = previousGitPager;
+ }
+
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ active: true,
+ current_phase: "checkpointing",
+ run_outcome: "continue",
+ });
+ await writeJson(join(cwd, ".omx", "ultragoal", "goals.json"), {
+ version: 1,
+ goals: [{ id: "G001-terminal", status: "complete" }],
+ aggregateCompletion: {
+ status: "complete",
+ completedAt: "2026-07-29T20:10:00.000Z",
+ evidence: "tests and independent reviews passed",
+ },
+ });
+ const terminalPayload = (input: Record<string, unknown>, identity: Record<string, unknown> = {}) => ({
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ ...identity,
+ tool_name: "Bash",
+ tool_input: {
+ command: `omx state write --input '${JSON.stringify(input)}' --json`,
+ },
+ });
+ const exactTerminalInput = {
+ mode: "ultragoal",
+ active: false,
+ current_phase: "complete",
+ };
+ assert.equal(
+ (await dispatchCodexNativeHook(terminalPayload(exactTerminalInput), { cwd })).outputJson?.decision,
+ "block",
+ "terminal transition must remain blocked until executor authority is revoked",
+ );
+ await revokeLocalNativeExecutorAssignment({
+ stateDir,
+ sessionId,
+ reason: "aggregate_complete",
+ });
+ assert.equal(
+ (await dispatchCodexNativeHook(terminalPayload(exactTerminalInput), { cwd })).outputJson,
+ null,
+ "exact root terminal transition must be allowed after aggregate checkpoint and executor revocation",
+ );
+ await writeJson(join(cwd, ".omx", "ultragoal", "goals.json"), {
+ version: 1,
+ goals: [{ id: "G001-terminal", status: "in_progress" }],
+ aggregateCompletion: { status: "complete" },
+ });
+ assert.equal(
+ (await dispatchCodexNativeHook(terminalPayload(exactTerminalInput), { cwd })).outputJson?.decision,
+ "block",
+ "terminal transition must remain blocked when any repo-native goal is incomplete",
+ );
+ await writeJson(join(cwd, ".omx", "ultragoal", "goals.json"), {
+ version: 1,
+ goals: [{ id: "G001-terminal", status: "complete" }],
+ aggregateCompletion: { status: "complete", evidence: "проверки пройдены" },
+ });
+ assert.equal(
+ (await dispatchCodexNativeHook(terminalPayload(exactTerminalInput), { cwd })).outputJson,
+ null,
+ "UTF-8 aggregate evidence must not invalidate byte-size pinning",
+ );
+ assert.equal(
+ (await dispatchCodexNativeHook(terminalPayload({ ...exactTerminalInput, reason: "smuggled" }), { cwd })).outputJson?.decision,
+ "block",
+ );
+ assert.equal(
+ (await dispatchCodexNativeHook(terminalPayload(exactTerminalInput, {
+ agent_id: childThreadId,
+ agent_type: "executor",
+ thread_id: childThreadId,
+ }), { cwd })).outputJson?.decision,
+ "block",
+ );
+
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ mode: "ultragoal",
+ active: false,
+ current_phase: "complete",
+ session_id: sessionId,
+ });
+ const terminal = await dispatchPhase("verifying");
+ assert.equal(terminal.outputJson?.decision, "block");
+ assert.match(String(terminal.outputJson?.reason ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/);
+
+ assert.equal(await __isAuthorizedActiveUltragoalPhaseTransitionFallbackForTests({
+ payload: {
+ hook_event_name: "PreToolUse",
+ cwd,
+ session_id: sessionId,
+ turn_id: turnId,
+ source: "native",
+ tool_name: "Bash",
+ tool_input: { command: `omx state write --input '${ACTIVATION_INPUT}' --json` },
+ },
+ policyCwd: cwd,
+ stateDir,
+ sessionId,
+ pointer: {
+ status: "identity-indeterminate",
+ state: {
+ session_id: "foreign-active-phase-session",
+ native_session_id: "foreign-active-phase-session",
+ cwd,
+ state_root: stateDir,
+ pid: process.pid,
+ platform: "linux",
+ started_at: bootstrap.created_at,
+ },
+ },
+ rootTranscript: { sessionId, hasExactTurnContext: true, hasTypedNativeSpawn: true },
+ }), false);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("allows the primary '$ultragoal' UserPromptSubmit activation when attached to tmux (Team is reachable)", async () => {
+ process.env.TMUX = "/tmp/tmux-3311-prompt,12345,0";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-prompt-tmux-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-3311-prompt-tmux";
+ await mkdir(stateDir, { recursive: true });
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: "thread-3311-prompt-tmux",
+ turn_id: "turn-3311-prompt-tmux",
+ source: "native",
+ prompt: "$ultragoal split this launch into durable goals",
+ },
+ { cwd },
+ );
+
+ assert.equal(result.skillState?.active, true);
+ assert.equal(result.skillState?.skill, "ultragoal");
+ assert.equal(result.skillState?.initialized_mode, "ultragoal");
+ assert.equal(result.skillState?.transition_error, undefined);
+ const detailState = JSON.parse(readFileSync(
+ join(stateDir, "sessions", sessionId, "ultragoal-state.json"),
+ "utf-8",
+ )) as { active?: boolean; current_phase?: string; error?: string };
+ assert.equal(detailState.active, true);
+ assert.equal(detailState.current_phase, "planning");
+ assert.equal(detailState.error, undefined);
+ assert.equal(await readNativeUltragoalBootstrap(stateDir, sessionId), null);
+
+ await dispatchCodexNativeHook({
+ hook_event_name: "PostToolUse",
+ cwd,
+ session_id: sessionId,
+ thread_id: "thread-3311-prompt-tmux",
+ source: "native",
+ tool_name: "Bash",
+ tool_input: { command: `omx state write --input '${ACTIVATION_INPUT}' --json` },
+ }, { cwd });
+ const postToolState = JSON.parse(readFileSync(
+ join(stateDir, "sessions", sessionId, "ultragoal-state.json"),
+ "utf-8",
+ )) as { active?: boolean; current_phase?: string; error?: string };
+ assert.equal(postToolState.active, true);
+ assert.equal(postToolState.current_phase, "planning");
+ assert.equal(postToolState.error, undefined);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("does not re-block continuation of an already-active '$ultragoal' UserPromptSubmit session outside tmux", async () => {
+ delete process.env.TMUX;
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-prompt-continue-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-3311-prompt-continue";
+ const leaderThreadId = "thread-3311-prompt-continue";
+ await writeLeaderSessionFixture(stateDir, sessionId, leaderThreadId, cwd);
+ await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ active: true,
+ skill: "ultragoal",
+ phase: "planning",
+ session_id: sessionId,
+ active_skills: [{ skill: "ultragoal", phase: "planning", active: true, session_id: sessionId }],
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "ultragoal-state.json"), {
+ active: true,
+ mode: "ultragoal",
+ current_phase: "planning",
+ session_id: sessionId,
+ });
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: leaderThreadId,
+ turn_id: "turn-3311-prompt-continue",
+ source: "native",
+ prompt: "$ultragoal continue with the next milestone",
+ },
+ { cwd },
+ );
+
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-NO-OWNER/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("does not block the primary '$ultragoal' UserPromptSubmit activation from a non-native (CLI) launcher outside tmux", async () => {
+ delete process.env.TMUX;
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-prompt-cli-"));
+ try {
+ await mkdir(join(cwd, ".omx", "state"), { recursive: true });
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: "sess-3311-prompt-cli",
+ thread_id: "thread-3311-prompt-cli",
+ turn_id: "turn-3311-prompt-cli",
+ source: "cli",
+ prompt: "$ultragoal split this launch into durable goals",
+ },
+ { cwd },
+ );
+
+ assert.equal(result.skillState?.initialized_mode, "ultragoal");
+ assert.equal(result.skillState?.transition_error, undefined);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ // --- Autopilot-supervised child recognition must not be intercepted ---
+ // #3311 repair-2: the prompt guard must refuse only a truly *standalone*
+ // fresh Ultragoal activation. When Autopilot is already active and
+ // supervising a child phase (e.g. ralplan), a "$ultragoal" prompt is a
+ // supervised-child transition handled entirely by recordSkillActivation's
+ // own isAutopilotSupervisedChildSkill branch; it must remain reachable on
+ // native App outside tmux exactly as it was on the pre-#3311-fix baseline.
+
+ it("does not intercept Autopilot-supervised '$ultragoal' child-phase recognition on native App outside tmux", async () => {
+ delete process.env.TMUX;
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-3311-autopilot-supervised-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-3311-autopilot-supervised";
+ const threadId = "thread-3311-autopilot-supervised";
+ await mkdir(join(stateDir, "sessions", sessionId), { recursive: true });
+ await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ active: true,
+ skill: "autopilot",
+ phase: "ralplan",
+ session_id: sessionId,
+ active_skills: [{ skill: "autopilot", phase: "ralplan", active: true, session_id: sessionId }],
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "autopilot-state.json"), {
+ active: true,
+ mode: "autopilot",
+ current_phase: "ralplan",
+ session_id: sessionId,
+ state: {
+ handoff_artifacts: {
+ ralplan_consensus_gate: { required: true, complete: false },
+ },
+ },
+ });
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: threadId,
+ turn_id: "turn-3311-autopilot-supervised",
+ source: "native",
+ prompt: "$ultragoal turn the approved plan into durable goals",
+ },
+ { cwd },
+ );
+
+ assert.equal(result.omxEventName, "keyword-detector");
+ assert.equal(result.skillState?.active, true);
+ assert.equal(result.skillState?.skill, "autopilot");
+ assert.equal(result.skillState?.supervised_child_skill, "ultragoal");
+ assert.equal(result.skillState?.transition_error, undefined);
+ assert.doesNotMatch(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-NO-OWNER/);
+ const message = String(
+ (result.outputJson as { hookSpecificOutput?: { additionalContext?: string } } | null)
+ ?.hookSpecificOutput?.additionalContext || "",
+ );
+ assert.doesNotMatch(message, /OMX-ULTRAGOAL-NO-OWNER/);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it("keeps a completed standalone Ralplan to Ultragoal handoff inactive until executor authorization", async () => {
+ delete process.env.TMUX;
+ process.env.OMX_NATIVE_SUBAGENT_ASSIGNMENTS = "on";
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = "local-experimental";
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-ralplan-ultragoal-bootstrap-"));
+ try {
+ const stateDir = join(cwd, ".omx", "state");
+ const sessionId = "sess-ralplan-ultragoal-bootstrap";
+ const threadId = "thread-ralplan-ultragoal-bootstrap";
+ await writeLeaderSessionFixture(stateDir, sessionId, threadId, cwd);
+ await writeJson(join(stateDir, "sessions", sessionId, "skill-active-state.json"), {
+ active: false,
+ skill: "ralplan",
+ phase: "complete",
+ session_id: sessionId,
+ owner_codex_session_id: sessionId,
+ target_session_id: sessionId,
+ active_skills: [{
+ skill: "ralplan",
+ phase: "complete",
+ active: false,
+ session_id: sessionId,
+ owner_codex_session_id: sessionId,
+ }],
+ });
+ await writeJson(join(stateDir, "sessions", sessionId, "ralplan-state.json"), {
+ active: false,
+ mode: "ralplan",
+ current_phase: "complete",
+ session_id: sessionId,
+ owner_codex_session_id: sessionId,
+ target_session_id: sessionId,
+ });
+
+ const result = await dispatchCodexNativeHook(
+ {
+ hook_event_name: "UserPromptSubmit",
+ cwd,
+ session_id: sessionId,
+ thread_id: threadId,
+ source: "native",
+ available_tools: ["collaboration.spawn_agent"],
+ prompt: "$ultragoal execute the approved plan",
+ },
+ { cwd },
+ );
+
+ assert.equal(result.skillState?.active, false);
+ assert.equal(result.skillState?.skill, "ultragoal");
+ assert.match(String(result.skillState?.transition_error ?? ""), /OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED/);
+ assert.equal(
+ existsSync(join(stateDir, "sessions", sessionId, "ultragoal-state.json")),
+ false,
+ );
} finally {
await rm(cwd, { recursive: true, force: true });
}
diff --git a/src/scripts/codex-native-hook.ts b/src/scripts/codex-native-hook.ts
index 8c74a5d4..b93d0d90 100644
--- a/src/scripts/codex-native-hook.ts
+++ b/src/scripts/codex-native-hook.ts
@@ -1,5 +1,5 @@
import { execFileSync } from "child_process";
-import { accessSync, closeSync, constants as fsConstants, existsSync, lstatSync, openSync, readFileSync, readSync, readdirSync, realpathSync, statSync } from "fs";
+import { accessSync, closeSync, constants as fsConstants, existsSync, lstatSync, openSync, readFileSync, readSync, readdirSync, realpathSync, statSync, type Dirent } from "fs";
import { appendFile, lstat, mkdir, open, readFile, readdir, stat, unlink, writeFile } from "fs/promises";
import { basename, delimiter, dirname, extname, isAbsolute, join, relative, resolve } from "path";
import { createHash } from "crypto";
@@ -54,6 +54,7 @@ import {
reconcileNativeSessionStart,
resolveSessionPointerContext,
type SessionStartOptions,
+ type SessionPointerReadResult,
writeNativeSessionOwner,
type SessionState,
} from "../hooks/session.js";
@@ -76,6 +77,7 @@ import {
import { parseTeamNoticeLedgerPrompt, reconcileTeamNoticeLedger } from "../team/notice-ledger.js";
import {
canonicalizeComparablePath,
+ codexHome,
omxNotepadPath,
resolveProjectMemoryPath,
sameFilePath,
@@ -97,6 +99,7 @@ import {
} from "../hooks/keyword-detector.js";
import { buildDeepInterviewConfigInstruction } from "../hooks/deep-interview-config-instruction.js";
import { readTeamModeConfig } from "../config/team-mode.js";
+import { resolveNativeUltragoalConfig } from "../config/native-ultragoal.js";
import {
detectNativeStopStallPattern,
loadAutoNudgeConfig,
@@ -165,6 +168,20 @@ import {
steerUltragoal,
type UltragoalSteeringProposal,
} from "../ultragoal/artifacts.js";
+import {
+ beginNativeUltragoalBootstrap,
+ DOCUMENTED_HOST_RECEIPT_UNAVAILABLE,
+ findReadyLocalNativeExecutorAssignment,
+ markNativeUltragoalBootstrapActive,
+ NATIVE_ASSIGNMENT_DIRECTORY,
+ nativeExecutorAssignmentFileIsSafe,
+ parseActiveLocalNativeExecutorAssignment,
+ prepareNativeUltragoalBootstrapActivation,
+ readNativeUltragoalBootstrap,
+ reconcileLocalNativeExecutorAssignments,
+ revokeLocalNativeExecutorAssignment,
+ validateLocalNativeExecutorIdentity,
+} from "../ultragoal/native-bootstrap.js";
import { triagePrompt } from "../hooks/triage-heuristic.js";
import { readTriageConfig } from "../hooks/triage-config.js";
import {
@@ -206,6 +223,11 @@ interface NativeHookDispatchOptions {
/** @internal Scoped deterministic SessionStart durability seam for native-hook tests. */
sessionStartOptions?: Pick<SessionStartOptions, 'platform' | 'regularFileSync'>;
reconcileHudForPromptSubmitFn?: typeof reconcileHudForPromptSubmit;
+ /** @internal Deterministic pinned-transcript race seam for native-hook tests. */
+ rootTranscriptPostReadHook?: (path: string) => void | Promise<void>;
+ /** @internal Deterministic transcript traversal seams for native-hook tests. */
+ rootTranscriptBeforeReadDirHook?: (path: string) => void | Promise<void>;
+ rootTranscriptScanMaxEntries?: number;
}
export interface NativeHookDispatchResult {
@@ -281,6 +303,9 @@ const RALPH_INTENT_STOPWORDS = new Set([
"ralph", "continue", "resume", "finish", "complete", "fix", "issue",
]);
const MAX_SESSION_META_LINE_BYTES = 256 * 1024;
+const MAX_ROOT_TRANSCRIPT_FIRST_LINE_BYTES = 64 * 1024;
+const MAX_ROOT_TRANSCRIPT_TAIL_BYTES = 8 * 1024 * 1024;
+const MAX_ROOT_TRANSCRIPT_SCAN_ENTRIES = 10_000;
function safeString(value: unknown): string {
return typeof value === "string" ? value : "";
@@ -428,6 +453,224 @@ function readBoundedFirstLineSync(path: string): string {
}
}
+interface SafeRootTranscriptMetadata {
+ sessionId: string;
+ hasExactTurnContext: boolean;
+ hasTypedNativeSpawn: boolean;
+}
+
+function readStrictStringAliasClaim(
+ record: Record<string, unknown>,
+ keys: readonly string[],
+): { present: boolean; valid: boolean; values: string[] } {
+ const presentKeys = keys.filter((key) => Object.prototype.hasOwnProperty.call(record, key));
+ if (presentKeys.length === 0) return { present: false, valid: true, values: [] };
+ const values: string[] = [];
+ for (const key of presentKeys) {
+ const value = record[key];
+ if (typeof value !== "string" || !value.trim()) return { present: true, valid: false, values: [] };
+ values.push(value.trim());
+ }
+ return { present: true, valid: new Set(values).size === 1, values: [...new Set(values)] };
+}
+
+async function findLiveRootTranscriptPaths(
+ sessionId: string,
+ options: {
+ beforeReadDirHook?: (path: string) => void | Promise<void>;
+ maxEntries?: number;
+ } = {},
+): Promise<string[] | null> {
+ const suffix = `-${sessionId}.jsonl`;
+ const matches: string[] = [];
+ const pending = [{ path: join(codexHome(), "sessions"), depth: 0 }];
+ const maxEntries = options.maxEntries ?? MAX_ROOT_TRANSCRIPT_SCAN_ENTRIES;
+ let visited = 0;
+
+ while (pending.length > 0 && visited < maxEntries) {
+ const current = pending.shift()!;
+ let entries: Dirent[];
+ try {
+ if (options.beforeReadDirHook) await options.beforeReadDirHook(current.path);
+ entries = await readdir(current.path, { withFileTypes: true });
+ } catch {
+ return null;
+ }
+ if (visited + entries.length > maxEntries) return null;
+ visited += entries.length;
+ for (const entry of entries) {
+ const path = join(current.path, entry.name);
+ if (entry.isDirectory() && current.depth < 4) {
+ pending.push({ path, depth: current.depth + 1 });
+ } else if (entry.isFile() && entry.name.endsWith(suffix)) {
+ matches.push(path);
+ if (matches.length > 1) return matches;
+ }
+ }
+ }
+ return pending.length === 0 ? matches : null;
+}
+
+async function readSafeRootTranscriptMetadata(
+ payload: CodexHookPayload,
+ cwd: string,
+ postReadHook?: (path: string) => void | Promise<void>,
+ scanOptions: {
+ beforeReadDirHook?: (path: string) => void | Promise<void>;
+ maxEntries?: number;
+ } = {},
+): Promise<SafeRootTranscriptMetadata | null> {
+ const hasAnyAlias = (keys: readonly string[]): boolean => keys.some((key) => (
+ Object.prototype.hasOwnProperty.call(payload, key)
+ ));
+ if (
+ payloadHasConflictingIdentityAliases(payload)
+ || hasSubagentThreadSpawnProvenance(payload)
+ || hasAnyAlias([
+ "owner_codex_thread_id",
+ "owner_omx_session_id",
+ "owner_codex_session_id",
+ "native_owner_session_id",
+ ])
+ || hasAnyAlias([
+ "agent_id",
+ "agentId",
+ "agent_role",
+ "agentRole",
+ "agent_type",
+ "agentType",
+ ])
+ ) return null;
+ const sessionClaim = readStrictStringAliasClaim(payload, ["session_id", "sessionId"]);
+ const sessionId = sessionClaim.values[0] ?? "";
+ const threadClaim = readStrictStringAliasClaim(payload, ["thread_id", "threadId"]);
+ if (
+ !sessionClaim.valid
+ || !sessionClaim.present
+ || !sessionId
+ || !threadClaim.valid
+ || (threadClaim.present && threadClaim.values[0] !== sessionId)
+ ) return null;
+
+ const paths = await findLiveRootTranscriptPaths(sessionId, scanOptions);
+ if (!paths || paths.length !== 1) return null;
+ const path = paths[0]!;
+ const metadata = await lstat(path).catch(() => null);
+ if (
+ !metadata
+ || !metadata.isFile()
+ || metadata.isSymbolicLink()
+ || metadata.nlink !== 1
+ || (metadata.mode & 0o022) !== 0
+ ) return null;
+
+ const handle = await open(path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0)).catch(() => null);
+ if (!handle) return null;
+ try {
+ const openedMetadata = await handle.stat();
+ if (
+ !openedMetadata.isFile()
+ || openedMetadata.nlink !== 1
+ || (openedMetadata.mode & 0o022) !== 0
+ || openedMetadata.dev !== metadata.dev
+ || openedMetadata.ino !== metadata.ino
+ ) return null;
+ const snapshot = await (async (): Promise<SafeRootTranscriptMetadata | null> => {
+ const buffer = Buffer.alloc(MAX_ROOT_TRANSCRIPT_FIRST_LINE_BYTES);
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
+ const newline = buffer.subarray(0, bytesRead).indexOf(0x0a);
+ if (newline < 0) return null;
+ const record = safeObject(JSON.parse(buffer.subarray(0, newline).toString("utf8")));
+ if (safeString(record?.type).trim() !== "session_meta") return null;
+ const transcriptPayload = safeObject(record?.payload);
+ if (!transcriptPayload || safeString(transcriptPayload.id).trim() !== sessionId) return null;
+ const transcriptSessionClaim = readStrictStringAliasClaim(transcriptPayload, ["session_id", "sessionId"]);
+ if (!transcriptSessionClaim.valid || (transcriptSessionClaim.present && transcriptSessionClaim.values[0] !== sessionId)) return null;
+ const threadSourceClaim = readStrictStringAliasClaim(transcriptPayload, ["thread_source", "threadSource"]);
+ if (!threadSourceClaim.valid || !threadSourceClaim.present || threadSourceClaim.values[0] !== "user") return null;
+ const source = transcriptPayload.source;
+ if (!["vscode", "exec"].includes(safeString(source).trim())) return null;
+ if (safeString(transcriptPayload.originator).trim() !== "Codex Desktop") return null;
+ const sourceObject = safeObject(source);
+ if (sourceObject && Object.prototype.hasOwnProperty.call(sourceObject, "subagent")) return null;
+ const transcriptCwd = safeString(transcriptPayload.cwd).trim();
+ if (!transcriptCwd) return null;
+ try {
+ if (realpathSync(transcriptCwd) !== realpathSync(cwd)) return null;
+ } catch {
+ return null;
+ }
+
+ const tailBytes = Math.min(openedMetadata.size, MAX_ROOT_TRANSCRIPT_TAIL_BYTES);
+ const tailOffset = openedMetadata.size - tailBytes;
+ const tailBuffer = Buffer.alloc(tailBytes);
+ const { bytesRead: tailBytesRead } = await handle.read(tailBuffer, 0, tailBytes, tailOffset);
+ let tailText = tailBuffer.subarray(0, tailBytesRead).toString("utf8");
+ if (tailOffset > 0) {
+ const firstNewline = tailText.indexOf("\n");
+ if (firstNewline < 0) return { sessionId, hasExactTurnContext: false, hasTypedNativeSpawn: false };
+ tailText = tailText.slice(firstNewline + 1);
+ }
+ if (!tailText.endsWith("\n")) {
+ return { sessionId, hasExactTurnContext: false, hasTypedNativeSpawn: false };
+ }
+ const completeTail = tailText;
+ let latestTurnContext: Record<string, unknown> | null = null;
+ for (const line of completeTail.split("\n")) {
+ if (!line) continue;
+ try {
+ const candidate = safeObject(JSON.parse(line));
+ if (safeString(candidate?.type).trim() === "turn_context") latestTurnContext = candidate;
+ } catch {
+ return { sessionId, hasExactTurnContext: false, hasTypedNativeSpawn: false };
+ }
+ }
+ const turnContextPayload = safeObject(latestTurnContext?.payload);
+ const payloadTurnClaim = readStrictStringAliasClaim(payload, ["turn_id", "turnId"]);
+ const contextTurnClaim = readStrictStringAliasClaim(turnContextPayload ?? {}, ["turn_id", "turnId"]);
+ const multiAgentModeClaim = readStrictStringAliasClaim(turnContextPayload ?? {}, ["multi_agent_mode", "multiAgentMode"]);
+ const multiAgentVersionClaim = readStrictStringAliasClaim(turnContextPayload ?? {}, ["multi_agent_version", "multiAgentVersion"]);
+ const contextCwd = safeString(turnContextPayload?.cwd).trim();
+ let exactContextCwd = false;
+ try {
+ exactContextCwd = realpathSync(contextCwd) === realpathSync(cwd);
+ } catch {
+ exactContextCwd = false;
+ }
+ const hasExactTurnContext = payloadTurnClaim.valid
+ && payloadTurnClaim.present
+ && contextTurnClaim.valid
+ && contextTurnClaim.present
+ && contextTurnClaim.values[0] === payloadTurnClaim.values[0]
+ && exactContextCwd;
+ const hasTypedNativeSpawn = hasExactTurnContext
+ && multiAgentModeClaim.valid
+ && multiAgentModeClaim.present
+ && multiAgentModeClaim.values[0] === "explicitRequestOnly"
+ && multiAgentVersionClaim.valid
+ && multiAgentVersionClaim.present
+ && multiAgentVersionClaim.values[0] === "v2";
+ return { sessionId, hasExactTurnContext, hasTypedNativeSpawn };
+ })();
+ if (postReadHook) await postReadHook(path);
+ const postReadMetadata = await handle.stat();
+ if (
+ postReadMetadata.dev !== openedMetadata.dev
+ || postReadMetadata.ino !== openedMetadata.ino
+ || postReadMetadata.mode !== openedMetadata.mode
+ || postReadMetadata.nlink !== openedMetadata.nlink
+ || postReadMetadata.size !== openedMetadata.size
+ || postReadMetadata.mtimeMs !== openedMetadata.mtimeMs
+ || postReadMetadata.ctimeMs !== openedMetadata.ctimeMs
+ ) return null;
+ return snapshot;
+ } catch {
+ return null;
+ } finally {
+ await handle.close().catch(() => {});
+ }
+}
+
@@ -2661,6 +2904,43 @@ function buildNativeOutsideTmuxTeamPromptBlockState(
// of an already-active standalone Ultragoal session) are left untouched, so
// resumption, prior-plan continuation, and non-standalone Ultragoal remain
// exactly as before.
+function nativeSubagentAssignmentsOptedIn(): boolean {
+ return resolveNativeUltragoalConfig().backend === "local-experimental";
+}
+
+function payloadAdvertisesCodexAppV2NativeSpawn(payload: CodexHookPayload): boolean {
+ const multiAgentMode = safeString(payload.multi_agent_mode ?? payload.multiAgentMode).trim().toLowerCase();
+ const multiAgentVersion = safeString(payload.multi_agent_version ?? payload.multiAgentVersion).trim().toLowerCase();
+ return multiAgentMode === "explicitrequestonly" && multiAgentVersion === "v2";
+}
+
+function payloadAdvertisesTypedNativeSpawn(
+ payload: CodexHookPayload,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
+): boolean {
+ const capabilities = safeObject(payload.omx_runtime_capabilities ?? payload.capabilities);
+ const nativeSubagents = capabilities?.native_subagents ?? capabilities?.nativeSubagents;
+ const multiAgent = capabilities?.multi_agent_v1 ?? capabilities?.multiAgentV1;
+ const roleRouting = capabilities?.role_routing ?? capabilities?.roleRouting;
+ if (roleRouting === true && (nativeSubagents === true || multiAgent === true)) return true;
+
+ // Codex App v2 exposes typed collaboration tools to the model while its
+ // native hook payload omits the legacy available_tools/capabilities inventory.
+ // Treat only the exact host-issued v2 marker as positive surface evidence;
+ // partial or older multi-agent markers remain unknown/fail-closed.
+ if (payloadAdvertisesCodexAppV2NativeSpawn(payload)) return true;
+
+ const availableTools = payload.available_tools ?? payload.availableTools ?? payload.tools;
+ if (Array.isArray(availableTools) && availableTools.some((tool) => {
+ const record = safeObject(tool);
+ const name = typeof tool === "string"
+ ? tool
+ : safeString(record?.name ?? record?.tool_name ?? record?.toolName).trim();
+ return isNativeSubagentSpawnToolName(name);
+ })) return true;
+ return rootTranscript?.hasTypedNativeSpawn === true;
+}
+
async function buildNativeOutsideTmuxUltragoalPromptBlockState(
classification: KeywordInputClassification,
cwd: string,
@@ -2669,6 +2949,7 @@ async function buildNativeOutsideTmuxUltragoalPromptBlockState(
sessionId?: string,
threadId?: string,
turnId?: string,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
): Promise<SkillActiveState | null> {
const match = classification.matches.find((entry) => entry.skill === "ultragoal") ?? null;
if (!match) return null;
@@ -2686,12 +2967,96 @@ async function buildNativeOutsideTmuxUltragoalPromptBlockState(
// planning guards). Fall through unchanged to recordSkillActivation's own
// transition/continuation/supervision logic.
const canonicalState = await readVisibleSkillActiveStateForStateDir(stateDir, sessionId);
- const hasAnyActiveTrackedSkill = canonicalState
- ? listActiveSkills(canonicalState).some((entry) => (
+ const activeTrackedSkills = canonicalState
+ ? listActiveSkills(canonicalState).filter((entry) => (
matchesSkillStopContext(entry, canonicalState, sessionId, threadId ?? "")
))
- : false;
- if (hasAnyActiveTrackedSkill) return null;
+ : [];
+ if (activeTrackedSkills.length > 0) return null;
+
+ const rootThreadId = safeString(threadId ?? readPayloadThreadId(payload)).trim()
+ || rootTranscript?.sessionId
+ || "";
+ const nativeConfig = resolveNativeUltragoalConfig();
+ const nativeSupport = resolveNativeSubagentSupportStatus({
+ payload,
+ persistedSupportBlocker: await readJsonIfExists(nativeSubagentSupportBlockerPath(stateDir)),
+ persistedRoleRoutingMarker: readRoleRoutingMarker(stateDir, { cwd, sessionId }),
+ persistedCapacityBlocker: await readJsonIfExists(nativeSubagentCapacityBlockerPath(stateDir)),
+ cwd,
+ sessionId,
+ });
+ if (nativeConfig.backend === "local-experimental" && rootThreadId) {
+ const ready = await reconcileLocalNativeExecutorAssignments({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ });
+ if (ready.ready && ready.childAgentId) return null;
+ if (
+ payloadAdvertisesTypedNativeSpawn(payload, rootTranscript)
+ && (
+ nativeSupport.status === "supported"
+ || payloadAdvertisesCodexAppV2NativeSpawn(payload)
+ || rootTranscript?.hasTypedNativeSpawn === true
+ )
+ ) {
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ backend: nativeConfig.backend,
+ ttlSeconds: nativeConfig.assignmentTtlSeconds,
+ });
+ const nowIso = new Date().toISOString();
+ return {
+ version: 1,
+ active: false,
+ skill: "ultragoal",
+ keyword: match.keyword,
+ phase: "bootstrap",
+ activated_at: nowIso,
+ updated_at: nowIso,
+ source: "keyword-detector",
+ session_id: sessionId,
+ thread_id: rootThreadId,
+ turn_id: turnId,
+ active_skills: [],
+ transition_error: buildNativeUltragoalBootstrapRequiredReason(
+ sessionId,
+ rootThreadId,
+ bootstrap.generation,
+ ),
+ };
+ }
+ } else if (nativeConfig.backend === "host" && rootThreadId) {
+ await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ backend: nativeConfig.backend,
+ ttlSeconds: nativeConfig.assignmentTtlSeconds,
+ });
+ const nowIso = new Date().toISOString();
+ return {
+ version: 1,
+ active: false,
+ skill: "ultragoal",
+ keyword: match.keyword,
+ phase: "bootstrap",
+ activated_at: nowIso,
+ updated_at: nowIso,
+ source: "keyword-detector",
+ session_id: sessionId,
+ thread_id: rootThreadId,
+ turn_id: turnId,
+ active_skills: [],
+ transition_error: ULTRAGOAL_HOST_RECEIPT_UNAVAILABLE_REASON,
+ };
+ }
const nowIso = new Date().toISOString();
return {
@@ -2711,6 +3076,40 @@ async function buildNativeOutsideTmuxUltragoalPromptBlockState(
};
}
+async function revokeTerminalNativeUltragoalBootstrap(
+ cwd: string,
+ stateDir: string,
+ sessionId: string,
+): Promise<void> {
+ if (!sessionId) return;
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ if (!bootstrap || bootstrap.status === "revoked") return;
+ const state = await readStopSessionPinnedState("ultragoal-state.json", cwd, sessionId, stateDir);
+ const phase = safeString(state?.current_phase ?? state?.currentPhase).trim().toLowerCase();
+ if (state?.active === false || TERMINAL_MODE_PHASES.has(phase)) {
+ await revokeLocalNativeExecutorAssignment({
+ stateDir,
+ sessionId,
+ reason: `ultragoal_${phase || "inactive"}`,
+ });
+ }
+}
+
+async function failNativeUltragoalActivation(
+ cwd: string,
+ stateDir: string,
+ sessionId: string,
+ reason: string,
+): Promise<void> {
+ await revokeLocalNativeExecutorAssignment({ stateDir, sessionId, reason });
+ await updateModeState("ultragoal", {
+ active: false,
+ current_phase: "failed",
+ error: reason,
+ last_turn_at: new Date().toISOString(),
+ }, cwd, sessionId);
+}
+
function buildSkillStateCliInstruction(mode: string, statePath: string): string {
return `skill: ${mode} activated and initial state initialized at ${statePath}; use CLI-first state updates via \`omx state write/read/clear --input '<json>' --json\`; use omx_state MCP only when explicit MCP compatibility is enabled.`;
}
@@ -4049,6 +4448,15 @@ function resolveConductorPolicyRoot(stateDir: string, fallbackCwd: string): Cond
return { cwd: canonicalFallback, valid: !statePresent, statePresent, externalStateRoot: statePresent };
}
+function readDirectPayloadAgentRole(payload: CodexHookPayload): string {
+ const roles = [...new Set([
+ "agent_role",
+ "agentRole",
+ "agent_type",
+ "agentType",
+ ].map((key) => safeString(payload[key]).trim().toLowerCase()).filter(Boolean))];
+ return roles.length === 1 ? roles[0] ?? "" : "";
+}
function readPayloadAgentRole(payload: CodexHookPayload): string {
const directRole = safeString(
@@ -5467,7 +5875,11 @@ function classifyPreToolUseMutationTransport(
const command = readPreToolUseCommand(payload);
if (
readPreToolUseRawCommand(payload) === command
- && (isAllowedOmxReadOnlyCommand(command, cwd) || isAllowedGhReadOnlyCommand(command) || isAllowedVersionProbeCommand(command))
+ && (
+ isAllowedOmxReadOnlyCommand(command, cwd)
+ || isAllowedGhReadOnlyCommand(command)
+ || isAllowedVersionProbeCommand(command)
+ )
) return "read-only";
return commandHasDeepInterviewWriteIntent(command, 0, cwd) || collectOmxStateCommandOperations(command, "write").length > 0 || commandHasNestedCliMutationIntent(command) || classifyConductorExecutableRuntime(command, 0, cwd) !== null
? "bash"
@@ -5487,7 +5899,6 @@ function classifyPreToolUseMutationTransport(
return "goal-lifecycle";
}
const canonicalToolName = canonicalizeNativeCollaborationToolName(toolName);
-
if (
CONDUCTOR_ORCHESTRATION_TOOL_NAMES.has(canonicalToolName)
|| canonicalToolName.startsWith("collaboration.")
@@ -9443,6 +9854,39 @@ function isSingleLiteralShellInvocation(command: string): boolean {
return splitShellCommandSegments(stripHeredocBodiesForCommandScan(normalizedCommand)).length === 1;
}
+function hasUnquotedShellFilenameExpansion(command: string): boolean {
+ let quote: "'" | '"' | null = null;
+ let braceDepth = 0;
+ let braceHasComma = false;
+ for (let index = 0; index < command.length; index += 1) {
+ const char = command[index] ?? "";
+ if (char === "\\" && quote !== "'") {
+ index += 1;
+ continue;
+ }
+ if (char === "'" || char === '"') {
+ quote = quote === char ? null : quote ?? char;
+ continue;
+ }
+ if (quote) continue;
+ if (char === "*" || char === "?" || char === "[") return true;
+ if (char === "{") {
+ braceDepth += 1;
+ if (braceDepth === 1) braceHasComma = false;
+ continue;
+ }
+ if (char === "," && braceDepth > 0) {
+ braceHasComma = true;
+ continue;
+ }
+ if (char === "}" && braceDepth > 0) {
+ braceDepth -= 1;
+ if (braceDepth === 0 && braceHasComma) return true;
+ }
+ }
+ return false;
+}
+
function literalInvocationWords(command: string): string[] {
return tokenizeShellWords(normalizeShellLineContinuations(command).trim()).map(shellWordLiteral);
}
@@ -9504,6 +9948,7 @@ async function handleDirectOmxCancel(input: {
command: string; rawCommand: string; cwd: string; stateDir: string;
canonicalSessionId: string; payload: CodexHookPayload; allowForce: boolean;
activeState: Record<string, unknown>;
+ rootTranscript?: SafeRootTranscriptMetadata | null;
}): Promise<DirectCancelResult> {
const cancelLike = /^[ \t]*omx[ \t]+cancel\b/.test(input.command);
if (!cancelLike) return { kind: "not-direct-cancel" };
@@ -9520,7 +9965,13 @@ async function handleDirectOmxCancel(input: {
if (!input.canonicalSessionId || aliases.length !== 1 || aliases[0] !== input.canonicalSessionId || payloadHasConflictingIdentityAliases(input.payload)) {
return { kind: "denied", reason: "session_binding", output: directCancelOutput("session_binding") };
}
- const actor = await resolvePreToolUseWriteActor(input.payload, input.cwd, input.stateDir, input.canonicalSessionId);
+ const actor = await resolvePreToolUseWriteActor(
+ input.payload,
+ input.cwd,
+ input.stateDir,
+ input.canonicalSessionId,
+ input.rootTranscript,
+ );
if (actor !== "main-root") return { kind: "denied", reason: "actor_authority", output: directCancelOutput("actor_authority") };
const recovery = await readHookCancelTransactionRecoveryState({ stateDir: input.stateDir, canonicalSessionId: input.canonicalSessionId });
@@ -10424,6 +10875,7 @@ async function buildRalplanPreToolUseBoundaryOutput(
resolvedSessionId?: string,
executionCwd = cwd,
authorityCwd = executionCwd,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
): Promise<Record<string, unknown> | null> {
const sessionId = safeString(resolvedSessionId ?? readPayloadSessionId(payload)).trim();
const threadId = readPayloadThreadId(payload);
@@ -10440,7 +10892,7 @@ async function buildRalplanPreToolUseBoundaryOutput(
const command = readPreToolUseCommand(payload);
const pathCandidates = readPreToolUsePathCandidates(payload);
const mutationTransport = classifyPreToolUseMutationTransport(payload, toolName);
- const actor = await resolvePreToolUseWriteActor(payload, authorityCwd, stateDir, sessionId);
+ const actor = await resolvePreToolUseWriteActor(payload, authorityCwd, stateDir, sessionId, rootTranscript);
if (actor === "team-worker") {
if (teamWorkerMutationTargetsProtectedWorkflowState(payload, toolName, command, executionCwd, stateDir)) {
return buildTeamWorkerProtectedStateDeny(
@@ -10528,15 +10980,27 @@ async function buildRalplanPreToolUseBoundaryOutput(
};
}
-function buildRawProtectedWorkflowStatePathOutput(
+async function buildRawProtectedWorkflowStatePathOutput(
payload: CodexHookPayload,
cwd: string,
stateDir: string,
-): Record<string, unknown> | null {
+ authoritativeSessionId = "",
+ activeConductor = false,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
+): Promise<Record<string, unknown> | null> {
const toolName = safeString(payload.tool_name).trim();
if (classifyPreToolUseMutationTransport(payload, toolName, cwd) !== "path") return null;
const candidates = collectImplementationToolPathCandidates(payload, toolName, readPreToolUsePathCandidates(payload));
- const protectedPath = candidates.find((candidate) => isRawProtectedPlanningStateCandidate(stateDir, cwd, candidate));
+ const protectedCandidates = candidates.filter((candidate) => isRawProtectedPlanningStateCandidate(stateDir, cwd, candidate));
+ if (
+ nativeSubagentAssignmentsOptedIn()
+ && activeConductor
+ && authoritativeSessionId
+ && protectedCandidates.length > 0
+ && protectedCandidates.every((candidate) => isSessionBoundNativeAssignmentPath(cwd, candidate, authoritativeSessionId))
+ && await resolvePreToolUseWriteActor(payload, cwd, stateDir, authoritativeSessionId, rootTranscript) === "main-root"
+ ) return null;
+ const protectedPath = protectedCandidates[0];
if (protectedPath === undefined) return null;
return {
decision: "block",
@@ -10555,6 +11019,7 @@ async function buildDeepInterviewPreToolUseBoundaryOutput(
resolvedSessionId?: string,
executionCwd = cwd,
authorityCwd = executionCwd,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
): Promise<Record<string, unknown> | null> {
const sessionId = safeString(resolvedSessionId ?? readPayloadSessionId(payload)).trim();
const threadId = readPayloadThreadId(payload);
@@ -10571,7 +11036,7 @@ async function buildDeepInterviewPreToolUseBoundaryOutput(
const command = readPreToolUseCommand(payload);
const pathCandidates = readPreToolUsePathCandidates(payload);
const mutationTransport = classifyPreToolUseMutationTransport(payload, toolName);
- const actor = await resolvePreToolUseWriteActor(payload, authorityCwd, stateDir, sessionId);
+ const actor = await resolvePreToolUseWriteActor(payload, authorityCwd, stateDir, sessionId, rootTranscript);
if (actor === "team-worker") {
if (teamWorkerMutationTargetsProtectedWorkflowState(payload, toolName, command, executionCwd, stateDir)) {
return buildTeamWorkerProtectedStateDeny(
@@ -10799,6 +11264,99 @@ interface ActiveConductorState {
type PreToolUseWriteActor = "main-root" | "native-child" | "provenance-conflict" | "team-worker";
+type NativeAssignmentAction = "path-write" | "bash-write";
+
+interface NativeSubagentAssignment {
+ schema_version: 1;
+ kind: "native-subagent-assignment";
+ lifecycle: "active";
+ root_session_id: string;
+ root_thread_id: string;
+ child_agent_id: string;
+ agent_type: string;
+ allowed_actions: NativeAssignmentAction[];
+ path_prefixes: string[];
+ issued_at: string;
+ expires_at: string;
+ bootstrap_generation: string;
+}
+
+
+function nativeAssignmentPath(stateDir: string, sessionId: string, childAgentId: string): string {
+ return join(
+ stateDir,
+ "sessions",
+ sessionId,
+ NATIVE_ASSIGNMENT_DIRECTORY,
+ `${encodeURIComponent(childAgentId)}.json`,
+ );
+}
+
+function isNativeAssignmentPath(stateDir: string, rawPath: string, executionCwd: string): boolean {
+ const absolute = isAbsolute(rawPath) ? resolve(rawPath) : resolve(executionCwd, rawPath);
+ const assignmentRoot = resolve(stateDir, "sessions");
+ const relativePath = relative(assignmentRoot, absolute).replace(/\\/g, "/");
+ return relativePath !== ""
+ && !relativePath.startsWith("../")
+ && /^.+\/native-assignments(?:\/|$)/.test(relativePath);
+}
+
+async function readNativeSubagentAssignment(
+ payload: CodexHookPayload,
+ cwd: string,
+ stateDir: string,
+ sessionId: string,
+): Promise<NativeSubagentAssignment | null> {
+ if (!nativeSubagentAssignmentsOptedIn()) return null;
+ const childAgentId = readPayloadAgentId(payload);
+ const agentType = readDirectPayloadAgentRole(payload);
+ if (!childAgentId || !agentType || resolveInstalledRoleName(agentType, undefined, cwd) === null) return null;
+
+ const trackingState = await readSubagentTrackingState(cwd).catch(() => null);
+ const trackedSession = safeObject(trackingState?.sessions?.[sessionId]);
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ const leaderThreadId = safeString(trackedSession?.leader_thread_id ?? bootstrap?.root_thread_id).trim();
+ if (!leaderThreadId) return null;
+ const identity = await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId: leaderThreadId,
+ childAgentId,
+ receiptNotBefore: bootstrap?.created_at,
+ receiptNotAfter: bootstrap?.expires_at,
+ });
+ if (!identity.ok) return null;
+
+ const path = nativeAssignmentPath(stateDir, sessionId, childAgentId);
+ if (!await nativeExecutorAssignmentFileIsSafe(stateDir, path)) return null;
+ let raw: Record<string, unknown> | null = null;
+ try {
+ raw = safeObject(JSON.parse(readFileSync(path, "utf-8")));
+ } catch {
+ return null;
+ }
+ const assignment = await parseActiveLocalNativeExecutorAssignment(raw, {
+ cwd,
+ sessionId,
+ rootThreadId: leaderThreadId,
+ childAgentId,
+ agentType,
+ });
+ if (!assignment) return null;
+ const ready = await findReadyLocalNativeExecutorAssignment({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId: leaderThreadId,
+ });
+ if (
+ !ready
+ || ready.child_agent_id !== assignment.child_agent_id
+ || ready.bootstrap_generation !== assignment.bootstrap_generation
+ ) return null;
+ return assignment;
+}
+
function hasSubagentThreadSpawnProvenance(payload: CodexHookPayload): boolean {
const source = payload.source;
if (!source || typeof source !== "object") return false;
@@ -10812,6 +11370,7 @@ async function resolvePreToolUseWriteActor(
cwd: string,
stateDir: string,
sessionId: string,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
): Promise<PreToolUseWriteActor> {
if (payloadHasConflictingIdentityAliases(payload)) return "provenance-conflict";
const unofficialAgentId = safeString(payload.agentId).trim();
@@ -10827,13 +11386,24 @@ async function resolvePreToolUseWriteActor(
const leaderAnchors = new Set<string>();
const trackerLeader = safeString(session?.leader_thread_id).trim();
if (trackerLeader) leaderAnchors.add(trackerLeader);
- if (leaderAnchors.has(payloadAgentId) || leaderAnchors.has(payloadThreadId)) return "main-root";
+ if (leaderAnchors.has(payloadAgentId) || leaderAnchors.has(payloadThreadId)) {
+ const hasCompanionIdentityClaim = payloadHasOwnerIdentityClaim(payload)
+ || ["agent_role", "agentRole", "agent_type", "agentType"].some((key) => (
+ Object.prototype.hasOwnProperty.call(payload, key)
+ ));
+ return hasCompanionIdentityClaim ? "provenance-conflict" : "main-root";
+ }
const rootSessionState = await readRootSessionStateFromStateDir(stateDir).catch(() => null);
const payloadSessionId = readPayloadSessionId(payload);
const leaderNativeSessionId = rootSessionState && payloadMatchesSessionPointer(sessionId, rootSessionState)
? safeString(rootSessionState.native_session_id).trim()
: "";
if (!payloadAgentId && !payloadThreadId && leaderNativeSessionId && payloadSessionId === leaderNativeSessionId) return "main-root";
+ if (
+ !payloadAgentId
+ && rootTranscript?.sessionId === payloadSessionId
+ && rootTranscript.hasExactTurnContext
+ ) return "main-root";
if (hasSubagentThreadSpawnProvenance(payload)) return "native-child";
if (payloadHasOwnerIdentityClaim(payload)) return "native-child";
@@ -10930,6 +11500,25 @@ const ULTRAGOAL_NO_OWNER_DENY_REASON =
+ "is tmux-only, and native child/descendant provenance intentionally does not grant write authority (see #3127). "
+ "Activating Conductor mode here would deadlock with only `omx cancel` reachable.";
+const ULTRAGOAL_HOST_RECEIPT_UNAVAILABLE_REASON =
+ `OMX-ULTRAGOAL-HOST-RECEIPT-UNAVAILABLE: ${DOCUMENTED_HOST_RECEIPT_UNAVAILABLE}. `
+ + "Host-backed native executor authority remains fail-closed until Codex exposes a documented receipt verifier.";
+
+function buildNativeUltragoalBootstrapRequiredReason(
+ sessionId: string,
+ rootThreadId: string,
+ generation: string,
+): string {
+ return "OMX-ULTRAGOAL-BOOTSTRAP-REQUIRED: typed native execution is available, but Ultragoal activation remains "
+ + "inactive until an exact executor is spawned and authorized. Spawn one typed `executor` with instructions to "
+ + "wait without tool calls for a follow-up after activation. Retain the returned agent path, then run "
+ + "`omx ultragoal native-bootstrap authorize "
+ + `--session-id ${JSON.stringify(sessionId)} --root-thread-id ${JSON.stringify(rootThreadId)} `
+ + `--bootstrap-generation ${JSON.stringify(generation)} `
+ + "--child-path <spawned-agent-path> --path-prefix . --json`, then retry the canonical Ultragoal state activation "
+ + "and use `followup_task` to start the authorized executor work. ";
+}
+
function collectUltragoalActivationCandidatePayloads(
payload: CodexHookPayload,
toolName: string,
@@ -10965,12 +11554,284 @@ function isUltragoalConductorActivationPayload(input: Record<string, unknown> |
return isNonTerminalPhase(flattened.current_phase ?? flattened.currentPhase);
}
+const ACTIVE_ULTRAGOAL_PHASE_TRANSITION_PHASES = new Set([
+ "planning",
+ "executing",
+ "verifying",
+ "reviewing",
+ "checkpointing",
+ "blocked",
+]);
+
+function isExactActiveUltragoalPhaseTransitionPayload(input: Record<string, unknown>): boolean {
+ const keys = Object.keys(input);
+ if (
+ keys.length !== 3
+ || !keys.includes("mode")
+ || !keys.includes("active")
+ || (keys.includes("current_phase") === keys.includes("currentPhase"))
+ ) return false;
+ const phase = safeString(input.current_phase ?? input.currentPhase).trim().toLowerCase();
+ return input.mode === "ultragoal"
+ && input.active === true
+ && ACTIVE_ULTRAGOAL_PHASE_TRANSITION_PHASES.has(phase);
+}
+
+function isExactActiveUltragoalPhaseTransitionTransport(
+ payload: CodexHookPayload,
+ cwd: string,
+): boolean {
+ const toolName = safeString(payload.tool_name).trim();
+ if (toolName === "mcp__omx_state__state_write") {
+ const input = safeObject(payload.tool_input);
+ return Boolean(input && isExactActiveUltragoalPhaseTransitionPayload(input));
+ }
+ if (toolName !== "Bash") return false;
+ const command = readPreToolUseCommand(payload);
+ if (!isSingleLiteralShellInvocation(command)) return false;
+ const words = tokenizeConductorShellWords(command);
+ const invocations = collectShellCliInvocations(words);
+ if (invocations.length !== 1 || invocations[0]?.commandIndex !== 0) return false;
+ if (shellWordLiteral(words[0] ?? "") !== "omx") return false;
+ if (!isStaticallyValidatedOmxStateWriteInvocation(words, 0)) return false;
+ const payloads = readAllStateWriteInputPayloads(cwd, command);
+ return payloads.length === 1 && isExactActiveUltragoalPhaseTransitionPayload(payloads[0]!);
+}
+
+function isExactTerminalUltragoalStatePayload(input: Record<string, unknown>): boolean {
+ const keys = Object.keys(input);
+ return keys.length === 3
+ && keys.includes("mode")
+ && keys.includes("active")
+ && keys.includes("current_phase")
+ && input.mode === "ultragoal"
+ && input.active === false
+ && input.current_phase === "complete";
+}
+
+function isExactTerminalUltragoalStateTransport(
+ payload: CodexHookPayload,
+ cwd: string,
+): boolean {
+ const toolName = safeString(payload.tool_name).trim();
+ if (toolName === "mcp__omx_state__state_write") {
+ const input = safeObject(payload.tool_input);
+ return Boolean(input && isExactTerminalUltragoalStatePayload(input));
+ }
+ if (toolName !== "Bash") return false;
+ const command = readPreToolUseCommand(payload);
+ if (!isSingleLiteralShellInvocation(command)) return false;
+ const words = tokenizeConductorShellWords(command);
+ const invocations = collectShellCliInvocations(words);
+ if (invocations.length !== 1 || invocations[0]?.commandIndex !== 0) return false;
+ if (shellWordLiteral(words[0] ?? "") !== "omx") return false;
+ if (!isStaticallyValidatedOmxStateWriteInvocation(words, 0)) return false;
+ const payloads = readAllStateWriteInputPayloads(cwd, command);
+ return payloads.length === 1 && isExactTerminalUltragoalStatePayload(payloads[0]!);
+}
+
+async function readPinnedJsonObject(path: string): Promise<Record<string, unknown> | null> {
+ const metadata = await lstat(path).catch(() => null);
+ if (
+ !metadata
+ || !metadata.isFile()
+ || metadata.isSymbolicLink()
+ || metadata.nlink !== 1
+ || (metadata.mode & 0o022) !== 0
+ ) return null;
+ const handle = await open(path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0)).catch(() => null);
+ if (!handle) return null;
+ try {
+ const openedMetadata = await handle.stat();
+ if (
+ !openedMetadata.isFile()
+ || openedMetadata.nlink !== 1
+ || (openedMetadata.mode & 0o022) !== 0
+ || openedMetadata.dev !== metadata.dev
+ || openedMetadata.ino !== metadata.ino
+ ) return null;
+ const raw = await handle.readFile({ encoding: "utf-8" });
+ const finalMetadata = await lstat(path).catch(() => null);
+ if (
+ !finalMetadata
+ || !finalMetadata.isFile()
+ || finalMetadata.isSymbolicLink()
+ || finalMetadata.nlink !== 1
+ || (finalMetadata.mode & 0o022) !== 0
+ || finalMetadata.dev !== metadata.dev
+ || finalMetadata.ino !== metadata.ino
+ || finalMetadata.size !== metadata.size
+ || Buffer.byteLength(raw, "utf-8") !== metadata.size
+ ) return null;
+ return safeObject(JSON.parse(raw));
+ } catch {
+ return null;
+ } finally {
+ await handle.close().catch(() => {});
+ }
+}
+
+async function readPinnedActiveUltragoalSessionState(
+ stateDir: string,
+ sessionId: string,
+): Promise<Record<string, unknown> | null> {
+ const path = join(stateDir, "sessions", sessionId, "ultragoal-state.json");
+ const metadata = await lstat(path).catch(() => null);
+ if (
+ !metadata
+ || !metadata.isFile()
+ || metadata.isSymbolicLink()
+ || metadata.nlink !== 1
+ || (metadata.mode & 0o022) !== 0
+ ) return null;
+ const handle = await open(path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0)).catch(() => null);
+ if (!handle) return null;
+ try {
+ const openedMetadata = await handle.stat();
+ if (
+ !openedMetadata.isFile()
+ || openedMetadata.nlink !== 1
+ || (openedMetadata.mode & 0o022) !== 0
+ || openedMetadata.dev !== metadata.dev
+ || openedMetadata.ino !== metadata.ino
+ ) return null;
+ const raw = await handle.readFile({ encoding: "utf-8" });
+ const state = safeObject(JSON.parse(raw));
+ const persistedMode = safeString(state?.mode).trim();
+ const persistedSessionAliases = state ? [
+ state.session_id,
+ state.owner_omx_session_id,
+ state.codex_session_id,
+ state.owner_codex_session_id,
+ ].filter((value) => value !== undefined) : [];
+ if (
+ !state
+ || (persistedMode !== "" && persistedMode !== "ultragoal")
+ || state.active !== true
+ || persistedSessionAliases.some((value) => safeString(value).trim() !== sessionId)
+ || !ACTIVE_ULTRAGOAL_PHASE_TRANSITION_PHASES.has(
+ safeString(state.current_phase ?? state.currentPhase).trim().toLowerCase(),
+ )
+ ) return null;
+ return state;
+ } catch {
+ return null;
+ } finally {
+ await handle.close().catch(() => {});
+ }
+}
+
+async function isAuthorizedTerminalUltragoalStateFallback(input: {
+ payload: CodexHookPayload;
+ policyCwd: string;
+ stateDir: string;
+ sessionId: string;
+ pointer: SessionPointerReadResult | null;
+ rootTranscript: SafeRootTranscriptMetadata | null;
+}): Promise<boolean> {
+ const { payload, policyCwd, stateDir, sessionId, pointer, rootTranscript } = input;
+ if (!rootTranscript?.hasExactTurnContext || rootTranscript.sessionId !== sessionId) return false;
+ if (
+ !pointer
+ || (pointer.status !== "usable" && pointer.status !== "identity-indeterminate")
+ || !pointer.state
+ ) return false;
+ const pointerState = pointer.state;
+ if (!payloadMatchesSessionPointer(sessionId, pointerState)) return false;
+ if (!safeString(pointerState.cwd).trim() || !isSessionStateAuthoritativeForCwd(pointerState, policyCwd)) return false;
+ const pointerStateRoot = safeString(pointerState.state_root).trim();
+ if (!pointerStateRoot || !sameFilePath(pointerStateRoot, stateDir)) return false;
+ const pointerNativeSessionId = safeString(pointerState.native_session_id).trim();
+ if (pointerNativeSessionId && pointerNativeSessionId !== rootTranscript.sessionId) return false;
+ if (!isExactTerminalUltragoalStateTransport(payload, policyCwd)) return false;
+
+ const activeState = await readPinnedActiveUltragoalSessionState(stateDir, sessionId);
+ if (safeString(activeState?.current_phase ?? activeState?.currentPhase).trim().toLowerCase() !== "checkpointing") {
+ return false;
+ }
+ const plan = await readPinnedJsonObject(join(policyCwd, ".omx", "ultragoal", "goals.json"));
+ const goals = Array.isArray(plan?.goals) ? plan.goals : [];
+ const aggregateCompletion = safeObject(plan?.aggregateCompletion);
+ if (
+ goals.length === 0
+ || goals.some((goal) => safeString(safeObject(goal)?.status).trim().toLowerCase() !== "complete")
+ || safeString(aggregateCompletion?.status).trim().toLowerCase() !== "complete"
+ ) return false;
+
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ if (
+ !bootstrap
+ || bootstrap.status !== "revoked"
+ || bootstrap.session_id !== sessionId
+ || bootstrap.root_thread_id !== rootTranscript.sessionId
+ || !bootstrap.child_agent_id
+ ) return false;
+ const assignment = await findReadyLocalNativeExecutorAssignment({
+ cwd: policyCwd,
+ stateDir,
+ sessionId,
+ rootThreadId: rootTranscript.sessionId,
+ });
+ return assignment === null;
+}
+
+async function isAuthorizedActiveUltragoalPhaseTransitionFallback(input: {
+ payload: CodexHookPayload;
+ policyCwd: string;
+ stateDir: string;
+ sessionId: string;
+ pointer: SessionPointerReadResult | null;
+ rootTranscript: SafeRootTranscriptMetadata | null;
+}): Promise<boolean> {
+ const { payload, policyCwd, stateDir, sessionId, pointer, rootTranscript } = input;
+ if (!rootTranscript?.hasExactTurnContext || rootTranscript.sessionId !== sessionId) return false;
+ if (
+ !pointer
+ || (pointer.status !== "usable" && pointer.status !== "identity-indeterminate")
+ || !pointer.state
+ ) return false;
+ const pointerState = pointer.state;
+ if (!payloadMatchesSessionPointer(sessionId, pointerState)) return false;
+ if (!safeString(pointerState.cwd).trim() || !isSessionStateAuthoritativeForCwd(pointerState, policyCwd)) return false;
+ const pointerStateRoot = safeString(pointerState.state_root).trim();
+ if (!pointerStateRoot || !sameFilePath(pointerStateRoot, stateDir)) return false;
+ const pointerNativeSessionId = safeString(pointerState.native_session_id).trim();
+ if (pointerNativeSessionId && pointerNativeSessionId !== rootTranscript.sessionId) return false;
+ if (!isExactActiveUltragoalPhaseTransitionTransport(payload, policyCwd)) return false;
+ if (!await readPinnedActiveUltragoalSessionState(stateDir, sessionId)) return false;
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ if (
+ !bootstrap
+ || bootstrap.status !== "active"
+ || bootstrap.session_id !== sessionId
+ || bootstrap.root_thread_id !== rootTranscript.sessionId
+ || !bootstrap.child_agent_id
+ ) return false;
+ const assignment = await findReadyLocalNativeExecutorAssignment({
+ cwd: policyCwd,
+ stateDir,
+ sessionId,
+ rootThreadId: rootTranscript.sessionId,
+ });
+ return Boolean(
+ assignment
+ && assignment.child_agent_id === bootstrap.child_agent_id
+ && assignment.bootstrap_generation === bootstrap.generation,
+ );
+}
+
+/** @internal Test-only authority evaluator for the session-scoped phase fallback. */
+export const __isAuthorizedActiveUltragoalPhaseTransitionFallbackForTests =
+ isAuthorizedActiveUltragoalPhaseTransitionFallback;
+
async function buildUltragoalNoOwnerActivationGuardOutput(
payload: CodexHookPayload,
cwd: string,
stateDir: string,
resolvedSessionId?: string,
policyCwd = cwd,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
+ pointer: SessionPointerReadResult | null = null,
): Promise<Record<string, unknown> | null> {
const toolName = safeString(payload.tool_name).trim();
if (toolName !== "Bash" && toolName !== "mcp__omx_state__state_write") return null;
@@ -10980,14 +11841,40 @@ async function buildUltragoalNoOwnerActivationGuardOutput(
const sessionId = safeString(resolvedSessionId ?? readPayloadSessionId(payload)).trim();
if (!sessionId) return null;
+ if (
+ rootTranscript?.hasExactTurnContext
+ && rootTranscript.sessionId === sessionId
+ && pointer?.state
+ && !payloadMatchesSessionPointer(sessionId, pointer.state)
+ && isExactActiveUltragoalPhaseTransitionTransport(payload, policyCwd)
+ ) {
+ return {
+ decision: "block",
+ reason: "OMX-ULTRAGOAL-FOREIGN-SESSION: the exact root phase transition does not match the selected workspace session pointer.",
+ hookSpecificOutput: {
+ hookEventName: "PreToolUse",
+ additionalContext: "The selected session pointer belongs to another Ultragoal session; phase writes remain fail-closed.",
+ },
+ };
+ }
+
// Already-active sessions (phase updates, resumption, or recovery on an
// existing stuck state) remain governed by the existing Conductor write
// guard and `omx cancel`, not this pre-activation refusal.
if (await readActiveConductorStateForPreToolUse(payload, policyCwd, stateDir, sessionId)) return null;
- const writeActor = await resolvePreToolUseWriteActor(payload, cwd, stateDir, sessionId);
+ const writeActor = await resolvePreToolUseWriteActor(payload, cwd, stateDir, sessionId, rootTranscript);
if (writeActor !== "main-root") return null;
+ if (await isAuthorizedActiveUltragoalPhaseTransitionFallback({
+ payload,
+ policyCwd,
+ stateDir,
+ sessionId,
+ pointer,
+ rootTranscript,
+ })) return null;
+
const executionSurface = resolveCodexExecutionSurface(cwd, {
hookEventName: "PreToolUse",
payload,
@@ -10996,21 +11883,164 @@ async function buildUltragoalNoOwnerActivationGuardOutput(
});
if (executionSurface.launcher !== "native" || executionSurface.transport !== "outside-tmux") return null;
+ const rootThreadId = readPayloadThreadId(payload) || rootTranscript?.sessionId || "";
+ const nativeConfig = resolveNativeUltragoalConfig();
+ if (nativeConfig.backend === "host") {
+ return {
+ decision: "block",
+ reason: ULTRAGOAL_HOST_RECEIPT_UNAVAILABLE_REASON,
+ hookSpecificOutput: {
+ hookEventName: "PreToolUse",
+ additionalContext: ULTRAGOAL_HOST_RECEIPT_UNAVAILABLE_REASON,
+ },
+ };
+ }
+ if (nativeConfig.backend === "local-experimental" && rootThreadId) {
+ let bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ if (!bootstrap) {
+ const nativeSupport = resolveNativeSubagentSupportStatus({
+ payload,
+ persistedSupportBlocker: await readJsonIfExists(nativeSubagentSupportBlockerPath(stateDir)),
+ persistedRoleRoutingMarker: readRoleRoutingMarker(stateDir, { cwd, sessionId }),
+ persistedCapacityBlocker: await readJsonIfExists(nativeSubagentCapacityBlockerPath(stateDir)),
+ cwd,
+ sessionId,
+ });
+ if (
+ payloadAdvertisesTypedNativeSpawn(payload, rootTranscript)
+ && (
+ nativeSupport.status === "supported"
+ || payloadAdvertisesCodexAppV2NativeSpawn(payload)
+ || rootTranscript?.hasTypedNativeSpawn === true
+ )
+ ) {
+ bootstrap = await beginNativeUltragoalBootstrap({
+ cwd: policyCwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ backend: nativeConfig.backend,
+ ttlSeconds: nativeConfig.assignmentTtlSeconds,
+ });
+ }
+ }
+ const ready = await findReadyLocalNativeExecutorAssignment({
+ cwd: policyCwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ });
+ if (ready) {
+ const activation = await prepareNativeUltragoalBootstrapActivation({
+ cwd: policyCwd,
+ stateDir,
+ sessionId,
+ childAgentId: ready.child_agent_id,
+ });
+ if (activation.ok) return null;
+ }
+ const reason = bootstrap
+ ? buildNativeUltragoalBootstrapRequiredReason(sessionId, rootThreadId, bootstrap.generation)
+ : ULTRAGOAL_NO_OWNER_DENY_REASON;
+ return {
+ decision: "block",
+ reason,
+ hookSpecificOutput: {
+ hookEventName: "PreToolUse",
+ additionalContext: reason,
+ },
+ };
+ }
+
return {
decision: "block",
reason: ULTRAGOAL_NO_OWNER_DENY_REASON,
hookSpecificOutput: {
hookEventName: "PreToolUse",
additionalContext:
- "Standalone Ultragoal Conductor mode requires an attached tmux session (Team execution) on native Codex App "
- + "outside tmux; native child/descendant provenance does not grant write authority. Do not set ultragoal "
- + "active/current_phase here. Proceed with direct bounded implementation for this task without "
+ "Standalone Ultragoal Conductor mode requires either an attached tmux session (Team execution) or a positively "
+ + "advertised typed native spawn surface backed by scoped write assignments; neither is proven on this native "
+ + "Codex App outside-tmux event. Do not set "
+ + "ultragoal active/current_phase here. Proceed with direct bounded implementation for this task without "
+ "entering Ultragoal's Conductor-gated planning mode, or re-run from an attached tmux OMX CLI shell so "
+ "`omx team` is available. `omx cancel` remains available if a stuck Conductor state already exists.",
},
};
}
+async function buildNativeUltragoalBootstrapMutationGuardOutput(
+ payload: CodexHookPayload,
+ cwd: string,
+ stateDir: string,
+ sessionId: string,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
+): Promise<Record<string, unknown> | null> {
+ if (safeString(payload.tool_name).trim() !== "Bash") return null;
+ const command = readPreToolUseCommand(payload);
+ if (!/\bomx\s+ultragoal\s+native-bootstrap\b/.test(command)) return null;
+ const actor = await resolvePreToolUseWriteActor(payload, cwd, stateDir, sessionId, rootTranscript);
+ if (actor === "main-root") return null;
+ const reason = actor === "native-child"
+ ? "OWNER_CONFIRMATION_REQUIRED: native Ultragoal bootstrap metadata is root-owned; a native child cannot authorize, revoke, or reconcile its own assignment."
+ : "PROVENANCE_DENIED: native Ultragoal bootstrap mutation requires exact Main-root session provenance.";
+ return {
+ decision: "block",
+ reason,
+ hookSpecificOutput: {
+ hookEventName: "PreToolUse",
+ additionalContext: reason,
+ },
+ };
+}
+
+function isExactNativeUltragoalBootstrapCommand(command: string): boolean {
+ if (nativeAssignedBashHasUnsafeStructure(".", command)) return false;
+ const words = tokenizeConductorShellWords(command).map(shellWordLiteral);
+ return words.length >= 4
+ && basename(words[0] ?? "") === "omx"
+ && words[1] === "ultragoal"
+ && words[2] === "native-bootstrap"
+ && ["authorize", "status", "revoke"].includes(words[3] ?? "");
+}
+
+async function buildPendingNativeUltragoalExecutorGuardOutput(
+ payload: CodexHookPayload,
+ cwd: string,
+ stateDir: string,
+ sessionId: string,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
+): Promise<Record<string, unknown> | null> {
+ if (!sessionId) return null;
+ let bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ if (!bootstrap || bootstrap.status === "revoked" || bootstrap.status === "expired") {
+ return null;
+ }
+ if (bootstrap.status === "active") {
+ const state = await readStopSessionPinnedState("ultragoal-state.json", cwd, sessionId, stateDir);
+ if (isActiveConductorModeState(state, "ultragoal", sessionId)) return null;
+ await revokeLocalNativeExecutorAssignment({
+ stateDir,
+ sessionId,
+ reason: "ultragoal_state_not_active",
+ });
+ bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionId);
+ }
+ const actor = await resolvePreToolUseWriteActor(payload, cwd, stateDir, sessionId, rootTranscript);
+ if (actor !== "native-child") return null;
+ const toolName = safeString(payload.tool_name).trim();
+ if (classifyPreToolUseMutationTransport(payload, toolName, cwd) === "read-only") return null;
+ if (await resolveAuthorizedSendMessageChildToLeader(payload, toolName, cwd, sessionId)) return null;
+ const reason = "OWNER_CONFIRMATION_REQUIRED: native Ultragoal bootstrap is not active; spawned executors remain read-only until the exact assignment/receipt validates and Main-root completes activation.";
+ return {
+ decision: "block",
+ reason,
+ hookSpecificOutput: {
+ hookEventName: "PreToolUse",
+ additionalContext: reason,
+ },
+ };
+}
+
function normalizeRepoRelativePath(cwd: string, rawPath: string): string | null {
const candidate = rawPath.trim();
if (!candidate || isUnresolvedVariableTarget(candidate)) return null;
@@ -11071,6 +12101,14 @@ function conductorPathTraversesLink(cwd: string, relativePath: string): boolean
return false;
}
+function isSessionBoundNativeAssignmentPath(cwd: string, rawPath: string, sessionId: string): boolean {
+ const relativePath = normalizeRepoRelativePath(cwd, rawPath);
+ const match = relativePath
+ ? /^\.omx\/state\/sessions\/([^/]+)\/native-assignments\/[^/]+\.json$/.exec(relativePath)
+ : null;
+ return sessionId !== "" && match?.[1] === sessionId;
+}
+
function isAllowedConductorMetadataPath(cwd: string, rawPath: string): boolean {
const relativePath = normalizeRepoRelativePath(cwd, rawPath);
if (!relativePath || conductorPathnameExpansionIsAmbiguous(relativePath)) return false;
@@ -11942,6 +12980,18 @@ function isPositivelyReadOnlyGitCommand(words: string[], commandIndex: number):
}
const subcommand = shellWordLiteral(args[index] ?? "");
if (!subcommand) return false;
+ if (subcommand === "status") {
+ return index === 0
+ && args.length === 2
+ && shellWordLiteral(args[1] ?? "") === "--short";
+ }
+ if (subcommand === "diff") {
+ return args.length === index + 5
+ && shellWordLiteral(args[index + 1] ?? "") === "--no-ext-diff"
+ && shellWordLiteral(args[index + 2] ?? "") === "--no-textconv"
+ && shellWordLiteral(args[index + 3] ?? "") === "--"
+ && shellWordLiteral(args[index + 4] ?? "") === ".";
+ }
const allowedOptions = new Map<string, Set<string>>([
["cat-file", new Set(["-e", "-t", "-s", "--exists", "--batch", "--batch-check", "--batch-command", "--buffer", "--follow-symlinks", "--allow-unknown-type", "--unordered"])],
["ls-files", new Set(["-c", "--cached", "-d", "--deleted", "-m", "--modified", "-o", "--others", "-i", "--ignored", "--exclude-standard", "--directory", "--no-empty-directory", "--full-name", "--stage", "--debug", "--eol", "--deduplicate", "--error-unmatch"])],
@@ -12349,7 +13399,35 @@ function sedScriptIsPositivelyReadOnly(script: string): boolean {
const normalized = shellWordLiteral(script).trim();
const substitution = parseConductorSingleSubstitutionProgram(normalized);
if (substitution) return !/[ew]/.test(substitution.flags);
- return /^[0-9$.,+~\-]*(?:p|P|q|Q|n|N|l|d|=)$/.test(normalized);
+ return /^[0-9$.,+~\-\s;{}pPqQnNld=]+$/.test(normalized)
+ && /(?:p|P|q|Q|n|N|l|d|=)/.test(normalized);
+}
+
+function isPositivelyClassifiedFindCommand(words: string[], commandIndex: number): boolean {
+ const args = collectConductorInvocationWords(words, commandIndex);
+ let sawPath = false;
+ for (let index = 0; index < args.length; index += 1) {
+ const raw = args[index] ?? "";
+ const word = shellWordLiteral(raw);
+ if (!word || isDynamicNestedCommandString(word) || /[$`]/.test(raw)) return false;
+ if (!word.startsWith("-") && !new Set(["!", "(", ")"]).has(word)) {
+ if (!/^[A-Za-z0-9._~/:=@,+{}-]+$/.test(word)) return false;
+ sawPath = true;
+ continue;
+ }
+ if (new Set(["!", "(", ")", "-a", "-and", "-o", "-or", "-print", "-print0", "-prune", "-empty", "-false", "-true"]).has(word)) continue;
+ if (new Set(["-type", "-name", "-iname", "-path", "-ipath", "-maxdepth", "-mindepth"]).has(word)) {
+ const valueRaw = args[index + 1] ?? "";
+ const value = shellWordLiteral(valueRaw);
+ if (!value || isDynamicNestedCommandString(value) || /[$`]/.test(valueRaw)) return false;
+ if ((word === "-maxdepth" || word === "-mindepth") && !/^[0-9]+$/.test(value)) return false;
+ if (word === "-type" && !/^[bcdpfls]$/.test(value)) return false;
+ index += 1;
+ continue;
+ }
+ return false;
+ }
+ return sawPath;
}
function isPositivelyClassifiedSedCommand(words: string[], commandIndex: number): boolean {
@@ -12948,7 +14026,12 @@ function inspectConductorRuntimeExecutions(command: string, cwd?: string, depth
inspection.uninspectedCommandNames.push(commandName);
}
} else if (commandName === "git") {
- if (commandSetsGitHelper || gitCommandHasUnsafeRuntimeEnvironment(words, commandIndex) || !isPositivelyReadOnlyGitCommand(words, commandIndex)) {
+ if (
+ commandSetsGitHelper
+ || conductorRedirectProducerMayBeShadowed(topLevelCommand, "git")
+ || gitCommandHasUnsafeRuntimeEnvironment(words, commandIndex)
+ || !isPositivelyReadOnlyGitCommand(words, commandIndex)
+ ) {
inspection.uninspectedOtherRuntimeCount += 1;
inspection.uninspectedCommandNames.push(commandName);
}
@@ -12962,6 +14045,11 @@ function inspectConductorRuntimeExecutions(command: string, cwd?: string, depth
inspection.uninspectedOtherRuntimeCount += 1;
inspection.uninspectedCommandNames.push(commandName);
}
+ } else if (commandName === "find") {
+ if (!isPositivelyClassifiedFindCommand(words, commandIndex)) {
+ inspection.uninspectedOtherRuntimeCount += 1;
+ inspection.uninspectedCommandNames.push(commandName);
+ }
} else if (
(commandName === "npm" || commandName === "pnpm" || commandName === "yarn")
&& packageManagerInvokesScriptRuntime(words, commandIndex)
@@ -16096,6 +17184,132 @@ function conductorOrchestrationWordIsStatic(word: string): boolean {
&& !/(?:^|[^\\])[<>]\(/.test(word);
}
+function isExactLeaderOwnedUltragoalMetadataCommand(
+ command: string,
+ rawCommand: string,
+ cwd: string,
+): boolean {
+ if (
+ command !== rawCommand
+ || !isSingleLiteralShellInvocation(command)
+ || hasUnquotedShellFilenameExpansion(command)
+ ) return false;
+ const words = tokenizeConductorShellWords(command);
+ if (words.length < 3) return false;
+ if (!words.every(conductorOrchestrationWordIsStatic)) return false;
+ const commandWord = shellWordLiteral(words[0] ?? "");
+ if (commandWord === "omx") {
+ if (!omxOrGjcExecutionContextIsTrusted(command, cwd, ["omx"])) return false;
+ } else {
+ if (!isAbsolute(commandWord) || !commandWord.includes("/") || commandNameFromShellWord(commandWord) !== "omx") return false;
+ if (commandHasUnsafeConductorShellState(command, cwd)) return false;
+ if (commandHasUnsafeDynamicLoaderEnvironment(command) || commandHasUnsafeLeadingRuntimeEnvironment(command)) return false;
+ const unsafeInheritedNames = [...OMX_GJC_TRUSTED_CONTEXT_UNSAFE_INHERITED_ENV_NAMES, ...CONDUCTOR_NODE_OUTPUT_ENVIRONMENT_NAMES];
+ if (unsafeInheritedNames.some((name) => safeString(process.env[name]).trim() !== "")) return false;
+ const state = resolveConductorCommandPathState(words, 0, 0, createConductorRuntimeShellState(cwd));
+ if (!conductorSlashCommandIsTrusted(commandWord, state, cwd)) return false;
+ }
+
+ const args = words.slice(1);
+ if (shellWordLiteral(args[0] ?? "") !== "ultragoal") return false;
+ const subcommand = shellWordLiteral(args[1] ?? "");
+ const trailing = args.slice(2);
+
+ const parseOptions = (
+ repeatableValueOptions: ReadonlySet<string>,
+ uniqueValueOptions: ReadonlySet<string>,
+ flagOptions: ReadonlySet<string>,
+ ): Map<string, string[]> | null => {
+ const seen = new Map<string, string[]>();
+ for (let index = 0; index < trailing.length; index += 1) {
+ const rawOption = trailing[index] ?? "";
+ const option = shellWordLiteral(rawOption);
+ if (!option || !option.startsWith("--") || option === "--") return null;
+ if (flagOptions.has(option)) {
+ if (seen.has(option)) return null;
+ seen.set(option, []);
+ continue;
+ }
+ const name = option.split("=", 1)[0] ?? "";
+ if (!repeatableValueOptions.has(name) && !uniqueValueOptions.has(name)) return null;
+ if (uniqueValueOptions.has(name) && seen.has(name)) return null;
+ const inlineValue = option.startsWith(`${name}=`);
+ const rawValue = inlineValue ? rawOption.slice(rawOption.indexOf("=") + 1) : trailing[index + 1] ?? "";
+ const value = shellWordLiteral(rawValue);
+ if (
+ !value
+ || !conductorOrchestrationWordIsStatic(rawValue)
+ || (!inlineValue && value.startsWith("-"))
+ ) return null;
+ if (option === name) index += 1;
+ seen.set(name, [...(seen.get(name) ?? []), value]);
+ }
+ return seen;
+ };
+
+ if (subcommand === "create" || subcommand === "create-goals") {
+ if (trailing.some((word) => ["--force", "--brief-file", "--from-stdin"].includes(shellWordLiteral(word)))) return false;
+ const parsed = parseOptions(new Set(["--goal"]), new Set(["--brief", "--codex-goal-mode"]), new Set(["--json"]));
+ const goalMode = parsed?.get("--codex-goal-mode")?.[0];
+ return Boolean(parsed?.has("--brief"))
+ && (goalMode === undefined || ["aggregate", "per-story", "per_story"].includes(goalMode));
+ }
+ if (["complete", "complete-goals", "next", "start-next"].includes(subcommand)) {
+ return parseOptions(new Set(), new Set(), new Set(["--retry-failed", "--json"])) !== null;
+ }
+ if (subcommand === "status") {
+ return parseOptions(new Set(), new Set(["--codex-goal-json"]), new Set(["--json"])) !== null;
+ }
+ if (subcommand === "steer") {
+ const parsed = parseOptions(
+ new Set(),
+ new Set(["--kind", "--target-goal-id", "--evidence", "--rationale"]),
+ new Set(["--json"]),
+ );
+ return parsed?.get("--kind")?.[0] === "annotate_ledger"
+ && parsed.has("--evidence")
+ && parsed.has("--rationale")
+ && parsed.has("--json");
+ }
+ if (subcommand === "checkpoint") {
+ const parsed = parseOptions(
+ new Set(),
+ new Set(["--goal-id", "--status", "--evidence", "--codex-goal-json", "--quality-gate-json"]),
+ new Set(["--json"]),
+ );
+ if (
+ !parsed?.has("--goal-id")
+ || !parsed.has("--status")
+ || !parsed.has("--evidence")
+ || !parsed.has("--json")
+ ) return false;
+ const status = parsed.get("--status")?.[0];
+ if (status === "complete") {
+ return parsed.has("--codex-goal-json") && parsed.has("--quality-gate-json");
+ }
+ if (status === "blocked") {
+ return parsed.has("--codex-goal-json") && !parsed.has("--quality-gate-json");
+ }
+ return status === "failed"
+ && !parsed.has("--codex-goal-json")
+ && !parsed.has("--quality-gate-json");
+ }
+ return false;
+}
+
+function isUltragoalMetadataCommandAttempt(command: string): boolean {
+ const words = tokenizeConductorShellWords(command);
+ const commandIndex = skipShellCommandPositionPrefixWords(words, 0);
+ if (commandNameFromShellWord(words[commandIndex] ?? "") !== "omx") return false;
+ const args = collectConductorInvocationWords(words, commandIndex).map(shellWordLiteral);
+ return args[0] === "ultragoal"
+ && [
+ "create", "create-goals",
+ "complete", "complete-goals", "next", "start-next",
+ "status", "steer", "checkpoint",
+ ].includes(args[1] ?? "");
+}
+
function isStaticallyRecognizedConductorOrchestrationMutation(
commandName: string,
words: string[],
@@ -19822,6 +21036,85 @@ function conductorStatePayloadPreservesActiveGuard(
return phase !== "" && isNonTerminalPhase(phase);
}
+function nativeAssignmentTargetIsWithinScope(
+ cwd: string,
+ rawTarget: string,
+ pathPrefixes: readonly string[],
+): boolean {
+ const relativeTarget = normalizePlanningArtifactRelativePath(cwd, rawTarget);
+ if (!relativeTarget || conductorPathnameExpansionIsAmbiguous(relativeTarget)) return false;
+ if (conductorPathTraversesLink(cwd, relativeTarget)) return false;
+ if (
+ relativeTarget === ".git"
+ || relativeTarget.startsWith(".git/")
+ || relativeTarget === ".omx"
+ || relativeTarget.startsWith(".omx/")
+ ) return false;
+ return pathPrefixes.some((prefix) => (
+ prefix === "."
+ || relativeTarget === prefix
+ || relativeTarget.startsWith(`${prefix}/`)
+ ));
+}
+
+function nativeAssignedBashHasUnsafeStructure(cwd: string, command: string): boolean {
+ const normalized = normalizeShellLineContinuations(command);
+ if (
+ splitConductorShellSegments(stripHeredocBodiesForCommandScan(normalized)).length !== 1
+ || hasUnresolvedShellArithmeticExpansion(normalized)
+ || hasUnquotedShellSubstitution(normalized)
+ || hasDynamicNestedShellExecution(normalized)
+ || hasUnsafeUnquotedHeredocExpansion(normalized)
+ || commandHasUnsafeConductorShellState(normalized, cwd)
+ || conductorCommandMayMutatePathResolution(normalized)
+ ) return true;
+ const interpreterWrites = extractConductorInterpreterWrites(normalized);
+ return interpreterWrites.some((write) => write.unresolved || write.targets.length === 0);
+}
+
+async function nativeChildAssignmentAllowsMutation(
+ payload: CodexHookPayload,
+ cwd: string,
+ stateDir: string,
+ sessionId: string,
+ toolName: string,
+ mutationTransport: PreToolUseMutationTransport,
+): Promise<boolean> {
+ if (
+ mutationTransport === "state"
+ || mutationTransport === "orchestration"
+ || mutationTransport === "goal-lifecycle"
+ || mutationTransport === "unknown"
+ ) {
+ return false;
+ }
+ const assignment = await readNativeSubagentAssignment(payload, cwd, stateDir, sessionId);
+ if (!assignment) return false;
+
+ if (mutationTransport === "path") {
+ if (!assignment.allowed_actions.includes("path-write")) return false;
+ const candidates = collectImplementationToolPathCandidates(
+ payload,
+ toolName,
+ readPreToolUsePathCandidates(payload),
+ );
+ return candidates.length > 0
+ && candidates.every((candidate) => (
+ !isNativeAssignmentPath(stateDir, candidate, cwd)
+ && nativeAssignmentTargetIsWithinScope(cwd, candidate, assignment.path_prefixes)
+ ));
+ }
+ if (mutationTransport !== "bash") return false;
+
+ const command = readPreToolUseCommand(payload);
+ if (nativeAssignedBashHasUnsafeStructure(cwd, command)) return false;
+ if (!assignment.allowed_actions.includes("bash-write")) return false;
+ const targets = extractDeepInterviewCommandWriteTargets(command, cwd, cwd);
+ if (targets.some((target) => isNativeAssignmentPath(stateDir, target, cwd))) return false;
+ return targets.length > 0 && targets.every((target) => (
+ nativeAssignmentTargetIsWithinScope(cwd, target, assignment.path_prefixes)
+ ));
+}
function buildConductorSessionProvenanceDeny(
activeState: ActiveConductorState,
@@ -19846,14 +21139,38 @@ export async function buildConductorPreToolUseWriteGuardOutput(
stateDir: string,
resolvedSessionId?: string,
policyCwd = cwd,
+ rootTranscript: SafeRootTranscriptMetadata | null = null,
+ pointer: SessionPointerReadResult | null = null,
): Promise<Record<string, unknown> | null> {
const activeState = await readActiveConductorStateForPreToolUse(payload, policyCwd, stateDir, resolvedSessionId);
if (!activeState) return null;
const sessionId = safeString(resolvedSessionId ?? readPayloadSessionId(payload)).trim();
- const writeActor = await resolvePreToolUseWriteActor(payload, cwd, stateDir, sessionId);
+ const writeActor = await resolvePreToolUseWriteActor(payload, cwd, stateDir, sessionId, rootTranscript);
if (writeActor === "provenance-conflict") {
return buildConductorSessionProvenanceDeny(activeState, "payload identity aliases conflict");
}
+ if (
+ writeActor === "main-root"
+ && await isAuthorizedActiveUltragoalPhaseTransitionFallback({
+ payload,
+ policyCwd,
+ stateDir,
+ sessionId,
+ pointer,
+ rootTranscript,
+ })
+ ) return null;
+ if (
+ writeActor === "main-root"
+ && await isAuthorizedTerminalUltragoalStateFallback({
+ payload,
+ policyCwd,
+ stateDir,
+ sessionId,
+ pointer,
+ rootTranscript,
+ })
+ ) return null;
const nativeSubagentSupport = resolveNativeSubagentSupportStatus({
payload,
persistedSupportBlocker: await readJsonIfExists(nativeSubagentSupportBlockerPath(stateDir)),
@@ -19871,9 +21188,26 @@ export async function buildConductorPreToolUseWriteGuardOutput(
const command = readPreToolUseCommand(payload);
const pathCandidates = readPreToolUsePathCandidates(payload);
const mutationTransport = classifyPreToolUseMutationTransport(payload, toolName, cwd);
+ const leaderMetadataCommandAttempt = writeActor === "main-root"
+ && toolName === "Bash"
+ && isUltragoalMetadataCommandAttempt(command);
- let blocked = false;
- let blockedDetail = "Main-root Conductor write is not delegated";
+ if (
+ writeActor === "main-root"
+ && toolName === "Bash"
+ && (
+ isExactNativeUltragoalBootstrapCommand(command)
+ || (
+ leaderMetadataCommandAttempt
+ && isExactLeaderOwnedUltragoalMetadataCommand(command, readPreToolUseRawCommand(payload), policyCwd)
+ )
+ )
+ ) return null;
+
+ let blocked = leaderMetadataCommandAttempt;
+ let blockedDetail = leaderMetadataCommandAttempt
+ ? "Ultragoal metadata command does not match the exact leader-owned option schema"
+ : "Main-root Conductor write is not delegated";
let nativeChildMutationAttempt = false;
if (toolName === "Bash") {
@@ -19925,7 +21259,10 @@ export async function buildConductorPreToolUseWriteGuardOutput(
blocked = true;
blockedDetail = describeConductorBlockedWrite(toolName, undefined, toolPathCandidates.length);
} else {
- const blockedPath = toolPathCandidates.find((candidate) => !isAllowedConductorMetadataExecutionPath(cwd, policyCwd, candidate));
+ const blockedPath = toolPathCandidates.find((candidate) => (
+ !isSessionBoundNativeAssignmentPath(policyCwd, candidate, sessionId)
+ && !isAllowedConductorMetadataExecutionPath(cwd, policyCwd, candidate)
+ ));
blocked = blockedPath !== undefined;
if (blockedPath !== undefined) {
blockedDetail = describeConductorBlockedWrite(toolName, blockedPath, toolPathCandidates.length);
@@ -19945,11 +21282,23 @@ export async function buildConductorPreToolUseWriteGuardOutput(
stateDir,
policyCwd,
);
- if (writeActor === "team-worker" && !teamWorkerProtectedStateTarget) return null;
+ if (writeActor === "team-worker" && mutationTransport !== "goal-lifecycle" && !teamWorkerProtectedStateTarget) return null;
if (writeActor === "team-worker" && teamWorkerProtectedStateTarget && !blocked) {
blocked = true;
blockedDetail = "Bash targets protected workflow state outside authorized Team-worker scope";
}
+ if (
+ writeActor === "native-child"
+ && nativeChildMutationAttempt
+ && await nativeChildAssignmentAllowsMutation(
+ payload,
+ policyCwd,
+ stateDir,
+ sessionId,
+ toolName,
+ mutationTransport,
+ )
+ ) return null;
if (!blocked && (writeActor !== "native-child" || !nativeChildMutationAttempt)) return null;
if (!blocked && nativeChildMutationAttempt && writeActor === "native-child") {
blockedDetail = toolName === "Bash"
@@ -21573,9 +22922,16 @@ export async function dispatchCodexNativeHook(
: "";
const threadId = safeString(payload.thread_id ?? payload.threadId).trim();
const turnId = safeString(payload.turn_id ?? payload.turnId).trim();
+ const safeRootTranscript = hookEventName === "UserPromptSubmit" || hookEventName === "PreToolUse" || hookEventName === "Stop"
+ ? await readSafeRootTranscriptMetadata(payload, cwd, options.rootTranscriptPostReadHook, {
+ beforeReadDirHook: options.rootTranscriptBeforeReadDirHook,
+ maxEntries: options.rootTranscriptScanMaxEntries,
+ })
+ : null;
+ const safeRootTurnTranscript = safeRootTranscript?.hasExactTurnContext ? safeRootTranscript : null;
const pointer = await readSessionPointer(pointerContext);
const currentSessionState = pointer.status === "usable" ? pointer.state ?? null : null;
- let promptTurnContext: ResolvedPromptTurnContext | null = hookEventName === "UserPromptSubmit"
+ let promptTurnContext: ResolvedPromptTurnContext | null = hookEventName === "UserPromptSubmit" && !safeRootTurnTranscript
? evaluateResolvedPromptTurn({
producer: "native",
payloadSessionId: payload.session_id ?? payload.sessionId,
@@ -21608,9 +22964,14 @@ export async function dispatchCodexNativeHook(
let canonicalSessionId = safeString(currentSessionState?.session_id).trim();
if (promptTurnContext?.status === "authorized") {
canonicalSessionId = promptTurnContext.authorization.targetSessionId;
+ } else if (safeRootTurnTranscript) {
+ canonicalSessionId = safeRootTurnTranscript.sessionId;
}
let allowGlobalSideEffects = promptTurnContext?.status !== "authorized"
|| promptTurnContext.authorization.globalSideEffects === "allow";
+ if (safeRootTurnTranscript && currentSessionState && !payloadMatchesSessionPointer(safeRootTurnTranscript.sessionId, currentSessionState)) {
+ allowGlobalSideEffects = false;
+ }
let resolvedNativeSessionId = nativeSessionId;
let skipCanonicalSessionStartContext = false;
let isSubagentSessionStart = false;
@@ -21801,8 +23162,16 @@ export async function dispatchCodexNativeHook(
if (hookEventName === "Stop") {
const stopPayloadSessionId = readPayloadSessionId(payload);
const authorizedWorkerStopSessionId = authoritativeWorkerPayloadSessionId;
+ const rootTranscriptAuthorizesStaleStop = !declaredTeamWorker
+ && pointer.status === "stale-dead"
+ && pointer.state !== null
+ && pointer.state !== undefined
+ && isSessionStateAuthoritativeForCwd(pointer.state, cwd)
+ && safeRootTranscript?.sessionId === stopPayloadSessionId;
const stopCanonicalSessionId = declaredTeamWorker && !authorizedWorkerStopSessionId
? ""
+ : rootTranscriptAuthorizesStaleStop
+ ? stopPayloadSessionId
: await resolveInternalSessionIdForPayload(
cwd,
authorizedWorkerStopSessionId || stopPayloadSessionId,
@@ -21843,6 +23212,13 @@ export async function dispatchCodexNativeHook(
} else if (stopCanonicalSessionId) {
canonicalSessionId = stopCanonicalSessionId;
}
+ if (rootTranscriptAuthorizesStaleStop) {
+ canonicalSessionId = stopPayloadSessionId;
+ resolvedNativeSessionId = stopPayloadSessionId;
+ allowImplicitSessionSideEffects = true;
+ allowGlobalSideEffects = false;
+ stopAuthorizationFailure = null;
+ }
if (authorizedWorkerStopSessionId && stopCanonicalSessionId === authorizedWorkerStopSessionId) {
allowImplicitSessionSideEffects = true;
stopAuthorizationFailure = null;
@@ -21919,7 +23295,7 @@ export async function dispatchCodexNativeHook(
} else if (prompt && !isSubagentPromptSubmit && allowImplicitSessionSideEffects) {
const rawHookSessionId = canonicalSessionId || nativeSessionId;
const normalizedHookSessionId = normalizeSessionId(rawHookSessionId);
- const explicitHookSessionId = currentSessionState ? undefined : normalizedHookSessionId;
+ const explicitHookSessionId = safeRootTurnTranscript?.sessionId ?? (currentSessionState ? undefined : normalizedHookSessionId);
if (rawHookSessionId && !normalizedHookSessionId) {
suppressActivationSeeding = true;
} else {
@@ -21948,6 +23324,7 @@ export async function dispatchCodexNativeHook(
sessionIdForState || undefined,
threadId || undefined,
turnId || undefined,
+ safeRootTurnTranscript,
) ?? await recordSkillActivation({
stateDir,
sourceCwd: cwd,
@@ -21963,6 +23340,29 @@ export async function dispatchCodexNativeHook(
},
});
}
+ if (
+ skillState?.active === true
+ && skillState.initialized_mode === "ultragoal"
+ && sessionIdForState
+ && isNativeOutsideTmuxUserPrompt(cwd, payload, sessionIdForState)
+ ) {
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, sessionIdForState);
+ let receiptConfirmed = bootstrap?.status === "active";
+ if (bootstrap && ["ready", "activating"].includes(bootstrap.status) && bootstrap.child_agent_id) {
+ const confirmed = await markNativeUltragoalBootstrapActive({
+ cwd,
+ stateDir,
+ sessionId: sessionIdForState,
+ childAgentId: bootstrap.child_agent_id,
+ });
+ receiptConfirmed = confirmed.ok;
+ }
+ if (!receiptConfirmed && resolveNativeUltragoalConfig().backend === "local-experimental") {
+ const reason = "native_ultragoal_activation_receipt_invalid";
+ await failNativeUltragoalActivation(cwd, stateDir, sessionIdForState, reason);
+ skillState = { ...skillState, active: false, transition_error: reason };
+ }
+ }
// --- Triage classifier (advisory-only, non-keyword prompts) ---
if (
prompt
@@ -22186,6 +23586,8 @@ export async function dispatchCodexNativeHook(
stateDir,
payloadSessionId,
payloadPolicyCwd,
+ safeRootTranscript,
+ pointer,
)
: null;
const directCancelCommand = safeString(payload.tool_name).trim() === "Bash"
@@ -22203,8 +23605,18 @@ export async function dispatchCodexNativeHook(
activeState: sessionBinding.valid
? (await readStopSessionPinnedState("autopilot-state.json", policyCwd, sessionBinding.canonicalSessionId, stateDir) ?? {})
: {},
+ rootTranscript: safeRootTranscript,
});
- if (directCancel.kind !== "not-direct-cancel") outputJson = directCancel.output;
+ if (directCancel.kind !== "not-direct-cancel") {
+ if (directCancel.kind === "handled" && sessionBinding.canonicalSessionId) {
+ await revokeLocalNativeExecutorAssignment({
+ stateDir,
+ sessionId: sessionBinding.canonicalSessionId,
+ reason: "root_cancelled",
+ });
+ }
+ outputJson = directCancel.output;
+ }
}
if (!outputJson && !policyRoot.valid && policyRoot.statePresent && mutationTransport !== "read-only") {
outputJson = buildConductorSessionProvenanceDeny(
@@ -22303,6 +23715,8 @@ export async function dispatchCodexNativeHook(
stateDir,
payloadSessionId,
policyCwd,
+ safeRootTranscript,
+ pointer,
)
: null;
outputJson = buildNativeUnknownRolePreToolUseOutput(payload, policyCwd)
@@ -22326,12 +23740,21 @@ export async function dispatchCodexNativeHook(
})();
outputJson = nativePreToolUseSpecificDeny
?? buildNativeUnknownRolePreToolUseOutput(payload, policyCwd)
+ ?? await buildPendingNativeUltragoalExecutorGuardOutput(
+ payload,
+ policyCwd,
+ stateDir,
+ preToolUseSessionId,
+ safeRootTranscript,
+ )
?? await buildDeepInterviewPreToolUseBoundaryOutput(
payload,
policyCwd,
stateDir,
preToolUseSessionId,
cwd,
+ cwd,
+ safeRootTranscript,
)
?? await buildRalplanPreToolUseBoundaryOutput(
payload,
@@ -22339,6 +23762,8 @@ export async function dispatchCodexNativeHook(
stateDir,
preToolUseSessionId,
cwd,
+ cwd,
+ safeRootTranscript,
)
?? await buildPlanningRootPointerConflictPreToolUseOutput(
payload,
@@ -22346,12 +23771,21 @@ export async function dispatchCodexNativeHook(
stateDir,
rootPointerConflict,
)
+ ?? await buildNativeUltragoalBootstrapMutationGuardOutput(
+ payload,
+ policyCwd,
+ stateDir,
+ preToolUseSessionId,
+ safeRootTranscript,
+ )
?? await buildUltragoalNoOwnerActivationGuardOutput(
payload,
cwd,
stateDir,
preToolUseSessionId,
policyCwd,
+ safeRootTranscript,
+ pointer,
)
?? await buildConductorPreToolUseWriteGuardOutput(
payload,
@@ -22359,8 +23793,17 @@ export async function dispatchCodexNativeHook(
stateDir,
preToolUseSessionId,
policyCwd,
+ safeRootTranscript,
+ pointer,
+ )
+ ?? await buildRawProtectedWorkflowStatePathOutput(
+ payload,
+ policyCwd,
+ stateDir,
+ preToolUseSessionId,
+ guardedConductorState !== null,
+ safeRootTranscript,
)
- ?? buildRawProtectedWorkflowStatePathOutput(payload, policyCwd, stateDir)
?? await buildNativeSubagentCapacityCloseGuardOutput(payload, policyCwd, stateDir)
?? buildMalformedPreToolUseBlockTestOutput(payload)
?? buildNativePreToolUseOutput(payload);
@@ -22375,6 +23818,34 @@ export async function dispatchCodexNativeHook(
}
await handleTeamWorkerPostToolUseSuccess(payload, cwd);
}
+ if (canonicalSessionId && isNativeOutsideTmuxUserPrompt(cwd, payload, canonicalSessionId)) {
+ const toolName = safeString(payload.tool_name).trim();
+ const activationCandidates = collectUltragoalActivationCandidatePayloads(payload, toolName, cwd);
+ if (activationCandidates.some((candidate) => isUltragoalConductorActivationPayload(candidate))) {
+ const bootstrap = await readNativeUltragoalBootstrap(stateDir, canonicalSessionId);
+ const state = await readStopSessionPinnedState("ultragoal-state.json", cwd, canonicalSessionId, stateDir);
+ if (isActiveConductorModeState(state, "ultragoal", canonicalSessionId)) {
+ let receiptConfirmed = bootstrap?.status === "active";
+ if (bootstrap?.status === "activating" && bootstrap.child_agent_id) {
+ const confirmed = await markNativeUltragoalBootstrapActive({
+ cwd,
+ stateDir,
+ sessionId: canonicalSessionId,
+ childAgentId: bootstrap.child_agent_id,
+ });
+ receiptConfirmed = confirmed.ok;
+ }
+ if (!receiptConfirmed && resolveNativeUltragoalConfig().backend === "local-experimental") {
+ await failNativeUltragoalActivation(
+ cwd,
+ stateDir,
+ canonicalSessionId,
+ "native_ultragoal_activation_receipt_invalid",
+ );
+ }
+ }
+ }
+ }
outputJson = buildNativePostToolUseOutput(payload);
} else if (hookEventName === "Stop") {
if (declaredTeamWorkerStopOnly) {
@@ -22413,6 +23884,9 @@ export async function dispatchCodexNativeHook(
};
}
}
+ if (!declaredTeamWorkerStopOnly && canonicalSessionId) {
+ await revokeTerminalNativeUltragoalBootstrap(policyCwd, stateDir, canonicalSessionId);
+ }
}
return {
diff --git a/src/scripts/notify-hook.ts b/src/scripts/notify-hook.ts
index 6c7e2cbc..42ab6e28 100644
--- a/src/scripts/notify-hook.ts
+++ b/src/scripts/notify-hook.ts
@@ -301,7 +301,8 @@ function looksLikeAutopilotTerminalHandoff(text: string): boolean {
function isTerminalModeStateObject(value: unknown, mode: string): boolean {
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
const state = value as Record<string, unknown>;
- if (safeString(state.mode).trim() !== mode) return false;
+ const persistedMode = safeString(state.mode).trim();
+ if (persistedMode && persistedMode !== mode) return false;
if (state.active === true) return false;
const phase = safeString(state.current_phase || state.currentPhase).trim().toLowerCase().replace(/_/g, '-');
if (['complete', 'completed', 'failed', 'cancelled', 'canceled', 'stopped', 'user-stopped'].includes(phase)) return true;
@@ -324,20 +325,40 @@ function terminalStateMatchesNotifyTurn(state: Record<string, unknown>, payload:
return Boolean(payloadThreadId && stateThreadId && payloadThreadId === stateThreadId);
}
-async function hasTerminalAutopilotStateForNotifyTurn(
+async function nativeStopReceiptMatchesNotifyTurn(
stateDir: string,
sessionId: string,
payload: Record<string, unknown>,
+): Promise<boolean> {
+ const payloadTurnId = safeString(payload['turn-id'] || payload.turn_id || '').trim();
+ if (!sessionId || !payloadTurnId) return false;
+ const rootState = await readJsonFileIfObject(join(stateDir, 'native-stop-state.json'));
+ const sessions = rootState?.sessions;
+ if (!sessions || typeof sessions !== 'object' || Array.isArray(sessions)) return false;
+ const session = (sessions as Record<string, unknown>)[sessionId];
+ if (!session || typeof session !== 'object' || Array.isArray(session)) return false;
+ const guard = (session as Record<string, unknown>).ordinary_no_progress_guard;
+ if (!guard || typeof guard !== 'object' || Array.isArray(guard)) return false;
+ return safeString((guard as Record<string, unknown>).last_turn_id).trim() === payloadTurnId;
+}
+
+async function hasTerminalModeStateForNotifyTurn(
+ stateDir: string,
+ sessionId: string,
+ payload: Record<string, unknown>,
+ mode: string,
): Promise<boolean> {
const state = await readScopedJsonIfExists(
stateDir,
- 'autopilot-state.json',
+ `${mode}-state.json`,
sessionId || undefined,
null,
{ includeRootFallback: true },
);
- return isTerminalModeStateObject(state, 'autopilot')
- && terminalStateMatchesNotifyTurn(state as Record<string, unknown>, payload);
+ if (!isTerminalModeStateObject(state, mode)) return false;
+ if (terminalStateMatchesNotifyTurn(state as Record<string, unknown>, payload)) return true;
+ return mode === 'ultragoal'
+ && await nativeStopReceiptMatchesNotifyTurn(stateDir, sessionId, payload);
}
async function shouldSuppressAutopilotTerminalReplayActivation(
@@ -352,7 +373,24 @@ async function shouldSuppressAutopilotTerminalReplayActivation(
const lastAssistantMessage = safeString(payload['last-assistant-message'] || payload.last_assistant_message || '');
if (!looksLikeAutopilotTerminalHandoff(lastAssistantMessage) && !isNotifyFallbackTaskCompletePayload(payload)) return false;
- return hasTerminalAutopilotStateForNotifyTurn(stateDir, sessionId, payload);
+ return hasTerminalModeStateForNotifyTurn(stateDir, sessionId, payload, 'autopilot');
+}
+
+async function shouldSuppressUltragoalTerminalReplayActivation(
+ stateDir: string,
+ payload: Record<string, unknown>,
+ isUltragoalActivation: boolean,
+ sessionId: string,
+): Promise<boolean> {
+ if (!isTurnCompletePayload(payload) && !isNotifyFallbackTaskCompletePayload(payload)) return false;
+ if (!isUltragoalActivation) return false;
+
+ // Native Codex notify replays the completed turn's original input after the
+ // final assistant message. A same-turn terminal state is stronger evidence
+ // than prose in that message and must win over the replayed `$ultragoal`
+ // keyword. A later turn has a different turn id and remains eligible to
+ // start a new run through the ordinary activation path.
+ return hasTerminalModeStateForNotifyTurn(stateDir, sessionId, payload, 'ultragoal');
}
export interface NotifySkillActivationInput {
@@ -425,6 +463,13 @@ export async function recordNotifySkillActivation(
input.sessionId || '',
);
if (terminalAutopilotReplay && runtimeMatches[0]?.skill === 'autopilot') return null;
+ const terminalUltragoalReplay = await shouldSuppressUltragoalTerminalReplayActivation(
+ input.stateDir,
+ input.payload,
+ runtimeMatches.some((match) => match.skill === 'ultragoal'),
+ input.sessionId || '',
+ );
+ if (terminalUltragoalReplay && runtimeMatches[0]?.skill === 'ultragoal') return null;
return (dependencies.recordSkillActivation ?? recordSkillActivation)({
stateDir: input.stateDir,
diff --git a/src/state/operations.ts b/src/state/operations.ts
index 3b3c99a5..c60433ff 100644
--- a/src/state/operations.ts
+++ b/src/state/operations.ts
@@ -134,6 +134,10 @@ export interface StateOperationResponse {
isError?: boolean;
}
+export interface StateOperationExecutionOptions {
+ beforeStateWriteCommit?: () => Promise<void>;
+}
+
const stateWriteQueues = new Map<string, Promise<void>>();
async function withStateWriteLock<T>(path: string, fn: () => Promise<T>): Promise<T> {
@@ -769,6 +773,7 @@ async function readSessionDetailTransitionModes(
export async function executeStateOperation(
name: StateOperationName,
rawArgs: Record<string, unknown> = {},
+ executionOptions: StateOperationExecutionOptions = {},
): Promise<StateOperationResponse> {
let cwd: string;
let explicitSessionId: string | undefined;
@@ -802,13 +807,17 @@ export async function executeStateOperation(
const mode = validateStateModeSegment(rawArgs.mode);
const { baseStateDir, rootSource } = getBaseStateDirWithSource(cwd);
await initializeStateEnvironment(cwd, effectiveSessionId, rootSource);
- const beforeCommit = createWritableCommitRevalidator({
+ const revalidateWritableScope = createWritableCommitRevalidator({
operation: 'state_write',
cwd,
explicitSessionId,
capturedScope: stateScope,
baseStateDir,
});
+ const beforeCommit: BeforeWritableCommit = async (event) => {
+ await revalidateWritableScope(event);
+ await executionOptions.beforeStateWriteCommit?.();
+ };
// Write to the exact resolved scope directory; never recompute the
// target root/path after authorization.
const path = join(stateScope.stateDir, getStateFilename(mode));
diff --git a/src/subagents/__tests__/tracker.test.ts b/src/subagents/__tests__/tracker.test.ts
index f5ace531..977adffa 100644
--- a/src/subagents/__tests__/tracker.test.ts
+++ b/src/subagents/__tests__/tracker.test.ts
@@ -5,7 +5,7 @@ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
import { hostname, tmpdir } from 'node:os';
import { join } from 'node:path';
import { describe, it } from 'node:test';
-import { __setCrossProcessPublishBarrierForTest, __setCrossProcessQuarantineBarrierForTest, consumeDirectChildReopenContext, CrossProcessLockLostError, buildSubagentResumeLedger, CROSS_PROCESS_LOCK_ARTIFACT_SWEEP_CAP, CROSS_PROCESS_LOCK_LEASE_MS, createSubagentTrackingState, crossProcessLockPath, DESCRIPTIVE_ADAPTED_PROVENANCE, fenceNativeSubagentAuthorities, forceGlobalAuthorityDenial, recordNativeSubagentAuthorityObservation, recordSubagentTurn, recordSubagentTurnForSession, NATIVE_SUBAGENT_PROVENANCE, readProcessStartIdentity, readSubagentTrackingState, readSubagentTrackingStateStrict, repairPersistedRootIdentity, revokeNativeSubagentAuthorities, selectReusableSubagentEntry, subagentTrackingPath, summarizeSubagentSession, withCrossProcessFileLockSync, writeSubagentTrackingState } from '../tracker.js';
+import { acquireCrossProcessFileLock, __setCrossProcessPublishBarrierForTest, __setCrossProcessQuarantineBarrierForTest, consumeDirectChildReopenContext, CrossProcessLockLostError, buildSubagentResumeLedger, CROSS_PROCESS_LOCK_ARTIFACT_SWEEP_CAP, CROSS_PROCESS_LOCK_LEASE_MS, createSubagentTrackingState, crossProcessLockPath, DESCRIPTIVE_ADAPTED_PROVENANCE, ensureExactDescriptiveLeaderForSession, fenceNativeSubagentAuthorities, forceGlobalAuthorityDenial, recordNativeSubagentAuthorityObservation, recordSubagentTurn, recordSubagentTurnForSession, NATIVE_SUBAGENT_PROVENANCE, readProcessStartIdentity, readSubagentTrackingState, readSubagentTrackingStateStrict, repairPersistedRootIdentity, revokeNativeSubagentAuthorities, selectReusableSubagentEntry, subagentTrackingPath, summarizeSubagentSession, withCrossProcessFileLockSync, writeSubagentTrackingState } from '../tracker.js';
import { NATIVE_SUBAGENT_ROLE_ROUTING_MARKER_FILE, readRoleRoutingMarker, writeRoleRoutingMarker } from '../role-routing-marker.js';
const CROSS_PROCESS_LOCK_HOLDER_SOURCE = `
@@ -919,6 +919,184 @@ describe('subagents/tracker', () => {
}
});
+ it('keeps an exact descriptive leader byte-for-byte without clearing completion or status', () => {
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-native-root-preserve-'));
+ try {
+ const path = subagentTrackingPath(cwd);
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
+ const timestamp = '2026-07-29T20:00:00.000Z';
+ const raw = `${JSON.stringify({
+ schemaVersion: 1,
+ sessions: {
+ canonical: {
+ session_id: 'canonical',
+ leader_thread_id: 'root',
+ updated_at: timestamp,
+ threads: {
+ root: {
+ thread_id: 'root',
+ kind: 'leader',
+ status: 'closed',
+ completed_at: timestamp,
+ completion_source: 'task_complete',
+ first_seen_at: timestamp,
+ last_seen_at: timestamp,
+ turn_count: 7,
+ },
+ child: {
+ thread_id: 'child',
+ kind: 'subagent',
+ provenance_kind: NATIVE_SUBAGENT_PROVENANCE,
+ direct_child_root_id: 'root',
+ direct_child_parent_id: 'root',
+ status: 'available',
+ first_seen_at: timestamp,
+ last_seen_at: timestamp,
+ turn_count: 1,
+ },
+ },
+ },
+ },
+ }, null, 2)}\n`;
+ writeFileSync(path, raw);
+ __setCrossProcessPublishBarrierForTest(() => {
+ throw new Error('exact root must not publish');
+ });
+ const result = ensureExactDescriptiveLeaderForSession(cwd, {
+ sessionId: 'canonical',
+ rootThreadId: 'root',
+ timestamp: '2026-07-29T21:00:00.000Z',
+ });
+ assert.equal(result.sessions.canonical?.threads.root?.status, 'closed');
+ assert.equal(result.sessions.canonical?.threads.root?.completed_at, timestamp);
+ assert.equal(readFileSync(path, 'utf8'), raw);
+
+ const conflicting = JSON.parse(raw);
+ conflicting.sessions.canonical.threads.child.direct_child_parent_id = 'foreign-parent';
+ const conflictingRaw = `${JSON.stringify(conflicting, null, 2)}\n`;
+ writeFileSync(path, conflictingRaw);
+ assert.throws(() => ensureExactDescriptiveLeaderForSession(cwd, {
+ sessionId: 'canonical',
+ rootThreadId: 'root',
+ }), /native_ultragoal_root_tracker_conflict/);
+ assert.equal(readFileSync(path, 'utf8'), conflictingRaw);
+ } finally {
+ __setCrossProcessPublishBarrierForTest(null);
+ rmSync(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('rejects a root id that is a trusted subagent in a foreign session without publishing', () => {
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-native-root-global-collision-'));
+ try {
+ const path = subagentTrackingPath(cwd);
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
+ const timestamp = '2026-07-29T20:00:00.000Z';
+ const raw = `${JSON.stringify({
+ schemaVersion: 1,
+ sessions: {
+ foreign: {
+ session_id: 'foreign',
+ leader_thread_id: 'foreign-root',
+ updated_at: timestamp,
+ threads: {
+ 'foreign-root': {
+ thread_id: 'foreign-root',
+ kind: 'leader',
+ first_seen_at: timestamp,
+ last_seen_at: timestamp,
+ turn_count: 1,
+ },
+ root: {
+ thread_id: 'root',
+ kind: 'subagent',
+ provenance_kind: NATIVE_SUBAGENT_PROVENANCE,
+ direct_child_root_id: 'foreign-root',
+ direct_child_parent_id: 'foreign-root',
+ status: 'available',
+ first_seen_at: timestamp,
+ last_seen_at: timestamp,
+ turn_count: 1,
+ },
+ },
+ },
+ },
+ }, null, 2)}\n`;
+ writeFileSync(path, raw);
+ assert.throws(() => ensureExactDescriptiveLeaderForSession(cwd, {
+ sessionId: 'canonical',
+ rootThreadId: 'root',
+ }), /native_ultragoal_root_tracker_conflict/);
+ assert.equal(readFileSync(path, 'utf8'), raw);
+ assert.equal(JSON.parse(readFileSync(path, 'utf8')).sessions.canonical, undefined);
+ } finally {
+ rmSync(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('serializes descriptive root publication before a competing authority conflict', async () => {
+ const cwd = mkdtempSync(join(tmpdir(), 'omx-native-root-authority-race-'));
+ const readyPath = join(cwd, 'authority-contended');
+ const resultPath = join(cwd, 'authority-result.json');
+ let competitor: ReturnType<typeof spawn> | undefined;
+ try {
+ const timestamp = '2026-07-29T20:00:00.000Z';
+ mkdirSync(join(cwd, '.omx', 'state'), { recursive: true });
+ writeFileSync(subagentTrackingPath(cwd), JSON.stringify({
+ schemaVersion: 1,
+ sessions: {
+ canonical: {
+ session_id: 'canonical',
+ updated_at: timestamp,
+ threads: {
+ child: {
+ thread_id: 'child',
+ kind: 'subagent',
+ provenance_kind: NATIVE_SUBAGENT_PROVENANCE,
+ direct_child_root_id: 'root',
+ direct_child_parent_id: 'root',
+ status: 'available',
+ first_seen_at: timestamp,
+ last_seen_at: timestamp,
+ turn_count: 1,
+ },
+ },
+ },
+ },
+ }));
+ __setCrossProcessPublishBarrierForTest(() => {
+ competitor = spawnAuthorityCompetitor(cwd, 'revoke', readyPath, resultPath);
+ waitForFileSync(readyPath, 10_000);
+ });
+ ensureExactDescriptiveLeaderForSession(cwd, {
+ sessionId: 'canonical',
+ rootThreadId: 'root',
+ });
+ __setCrossProcessPublishBarrierForTest(null);
+ assert.ok(competitor);
+ await waitForChildExit(competitor);
+ const result = JSON.parse(readFileSync(resultPath, 'utf8'));
+ assert.equal(result.observedContention, true);
+ assert.equal(result.result, 'revoked');
+ const state = JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8'));
+ assert.equal(state.sessions.canonical.leader_thread_id, 'root');
+ assert.equal(state.sessions.canonical.threads.root.kind, 'leader');
+ assert.equal(state.sessions.canonical.threads.child.reopen_authority_revoked, true);
+ assert.throws(() => ensureExactDescriptiveLeaderForSession(cwd, {
+ sessionId: 'canonical',
+ rootThreadId: 'other-root',
+ }), /native_ultragoal_root_tracker_conflict/);
+ assert.equal(
+ JSON.parse(readFileSync(subagentTrackingPath(cwd), 'utf8')).sessions.canonical.threads.child.reopen_authority_revoked,
+ true,
+ );
+ } finally {
+ __setCrossProcessPublishBarrierForTest(null);
+ await stopChild(competitor);
+ rmSync(cwd, { recursive: true, force: true });
+ }
+ });
+
it('serializes a queued reopen behind revocation publication', async () => {
const cwd = mkdtempSync(join(tmpdir(), 'omx-3284-tracker-contended-revoke-first-'));
const readyPath = join(cwd, 'reopen-contended');
@@ -1880,6 +2058,31 @@ describe('subagents/tracker', () => {
}
});
+ it('can preserve a live local async owner beyond the legacy lease', async () => {
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
+ const resourcePath = join(cwd, 'lock-resource');
+ const lockPath = crossProcessLockPath(resourcePath);
+ try {
+ const liveClaim = crossProcessLockClaim(
+ 'live-async-owner',
+ process.pid,
+ Date.now() - CROSS_PROCESS_LOCK_LEASE_MS - 1,
+ );
+ await writeFile(lockPath, liveClaim);
+ await assert.rejects(
+ acquireCrossProcessFileLock(resourcePath, {
+ maxAttempts: 1,
+ retryMs: 1,
+ preserveLiveLocalOwner: true,
+ }),
+ /Timed out waiting for cross-process lock/,
+ );
+ assert.equal(readFileSync(lockPath, 'utf-8'), liveClaim);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
it('does not steal a live same-host identity-matched claim after its lease or mistake its token for ours', async () => {
const cwd = await mkdtemp(join(tmpdir(), 'omx-subagent-tracker-'));
const resourcePath = join(cwd, 'lock-resource');
diff --git a/src/subagents/tracker.ts b/src/subagents/tracker.ts
index 7823b252..dfb5d234 100644
--- a/src/subagents/tracker.ts
+++ b/src/subagents/tracker.ts
@@ -567,12 +567,16 @@ function isCrossProcessLockOlderThanLease(acquiredAtMs: number, nowMs: number):
return acquiredAtMs < nowMs - CROSS_PROCESS_LOCK_LEASE_MS;
}
-function isCrossProcessLockReclaimable(claim: CrossProcessLockClaim): boolean {
+function isCrossProcessLockReclaimable(
+ claim: CrossProcessLockClaim,
+ options: { preserveLiveLocalOwner?: boolean } = {},
+): boolean {
if (claim.host !== hostname()) return isCrossProcessLockOlderThanLease(claim.acquiredAtMs, Date.now());
if (isCrossProcessLockOwnerDead(claim.pid)) return true;
const currentPidStartId = readProcessStartIdentity(claim.pid);
if (claim.pidStartId && currentPidStartId) return currentPidStartId !== claim.pidStartId;
+ if (options.preserveLiveLocalOwner) return false;
return isCrossProcessLockOlderThanLease(claim.acquiredAtMs, Date.now());
}
@@ -624,9 +628,13 @@ function restoreQuarantinedCrossProcessLock(lockPath: string, quarantinedPath: s
removeCrossProcessLockFile(quarantinedPath);
}
-function recoverCrossProcessFileLock(lockPath: string, observed: CrossProcessLockState): boolean {
+function recoverCrossProcessFileLock(
+ lockPath: string,
+ observed: CrossProcessLockState,
+ options: { preserveLiveLocalOwner?: boolean } = {},
+): boolean {
if (observed.kind === 'missing') return true;
- if (observed.kind === 'claim' && !isCrossProcessLockReclaimable(observed.claim)) return false;
+ if (observed.kind === 'claim' && !isCrossProcessLockReclaimable(observed.claim, options)) return false;
const quarantinedPath = `${lockPath}.${Date.now()}.${randomUUID()}.quarantine`;
try {
@@ -644,7 +652,11 @@ function recoverCrossProcessFileLock(lockPath: string, observed: CrossProcessLoc
&& captured.kind === 'claim'
&& captured.claim.token === observed.claim.token;
const capturedRecoverable = captured.kind === 'malformed'
- || (capturedExpectedClaim && captured.kind === 'claim' && isCrossProcessLockReclaimable(captured.claim));
+ || (
+ capturedExpectedClaim
+ && captured.kind === 'claim'
+ && isCrossProcessLockReclaimable(captured.claim, options)
+ );
if (!capturedRecoverable) {
restoreQuarantinedCrossProcessLock(lockPath, quarantinedPath);
return true;
@@ -742,6 +754,47 @@ export function __setCrossProcessQuarantineBarrierForTest(
crossProcessQuarantineBarrier = barrier;
}
+export type CrossProcessFileLockHandle = {
+ assertOwnership(): void;
+ release(): void;
+};
+
+/** Acquire the shared recoverable lock for an async caller that owns its writes. */
+export async function acquireCrossProcessFileLock(
+ resourcePath: string,
+ options: { maxAttempts?: number; retryMs?: number; preserveLiveLocalOwner?: boolean } = {},
+): Promise<CrossProcessFileLockHandle> {
+ const lockPath = crossProcessLockPath(resourcePath);
+ const maxAttempts = typeof options.maxAttempts === 'number' && Number.isFinite(options.maxAttempts)
+ ? Math.max(1, Math.floor(options.maxAttempts))
+ : DEFAULT_CROSS_PROCESS_LOCK_MAX_ATTEMPTS;
+ const retryMs = typeof options.retryMs === 'number' && Number.isFinite(options.retryMs)
+ ? Math.max(1, Math.floor(options.retryMs))
+ : DEFAULT_CROSS_PROCESS_LOCK_RETRY_MS;
+ mkdirSync(dirname(lockPath), { recursive: true });
+ const token = randomUUID();
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
+ if (
+ tryAcquireCrossProcessFileLock(lockPath, token)
+ || (
+ recoverCrossProcessFileLock(lockPath, readCrossProcessLockState(lockPath), options)
+ && tryAcquireCrossProcessFileLock(lockPath, token)
+ )
+ ) {
+ return {
+ assertOwnership: () => assertCrossProcessFileLockOwnership(lockPath, token),
+ release: () => releaseCrossProcessFileLock(lockPath, token),
+ };
+ }
+ if (attempt < maxAttempts - 1) {
+ await new Promise((resolveDelay) => {
+ setTimeout(resolveDelay, Math.min(25, retryMs * 2 ** Math.min(attempt, 4)));
+ });
+ }
+ }
+ throw new Error(`Timed out waiting for cross-process lock at ${lockPath}`);
+}
+
export function withCrossProcessFileLockSync<T>(
resourcePath: string,
operation: (context: CrossProcessFileLockContext) => T,
@@ -1077,6 +1130,81 @@ export async function recordSubagentTurnForSession(cwd: string, input: RecordSub
return next;
});
}
+
+export function ensureExactDescriptiveLeaderForSession(cwd: string, input: {
+ sessionId: string;
+ rootThreadId: string;
+ timestamp?: string;
+}): SubagentTrackingState {
+ const sessionId = input.sessionId.trim();
+ const rootThreadId = input.rootThreadId.trim();
+ if (!sessionId || !rootThreadId) throw new Error('native_ultragoal_root_tracker_conflict');
+
+ return withCrossProcessFileLockSync(subagentTrackingPath(cwd), (context) => {
+ const strict = readSubagentTrackingStateStrictSync(cwd);
+ if (!strict.ok) throw new Error('Malformed subagent tracker authority state');
+ const current = strict.state;
+ const session = current.sessions[sessionId];
+ const root = session?.threads[rootThreadId];
+ const conflictingAuthority = Object.values(session?.threads ?? {}).some((thread) => {
+ if (thread.thread_id === rootThreadId) {
+ return thread.provenance_kind === NATIVE_SUBAGENT_PROVENANCE
+ || thread.direct_child_parent_id !== undefined
+ || thread.direct_child_root_id !== undefined
+ || thread.reopen_authority_revoked !== undefined
+ || thread.reopen_authority_conflict_reason !== undefined
+ || thread.reopen_authority_conflict_at !== undefined;
+ }
+ if (thread.provenance_kind === NATIVE_SUBAGENT_PROVENANCE) {
+ return thread.direct_child_root_id !== rootThreadId
+ || thread.direct_child_parent_id !== rootThreadId;
+ }
+ return thread.direct_child_parent_id !== undefined
+ || thread.direct_child_root_id !== undefined
+ || thread.reopen_authority_revoked !== undefined
+ || thread.reopen_authority_conflict_reason !== undefined
+ || thread.reopen_authority_conflict_at !== undefined;
+ });
+ if (
+ hasLeaderSubagentCollision(current, rootThreadId)
+ || (session?.leader_thread_id && session.leader_thread_id !== rootThreadId)
+ || Object.values(session?.threads ?? {}).some((thread) => (
+ thread.kind === 'leader' && thread.thread_id !== rootThreadId
+ ))
+ || root?.kind === 'subagent'
+ || conflictingAuthority
+ ) throw new Error('native_ultragoal_root_tracker_conflict');
+
+ if (session?.leader_thread_id === rootThreadId && root?.kind === 'leader') return current;
+
+ const timestamp = input.timestamp ?? new Date().toISOString();
+ const nextRoot: TrackedSubagentThread = root ?? {
+ thread_id: rootThreadId,
+ kind: 'leader',
+ first_seen_at: timestamp,
+ last_seen_at: timestamp,
+ turn_count: 1,
+ };
+ const next: SubagentTrackingState = {
+ ...current,
+ sessions: {
+ ...current.sessions,
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: rootThreadId,
+ updated_at: session?.updated_at ?? timestamp,
+ threads: {
+ ...session?.threads,
+ [rootThreadId]: nextRoot,
+ },
+ },
+ },
+ };
+ context.assertOwnership();
+ writeSubagentTrackingStateSync(cwd, next, context.publish);
+ return next;
+ });
+}
export function recordNativeSubagentAuthorityObservation(
cwd: string,
observation: NativeSubagentAuthorityObservation,
@@ -1182,6 +1310,12 @@ function readAuthorityFence(cwd: string): { ok: boolean; ids: Set<string> } {
}
}
+/** True when durable authority state requires fail-closed denial for this child. */
+export function isNativeSubagentAuthorityFenced(cwd: string, childThreadId: string): boolean {
+ const fence = readAuthorityFence(cwd);
+ return !fence.ok || fence.ids.has(childThreadId.trim());
+}
+
/** Upper bound on fenced ids, so repeated failures cannot grow the fence without limit. */
export const AUTHORITY_FENCE_MAX_IDS = 512;
diff --git a/src/ultragoal/__tests__/artifacts.test.ts b/src/ultragoal/__tests__/artifacts.test.ts
index ecc90f7c..dedb81c9 100644
--- a/src/ultragoal/__tests__/artifacts.test.ts
+++ b/src/ultragoal/__tests__/artifacts.test.ts
@@ -29,6 +29,7 @@ import {
type UltragoalSteeringProposal,
} from '../artifacts.js';
import { LEADER_CONDUCTOR_BLOCK, buildUnsupportedNativeSubagentGuidance } from '../../leader/contract.js';
+import { __setWritableStateScopeTestHooksForTests } from '../../mcp/state-paths.js';
import { steeringFixtures, type SteeringFixtureProposal } from './steering-fixtures.js';
const tmpdir = (): string => realpathSync(osTmpdir());
@@ -3213,6 +3214,8 @@ describe('ultragoal artifacts', () => {
it('allows durable Ultragoal mutations for an exact-match identity-indeterminate pointer and rejects mismatches', async () => {
await withTempRepo(async (cwd) => {
const previousEnv = process.env.OMX_SESSION_ID;
+ const previousCodexThreadId = process.env.CODEX_THREAD_ID;
+ const previousBackend = process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
const sessionId = 'sess-indeterminate';
const stateDir = join(cwd, '.omx', 'state');
try {
@@ -3225,6 +3228,8 @@ describe('ultragoal artifacts', () => {
}));
__setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
process.env.OMX_SESSION_ID = sessionId;
+ delete process.env.CODEX_THREAD_ID;
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = 'off';
const plan = await createUltragoalPlan(cwd, { brief: '- Ship the indeterminate recovery' });
assert.equal(plan.goals.length, 1);
@@ -3254,6 +3259,249 @@ describe('ultragoal artifacts', () => {
} finally {
if (typeof previousEnv === 'string') process.env.OMX_SESSION_ID = previousEnv;
else delete process.env.OMX_SESSION_ID;
+ if (typeof previousCodexThreadId === 'string') process.env.CODEX_THREAD_ID = previousCodexThreadId;
+ else delete process.env.CODEX_THREAD_ID;
+ if (typeof previousBackend === 'string') process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = previousBackend;
+ else delete process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ __resetSessionPointerTransactionDependenciesForTests();
+ }
+ });
+ });
+
+ it('opts App-native recovery into local-experimental Ultragoal artifacts only', async () => {
+ await withTempRepo(async (cwd) => {
+ const previousBackend = process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ const previousCodexThreadId = process.env.CODEX_THREAD_ID;
+ const previousOmxSessionId = process.env.OMX_SESSION_ID;
+ const sessionId = '019faf7e-0010-7000-8000-000000000010';
+ const stateDir = join(cwd, '.omx', 'state');
+ try {
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(join(stateDir, 'session.json'), JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: 8388607,
+ }));
+ __setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
+ delete process.env.OMX_SESSION_ID;
+ process.env.CODEX_THREAD_ID = sessionId;
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = 'local-experimental';
+
+ const plan = await createUltragoalPlan(cwd, { brief: '- Ship native App recovery' });
+ assert.equal(plan.goals.length, 1);
+ assert.equal(existsSync(join(cwd, '.omx', 'ultragoal', 'goals.json')), true);
+ assert.deepEqual(await assertUltragoalWritableLifecycleAuthority(cwd), {
+ kind: 'resolved',
+ source: 'session',
+ sessionId,
+ stateDir: join(stateDir, 'sessions', sessionId),
+ });
+
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = 'host';
+ await assert.rejects(
+ () => addUltragoalGoal(cwd, { title: 'Must not persist', objective: 'Host backend cannot use local recovery.' }),
+ /writable lifecycle authority/,
+ );
+ } finally {
+ if (typeof previousBackend === 'string') process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = previousBackend;
+ else delete process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ if (typeof previousCodexThreadId === 'string') process.env.CODEX_THREAD_ID = previousCodexThreadId;
+ else delete process.env.CODEX_THREAD_ID;
+ if (typeof previousOmxSessionId === 'string') process.env.OMX_SESSION_ID = previousOmxSessionId;
+ else delete process.env.OMX_SESSION_ID;
+ __resetSessionPointerTransactionDependenciesForTests();
+ }
+ });
+ });
+
+ it('revalidates the App-native pointer before the first durable artifact commit', async () => {
+ await withTempRepo(async (cwd) => {
+ const previousBackend = process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ const previousCodexThreadId = process.env.CODEX_THREAD_ID;
+ const sessionId = '019faf7e-0011-7000-8000-000000000011';
+ const stateDir = join(cwd, '.omx', 'state');
+ const sessionPath = join(stateDir, 'session.json');
+ let recoveryReadCount = 0;
+ try {
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(sessionPath, JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: 8388607,
+ }));
+ __setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
+ process.env.CODEX_THREAD_ID = sessionId;
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = 'local-experimental';
+ __setWritableStateScopeTestHooksForTests({
+ beforeRecoveryReread: async () => {
+ recoveryReadCount += 1;
+ if (recoveryReadCount === 3) {
+ await writeFile(sessionPath, JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: 9999999,
+ }));
+ }
+ },
+ });
+
+ await assert.rejects(
+ () => createUltragoalPlan(cwd, { brief: '- Must not commit after pointer drift' }),
+ /writable lifecycle authority/,
+ );
+ assert.equal(existsSync(join(cwd, '.omx', 'ultragoal', 'brief.md')), false);
+ assert.equal(existsSync(join(cwd, '.omx', 'ultragoal', 'goals.json')), false);
+ } finally {
+ __setWritableStateScopeTestHooksForTests({});
+ if (typeof previousBackend === 'string') process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = previousBackend;
+ else delete process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ if (typeof previousCodexThreadId === 'string') process.env.CODEX_THREAD_ID = previousCodexThreadId;
+ else delete process.env.CODEX_THREAD_ID;
+ __resetSessionPointerTransactionDependenciesForTests();
+ }
+ });
+ });
+
+ it('fails annotate_ledger closed when App-native authority changes immediately before plan commit', async () => {
+ await withTempRepo(async (cwd) => {
+ const previousBackend = process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ const previousCodexThreadId = process.env.CODEX_THREAD_ID;
+ const previousOmxSessionId = process.env.OMX_SESSION_ID;
+ const sessionId = '019faf7e-0012-7000-8000-000000000012';
+ const stateDir = join(cwd, '.omx', 'state');
+ const sessionPath = join(stateDir, 'session.json');
+ const goalsPath = join(cwd, '.omx', 'ultragoal', 'goals.json');
+ const ledgerPath = join(cwd, '.omx', 'ultragoal', 'ledger.jsonl');
+ let recoveryReadCount = 0;
+ try {
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(sessionPath, JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: 8388607,
+ }));
+ __setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
+ delete process.env.OMX_SESSION_ID;
+ process.env.CODEX_THREAD_ID = sessionId;
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = 'local-experimental';
+
+ await createUltragoalPlan(cwd, { brief: '- Preserve commit-time authority' });
+ const beforeGoals = await readFile(goalsPath, 'utf-8');
+ const beforeLedger = await readFile(ledgerPath, 'utf-8');
+ __setWritableStateScopeTestHooksForTests({
+ beforeRecoveryReread: async () => {
+ recoveryReadCount += 1;
+ // annotate_ledger has no plan mutation: before-lock, after-lock,
+ // pre-mkdir, then the ledger's final pre-append authority check.
+ if (recoveryReadCount === 4) {
+ await writeFile(sessionPath, JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: 9999999,
+ }));
+ }
+ },
+ });
+
+ await assert.rejects(
+ () => steerUltragoal(cwd, {
+ kind: 'annotate_ledger',
+ source: 'cli',
+ evidence: 'commit-time race evidence',
+ rationale: 'record evidence without changing the goal graph',
+ }),
+ /writable lifecycle authority/,
+ );
+ assert.equal(await readFile(goalsPath, 'utf-8'), beforeGoals);
+ assert.equal(await readFile(ledgerPath, 'utf-8'), beforeLedger);
+ } finally {
+ __setWritableStateScopeTestHooksForTests({});
+ if (typeof previousBackend === 'string') process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = previousBackend;
+ else delete process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ if (typeof previousCodexThreadId === 'string') process.env.CODEX_THREAD_ID = previousCodexThreadId;
+ else delete process.env.CODEX_THREAD_ID;
+ if (typeof previousOmxSessionId === 'string') process.env.OMX_SESSION_ID = previousOmxSessionId;
+ else delete process.env.OMX_SESSION_ID;
+ __resetSessionPointerTransactionDependenciesForTests();
+ }
+ });
+ });
+
+ it('fails a final checkpoint closed when App-native authority changes immediately before plan commit', async () => {
+ await withTempRepo(async (cwd) => {
+ const previousBackend = process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ const previousCodexThreadId = process.env.CODEX_THREAD_ID;
+ const previousOmxSessionId = process.env.OMX_SESSION_ID;
+ const sessionId = '019faf7e-0013-7000-8000-000000000013';
+ const stateDir = join(cwd, '.omx', 'state');
+ const sessionPath = join(stateDir, 'session.json');
+ const goalsPath = join(cwd, '.omx', 'ultragoal', 'goals.json');
+ const ledgerPath = join(cwd, '.omx', 'ultragoal', 'ledger.jsonl');
+ let recoveryReadCount = 0;
+ try {
+ await mkdir(stateDir, { recursive: true });
+ await writeFile(sessionPath, JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: 8388607,
+ }));
+ __setSessionPointerTransactionDependenciesForTests({ probePid: () => 'indeterminate' });
+ delete process.env.OMX_SESSION_ID;
+ process.env.CODEX_THREAD_ID = sessionId;
+ process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = 'local-experimental';
+
+ const created = await createUltragoalPlan(cwd, { brief: '- Preserve final checkpoint authority' });
+ const started = await startNextUltragoal(cwd);
+ const beforeGoals = await readFile(goalsPath, 'utf-8');
+ const beforeLedger = await readFile(ledgerPath, 'utf-8');
+ __setWritableStateScopeTestHooksForTests({
+ beforeRecoveryReread: async () => {
+ recoveryReadCount += 1;
+ // Revoke the selected pointer at writePlan's final pre-rename check.
+ if (recoveryReadCount === 5) {
+ await writeFile(sessionPath, JSON.stringify({
+ session_id: sessionId,
+ native_session_id: sessionId,
+ cwd,
+ state_root: stateDir,
+ pid: 9999999,
+ }));
+ }
+ },
+ });
+
+ await assert.rejects(
+ () => checkpointUltragoal(cwd, {
+ goalId: started.goal!.id,
+ status: 'complete',
+ evidence: 'implementation and verification complete for the active ultragoal',
+ codexGoal: { goal: { objective: created.codexObjective, status: 'complete' } },
+ qualityGate: cleanQualityGate(),
+ }),
+ /writable lifecycle authority/,
+ );
+ assert.equal(await readFile(goalsPath, 'utf-8'), beforeGoals);
+ assert.equal(await readFile(ledgerPath, 'utf-8'), beforeLedger);
+ } finally {
+ __setWritableStateScopeTestHooksForTests({});
+ if (typeof previousBackend === 'string') process.env.OMX_NATIVE_ULTRAGOAL_BACKEND = previousBackend;
+ else delete process.env.OMX_NATIVE_ULTRAGOAL_BACKEND;
+ if (typeof previousCodexThreadId === 'string') process.env.CODEX_THREAD_ID = previousCodexThreadId;
+ else delete process.env.CODEX_THREAD_ID;
+ if (typeof previousOmxSessionId === 'string') process.env.OMX_SESSION_ID = previousOmxSessionId;
+ else delete process.env.OMX_SESSION_ID;
__resetSessionPointerTransactionDependenciesForTests();
}
});
diff --git a/src/ultragoal/__tests__/native-bootstrap.test.ts b/src/ultragoal/__tests__/native-bootstrap.test.ts
new file mode 100644
index 00000000..233edbc5
--- /dev/null
+++ b/src/ultragoal/__tests__/native-bootstrap.test.ts
@@ -0,0 +1,755 @@
+import assert from 'node:assert/strict';
+import { chmod, link, mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises';
+import { tmpdir } from 'node:os';
+import { dirname, join } from 'node:path';
+import { describe, it } from 'node:test';
+import {
+ beginNativeUltragoalBootstrap,
+ DOCUMENTED_HOST_RECEIPT_UNAVAILABLE,
+ findReadyLocalNativeExecutorAssignment,
+ issueLocalNativeExecutorAssignment,
+ markNativeUltragoalBootstrapActive,
+ nativeExecutorAssignmentPath,
+ prepareNativeUltragoalBootstrapActivation,
+ readNativeUltragoalBootstrap,
+ reconcileLocalNativeExecutorAssignments,
+ resolveLocalNativeExecutorChildReceipt,
+ revokeLocalNativeExecutorAssignment,
+ unavailableHostNativeExecutorReceiptVerifier,
+ validateLocalNativeExecutorIdentity,
+} from '../native-bootstrap.js';
+
+async function writeJson(path: string, value: unknown): Promise<void> {
+ await mkdir(dirname(path), { recursive: true });
+ await writeFile(path, `${JSON.stringify(value, null, 2)}\n`);
+}
+
+async function fixture() {
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-native-bootstrap-'));
+ const stateDir = join(cwd, '.omx', 'state');
+ const sessionId = 'session-native-bootstrap';
+ const rootThreadId = 'root-native-bootstrap';
+ const childAgentId = 'child-native-bootstrap';
+ const now = new Date('2026-07-28T12:00:00.000Z');
+ await writeJson(join(stateDir, 'subagent-tracking.json'), {
+ schemaVersion: 1,
+ sessions: {
+ [sessionId]: {
+ session_id: sessionId,
+ leader_thread_id: rootThreadId,
+ updated_at: now.toISOString(),
+ threads: {
+ [rootThreadId]: {
+ thread_id: rootThreadId,
+ kind: 'leader',
+ first_seen_at: now.toISOString(),
+ last_seen_at: now.toISOString(),
+ turn_count: 1,
+ },
+ [childAgentId]: {
+ thread_id: childAgentId,
+ kind: 'subagent',
+ mode: 'executor',
+ status: 'available',
+ provenance_kind: 'native_subagent',
+ direct_child_parent_id: rootThreadId,
+ direct_child_root_id: rootThreadId,
+ first_seen_at: now.toISOString(),
+ last_seen_at: now.toISOString(),
+ turn_count: 1,
+ },
+ },
+ },
+ },
+ });
+ return { cwd, stateDir, sessionId, rootThreadId, childAgentId, now };
+}
+
+async function writeChildRollout(input: {
+ codexHome: string;
+ childId: string;
+ timestamp: string;
+ cwd: string;
+ sessionId: string;
+ rootThreadId: string;
+ agentPath: string;
+ depth?: number;
+ role?: string;
+ directory?: string;
+}): Promise<string> {
+ const path = join(
+ input.codexHome,
+ 'sessions',
+ input.directory ?? '2026/07/29',
+ `rollout-test-${input.childId}.jsonl`,
+ );
+ await mkdir(dirname(path), { recursive: true });
+ await writeFile(path, `${JSON.stringify({
+ timestamp: input.timestamp,
+ type: 'session_meta',
+ payload: {
+ id: input.childId,
+ session_id: input.sessionId,
+ cwd: input.cwd,
+ source: {
+ subagent: {
+ thread_spawn: {
+ parent_thread_id: input.rootThreadId,
+ depth: input.depth ?? 1,
+ agent_path: input.agentPath,
+ agent_role: input.role ?? 'executor',
+ },
+ },
+ },
+ },
+ })}\n`);
+ return path;
+}
+
+describe('native Ultragoal bootstrap', () => {
+ it('seeds only the exact descriptive root tracker and fails closed on leader contradiction', async () => {
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-native-bootstrap-root-seed-'));
+ const stateDir = join(cwd, '.omx', 'state');
+ const sessionId = 'session-root-seed';
+ const rootThreadId = 'root-thread-seed';
+ try {
+ await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId,
+ rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 300,
+ });
+ const tracking = JSON.parse(await readFile(join(stateDir, 'subagent-tracking.json'), 'utf8')) as {
+ sessions: Record<string, {
+ leader_thread_id?: string;
+ threads: Record<string, Record<string, unknown>>;
+ }>;
+ };
+ const root = tracking.sessions[sessionId]?.threads[rootThreadId];
+ assert.equal(tracking.sessions[sessionId]?.leader_thread_id, rootThreadId);
+ assert.equal(root?.kind, 'leader');
+ assert.equal(root?.provenance_kind, undefined);
+ assert.equal(root?.direct_child_parent_id, undefined);
+ assert.equal(root?.direct_child_root_id, undefined);
+
+ const conflictingSessionId = 'session-root-conflict';
+ const conflictTimestamp = new Date().toISOString();
+ await writeJson(join(stateDir, 'subagent-tracking.json'), {
+ schemaVersion: 1,
+ sessions: {
+ [conflictingSessionId]: {
+ session_id: conflictingSessionId,
+ leader_thread_id: 'foreign-root',
+ updated_at: conflictTimestamp,
+ threads: {
+ 'foreign-root': {
+ thread_id: 'foreign-root',
+ kind: 'leader',
+ first_seen_at: conflictTimestamp,
+ last_seen_at: conflictTimestamp,
+ turn_count: 1,
+ },
+ },
+ },
+ },
+ });
+ await assert.rejects(beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir,
+ sessionId: conflictingSessionId,
+ rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 300,
+ }), /native_ultragoal_root_tracker_conflict/);
+ assert.equal(await readNativeUltragoalBootstrap(stateDir, conflictingSessionId), null);
+ const afterConflict = JSON.parse(await readFile(join(stateDir, 'subagent-tracking.json'), 'utf8')) as {
+ sessions: Record<string, { threads: Record<string, unknown> }>;
+ };
+ assert.equal(afterConflict.sessions[conflictingSessionId]?.threads[rootThreadId], undefined);
+ } finally {
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('resolves a safe unique child rollout from an exact agent path without granting tracker authority', async () => {
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-native-child-path-'));
+ const codexHome = join(cwd, 'codex-home');
+ const previousCodexHome = process.env.CODEX_HOME;
+ process.env.CODEX_HOME = codexHome;
+ const childId = '019faf7d-ffbb-70d2-b58f-9bb83e752007';
+ const sessionId = 'session-child-path';
+ const rootThreadId = 'root-child-path';
+ const agentPath = '/root/ultragoal_native_executor';
+ const timestamp = '2026-07-29T20:00:00.000Z';
+ try {
+ await writeChildRollout({
+ codexHome,
+ childId,
+ timestamp,
+ cwd,
+ sessionId,
+ rootThreadId,
+ agentPath,
+ });
+ assert.deepEqual(await resolveLocalNativeExecutorChildReceipt({
+ cwd,
+ sessionId,
+ rootThreadId,
+ agentPath,
+ receiptNotBefore: '2026-07-29T19:59:00.000Z',
+ receiptNotAfter: '2026-07-29T20:01:00.000Z',
+ now: new Date(timestamp),
+ }), { ok: true, childAgentId: childId });
+ await assert.rejects(readFile(join(cwd, '.omx', 'state', 'subagent-tracking.json')), /ENOENT/);
+ } finally {
+ if (previousCodexHome === undefined) delete process.env.CODEX_HOME;
+ else process.env.CODEX_HOME = previousCodexHome;
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('rejects missing, ambiguous, stale, foreign, malformed, writable, and linked child-path receipts', async () => {
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-native-child-path-deny-'));
+ const codexHome = join(cwd, 'codex-home');
+ const previousCodexHome = process.env.CODEX_HOME;
+ process.env.CODEX_HOME = codexHome;
+ const sessionId = 'session-child-path-deny';
+ const rootThreadId = 'root-child-path-deny';
+ const timestamp = '2026-07-29T20:00:00.000Z';
+ const window = {
+ receiptNotBefore: '2026-07-29T19:59:00.000Z',
+ receiptNotAfter: '2026-07-29T20:01:00.000Z',
+ now: new Date(timestamp),
+ };
+ const resolvePath = (agentPath: string) => resolveLocalNativeExecutorChildReceipt({
+ cwd, sessionId, rootThreadId, agentPath, ...window,
+ });
+ try {
+ await mkdir(join(codexHome, 'sessions'), { recursive: true });
+ assert.deepEqual(await resolvePath('/root/missing'), {
+ ok: false, reason: 'child_transcript_receipt_missing',
+ });
+
+ const unreadableDirectory = join(codexHome, 'sessions', 'unreadable');
+ await mkdir(unreadableDirectory, { recursive: true });
+ await chmod(unreadableDirectory, 0o000);
+ assert.deepEqual(await resolvePath('/root/missing'), {
+ ok: false, reason: 'child_transcript_receipt_scan_incomplete',
+ });
+ await beginNativeUltragoalBootstrap({
+ cwd,
+ stateDir: join(cwd, '.omx', 'state'),
+ sessionId,
+ rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 300,
+ now: new Date(timestamp),
+ });
+ assert.deepEqual(await validateLocalNativeExecutorIdentity({
+ cwd,
+ sessionId,
+ rootThreadId,
+ childAgentId: '019faf7d-0099-7000-8000-000000000099',
+ receiptNotBefore: window.receiptNotBefore,
+ receiptNotAfter: window.receiptNotAfter,
+ }), { ok: false, reason: 'child_transcript_receipt_scan_incomplete' });
+ await chmod(unreadableDirectory, 0o700);
+
+ const invalidCases = [
+ { name: 'stale', childId: '019faf7d-0001-7000-8000-000000000001', timestamp: '2026-07-29T19:58:59.000Z' },
+ { name: 'parent', childId: '019faf7d-0002-7000-8000-000000000002', rootThreadId: 'foreign-root' },
+ { name: 'depth', childId: '019faf7d-0003-7000-8000-000000000003', depth: 2 },
+ { name: 'role', childId: '019faf7d-0004-7000-8000-000000000004', role: 'reviewer' },
+ { name: 'cwd', childId: '019faf7d-0005-7000-8000-000000000005', cwd: codexHome },
+ { name: 'session', childId: '019faf7d-0006-7000-8000-000000000006', sessionId: 'foreign-session' },
+ { name: 'id', childId: 'not-a-canonical-uuid' },
+ ];
+ for (const invalid of invalidCases) {
+ const agentPath = `/root/deny_${invalid.name}`;
+ await writeChildRollout({
+ codexHome,
+ childId: invalid.childId,
+ timestamp: invalid.timestamp ?? timestamp,
+ cwd: invalid.cwd ?? cwd,
+ sessionId: invalid.sessionId ?? sessionId,
+ rootThreadId: invalid.rootThreadId ?? rootThreadId,
+ agentPath,
+ depth: invalid.depth,
+ role: invalid.role,
+ directory: invalid.name,
+ });
+ assert.deepEqual(await resolvePath(agentPath), {
+ ok: false, reason: 'child_transcript_receipt_missing',
+ }, invalid.name);
+ }
+
+ const writablePath = await writeChildRollout({
+ codexHome,
+ childId: '019faf7d-0007-7000-8000-000000000007',
+ timestamp,
+ cwd,
+ sessionId,
+ rootThreadId,
+ agentPath: '/root/deny_writable',
+ directory: 'writable',
+ });
+ await chmod(writablePath, 0o666);
+ assert.deepEqual(await resolvePath('/root/deny_writable'), {
+ ok: false, reason: 'child_transcript_receipt_missing',
+ });
+
+ const linkedSource = await writeChildRollout({
+ codexHome,
+ childId: '019faf7d-0008-7000-8000-000000000008',
+ timestamp,
+ cwd,
+ sessionId,
+ rootThreadId,
+ agentPath: '/root/deny_linked',
+ directory: 'linked',
+ });
+ await link(linkedSource, `${linkedSource}.copy`);
+ assert.deepEqual(await resolvePath('/root/deny_linked'), {
+ ok: false, reason: 'child_transcript_receipt_missing',
+ });
+
+ const symlinkTarget = await writeChildRollout({
+ codexHome,
+ childId: '019faf7d-0009-7000-8000-000000000009',
+ timestamp,
+ cwd,
+ sessionId,
+ rootThreadId,
+ agentPath: '/root/deny_symlink',
+ directory: 'outside-live-tree',
+ });
+ const symlinkPath = join(codexHome, 'sessions', `rollout-link-019faf7d-0009-7000-8000-000000000009.jsonl`);
+ await symlink(symlinkTarget, symlinkPath);
+ await rm(symlinkTarget);
+ assert.deepEqual(await resolvePath('/root/deny_symlink'), {
+ ok: false, reason: 'child_transcript_receipt_missing',
+ });
+
+ for (const [index, childId] of [
+ '019faf7d-0010-7000-8000-000000000010',
+ '019faf7d-0011-7000-8000-000000000011',
+ ].entries()) {
+ await writeChildRollout({
+ codexHome,
+ childId,
+ timestamp,
+ cwd,
+ sessionId,
+ rootThreadId,
+ agentPath: '/root/deny_ambiguous',
+ directory: `ambiguous-${index}`,
+ });
+ }
+ assert.deepEqual(await resolvePath('/root/deny_ambiguous'), {
+ ok: false, reason: 'child_transcript_receipt_ambiguous',
+ });
+ } finally {
+ if (previousCodexHome === undefined) delete process.env.CODEX_HOME;
+ else process.env.CODEX_HOME = previousCodexHome;
+ await rm(cwd, { recursive: true, force: true });
+ }
+ });
+ it('keeps the host backend explicitly unavailable without a documented verifier', async () => {
+ const f = await fixture();
+ try {
+ const state = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'host',
+ ttlSeconds: 300,
+ now: f.now,
+ });
+ assert.equal(state.status, 'host-receipt-unavailable');
+ assert.equal(state.reason, DOCUMENTED_HOST_RECEIPT_UNAVAILABLE);
+ assert.deepEqual(await unavailableHostNativeExecutorReceiptVerifier.verifyActivationReceipt({
+ cwd: f.cwd,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ }), { ok: false, reason: DOCUMENTED_HOST_RECEIPT_UNAVAILABLE });
+ } finally {
+ await rm(f.cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('orders local bootstrap before assignment and activation', async () => {
+ const f = await fixture();
+ try {
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ now: f.now,
+ });
+ assert.equal(bootstrap.status, 'awaiting-executor');
+ assert.equal(await findReadyLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ now: f.now,
+ }), null);
+
+ await assert.rejects(
+ issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['$UNRESOLVED/*'],
+ ttlSeconds: 300,
+ now: f.now,
+ }),
+ /invalid_native_assignment_path_prefixes/,
+ );
+
+ const assignment = await issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src', 'tests'],
+ ttlSeconds: 300,
+ now: f.now,
+ });
+ assert.equal(assignment.bootstrap_generation, bootstrap.generation);
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'ready');
+ assert.equal((await findReadyLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ now: f.now,
+ }))?.child_agent_id, f.childAgentId);
+
+ const prepared = await prepareNativeUltragoalBootstrapActivation({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ childAgentId: f.childAgentId,
+ now: f.now,
+ });
+ assert.equal(prepared.ok, true);
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'activating');
+ const activation = await markNativeUltragoalBootstrapActive({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ childAgentId: f.childAgentId,
+ now: f.now,
+ });
+ assert.equal(activation.ok, true);
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'active');
+ assert.equal((await markNativeUltragoalBootstrapActive({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ childAgentId: f.childAgentId,
+ now: f.now,
+ })).ok, true);
+
+ const renewed = await issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 600,
+ now: new Date(f.now.getTime() + 60_000),
+ });
+ assert.equal(renewed.bootstrap_generation, bootstrap.generation);
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'active');
+ } finally {
+ await rm(f.cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('revokes a local lease when tracker lifecycle closes and supports explicit revoke', async () => {
+ const f = await fixture();
+ try {
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ now: f.now,
+ });
+ await issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 300,
+ now: f.now,
+ });
+ const trackerPath = join(f.stateDir, 'subagent-tracking.json');
+ const tracker = JSON.parse(await readFile(trackerPath, 'utf-8')) as {
+ sessions: Record<string, { threads: Record<string, { status: string }> }>;
+ };
+ tracker.sessions[f.sessionId].threads[f.childAgentId].status = 'closed';
+ await writeJson(trackerPath, tracker);
+ assert.deepEqual(await reconcileLocalNativeExecutorAssignments({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ now: f.now,
+ }), { ready: false });
+ const assignment = JSON.parse(await readFile(
+ nativeExecutorAssignmentPath(f.stateDir, f.sessionId, f.childAgentId),
+ 'utf-8',
+ )) as { lifecycle: string; revoke_reason?: string };
+ assert.equal(assignment.lifecycle, 'revoked');
+ assert.equal(assignment.revoke_reason, 'child_closed');
+
+ await revokeLocalNativeExecutorAssignment({
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ reason: 'root_cancelled',
+ now: f.now,
+ });
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'revoked');
+ } finally {
+ await rm(f.cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('denies explicit and fail-closed durable authority fences', async () => {
+ const f = await fixture();
+ try {
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ now: f.now,
+ });
+ const fencePath = join(f.stateDir, 'subagent-tracking.json.authority-fence.json');
+ await writeJson(fencePath, { ids: [f.childAgentId] });
+ await assert.rejects(issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 300,
+ now: f.now,
+ }), /child_authority_fenced/);
+
+ await writeFile(fencePath, '{ malformed');
+ await assert.rejects(issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 300,
+ now: f.now,
+ }), /child_authority_fenced/);
+ } finally {
+ await rm(f.cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('rotates expired bootstrap generations and cannot activate without the exact assignment file', async () => {
+ const f = await fixture();
+ try {
+ const first = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 30,
+ now: f.now,
+ });
+ await issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: first.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 30,
+ now: f.now,
+ });
+ const assignmentPath = nativeExecutorAssignmentPath(f.stateDir, f.sessionId, f.childAgentId);
+ await rm(assignmentPath);
+ const missingAssignmentActivation = await markNativeUltragoalBootstrapActive({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ childAgentId: f.childAgentId,
+ now: f.now,
+ });
+ assert.equal(missingAssignmentActivation.ok, false);
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'ready');
+
+ const second = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 30,
+ now: new Date(f.now.getTime() + 31_000),
+ });
+ assert.notEqual(second.generation, first.generation);
+ assert.equal(second.status, 'awaiting-executor');
+ } finally {
+ await rm(f.cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('serializes authorize before revoke so stale readiness cannot resurrect authority', async () => {
+ const f = await fixture();
+ try {
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ now: f.now,
+ });
+ const concurrent = await Promise.allSettled([
+ issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 300,
+ now: f.now,
+ }),
+ revokeLocalNativeExecutorAssignment({
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ reason: 'concurrent_root_revoke',
+ now: f.now,
+ }),
+ ]);
+ if (concurrent[0].status === 'rejected') {
+ assert.match(String(concurrent[0].reason), /native_ultragoal_bootstrap_not_ready/);
+ }
+ assert.equal(concurrent[1].status, 'fulfilled');
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'revoked');
+ const assignmentPath = nativeExecutorAssignmentPath(f.stateDir, f.sessionId, f.childAgentId);
+ if (concurrent[0].status === 'fulfilled') {
+ const assignment = JSON.parse(await readFile(assignmentPath, 'utf-8')) as {
+ lifecycle: string;
+ revoke_reason?: string;
+ };
+ assert.equal(assignment.lifecycle, 'revoked');
+ assert.equal(assignment.revoke_reason, 'concurrent_root_revoke');
+ } else {
+ await assert.rejects(readFile(assignmentPath), /ENOENT/);
+ }
+ const replacement = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ now: f.now,
+ });
+ await assert.rejects(issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 300,
+ now: f.now,
+ }), /native_ultragoal_bootstrap_not_ready/);
+ assert.notEqual(replacement.generation, bootstrap.generation);
+ } finally {
+ await rm(f.cwd, { recursive: true, force: true });
+ }
+ });
+
+ it('recovers one dead lifecycle lock without letting concurrent mutations overlap', async () => {
+ const f = await fixture();
+ try {
+ const bootstrap = await beginNativeUltragoalBootstrap({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ backend: 'local-experimental',
+ ttlSeconds: 900,
+ now: f.now,
+ });
+ const lockPath = join(
+ f.stateDir,
+ 'sessions',
+ f.sessionId,
+ 'native-ultragoal-bootstrap.json.lock',
+ );
+ await writeJson(lockPath, { pid: 2_147_483_647, token: 'dead-owner' });
+ const concurrent = await Promise.allSettled([
+ issueLocalNativeExecutorAssignment({
+ cwd: f.cwd,
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ rootThreadId: f.rootThreadId,
+ childAgentId: f.childAgentId,
+ expectedGeneration: bootstrap.generation,
+ pathPrefixes: ['src'],
+ ttlSeconds: 300,
+ now: f.now,
+ }),
+ revokeLocalNativeExecutorAssignment({
+ stateDir: f.stateDir,
+ sessionId: f.sessionId,
+ reason: 'dead_lock_concurrent_revoke',
+ now: f.now,
+ }),
+ ]);
+ if (concurrent[0].status === 'rejected') {
+ assert.match(String(concurrent[0].reason), /native_ultragoal_bootstrap_not_ready/);
+ }
+ assert.equal(concurrent[1].status, 'fulfilled');
+ assert.equal((await readNativeUltragoalBootstrap(f.stateDir, f.sessionId))?.status, 'revoked');
+ await assert.rejects(readFile(lockPath), /ENOENT/);
+ await assert.rejects(readFile(`${lockPath}.reaper`), /ENOENT/);
+ } finally {
+ await rm(f.cwd, { recursive: true, force: true });
+ }
+ });
+});
diff --git a/src/ultragoal/artifacts.ts b/src/ultragoal/artifacts.ts
index 9e4ca72f..920e1f3c 100644
--- a/src/ultragoal/artifacts.ts
+++ b/src/ultragoal/artifacts.ts
@@ -3,6 +3,7 @@ import { appendFile, mkdir, open, readFile, rename, rm, writeFile } from 'node:f
import { isAbsolute, join, relative } from 'node:path';
import { normalizeSessionId, resolveWritableStateScope, WRITABLE_STATE_SCOPE_ERRORS } from '../mcp/state-paths.js';
import type { ResolvedStateScope } from '../mcp/state-paths.js';
+import { resolveNativeUltragoalConfig } from '../config/native-ultragoal.js';
import {
formatCodexGoalReconciliation,
buildCompletedCodexGoalRemediation,
@@ -874,7 +875,9 @@ export async function assertUltragoalWritableLifecycleAuthority(
): Promise<UltragoalWritableAuthority> {
try {
const suppliedEnvironmentSessionId = process.env.OMX_SESSION_ID?.trim();
- const scope = await resolveWritableStateScope(cwd);
+ const scope = await resolveWritableStateScope(cwd, undefined, {
+ nativeUltragoalBackend: resolveNativeUltragoalConfig().backend,
+ });
if (
options.allowUnboundEnvironment === false
&& suppliedEnvironmentSessionId
@@ -933,7 +936,7 @@ function describeWritableAuthority(authority: UltragoalWritableAuthority): strin
async function withUltragoalMutationLock<T>(
cwd: string,
- operation: () => Promise<T>,
+ operation: (beforeCommit: () => Promise<void>) => Promise<T>,
options: { allowUnboundEnvironment?: boolean } = {},
): Promise<T> {
const beforeLock = await assertUltragoalWritableLifecycleAuthority(cwd, options);
@@ -964,15 +967,29 @@ async function withUltragoalMutationLock<T>(
`Refusing durable ultragoal mutation after writable lifecycle authority drift while waiting for the mutation lock: before lock ${describeWritableAuthority(beforeLock)}; after lock ${describeWritableAuthority(afterLock)}.`,
);
}
- return await operation();
+ const beforeCommit = async (): Promise<void> => {
+ const current = await assertUltragoalWritableLifecycleAuthority(cwd, options);
+ if (!writableAuthorityEquals(afterLock, current)) {
+ throw new UltragoalError(
+ `Refusing durable ultragoal mutation after writable lifecycle authority drift before commit: locked ${describeWritableAuthority(afterLock)}; current ${describeWritableAuthority(current)}.`,
+ );
+ }
+ };
+ return await operation(beforeCommit);
} finally {
await handle.close().catch(() => undefined);
await rm(lockPath, { force: true }).catch(() => undefined);
}
}
-async function appendLedger(cwd: string, entry: UltragoalLedgerEntry): Promise<void> {
+async function appendLedger(
+ cwd: string,
+ entry: UltragoalLedgerEntry,
+ beforeCommit: () => Promise<void>,
+): Promise<void> {
+ await beforeCommit();
await mkdir(ultragoalDir(cwd), { recursive: true });
+ await beforeCommit();
const path = ultragoalLedgerPath(cwd);
await appendFile(path, `${JSON.stringify(entry)}\n`);
}
@@ -1014,7 +1031,11 @@ function requiresAggregateObjectiveMigration(plan: UltragoalPlan, statePathPrefi
}
/** Durable legacy-objective migration; caller MUST hold the mutation lock. */
-async function migrateAggregateObjectiveUnderLock(cwd: string, parsed: UltragoalPlan): Promise<UltragoalPlan> {
+async function migrateAggregateObjectiveUnderLock(
+ cwd: string,
+ parsed: UltragoalPlan,
+ beforeCommit: () => Promise<void>,
+): Promise<UltragoalPlan> {
const statePathPrefix = ultragoalStatePathPrefix(cwd);
if (!requiresAggregateObjectiveMigration(parsed, statePathPrefix)) return parsed;
const canonicalStatePathMigration = requiresCanonicalStatePathMigration(parsed, statePathPrefix);
@@ -1024,7 +1045,7 @@ async function migrateAggregateObjectiveUnderLock(cwd: string, parsed: Ultragoal
parsed.statePathPrefix = statePathPrefix === '' ? undefined : statePathPrefix;
parsed.codexObjectiveAliases = Array.from(new Set([...(parsed.codexObjectiveAliases ?? []), previousObjective].filter((value): value is string => typeof value === 'string' && value.length > 0)));
parsed.updatedAt = now;
- await writePlan(cwd, parsed);
+ await writePlan(cwd, parsed, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'aggregate_objective_migrated',
@@ -1033,13 +1054,16 @@ async function migrateAggregateObjectiveUnderLock(cwd: string, parsed: Ultragoal
: 'Migrated legacy enumerated aggregate Codex objective to the stable pointer objective.',
before: { codexObjective: previousObjective },
after: { codexObjective: parsed.codexObjective },
- });
+ }, beforeCommit);
return parsed;
}
/** Locked plan read for mutators that already hold the mutation lock. */
-async function readUltragoalPlanUnderLock(cwd: string): Promise<UltragoalPlan> {
- return migrateAggregateObjectiveUnderLock(cwd, await readUltragoalPlanFile(cwd));
+async function readUltragoalPlanUnderLock(
+ cwd: string,
+ beforeCommit: () => Promise<void>,
+): Promise<UltragoalPlan> {
+ return migrateAggregateObjectiveUnderLock(cwd, await readUltragoalPlanFile(cwd), beforeCommit);
}
export async function readUltragoalPlan(cwd: string): Promise<UltragoalPlan> {
@@ -1048,19 +1072,30 @@ export async function readUltragoalPlan(cwd: string): Promise<UltragoalPlan> {
// The legacy objective migration is a durable story transition: it requires
// writable lifecycle authority and the mutation lock, and re-reads the plan
// under the lock so a concurrent mutator cannot be clobbered or duplicated.
- return withUltragoalMutationLock(cwd, async () => readUltragoalPlanUnderLock(cwd));
+ return withUltragoalMutationLock(cwd, async (beforeCommit) => readUltragoalPlanUnderLock(cwd, beforeCommit));
}
-async function writePlan(cwd: string, plan: UltragoalPlan): Promise<void> {
+async function writePlan(
+ cwd: string,
+ plan: UltragoalPlan,
+ beforeCommit: () => Promise<void>,
+): Promise<void> {
+ await beforeCommit();
await mkdir(ultragoalDir(cwd), { recursive: true });
const path = ultragoalGoalsPath(cwd);
const tmpPath = `${path}.${process.pid}.${Date.now()}.tmp`;
- await writeFile(tmpPath, `${JSON.stringify(plan, null, 2)}\n`);
- await rename(tmpPath, path);
+ await beforeCommit();
+ try {
+ await writeFile(tmpPath, `${JSON.stringify(plan, null, 2)}\n`);
+ await beforeCommit();
+ await rename(tmpPath, path);
+ } finally {
+ await rm(tmpPath, { force: true }).catch(() => undefined);
+ }
}
export async function createUltragoalPlan(cwd: string, options: CreateUltragoalOptions): Promise<UltragoalPlan> {
- return withUltragoalMutationLock(cwd, async () => {
+ return withUltragoalMutationLock(cwd, async (beforeCommit) => {
if (!options.force && existsSync(ultragoalGoalsPath(cwd))) {
throw new UltragoalError(`Refusing to overwrite existing ${ULTRAGOAL_DIR}/${ULTRAGOAL_GOALS}; pass --force to recreate it.`);
}
@@ -1096,11 +1131,14 @@ export async function createUltragoalPlan(cwd: string, options: CreateUltragoalO
plan.codexObjective = aggregateCodexObjective(statePathPrefix);
}
+ await beforeCommit();
await mkdir(ultragoalDir(cwd), { recursive: true });
+ await beforeCommit();
await writeFile(ultragoalBriefPath(cwd), options.brief.endsWith('\n') ? options.brief : `${options.brief}\n`);
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
+ await beforeCommit();
await writeFile(ultragoalLedgerPath(cwd), '');
- await appendLedger(cwd, { ts: now, event: 'plan_created', message: `${candidates.length} goal(s) created` });
+ await appendLedger(cwd, { ts: now, event: 'plan_created', message: `${candidates.length} goal(s) created` }, beforeCommit);
return plan;
}, { allowUnboundEnvironment: false });
}
@@ -1170,14 +1208,14 @@ function appendGoalToPlan(plan: UltragoalPlan, options: AddUltragoalGoalOptions
}
export async function addUltragoalGoal(cwd: string, options: AddUltragoalGoalOptions): Promise<{ plan: UltragoalPlan; goal: UltragoalItem }> {
- return withUltragoalMutationLock(cwd, async () => {
- const plan = await readUltragoalPlanUnderLock(cwd);
+ return withUltragoalMutationLock(cwd, async (beforeCommit) => {
+ const plan = await readUltragoalPlanUnderLock(cwd, beforeCommit);
if (plan.aggregateCompletion?.status === 'complete') {
throw new UltragoalError('Cannot add a goal to an already completed aggregate ultragoal plan; start a new plan for post-terminal work.');
}
const now = iso(options.now);
const goal = appendGoalToPlan(plan, options);
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'goal_added',
@@ -1185,7 +1223,7 @@ export async function addUltragoalGoal(cwd: string, options: AddUltragoalGoalOpt
status: goal.status,
evidence: options.evidence,
message: goal.title,
- });
+ }, beforeCommit);
return { plan, goal };
});
}
@@ -1457,8 +1495,8 @@ function applySteeringMutation(plan: UltragoalPlan, proposal: UltragoalSteeringP
}
export async function steerUltragoal(cwd: string, proposal: UltragoalSteeringProposal, options: { now?: Date; directiveText?: string } = {}): Promise<SteerUltragoalResult> {
- return withUltragoalMutationLock(cwd, async () => {
- const plan = await readUltragoalPlanUnderLock(cwd);
+ return withUltragoalMutationLock(cwd, async (beforeCommit) => {
+ const plan = await readUltragoalPlanUnderLock(cwd, beforeCommit);
const existing = proposal.idempotencyKey
? (await readSteeringLedgerEntries(cwd)).find((entry) => entry.event === 'steering_accepted' && (entry.idempotencyKey === proposal.idempotencyKey || entry.steering?.idempotencyKey === proposal.idempotencyKey) && entry.steering)
: undefined;
@@ -1499,7 +1537,7 @@ export async function steerUltragoal(cwd: string, proposal: UltragoalSteeringPro
idempotencyKey: proposal.idempotencyKey,
};
- if (invariant.accepted) await writePlan(cwd, plan);
+ if (invariant.accepted && proposal.kind !== 'annotate_ledger') await writePlan(cwd, plan, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: invariant.accepted ? 'steering_accepted' : 'steering_rejected',
@@ -1510,7 +1548,7 @@ export async function steerUltragoal(cwd: string, proposal: UltragoalSteeringPro
mutationKind: proposal.kind,
before: audit.before,
after: audit.after,
- });
+ }, beforeCommit);
return { plan, accepted: invariant.accepted, audit, rejectedReasons: invariant.rejectedReasons, deduped: false };
});
@@ -1730,20 +1768,20 @@ function validateQualityGate(value: unknown, requiredInvariants: readonly Requir
}
export async function startNextUltragoal(cwd: string, options: StartNextOptions = {}): Promise<{ plan: UltragoalPlan; goal: UltragoalItem | null; resumed: boolean; done: boolean }> {
- return withUltragoalMutationLock(cwd, async () => {
- const plan = await readUltragoalPlanUnderLock(cwd);
+ return withUltragoalMutationLock(cwd, async (beforeCommit) => {
+ const plan = await readUltragoalPlanUnderLock(cwd, beforeCommit);
const now = iso(options.now);
if (plan.aggregateCompletion?.status === 'complete') return { plan, goal: null, resumed: false, done: true };
const existing = plan.goals.find((goal) => goal.status === 'in_progress' && isScheduleEligibleGoal(goal));
if (existing) {
- await appendLedger(cwd, { ts: now, event: 'goal_resumed', goalId: existing.id, status: existing.status, message: 'Resuming active ultragoal' });
+ await appendLedger(cwd, { ts: now, event: 'goal_resumed', goalId: existing.id, status: existing.status, message: 'Resuming active ultragoal' }, beforeCommit);
return { plan, goal: existing, resumed: true, done: false };
}
let next = plan.goals.find((goal) => goal.status === 'pending' && isScheduleEligible(goal));
if (!next && options.retryFailed) {
next = plan.goals.find((goal) => goal.status === 'failed' && !goal.nonRetriable && isScheduleEligible(goal));
- if (next) await appendLedger(cwd, { ts: now, event: 'goal_retried', goalId: next.id, status: 'pending', message: next.failureReason });
+ if (next) await appendLedger(cwd, { ts: now, event: 'goal_retried', goalId: next.id, status: 'pending', message: next.failureReason }, beforeCommit);
}
if (!next) return { plan, goal: null, resumed: false, done: isUltragoalDone(plan) };
@@ -1756,15 +1794,15 @@ export async function startNextUltragoal(cwd: string, options: StartNextOptions
next.updatedAt = now;
plan.activeGoalId = next.id;
plan.updatedAt = now;
- await writePlan(cwd, plan);
- await appendLedger(cwd, { ts: now, event: 'goal_started', goalId: next.id, status: next.status, message: `Attempt ${next.attempt}` });
+ await writePlan(cwd, plan, beforeCommit);
+ await appendLedger(cwd, { ts: now, event: 'goal_started', goalId: next.id, status: next.status, message: `Attempt ${next.attempt}` }, beforeCommit);
return { plan, goal: next, resumed: false, done: false };
});
}
export async function checkpointUltragoal(cwd: string, options: CheckpointOptions): Promise<UltragoalPlan> {
- return withUltragoalMutationLock(cwd, async () => {
- const plan = await readUltragoalPlanUnderLock(cwd);
+ return withUltragoalMutationLock(cwd, async (beforeCommit) => {
+ const plan = await readUltragoalPlanUnderLock(cwd, beforeCommit);
const goal = plan.goals.find((candidate) => candidate.id === options.goalId);
if (!goal) throw new UltragoalError(`Unknown ultragoal id: ${options.goalId}`);
if (plan.aggregateCompletion?.status === 'complete' && options.status !== 'complete') {
@@ -1781,7 +1819,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
goal.failureReason = assertNonEmpty(options.evidence, '--evidence');
plan.activeGoalId = goal.id;
plan.updatedAt = now;
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'goal_blocked',
@@ -1790,7 +1828,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
evidence: options.evidence,
codexGoal: options.codexGoal,
message: 'Codex get_goal was unavailable due to a DB/schema/context error; strict completion reconciliation is deferred until get_goal works.',
- });
+ }, beforeCommit);
return plan;
}
if (!snapshot?.available) {
@@ -1811,7 +1849,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
goal.updatedAt = now;
plan.activeGoalId = goal.id;
plan.updatedAt = now;
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'goal_blocked',
@@ -1820,7 +1858,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
evidence,
codexGoal: options.codexGoal,
message: 'Native Codex goal status is blocked for the matching objective; recorded a non-terminal goal_blocked checkpoint. Continue work without treating this as complete or failed; re-check get_goal when the blocker clears.',
- });
+ }, beforeCommit);
return plan;
}
if (snapshot.status !== 'complete') {
@@ -1834,7 +1872,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
if (safeCompletedAggregateBlocker) goal.failureReason = assertNonEmpty(options.evidence, '--evidence');
plan.activeGoalId = goal.id;
plan.updatedAt = now;
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'goal_blocked',
@@ -1845,7 +1883,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
message: safeCompletedAggregateBlocker
? 'Completed aggregate Codex goal is already terminal while the repo-native microgoal remains in progress; recorded a non-terminal safe-recovery blocker to avoid repeating an impossible checkpoint loop.'
: undefined,
- });
+ }, beforeCommit);
return plan;
}
let aggregateCompletion: UltragoalAggregateCompletion | undefined;
@@ -1942,7 +1980,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
plan.aggregateCompletion = aggregateCompletion;
if (plan.activeGoalId === goal.id) delete plan.activeGoalId;
plan.updatedAt = now;
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'goal_completed',
@@ -1952,7 +1990,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
codexGoal: options.codexGoal,
qualityGate,
message: 'Active repo-native microgoal completed while reconciling a completed task-scoped aggregate Codex goal snapshot.',
- });
+ }, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'aggregate_completed',
@@ -1962,7 +2000,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
codexGoal: options.codexGoal,
qualityGate,
message: 'Aggregate ultragoal plan completed via task-scoped Codex goal snapshot; checkpointed active microgoal row was reconciled to complete.',
- });
+ }, beforeCommit);
return plan;
}
goal.status = options.status;
@@ -2008,7 +2046,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
if (plan.activeGoalId === goal.id) delete plan.activeGoalId;
}
plan.updatedAt = now;
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
const blockerEvent = goal.status === 'needs_user_decision';
await appendLedger(cwd, {
ts: now,
@@ -2024,7 +2062,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
message: blockerEvent
? `Blocked on repeated external authorization. Required decision: ${goal.requiredExternalDecision}.`
: undefined,
- });
+ }, beforeCommit);
if (options.status === 'complete' && goal.resolvesReviewBlockedGoalId) {
const resolvedParent = plan.goals.find((candidate) => candidate.id === goal.resolvesReviewBlockedGoalId);
if (resolvedParent?.reviewBlockerResolution?.status === 'complete' && resolvedParent.reviewBlockerResolution.resolverGoalId === goal.id) {
@@ -2037,7 +2075,7 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
codexGoal: options.codexGoal,
qualityGate,
message: `Review-blocked final story resolved by ${goal.id}; original failed review remains in prior final_review_failed/goal_review_blocked ledger entries.`,
- });
+ }, beforeCommit);
}
}
if (normalFinalAggregateCompletion) {
@@ -2050,15 +2088,15 @@ export async function checkpointUltragoal(cwd: string, options: CheckpointOption
codexGoal: options.codexGoal,
qualityGate,
message: 'Aggregate ultragoal plan completed with a clean final quality gate.',
- });
+ }, beforeCommit);
}
return plan;
});
}
export async function recordFinalReviewBlockers(cwd: string, options: RecordFinalReviewBlockersOptions): Promise<{ plan: UltragoalPlan; blockedGoal: UltragoalItem; addedGoal: UltragoalItem }> {
- return withUltragoalMutationLock(cwd, async () => {
- const plan = await readUltragoalPlanUnderLock(cwd);
+ return withUltragoalMutationLock(cwd, async (beforeCommit) => {
+ const plan = await readUltragoalPlanUnderLock(cwd, beforeCommit);
const goal = plan.goals.find((candidate) => candidate.id === options.goalId);
if (!goal) throw new UltragoalError(`Unknown ultragoal id: ${options.goalId}`);
assertNonEmpty(options.evidence, '--evidence');
@@ -2102,7 +2140,7 @@ export async function recordFinalReviewBlockers(cwd: string, options: RecordFina
if (plan.activeGoalId === goal.id) delete plan.activeGoalId;
plan.updatedAt = now;
- await writePlan(cwd, plan);
+ await writePlan(cwd, plan, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'final_review_failed',
@@ -2113,7 +2151,7 @@ export async function recordFinalReviewBlockers(cwd: string, options: RecordFina
message: aggregateMode
? 'Final aggregate code-review was not clean; blocker story was appended while Codex goal remains active.'
: 'Final per-story code-review was not clean; blocker story was appended and may require an available Codex goal context.',
- });
+ }, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'goal_added',
@@ -2121,7 +2159,7 @@ export async function recordFinalReviewBlockers(cwd: string, options: RecordFina
status: addedGoal.status,
evidence: options.evidence,
message: addedGoal.title,
- });
+ }, beforeCommit);
await appendLedger(cwd, {
ts: now,
event: 'goal_review_blocked',
@@ -2129,7 +2167,7 @@ export async function recordFinalReviewBlockers(cwd: string, options: RecordFina
status: goal.status,
evidence: options.evidence,
codexGoal: options.codexGoal,
- });
+ }, beforeCommit);
return { plan, blockedGoal: goal, addedGoal };
});
}
diff --git a/src/ultragoal/native-bootstrap.ts b/src/ultragoal/native-bootstrap.ts
new file mode 100644
index 00000000..0d0079e3
--- /dev/null
+++ b/src/ultragoal/native-bootstrap.ts
@@ -0,0 +1,1106 @@
+import { randomUUID } from 'node:crypto';
+import { constants as fsConstants, type Dirent } from 'node:fs';
+import { access, chmod, lstat, mkdir, open, readFile, readdir, realpath, rename, unlink, writeFile } from 'node:fs/promises';
+import { homedir } from 'node:os';
+import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
+import {
+ acquireCrossProcessFileLock,
+ ensureExactDescriptiveLeaderForSession,
+ isNativeSubagentAuthorityFenced,
+ NATIVE_SUBAGENT_PROVENANCE,
+ recordSubagentTurnForSession,
+ readSubagentTrackingState,
+} from '../subagents/tracker.js';
+import type { NativeUltragoalBackend } from '../config/native-ultragoal.js';
+
+export const NATIVE_ULTRAGOAL_BOOTSTRAP_FILE = 'native-ultragoal-bootstrap.json';
+export const NATIVE_ASSIGNMENT_DIRECTORY = 'native-assignments';
+export const DOCUMENTED_HOST_RECEIPT_UNAVAILABLE = 'documented_host_native_executor_receipt_unavailable';
+
+export type NativeUltragoalBootstrapStatus =
+ | 'awaiting-executor'
+ | 'ready'
+ | 'activating'
+ | 'active'
+ | 'revoked'
+ | 'expired'
+ | 'host-receipt-unavailable';
+
+export interface NativeUltragoalBootstrapState {
+ schema_version: 1;
+ kind: 'native-ultragoal-bootstrap';
+ generation: string;
+ backend: NativeUltragoalBackend;
+ status: NativeUltragoalBootstrapStatus;
+ session_id: string;
+ root_thread_id: string;
+ child_agent_id?: string;
+ created_at: string;
+ updated_at: string;
+ expires_at: string;
+ reason?: string;
+}
+
+export interface LocalNativeExecutorAssignment {
+ schema_version: 1;
+ kind: 'native-subagent-assignment';
+ lifecycle: 'active' | 'revoked' | 'expired';
+ root_session_id: string;
+ root_thread_id: string;
+ child_agent_id: string;
+ agent_type: 'executor';
+ allowed_actions: Array<'path-write' | 'bash-write'>;
+ path_prefixes: string[];
+ issued_at: string;
+ expires_at: string;
+ bootstrap_generation: string;
+ revoked_at?: string;
+ revoke_reason?: string;
+}
+
+export interface HostNativeExecutorReceiptVerifier {
+ readonly available: boolean;
+ verifyActivationReceipt(input: {
+ cwd: string;
+ sessionId: string;
+ rootThreadId: string;
+ }): Promise<{ ok: true; childAgentId: string } | { ok: false; reason: string }>;
+}
+
+const ACTIVE_ASSIGNMENT_SCHEMA_KEYS = new Set([
+ 'schema_version',
+ 'kind',
+ 'lifecycle',
+ 'root_session_id',
+ 'root_thread_id',
+ 'child_agent_id',
+ 'agent_type',
+ 'allowed_actions',
+ 'path_prefixes',
+ 'issued_at',
+ 'expires_at',
+ 'bootstrap_generation',
+]);
+const MAX_ASSIGNMENT_LIFETIME_MS = 24 * 60 * 60 * 1000;
+
+export const unavailableHostNativeExecutorReceiptVerifier: HostNativeExecutorReceiptVerifier = {
+ available: false,
+ async verifyActivationReceipt() {
+ return { ok: false, reason: DOCUMENTED_HOST_RECEIPT_UNAVAILABLE };
+ },
+};
+
+function bootstrapPath(stateDir: string, sessionId: string): string {
+ return join(stateDir, 'sessions', sessionId, NATIVE_ULTRAGOAL_BOOTSTRAP_FILE);
+}
+
+async function withNativeUltragoalLifecycleLock<T>(
+ stateDir: string,
+ sessionId: string,
+ operation: () => Promise<T>,
+): Promise<T> {
+ const handle = await acquireCrossProcessFileLock(bootstrapPath(stateDir, sessionId), {
+ maxAttempts: 200,
+ retryMs: 25,
+ preserveLiveLocalOwner: true,
+ });
+ try {
+ const result = await operation();
+ handle.assertOwnership();
+ return result;
+ } finally {
+ handle.release();
+ }
+}
+
+export function nativeExecutorAssignmentPath(stateDir: string, sessionId: string, childAgentId: string): string {
+ return join(
+ stateDir,
+ 'sessions',
+ sessionId,
+ NATIVE_ASSIGNMENT_DIRECTORY,
+ `${encodeURIComponent(childAgentId)}.json`,
+ );
+}
+
+async function writeJsonAtomic(path: string, value: unknown, mode = 0o600): Promise<void> {
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
+ const tmpPath = `${path}.tmp.${process.pid}.${Date.now()}.${randomUUID()}`;
+ await writeFile(tmpPath, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf-8', mode });
+ try {
+ await chmod(tmpPath, mode);
+ await rename(tmpPath, path);
+ } catch (error) {
+ await unlink(tmpPath).catch(() => {});
+ throw error;
+ }
+}
+
+async function readJsonObject(path: string): Promise<Record<string, unknown> | null> {
+ try {
+ const parsed = JSON.parse(await readFile(path, 'utf-8')) as unknown;
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
+ ? parsed as Record<string, unknown>
+ : null;
+ } catch {
+ return null;
+ }
+}
+
+function readString(value: unknown): string {
+ return typeof value === 'string' ? value.trim() : '';
+}
+
+function normalizePrefix(cwd: string, rawPrefix: string): string | null {
+ const trimmed = rawPrefix.trim().replace(/\\/g, '/');
+ if (trimmed === '.') return '.';
+ if (!trimmed || isAbsolute(trimmed) || trimmed.includes('\0') || /[$`*?\[\]{}]/.test(trimmed)) return null;
+ const absolute = resolve(cwd, trimmed);
+ const normalized = relative(cwd, absolute).replace(/\\/g, '/');
+ if (!normalized || normalized === '..' || normalized.startsWith('../')) return null;
+ if (
+ normalized === '.git'
+ || normalized.startsWith('.git/')
+ || normalized === '.omx'
+ || normalized.startsWith('.omx/')
+ ) return null;
+ return normalized;
+}
+
+async function pathPrefixTraversesUnsafeLink(cwd: string, relativePath: string): Promise<boolean> {
+ if (relativePath === '.') return false;
+ let current = resolve(cwd);
+ for (const segment of relativePath.split('/').filter(Boolean)) {
+ current = join(current, segment);
+ try {
+ const metadata = await lstat(current);
+ if (metadata.isSymbolicLink() || (!metadata.isDirectory() && metadata.nlink > 1)) return true;
+ } catch (error) {
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue;
+ return true;
+ }
+ }
+ return false;
+}
+
+export async function parseActiveLocalNativeExecutorAssignment(
+ raw: Record<string, unknown> | null,
+ input: {
+ cwd: string;
+ sessionId: string;
+ rootThreadId: string;
+ childAgentId: string;
+ agentType: string;
+ nowMs?: number;
+ },
+): Promise<(LocalNativeExecutorAssignment & { lifecycle: 'active' }) | null> {
+ if (!raw || Object.keys(raw).some((key) => !ACTIVE_ASSIGNMENT_SCHEMA_KEYS.has(key))) return null;
+ if (
+ raw.schema_version !== 1
+ || raw.kind !== 'native-subagent-assignment'
+ || raw.lifecycle !== 'active'
+ || readString(raw.root_session_id) !== input.sessionId
+ || readString(raw.root_thread_id) !== input.rootThreadId
+ || readString(raw.child_agent_id) !== input.childAgentId
+ || readString(raw.agent_type).toLowerCase() !== 'executor'
+ || input.agentType.trim().toLowerCase() !== 'executor'
+ || !readString(raw.bootstrap_generation)
+ ) return null;
+
+ const nowMs = input.nowMs ?? Date.now();
+ const issuedAt = Date.parse(readString(raw.issued_at));
+ const expiresAt = Date.parse(readString(raw.expires_at));
+ if (
+ !Number.isFinite(issuedAt)
+ || !Number.isFinite(expiresAt)
+ || issuedAt > nowMs + 30_000
+ || expiresAt <= nowMs
+ || expiresAt <= issuedAt
+ || expiresAt - issuedAt > MAX_ASSIGNMENT_LIFETIME_MS
+ ) return null;
+
+ const allowedActions = Array.isArray(raw.allowed_actions)
+ ? raw.allowed_actions.map((value) => readString(value))
+ : [];
+ if (
+ allowedActions.length === 0
+ || allowedActions.length > 2
+ || new Set(allowedActions).size !== allowedActions.length
+ || allowedActions.some((action) => action !== 'path-write' && action !== 'bash-write')
+ ) return null;
+
+ const pathPrefixes = Array.isArray(raw.path_prefixes)
+ ? raw.path_prefixes.map((value) => normalizePrefix(input.cwd, readString(value)))
+ : [];
+ if (
+ pathPrefixes.length === 0
+ || pathPrefixes.length > 32
+ || pathPrefixes.some((prefix) => prefix === null)
+ || new Set(pathPrefixes).size !== pathPrefixes.length
+ ) return null;
+ for (const prefix of pathPrefixes as string[]) {
+ if (await pathPrefixTraversesUnsafeLink(input.cwd, prefix)) return null;
+ }
+
+ return {
+ schema_version: 1,
+ kind: 'native-subagent-assignment',
+ lifecycle: 'active',
+ root_session_id: input.sessionId,
+ root_thread_id: input.rootThreadId,
+ child_agent_id: input.childAgentId,
+ agent_type: 'executor',
+ allowed_actions: allowedActions as Array<'path-write' | 'bash-write'>,
+ path_prefixes: pathPrefixes as string[],
+ issued_at: new Date(issuedAt).toISOString(),
+ expires_at: new Date(expiresAt).toISOString(),
+ bootstrap_generation: readString(raw.bootstrap_generation),
+ };
+}
+
+function parseBootstrap(raw: Record<string, unknown> | null): NativeUltragoalBootstrapState | null {
+ if (
+ raw?.schema_version !== 1
+ || raw.kind !== 'native-ultragoal-bootstrap'
+ || !readString(raw.generation)
+ || !['off', 'host', 'local-experimental'].includes(readString(raw.backend))
+ || ![
+ 'awaiting-executor', 'ready', 'activating', 'active', 'revoked', 'expired', 'host-receipt-unavailable',
+ ].includes(readString(raw.status))
+ || !readString(raw.session_id)
+ || !readString(raw.root_thread_id)
+ || !readString(raw.created_at)
+ || !readString(raw.updated_at)
+ || !readString(raw.expires_at)
+ || !Number.isFinite(Date.parse(readString(raw.expires_at)))
+ ) return null;
+ return raw as unknown as NativeUltragoalBootstrapState;
+}
+
+function parseAssignment(raw: Record<string, unknown> | null): LocalNativeExecutorAssignment | null {
+ if (
+ raw?.schema_version !== 1
+ || raw.kind !== 'native-subagent-assignment'
+ || !['active', 'revoked', 'expired'].includes(readString(raw.lifecycle))
+ || raw.agent_type !== 'executor'
+ || !Array.isArray(raw.allowed_actions)
+ || !Array.isArray(raw.path_prefixes)
+ || !readString(raw.root_session_id)
+ || !readString(raw.root_thread_id)
+ || !readString(raw.child_agent_id)
+ || !readString(raw.issued_at)
+ || !readString(raw.expires_at)
+ || !readString(raw.bootstrap_generation)
+ || !Number.isFinite(Date.parse(readString(raw.expires_at)))
+ ) return null;
+ return raw as unknown as LocalNativeExecutorAssignment;
+}
+
+async function beginNativeUltragoalBootstrapUnlocked(input: {
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ rootThreadId: string;
+ backend: NativeUltragoalBackend;
+ ttlSeconds: number;
+ now?: Date;
+}): Promise<NativeUltragoalBootstrapState> {
+ const now = input.now ?? new Date();
+ const cwd = input.cwd;
+ ensureExactDescriptiveLeaderForSession(cwd, {
+ sessionId: input.sessionId,
+ rootThreadId: input.rootThreadId,
+ timestamp: now.toISOString(),
+ });
+ const existing = parseBootstrap(await readJsonObject(bootstrapPath(input.stateDir, input.sessionId)));
+ if (
+ existing
+ && existing.session_id === input.sessionId
+ && existing.root_thread_id === input.rootThreadId
+ && existing.backend === input.backend
+ && Date.parse(existing.expires_at) > now.getTime()
+ && ['awaiting-executor', 'ready', 'activating', 'active'].includes(existing.status)
+ ) return existing;
+
+ if (existing?.child_agent_id) {
+ const staleAssignmentPath = nativeExecutorAssignmentPath(
+ input.stateDir,
+ input.sessionId,
+ existing.child_agent_id,
+ );
+ const staleAssignment = parseAssignment(await readJsonObject(staleAssignmentPath));
+ if (staleAssignment?.lifecycle === 'active') {
+ await transitionAssignment(
+ staleAssignmentPath,
+ staleAssignment,
+ Date.parse(existing.expires_at) <= now.getTime() ? 'expired' : 'revoked',
+ 'bootstrap_replaced',
+ now,
+ );
+ }
+ }
+
+ const state: NativeUltragoalBootstrapState = {
+ schema_version: 1,
+ kind: 'native-ultragoal-bootstrap',
+ generation: randomUUID(),
+ backend: input.backend,
+ status: input.backend === 'host' ? 'host-receipt-unavailable' : 'awaiting-executor',
+ session_id: input.sessionId,
+ root_thread_id: input.rootThreadId,
+ created_at: now.toISOString(),
+ updated_at: now.toISOString(),
+ expires_at: new Date(now.getTime() + input.ttlSeconds * 1000).toISOString(),
+ ...(input.backend === 'host' ? { reason: DOCUMENTED_HOST_RECEIPT_UNAVAILABLE } : {}),
+ };
+ await writeJsonAtomic(bootstrapPath(input.stateDir, input.sessionId), state);
+ return state;
+}
+
+export async function beginNativeUltragoalBootstrap(
+ input: Parameters<typeof beginNativeUltragoalBootstrapUnlocked>[0],
+): Promise<NativeUltragoalBootstrapState> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, () => (
+ beginNativeUltragoalBootstrapUnlocked(input)
+ ));
+}
+
+export async function readNativeUltragoalBootstrap(
+ stateDir: string,
+ sessionId: string,
+): Promise<NativeUltragoalBootstrapState | null> {
+ return parseBootstrap(await readJsonObject(bootstrapPath(stateDir, sessionId)));
+}
+
+export async function validateLocalNativeExecutorIdentity(input: {
+ cwd: string;
+ sessionId: string;
+ rootThreadId: string;
+ childAgentId: string;
+ receiptNotBefore?: string;
+ receiptNotAfter?: string;
+}): Promise<{ ok: true } | { ok: false; reason: string }> {
+ const tracking = await readSubagentTrackingState(input.cwd).catch(() => null);
+ const session = tracking?.sessions?.[input.sessionId];
+ const child = session?.threads?.[input.childAgentId];
+ if (!session || session.leader_thread_id !== input.rootThreadId) {
+ return { ok: false, reason: 'leader_session_mismatch' };
+ }
+ if (isNativeSubagentAuthorityFenced(input.cwd, input.childAgentId)) {
+ return { ok: false, reason: 'child_authority_fenced' };
+ }
+ if (child) {
+ if (child.kind !== 'subagent') return { ok: false, reason: 'child_not_tracked' };
+ if (child.reopen_authority_revoked === true) return { ok: false, reason: 'child_authority_revoked' };
+ if (child.status && child.status !== 'available') return { ok: false, reason: `child_${child.status}` };
+ if (child.completed_at) return { ok: false, reason: 'child_completed' };
+ const role = readString(child.mode || child.role).toLowerCase();
+ if (role && role !== 'executor') return { ok: false, reason: 'child_role_mismatch' };
+ const carriesAuthority = child.provenance_kind === NATIVE_SUBAGENT_PROVENANCE
+ || child.direct_child_parent_id !== undefined
+ || child.direct_child_root_id !== undefined;
+ if (carriesAuthority) {
+ if (role !== 'executor') return { ok: false, reason: 'child_role_mismatch' };
+ if (child.provenance_kind !== NATIVE_SUBAGENT_PROVENANCE) {
+ return { ok: false, reason: 'child_native_authority_unproven' };
+ }
+ if (child.direct_child_parent_id !== input.rootThreadId) {
+ return { ok: false, reason: 'child_parent_mismatch' };
+ }
+ if (child.direct_child_root_id !== input.rootThreadId) {
+ return { ok: false, reason: 'child_root_mismatch' };
+ }
+ return { ok: true };
+ }
+ }
+
+ if (!readString(input.receiptNotBefore) || !readString(input.receiptNotAfter)) {
+ return { ok: false, reason: 'child_transcript_receipt_unbound' };
+ }
+
+ // Codex App v2 currently puts the canonical child id and typed direct-parent
+ // receipt in the child rollout session_meta, while SessionStart reports the
+ // root session id. local-experimental may consume that same-user receipt for
+ // this scoped assignment only; it never promotes the child into persisted
+ // reopen authority in subagent-tracking.json.
+ const transcriptReceipt = await validateLocalCodexAppExecutorTranscript(input);
+ if (transcriptReceipt.ok) return transcriptReceipt;
+ return {
+ ok: false,
+ reason: transcriptReceipt.reason || (child ? 'child_native_authority_unproven' : 'child_not_tracked'),
+ };
+}
+
+const MAX_LOCAL_TRANSCRIPT_FIRST_LINE_BYTES = 64 * 1024;
+const MAX_LOCAL_TRANSCRIPT_SCAN_ENTRIES = 10_000;
+const CANONICAL_CODEX_THREAD_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
+
+export type LocalNativeExecutorChildReceiptResolution =
+ | { ok: true; childAgentId: string }
+ | { ok: false; reason: string };
+
+function readUniqueStringAlias(
+ value: Record<string, unknown> | null,
+ aliases: string[],
+): { present: false } | { present: true; valid: false } | { present: true; valid: true; value: string } {
+ if (!value) return { present: false };
+ const present = aliases.filter((alias) => Object.prototype.hasOwnProperty.call(value, alias));
+ if (present.length === 0) return { present: false };
+ const values = present.map((alias) => readString(value[alias]));
+ if (values.some((candidate) => !candidate) || new Set(values).size !== 1) {
+ return { present: true, valid: false };
+ }
+ return { present: true, valid: true, value: values[0]! };
+}
+
+async function readBoundedTranscriptSessionMeta(path: string): Promise<Record<string, unknown> | null> {
+ const metadata = await lstat(path).catch(() => null);
+ if (
+ !metadata
+ || !metadata.isFile()
+ || metadata.isSymbolicLink()
+ || metadata.nlink !== 1
+ || (metadata.mode & 0o022) !== 0
+ ) return null;
+
+ const handle = await open(path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0)).catch(() => null);
+ if (!handle) return null;
+ try {
+ const openedMetadata = await handle.stat();
+ if (
+ !openedMetadata.isFile()
+ || openedMetadata.nlink !== 1
+ || (openedMetadata.mode & 0o022) !== 0
+ || openedMetadata.dev !== metadata.dev
+ || openedMetadata.ino !== metadata.ino
+ ) return null;
+ const buffer = Buffer.alloc(MAX_LOCAL_TRANSCRIPT_FIRST_LINE_BYTES);
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
+ const newline = buffer.subarray(0, bytesRead).indexOf(0x0a);
+ if (newline < 0) return null;
+ const line = buffer.subarray(0, newline).toString('utf8').trim();
+ if (!line) return null;
+ const parsed = JSON.parse(line) as unknown;
+ const finalMetadata = await handle.stat();
+ if (
+ finalMetadata.dev !== openedMetadata.dev
+ || finalMetadata.ino !== openedMetadata.ino
+ || finalMetadata.mode !== openedMetadata.mode
+ || finalMetadata.nlink !== openedMetadata.nlink
+ || finalMetadata.size !== openedMetadata.size
+ || finalMetadata.mtimeMs !== openedMetadata.mtimeMs
+ || finalMetadata.ctimeMs !== openedMetadata.ctimeMs
+ ) return null;
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
+ ? parsed as Record<string, unknown>
+ : null;
+ } catch {
+ return null;
+ } finally {
+ await handle.close().catch(() => {});
+ }
+}
+
+async function findLocalCodexTranscriptPaths(
+ childAgentId: string,
+): Promise<{ paths: string[]; complete: boolean }> {
+ const codexHome = process.env.CODEX_HOME?.trim() || join(homedir(), '.codex');
+ const suffix = `-${childAgentId}.jsonl`;
+ const matches: string[] = [];
+ let visited = 0;
+ const pending = [{ path: join(codexHome, 'sessions'), depth: 0 }];
+
+ while (pending.length > 0) {
+ const current = pending.shift()!;
+ let entries: Dirent[];
+ try {
+ entries = await readdir(current.path, { withFileTypes: true });
+ } catch {
+ return { paths: matches, complete: false };
+ }
+ if (visited + entries.length > MAX_LOCAL_TRANSCRIPT_SCAN_ENTRIES) {
+ return { paths: matches, complete: false };
+ }
+ visited += entries.length;
+ for (const entry of entries) {
+ const path = join(current.path, entry.name);
+ if (entry.isDirectory() && current.depth < 4) {
+ pending.push({ path, depth: current.depth + 1 });
+ } else if (entry.isFile() && entry.name.endsWith(suffix)) {
+ matches.push(path);
+ if (matches.length > 1) return { paths: matches, complete: true };
+ }
+ }
+ }
+ return { paths: matches, complete: true };
+}
+
+async function findLiveLocalCodexTranscriptPaths(): Promise<{ paths: string[]; complete: boolean }> {
+ const codexHome = process.env.CODEX_HOME?.trim() || join(homedir(), '.codex');
+ const matches: string[] = [];
+ let visited = 0;
+ const pending = [{ path: join(codexHome, 'sessions'), depth: 0 }];
+
+ while (pending.length > 0) {
+ const current = pending.shift()!;
+ let entries: Dirent[];
+ try {
+ entries = await readdir(current.path, { withFileTypes: true });
+ } catch {
+ return { paths: matches, complete: false };
+ }
+ if (visited + entries.length > MAX_LOCAL_TRANSCRIPT_SCAN_ENTRIES) {
+ return { paths: matches, complete: false };
+ }
+ visited += entries.length;
+ for (const entry of entries) {
+ const path = join(current.path, entry.name);
+ if (entry.isDirectory() && current.depth < 4) {
+ pending.push({ path, depth: current.depth + 1 });
+ } else if (entry.isFile() && entry.name.startsWith('rollout-') && entry.name.endsWith('.jsonl')) {
+ matches.push(path);
+ }
+ }
+ }
+ return { paths: matches, complete: true };
+}
+
+/**
+ * Resolve a typed executor's canonical child id from the App-owned rollout.
+ * The supplied agent path is only a lookup key; every authority-bearing field
+ * is re-attested from one safe, unique, generation-bounded session_meta record.
+ */
+export async function resolveLocalNativeExecutorChildReceipt(input: {
+ cwd: string;
+ sessionId: string;
+ rootThreadId: string;
+ agentPath: string;
+ receiptNotBefore: string;
+ receiptNotAfter: string;
+ now?: Date;
+}): Promise<LocalNativeExecutorChildReceiptResolution> {
+ const requestedAgentPath = readString(input.agentPath);
+ const notBefore = Date.parse(readString(input.receiptNotBefore));
+ const notAfter = Date.parse(readString(input.receiptNotAfter));
+ if (
+ !requestedAgentPath
+ || !Number.isFinite(notBefore)
+ || !Number.isFinite(notAfter)
+ || notAfter < notBefore
+ ) return { ok: false, reason: 'child_transcript_receipt_unbound' };
+
+ const canonicalInputCwd = await realpath(input.cwd).catch(() => '');
+ if (!canonicalInputCwd) return { ok: false, reason: 'child_transcript_receipt_cwd_invalid' };
+ const nowMs = (input.now ?? new Date()).getTime();
+ const matches: string[] = [];
+
+ const scan = await findLiveLocalCodexTranscriptPaths();
+ if (!scan.complete) return { ok: false, reason: 'child_transcript_receipt_scan_incomplete' };
+ for (const path of scan.paths) {
+ const record = await readBoundedTranscriptSessionMeta(path);
+ if (!record || record.type !== 'session_meta') continue;
+ const payload = record.payload && typeof record.payload === 'object' && !Array.isArray(record.payload)
+ ? record.payload as Record<string, unknown>
+ : null;
+ const source = payload?.source && typeof payload.source === 'object' && !Array.isArray(payload.source)
+ ? payload.source as Record<string, unknown>
+ : null;
+ const subagent = source?.subagent && typeof source.subagent === 'object' && !Array.isArray(source.subagent)
+ ? source.subagent as Record<string, unknown>
+ : null;
+ const spawn = subagent?.thread_spawn && typeof subagent.thread_spawn === 'object' && !Array.isArray(subagent.thread_spawn)
+ ? subagent.thread_spawn as Record<string, unknown>
+ : null;
+ const agentPath = readUniqueStringAlias(spawn, ['agent_path', 'agentPath']);
+ if (!agentPath.present || !agentPath.valid || agentPath.value !== requestedAgentPath) continue;
+
+ const childId = readUniqueStringAlias(payload, ['id']);
+ const sessionClaim = readUniqueStringAlias(payload, ['session_id', 'sessionId']);
+ const cwdClaim = readUniqueStringAlias(payload, ['cwd']);
+ const parentClaim = readUniqueStringAlias(spawn, ['parent_thread_id', 'parentThreadId']);
+ const roleClaim = readUniqueStringAlias(spawn, ['agent_role', 'agentRole', 'agent_type', 'agentType']);
+ const timestamp = Date.parse(readString(record.timestamp));
+ const canonicalReceiptCwd = cwdClaim.present && cwdClaim.valid
+ ? await realpath(cwdClaim.value).catch(() => '')
+ : '';
+ if (
+ !childId.present || !childId.valid || !CANONICAL_CODEX_THREAD_ID.test(childId.value)
+ || !path.endsWith(`-${childId.value}.jsonl`)
+ || !sessionClaim.present || !sessionClaim.valid
+ || (sessionClaim.value !== input.sessionId && sessionClaim.value !== input.rootThreadId)
+ || !parentClaim.present || !parentClaim.valid || parentClaim.value !== input.rootThreadId
+ || spawn?.depth !== 1
+ || !roleClaim.present || !roleClaim.valid || roleClaim.value.toLowerCase() !== 'executor'
+ || !canonicalReceiptCwd || canonicalReceiptCwd !== canonicalInputCwd
+ || !Number.isFinite(timestamp) || timestamp < notBefore || timestamp > notAfter
+ || timestamp > nowMs + 30_000
+ ) continue;
+ matches.push(childId.value);
+ if (matches.length > 1) return { ok: false, reason: 'child_transcript_receipt_ambiguous' };
+ }
+
+ return matches.length === 1
+ ? { ok: true, childAgentId: matches[0]! }
+ : { ok: false, reason: 'child_transcript_receipt_missing' };
+}
+
+async function validateLocalCodexAppExecutorTranscript(input: {
+ cwd: string;
+ sessionId: string;
+ rootThreadId: string;
+ childAgentId: string;
+ receiptNotBefore?: string;
+ receiptNotAfter?: string;
+}): Promise<{ ok: true } | { ok: false; reason: string }> {
+ const scan = await findLocalCodexTranscriptPaths(input.childAgentId);
+ if (!scan.complete) return { ok: false, reason: 'child_transcript_receipt_scan_incomplete' };
+ const paths = scan.paths;
+ if (paths.length === 0) return { ok: false, reason: 'child_transcript_receipt_missing' };
+ if (paths.length !== 1) return { ok: false, reason: 'child_transcript_receipt_ambiguous' };
+ const record = await readBoundedTranscriptSessionMeta(paths[0]!);
+ if (!record || record.type !== 'session_meta') {
+ return { ok: false, reason: 'child_transcript_receipt_invalid' };
+ }
+ const payload = record.payload && typeof record.payload === 'object' && !Array.isArray(record.payload)
+ ? record.payload as Record<string, unknown>
+ : null;
+ const source = payload?.source && typeof payload.source === 'object' && !Array.isArray(payload.source)
+ ? payload.source as Record<string, unknown>
+ : null;
+ const subagent = source?.subagent && typeof source.subagent === 'object' && !Array.isArray(source.subagent)
+ ? source.subagent as Record<string, unknown>
+ : null;
+ const spawn = subagent?.thread_spawn && typeof subagent.thread_spawn === 'object' && !Array.isArray(subagent.thread_spawn)
+ ? subagent.thread_spawn as Record<string, unknown>
+ : null;
+ const receiptSessionId = readString(payload?.session_id ?? payload?.sessionId);
+ const receiptCwd = readString(payload?.cwd);
+ const receiptTimestamp = Date.parse(readString(record.timestamp));
+ const receiptNotBefore = Date.parse(readString(input.receiptNotBefore));
+ const receiptNotAfter = Date.parse(readString(input.receiptNotAfter));
+ const [canonicalReceiptCwd, canonicalInputCwd] = receiptCwd
+ ? await Promise.all([realpath(receiptCwd).catch(() => ''), realpath(input.cwd).catch(() => '')])
+ : ['', ''];
+ const role = readString(spawn?.agent_role ?? spawn?.agentRole ?? spawn?.agent_type ?? spawn?.agentType).toLowerCase();
+ if (
+ readString(payload?.id) !== input.childAgentId
+ || (receiptSessionId !== input.sessionId && receiptSessionId !== input.rootThreadId)
+ || !Number.isFinite(receiptTimestamp)
+ || !Number.isFinite(receiptNotBefore)
+ || !Number.isFinite(receiptNotAfter)
+ || receiptTimestamp < receiptNotBefore
+ || receiptTimestamp > receiptNotAfter
+ || receiptTimestamp > Date.now() + 30_000
+ || !canonicalReceiptCwd
+ || canonicalReceiptCwd !== canonicalInputCwd
+ || readString(spawn?.parent_thread_id ?? spawn?.parentThreadId) !== input.rootThreadId
+ || spawn?.depth !== 1
+ || role !== 'executor'
+ ) return { ok: false, reason: 'child_transcript_receipt_mismatch' };
+ return { ok: true };
+}
+
+async function issueLocalNativeExecutorAssignmentUnlocked(input: {
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ rootThreadId: string;
+ childAgentId: string;
+ expectedGeneration: string;
+ pathPrefixes: string[];
+ ttlSeconds: number;
+ allowedActions?: Array<'path-write' | 'bash-write'>;
+ now?: Date;
+}): Promise<LocalNativeExecutorAssignment> {
+ const now = input.now ?? new Date();
+ if (!Number.isInteger(input.ttlSeconds) || input.ttlSeconds < 30 || input.ttlSeconds > 3600) {
+ throw new Error('invalid_native_assignment_ttl');
+ }
+ let bootstrap = await readNativeUltragoalBootstrap(input.stateDir, input.sessionId);
+ const wasActive = bootstrap?.status === 'active';
+ if (
+ !bootstrap
+ || bootstrap.backend !== 'local-experimental'
+ || bootstrap.session_id !== input.sessionId
+ || bootstrap.root_thread_id !== input.rootThreadId
+ || bootstrap.generation !== input.expectedGeneration
+ || !['awaiting-executor', 'ready', 'active'].includes(bootstrap.status)
+ || Date.parse(bootstrap.expires_at) <= now.getTime()
+ ) throw new Error('native_ultragoal_bootstrap_not_ready');
+
+ const tracked = await validateLocalNativeExecutorIdentity({
+ ...input,
+ receiptNotBefore: bootstrap.created_at,
+ receiptNotAfter: bootstrap.expires_at,
+ });
+ if (!tracked.ok) throw new Error(tracked.reason);
+ const normalizedPrefixes = input.pathPrefixes.map((prefix) => normalizePrefix(input.cwd, prefix));
+ if (
+ normalizedPrefixes.length === 0
+ || normalizedPrefixes.length > 32
+ || normalizedPrefixes.some((prefix) => prefix === null)
+ || new Set(normalizedPrefixes).size !== normalizedPrefixes.length
+ ) throw new Error('invalid_native_assignment_path_prefixes');
+ for (const prefix of normalizedPrefixes as string[]) {
+ if (await pathPrefixTraversesUnsafeLink(input.cwd, prefix)) {
+ throw new Error('invalid_native_assignment_path_prefixes');
+ }
+ }
+ const actions = input.allowedActions ?? ['path-write', 'bash-write'];
+ if (
+ actions.length === 0
+ || actions.length > 2
+ || new Set(actions).size !== actions.length
+ || actions.some((action) => action !== 'path-write' && action !== 'bash-write')
+ ) throw new Error('invalid_native_assignment_actions');
+ await recordSubagentTurnForSession(input.cwd, {
+ sessionId: input.sessionId,
+ threadId: input.childAgentId,
+ kind: 'subagent',
+ leaderThreadId: input.rootThreadId,
+ mode: 'executor',
+ });
+ const requestedExpiry = now.getTime() + input.ttlSeconds * 1000;
+ const expiresAt = wasActive
+ ? requestedExpiry
+ : Math.min(requestedExpiry, Date.parse(bootstrap.expires_at));
+ const assignment: LocalNativeExecutorAssignment = {
+ schema_version: 1,
+ kind: 'native-subagent-assignment',
+ lifecycle: 'active',
+ root_session_id: input.sessionId,
+ root_thread_id: input.rootThreadId,
+ child_agent_id: input.childAgentId,
+ agent_type: 'executor',
+ allowed_actions: actions,
+ path_prefixes: normalizedPrefixes as string[],
+ issued_at: now.toISOString(),
+ expires_at: new Date(expiresAt).toISOString(),
+ bootstrap_generation: bootstrap.generation,
+ };
+ await writeJsonAtomic(
+ nativeExecutorAssignmentPath(input.stateDir, input.sessionId, input.childAgentId),
+ assignment,
+ );
+ await writeJsonAtomic(bootstrapPath(input.stateDir, input.sessionId), {
+ ...bootstrap,
+ status: wasActive ? 'active' : 'ready',
+ child_agent_id: input.childAgentId,
+ updated_at: now.toISOString(),
+ ...(wasActive ? { expires_at: new Date(expiresAt).toISOString(), reason: undefined } : {}),
+ });
+ return assignment;
+}
+
+export async function issueLocalNativeExecutorAssignment(
+ input: Parameters<typeof issueLocalNativeExecutorAssignmentUnlocked>[0],
+): Promise<LocalNativeExecutorAssignment> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, () => (
+ issueLocalNativeExecutorAssignmentUnlocked(input)
+ ));
+}
+
+export async function nativeExecutorAssignmentFileIsSafe(stateDir: string, path: string): Promise<boolean> {
+ try {
+ const relativePath = relative(resolve(stateDir), resolve(path)).replace(/\\/g, '/');
+ if (!relativePath || relativePath === '..' || relativePath.startsWith('../')) return false;
+ let current = resolve(stateDir);
+ for (const segment of relativePath.split('/').filter(Boolean)) {
+ current = join(current, segment);
+ const metadata = await lstat(current);
+ if (metadata.isSymbolicLink()) return false;
+ if (current === resolve(path)) {
+ if (!metadata.isFile() || metadata.nlink !== 1 || (metadata.mode & 0o022) !== 0 || metadata.size > 64 * 1024) {
+ return false;
+ }
+ } else if (!metadata.isDirectory()) return false;
+ }
+ await access(path, fsConstants.R_OK);
+ return true;
+ } catch {
+ return false;
+ }
+}
+
+async function transitionAssignment(
+ path: string,
+ assignment: LocalNativeExecutorAssignment,
+ lifecycle: 'revoked' | 'expired',
+ reason: string,
+ now = new Date(),
+): Promise<LocalNativeExecutorAssignment> {
+ const next: LocalNativeExecutorAssignment = {
+ ...assignment,
+ lifecycle,
+ revoked_at: now.toISOString(),
+ revoke_reason: reason,
+ };
+ await writeJsonAtomic(path, next);
+ return next;
+}
+
+async function findReadyLocalNativeExecutorAssignmentUnlocked(input: {
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ rootThreadId: string;
+ now?: Date;
+}): Promise<LocalNativeExecutorAssignment | null> {
+ const now = input.now ?? new Date();
+ const bootstrap = await readNativeUltragoalBootstrap(input.stateDir, input.sessionId);
+ if (
+ !bootstrap
+ || bootstrap.backend !== 'local-experimental'
+ || bootstrap.root_thread_id !== input.rootThreadId
+ || !bootstrap.child_agent_id
+ || !['ready', 'activating', 'active'].includes(bootstrap.status)
+ || Date.parse(bootstrap.expires_at) <= now.getTime()
+ ) return null;
+ const path = nativeExecutorAssignmentPath(input.stateDir, input.sessionId, bootstrap.child_agent_id);
+ if (!await nativeExecutorAssignmentFileIsSafe(input.stateDir, path)) return null;
+ const rawAssignment = await readJsonObject(path);
+ const transitionableAssignment = parseAssignment(rawAssignment);
+ if (
+ transitionableAssignment?.lifecycle === 'active'
+ && Date.parse(transitionableAssignment.expires_at) <= now.getTime()
+ ) {
+ await transitionAssignment(path, transitionableAssignment, 'expired', 'assignment_expired', now);
+ return null;
+ }
+ const assignment = await parseActiveLocalNativeExecutorAssignment(rawAssignment, {
+ cwd: input.cwd,
+ sessionId: input.sessionId,
+ rootThreadId: input.rootThreadId,
+ childAgentId: bootstrap.child_agent_id,
+ agentType: 'executor',
+ nowMs: now.getTime(),
+ });
+ if (!assignment || assignment.bootstrap_generation !== bootstrap.generation) return null;
+ const tracked = await validateLocalNativeExecutorIdentity({
+ cwd: input.cwd,
+ sessionId: input.sessionId,
+ rootThreadId: input.rootThreadId,
+ childAgentId: assignment.child_agent_id,
+ receiptNotBefore: bootstrap.created_at,
+ receiptNotAfter: bootstrap.expires_at,
+ });
+ if (!tracked.ok) {
+ await transitionAssignment(path, assignment, 'revoked', tracked.reason, now);
+ return null;
+ }
+ return assignment;
+}
+
+export async function findReadyLocalNativeExecutorAssignment(
+ input: Parameters<typeof findReadyLocalNativeExecutorAssignmentUnlocked>[0],
+): Promise<LocalNativeExecutorAssignment | null> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, () => (
+ findReadyLocalNativeExecutorAssignmentUnlocked(input)
+ ));
+}
+
+async function validateNativeUltragoalActivationReceipt(input: {
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ childAgentId: string;
+ now?: Date;
+}, allowedStatuses: NativeUltragoalBootstrapStatus[]): Promise<{
+ ok: true;
+ assignment: LocalNativeExecutorAssignment;
+ bootstrap: NativeUltragoalBootstrapState;
+} | { ok: false }> {
+ const bootstrap = await readNativeUltragoalBootstrap(input.stateDir, input.sessionId);
+ if (
+ !bootstrap
+ || !allowedStatuses.includes(bootstrap.status)
+ || bootstrap.child_agent_id !== input.childAgentId
+ ) return { ok: false };
+ const now = input.now ?? new Date();
+ if (Date.parse(bootstrap.expires_at) <= now.getTime()) return { ok: false };
+ const assignmentPath = nativeExecutorAssignmentPath(input.stateDir, input.sessionId, input.childAgentId);
+ if (!await nativeExecutorAssignmentFileIsSafe(input.stateDir, assignmentPath)) return { ok: false };
+ const assignment = await parseActiveLocalNativeExecutorAssignment(await readJsonObject(assignmentPath), {
+ cwd: input.cwd,
+ sessionId: input.sessionId,
+ rootThreadId: bootstrap.root_thread_id,
+ childAgentId: input.childAgentId,
+ agentType: 'executor',
+ nowMs: now.getTime(),
+ });
+ if (
+ !assignment
+ || assignment.bootstrap_generation !== bootstrap.generation
+ ) return { ok: false };
+ const tracked = await validateLocalNativeExecutorIdentity({
+ cwd: input.cwd,
+ sessionId: input.sessionId,
+ rootThreadId: bootstrap.root_thread_id,
+ childAgentId: input.childAgentId,
+ receiptNotBefore: bootstrap.created_at,
+ receiptNotAfter: bootstrap.expires_at,
+ });
+ if (!tracked.ok) return { ok: false };
+ return { ok: true, assignment, bootstrap };
+}
+
+export async function withNativeUltragoalActivationAuthorization<T>(input: {
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ childAgentId: string;
+ bootstrapStatus?: 'activating' | 'active';
+}, run: (assertAuthorized: () => Promise<void>) => Promise<T>): Promise<
+ { ok: true; value: T } | { ok: false }
+> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, async () => {
+ const bootstrapStatus = input.bootstrapStatus ?? 'activating';
+ const initial = await validateNativeUltragoalActivationReceipt(input, [bootstrapStatus]);
+ if (!initial.ok) return { ok: false };
+ const expectedGeneration = initial.bootstrap.generation;
+ const expectedAssignmentId = initial.assignment.child_agent_id;
+ const assertAuthorized = async (): Promise<void> => {
+ const current = await validateNativeUltragoalActivationReceipt(input, [bootstrapStatus]);
+ if (
+ !current.ok
+ || current.bootstrap.generation !== expectedGeneration
+ || current.assignment.child_agent_id !== expectedAssignmentId
+ ) throw new Error('native_ultragoal_activation_receipt_invalid');
+ };
+ return { ok: true, value: await run(assertAuthorized) };
+ });
+}
+
+async function prepareNativeUltragoalBootstrapActivationUnlocked(input: {
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ childAgentId: string;
+ now?: Date;
+}): Promise<{ ok: true; assignment: LocalNativeExecutorAssignment } | { ok: false }> {
+ const validated = await validateNativeUltragoalActivationReceipt(input, ['ready', 'activating']);
+ if (!validated.ok) return validated;
+ const { assignment, bootstrap } = validated;
+ if (bootstrap.status !== 'activating') {
+ await writeJsonAtomic(bootstrapPath(input.stateDir, input.sessionId), {
+ ...bootstrap,
+ status: 'activating',
+ updated_at: (input.now ?? new Date()).toISOString(),
+ });
+ }
+ return { ok: true, assignment };
+}
+
+export async function prepareNativeUltragoalBootstrapActivation(
+ input: Parameters<typeof prepareNativeUltragoalBootstrapActivationUnlocked>[0],
+): Promise<{ ok: true; assignment: LocalNativeExecutorAssignment } | { ok: false }> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, () => (
+ prepareNativeUltragoalBootstrapActivationUnlocked(input)
+ ));
+}
+
+async function markNativeUltragoalBootstrapActiveUnlocked(
+ input: Parameters<typeof prepareNativeUltragoalBootstrapActivationUnlocked>[0],
+): Promise<{ ok: true; assignment: LocalNativeExecutorAssignment } | { ok: false }> {
+ const validated = await validateNativeUltragoalActivationReceipt(input, ['ready', 'activating', 'active']);
+ if (!validated.ok) return validated;
+ const { assignment, bootstrap } = validated;
+ if (bootstrap.status !== 'active') {
+ await writeJsonAtomic(bootstrapPath(input.stateDir, input.sessionId), {
+ ...bootstrap,
+ status: 'active',
+ updated_at: (input.now ?? new Date()).toISOString(),
+ });
+ }
+ return { ok: true, assignment };
+}
+
+export async function markNativeUltragoalBootstrapActive(
+ input: Parameters<typeof markNativeUltragoalBootstrapActiveUnlocked>[0],
+): Promise<{ ok: true; assignment: LocalNativeExecutorAssignment } | { ok: false }> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, () => (
+ markNativeUltragoalBootstrapActiveUnlocked(input)
+ ));
+}
+
+async function revokeLocalNativeExecutorAssignmentUnlocked(input: {
+ stateDir: string;
+ sessionId: string;
+ childAgentId?: string;
+ reason: string;
+ now?: Date;
+}): Promise<void> {
+ const now = input.now ?? new Date();
+ const bootstrap = await readNativeUltragoalBootstrap(input.stateDir, input.sessionId);
+ const childAgentId = input.childAgentId ?? bootstrap?.child_agent_id;
+ if (childAgentId) {
+ const path = nativeExecutorAssignmentPath(input.stateDir, input.sessionId, childAgentId);
+ const assignment = parseAssignment(await readJsonObject(path));
+ if (assignment?.lifecycle === 'active') {
+ await transitionAssignment(path, assignment, 'revoked', input.reason, now);
+ }
+ }
+ if (bootstrap) {
+ await writeJsonAtomic(bootstrapPath(input.stateDir, input.sessionId), {
+ ...bootstrap,
+ status: 'revoked',
+ updated_at: now.toISOString(),
+ reason: input.reason,
+ });
+ }
+}
+
+export async function revokeLocalNativeExecutorAssignment(
+ input: Parameters<typeof revokeLocalNativeExecutorAssignmentUnlocked>[0],
+): Promise<void> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, () => (
+ revokeLocalNativeExecutorAssignmentUnlocked(input)
+ ));
+}
+
+async function reconcileLocalNativeExecutorAssignmentsUnlocked(input: {
+ cwd: string;
+ stateDir: string;
+ sessionId: string;
+ rootThreadId: string;
+ now?: Date;
+}): Promise<{ ready: boolean; childAgentId?: string }> {
+ const bootstrap = await readNativeUltragoalBootstrap(input.stateDir, input.sessionId);
+ const directory = join(input.stateDir, 'sessions', input.sessionId, NATIVE_ASSIGNMENT_DIRECTORY);
+ const entries = await readdir(directory).catch(() => []);
+ for (const entry of entries) {
+ if (!entry.endsWith('.json')) continue;
+ const path = join(directory, entry);
+ const assignment = parseAssignment(await readJsonObject(path));
+ if (!assignment || assignment.lifecycle !== 'active') continue;
+ if (
+ !bootstrap
+ || assignment.bootstrap_generation !== bootstrap.generation
+ || assignment.child_agent_id !== bootstrap.child_agent_id
+ ) {
+ await transitionAssignment(path, assignment, 'revoked', 'bootstrap_replaced', input.now);
+ continue;
+ }
+ const tracked = await validateLocalNativeExecutorIdentity({
+ cwd: input.cwd,
+ sessionId: input.sessionId,
+ rootThreadId: input.rootThreadId,
+ childAgentId: assignment.child_agent_id,
+ receiptNotBefore: bootstrap.created_at,
+ receiptNotAfter: bootstrap.expires_at,
+ });
+ if (!tracked.ok) await transitionAssignment(path, assignment, 'revoked', tracked.reason, input.now);
+ }
+ const assignment = await findReadyLocalNativeExecutorAssignmentUnlocked(input);
+ return assignment
+ ? { ready: true, childAgentId: assignment.child_agent_id }
+ : { ready: false };
+}
+
+export async function reconcileLocalNativeExecutorAssignments(
+ input: Parameters<typeof reconcileLocalNativeExecutorAssignmentsUnlocked>[0],
+): Promise<{ ready: boolean; childAgentId?: string }> {
+ return withNativeUltragoalLifecycleLock(input.stateDir, input.sessionId, () => (
+ reconcileLocalNativeExecutorAssignmentsUnlocked(input)
+ ));
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment