Skip to content

Commit e7b28de

Browse files
paired-replay reds: the CI red at the tag was an invalid execute_threshold_percentage (95 > the 90 cap) in the replay fixture whose config-warning turn became an extra model request under slower Linux runs and shifted the signed-thinking divergences (fixture now 90; assertions unchanged); the local red was a stale plugin dist retained across checkouts — the e2e runner now refuses a dist older than the newest source file; ranked inert whitespace tags replay only at their original part index or beside a thinking part so a late blank after a completed step never inherits an older prefix
Co-authored-by: Alfonso <alfonso-magic-context@users.noreply.github.com>
2 parents 2582d8f + 0403086 commit e7b28de

5 files changed

Lines changed: 92 additions & 21 deletions

File tree

‎packages/e2e-tests/src/opencode-runner/spawn.ts‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
existsSync,
1313
mkdirSync,
1414
readFileSync,
15+
readdirSync,
1516
realpathSync,
1617
statSync,
1718
writeFileSync,
@@ -26,17 +27,30 @@ import {
2627
} from "../rust-runner/hermetic-subc";
2728

2829
const REPO_ROOT = resolve(import.meta.dir, "../../../..");
29-
// Prefer the bundled `dist/index.js` (what published users actually run)
30-
// over raw `src/index.ts`. The bundled file is one ~5MB file with all imports
31-
// inlined; loading it is fast even on cold runners. The TS-source path
32-
// triggers Bun's runtime TS transpile + dynamic resolution across hundreds
33-
// of submodule imports — on slow Linux CI runners this can take long enough
34-
// to make `opencode serve` appear hung when it's just blocked in plugin
35-
// load. Production never loads from src/, so testing src/ doesn't reflect
36-
// reality and exposes us to a slowness path users never see.
30+
const PLUGIN_SRC_ROOT = join(REPO_ROOT, "packages/plugin/src");
3731
const PLUGIN_DIST_ENTRY = join(REPO_ROOT, "packages/plugin/dist/index.js");
38-
const PLUGIN_SRC_ENTRY = join(REPO_ROOT, "packages/plugin/src/index.ts");
39-
const PLUGIN_ENTRY = existsSync(PLUGIN_DIST_ENTRY) ? PLUGIN_DIST_ENTRY : PLUGIN_SRC_ENTRY;
32+
const PLUGIN_SRC_ENTRY = join(PLUGIN_SRC_ROOT, "index.ts");
33+
34+
function newestSourceMtime(directory: string): number {
35+
let newest = 0;
36+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
37+
const path = join(directory, entry.name);
38+
newest = Math.max(
39+
newest,
40+
entry.isDirectory() ? newestSourceMtime(path) : statSync(path).mtimeMs,
41+
);
42+
}
43+
return newest;
44+
}
45+
46+
// A fresh bundle is the closest production representation and avoids slow source
47+
// loading on CI. Ignored dist files can survive a local checkout, though, so never
48+
// let an older bundle silently test different code from the current source tree.
49+
const PLUGIN_ENTRY =
50+
existsSync(PLUGIN_DIST_ENTRY) &&
51+
statSync(PLUGIN_DIST_ENTRY).mtimeMs >= newestSourceMtime(PLUGIN_SRC_ROOT)
52+
? PLUGIN_DIST_ENTRY
53+
: PLUGIN_SRC_ENTRY;
4054

4155
export interface IsolatedEnv {
4256
configDir: string;

‎packages/e2e-tests/src/paired-session-replay.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ async function driveTrailingBlankLane(
818818

819819
export async function runPairedTrailingBlankSequenceReplay(): Promise<TrailingBlankSequenceReplayResult> {
820820
const config = {
821-
execute_threshold_percentage: 95,
821+
execute_threshold_percentage: 90,
822822
memory: { auto_search: { enabled: false } },
823823
compressor: { enabled: false },
824824
};
@@ -898,7 +898,7 @@ export async function runPairedSessionReplay(options: {
898898
modelID: arm.model_id,
899899
modelContextLimit: 200_000,
900900
magicContextConfig: {
901-
execute_threshold_percentage: 95,
901+
execute_threshold_percentage: 90,
902902
memory: { auto_search: { enabled: false } },
903903
compressor: { enabled: false },
904904
},
@@ -909,7 +909,7 @@ export async function runPairedSessionReplay(options: {
909909
await harness.restart({
910910
rust: true,
911911
magicContextConfig: {
912-
execute_threshold_percentage: 95,
912+
execute_threshold_percentage: 90,
913913
memory: { auto_search: { enabled: false } },
914914
compressor: { enabled: false },
915915
},

‎packages/e2e-tests/tests/rust-paired-session-replay.test.ts‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,40 @@
22

33
import { describe, expect, it } from "bun:test";
44
import {
5+
type PairedReplayResult,
56
runPairedSessionReplay,
67
runPairedTrailingBlankSequenceReplay,
78
} from "../src/paired-session-replay";
89
import { rustPrereqs } from "../src/rust-scenario-support";
910

11+
const DIVERGENCE_AXES = [
12+
"empty_content_shapes",
13+
"dropped_placeholder_shapes",
14+
"reasoning_signature_shapes",
15+
"tool_pairing_shapes",
16+
] as const;
17+
18+
function namedDivergences(result: PairedReplayResult, unadjudicatedOnly = false): string[] {
19+
return result.passes.flatMap((pass) =>
20+
DIVERGENCE_AXES.flatMap((axis) => {
21+
const valueSpace = pass[axis];
22+
if (valueSpace.classification !== "divergent_value_space") return [];
23+
if (unadjudicatedOnly && valueSpace.adjudication !== undefined) return [];
24+
return [`${pass.pass}:${axis}`];
25+
}),
26+
);
27+
}
28+
1029
describe.skipIf(!rustPrereqs.ok)("TS/Rust paired-session wire replay", () => {
1130
it("keeps the H13 empty, dropped-placeholder, and signed-thinking value spaces aligned", async () => {
1231
const result = await runPairedSessionReplay({ providerID: "anthropic" });
1332

14-
expect(result.divergence_count).toBe(3);
15-
expect(result.unadjudicated_divergence_count).toBe(0);
33+
expect(namedDivergences(result)).toEqual([
34+
"isolated-assistant-dropped-placeholder:reasoning_signature_shapes",
35+
"raw-empty-assistant-text:reasoning_signature_shapes",
36+
"observe-empty-and-placeholder:reasoning_signature_shapes",
37+
]);
38+
expect(namedDivergences(result, true)).toEqual([]);
1639
expect(result.passes).toHaveLength(4);
1740
for (const pass of result.passes) {
1841
expect(pass.empty_content_shapes.classification).toBe("matched_value_space");
@@ -52,8 +75,8 @@ describe.skipIf(!rustPrereqs.ok)("TS/Rust paired-session wire replay", () => {
5275
it("keeps MC-synthetic non-Anthropic sentinels non-empty in both lanes", async () => {
5376
const result = await runPairedSessionReplay({ providerID: "mock-anthropic" });
5477

55-
expect(result.unadjudicated_divergence_count).toBe(0);
56-
expect(result.divergence_count).toBe(0);
78+
expect(namedDivergences(result)).toEqual([]);
79+
expect(namedDivergences(result, true)).toEqual([]);
5780
for (const pass of result.passes) {
5881
expect(pass.empty_content_shapes).toEqual({
5982
classification: "matched_value_space",
@@ -74,8 +97,8 @@ describe.skipIf(!rustPrereqs.ok)("TS/Rust paired-session wire replay", () => {
7497
const result = await runPairedSessionReplay({ providerArm: "openai-responses" });
7598

7699
expect(result.wire_family).toBe("openai_responses");
77-
expect(result.unadjudicated_divergence_count).toBe(0);
78-
expect(result.divergence_count).toBe(0);
100+
expect(namedDivergences(result)).toEqual([]);
101+
expect(namedDivergences(result, true)).toEqual([]);
79102
expect(result.passes).toHaveLength(2);
80103
for (const pass of result.passes) {
81104
expect(pass.empty_content_shapes.classification).toBe("matched_value_space");

‎packages/plugin/src/hooks/magic-context/tag-messages-whitespace.test.ts‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,29 @@ describe("whitespace-only assistant tag transition", () => {
168168
}
169169
});
170170

171+
it("does not move an inert thinking-frame prefix onto a newly appended post-step blank", () => {
172+
const db = openTestDb();
173+
const sessionId = "ses-whitespace-late-post-step";
174+
insertTag(db, sessionId, "assistant-late:p0", "message", 1, 6);
175+
markWhitespaceAssistantTagInert(db, sessionId, 6, "assistant-late:p0");
176+
const message = assistant(
177+
"assistant-late",
178+
[
179+
{ type: "thinking", thinking: "signed", signature: "sig" },
180+
{ type: "step-finish" },
181+
{ type: "text", text: "" },
182+
],
183+
sessionId,
184+
);
185+
const tagger = createTagger();
186+
tagger.initFromDb(sessionId, db);
187+
188+
tagMessages(sessionId, [message], tagger, db);
189+
190+
expect(textOf(message, 2)).toBe("");
191+
expect(tagger.getTag(sessionId, "assistant-late:p2", "message")).toBeUndefined();
192+
});
193+
171194
it("mints a fresh tag when real text reaches an ordinal formerly occupied by inert whitespace", () => {
172195
const db = openTestDb();
173196
const sessionId = "ses-whitespace-remap-real";

‎packages/plugin/src/hooks/magic-context/tag-messages.ts‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,19 @@ export function tagMessages(
657657
sessionId,
658658
contentId,
659659
);
660-
const inertForThisPart =
661-
inertWhitespaceTagsByMessage.get(messageId)?.[whitespaceRank]?.tagNumber;
660+
const rankedInertTag =
661+
inertWhitespaceTagsByMessage.get(messageId)?.[whitespaceRank];
662+
// Reuse a retired whitespace tag only at its original part index or
663+
// next to a thinking part, where whitespace is provider framing. A
664+
// blank added after a completed step must remain untagged instead of
665+
// inheriting an older prefix.
666+
const canReplayRankedTag =
667+
rankedInertTag?.partIndex === partIndex ||
668+
isThinkingPart(message.parts[partIndex - 1]) ||
669+
isThinkingPart(message.parts[partIndex + 1]);
670+
const inertForThisPart = canReplayRankedTag
671+
? rankedInertTag?.tagNumber
672+
: undefined;
662673
whitespaceRank += 1;
663674
if (inertForThisPart !== undefined) {
664675
// Bind by rank, bypassing the ordinal fallback: after a remap the

0 commit comments

Comments
 (0)