Codex's native subagent status is a fixed two-value enum
(CollabAgentToolCallStatus::{InProgress, Completed}) with no custom status
field, so the proposal's executing/verifying/completed triad cannot be
rendered in that view by anyone. Records the decision, and preserves the
reachable path -- codex exec --json ThreadEvents persisted by #4624, then
read at execute:wave:pre/post by an EoS capability.
Co-authored-by: sim <sim@local>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
106
.out-of-scope/codex-native-supervisor-adapter.md
Normal file
106
.out-of-scope/codex-native-supervisor-adapter.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Codex native supervisor adapter for orchestrator-worktree executors
|
||||
|
||||
**Source:** [#4625](https://github.com/open-gsd/gsd-core/issues/4625)
|
||||
**Decision:** wontfix — No-go as filed; the observability goal is redirected to EoS, behind [#4624](https://github.com/open-gsd/gsd-core/issues/4624)
|
||||
**Date:** 2026-09-11
|
||||
|
||||
## Proposal summary
|
||||
|
||||
Reporter proposed an opt-in, Codex-only supervision adapter layered on the existing negotiated
|
||||
`orchestrator-worktree` dispatch backend. For each selected executor the root would create the
|
||||
existing GSD-managed worktree and launch one **native Codex supervisor subagent**, which owns
|
||||
exactly one external `codex exec --cd <worktree>` worker and surfaces evidence-backed progress in
|
||||
Codex's native subagent UI as three strict states:
|
||||
|
||||
- `executing` — the persisted worker process is alive after successful launch
|
||||
- `verifying` — that process reached a terminal state and the supervisor is reconciling its
|
||||
result, SUMMARY, plan-scoped commits, branch and manifest
|
||||
- `completed` — reconciliation succeeded and the manifest-only merge/cleanup gauntlet finished
|
||||
|
||||
The supervisor would run the worker in the foreground (explicitly not backgrounded with `&`
|
||||
behind a cosmetic status), consume the persisted lifecycle protocol proposed in #4624, and be
|
||||
disabled by default with no behavior change for other runtimes or the default direct adapter.
|
||||
|
||||
## Why GSD does not own this
|
||||
|
||||
- **The target surface cannot carry the states the proposal is built on.** Codex's native
|
||||
subagent status is a fixed two-value enum — `CollabAgentToolCallStatus::{InProgress,
|
||||
Completed}`, emitted by `wait_agent`. There is no free-text or custom status field. The
|
||||
proposal's `executing` / `verifying` / `completed` triad cannot be rendered in that view **by
|
||||
anyone, gsd-core included.** This is not a question of where the adapter lives, and it is the
|
||||
decisive ground: the feature's central promise is not deliverable as specified.
|
||||
|
||||
- **The native subagent list is populated only by Codex's own `spawn_agent` / `wait_agent`
|
||||
machinery.** `notify` (a fire-and-forget subprocess spawn on `agent-turn-complete`) and the
|
||||
`hooks.toml` command hooks observe Codex's *own* turn and tool events; neither is documented as
|
||||
rendering into that list. A framework that did not itself drive `spawn_agent` could not reach it.
|
||||
|
||||
- **That machinery is unreleased.** `multi_agents_v2` was found at source level on the `openai/codex`
|
||||
`main` branch and could not be verified as shipped or GA; the `--experimental-json` alias beside it
|
||||
points the same way. Committing a core-resident adapter to an unstable, unreleased third-party
|
||||
interface would be building ahead of the vendor.
|
||||
|
||||
- **A second core dispatch adapter is a permanent tax.** Every future change to the executor
|
||||
lifecycle would have to be made twice, or proven to apply to both paths. The graph rates the
|
||||
isolation resolver's blast radius MEDIUM, and `dispatch.isolation` is declared across multiple
|
||||
runtime capability descriptors, so an adapter is a multi-descriptor change rather than a local one.
|
||||
|
||||
Note what the proposal got **right**, none of which is a ground for rejection: the observability
|
||||
gap it describes is real and was confirmed; its containment shape (opt-in, default-off, no change
|
||||
to other runtimes or the default path) is the correct one for this class of change; its
|
||||
self-imposed rule that a worker must never show `completed` merely because a process exited is
|
||||
exactly the right invariant; and it correctly identified and filed its own correctness
|
||||
prerequisite separately as #4624, which is now `confirmed-bug`. The filing was specific enough to
|
||||
be checked against the runtime, which is why the mechanism problem surfaced at all.
|
||||
|
||||
## What this does NOT cover
|
||||
|
||||
This entry denies **gsd-core building a second, core-resident dispatch adapter around Codex's
|
||||
native subagent UI.** Its keyword surface — supervisor, observability, worker state, lifecycle,
|
||||
subagent, Codex, orchestrator-worktree — overlaps requests this decision deliberately does not
|
||||
deny. Do not apply this entry to:
|
||||
|
||||
- **Worker-state visibility for Codex executors as a goal.** It is legitimate and it is reachable.
|
||||
`codex exec --json` emits structured JSONL `ThreadEvent`s — `thread.started` (carrying
|
||||
`thread_id`), `turn.started` / `turn.completed` / `turn.failed`, `item.*`, `thread.error` — and a
|
||||
session resumes via `codex exec --json resume <thread_id>`. That is a genuine terminal-state
|
||||
signal for an external worker, and nothing here denies using it.
|
||||
- **#4624, the persisted lifecycle record.** That is a confirmed defect fix and core work
|
||||
regardless of this decision. Its diagnosis found the current `orchestrator-worktree` wait path is
|
||||
a single prose sentence with no captured PID and no durable per-worker record.
|
||||
- **An EoS capability that reads that record and reports state.** Once a durable per-worker record
|
||||
exists on disk, a capability can register a `step` hook at `execute:wave:pre` /
|
||||
`execute:wave:post` (ADR-857's loop extension points) and display each worker's state with no
|
||||
core change of its own. **This is the sanctioned path for this request**, and it is open now.
|
||||
- **Fixing the existing `orchestrator-worktree` adapter.** Defects in the shipped path are bug
|
||||
reports, not this proposal.
|
||||
- **Codex runtime support generally** (`capabilities/codex/capability.json`), which is unaffected.
|
||||
|
||||
## Re-open criteria
|
||||
|
||||
- **Codex ships a documented, non-experimental surface that accepts a custom status string from a
|
||||
third party into its native subagent view.** This is the ground the decision actually rests on;
|
||||
if it changes, the decision should be revisited rather than cited. A resubmission should name
|
||||
the specific released Codex version and the surface.
|
||||
- Separately, and only then: #4624 has shipped, and a resubmission **names a specific residual
|
||||
visibility failure observed after the EoS read-and-report path was tried** — rather than arguing
|
||||
for the native-UI adapter in the abstract.
|
||||
|
||||
A core-resident adapter is accepted here only once the surface it targets can carry the states it
|
||||
was specified to show. Until then, the wave-boundary read of a persisted record is strictly more
|
||||
capable than the thing this entry declines, because it can express states the native enum cannot.
|
||||
|
||||
## Related
|
||||
|
||||
- [#4624](https://github.com/open-gsd/gsd-core/issues/4624) — the persisted-lifecycle defect this
|
||||
was sequenced behind; `confirmed-bug`
|
||||
- [`subagent-activity-watchdog.md`](./subagent-activity-watchdog.md) — denies a *generalized*
|
||||
event-driven watchdog; explicitly preserves narrow per-spawn-site work, and so does **not** deny
|
||||
the EoS path above
|
||||
- [`codex-native-plugin-skips-preproposal.md`](./codex-native-plugin-skips-preproposal.md) — the
|
||||
standing no-new-first-party-add-ons policy; targets distribution surfaces, and so was **not** the
|
||||
ground for this decision
|
||||
- [ADR-857](../docs/adr/857-capability-system.md) — the capability system and its 12 loop extension
|
||||
points
|
||||
- `gsd-core/references/loop-hook-dispatch.md` — the `contribution` / `step` / `gate` hook contract
|
||||
- `capabilities/codex/capability.json` — existing Codex runtime support, unaffected
|
||||
Reference in New Issue
Block a user