Skip to content

test: [de-fork] trace-golden e2e harness (session trace as behavioral oracle)#1015

Open
anandgupta42 wants to merge 4 commits into
mainfrom
defork/trace-golden-e2e
Open

test: [de-fork] trace-golden e2e harness (session trace as behavioral oracle)#1015
anandgupta42 wants to merge 4 commits into
mainfrom
defork/trace-golden-e2e

Conversation

@anandgupta42

@anandgupta42 anandgupta42 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

PINEAPPLE

Summary

A novel integration-test technique for de-fork stages S5 (native/plugin tool parity) and S7 (validator continuation): drive a real headless session with a scripted model, capture the trace it emits, normalize out nondeterminism, and partial-order-match it against a committed golden. Test infra only — no product-code change.

Explicitly NOT a security oracle: tracing is best-effort/failure-suppressing and TraceSpan has no deny state, so an absent span is not proof of non-execution. (S3's HardPolicy uses an independent audit probe instead.) This harness corroborates observable behavior only.

  • normalize.ts — versioned allowlist-projection normalizer; every field classified stable-keep / volatile-drop / volatile-canonicalize; throws on an unknown field so schema drift surfaces. Structural, timing-independent sibling ranking; callId uniqueness canonicalized; loop-summary hashes stripped structurally; realpath-variant path scrubbing (no macOS /private<HOME> leak).
  • match.ts — partial-order structural diff; concurrent siblings compared as an unordered multiset via full canonical signature.
  • driver.ts — drives a real opencode run subprocess against the fork's own TestLLMServer.
  • trace-golden.test.ts — 34 tests; each reviewed correctness fix has a describe block that fails on revert. Missing golden fails unless TRACE_GOLDEN_UPDATE=1 (rejected under CI). Scenario auto-discovery.
  • stability-check.ts — 100/100 independent subprocess runs → 1 unique hash.
  • fixtures/real-traces/ — 8 benign smoke-session traces (PONG/BANANA/6×7; no PII, only model-version strings) pinning the normalizer against real schema shapes.

This went through three review rounds (a Codex technique review + a Codex code review + my verification) that took it from a plausible-but-flawed oracle → concurrency-safe → 7 correctness blockers fixed. All verified.

Test Plan

  • bun test test/altimate/trace-golden/: 34 pass / 0 fail (verified).
  • stability-check.ts: 100/100 runs, 1 unique hash, matches golden.
  • bun run typecheck: clean.

The CI wiring that runs the live subprocess test lands in a combined "wire de-fork CI checks" follow-up (that ci.yml region is co-edited by a sibling stage).

Checklist

  • Tests added/updated
  • Documentation updated (technique doc)
  • CHANGELOG updated — N/A (internal test infra)

Closes #1012


Summary by cubic

Adds a trace-golden E2E harness for de-fork S5 (tool parity) and S7 (validator continuation). Runs a real headless opencode run session with a scripted model, normalizes the trace, and partial-order-matches it to a committed golden to catch behavioral drift. Wired into CI; test infra only, no product code changes. Not a security oracle.

  • New Features

    • normalize.ts: versioned allowlist projection; drops/canonicalizes volatile fields; rejects unknown keys; stable sibling ranking; path scrubbing.
    • match.ts: partial-order structural diff with unordered multiset compare for concurrent siblings.
    • driver.ts + trace-golden.test.ts: launch real opencode CLI against TestLLMServer; auto-discover scenarios; update goldens via TRACE_GOLDEN_UPDATE=1; 35 tests. stability-check.ts: 100/100 runs produce one normalized hash.
  • Bug Fixes

    • Sanitized fixture home paths to /home/developer/... for portability.
    • stability-check.ts: validate CONCURRENCY like RUNS and fail early on bad input.
    • CI: added test/altimate/trace-golden/ to SUBPROCESS_PATHS so the live golden test runs in the subprocess pass.
    • normalize.ts: narrowed temp-path canonicalization to only mkdtemp-style random tails (preserves distinct stable prefixes; supports / and \) to avoid false matches.
    • Scenario runner: resolve placeholders in prompt and setup files (not just model-script.json) to prevent leaking literal placeholders into the CLI.

Written for commit b89b4ad. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added end-to-end “trace-golden” validation for scripted sessions, including deterministic trace normalization and structural golden comparisons.
    • Added a new smoke scenario with representative trace fixtures (success, tool calls, and crash/interrupt cases).
    • Added a stability check that re-runs scenarios in isolated subprocesses to confirm golden consistency.
  • Documentation
    • Expanded trace-golden documentation, including comparison expectations, normalization rules, and guidance for reviewing and updating goldens.
  • Testing
    • Introduced an automated subprocess scenario driver and improved diff output for trace mismatches.

… oracle)

A novel integration-test technique for de-fork stages S5 (native/plugin tool
parity) and S7 (validator continuation): drive a real headless session with a
scripted model, capture the trace it emits, normalize out nondeterminism, and
partial-order-match it against a committed golden. Test infra only — no
product-code change.

Explicitly NOT a security oracle: tracing is best-effort/failure-suppressing
and TraceSpan has no deny state, so an absent span is not proof of
non-execution (S3's HardPolicy uses an independent audit probe instead). This
harness corroborates observable behavior only.

- `normalize.ts` — versioned allowlist-projection normalizer; every field
  classified stable-keep/volatile-drop/volatile-canonicalize; throws on an
  unknown span/trace field so schema drift surfaces. Structural, timing-
  independent sibling ranking (tool-call siblings under a generation collapse
  to one concurrent bucket; root-attached tools keep real ranks). callId
  uniqueness canonicalized; loop-summary hashes stripped structurally;
  realpath-variant path scrubbing (no macOS `/private<HOME>` leak).
- `match.ts` — partial-order structural diff; concurrent siblings compared as
  an unordered multiset via full canonical signature.
- `driver.ts` — drives a real `opencode run` subprocess against the fork's own
  `TestLLMServer`, recovering the trace path from the CLI's `trace_saved` event.
- `trace-golden.test.ts` — 34 tests; each of the reviewed correctness fixes has
  a describe block that fails on revert. Missing golden fails unless
  `TRACE_GOLDEN_UPDATE=1` (rejected under CI). Scenario auto-discovery.
- `stability-check.ts` — drives the smoke scenario through N independent
  subprocess runs; verified 100/100 → 1 unique hash.
- `fixtures/real-traces/` — 8 benign smoke-session traces (PONG/BANANA/etc.;
  no PII) that pin the normalizer against real schema shapes.

Test Plan:
- `bun test test/altimate/trace-golden/`: 34 pass, 0 fail.
- `stability-check.ts`: 100/100 runs, 1 unique hash, matches golden.
- `bun run typecheck`: clean.

NOTE: the CI wiring that runs the live subprocess test lands in a combined
"wire de-fork CI checks" follow-up (that ci.yml region is co-edited by a
sibling stage).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@claude claude 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.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@github-actions

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a trace-golden E2E harness that drives real headless CLI sessions, captures traces, normalizes nondeterministic data, partially matches span topology, compares committed goldens, and validates stability across repeated isolated runs.

Changes

Trace-golden verification

Layer / File(s) Summary
Driver workflow and contracts
docs/internal/2026-07-18-trace-golden-e2e-technique.md, packages/opencode/test/altimate/trace-golden/DRIVER-NOTES.md, packages/opencode/test/altimate/trace-golden/driver.ts
Documents the trace-golden method and implements scripted LLM/tool turns, real CLI execution, trace_saved discovery, and trace loading.
Deterministic trace normalization
packages/opencode/test/altimate/trace-golden/normalize.ts
Projects supported trace fields, canonicalizes span topology and identifiers, scrubs dynamic values and paths, and produces stable output.
Partial-order trace matching
packages/opencode/test/altimate/trace-golden/match.ts
Compares normalized traces while preserving ordered siblings and matching concurrent rank-tied subtrees by canonical signatures.
Scenario corpus and regression suite
packages/opencode/test/altimate/trace-golden/fixtures/real-traces/*, packages/opencode/test/altimate/trace-golden/scenarios/smoke/*, packages/opencode/test/altimate/trace-golden/trace-golden.test.ts, .github/workflows/ci.yml
Adds real trace fixtures, a smoke scenario, golden update policy, normalization and matching tests, schema-drift checks, CI wiring checks, and live subprocess golden comparisons.
Repeated stability verification
packages/opencode/test/altimate/trace-golden/stability-check.ts, packages/opencode/test/altimate/trace-golden/DRIVER-NOTES.md
Adds repeated isolated runs, concurrency-limited execution, normalized hashing, golden comparison, and stability reporting.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Scenario
  participant CliFixture
  participant LocalLLM
  participant OpenCodeCLI
  participant Trace
  participant Normalizer
  participant Matcher
  Scenario->>CliFixture: load prompt, setup files, and scripted turns
  CliFixture->>LocalLLM: serve deterministic responses
  CliFixture->>OpenCodeCLI: run headless session
  OpenCodeCLI->>Trace: save trace file
  Trace-->>CliFixture: emit trace_saved path
  CliFixture->>Normalizer: normalize captured trace
  Normalizer->>Matcher: provide normalized trace
  Matcher-->>Scenario: report golden diffs
Loading

Possibly related PRs

Poem

I’m a rabbit with traces tucked tight,
Golden hops through the test-suite night.
Paths turn stable, spans align,
Tool calls dance in ordered time.
One hundred runs, one hash to share—
A carrot of proof in the burrow air!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements the trace-golden harness, normalization, matching, driver, scenarios, and docs required by #1012.
Out of Scope Changes check ✅ Passed The changes stay within test infra, docs, fixtures, and CI wiring and do not introduce unrelated product behavior.
Title check ✅ Passed The title clearly summarizes the new trace-golden end-to-end harness and matches the main change.
Description check ✅ Passed The description covers the issue, change summary, verification, and checklist; only the template headings are not followed exactly.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch defork/trace-golden-e2e

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

1 similar comment
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/opencode/test/altimate/trace-golden/driver.ts (2)

42-48: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use Effect.fn/Effect.fnUntraced and fail via the Effect channel.

driveScenario is a public, traceable effect and pushTurn an internal helper; per guidelines these should be Effect.fn("Driver.driveScenario") and Effect.fnUntraced. Two related idiom points:

  • pushTurn (Line 44) throw new Error(...) executes during generator evaluation and surfaces as a defect, not a typed failure — prefer failing through the Effect channel for consistency with Line 80.
  • Line 80 uses yield* Effect.fail(new Error(...)); a Schema.TaggedErrorClass yielded directly (yield* new DriveError(...)) would align with the typed-error guideline.

As per coding guidelines: "Use Effect.fn(\"Domain.method\") for named/traced effects and Effect.fnUntraced for internal helpers" and "prefer yield* new MyError(...) over yield* Effect.fail(new MyError(...))".

Also applies to: 63-66, 80-86

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/test/altimate/trace-golden/driver.ts` around lines 42 - 48,
Convert the public driveScenario effect to Effect.fn("Driver.driveScenario") and
the internal pushTurn helper to Effect.fnUntraced. Replace pushTurn’s thrown
missing-toolName error with an Effect-channel failure, and update the related
error path around line 80 to yield the DriveError instance directly rather than
wrapping it with Effect.fail.

Source: Coding guidelines


11-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer the FileSystem.FileSystem service over raw node:fs/promises for effectful I/O.

Reading the trace here goes through Effect.tryPromise(() => fs.readFile(...)); yielding FileSystem.FileSystem keeps the read inside the Effect environment (testable, mockable, uniform error channel) rather than dropping to a platform API.

As per coding guidelines: "Prefer FileSystem.FileSystem instead of raw fs/promises for effectful file I/O".

Also applies to: 90-93

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/test/altimate/trace-golden/driver.ts` around lines 11 - 16,
Replace the raw node:fs/promises dependency and its Effect.tryPromise read in
the trace-loading flow with the Effect FileSystem.FileSystem service. Update the
relevant Effect environment requirements and use the service’s file-read
operation so I/O remains injectable and errors stay in the Effect channel,
including the additional occurrence around the trace read at the referenced
later section.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_2e819da4cffeMhWRAOCOslv3mp.json`:
- Around line 32-40: Sanitize the recorded trace fixture by replacing every
occurrence of the developer-specific /Users/anandgupta/... path with the generic
/home/developer/... equivalent throughout the entire fixture, including all
referenced path locations. Do not alter other trace content.

In `@packages/opencode/test/altimate/trace-golden/stability-check.ts`:
- Around line 225-229: Validate CONCURRENCY in main alongside RUNS before
discovering scenarios or starting the pool, rejecting non-finite values and
values below 1 with a clear stability-check error that includes the invalid
value. Keep the existing RUNS validation and downstream runPool behavior
unchanged.

In `@packages/opencode/test/altimate/trace-golden/trace-golden.test.ts`:
- Around line 171-183: Replace the manual temporary-directory scaffolding with
the tmpdir fixture in all three sites:
packages/opencode/test/altimate/trace-golden/trace-golden.test.ts lines 171-183
and 193-202, and lines 903-948. In each test, use await using tmp = await
tmpdir() from fixture/fixture.ts, remove mkdtempSync/try-finally/rmSync cleanup,
and create the symlink target under the fixture path in the realpath test;
preserve each test’s existing assertions and behavior.

---

Nitpick comments:
In `@packages/opencode/test/altimate/trace-golden/driver.ts`:
- Around line 42-48: Convert the public driveScenario effect to
Effect.fn("Driver.driveScenario") and the internal pushTurn helper to
Effect.fnUntraced. Replace pushTurn’s thrown missing-toolName error with an
Effect-channel failure, and update the related error path around line 80 to
yield the DriveError instance directly rather than wrapping it with Effect.fail.
- Around line 11-16: Replace the raw node:fs/promises dependency and its
Effect.tryPromise read in the trace-loading flow with the Effect
FileSystem.FileSystem service. Update the relevant Effect environment
requirements and use the service’s file-read operation so I/O remains injectable
and errors stay in the Effect channel, including the additional occurrence
around the trace read at the referenced later section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3f64e5f0-8452-4731-a59a-2041eea93f87

📥 Commits

Reviewing files that changed from the base of the PR and between 8a50ec7 and 337144a.

📒 Files selected for processing (19)
  • docs/internal/2026-07-18-trace-golden-e2e-technique.md
  • packages/opencode/test/altimate/trace-golden/DRIVER-NOTES.md
  • packages/opencode/test/altimate/trace-golden/driver.ts
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_0c832d792ffeGW44jvnbD1ofca.json
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_0c9a811f7ffeVHtkexaP3SKoMg.json
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_0dfeccc49ffetVwiuQmrDKxNxh.json
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_0e3a95d6bffexTX5KtOaS4FOT9.json
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_0e3f286e5ffeGgjTZeBHqhT14w.json
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_0fb0d89c3ffemtOM9qTPAFNZyK.json
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_2e819da4cffeMhWRAOCOslv3mp.json
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_2e81c7baeffeaz1CvDUlNzeL4Y.json
  • packages/opencode/test/altimate/trace-golden/match.ts
  • packages/opencode/test/altimate/trace-golden/normalize.ts
  • packages/opencode/test/altimate/trace-golden/scenarios/smoke/golden.json
  • packages/opencode/test/altimate/trace-golden/scenarios/smoke/model-script.json
  • packages/opencode/test/altimate/trace-golden/scenarios/smoke/prompt.json
  • packages/opencode/test/altimate/trace-golden/scenarios/smoke/setup.json
  • packages/opencode/test/altimate/trace-golden/stability-check.ts
  • packages/opencode/test/altimate/trace-golden/trace-golden.test.ts

Comment thread packages/opencode/test/altimate/trace-golden/stability-check.ts
Comment thread packages/opencode/test/altimate/trace-golden/trace-golden.test.ts Outdated
const ciYml = fsSync.readFileSync(ciYmlPath, "utf-8")
const subprocessPathsLine = ciYml.split("\n").find((line) => line.includes("SUBPROCESS_PATHS="))
expect(subprocessPathsLine).toBeDefined()
expect(subprocessPathsLine).toContain("test/altimate/trace-golden/")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CRITICAL: This assertion will fail on merge of this PR.

.github/workflows/ci.yml:150 defines SUBPROCESS_PATHS without test/altimate/trace-golden/, and this PR does not modify ci.yml. The PR description explicitly defers that wiring to a sibling stage: "The CI wiring that runs the live subprocess test lands in a combined 'wire de-fork CI checks' follow-up (that ci.yml region is co-edited by a sibling stage)."

Unlike the live cliIt.live(...) scenarios below, this test is a plain test(...) — it is NOT gated by OPENCODE_SKIP_SUBPROCESS=1, so it executes in the MAIN CI test pass and fails there the moment this PR merges, before the follow-up lands. The local bun test run cited in the Test Plan (34 pass / 0 fail) must not have included this describe block, or it would have caught this.

Either land the ci.yml change in this PR (it is a one-line edit to the same SUBPROCESS_PATHS string), gate this test on the wiring actually being present, or move it into the follow-up PR that adds the wiring.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Incremental Pass (commit e40d0d1b89b4ad) — 4 files, no new issues

The new commit b89b4ad38 narrows the temp-subdir canonicalizer, extends placeholder resolution to every scenario input, and tightens the regression coverage — all verified clean:

  • normalize.ts:594TMP_SUBDIR_PATTERN rewritten from /(<TMP>)\/[^\/"'\s]+/ (collapse the entire first segment under <TMP>) to /(<TMP>[\/\\][^/\\"'\s]*?[-_.])[A-Za-z0-9]{6,}(?=[/\\"'\s]|$)/ (collapse ONLY the ≥6-char base62 tail that follows a caller delimiter). Replacement token renamed <TMPDIR><RAND> to match the narrower semantics. Verified sound: the non-greedy prefix + delimiter anchor + 6-char lower bound + separator/EOL lookahead correctly matches POSIX mkdtemp 6-char random tails (e.g. diffverify-CGXm4a) on both / and \ (Windows) separators while preserving short stable names (<TMP>/input-a stays distinct from <TMP>/input-b). Runs strictly after path scrubbing produces the literal <TMP>, so it remains a no-op on text that never carried a temp path.
  • stability-check.ts:91-93resolvePlaceholders(...) now wraps prompt and setup parsing (previously only script was wrapped). Real correctness fix matching trace-golden.test.ts: a <HOME> in prompt.json or a setup-file content now reaches the CLI as the real fixture home instead of the literal placeholder. The locally-defined resolvePlaceholders (line 61) is recursive over strings/arrays/objects.
  • trace-golden.test.ts:958-986 — updated the existing mkdtemp-canonicalization test to match the new behavior (<TMP>/diffverify-<RAND>/newfile.txt) and added a counterpart regression test asserting that stable directory names directly under the temp root (input-a vs input-b) stay distinct after normalization.
  • trace-golden.test.ts:1072-1090 — same resolvePlaceholders extension to prompt + setup as stability-check.ts, with an inline comment explaining why every fixture input must be resolved.
  • driver.ts:89-97 — documentation-only KNOWN LIMITATION block describing why a blanket pending === 0 && misses === [] assertion isn't added now (real CLI runs make auxiliary title/summary generations a scenario script legitimately doesn't cover). No code-logic change.

No new issues introduced by these changes.

Files Reviewed (4 files)
  • packages/opencode/test/altimate/trace-golden/driver.ts — doc-only KNOWN LIMITATION note (clean)
  • packages/opencode/test/altimate/trace-golden/normalize.ts — TMP_SUBDIR regex narrowed to random-tail-only (clean)
  • packages/opencode/test/altimate/trace-golden/stability-check.ts — placeholder resolution extended to prompt + setup (clean)
  • packages/opencode/test/altimate/trace-golden/trace-golden.test.ts — updated expectations + new stable-name regression test + placeholder resolution (clean)
Previous Review Summaries (3 snapshots, latest commit e40d0d1)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit e40d0d1)

Status: No Issues Found | Recommendation: Merge

Incremental Pass (commit 516eb68e40d0d1) — 4 files, prior CRITICAL resolved

The new commit e40d0d15 lands the one-line ci.yml edit the prior CRITICAL (trace-golden.test.ts:1022) was blocking on, plus a determinism hardening and a test refactor — all verified clean:

  • .github/workflows/ci.yml:150 — appended test/altimate/trace-golden/ to SUBPROCESS_PATHS. The plain test(...) assertion expect(subprocessPathsLine).toContain("test/altimate/trace-golden/") now passes in the main CI pass. Prior CRITICAL resolved.
  • normalize.ts:593 — added TMP_SUBDIR_PATTERN = /(<TMP>)\/[^\/\"'\s]+/g applied last in scrubDynamicTokens(), collapsing the first path segment under an already-scrubbed <TMP> to <TMPDIR>. Handles per-run-random mkdtemp suffixes a tool creates directly under the OS temp root (<TMP>/diffverify-<rand>/…) that survive <TMP> prefix scrubbing. Verified sound: runs strictly after path scrubbing produces the literal <TMP>, the character class bounds the match to a single segment, and it is a no-op on text that never carried a temp path.
  • trace-golden.test.ts — refactored two discoverScenarios tests from mkdtempSync + try/finally to await using tmp = await tmpdir() (AsyncDisposable; cleanup guaranteed on throw, including the symlinked-temp-dir case via fs.realpath). This addresses the prior coderabbit "Adopt the tmpdir convention" advisory. Added a matching regression test (diffverify-CGXm4a vs Zq9T1p normalize identically to <TMP>/<TMPDIR>/newfile.txt). Logic verified: default tmpRoots is [os.tmpdir()], so path scrubbing yields <TMP>/diffverify-<rand>/newfile.txt, then TMP_SUBDIR_PATTERN collapses to <TMP>/<TMPDIR>/newfile.txt. ✓
  • driver.ts:21 & trace-golden.test.ts:1034 — documentation-only additions describing known limitations (single-tool-per-turn schema can't yet produce concurrent-sibling topology; S5 native→plugin parity needs a route sentinel). No code-logic change.

No new issues introduced by these changes.

Files Reviewed (4 files)
  • .github/workflows/ci.yml — SUBPROCESS_PATHS wired (prior CRITICAL resolved)
  • packages/opencode/test/altimate/trace-golden/driver.ts — doc-only limitation note (clean)
  • packages/opencode/test/altimate/trace-golden/normalize.ts — TMP_SUBDIR canonicalizer + scrub pass (clean)
  • packages/opencode/test/altimate/trace-golden/trace-golden.test.ts — tmpdir refactor + TMP_SUBDIR regression test (clean)

Previous review (commit 516eb68)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 0
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
packages/opencode/test/altimate/trace-golden/trace-golden.test.ts 1008 Unresolved — verified against HEAD 516eb68. The plain test(...) at line 1003–1009 asserts SUBPROCESS_PATHS in .github/workflows/ci.yml contains test/altimate/trace-golden/. ci.yml is still unmodified by this PR (confirmed: zero diff on .github/workflows/ci.yml since 337144a), and this assertion is NOT gated by cliIt.live/OPENCODE_SKIP_SUBPROCESS=1, so it executes in the MAIN CI test pass and fails the moment this PR merges, before the deferred ci.yml follow-up lands. Either land the one-line ci.yml edit in this PR, gate this assertion on the wiring being present, or move it into the follow-up PR.
Incremental Pass (commit 337144a516eb68) — 3 files, no new issues

This commit addressed two prior advisory findings from other reviewers; both fixes verified clean:

  • fixtures/real-traces/ses_2e819da4cffeMhWRAOCOslv3mp.json & ses_2e81c7baeffeaz1CvDUlNzeL4Y.json — sanitized all /Users/anandgupta/... developer-home paths to generic /home/developer/.... Grep confirms no anandgupta or /Users/ remnants remain under fixtures/. PII leak closed.
  • stability-check.ts:227 — added CONCURRENCY validity guard mirroring the existing RUNS guard (!Number.isFinite || < 1). Sound: a 0/NaN CONCURRENCY previously caused runPool to spawn no workers and crash downstream in outcomes.filter/avgMs reduce; now fails fast with a clear message.

No new issues introduced by these changes.

Files Reviewed (4 files)
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_2e819da4cffeMhWRAOCOslv3mp.json — sanitized (clean)
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/ses_2e81c7baeffeaz1CvDUlNzeL4Y.json — sanitized (clean)
  • packages/opencode/test/altimate/trace-golden/stability-check.ts — CONCURRENCY guard added (clean)
  • packages/opencode/test/altimate/trace-golden/trace-golden.test.ts — unchanged; carried-forward CRITICAL at L1008 re-verified

Fix these issues in Kilo Cloud

Previous review (commit 337144a)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 0
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
packages/opencode/test/altimate/trace-golden/trace-golden.test.ts 1008 Newly-added SUBPROCESS_PATHS assertion fails on this PR — ci.yml is unmodified and the test is not gated by cliIt.live/OPENCODE_SKIP_SUBPROCESS=1, so it runs in the MAIN CI pass and fails on merge. PR description defers the ci.yml wiring to a sibling follow-up.
Files Reviewed (5 source files; 11 JSON scenarios/fixtures + 2 docs skimmed)
  • packages/opencode/test/altimate/trace-golden/trace-golden.test.ts — 1 issue
  • packages/opencode/test/altimate/trace-golden/normalize.ts — clean
  • packages/opencode/test/altimate/trace-golden/match.ts — clean
  • packages/opencode/test/altimate/trace-golden/driver.ts — clean
  • packages/opencode/test/altimate/trace-golden/stability-check.ts — clean
  • packages/opencode/test/altimate/trace-golden/scenarios/smoke/{golden,model-script,prompt,setup}.json — data, reviewed for shape consistency
  • packages/opencode/test/altimate/trace-golden/fixtures/real-traces/*.json — data
  • docs/internal/2026-07-18-trace-golden-e2e-technique.md, DRIVER-NOTES.md — docs

Fix these issues in Kilo Cloud


Reviewed by glm-5.2 · Input: 67.6K · Output: 14.5K · Cached: 1.1M

Review guidance: REVIEW.md from base branch main

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 337144a789

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const ciYml = fsSync.readFileSync(ciYmlPath, "utf-8")
const subprocessPathsLine = ciYml.split("\n").find((line) => line.includes("SUBPROCESS_PATHS="))
expect(subprocessPathsLine).toBeDefined()
expect(subprocessPathsLine).toContain("test/altimate/trace-golden/")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add the trace-golden suite to the subprocess CI pass

The current .github/workflows/ci.yml main pass sets OPENCODE_SKIP_SUBPROCESS=1, while its SUBPROCESS_PATHS assignment does not include test/altimate/trace-golden/. Consequently the live golden scenario is skipped, and this ordinary test(...) assertion itself fails in the main pass on every CI run. Include this directory in the workflow's subprocess pass as part of this commit rather than relying on an unspecified follow-up.

Useful? React with 👍 / 👎.

3. **Normalize** out nondeterminism (timestamps, spanIds, costs, abs paths, durations, host).
4. **Diff the normalized span topology** against a committed golden.

A change in observable behavior = a diff in the golden. A tool moving from native→plugin (S5) that changes nothing observable produces an identical golden. A `DROP DATABASE` that should be blocked produces a `hard_policy_denied` span — the deny is **in the trace**, so the golden proves enforcement end-to-end, through whatever route the session took, not just at the unit that implements it.

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 Badge Remove the nonexistent denial-span guarantee

For an S3/HardPolicy scenario, this states that a hard_policy_denied span exists and proves enforcement, but the correction at the top of this document and src/altimate/observability/tracing.ts establish that spans only have ok | error status and permission denials emit no such event. The later S3 stage-hook section repeats this impossible assertion, so following the specification could incorrectly treat the trace as a security oracle; rewrite these remaining claims to require the independent audit probe and dispatcher counters.

Useful? React with 👍 / 👎.

Comment on lines +21 to +26
/** One scripted assistant turn: either plain text (session ends) or a tool call (session continues). */
export interface ScriptedTurn {
readonly kind: "text" | "tool"
readonly text?: string
readonly toolName?: string
readonly toolInput?: unknown

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Support multiple tool calls in one scripted turn

For any scenario intended to exercise concurrent sibling tool calls, this schema can represent only one tool call per assistant turn, and pushTurn invokes llm.tool(...), which queues a separate reply().tool(...) response for every array element. Thus two adjacent tool entries become two generations with singleton tool children rather than one generation dispatching multiple calls, so the live harness cannot exercise the concurrent topology that the partial-order matcher and planned S7 concurrency scenarios are meant to protect. Add a grouped/multi-tool turn representation and queue all calls in one Reply.

Useful? React with 👍 / 👎.

Comment on lines +620 to +624
function replaceAllPrefixed(text: string, root: string, placeholder: string): string {
if (!root) return text
const normalizedRoot = root.endsWith(path.sep) ? root.slice(0, -1) : root
if (!normalizedRoot) return text
return text.split(normalizedRoot).join(placeholder)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Canonicalize generated temporary-directory names

When a traced tool uses mkdtemp or otherwise emits a randomized directory directly below the OS temp root, this replacement only changes the prefix and leaves the random component intact; for example the committed fixture ses_0e3f286e5ffeGgjTZeBHqhT14w.json:72 becomes <TMP>/diffverify-CGXm/newfile.txt, so an equivalent later run with another suffix produces a different golden. The driver supplies only fixture.home and cannot enumerate temp directories created by tools, so scenarios involving such tools will flap unless generated temp-directory components are canonicalized as well.

Useful? React with 👍 / 👎.

Comment on lines +404 to +405
function toolContentKey(span: TraceSpan): string {
return `${span.kind} ${span.name} ${stableStringify(span.input ?? null)} ${stableStringify(span.output ?? null)}`

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 Badge Scrub volatile content before assigning concurrent ordinals

When concurrent same-rank tool calls have the same name/input and outputs containing run-random IDs or paths before a stable distinguishing suffix, this key sorts their raw, unsanitized values even though normalizeSpan scrubs those values later. A different random prefix can therefore reverse which logical call receives each DFS ordinal, making equivalent normalized traces and stability hashes differ. Build the ordering key from the same scrubbed representation used in the normalized spans rather than from the raw trace payload.

Useful? React with 👍 / 👎.

Comment on lines +1082 to +1085
const golden = yield* readJson<NormalizedTrace>(goldenPath)
const matchResult = match(golden, actual)
if (!matchResult.pass) {
return yield* Effect.fail(new Error(matchResult.format()))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Require a dispatcher sentinel for S5 scenarios

For an S5 native-to-plugin migration, this generic scenario runner accepts a scenario solely when its normalized trace matches the golden. The design document explicitly notes that native and plugin routes produce identical traces and therefore requires an independent dispatcher sentinel, but neither the scenario schema nor this pass path checks one. A migration that accidentally continues invoking the old native implementation will consequently pass its advertised parity gate; require and validate a route-specific sentinel for S5 scenarios before accepting the trace match.

Useful? React with 👍 / 👎.

@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.

1 issue found across 19 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/opencode/test/altimate/trace-golden/stability-check.ts">

<violation number="1" location="packages/opencode/test/altimate/trace-golden/stability-check.ts:150">
P2: `checkScenario` at line 149 reads `goldenPath` unconditionally with no existence check. If `golden.json` is missing (e.g., for a newly discovered scenario directory), this produces a raw ENOENT or JSON parse error instead of a clear message. Consider a guard similar to `resolveGoldenAction` in the test file to produce a helpful error like: "golden.json not found — run with TRACE_GOLDEN_UPDATE=1 first".</violation>
</file>

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

const overallStart = Date.now()

const goldenPath = path.join(dir, "golden.json")
const golden = JSON.parse(await fs.readFile(goldenPath, "utf-8")) as NormalizedTrace

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: checkScenario at line 149 reads goldenPath unconditionally with no existence check. If golden.json is missing (e.g., for a newly discovered scenario directory), this produces a raw ENOENT or JSON parse error instead of a clear message. Consider a guard similar to resolveGoldenAction in the test file to produce a helpful error like: "golden.json not found — run with TRACE_GOLDEN_UPDATE=1 first".

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/test/altimate/trace-golden/stability-check.ts, line 150:

<comment>`checkScenario` at line 149 reads `goldenPath` unconditionally with no existence check. If `golden.json` is missing (e.g., for a newly discovered scenario directory), this produces a raw ENOENT or JSON parse error instead of a clear message. Consider a guard similar to `resolveGoldenAction` in the test file to produce a helpful error like: "golden.json not found — run with TRACE_GOLDEN_UPDATE=1 first".</comment>

<file context>
@@ -0,0 +1,265 @@
+  const overallStart = Date.now()
+
+  const goldenPath = path.join(dir, "golden.json")
+  const golden = JSON.parse(await fs.readFile(goldenPath, "utf-8")) as NormalizedTrace
+  const goldenHash = stableStringify(golden)
+
</file context>

Comment thread packages/opencode/test/altimate/trace-golden/stability-check.ts
Comment thread packages/opencode/test/altimate/trace-golden/trace-golden.test.ts
…ONCURRENCY

- Two `real-traces/` fixtures contained a developer's `/Users/anandgupta/...`
  home path (PII + CI-portability risk). Replaced with `/home/developer/...`
  throughout — the fixtures are used only for normalizer idempotency (normalize
  twice, compare), so the content swap doesn't affect any assertion (CodeRabbit).
- `stability-check.ts` now validates `CONCURRENCY` the same way as `RUNS`
  (`Number.isFinite && >= 1`), so a bad env/arg fails with a clear message
  instead of `runPool` spawning zero workers and crashing downstream (CodeRabbit).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

2 similar comments
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 516eb684c5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

function scrubText(text: string, entries: RootEntry[]): string {
let out = text
for (const { root, placeholder } of entries) out = replaceAllPrefixed(out, root, placeholder)
return scrubDynamicTokens(out)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve stable values in tool payloads

Because every string in span inputs and outputs flows through this function, behavioral values that merely resemble trace bookkeeping are erased. For example, a finops tool changing its result from $10 to $20, or a configuration read changing 500ms to 1000ms, normalizes both versions to the same payload, so the golden can pass despite a user-visible regression. Restrict cost/duration scrubbing to generated summary fields such as the root output and narrative rather than arbitrary tool/model content.

Useful? React with 👍 / 👎.


for (const [name, content] of Object.entries(setup.files ?? {})) {
yield* Effect.tryPromise({
try: () => fs.writeFile(path.join(fixture.home, name), content, "utf-8"),

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 Badge Create parent directories for setup files

When a scenario needs a nested fixture such as models/orders.sql or .opencode/config.json, its parent directory does not yet exist and fs.writeFile fails with ENOENT before the CLI session runs. The stability runner repeats the same direct-write behavior, so such scenarios cannot be exercised by either advertised path; create each destination's parent directories recursively first.

Useful? React with 👍 / 👎.

Comment on lines +695 to +696
if (span.input !== undefined) out.input = scrubPaths(span.input, entries)
if (span.output !== undefined) out.output = scrubPaths(span.output, entries)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Canonicalize derived multi-tool generation fields

When one assistant generation dispatches multiple tools, Tracer.logToolCall appends both generationToolCalls and pendingToolResults as each tool completes, and logStepFinish serializes that completion order into the generation output and the next generation input. A scheduling flip therefore changes these fields even though the normalizer correctly treats the sibling tool spans as an unordered concurrent group, causing equivalent concurrent runs to mismatch or produce different stability hashes. Canonicalize these derived multi-tool fields from the child spans rather than preserving their completion-ordered strings.

Useful? React with 👍 / 👎.

return fsSync
.readdirSync(dir, { withFileTypes: true })
.filter((e) => e.isDirectory())
.filter((e) => REQUIRED_FILES.every((f) => fsSync.existsSync(path.join(dir, e.name, f))))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Fail on incomplete scenario directories

When a newly committed scenario omits any listed file, this filter silently removes it from both the live suite and the stability runner, so CI passes without exercising the scenario at all. This also affects scenarios created from the technique document's documented shape (prompt.json + model-script.json + golden.json), which does not include setup.json; treat absent setup as empty or register an explicit failure for incomplete directories instead of excluding them.

Useful? React with 👍 / 👎.

function pushTurn(llm: CliFixture["llm"], turn: ScriptedTurn): Effect.Effect<void> {
if (turn.kind === "tool") {
if (!turn.toolName) throw new Error("driveScenario: tool turn missing toolName")
return llm.tool(turn.toolName, turn.toolInput ?? {})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Assign unique call IDs across scripted turns

When a scenario contains tool calls in multiple assistant turns, each invocation of llm.tool(...) constructs a new Reply, whose private sequence restarts at zero, so every turn emits call_1. The normalizer deliberately preserves duplicate-ID equality as a continuation-correctness signal, meaning a multi-turn S7 golden will encode artificial duplicate call IDs and cannot detect whether the real flow maintains distinct IDs. Allow the script to supply IDs or allocate them monotonically across the whole driven session.

Useful? React with 👍 / 👎.

…dir determinism, tmpdir convention

- CRITICAL (fails on merge): the plain `test(...)` asserting ci.yml's
  SUBPROCESS_PATHS includes `test/altimate/trace-golden/` runs in the MAIN CI
  pass but the branch tip didn't wire that path, so it would fail the moment
  this PR merged. Add `test/altimate/trace-golden/` to SUBPROCESS_PATHS in
  ci.yml — the assertion now passes AND the live golden scenario actually runs
  in the bounded subprocess pass where it belongs (it spawns a real CLI + mock
  LLM). Makes the PR self-contained instead of deferring to a sibling stage.

- Temp-dir determinism (normalize.ts): a tool that creates its own scratch dir
  directly under the OS temp root (`mkdtemp` -> `$TMPDIR/diffverify-<rand>/`)
  left a per-run-random segment behind after `<TMP>` prefix scrubbing, so any
  future live scenario touching such a tool would flap on the random suffix.
  Add TMP_SUBDIR_PATTERN to canonicalize the first path segment under `<TMP>`
  to `<TMPDIR>` (any dir a tool makes there is inherently per-run) — keeps
  nested paths stable. +1 unit test (two different suffixes normalize equal).

- tmpdir() convention (Major): the 3 manual `mkdtempSync` + `try/finally rmSync`
  scaffolds now use `await using tmp = await tmpdir()` (test/fixture/fixture.ts)
  with automatic per-test cleanup, per test/AGENTS.md.

- Documented two known limitations tied to scenario types not shipped in this PR
  (per YAGNI — the guardrails land WITH the first such scenario, not before one
  exists): driver.ts's single-tool-per-turn schema can't yet generate S7
  concurrent-sibling topology end-to-end; and the generic scenario runner needs a
  per-route dispatcher sentinel for S5 native->plugin parity (trace-match alone
  can't distinguish identical native/plugin routes).

PII: fixture home paths already sanitized on the branch tip (verified no
`/Users/...` remains). 34 pass / 1 skip / 0 fail, typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

1 similar comment
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e40d0d15b3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// there is inherently per-run, so collapsing it keeps nested paths (`.../newfile.txt`)
// deterministic instead of flapping on the random suffix. Runs AFTER path scrubbing has
// produced the literal `<TMP>`, so it is a no-op on text that never carried a temp path.
const TMP_SUBDIR_PATTERN = /(<TMP>)\/[^\/"'\s]+/g

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve stable names directly below the temp root

When a scenario intentionally uses a stable temp path, this pattern replaces its first component unconditionally rather than only canonicalizing generated directory names. For example, tool payloads containing /tmp/input-a and /tmp/input-b both normalize to <TMP>/<TMPDIR>, so a behavioral regression that changes which fixed file is accessed can still match the golden. Restrict this replacement to recognizable randomized mkdtemp names or explicitly registered generated directories.

Useful? React with 👍 / 👎.

// there is inherently per-run, so collapsing it keeps nested paths (`.../newfile.txt`)
// deterministic instead of flapping on the random suffix. Runs AFTER path scrubbing has
// produced the literal `<TMP>`, so it is a no-op on text that never carried a temp path.
const TMP_SUBDIR_PATTERN = /(<TMP>)\/[^\/"'\s]+/g

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 Badge Match Windows separators when canonicalizing temp directories

On Windows, replacing os.tmpdir() leaves paths such as <TMP>\diffverify-CGXm\newfile.txt, but this regex recognizes only /. Any scenario whose tool creates a randomized directory under the Windows temp root therefore retains the random suffix and can produce a different stability hash on every run; accept both path separators when applying this canonicalization.

Useful? React with 👍 / 👎.

Comment on lines +84 to +87
const result = yield* fixture.opencode.run(options.prompt, {
...options.runOpts,
format: "json",
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Require exact consumption of scripted model turns

When the session exits before consuming every queued turn—precisely the failure mode an S7 continuation scenario is meant to catch—opencode.run still succeeds and driveScenario never checks fixture.llm.pending; conversely, an unexpected extra generation receives TestLLMServer's automatic "ok" fallback and is only recorded as a miss. During initial golden creation or an explicit update, either case can self-approve a trace that did not execute the declared script, so assert that no queued responses or unmatched requests remain before returning.

Useful? React with 👍 / 👎.

Comment on lines +754 to +758
const topTools = trace.summary.topTools
?.map((t) => ({ name: t.name, count: t.count }))
// count desc (real signal) then name asc (deterministic tiebreak) — the raw topTools array ties
// on Map-insertion order, which is completion order and therefore not reproducible (tracing.ts:1332).
.sort((a, b) => b.count - a.count || a.name.localeCompare(b.name))

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 Badge Stabilize top-tool membership before truncation

When more than ten tool names tie at the cutoff, this only sorts the ten entries already selected by Trace.enrichSummary. That producer sorts by count alone and then calls .slice(0, 10), so ties retain the tool-span Map insertion order, which is concurrent completion order; equivalent runs with eleven one-shot concurrent tools can therefore omit different names and produce different normalized hashes. Apply a stable name tiebreak before the producer truncates, or avoid treating an ambiguously truncated list as deterministic.

Useful? React with 👍 / 👎.

Comment on lines +1050 to +1053
const { prompt } = yield* readJson<{ prompt: string }>(path.join(scenarioDir, "prompt.json"))
const setup = yield* readJson<{ files?: Record<string, string> }>(path.join(scenarioDir, "setup.json"))
const scriptRaw = yield* readJson<ScriptedTurn[]>(path.join(scenarioDir, "model-script.json"))
const script = resolvePlaceholders(scriptRaw, fixture.home)

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 Badge Resolve home placeholders across every scenario fixture

Only model-script.json is passed through resolvePlaceholders, while the prompt and setup-file contents are used verbatim. A scenario that writes configuration such as a plugin path containing <HOME>/plugin.ts, or places <HOME> in its prompt, therefore sends the literal placeholder to the real CLI; the live test and stability runner both reproduce the same broken setup rather than exercising the intended fixture. Resolve the prompt and setup object with the fixture home as well.

Useful? React with 👍 / 👎.

…anon + full placeholder resolution

- normalize.ts temp-dir canonicalization was too broad: it collapsed the ENTIRE first
  segment under `<TMP>` to `<TMPDIR>`, so distinct STABLE names (`<TMP>/input-a` vs
  `<TMP>/input-b`) mapped to the same placeholder — a regression that swapped which fixed
  file a tool touched would still match the golden (codex). Narrow TMP_SUBDIR_PATTERN to
  canonicalize ONLY a recognizable mkdtemp random tail (`<delimiter><>=6 base62>`), preserving
  the stable prefix, and accept `\` as well as `/` so it also fires on the Windows temp root
  (codex). +1 test that two stable names stay distinct; existing random-suffix test updated.

- Fixture placeholder resolution: only `model-script.json` was passed through
  resolvePlaceholders, so a scenario with `<HOME>` in its prompt or a setup file sent the
  literal placeholder to the real CLI — and both the live test and stability-check.ts
  reproduced the same broken setup (codex). Resolve prompt + setup as well, in both runners.

- Documented the script-consumption gap (codex): TestLLMServer exposes `pending`/`misses`,
  but a blanket exact-consumption assertion would flake on a real CLI's auxiliary
  (title/summary) generations, so that guard belongs per-scenario with the first S7
  continuation scenario, not as a blanket gate. 35 pass / 1 skip / 0 fail, typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

2 similar comments
@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@github-actions

Copy link
Copy Markdown

👋 This PR was automatically closed by our quality checks.

Common reasons:

  • New GitHub account with limited contribution history
  • PR description doesn't meet our guidelines
  • Contribution appears to be AI-generated without meaningful review

If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b89b4ad38b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// regression that swaps which fixed file a tool touches still diffs — while killing the flap on a
// genuinely random `mkdtemp` tail. Both `/` and `\` (Windows temp root) separators are accepted.
// Runs AFTER path scrubbing produced the literal `<TMP>`, so it is a no-op on non-temp text.
const TMP_SUBDIR_PATTERN = /(<TMP>[/\\][^/\\"'\s]*?[-_.])[A-Za-z0-9]{6,}(?=[/\\"'\s]|$)/g

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Limit temp random-tail matching to generated names

When a scenario uses stable temp directories whose names contain a delimiter followed by six or more alphanumeric characters, this regex incorrectly treats the stable suffix as random; for example, <TMP>/input-orders/data and <TMP>/input-customers/data both become <TMP>/input-<RAND>/data, allowing a wrong-path regression to match the golden. Fresh evidence for the previously raised stable-name concern is the current {6,} matcher, while its negative test covers only the one-character suffixes input-a and input-b; restrict canonicalization to explicitly known/generated directories or another signal that distinguishes actual random tails.

Useful? React with 👍 / 👎.

},
"output": {
"parts": 4,
"content": "You are powered by the model named claude-sonnet-4-6. The exact model ID is anthropic/claude-sonnet-4-6\nHere is some useful information about the environment you are running in:\n<env>\n Working directory: /home/developer/codebase/altimate-code/.claude/worktrees/openui/packages/opencode\n Workspace root folder: /home/developer/codebase/altimate-code/.claude/worktrees/openui\n Is directory a git repo: yes\n Platform: darwin\n Today's date: Sun Mar 22 2026\n</env>\n<directories>\n \n</directories>\n\nSkills provide specialized instructions and workflows for specific tasks.\nUse the skill tool to load a skill when a task matches its description.\n<available_skills>\n <skill>\n <name>teach</name>\n <description>Teach your AI teammate a pattern by showing it an example file from your codebase</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/teach/SKILL.md</location>\n </skill>\n <skill>\n <name>training-status</name>\n <description>Show what your AI teammate has learned — patterns, rules, glossary, and standards</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/training-status/SKILL.md</location>\n </skill>\n <skill>\n <name>pii-audit</name>\n <description>Classify schema columns for PII (SSN, email, phone, name, address, credit card) and check whether queries expose them. Use for GDPR/CCPA/HIPAA compliance audits.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/pii-audit/SKILL.md</location>\n </skill>\n <skill>\n <name>cost-report</name>\n <description>Analyze Snowflake query costs and identify optimization opportunities</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/cost-report/SKILL.md</location>\n </skill>\n <skill>\n <name>data-viz</name>\n <description>Build modern, interactive data visualizations and dashboards using code-based component libraries (shadcn/ui, Recharts, Tremor, Nivo, D3, Victory, visx). Use this skill whenever the user asks to visualize data, build dashboards, create analytics views, chart metrics, tell a data story, build a reporting interface, create KPI cards, plot graphs, or explore a dataset — even if they mention PowerBI, Tableau, Streamlit, Metabase, Looker, Grafana, or similar tools. Also trigger when the user says \"make a dashboard\", \"show me the data\", \"chart this\", \"visualize trends\", \"build an analytics page\", \"data story\", or anything involving turning raw data into interactive visual interfaces. If the task involves presenting data visually — this is the skill. Always prefer building a real, interactive, code-based UI over exporting to or recommending a BI platform.\n</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/data-viz/SKILL.md</location>\n </skill>\n <skill>\n <name>sql-review</name>\n <description>Pre-merge SQL quality gate — lint 26 anti-patterns, grade readability/performance A-F, validate syntax, and scan for injection threats. Use before committing or reviewing SQL changes.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/sql-review/SKILL.md</location>\n </skill>\n <skill>\n <name>dbt-troubleshoot</name>\n <description>Debug dbt errors — compilation failures, runtime database errors, test failures, wrong data, and performance issues. Use when something is broken, producing wrong results, or failing to build. Powered by altimate-dbt.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/dbt-troubleshoot/SKILL.md</location>\n </skill>\n <skill>\n <name>altimate-setup</name>\n <description>Configure Altimate platform credentials for datamate and API access</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/altimate-setup/SKILL.md</location>\n </skill>\n <skill>\n <name>dbt-docs</name>\n <description>Document dbt models and columns in schema.yml with business context — model descriptions, column definitions, and doc blocks. Use when adding or improving documentation for discoverability. Powered by altimate-dbt.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/dbt-docs/SKILL.md</location>\n </skill>\n <skill>\n <name>dbt-analyze</name>\n <description>Analyze downstream impact of dbt model changes using column-level lineage and the dependency graph. Use when evaluating the blast radius of a change before shipping. Powered by altimate-dbt.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/dbt-analyze/SKILL.md</location>\n </skill>\n <skill>\n <name>lineage-diff</name>\n <description>Compare column-level lineage between two versions of a SQL query to show added, removed, and changed data flow edges.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/lineage-diff/SKILL.md</location>\n </skill>\n <skill>\n <name>dbt-develop</name>\n <description>Create and modify dbt models — staging, intermediate, marts, incremental, medallion architecture. Use when building new SQL models, extending existing ones, scaffolding YAML configs, or reorganizing project structure. Powered by altimate-dbt.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/dbt-develop/SKILL.md</location>\n </skill>\n <skill>\n <name>train</name>\n <description>Train your AI teammate on team standards from a document or style guide</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/train/SKILL.md</location>\n </skill>\n <skill>\n <name>sql-translate</name>\n <description>Translate SQL queries between database dialects (Snowflake, BigQuery, PostgreSQL, MySQL, etc.)</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/sql-translate/SKILL.md</location>\n </skill>\n <skill>\n <name>schema-migration</name>\n <description>Analyze DDL migrations for data loss risks — type narrowing, missing defaults, dropped constraints, breaking column changes. Use before applying schema changes to production.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/schema-migration/SKILL.md</location>\n </skill>\n <skill>\n <name>query-optimize</name>\n <description>Analyze and optimize SQL queries for better performance</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/query-optimize/SKILL.md</location>\n </skill>\n <skill>\n <name>dbt-test</name>\n <description>Add schema tests, unit tests, and data quality checks to dbt models. Use when validating data integrity, adding test definitions to schema.yml, writing unit tests, or practicing test-driven development in dbt. Powered by altimate-dbt.</description>\n <location>file:///home/developer/codebase/altimate-code/.claude/worktrees/openui/.opencode/skills/dbt-test/SKILL.md</location>\n </skill>\n</available_skills>\n\n## Altimate Knowledge\n\nKnowledge from previous sessions and team training. Apply it consistently.\n\n### Learned Rules\n_Always follow these rules. They were taught by the user through corrections and explicit instruction._\n\n#### no-positional-group-by (applied 24x)\n## Never use positional GROUP BY\n\n**Rule:** Always use explicit column names in GROUP BY. Never use positional references (`GROUP BY 1, 2, 3`).\n\n**Why:** Positional GROUP BY is fragile. Adding, removing, or reordering a SELECT column silently shifts which columns are grouped — the query still runs but produces wrong aggregations with no error.\n\n**Wrong:**\n```sql\nselect\n order_date,\n order_channel,\n sum(revenue) as revenue\nfrom orders\ngroup by 1, 2\n```\n\n**Right:**\n```sql\nselect\n order_date,\n order_channel,\n sum(revenue) as revenue\nfrom orders\ngroup by order_date, order_channel\n```\n\n**Edge case — computed expressions:** When grouping by an expression (e.g. `date_trunc`, `date_part`), repeat the full expression in GROUP BY rather than using a positional alias:\n\n```sql\n-- Wrong\nselect date_trunc('month', order_date) as month, sum(revenue)\nfrom orders\ngroup by 1\n\n-- Right\nselect date_trunc('month', order_date) as month, sum(revenue)\nfrom orders\ngroup by date_trunc('month', order_date)\n```\n\n**Applies to:** All SQL written in dbt models, ad-hoc queries, CTEs, subqueries, and window function PARTITION BY clauses.\n\n\nInstructions from: /home/developer/codebase/altimate-code/.claude/worktrees/openui/packages/opencode/AGENTS.md\n# opencode database guide\n\n## Database\n\n- **Schema**: Drizzle schema lives in `src/**/*.sql.ts`.\n- **Naming**: tables and columns use snake*case; join columns are `<entity>_id`; indexes are `<table>*<column>\\_idx`.\n- **Migrations**: generated by Drizzle Kit using `drizzle.config.ts` (schema: `./src/**/*.sql.ts`, output: `./migration`).\n- **Command**: `bun run db generate --name <slug>`.\n- **Output**: creates `migration/<timestamp>_<slug>/migration.sql` and `snapshot.json`.\n- **Tests**: migration tests should read the per-folder layout (no `_journal.json`).\n\n# opencode Effect guide\n\nInstructions to follow when writing Effect.\n\n## Schemas\n\n- Use `Schema.Class` for data types with multiple fields.\n- Use branded schemas (`Schema.brand`) for single-value types.\n\n## Services\n\n- Services use `ServiceMap.Service<ServiceName, ServiceName.Service>()(\"@console/<Name>\")`.\n- In `Layer.effect`, always return service implementations with `ServiceName.of({ ... })`, never a plain object.\n\n## Errors\n\n- Use `Schema.TaggedErrorClass` for typed errors.\n- For defect-like causes, use `Schema.Defect` instead of `unknown`.\n- In `Effect.gen`, prefer `yield* new MyError(...)` over `yield* Effect.fail(new MyError(...))` for direct early-failure branches.\n\n## Effects\n\n- Use `Effect.gen(function* () { ... })` for composition.\n- Use `Effect.fn(\"ServiceName.method\")` for named/traced effects and `Effect.fnUntraced` for internal helpers.\n- `Effect.fn` / `Effect.fnUntraced` accept pipeable operators as extra arguments, so avoid unnecessary `flow` or outer `.pipe()` wrappers.\n\n## Time\n\n- Prefer `DateTime.nowAsDate` over `new Date(yield* Clock.currentTimeMillis)` when you need a `Date`.\n\n## Errors\n\n- In `Effect.gen/fn`, prefer `yield* new MyError(...)` over `yield* Effect.fail(new MyError(...))` for direct early-failure branches.\n"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove recorded user-training content from fixtures

This committed trace contains the complete session system prompt, including a learned rule explicitly described as having been taught through user corrections, its application count, the installed internal skill catalog, and local worktree/configuration details; the same disclosure appears in ses_2e819da4cffeMhWRAOCOslv3mp.json. Shipping raw session-specific training data as a supposedly benign smoke fixture exposes information unrelated to the test to every repository reader, so replace these payloads with synthetic or comprehensively sanitized content.

Useful? React with 👍 / 👎.

/** Recursively replaces absolute-path prefixes anywhere inside a JSON-cloneable value with placeholders. */
function scrubPaths(value: unknown, entries: RootEntry[]): unknown {
if (typeof value === "string") return scrubText(value, entries)
if (Array.isArray(value)) return value.map((v) => scrubPaths(v, entries))

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 Badge Sort fingerprint tags before preserving payload arrays

When environment-fingerprint skill selection is enabled and the working directory differs from the worktree root, src/altimate/fingerprint/index.ts:42-47 runs both directory scans concurrently, lets them append into one shared tags array, and preserves whichever completion order wins in the traced output.tags. This generic array mapping retains that race order, so identical sessions whose two directories contribute different tags can produce different normalized hashes and golden diffs; canonicalize this known set-like fingerprint field before comparison.

Useful? React with 👍 / 👎.

@anandgupta42

Copy link
Copy Markdown
Contributor Author

Review comments addressed (2 rounds)

Thanks to @chatgpt-codex-connector, @coderabbitai, and @kilo-code-bot.

Round 1 — e40d0d15b3

  • CRITICAL (would fail on merge): the plain test() asserting ci.yml's SUBPROCESS_PATHS includes test/altimate/trace-golden/ runs in the main CI pass, but the path wasn't wired. Added it — the assertion passes and the live golden scenario now actually runs in the bounded subprocess pass.
  • Temp-dir determinism, await using tmpdir() convention across the 3 temp sites, PII sanitization (verified no /Users/... remains).

Round 2 — b89b4ad38b

  • Temp-dir canonicalization was too broad (codex): it collapsed the entire first segment under <TMP>, so distinct stable names (<TMP>/input-a vs input-b) mapped to the same placeholder — a regression that swapped which fixed file a tool touched would still match the golden. Narrowed to canonicalize only a recognizable mkdtemp random tail, and made it accept \ for the Windows temp root. +stable-name-preservation test.
  • Fixture placeholder resolution (codex): only model-script.json was resolved, so <HOME> in a prompt/setup file reached the CLI literally — fixed in both the live runner and stability-check.ts.

Deferred (documented at the site): blanket exact script-consumption assertion (would flake on a real CLI's auxiliary title/summary generations — belongs per-scenario with the first S7 continuation scenario) and the top-tool tie-break (producer-side, latent). 35 pass / 1 skip, typecheck clean.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@anandgupta42 Thanks for the thorough follow-up. The CI subprocess wiring, narrowed temp-directory canonicalization with stable-name coverage, and complete <HOME> placeholder resolution address the concerns I raised.

Deferring exact script-consumption checks until the first S7 continuation scenario—and leaving the producer-side top-tool tie-break as documented latent work—sounds appropriately scoped. Nice work validating this with 35 passing tests, one skip, and clean type checking.

🐇✨


✏️ Learnings added
Learnt from: anandgupta42
URL: https://github.com/AltimateAI/altimate-code/pull/1015

Timestamp: 2026-07-20T02:26:59.710Z
Learning: In `packages/opencode/test/altimate/trace-golden/normalize.ts`, temporary-directory canonicalization must preserve distinct stable names under `<TMP>` and only normalize recognizable random `mkdtemp` tails; the behavior must also support Windows-style `\` temp-root paths.

Learnt from: anandgupta42
URL: https://github.com/AltimateAI/altimate-code/pull/1015

Timestamp: 2026-07-20T02:26:59.710Z
Learning: Trace-golden scenario fixture `<HOME>` placeholders must be resolved consistently in `prompt.json`, `setup.json`, and `model-script.json` by both the live trace-golden runner and `packages/opencode/test/altimate/trace-golden/stability-check.ts`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

De-fork e2e: trace-golden harness (session trace as behavioral snapshot oracle)

1 participant