Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ All notable changes to this project will be documented in this file.

## Unreleased

## 1.9.1 - 2026-07-18

- Added `runtime.ultraReasoningEffort` to override Ultra's default `max` inference effort with `low`, `medium`, `high`, or `xhigh`.
- Aligned Ultra's multi-agent mode prompt and inherited child policy with official Codex Multi-Agent V2 behavior.
- Added a pinned-source Codex-to-OpenCode prompt transformation, build-generated Ultra overlays, source/output drift checks, and compiled package delivery.
- Corrected catalog documentation for live-entry precedence, official GitHub missing-model supplementation, and Ultra eligibility provenance.

## 1.9.0 - 2026-07-10

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ This directory contains user and developer documentation for `opencode-codex-aut
- `development/TESTING.md`
- `development/UPSTREAM_SYNC.md`
- `development/ULTRA.md` (WIP, default-off)
- `development/PROMPT_COMPATIBILITY.md`

## Local planning and research

Expand Down
16 changes: 9 additions & 7 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,16 @@ Mode-derived runtime defaults when omitted:
- `runtime.ultraReasoningEffort: "low" | "medium" | "high" | "xhigh" | "max"`
- Selects the inference effort sent while logical Ultra mode is active.
- Defaults to `"max"`, matching official Codex. Lower values retain Ultra's proactive multi-agent policy while reducing inference reasoning effort.
- OpenCode may log the logical picker value `ultra` before the plugin's last-mile request transform; the backend receives this configured wire effort, not literal `ultra`.

### Model behavior

- Model availability comes from the selected catalog source for the current account.
- When a live account-scoped `/backend-api/codex/models` fetch succeeds, the plugin uses that source alone after normalizing, deduplicating, and sorting the catalog response for provider shaping.
- When live catalog data is unavailable, the plugin falls back to the shared GitHub `models.json` snapshot, normalized through the same catalog parser.
- The plugin does not field-merge live catalog entries with GitHub fallback entries.
- Do not rely on a static model list: GPT-5.6-era models and variants are sourced from the authenticated account's live catalog when that fetch succeeds, or from the shared GitHub snapshot when live catalog data is unavailable.
- Actual availability still depends on the authenticated account's live catalog and plan entitlements.
- Model availability is assembled from the current account's live catalog and the version-matched official GitHub `models.json` cache.
- A successful live `/backend-api/codex/models` response wins for every matching slug. Official GitHub entries supply only slugs missing from that response.
- The plugin does not combine fields across matching live and GitHub entries. GitHub-supplied models retain `catalog_source: "github_fallback"` so their provenance remains observable.
- When live catalog data is unavailable, the normalized GitHub snapshot supplies the fallback catalog.
- Do not rely on a static model list: GPT-5.6-era models and variants can arrive from either source under those precedence rules.
- Catalog visibility is not an entitlement guarantee. Actual backend access still depends on the authenticated account and may require re-authentication after an account or model rollout.

- `global.personality: string`
- Personality key applied to all models unless overridden.
Expand All @@ -160,9 +161,10 @@ Mode-derived runtime defaults when omitted:
- User config can still override reasoning effort globally, per model, or per variant.
- `ultra` reasoning variant
- Work in progress and available only when `runtime.ultra=true` and the active model advertises `ultra` with `multi_agent_version: "v2"`.
- `codex` mode adds the official Codex proactive multi-agent mode guidance to eligible root and inherited Ultra child turns; `native` mode preserves OpenCode-native prompt identity.
- `codex` mode adds the generated OpenCode-compatible form of Codex's proactive multi-agent mode guidance to eligible root and inherited Ultra child turns; `native` mode preserves OpenCode-native prompt identity.
- Correlated Ultra selections remain safe on unsupported or stale catalogs: the backend request sends the configured Ultra reasoning effort, defaulting to `max`, without proactive delegation. An uncorrelated literal `ultra` fails closed to wire `max`.
- There is no public concurrency setting; OpenCode remains responsible for agent execution and lifecycle.
- The overlay is generated from pinned Codex source with exact, count-checked substitutions backed by pinned OpenCode task-tool evidence. See `docs/development/PROMPT_COMPATIBILITY.md`.
- `global.reasoningMode: "standard" | "pro"` (optional)
- GPT-5.6 reasoning mode, emitted as `reasoning.mode` independently of `reasoning.effort`.
- An explicit request value is preserved. The same per-model and per-variant precedence applies.
Expand Down
8 changes: 4 additions & 4 deletions docs/development/OPENCODE_V1_17_18_SYNC.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ The full tagged comparison is [v1.3.0...v1.17.18](https://github.com/anomalyco/o
| Request identity | **Aligned:** final hooks emit `session-id`; legacy `session_id` remains an inbound/redaction compatibility alias. Originator and native UA remain aligned. |
| Endpoint routing | **Aligned for HTTP:** both Responses and Chat Completions are rewritten to the Codex Responses backend. |
| Model catalog | **Mostly aligned and intentionally richer:** local live account-scoped Codex metadata plus tagged GitHub fallback is stronger than upstream's models.dev-based hook. Confirm hidden/API-support filtering and never clone metadata across slugs. |
| Model visibility | **Aligned by stronger authority:** local behavior follows account-scoped live catalog visibility/support fields and refuses to grant Ultra eligibility from GitHub fallback metadata. It intentionally does not copy OpenCode's version heuristic. |
| Model visibility | **Aligned by stronger authority:** live entries win for matching slugs, while version-matched official GitHub entries supply missing slugs and retain their provenance. Ultra eligibility requires explicit capability fields from either source; the plugin does not copy OpenCode's version heuristic. |
| Refresh | **Aligned by stronger isolation:** catalog fetches are single-flight and account refresh/persistence remains lock-guarded by strict identity. Upstream's single-record global promise is not copied across rotating accounts. |
| Retry/error | **Layering gap, not necessarily code gap:** local bounded 429 rotation is intentional; verify host 5xx and OpenAI `server_error`/`server_is_overloaded` semantics survive unchanged. |
| GPT-5.6 Ultra | **No OpenCode parity gap:** upstream has no literal Ultra contract. Local logical Ultra normalization is an extension and should remain isolated from native request identity and authorized only by live catalog metadata. |
| GPT-5.6 Ultra | **Intentional extension:** upstream has no literal Ultra contract. Local logical Ultra normalization remains isolated from native request identity and is authorized only by explicit live or version-matched official GitHub catalog metadata. Codex delegation-policy wording is transformed through pinned OpenCode task-tool evidence. |
| WebSockets | **Optional gap:** v1.17.18 has experimental Responses WebSockets; local HTTP-only behavior remains valid unless feature parity is explicitly desired. |
| Plugin lifecycle | **Aligned:** `dispose` stops the instance's proactive-refresh scheduler and composes any Codex-layer cleanup. |
| Upstream watcher | **Aligned:** paths and hashes target v1.17.18, including the moved Codex plugin, models.dev core, and optional WebSocket transport files. Source-filtered checks allow OpenCode to advance independently of Codex path drift. |
Expand All @@ -68,14 +68,14 @@ The full tagged comparison is [v1.3.0...v1.17.18](https://github.com/anomalyco/o

1. Changed outbound identity from `session_id` to `session-id`; affinity, redirect stripping, snapshots/redaction, and tests accept legacy input where needed while generated hooks emit only the canonical header.
2. Updated the upstream watch and sync guide to v1.17.18 paths/hashes, including `plugin/openai/codex.ts`, `packages/core/src/models-dev.ts`, `ws.ts`, and `ws-pool.ts`.
3. Preserved the account-scoped live Codex catalog as the stronger authority for visibility, defaults, and Ultra eligibility; GitHub fallback metadata remains fail-closed for Ultra.
3. Preserved live Codex entries as the stronger authority for matching slugs while allowing the version-matched official GitHub catalog to supply missing models and explicit Ultra eligibility metadata without cross-slug or cross-source field synthesis.
4. Upgraded `@opencode-ai/plugin` and `@opencode-ai/sdk` to `^1.17.18`, adapted the narrow declaration shim and config type boundary, and passed full type/test/build verification.
5. Composed the new plugin `dispose` hook to stop proactive-refresh timers without allowing disposal of an older instance to clear a newer instance's scheduler.

### Optional follow-up

- Prototype experimental Responses WebSockets behind an explicit opt-in. Match upstream pooling/disposal, custom base URL, title HTTP fallback, internal-header stripping, stream retry, and idle handling before enabling it by default.
- Track upstream's models.dev/core catalog only for OpenCode host compatibility; keep the live account-scoped Codex catalog authoritative for Codex defaults and Ultra eligibility.
- Track upstream's models.dev/core catalog only for OpenCode host compatibility; keep live entries authoritative for matching Codex slugs and use only source-faithful, version-matched GitHub entries for missing slugs.
- Add a documented ownership matrix: host retries transport/5xx errors; this plugin rotates accounts only for bounded 429/auth cases; neither layer silently multiplies attempts.

### No action
Expand Down
88 changes: 88 additions & 0 deletions docs/development/PROMPT_COMPATIBILITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Codex-to-OpenCode Prompt Compatibility

Codex prompt behavior cannot be copied into OpenCode safely by changing tool names in prose. The two harnesses differ in tool schemas, agent lifecycle, concurrency, steering, cancellation, injected context, and instruction precedence. This document defines the maintainable workflow for adapting a pinned Codex prompt surface to OpenCode.

Ultra uses this workflow for its proactive and explicit-request-only mode overlays. The scope is deliberately narrow: it adapts the Codex delegation-policy wording to OpenCode's `task` tool without copying Codex-specific collaboration tools, limits, or lifecycle instructions.

## Design goals

- Preserve portable upstream wording exactly where the harnesses agree.
- Make every harness-specific difference explicit and reviewable.
- Fail closed when the pinned source or an expected replacement changes.
- Separate verified harness facts from policy choices made by this plugin.
- Generate runtime prompt artifacts deterministically instead of editing them by hand.
- Test the final composed OpenCode instructions, not only individual replacement rules.

## Artifact model

The implementation follows the same source-to-generated pattern used by Claudex:

| Artifact | Responsibility |
| --- | --- |
| Pinned Codex source | Verbatim upstream prompt fragment plus source repository, tag or commit, path, and SHA-256. |
| Harness evidence manifest | Pinned Codex and OpenCode source files and the exact symbols that prove each mapped capability. |
| Transformation rules | Ordered declarative operations with exact expected match counts. |
| Generator | Validates the source hash, applies only supported operations, and writes atomically. |
| Generated OpenCode overlay | Runtime artifact; never edited directly. |
| Drift checker | Regenerates in memory, compares output byte-for-byte, and audits pinned source evidence. |

The current scope is the Ultra multi-agent overlay only. It does not replace OpenCode's full base prompt or create a second general-purpose orchestrator.

## Difference inventory

Before adding a transformation, record the contract on both sides. The checked-in evidence and rules live under `prompts/`, the generator is `scripts/generate-prompt-compatibility.mjs`, and the runtime artifact is `lib/codex-native/generated/ultra-instructions.ts`.

| Surface | Codex evidence | OpenCode evidence | Adaptation decision |
| --- | --- | --- | --- |
| Delegation tools | `spawn_agent`-based collaboration family | `task` with `description`, `prompt`, `subagent_type`, and optional `task_id` | Replace Codex's generic spawn/use wording with OpenCode's `task` tool; leave parameters to the host tool schema. |
| Child identity | Root/child role and inheritance rules | Session parentage, agent mode, and child model inheritance | Translate only states represented by OpenCode hooks. |
| Concurrency | Limit and scheduling semantics | Host task scheduling semantics | Do not copy Codex limits unless OpenCode enforces the same contract. |
| Steering and follow-up | Codex agent messaging lifecycle | OpenCode task/session lifecycle | Remove or replace unsupported actions explicitly. |
| Cancellation and failure | Codex failure propagation | OpenCode tool and session errors | Keep the root turn recoverable when the host contract allows it. |
| Instruction precedence | Codex developer-overlay ordering | OpenCode hook composition ordering | Verify the final composed prompt and idempotent replacement behavior. |
| Auxiliary turns | Codex title, summary, and compaction policy | OpenCode auxiliary request detection | Keep delegation overlays off auxiliary turns. |

Each row must cite a pinned file and symbol in the evidence manifest. A statement observed only in a session log is a hypothesis until matched to source or a stable public contract.

## Allowed transformations

Keep the rule language intentionally small:

- `replace_literal` with `expectedCount`.

The generator rejects unknown operations, hash mismatches, missing constants, unexpected match counts, missing evidence symbols, and output drift. It does not use regular-expression substitutions for semantic rewrites or silently accept upstream changes.

## Verification contract

A prompt-compatibility change is complete only when all of these pass:

1. The pinned Codex prompt hash matches.
2. Every Codex and OpenCode evidence file exists at its pinned revision and contains the declared symbols.
3. Generation is deterministic and `--check` reports a byte-for-byte match.
4. Tests cover root, child, auxiliary, native-mode, disabled, degraded, retry, and idempotent composition paths.
5. A captured final OpenCode request contains the generated overlay exactly once and retains unrelated host instructions.
6. A manual Ultra smoke records the selected logical effort, final wire effort, available host tools, actual delegation calls, and child-session lineage separately.
7. `npm run verify` passes.

The smoke must not treat selecting `ultra` as proof that delegation occurred. OpenCode can log the logical `ultra` selection before the plugin's last-mile transform; the backend receives `runtime.ultraReasoningEffort`, which defaults to `max`.

## Update workflow

1. Pin the new Codex and OpenCode revisions.
2. Run the evidence audit before changing rules.
3. Review upstream prompt differences independently from harness API differences.
4. Update the difference inventory and transformation rules together.
5. Regenerate the runtime artifact.
6. Inspect the source-to-generated diff and final composed-prompt fixtures.
7. Run the verification contract and record any intentional compatibility gaps in `docs/development/ULTRA.md`.

Do not update a source hash merely to make the checker pass. A changed hash is a review trigger: either the existing mapping is still valid and can be repinned with evidence, or the transformation and its tests must change.

## Commands

```bash
npm run generate:prompts
npm run check:prompts
```

`generate:prompts` validates every pinned source before atomically replacing the generated runtime module. `npm run build` runs generation before TypeScript compilation, producing `dist/lib/codex-native/generated/ultra-instructions.js`; `prepack` runs that build, so the completed overlay and the applicable upstream license and notice files are included in the published package. `check:prompts` performs the same validation in memory and fails if the checked-in module differs. The full `npm run verify` gate checks drift and then exercises the build and distribution smoke path.
1 change: 1 addition & 0 deletions docs/development/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ Use this section for implementation internals and maintenance workflows.
- `docs/development/TESTING.md` - test strategy and verification commands.
- `docs/development/UPSTREAM_SYNC.md` - how we track/sync upstream behavior.
- `docs/development/ULTRA.md` - default-off GPT-5.6 Ultra WIP contract and rollout guidance.
- `docs/development/PROMPT_COMPATIBILITY.md` - pinned-source build workflow for adapting Codex prompt overlays to the OpenCode harness.
- `docs/development/OPENCODE_V1_17_18_SYNC.md` - detailed v1.3.0 to v1.17.18 parity audit and disposition.
- `docs/development/upstream-watch.json` - upstream watch state artifact.
2 changes: 2 additions & 0 deletions docs/development/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ npm run check:docs
npm run verify
```

`npm run build` first runs `npm run generate:prompts`, then compiles the generated Ultra instruction module into `dist`. Full verification also runs `npm run check:prompts` before tests and `npm run check:prompt-artifact` after the build to prove the checked-in source and compiled exports match the pinned transformation.

`npm run verify` is the required local gate before commits, pushes, and PR updates. `npm run verify:local` runs that gate with caching, and the installed git hooks enforce it automatically before `git commit` and `git push`. The commit hook accepts staged-only commit-ready changes; the push hook requires a clean tree and derives the touched-file set from the outgoing commits so the local regression-only ratchet matches the actual push surface instead of only `HEAD^`. GitHub Actions still adds extra platform and security jobs beyond the repo-local verify run.

PR GitHub CI is intentionally slimmer than local `verify`: it keeps the clean-room Ubuntu verify job, Linux tarball smoke, Windows smoke, and secret scanning. The separate `npm audit` dependency audit remains GitHub-hosted, but it now runs on default-branch pushes instead of every PR.
Expand Down
Loading
Loading