Add omp as a fifth native driver - #346
Conversation
omp is pi-family (loads pi-style extensions, reads PI_* env fallbacks), so
this follows the pi driver's shape: a typed `omp {}` block, an `omp-session`
wrapper owning the presence lease and the terminal observed-state record, and
an injected `omp-channel.ts` extension delivering inbox messages natively over
the shared newline-JSON frame protocol.
Where omp measurably diverges from pi (v18.0.3, 2026-08-25 captures in
docs/vrs/06-omp-driver/.experiments/), the code diverges deliberately:
- No `agent_settled` event exists, so the idle edge is `agent_end` followed by
bounded `ctx.isIdle()` polling instead of pi's settled event.
- omp exposes `tool_approval_requested`/`tool_approval_resolved`, which the
channel projects onto the blocked-on-human axis pi cannot express; the Rust
channel loop parses the optional blockedOn/ask/reason frame fields for both
harnesses.
- The delivery-critical surface is versioned behavior rather than API
contract, so the wrapper hard-gates the provider major (18.x) under the
codex/opencode admission convention instead of degrading silently.
- The channel asset is forked, not shared: each harness's correctness must not
depend on the other's branch. Fresh ST2_OMP_CHANNEL_* env names keep a seat
from adopting stray pi channel configuration.
Verified live on dev3: presence lease, seeded and transitioning observed
state, restored-context seeding, and native message delivery into the running
TUI. VRS for the subsystem lives in docs/vrs/06-omp-driver/ with decision
0007; DQ-OMP-1..5 record the unmeasured residuals (deny path, ask-axis
discrimination, steer/modal visuals, update-banner suppression).
agent-identity: unknown
agent-persona: generalist
agent-supervisor: unavailable
agent-tool: OMP
agent-tool-version: 18.0.3
agent-runtime: OMP 18.0.3
tooling-profile: dotfiles@929dc21
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 776797b4c1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex please review — omp as a fifth native st2 driver: typed Posted on behalf of @schickling
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 776797b4c1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… block as a spec candidate Review findings: the major-only comparison admitted unverified 18.x minors against OMP-R05's per-minor admission contract, so admission is now an exact verified-version list like the opencode gate; and looks_like_spec now counts an omp driver block as an agent-shaped signal, matching every other provider. agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.3 agent-runtime: OMP 18.0.3 tooling-profile: dotfiles@929dc21
8aff691 to
cfc511d
Compare
Codex review: a session replacement during the post-agent_end polling window could let the retired context publish idle into the successor's channel; the poll now drops its result when state.child has moved on.
Problem
omp — an earendil-works/pi-family coding harness in daily use on this fleet — has no st2 support: seats are hand-authored tasks with no presence lease, no observed harness state, and no native message delivery. Every other maintained harness (claude, codex, pi, opencode) has a typed driver.
Goal
driver omp { model, effort, prompt }declared seats get the same first-class treatment as the pi driver: pure KDL expansion, a session wrapper owning presence and the terminal observed-state record, live active/idle/blocked observations, and native inbox delivery through an injected extension channel — never screen scraping.Decisions
docs/vrs/06-omp-driver/.experiments/):agent_settleddoes not exist (absent from the binary), so the idle edge isagent_endfollowed by boundedctx.isIdle()polling; atagent_enditself the proof measured still-false.tool_approval_requested/tool_approval_resolvedwith a correlatingtoolCallId, giving the blocked-on-human axis pi cannot express. Both events verified firing under forced approval mode.hooks/omp-channel.ts), not a shared parameterized file: each harness's correctness must not depend on the other's branch. FreshST2_OMP_CHANNEL_*env names prevent adopting stray pi channel config.effort(carrying omp's thinking level verbatim via--thinking) for consistency with the existingPiDriverconvention.st2 driver omp-channelreusespi_channel.rsparameterized by harness); only the TS asset forks.Verification
cargo test --workspace: 470 lib tests plus integration suites). One pre-existing failure (incomplete_apply_marker_blocks_declarations_but_not_the_state_plane) reproduces on clean HEAD of this branch and is unrelated to this change.checks.pi-extension-typesextended: both extensions type-check against the pinned pi typings and are driven through their open path by runtime smokes.tests/fixtures/driver/omp.*.kdl), launch classification exactness, blocked-frame parsing, version-gate admission/refusal/garble paths, extension splice position, offline defaults.driver ompseat; verified presenceavailable; harness-state seededidleunderharness: "omp"fenced by the wrapper's session token; ast2 message sendlanded in the live TUI together with the restored-context block; observed state cycled active then idle around the delivery. The model's reply hit a provider-side 429 weekly quota — outside st2's surface.Complexity
One new wrapper module mirroring the four existing per-harness shapes; the shared channel loop gains one parameterized harness kind plus optional frame fields. The fork-vs-share choice for the TS asset is the one deliberate duplication, argued above and in decision 0007.
Concerns
tool_approval_resolved { approved: false }is unmeasured (Claude ends its turn eventlessly there); v1 accepts a possibly brief misprojection (OMP-T01).permissionfor every approval) until a question-form capture lands (OMP-T02).PI_OFFLINEsuppresses omp's update banner could not be established in print mode (DQ-OMP-5).Follow-ups
docs/vrs/06-omp-driver/open-questions.md.References
docs/vrs/06-omp-driver/, decision 0007Posted on behalf of @schickling
agent_identityagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile