Skip to content

feat(omp): integrate Oh My Pi provider on current main - #11973

Draft
nullStack65 wants to merge 25 commits into
pingdotgg:mainfrom
nullStack65:feat/omp-main-integration-20260915
Draft

nullStack65 wants to merge 25 commits into
pingdotgg:mainfrom
nullStack65:feat/omp-main-integration-20260915

Conversation

@nullStack65

@nullStack65 nullStack65 commented Sep 15, 2026

Copy link
Copy Markdown

What this is

A draft, source-only integration of the Oh My Pi (omp) provider from #11791
(head 14ed34f4e21946819109d2cdf17186d89b4b6d1b, unchanged) onto current main.

Refresh history: the first integration head 2d713044d was built on
3efdcc5296f1754e0f3bf7fee5fc2ada510e0438 (dispatch main). Main then moved to
f4600d77dd7c2fa9f10e8f4500882e427fcc7e26, producing refreshed head ad9837ed5
(a merge that preserves 2d713044d as an ancestor). Main moved once more to
87a12b53fdff7e2e0318af3edea54005557cea56 (#11928), and the branch was synced to
it, yielding the current head d8707173644cfc49c62b1ad2f840a0ffc41a4b5c. It
exists to answer whether the OMP feature set can ride today's main cleanly.
It does not install, sign in to, or run OMP, and it is not a merge request.

Integration shape

  • Branch: feat/omp-main-integration-20260915 (fork nullStack65/t3code).
  • Head d8707173644cfc49c62b1ad2f840a0ffc41a4b5c: merge of
    ad9837ed5e6ec8ce249b8264c3f0da174c87ff90 (refreshed integration) with
    87a12b53fdff7e2e0318af3edea54005557cea56 (current main). ad9837ed5 merged
    f4600d77dd7c2fa9f10e8f4500882e427fcc7e26 with 2d713044d609d82b8eda3802659ce2da5c09605e,
    which itself merged feat(omp): Oh My Pi provider with full terminal parity #11791 head 14ed34f4e21946819109d2cdf17186d89b4b6d1b
    into 3efdcc52... plus two conformance commits. All 18 PR commits and
    authorship survive; nothing is squashed or rewritten.
  • Net diff vs 87a12b53: 71 files, +13,397 / −186.
  • No textual conflicts were hit on either refresh; overlaps were hand-audited:
    • packages/contracts/src/settings.ts / .test.ts: main's followUpBehavior
      and the OMP provider settings coexist.
    • AddProviderInstanceDialog.tsx: main's simplified Dialog import kept;
      feat(omp): Oh My Pi provider with full terminal parity #11791's removal of the Pi Agent coming-soon row kept.
    • pnpm-lock.yaml: main's version kept (the PR's alchemy peer-hash churn has
      no accompanying package.json change).
    • #11928 (usage refresh): lands only in apps/web, apps/mobile,
      packages/client-runtime, and docs; no OMP file overlap.
  • ProviderRuntimeIngestion.ts keeps main's thread.title.generate.complete
    dispatch and combines main's manual-title guard with the PR's explicit-agent
    rename override: an OMP /rename (nameIsExplicit) replaces a generated
    title, while a manual T3 rename still wins.
  • Every other PR-touched file is byte-for-byte feat(omp): Oh My Pi provider with full terminal parity #11791 content; the only deltas
    from the PR head are that title-policy merge, lint/typecheck conformance, and
    files main itself changed since the PR's branch point.

Feature parity

All #11791 capabilities are present: omp driver registration, ACP runtime,
OMP model catalog with upstream grouping and thinking ladders, skills/command
discovery, slash-command argument suggestions, usage_update context meter,
/compact, usage/auth projection, self-update advisory, transcript/project
discovery and import/resume, /rename, /fresh session replacement,
approvals, subagent progress, image input, interrupt, web/mobile metadata,
text generation, and docs.

Validation (source-only, on the refreshed heads)

  • Server / web / contracts / mobile / client-runtime typecheck: 0 errors,
    0 warnings.
  • OMP server suites (13 files): 189 pass, 4 skipped.
  • Provider registry + runtime ingestion + session importer + server settings:
    pass; AgentSessionScanner passes standalone (85 pass / 5 skipped).
  • Web: 176 + 6 pass across the composer/provider and usage suites; contracts:
    129 pass; client-runtime usage: 7 pass; mobile usage section: 2 pass; root
    script suite: 17 pass.
  • vp fmt --check clean on all changed files; vp lint exit 0 (ChatComposer
    warning count identical to main, 43); git diff --check clean.
  • One scanner case-variant test fails intermittently under multi-file load on
    this Windows host; clean main fails the same family (3-4 tests per run,
    including standalone), so it is environmental, not introduced here.

Work done by opencode (deepseek-v4.1-flash) in the OpenCode harness; refresh
passes by opencode (deepseek-v4.1-flash), OpenCode harness.

omnificate and others added 21 commits September 14, 2026 09:37
Adds omp (https://github.com/can1357/oh-my-pi) as a seventh built-in
provider by driving its native stdio ACP server (`omp acp`) through the
existing generic ACP client stack (effect-acp), mirroring the
Cursor/Grok driver layout:

- OmpDriver: provider bundle; manual-only maintenance (T3 never guesses
  an omp update command); model catalog sourced exclusively from the
  probe ACP session's configOptions during status checks.
- OmpAdapter: session lifecycle on the shared ACP runtime: permission
  bridging via session/request_permission echoing advertised snake_case
  option ids, dual elicitation bridging (typed session/elicitation plus
  the official-SDK ext method elicitation/create with its flat
  response), task-tool subagent projection into the Agents panel,
  steering merge, pre-prompt and in-permit cancel checkpoints, and a
  per-session dispatch lock that serializes the configuration write,
  the turn.started stamp, and the session/prompt dispatch registration
  (omp applies model writes to the shared session). The permit is
  released on dispatch registration or prompt fiber exit (raced), never
  held across the prompt, so steers stay concurrent; the join carries
  onInterrupt interruption so post-dispatch cancels cannot orphan a
  prompt. Rollback is advertised unsupported: the ACP session cannot
  rewind its native conversation history.
- OmpProvider: `omp --version` probe plus ACP model discovery;
  capabilities attach only to the model the probe session currently
  runs (trimmed currentValue), other catalog entries report null. Owns
  both model-option selectors (select-guarded and unguarded existence
  probe) so their category/id normalization cannot drift.
- OmpAcpSupport: spawn args per RuntimeMode (Supervised
  --approval-mode=always-ask, Auto-accept edits --approval-mode=write,
  Auto --auto-approve, Full access --approval-mode=yolo); model writes
  only when the session advertises no model option at all (write
  through) or advertises the requested slug in its select model option;
  unadvertised slugs and non-select model options preserve the session's
  configured model, and the effective model is returned so callers stamp
  truthful turn/session state.
- OmpTextGeneration: unattended commit/PR/branch/title generation with
  --auto-approve and elicitation disabled.
- Contracts: OmpSettings/OmpSettingsPatch, off by default like
  cursor/grok/opencode; display name "Oh My Pi".
- Web/mobile: provider icon, settings metadata, add-provider entry;
  model rows render the provider and upstream label per model.

Tests: adapter/provider/support/text-generation suites on the shared
mock ACP agent covering the four model-write cases (no model option,
advertised slug, unadvertised slug, non-select model option), flat
elicitation responses, prepare-cancel permit release, dispatch
serialization order, thread-filtered event consumers, plus picker row
label coverage. Validated end to end against a real omp 18.1.15
install (11.9k-model catalog, streamed turn in the built desktop UI).

Discussion: pingdotgg#10883.
Merges the OMP provider work from pingdotgg#11791 (head
14ed34f) onto main
3efdcc5.

Conflict resolution in ProviderRuntimeIngestion.ts keeps both sides:
main's manual-title guard from pingdotgg#10720 (`titleState.source !== "manual"`)
and the PR's explicit agent rename override (`nameIsExplicit`), so an
OMP `/rename` replaces a generated title while a manual T3 rename still
wins. Main's `thread.title.generate.complete` dispatch with optimistic
title/version expectations is preserved over the PR's older
`thread.meta.update` call.

pnpm-lock.yaml takes main's version: the PR changed only a peer-suffix
hash for alchemy with no package.json change, which is lockfile drift.

OMP feature work is otherwise carried unmodified per file; see the
integration report for the per-file audit.
`vp lint` on the integrated files surfaced one error and dead imports
carried from the PR:

- AgentSessionScanner.test.ts read `NodeOS.platform()`, which current
  main's `t3code/no-global-process-runtime` rule rejects. Use
  `HostProcessPlatform.defaultValue()`, the pattern main's own tests use
  for module-scope platform checks.
- Drop unused `Dialog*`/`PiAgentIcon` imports in
  AddProviderInstanceDialog after the PR removed the Pi Agent coming-soon
  option, plus unused `EffectAcpSchema` and `acpPermissionOutcome`
  imports in OMP files.

No behavior change.
Current `@effect/tsgo` reports `@effect-diagnostics-next-line
preferSchemaOverJson:off` as TS377000 ("directive has no effect") on
11 OMP lines. effect-tsgo promotes those warnings to a non-zero
`tsc --noEmit` exit, so the server typecheck failed on warnings alone.
The directives suppress nothing on this toolchain; remove exactly the
11 flagged lines and let fmt reflow one JSON.stringify block.

Server typecheck now has 0 errors and 0 warnings (suggestions only).
No behavior change.
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 15, 2026
@nullStack65

Copy link
Copy Markdown
Author

Independent exact-head source review — Oh My Pi (omp) integration

Verdict: CLEAN_FOR_LIVE_ACCEPTANCE (source-only). No blockers found. Non-blocking observations are listed separately below and are explicitly not part of the verdict.

Reviewed state (re-fetched immediately before posting):

Ref SHA
Candidate #11973 head d8707173644cfc49c62b1ad2f840a0ffc41a4b5c (draft; mergeable=true, mergeable_state=blocked)
Candidate #11973 base at creation 87a12b53fdff7e2e0318af3edea54005557cea56
Upstream main during review b12c92f695a6b12116fb2cda40d610bdbe2a9566 (moved from 37a8ab2b2… while this review ran)
Source feature #11791 head 14ed34f4e21946819109d2cdf17186d89b4b6d1b (base 549d182aaadbf0e1e195d1a8cdc1805200e6751e; still open, not merged)
Older provenance #10893 b80bfd70c1b02c720787ac3e66822bfc5db1073f (open, not merged; not used by this candidate)

Constraints honored: read-only. No source changes, no commits, no merge, no OMP install, no sign-in, no provider credentials, no inference. Tests were executed in an isolated WSL Ubuntu 24.04 clone (~/review-t3) with Node 24.21.0 + pnpm 11.10.0 and no omp on PATH.


1. Provenance / commit graph

The candidate is a genuine descendant of the #11791 implementation, not a re-implementation:

  • git merge-base --is-ancestor 14ed34f4e2 d870717364true. 14ed34f4e2 is the tip of a linear 18-commit chain, so all 18 feat(omp): Oh My Pi provider with full terminal parity #11791 commits are ancestors of the candidate head (oldest 5766179db → newest 14ed34f4e2). Authorship preserved (17 authored by pedro, the base commit 5766179db authored by omni; OMP titles intact).
  • Integration chain on top:
    • 1434242917 = merge of 3efdcc529 (main) + 14ed34f4e2 (OMP tip) — "integrate on current main"
    • 959429b717 (lint), 2d713044d6 (drop no-op effect-diagnostics directives)
    • ad9837ed5e = merge of f4600d77dd (main) + 2d713044d6 — "refresh onto current main"
    • d870717364 = merge of ad9837ed5e (first parent, feature) + 87a12b53fd (second parent, main) — correct direction, no reverse merge
  • Range 87a12b53f..d87071736 contains exactly 23 commits: the 18 OMP commits + 3 integration commits + 2 refresh merges. Every non-OMP commit in that range is an upstream main commit reachable from current main; no unrelated branch content entered.
  • File-level: candidate net diff 87a12b53f...d87071736 = 71 files; 0 files outside the feat(omp): Oh My Pi provider with full terminal parity #11791 file set, and the source set is fully covered (72 = 71 + retained pnpm-lock.yaml). The net diff is genuinely "current main + OMP integration/conformance only".
  • Drift: current main (b12c92f) advanced 3 commits past the candidate base (GitVcsDriver fix, Hermes lint list, contracts Intl.Segmenter monogram fix). Zero file overlap with the 71 PR files. Harmless new drift, not a review blocker; the branch still reports mergeable=true.

2. Per-file parity audit (independently reproduced)

I recomputed blob-level parity between 549d182...14ed34f (#11791 net) and 87a12b53...d870717 (candidate net):

72 source files = 54 byte-identical + 17 content deltas + 1 source-only (pnpm-lock.yaml). No candidate-only files, no status mismatches. The owner's "54 identical / 18 deltas" is confirmed (the 18th being the retained lockfile).

All 17 deltas classified (A = current-main reconciliation, B = lint/typecheck conformance, C = main already implements differently, D = behavior-changing integration delta, E = suspicious):

Lint/typecheck-only (B) — 6 OMP files, all removals of stale/no-op @effect-diagnostics directives or now-unused imports:
OmpCommands.ts (-1), OmpCommands.test.ts (-11/+6), OmpModelCatalog.ts (-1), OmpModelCatalog.test.ts (-4), OmpAdapter.ts (unused acpPermissionOutcome import), OmpAcpSupport.ts (unused EffectAcpSchema type import), OmpProvider.test.ts (-1). No feature code touched.

Current-main reconciliation (A/C) — shared files keep main's newer code and re-apply only the OMP hunks:

  • AgentSessionScanner.test.ts (+3/-2): adopts main's HostProcessPlatform + listActivitiesByKind mock; OMP tests added on top.
  • ProviderRegistry.test.ts: main's newer Codex-message tests retained; candidate adds "omp" to the registered-driver expectation.
  • ProviderRuntimeIngestion.test.ts: main's list-boundary tests retained; candidate adds the explicit-rename test.
  • CommandPalette.tsx / Sidebar.tsx: main's clone-tracking and custom-snooze features retained; OMP's resolveThreadProviderDisplayName display-name hunks re-applied (region byte-identical to source).
  • ChatComposer.tsx: main's openControl/data-composer-shortcut retained; OMP slash-argument autocomplete re-applied.
  • AddProviderInstanceDialog.tsx: retains main's dialog refactor; removes the piAgent "Pi Agent" coming-soon placeholder and the imports the source PR left unused. The placeholder removal is source intent (it is already absent in 14ed34f); the legacy piAgent slug still maps to "Oh My Pi" (providerModels.ts:20-28), so no functional provider is lost.
  • settings.ts / settings.test.ts: main's followUpBehavior additions retained; OmpSettings (enabled default false), OmpSettingsPatch, provider registration, and exported defaultEnabledForDriver added.
  • ProviderRuntimeIngestion.ts (+8/-1 vs base): see §3.
  • Main's splitBufferedAssistantText list-item splitting (C): candidate keeps main's newer implementation + tests; the older source variant is correctly not restored.

No feature hunk was dropped. Every OMP-specific production file from #11791 exists in the candidate, and the only deltas in OMP-named files are lint removals.

3. Title / session authority

The candidate re-implements #11791's explicit-rename behavior on main's newer title machinery instead of the source's old thread.meta.update dispatch:

  • ProviderRuntimeIngestion.ts:2067-2085 — dispatch now thread.title.generate.complete guarded by thread.titleState?.source !== "manual" && (nameIsExplicit === true || canReplaceThreadTitle(thread.title)), with expectedTitle/expectedVersion optimistic checks.
  • decider.ts:1215-1246 — the command itself re-checks source !== "manual", title === expectedTitle, version === expectedVersion, so concurrency is enforced twice.
  • OmpAdapter.ts:1493-1507 — omp session_info_updatethread.metadata.updated with nameIsExplicit: true.

Walkthrough of the required cases:

  1. generated → OMP explicit rename: applies (explicit bypasses canReplaceThreadTitle; generated is not manual; version matches captured value). Covered by the new test at ProviderRuntimeIngestion.test.ts:3959-3978 (passes).
  2. manual T3 title → OMP rename: blocked at ingestion by source !== "manual" and again at the decider; the manual title is never silently overwritten. Decider-level guard covered by decider.titleRegeneration.test.ts:74-101 ("rejects an initial result after a manual rename to the same text"); manual ownership recording at :103-119.
  3. generated → ordinary provider non-explicit title: unchanged main behavior — only default/seed titles are replaceable (ProviderRuntimeIngestion.test.ts:3914-3957).
  4. no title (New thread) → OMP rename: applies via either branch.
  5. duplicate/replayed title events: command ids embed a random UUID (ProviderRuntimeIngestion.ts:985-988), so replays are not deduped by command id; the decider's expectedTitle/expectedVersion checks make re-application effectively idempotent (same title, needsRefinement:false, generated state). A replayed older rename can in principle re-assert its text if it lands after a newer one — this is the same class as main's existing title-seed path and is not a candidate regression. No corruption or authority inversion found.

/fresh and session/load boundaries: OmpAcpSupport.ts:103-105 passes adoptAgentSessionIdChanges: true; OmpAdapter.ts:1190-1197, 1229-1235 tracks new /fresh ids for event routing while keeping the original id as the resume cursor ("keeps streaming after omp swaps its session id" and "resumes an omp session named by an imported cursor" both pass). Session identity is not corrupted; imported transcripts require a session record before resume (AgentSessionScanner tests: "skips an omp transcript whose session record is missing").

4. Feature parity (traced end-to-end, not file existence)

All 24 capability areas are wired: provider registration (builtInDrivers.ts:27,56; settings.ts:1200), ACP transport (OmpAcpSupport.ts:55-121), OMP-owned model catalog (OmpCommands.ts/OmpModelCatalog.ts via RPC probe with ACP fallback), upstream provider grouping, per-model thinking levels, skill discovery + $ dispatch, command discovery, command argument autocomplete, usage_update context meter, /compact, usage/auth display, self-update advisory, transcript/project discovery, import + session/load resume, /rename, /fresh, permission/approval handling, subagent progress, image input, interrupt/cancel, web UI (settings/form/icon/onboarding), mobile icon, text generation, and documented limitations.

Nothing that #11791 exposed is missing in #11973. Gaps found are present in #11791 too (verified byte-identical files), i.e. scope/robustness observations, not regressions: no live account.rate-limits.updated emitter (OmpUsage.ts:18-23 is aspirational; limits are probe-only), OmpModelCatalog.metadataBySlug has no production consumer, /compact UI depends on the RPC command probe (OmpProvider.ts:696-699), and mobile has no slash-argument autocomplete (web-only in #11791).

5. Shared-runtime regression review

Generic changes are limited and consistent with existing provider patterns:

  • resolveThreadProviderDisplayName (web display only): configured instance label now outranks the persisted session slug, with brand/legacy/humanized fallbacks. Intended by the feature ("honest provider labels"); covered by providerModels.test.ts (passes).
  • defaultEnabledForDriver export widening + OmpSettings default disabled: omp is off by default; serverSettings.ts:275-326 restores previously-used providers exactly like cursor/grok/opencode (same pre-existing pattern, explicit settings always win).
  • Registry/expectation and scanner changes are additive; no provider-independent semantics weakened, no OMP special-casing leaked into generic paths, no lifecycle/optional-handling changes outside the OMP files.
  • Claude/Codex/OpenCode/ACP behavior: no candidate changes found in their generic code paths; shared-file deltas are the display-name resolver and additive schema/registry entries listed above.

6. Security / auth / process boundary

  • Credentials: no capture/persist/log/copy of provider auth material. OmpSettings carries only enabled/binaryPath/customModels; auth is omp-local under ~/.omp (single ACP authMethodId: "agent"); account email/plan appear only in the same status-cache/display path as Claude/Codex.
  • Spawn safety: fixed literal args (["acp","--approval-mode=…"], --mode rpc, usage --json, update --check), binary as a path, no shell interpolation; Windows .cmd/.bat path goes through the repo's escaping resolveSpawnCommand. Model/session/skill values travel over ACP JSON-RPC or prompt text, never argv.
  • Transcript/import boundary: size/record caps, absolute-path + realpath + workspace-identity validation, role/attribution filtering; import creates a stopped, history-only thread and cannot enable omp or grant runtime permissions. Scanner only considers enabled instances; PI_CODING_AGENT_DIR/OMP_PROFILE are resolved per-instance with profile-name validation.
  • Permissions: requests surface to the user; auto-approve exists only in full-access; omp maps decisions onto the agent's advertised option kinds (OmpAdapter.ts:358-376,1325-1399).
  • Auto-enable: off by default; only the shared "restore used providers" path can re-enable after prior use, and an explicit disable wins.

Non-blocking security notes (also present in #11791):

  • Unattended text generation spawns omp with runtimeMode: "auto"--auto-approve and registers no permission/elicitation handler (OmpTextGeneration.ts:62-77, asserted by its tests; OmpAcpSupport.ts:59-60). Other providers constrain this path (read-only/deny tools). Repo-derived prompt content is the input. Recommend approval-required + auto-deny for this path.
  • T3 "Auto" mode maps to unconditional --auto-approve for omp, wider than the mode's documented "automatic review" contract.
  • omp transcript titles/session ids are not length-capped before persistence (robustness only; React escapes text).

7. Lockfile

Keeping main's pnpm-lock.yaml is correct. #11791's lockfile diff is 2 lines / 2 hunks: the alchemy@2.0.0-beta.76 peer-resolution hash string changes in the importer and snapshot entries. No package.json changed anywhere in the source PR, so the churn is resolution noise, not a dependency change. Independently verified:

  • pnpm install --frozen-lockfile with main's lockfile succeeds (4m22s, pnpm 11.10.0);
  • all workspace packages typecheck with the frozen install (no source file relies on a package/version only present in the discarded lockfile);
  • 701 tests pass against the frozen install.

8. Independent test evidence

Run on the exact candidate head in a clean WSL clone (source-only; omp absent from PATH):

Check Result
OMP server suite: adapter/provider/driver/commands/catalog/usage/maintenance/skill-dispatch/ANSI/ACP-support/text-generation (11 files) 161 passed
Shared server: ProviderRuntimeIngestion (79), ProviderRegistry (52), AgentSessionScanner (90), AgentSessionImporter (14) 235 passed
Contracts settings.test.ts 129 passed
Web composer/pickers/readiness (8 files) 176 passed
Total 701 passed, 0 failed (24 files)
Typecheck: packages/contracts, packages/client-runtime, apps/server, apps/web, apps/mobile all EXIT=0
Targeted lint of all 71 changed files (vp lint --report-unused-disable-directives) 0 errors (82 pre-existing-pattern warnings)
git diff --check clean
pnpm install --frozen-lockfile success

Reported Windows scanner flake: not independently reproduced here (Linux-only runner; AgentSessionScanner.test.ts 90/90 passed). Unreproduced, and the candidate's scanner delta vs #11791 is only main-drift imports plus the preserved skipIf(!symlinksSupported) guards; I found no source-level evidence of a candidate-caused flake. Windows-native confirmation remains unproven.

9. Hosted CI state

Workflow runs for d870717364 exist (created 22:52–22:54Z) and are not passing CI: CI, Web Preview, Mobile EAS Preview, Mobile Fingerprint Check all completed with conclusion action_required and 0 jobs — the standard fork-workflow maintainer-approval gate, not a test failure. PR Size and PR Vouch (pull_request_target) passed; CodeRabbit skipped (draft). This should not be cited as green CI.


Verdict: CLEAN_FOR_LIVE_ACCEPTANCE (source-only)

Established: source integration correctness (18/18 source commits preserved as ancestry, correct merge directions, OMP-only net diff), file-level parity (54 identical + 17 justified deltas + lockfile, no dropped feature hunk), current-main compatibility (no-overlap drift; frozen install; all typechecks), feature wiring end-to-end, title/session authority behavior, no security boundary violations, no shared-runtime regressions, and 701 passing source-only tests.

Unproven (requires live acceptance): real omp startup, real authentication, real provider model discovery, live streaming, live context usage, live compaction, live resume/import, live subagents/approvals/images/cancel, and actual inference.

Non-blocking recommendations (not gating): constrain text-generation approval (OmpTextGeneration.ts), align omp "Auto" with a review step or document it, fix the stale live-rate-limit comment or wire the emitter, add length caps for omp titles/session ids, and add mobile slash-argument handling if parity is desired.

@nullStack65

Copy link
Copy Markdown
Author

Operator-authorized live acceptance — Oh My Pi (omp) integration

Verdict: LIVE_ACCEPTANCE_PASS for the integration surface as exercised, with a separate provider/account limitation (details in §5, §13). No candidate defect was found that requires a source change. This is a report only — no changes were made to the branch.

1. Exact refs at test time

Ref SHA
Candidate #11973 head (tested, unchanged since source review) d8707173644cfc49c62b1ad2f840a0ffc41a4b5c
Source feature #11791 head 14ed34f4e21946819109d2cdf17186d89b4b6d1b
T3 main at test start 935c55b3778fdeae0e25b250ce2a9fa7e79c0327
T3 main at test end f8500f11271622ed82df7f6c1d7f73eddb4f43e6 (+4 commits: #12011, #11954, #12002, #12008)
Candidate base at creation 87a12b53fdff7e2e0318af3edea54005557cea56
  • Main advanced twice during acceptance. Both fresh deltas overlap 0 of the 71 candidate files (comm -12 empty both times), so acceptance ran against the reviewed head per the dispatch rule.
  • feat(omp): integrate Oh My Pi provider on current main #11973 is still draft, mergeable=MERGEABLE, mergeStateStatus=BLOCKED, head unchanged, no new comments/reviews since the source review comment.
  • Runtime identity: T3 dev server executed directly from a clean checkout at d8707173…; /.well-known/t3/environment reported serverVersion 0.0.40, environmentId 2982703e-f980-45de-9774-0b2136e449e6. No released build was used.
  • Environment: macOS x64, Node 25.6.0 (repo wants ^24; pre-existing warning), pnpm 11.10.0. Sandboxed T3 home; no writes to the live ~/.t3/userdata.

2. OMP install and state protection

  • Install: ~/.local/bin/omp, omp/18.0.10 (installed 2026-08-28). Latest stable per omp update --check: 18.2.1 — advisory rendered correctly in T3 ("Update available"). No update was performed: 18.0.10 satisfied every exercised path; no compatibility failure appeared.
  • State protection: ~/.omp/agent/config.yml hash identical before/after (8c5d6b0d…); agent.db, history.db, models.db all integrity_check = ok; 401 pre-existing session transcripts intact plus the 1 new acceptance session; auth still readable (openai-codex account present, not logged out). No credential contents were read, printed, or committed.

3. Discovery / auth (no inference)

Enabled Oh My Pi through the real Settings UI (off by default, as designed). Provider snapshot then reported:

  • version 18.0.10, installed: true, status: ready, message "2 upstream providers configured through Oh My Pi".
  • 5 models: openai-codex/gpt-5.5, openai-codex/gpt-5.6-luna, openai-codex/gpt-5.6-sol, openai-codex/gpt-5.6-terra, ollama/qwen2.5:0.5b — grouped by upstream provider with per-model thinking ladders (luna/sol/terra low…max; 5.5 low…xhigh) and context windows (272K codex / 32K ollama).
  • 65 slash commands + 5 skills at machine level; the live session published 66 available_commands_update entries on session/new and again on session/load.
  • Auth: authenticated (agent), account line rendered in the provider card (email redacted here).
  • Onboarding "Agents" step lists Oh My Pi alongside Codex/Claude, and the project-import scan discovered the acceptance workspace's OMP session (1 conversation).
  • Probe observations under machine load (host load avg 7–16, 8 GB RAM): omp --version (4 s budget) and omp usage --json (3 s budget) each timed out once, transiently degrading the snapshot to error (no commands/skills). Opening the client and running a full "Refresh provider status" recovered to ready. This is environment sensitivity, not a data-loss bug; warm probe timings were 1.3–1.5 s.

4. Model selection and attempts

Policy: subscription route, non-Anthropic, low cost. Primary: openai-codex/gpt-5.6-luna (ChatGPT subscription backend, lowest codex cost).

  1. Attempt 1 — luna, text turn (turn started 01:35:50.388Z): OMP ACP turn ran end-to-end, then failed at the upstream provider:
    • UI: "Codex error event: The usage limit has been reached (code=usage_limit_reached)".
    • OMP log: agent turn ended with provider error provider=openai-codex model=gpt-5.6-luna; codex-auto-reset reason no-credits.
    • Account capacity from omp usage --json: chat 7d and base-model-inference ("gpt-reserve") 7d both 100% used; reset 2026-09-19T17:18Z. spark 5h/7d windows were at 0% but map to gpt-5.3-codex-spark, which is not in this account's catalog.
  2. Attempt 2 — single alternate, ollama/qwen2.5:0.5b (model switch round-tripped through session/set_config_option): generation hung for >30 min with no ACP stream frames. Isolation: direct omp -p with the same model also stalls, and a direct curl to ollama for a 24-token completion times out >120 s with the runner spinning at ~200% CPU and flat RSS (model never loads). Restarting ollama did not help. Classified as a local-runtime environment limitation, not T3 or OMP.
  3. Attempt 3 — image turn with luna: same usage_limit_reached (see §9).

No silent fallback occurred; each attempt is recorded above. The quota block is account-wide for the in-catalog codex models until the reset date.

5. Real ACP session lifecycle (verified on the failure-free paths)

Exact frame sequence observed through the candidate adapter (events.<thread>.log), for both session/new and session/load:

initialize → authenticate → session/new|session/load → session/set_config_option → session.started (agentInfo: oh-my-pi 18.0.10) → thread.started (providerThreadId) → turn.started (model) → available_commands_update (66) → session/prompt → usage_update → turn.completed → item.completed.

Token accounting is real: usage_update {size: 272000, used: 16486} mapped to T3 thread.token-usage.updated {usedTokens, maxTokens}. First ACP session/prompt succeeded with stopReason: end_turn while the upstream model call failed — T3 surfaced the provider error text faithfully, with no duplicate/stale terminal event.

6. Model / thinking switching

  • Model switch luna → qwen on the live session emitted session/set_config_option (succeeded) and all subsequent turns used the new model (turn.started payloads).
  • Thinking UI offered OMP's per-model ladder exactly (Off, Auto, Low, Medium, High, Extra High, Max); selecting High updates the control; the config options are sent and accepted by OMP at turn start (two set_config_option successes observed on the luna turn setup, incl. the "High" selection on the image turn).
  • No extra substantive turns were generated for this check.

7. Commands / context / compaction

  • Composer / menu listed the OMP catalog with descriptions and the "Oh My Pi" provider label (/context, /compact, /rename, /fresh, /review, /security, /handoff, /shake, /usage, /model, …).
  • Argument autocomplete verified: typing /compact offered soft / remote / snapcompact from OMP's hint — web-only feature, working.
  • /context executed (local, no model): OMP returned the live breakdown — "Context window: 32768 tokens (50% used); system prompt 6704 (20%); system tools 9174 (28%); auto-compact buffer 16232 (50%)".
  • /compact executed through the real compaction path: OMP replied "Compaction failed: Nothing to compact (session too small)"; session stayed usable. Note: T3 also rendered its generic synthesized "Context compacted" notice (the shared provider-native-command fallback), which contradicts the failure text in that edge case — generic behavior, not OMP-specific, non-gating.

8. Titles and /fresh

  • Generated → explicit OMP rename: OMP /rename OMP Rename Live replaced the generated T3 title in header and sidebar.
  • Manual authority: manual T3 rename to "Manual Title Wins", then OMP /rename OMP Tries Again — OMP renamed its own session ("Session renamed to OMP Tries Again.") while T3 kept the manual title. Authority correct in both directions.
  • /fresh: executed; OMP replied "Fresh provider session started (0 provider states pruned)". No session-id rotation was observable in this state (no live provider stream to prune); T3 kept receiving events and the thread remained coherent. Honest caveat: rotation itself was not reproduced live; source tests cover it.

9. Image input

  • Generated a 64×64 non-sensitive PNG, attached through T3's composer. T3 stored it as an asset, rendered it in the message, and the turn reached the provider (luna) with the prompt; only the upstream quota blocked a model response. Attachment plumbing verified end-to-end; model answer not obtainable (quota).

10. Cancel / interrupt

  • User cancel: Stop generation → turn.completed {state: "cancelled", stopReason: "cancelled"}; no trailing stream; thread stayed usable. Reproduced on two threads.
  • Abrupt process death: killing the ACP process mid-turn produced the same clean terminal state within seconds, with the T3 session reaped correctly.

11. Restart / resume

  • Cleanly stopped and restarted the candidate server (same sandbox home).
  • Reopening the thread showed full prior history; the next turn used session/load (not session/new) with the same providerThreadId 01a0a7db-19a4-7050-a0db-7a0f785185cb and the same native session file.
  • Resume from an imported cursor: the imported thread's first message also drove session/load with the imported session id.

12. Transcript / project import

  • Import scan discovered the acceptance workspace: /Users/businessaccount/Documents/t3-omp-integration-20260915/sandbox — 1 conversation (the live OMP session) — alongside unrelated provider histories.
  • Imported exactly the 1 representative session. Result: thread import:omp:01a0a7db-19a4-7050-a0db-7a0f785185cb, title taken from the OMP session name ("OMP Tries Again"), history-only (18 projected messages, no provider session row, shown settled), original OMP transcript files untouched.
  • Missing/invalid session records fail closed by construction (import path); not fabricated live beyond the representative case.

13. Interactive command / elicitation

  • /review surfaced a real T3 elicitation: "User input requested — Review Mode" with four options. Selecting "2. Review uncommitted changes" round-tripped (user-input.requesteduser-input.resolved {value: "2. Review uncommitted changes"}).
  • OMP then returned no output, and T3 emitted an honest runtime.warning: "Oh My Pi ran /review without returning any output — that command only renders in its own terminal UI." Turn completed cleanly. This matches the documented terminal-only-command behavior.

14. Usage / context evidence (live)

  • Usage page (Limits): Codex weekly 0% left; Oh My Pi rows read from the OMP probe — "5 hours (Spark)" 100% left (reset in ~5 h) and 7-day windows with live reset times ("+33% in 3d 14h", "↻ 5d 0h"). Account email rendered on the auth line (redacted here).
  • Context: model-declared 272K (codex) / 32K (ollama); /context showed active usage 50% of 32K; live usage_update frames fed the T3 meter and token usage.
  • Declared context window, active usage, and provider quota are reported as distinct pieces of data; no unavailable limits were inferred.

15. Known non-blocking source-review notes — live observations

  • Text-generation auto-approve: not triggerable live (title generation failed at the Codex quota; OMP text generation was not exercised).
  • T3 "Auto" ↔ OMP auto-approve: not exercised; Full access correctly launched omp acp --approval-mode=yolo.
  • Titles/session-id length caps: no over-length value observed.
  • Rate-limit live-update comments: no live account.rate-limits.updated emitter observed (probe-only), matching the source review note.
  • Mobile slash-argument parity: not tested (web surface only).

16. Not exercisable in this environment (reported, not fabricated)

  • Approval flow and subagents could not be triggered: both require a model-driven tool call, and the only authenticated subscription route is quota-blocked until 2026-09-19T17:18Z while the local ollama model cannot load on this machine. These are provider/account + local-runtime limitations, unrelated to the candidate.
  • Consequently, a successful streamed assistant generation was not obtained in this window. Everything around inference — discovery, config, streaming lifecycle, usage accounting, commands, cancels, resume, import, elicitation, attachments — was exercised live.

17. Cleanup proof

  • Candidate runtime stopped by captured PIDs (dev-runner + children + a brief server-only descriptor run); ports 13773/5733 free; zero omp acp children remain. No pkill/pattern kills were used.
  • Temporary artifacts removed (test image, browser auth state, probe payloads, pairing scratch); the one minted pairing credential is not active (No active pairing credentials); no credential/token/pairing URL appears in any published artifact.
  • OMP left intact: config hash unchanged, DB integrity ok, sessions preserved (401 + 1), account still authenticated, no logout.
  • Workspace: no repository files changed; git status shows only untracked acceptance scratch under .acceptance/.

18. Remaining risks / limitations

  1. Account quota exhaustion (resets 2026-09-19T17:18Z) blocks real inference with every in-catalog codex model; a follow-up live pass after reset is the only way to cover approval/subagent/successful-streaming.
  2. Local ollama runtime is unusable on this machine (runner never loads the model), independent of T3/OMP.
  3. Probe timeouts under load: a single omp --version timeout transiently degrades the OMP snapshot to error (0 commands/skills, status error) until the next successful check. Low severity; consider whether a version-probe failure should skip catalog discovery (source-design question, not a regression).
  4. The generic synthesized "Context compacted" notice can contradict an OMP "compaction failed" message (shared path; non-gating).

Unattended commit/PR/branch/title generation spawned omp with
--auto-approve and registered no permission handlers, so
repository-derived prompt text could steer the model into write or
destructive tool work that ran without any user in the loop.

Spawn those sessions with --no-tools and always-ask instead, and answer
any remaining permission request with a refusal and any elicitation with
a decline, so nothing can pause on UI that does not exist. The
interactive provider is unchanged.
The omp usage --json probe refreshes provider quota over the network.
Warm runs measure 0.5-1.3s but the first refresh after an omp update
measured 4.8s, so the 3s bound dropped a healthy account's limits and
could transiently degrade the snapshot. 10s matches omp's own
update --check bound and still fails rather than hanging a refresh.
@nullStack65

Copy link
Copy Markdown
Author

Current-runtime refresh + bounded safety hardening — checkpoint

Verdict: CURRENT_RUNTIME_PASS

This slice refreshed the runtime evidence to current OMP, classified current-main drift, repaired one narrow probe-timeout brittleness, and closed the unattended text-generation approval gap found in independent review. No Codex inference was attempted (quota remains exhausted until ~2026-09-19T17:18:32Z).

1. Exact refs

Ref Value
#11973 previous head d8707173644cfc49c62b1ad2f840a0ffc41a4b5c
#11973 new head 8f021c5f389eec3a9a7d7f9266c623686792a2b5 (2 commits, draft kept, MERGEABLE)
T3 main at refresh f8500f11271622ed82df7f6c1d7f73eddb4f43e6
#11791 source head 14ed34f4e21946819109d2cdf17186d89b4b6d1b (unchanged; no newer OMP carrier or superseding provider PR found)
OMP before 18.0.10 (tag 33cc6b9a043a74e00a157e72ca909272796d8461)
OMP after 18.2.1 (tag acf943d3c8dc1ed135b42aa33fef4d9d2ff61c9a)

2. Current-main drift classification

main moved 87a12b53ff8500f112 (9 commits, 44 changed files). The candidate touches 71 files. The intersection is 0 files:

  • f8500f112 mobile licenses toolbar, eed974c12 Claude rewind, 0ec2b08a9 mobile deep links, 8c18b5bb2 Antigravity _MEI cleanup, 935c55b37 environment discovery, 7a368fe7c project monograms, b12c92f69 checkpoint index reuse, 37a8ab2b2 Hermes lint bans, 6f7aaffe2 monogram Intl fix.

No semantic overlap with OMP/shared integration surfaces, so per the dispatch rule the reviewed head was kept and no main merge was performed.

3. OMP user-state proof

  • Pre-update: config.yml sha256 8c5d6b0d…; agent.db 928f5c5c…; history.db 42d92f46…; models.db d84f01c9…; integrity_check = ok ×3; auth = 1 openai-codex OAuth credential; 3624 session files.
  • Update used OMP's supported updater (omp update). Updater verified the installed asset sha256 6a5e678b95fdceec03eb1bdcd5046ff76e25eb092acab5d52a785e7582b4467e; the new binary's on-disk hash matches.
  • Post-update (before first use): all four hashes byte-identical — no eager migration or config rewrite.
  • Post-live: config hash unchanged; auth still 1× openai-codex (never logged out); integrity ok ×3; session files 3624 → 3680 — all new sessions were created in the sandbox project by this slice's live ACP runs, nothing was removed. Credentials were never read, printed, or written to logs/artifacts.

4. 18.0.10 → 18.2.1 delta and current compatibility (no inference)

Release deltas that matter to this integration: ACP always-ask/write granted calls no longer stick pending (#10850); ACP no longer advertises custom/file slash commands that collide with builtin aliases (#12092); file slash commands now carry input.hint (#11647); ACP clients now observe dynamic model changes; ACP JSON-RPC drains inbound requests on EOF (#11567); /drop/delete; /switch added; tool context missing at execute time now fails closed to always-ask (#10362); MCP tool naming preserves digits.

Live run (candidate code driving the real omp 18.2.1 binary, existing auth, no model turn):

  • initializeoh-my-pi 18.2.1, auth method agent, loadSession: true, promptCapabilities {embeddedContext, image}, sessionCapabilities {close, fork, list, resume}, model config option id model.
  • session/new config options: mode (default|plan), model 7 entries (openai-codex/gpt-5.5, …/gpt-5.6-luna, …/gpt-5.6-sol, …/gpt-5.6-terra, …/gpt-6-astra, …/gpt-daybreak-blue-latest, ollama/qwen2.5:0.5b), thinking off|auto|low|medium|high|xhigh|max.
  • Model and thinking set_config_option succeeded without inference; available_commands_update carried 69 entries at session/new (66 on 18.0.10 in the prior live run) including skill: entries.
  • /context returned the live breakdown (272K window, 6% used); /rename <title> returned the rename notice plus a session_info_update title; /fresh reported "Fresh provider session started (0 provider states pruned)." and rotated the session id on the same connection (the runtime adopted it); /compact returned "Nothing to compact (session too small)".
  • /review raised a real elicitation (declined by the handler), produced no model output, and completed end_turn; an idle session/cancel settled in 1 ms and the session stayed usable afterward (/context succeeded).
  • session/load of the same session id returned the same session id with config options; resume parity holds on 18.2.1.
  • Provider snapshot through the candidate driver: version 18.2.1, status ready, "2 upstream providers configured through Oh My Pi." (Openai Codex, Ollama), auth authenticated (account label/email present, redacted here), 6 models with per-provider grouping and thinking ladders (gpt-5.5 low…xhigh; luna/sol/terra/astra low…max; ollama none), 68 slash commands, 5 skills, usage windows openai-codex:5h + 3×7d. The RPC catalog probe (omp --mode rpc --no-session --no-lsp) also works unchanged on 18.2.1 (68 commands, 1 machine-level skill, 6 models with context windows and ladders).

No runtime incompatibility was found. Raw observations: artifacts/omp-delta/live-18.2.1-observations.ndjson and rpc-catalog-probe-18.2.1.json (local evidence, not committed).

5. Probe timings and timeout repair

Probe Measured
omp --version idle 0.08–0.27 s (5 runs), first run after update 0.73 s
omp --version under +8 CPU burners 0.11 s (5 runs)
omp usage --json warm 0.49–0.50 s
omp usage --json after usage invalidate 0.75–1.26 s (3 runs)
omp usage --json first run after update 4.76 s (exceeded the old 3 s bound)
RPC catalog probe 12.4 s at load ~20 (20 s snapshot bound, 45 s inner)
Full live ACP suite 6–16 s total

Conclusion: the 4 s version probe has 15–40× headroom on current OMP and is not brittle — kept. The 3 s usage bound was exceeded by an ordinary cold quota refresh, so it was raised narrowly to 10 s (matching omp's own update --check bound), still bounded so a refresh cannot hang. OmpUsage.ts comment records the measurement. No other timeout was touched and no unbounded waits were introduced.

6. Unattended text-generation security repair

Finding (confirmed in source): OmpTextGeneration spawned omp acp --auto-approve (yolo) and registered no permission/elicitation handlers, so repository-derived prompt text (staged patches, diffs) could steer the model into write/destructive tool work that executed with no user in the loop.

Repair, in the smallest shape that keeps generation unattended:

  • Spawns now use --approval-mode=always-ask and --no-tools (both documented OMP flags, present in the tested 18.0.10 floor and in 18.2.1; no invented flags).
  • Any permission request is answered with {outcome:{outcome:"cancelled"}}; any elicitation is answered with {action:{action:"decline"}}; unknown elicitation/create extension requests are declined, everything else still fails method-not-found, so nothing can wait on absent UI.
  • The interactive OMP provider's semantics are unchanged (ompAcpSpawnArgs("auto") and every other mode are byte-identical).

Regression tests added: spawn args assert ["acp", "--approval-mode=always-ask", "--no-tools"]; a mock agent that requests tool permission now fails the generation as cancelled (no auto-approve, no hang); a mock agent that requests elicitation gets an immediate decline and cannot block (no timeout).

7. Source validation (all on 8f021c5f3)

  • OmpAcpSupport + OmpTextGeneration suites: 18 passed (incl. 3 new tests).
  • OmpUsage/OmpMaintenance/OmpModelCatalog/OmpCommands/OmpSkillDispatch: 43 passed.
  • OmpProvider + OmpDriver: 38 passed.
  • OmpAdapter: 58 passed.
  • vp run --filter t3 typecheck: 0 errors. Lint on changed files: clean (3 pre-existing warnings in OmpUsage untouched). vp fmt --check: clean. git diff --check: clean.
  • Temporary live-acceptance test file removed; worktree has only the two pushed commits plus untracked local scratch.

8. Remaining quota-gated live items

Successful streamed assistant generation, approval-driven tool execution against a real tool call, and subagent execution remain unproven because every in-catalog Codex model is quota-blocked until ~2026-09-19T17:18:32Z; cancelling an in-flight model turn and a real image-answer turn are likewise inference-gated. Everything around inference — discovery, auth, session lifecycle, catalogs, config switching, local commands, elicitation, resume, cancel/cleanup, import-shaped resume — was exercised live on 18.2.1 without consuming a model turn.

Final result: CURRENT_RUNTIME_PASS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants