Skip to content

fix(pi): reduce OMP native inputs and optional Codex reasoning - #433

Open
SilentBless wants to merge 7 commits into
cortexkit:masterfrom
SilentBless:fix/omp-native-context-reductions
Open

fix(pi): reduce OMP native inputs and optional Codex reasoning#433
SilentBless wants to merge 7 commits into
cortexkit:masterfrom
SilentBless:fix/omp-native-context-reductions

Conversation

@SilentBless

@SilentBless SilentBless commented Sep 10, 2026

Copy link
Copy Markdown

What

Reduce OMP's native tool inputs and eligible old Codex reasoning without discarding the surrounding provider-native history.

  • Update the selected function_call.arguments or custom_tool_call.input while preserving call identity, unrelated native-only reasoning and hosted results.
  • Match uniquely identified native calls even when OMP synthesized a block ID because the captured native item has no ID.
  • Reuse OMP's existing custom-input fallback instead of inventing a new custom-tool representation.
  • Clear old encrypted reasoning only on Codex models whose resolved compatibility settings explicitly allow omission, and only from incremental history without protected native dependencies.
  • Replay the same durable clearing decision and restore the original native payload if persisting its watermark fails.

Native text, user/developer carriers and full-history semantics are not rewritten. Ordinary tag injection does not mutate native history. Scheduling and protected windows are unchanged. This PR does not claim to solve every native-text reduction case.

Why

OMP intentionally treats assistant.providerPayload.items as authoritative on same-model native replay. Magic Context currently reduces a tool input or clears old reasoning in assistant.content while leaving that native copy intact. The queue can drain and record a dropped tag, yet the original large input and encrypted reasoning are serialized into the next request.

Clearing the whole assistant payload is not an equivalent fix: a source-level counterexample removes the stale input but also loses unrelated native-only reasoning and a hosted image result, even though the selected tool pair remains valid.

The fix is deliberately limited to the two mutation units in the reproduction. Native-text synchronization was excluded after review identified fragmented text identities and instrumentation ownership concerns; it requires a separate contract, not a broader heuristic mapper here.

Preservation boundaries

Native reasoning remains intact for non-Codex or unknown model capabilities, mandatory all-turn/tool-call reasoning, full snapshots, plaintext/malformed reasoning, redacted thinking and computer-linked reasoning. These cases are retained rather than speculatively reconstructed. Tool inputs with ambiguous identities are not guessed.

Related work

No Fixes reference is used because these are related precedents, not demonstrated duplicates.

Verification

The actual Magic Context queue/transcript functions and OMP serializers were exercised from their TypeScript sources using synthetic fixtures. The original queued reduction shrank its serialized request from 146,083 to 5,121 characters, removed old arguments and reasoning, and retained recent encrypted reasoning, a hosted image result and the selected tool pair. Additional source-level checks cover custom-input fallback parity, full-snapshot authority, synthesized tool IDs and mandatory reasoning preservation.

A subsequent live check used the normal installed OMP v18.1.10 CLI with an isolated profile and this built extension on openai-codex/gpt-6-astra:xhigh. Four model turns completed: the native tool input was actually replaced before a successful continuation, and a real encrypted reasoning item from a later response was then removed before another successful continuation (MC_PROFILE_REASONING_OK.). Its original ciphertext remained in the saved source session; the observer checked its hash was absent from outgoing native history, and the persisted clearing watermark advanced to its range. The native call ID remained stable. No previous_response_id shortcut or custom transport was used. This establishes live acceptance for this tested Codex flow, not every provider or native-history shape. Final gates after removing the standalone probes:

  • Core: typecheck, lint, build, compiled-TUI check; 4,605 tests passed.
  • Pi: typecheck, lint, build; 1,036 tests passed. Lint reports two existing warnings and no errors.
  • Six source-serializer scenarios passed. The full OMP-mode context-handler fixture measured 54,932 → 4,947 characters, with native text, the hosted result and the tool pair intact.
  • A mixed plaintext/encrypted reasoning regression failed before its preservation guard and passes afterward. The rollback regression now asserts that the failing watermark write was actually attempted.

Independent reviews identified synthesized tool IDs, mandatory reasoning, mixed plaintext/encrypted items and native-text identity risks. The first three are handled by the targeted code and regressions; native-text rewriting was removed from scope. The separate droppedTokens accounting issue is unchanged.

Source-level OMP handler reproduction

Use sibling Magic Context and OMP source checkouts with their normal development dependencies (including the OMP native addon). The reference OMP revision was 34e938c3b37ab3b60375a6cef9c137166cb5fb70. Save this inside packages/pi-plugin/native-replay-probe.test.ts and run bun test native-replay-probe.test.ts there. It runs the real context handler and serializer, not a remote provider.

import { expect, test } from "bun:test";
import { getPendingOps, getTagsBySession, queuePendingOp } from "@magic-context/core/features/magic-context/storage";
import { buildModel } from "../../../oh-my-pi/packages/catalog/src/build";
import { convertCodexResponsesMessages } from "../../../oh-my-pi/packages/ai/src/providers/openai-codex-responses";
import type { AssistantMessage, Context } from "../../../oh-my-pi/packages/ai/src/types";
import { createFakePi, createTestDb, fakeContext } from "./src/test-utils.test";
import { clearContextHandlerSession, registerPiContextHandler } from "./src/context-handler";
import { __setPiHarnessKindForTesting } from "./src/pi-harness-kind";

const model = buildModel({ id: "gpt-probe", name: "Probe", api: "openai-codex-responses", provider: "openai-codex", baseUrl: "https://example.invalid", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 272000, maxTokens: 64000 });
const zeroUsage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } };
function assistant(content: AssistantMessage["content"], items: Record<string, unknown>[], dt = true): AssistantMessage {
  return { role: "assistant", api: model.api, provider: model.provider, model: model.id, content, providerPayload: { type: "openaiResponsesHistory", provider: model.provider, dt, items }, usage: zeroUsage, stopReason: "toolUse", timestamp: 2 };
}

test("full OMP context handler reduces the actual outgoing native history", async () => {
  const db = createTestDb();
  const sessionId = "full-omp-native-probe";
  try {
    __setPiHarnessKindForTesting("omp");
    const fake = createFakePi();
    registerPiContextHandler(fake.pi as never, { db, protectedTags: 20, heuristics: { clearReasoningAge: 20 } });
    const handler = fake.handlers.get("context") as (event: { messages: never[] }, ctx: never) => Promise<{ messages: never[] } | undefined>;
    const stale = "FULL_HANDLER_STALE_INPUT_".repeat(2000);
    const encrypted = "FULL_HANDLER_OLD_ENCRYPTED_".repeat(2000);
    const old = assistant([
      { type: "thinking", thinking: "old summary" },
      { type: "text", text: "Retain native text", textSignature: "msg_full" },
      { type: "toolCall", id: "call_full|fc_full", name: "read", arguments: { path: stale } },
    ], [
      { type: "reasoning", encrypted_content: encrypted, summary: [{ type: "summary_text", text: "old summary" }] },
      { type: "message", role: "assistant", id: "msg_full", content: [{ type: "output_text", text: "Retain native text", annotations: [] }] },
      { type: "function_call", id: "fc_full", call_id: "call_full", name: "read", arguments: JSON.stringify({ path: stale }) },
      { type: "image_generation_call", id: "ig_full", status: "completed", result: "aW1hZ2UtcGF5bG9hZA==", output_format: "png" },
    ]);
    const messages: Context["messages"] = [
      { role: "user", content: "Initial request", timestamp: 1 }, old,
      { role: "toolResult", toolCallId: "call_full|fc_full", toolName: "read", content: [{ type: "text", text: "old result" }], isError: false, timestamp: 3 },
    ];
    for (let i = 0; i < 25; i++) {
      messages.push({ ...assistant([{ type: "toolCall", id: `full_${i}|fc_${i}`, name: "read", arguments: { path: "example.ts" } }], []), providerPayload: undefined, timestamp: 4 + i * 2 });
      messages.push({ role: "toolResult", toolCallId: `full_${i}|fc_${i}`, toolName: "read", content: [{ type: "text", text: `result ${i}` }], isError: false, timestamp: 5 + i * 2 });
    }
    messages.push({ role: "user", content: "Continue", timestamp: 100 });
    const ids = messages.map((_, i) => `full-entry-${i}`);
    const run = async (percent: number) => {
      const input = structuredClone(messages);
      const result = await handler({ messages: input as never[] }, {
        ...fakeContext(sessionId, process.cwd(), ids, input as never), model,
        getContextUsage: () => ({ tokens: model.contextWindow * percent / 100, percent, contextWindow: model.contextWindow }),
      } as never);
      if (!result) throw new Error("context handler did not return messages");
      return result.messages as unknown as Context["messages"];
    };
    const initial = await run(0);
    const before = JSON.stringify(convertCodexResponsesMessages(model, { messages: initial }));
    expect(before).toContain(stale);
    const tag = getTagsBySession(db, sessionId).find(value => value.type === "tool" && value.messageId === "call_full|fc_full");
    if (!tag) throw new Error("full handler failed to tag old tool input");
    queuePendingOp(db, sessionId, tag.tagNumber, "drop");
    const reduced = await run(90);
    const items = convertCodexResponsesMessages(model, { messages: reduced });
    const after = JSON.stringify(items);
    expect(getPendingOps(db, sessionId)).toEqual([]);
    expect(after).not.toContain(stale);
    expect(after).not.toContain(encrypted);
    expect(after).toContain("Retain native text");
    expect(items.some(item => item.type === "image_generation_call")).toBe(true);
    expect(items.some(item => item.type === "function_call" && item.call_id === "call_full")).toBe(true);
    expect(items.some(item => item.type === "function_call_output" && item.call_id === "call_full")).toBe(true);
    console.log(JSON.stringify({ probe: "full-omp-context-handler", beforeWireChars: before.length, afterWireChars: after.length,
      nativeArgumentsAndOldReasoningRemoved: true, nativeTextHostedImageAndToolPairPreserved: true, providerRequestSent: false }));
  } finally {
    clearContextHandlerSession(sessionId);
    __setPiHarnessKindForTesting(undefined);
    db.close();
  }
});

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Fixes OMP native replay so tool-input reductions and eligible Codex reasoning clearing now mutate the serialized provider history and persist as durable replay state, so the reductions survive restarts and session clones.

Bug Fixes

  • Rewrites the matched native function_call.arguments or custom_tool_call.input while preserving call identity, unrelated native-only reasoning, and hosted results; leaves calls untouched when reduced inputs cannot be safely serialized to JSON.
  • Clears old encrypted reasoning only for Codex models whose resolved compatibility settings explicitly allow omission, and only from incremental history without protected native dependencies.
  • Persists native tool inputs and reasoning decisions in separate session-meta columns, defers first activation to an authorized cache-busting pass, and suspends saved decisions while compaction is off, resuming when re-enabled.
  • Restores the original providerPayload if persisting either replay state fails; malformed persisted state also fails closed, keeping native history intact, and the decision retries on the next authorized pass.
  • Reuses OMP's existing custom-input fallback instead of introducing a new tool representation.
  • Native text, user/developer carriers, and full-history snapshots are never rewritten; local Pi thinking cleanup still runs independently and advances only its own watermark, never the native reasoning set.
  • Clone/session copy inherits only the retained native decisions and remaps their ids to the clone.

Written for commit 29d0b26. Summary will update on new commits.

Review in cubic

Greptile Summary

This PR synchronizes Magic Context reductions with OMP’s provider-native replay history and persists those decisions across subsequent passes, restarts, and session clones.

  • Rewrites matched native function and custom-tool inputs without replacing unrelated provider history.
  • Clears eligible encrypted Codex reasoning while preserving unsupported or protected reasoning shapes.
  • Adds durable, validated replay state with fail-closed persistence and rollback behavior.
  • Filters and remaps retained native replay decisions when cloning sessions.
  • Adds regression coverage for replay activation, persistence failures, compatibility boundaries, and clone inheritance.

Confidence Score: 5/5

The PR appears safe to merge because no actionable new failures or repository-rule violations were identified.

The changes since the previous review introduce no additional code differences, and the current implementation conservatively validates persisted state, gates native mutations, and preserves the prior payload when persistence fails.

Important Files Changed

Filename Overview
packages/pi-plugin/src/context-handler.ts Integrates durable native tool-input and reasoning replay after transcript commit, retaining native history when replay state is unavailable.
packages/pi-plugin/src/native-replay-pi.ts Implements conservative native call matching, input rewriting, and compatibility-gated encrypted reasoning removal.
packages/pi-plugin/src/native-replay-state-pi.ts Coordinates persisted replay decisions so new native mutations are published only after successful storage.
packages/plugin/src/features/magic-context/storage-native-replay.ts Adds validated transactional persistence for frozen native tool inputs and cleared-reasoning entry IDs.
packages/plugin/src/features/magic-context/storage-clone.ts Filters and remaps native replay decisions to only the state retained by a cloned session.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Pi context pass] --> B[Apply local transcript reductions]
    B --> C[Commit canonical transcript]
    C --> D[Load persisted native replay state]
    D --> E[Replay saved tool inputs and reasoning decisions]
    E --> F{Authorized cache-busting pass?}
    F -- No --> G[Return replayed history]
    F -- Yes --> H[Detect new native mutations]
    H --> I{Persist decisions successfully?}
    I -- Yes --> J[Publish updated native payload]
    I -- No --> K[Retain prior native payload]
    J --> G
    K --> G
Loading

Reviews (5): Last reviewed commit: "refactor: clarify native replay ownershi..." | Re-trigger Greptile

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/pi-plugin/src/signal-peek-drain.test.ts">

<violation number="1" location="packages/pi-plugin/src/signal-peek-drain.test.ts:210">
P2: This test was removed even though every assertion it pinned still holds against the current source. The test's `code` reads context-handler.ts, which still contains `stripInlineThinkingPi({`, `const combinedWatermark = Math.max(`, and `clearedReasoningThroughTag: combinedWatermark` (lines 5672, 5678, 5684). No other test covers the inline-thinking watermark-sharing wiring, so removing it drops regression coverage with no corresponding source change to justify it. Restore the test or update it if the watermark sharing was intentionally reworked.</violation>
</file>

<file name="packages/pi-plugin/src/native-replay-pi.ts">

<violation number="1" location="packages/pi-plugin/src/native-replay-pi.ts:170">
P2: When an incremental Codex reasoning item has a non-empty `summary`, `clearNativeReasoning` still deletes it because it only checks `content`. Preserve non-empty `summary` items as well, otherwise context reduction drops visible native reasoning instead of only removable encrypted-only reasoning.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment on lines +170 to +171
(item.content !== undefined &&
(!Array.isArray(item.content) || item.content.length > 0))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When an incremental Codex reasoning item has a non-empty summary, clearNativeReasoning still deletes it because it only checks content. Preserve non-empty summary items as well, otherwise context reduction drops visible native reasoning instead of only removable encrypted-only reasoning.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/pi-plugin/src/native-replay-pi.ts, line 170:

<comment>When an incremental Codex reasoning item has a non-empty `summary`, `clearNativeReasoning` still deletes it because it only checks `content`. Preserve non-empty `summary` items as well, otherwise context reduction drops visible native reasoning instead of only removable encrypted-only reasoning.</comment>

<file context>
@@ -0,0 +1,187 @@
+		if (
+			typeof item.encrypted_content !== "string" ||
+			item.encrypted_content.length === 0 ||
+			(item.content !== undefined &&
+				(!Array.isArray(item.content) || item.content.length > 0))
+		) {
</file context>
Suggested change
(item.content !== undefined &&
(!Array.isArray(item.content) || item.content.length > 0))
((item.content !== undefined &&
(!Array.isArray(item.content) || item.content.length > 0)) ||
(item.summary !== undefined &&
(!Array.isArray(item.summary) || item.summary.length > 0)))

);
});

test("inline thinking stripping shares the reasoning watermark", () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This test was removed even though every assertion it pinned still holds against the current source. The test's code reads context-handler.ts, which still contains stripInlineThinkingPi({, const combinedWatermark = Math.max(, and clearedReasoningThroughTag: combinedWatermark (lines 5672, 5678, 5684). No other test covers the inline-thinking watermark-sharing wiring, so removing it drops regression coverage with no corresponding source change to justify it. Restore the test or update it if the watermark sharing was intentionally reworked.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/pi-plugin/src/signal-peek-drain.test.ts, line 210:

<comment>This test was removed even though every assertion it pinned still holds against the current source. The test's `code` reads context-handler.ts, which still contains `stripInlineThinkingPi({`, `const combinedWatermark = Math.max(`, and `clearedReasoningThroughTag: combinedWatermark` (lines 5672, 5678, 5684). No other test covers the inline-thinking watermark-sharing wiring, so removing it drops regression coverage with no corresponding source change to justify it. Restore the test or update it if the watermark sharing was intentionally reworked.</comment>

<file context>
@@ -207,12 +207,6 @@ describe("source contract: peek-then-drain in runPipeline (history)", () => {
-		expect(code).toContain("clearedReasoningThroughTag: combinedWatermark");
-	});
-
 	test("model switch reset clears usage, reasoning, failure, limit, and recovery state", () => {
 		expect(code).toContain("clearedReasoningThroughTag: 0");
 		expect(code).toContain("clearHistorianFailureState(options.db, sessionId)");
</file context>

Comment thread packages/pi-plugin/src/reasoning-replay-pi.ts Outdated
Comment thread packages/pi-plugin/src/native-replay-pi.ts Outdated
Comment thread packages/pi-plugin/src/context-handler.ts Outdated

@magic-alfonso magic-alfonso Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for narrowing this to the native mutation units rather than dropping the whole payload. I checked OMP's Codex serializer directly: same-model native history bypasses the content conversion, and incremental versus full-snapshot replay behaves as described. I also reproduced the source-level 54,932 → 4,947 result against OMP source, with the native text, hosted image result and tool pair retained, and identical serialized bytes on the following defer pass. Your reported live OMP continuation check is valuable additional evidence beyond that source test.

Please address these before merging:

  1. Existing clearedReasoningThroughTag and dropped-tag state predate native rewriting. The new every-pass replay in reasoning-replay-pi.ts / context-handler.ts treats those records as permission to change native bytes immediately, even when no new reduction is queued. Please persist first native application on an already-authorized cache-busting pass, then replay that decision unchanged. Add upgrade-state coverage for both reasoning and already-dropped tool inputs, including multiple defer passes. A seeded legacy-watermark, zero-pressure/empty-queue probe currently removes native ciphertext that was previously retained.
  2. Please restore the deleted “inline thinking stripping shares the reasoning watermark” test in signal-peek-drain.test.ts, or replace it with stronger coverage of that same property and explain the change. The production code still shares that watermark; restoring the test unchanged passes.
  3. Please separate native retention from ordinary non-Codex typed-thinking cleanup. In reasoning-replay-pi.ts:155 and the matching replay branch, continue on preserved now suppresses existing cleanup for non-Codex Responses payloads. I ran the same real context-handler fixture on this PR and current master: at 90% usage master empties the old thinking and removes its signature, while this PR retains both and leaves the watermark at zero. A seeded-watermark replay also clears on master but not on the PR. Preserve actual required native dependencies, but add false-capability/non-Codex coverage so that policy does not inadvertently disable the legacy content lane.

I also verified the automated serialization concern in its narrower form: a programmatic BigInt input passed to the native tool-input setter throws here but not on master. A defensive serialization catch is sensible; ordinary JSON model arguments cannot produce that example, so I am not claiming a demonstrated remote-model pipeline outage. Conversely, I would not adopt the suggested blanket preservation of nonempty reasoning summary: your reproduction intentionally clears such old summaries together with optional encrypted reasoning. That is distinct from the protected plaintext reasoning content field.

The new regressions are substantive: reverting the native transcript synchronization, mixed/plaintext preservation guard, and native rollback capture each makes its corresponding test fail. The rollback assertion also really reaches the faulted persistence write. I additionally tested a failed-write pass followed by two defer passes through OMP's actual serializer: one attempted write, watermark zero, retained ciphertext, and three byte-identical 5,817-character inputs (A→A→A). I do not see the rollback restore itself introducing an A→B→A wire flip. Snapshotting a native payload reference when omission is disallowed is avoidable allocation work, not a demonstrated byte-stability defect.

One documentation/testing caveat: function calls carry the canonical dropped-marker JSON, while custom calls use OMP's existing empty-string fallback. The latter does not carry the dropped marker and should not be claimed to have identical copied-input rejection behavior without a tool-level test. Also, this head already includes #431 and the shared bust-permission changes; my cache concern is the first activation of the new native representation, not a missing rebase.

@magic-alfonso

magic-alfonso Bot commented Sep 10, 2026

Copy link
Copy Markdown

Follow-up after checking the contract with the Oh My Pi side: clearing old encrypted reasoning with both compat flags false is supported as described, with computer-call-linked reasoning as the only retention exception (under those flags the native builder emits no reasoning placeholders, so the clearing matches what native would send). Rewriting a matched function_call's arguments in place with call_id preserved is wire-safe — pairing and orphan repair key on (kind, call_id) only, and replay does not re-validate arguments — but there is no sanctioned mutation hook, and the rewrite is irreversible in the stored session JSONL; that deserves a sentence in the README. Two cases worth adding to the live check: a reasoning-only turn with all reasoning cleared falls back to the visible-transcript rebuild (expected and harmless), and a session containing an aborted turn, since orphan repair is the one path where pairing matters.

@SilentBless

Copy link
Copy Markdown
Author

Review follow-up pushed in b99a3fc3 (current head 10d797cc, including a non-rewriting merge of upstream 18f6bb9a).

  • Guarded native function-call argument serialization. Circular data, BigInt, throwing toJSON, or a non-string serialization result leave the native payload unchanged instead of aborting the transform.
  • Separated native-payload retention from local Pi thinking cleanup in both fresh clearing and durable replay. Ordinary stale thinking/signatures clear again; redacted blocks and protected native history remain intact.
  • Gated native providerPayload rollback snapshots on nativeReasoningMayClear, removing unused snapshot/restore work on other models.
  • Replaced the removed source-string watermark assertion with a behavioral inline-only persistence/restart test. It still replays the cleanup when the current age threshold prevents a fresh cleanup. A mutation check that ignored the inline watermark made the test fail by restoring the old <think> text.

The proposal to preserve every nonempty native summary was not applied. OMP's finalizeReasoningThinking maps summary_text to the ordinary Pi thinking display, which age-based cleanup intentionally removes. It is distinct from the protected native content payload. A regression and README clarification cover that distinction.

The README also states the native API boundary: OMP has no dedicated native-item mutation API. These reductions operate on the request transcript; the adapter does not itself perform a stored JSONL rewrite. OMP normally clones context input, with a shallow-array fallback for non-cloneable data; native tool-input updates are copy-on-write.

Verification on the updated upstream integration:

  • Core typecheck, lint, build, compiled-TUI check: passed; 4,611 tests passed.
  • Pi typecheck, lint, build: passed; 1,040 tests passed, with the existing lint warnings only.
  • An additional request-copy/native subset passed 28 tests after the documentation follow-up.

No new live model calls were made for this follow-up. The four-turn live evidence above remains tied to 77f8dda4. The suggested reasoning-only and aborted-turn live cases have not been claimed as executed.

@SilentBless

Copy link
Copy Markdown
Author

Addressed the upgrade-state feedback in f161392.

  • Legacy dropped tags and clearedReasoningThroughTag no longer authorize first native application during defer. Native tool-input values and native reasoning removals now have separate persisted state.
  • Transcript setters collect input changes; the final native stage replays saved decisions, plans newly authorized changes, persists them, then publishes the new bytes. Failed writes retain the previous native representation. A later authorized input reduction can update the frozen value; defer cannot.
  • Ordinary typed/inline thinking cleanup remains independent. Native-only reasoning uses its own replay state rather than advancing the local watermark. Positional pi-msg-* and synthetic IDs cannot own durable native reasoning decisions.
  • Clone inheritance filters/remaps these records. The CLI still supports older schemas, and its later generic metadata copy cannot overwrite the filtered native decisions.
  • README explicitly distinguishes function-call dropped-marker JSON from custom-call empty-string fallback; no identical copied-input rejection behavior is claimed.

Verification:

  • Real OMP TypeScript serializer (34e938c3b37ab3b60375a6cef9c137166cb5fb70): five scenarios passed, including legacy upgrade, independent persistence failures and frozen-input progression. The upgrade sequence was A→A→A (653 chars, identical SHA-256), followed by the authorized transition and B→B→B (514 chars, identical SHA-256).
  • Additional regressions cover native-only reasoning, stable-ID adoption, failed replacement of an already frozen input, restart replay, and clone metadata ownership.
  • Core: 4,618 tests passed; typecheck, lint, build and compiled-TUI check passed.
  • Pi: 1,047 tests passed; typecheck, lint and build passed. Only the two pre-existing lint warnings remain.
  • Real Node SQLite smoke passed; the new native storage commit/rollback path was also exercised under Node.
  • Two independent source reviews have no remaining blockers after the identity and clone fixes.

No new live-provider requests were made for this update. The earlier live Codex continuation evidence remains separate from these upgrade/cache-state checks.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 15 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/pi-plugin/src/context-handler.ts Outdated
@SilentBless
SilentBless force-pushed the fix/omp-native-context-reductions branch from 84d215d to 29d0b26 Compare September 11, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant