Skip to content

test: session utilities — isDefaultTitle, fromRow/toRow, createObservationMask#540

Closed
anandgupta42 wants to merge 1 commit intomainfrom
test/hourly-20260328-1020
Closed

test: session utilities — isDefaultTitle, fromRow/toRow, createObservationMask#540
anandgupta42 wants to merge 1 commit intomainfrom
test/hourly-20260328-1020

Conversation

@anandgupta42
Copy link
Copy Markdown
Contributor

@anandgupta42 anandgupta42 commented Mar 28, 2026

What does this PR do?

Adds 17 new tests covering two previously untested modules in the session subsystem. These were identified via automated test discovery as having zero test coverage despite containing non-trivial logic that directly affects user-facing behavior.

1. Session.isDefaultTitle and Session.fromRow/toRowsrc/session/index.ts (9 new tests)

These utility functions handle session identity and database serialization. Zero tests existed. A field mapping bug in fromRow would silently corrupt session data — e.g., dropping time_archived causes archived sessions to appear active, or null-coalescence logic in summary (where a single non-null column triggers object construction) could produce malformed summaries. New coverage includes:

  • isDefaultTitle regex matching for parent/child prefixes, rejection of partial matches, and edge cases (missing timestamp, extra suffix)
  • fromRow/toRow roundtrip with full field population (summary, share, revert, permission, timestamps)
  • fromRow null-to-undefined mapping: all-null summary columns → undefined summary object
  • fromRow partial summary: single non-null column triggers summary construction with zero-defaults

2. SessionCompaction.createObservationMasksrc/session/compaction.ts (8 new tests)

This function generates the text the LLM sees after a tool's output is pruned during context compaction. Bad formatting here means the LLM can't reconstruct what a tool previously did, causing it to re-run tools or hallucinate results in long sessions. Zero tests existed. New coverage includes:

  • Completed tool part with normal output: tool name, args summary, line count, byte size, first-line fingerprint
  • Empty output handling (no fingerprint, correct 0 B / 1 line counts)
  • Large output: correct KB/MB formatting thresholds via formatBytes
  • Surrogate pair safety: truncateArgs doesn't produce malformed UTF-16 when truncating near emoji boundaries
  • Pending, running, and error tool states: correct input extraction from each discriminated union variant

Type of change

  • New feature (non-breaking change which adds functionality)

Issue for this PR

N/A — proactive test coverage via automated test discovery

How did you verify your code works?

bun test test/session/session-utils.test.ts     # 9 pass
bun test test/session/observation-mask.test.ts   # 8 pass

Checklist

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for session utility functions and observation mask generation to improve code quality and reliability.

…ationMask

Add 17 tests covering two untested modules in the session subsystem:
session identity helpers and compaction observation masks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@claude claude bot left a comment

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 to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

📝 Walkthrough

Walkthrough

Two new test suites validate core session functionality: createObservationMask generates correct string representations for tool messages in various states (completed, running, error, pending) with proper formatting of output sizes and argument serialization, while session utilities verify title format validation and bidirectional serialization between Session.Info objects and database rows.

Changes

Cohort / File(s) Summary
Session Test Coverage
packages/opencode/test/session/observation-mask.test.ts, packages/opencode/test/session/session-utils.test.ts
Added comprehensive test suites for observation mask generation (testing multiple tool message states, Unicode handling, size formatting) and session utilities (testing title validation, row serialization roundtripping, and null value handling in summary fields).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Whiskers twitching with glee,
Test cases hop wild and free,
Observation masks shine,
Sessions serialize fine,
Code quality verified with care, you see!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main changes: adding tests for three key session utility functions (isDefaultTitle, fromRow/toRow, createObservationMask).
Description check ✅ Passed The PR description is comprehensive and covers all required template sections with detailed explanations of the changes, testing approach, and verification results.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 test/hourly-20260328-1020

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/opencode/test/session/session-utils.test.ts (1)

116-143: Optional: assert summary.diffs null-coalescing in partial-summary case.

You already verify numeric defaults; adding diffs assertion would lock in the null -> undefined contract for this path too.

Optional assertion
   expect(info.summary).toBeDefined()
   expect(info.summary!.additions).toBe(5)
   expect(info.summary!.deletions).toBe(0)
   expect(info.summary!.files).toBe(0)
+  expect(info.summary!.diffs).toBeUndefined()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/session/session-utils.test.ts` around lines 116 - 143,
In the "fromRow constructs summary when at least one summary column is non-null"
test, add an assertion to verify how null summary_diffs is normalized by
Session.fromRow: after constructing info via Session.fromRow(row as any), assert
info.summary!.diffs is undefined (e.g.,
expect(info.summary!.diffs).toBeUndefined()) so the test locks in the null ->
undefined contract for summary.diffs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/opencode/test/session/observation-mask.test.ts`:
- Around line 120-139: The surrogate-pair test currently doesn't assert that
truncation actually ran; update the test that calls
SessionCompaction.createObservationMask (the test using makeToolPart and
variable mask) to assert the truncation happened by checking for an ellipsis or
that the "after" suffix is removed (e.g., expect(mask).toContain("…") or
expect(mask).not.toContain("after")); keep the existing UTF-8 round-trip checks
but add this additional assertion so the truncation path is exercised and
verified.
- Around line 58-61: The pending-state fixture returned by makeToolPart
currently sets state: { status: "pending" } which violates the ToolStatePending
contract (missing required input and raw), and it hides the issue with a
force-cast to MessageV2.ToolPart; update makeToolPart so that when creating a
pending state (ToolStatePending) it includes the required fields (e.g., input
and raw with appropriate test values or nullability matching the schema) and
remove or replace the unsafe "as MessageV2.ToolPart" cast with a properly typed
return or a validated factory variant so the fixture matches the
ToolStatePending shape used by MessageV2.ToolPart.

---

Nitpick comments:
In `@packages/opencode/test/session/session-utils.test.ts`:
- Around line 116-143: In the "fromRow constructs summary when at least one
summary column is non-null" test, add an assertion to verify how null
summary_diffs is normalized by Session.fromRow: after constructing info via
Session.fromRow(row as any), assert info.summary!.diffs is undefined (e.g.,
expect(info.summary!.diffs).toBeUndefined()) so the test locks in the null ->
undefined contract for summary.diffs.
🪄 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: 5aa9453f-bd91-4af4-9acb-13679d18b838

📥 Commits

Reviewing files that changed from the base of the PR and between 9ba2114 and 7e64c74.

📒 Files selected for processing (2)
  • packages/opencode/test/session/observation-mask.test.ts
  • packages/opencode/test/session/session-utils.test.ts

Comment on lines +58 to +61
return {
...base,
state: { status: "pending" },
} as MessageV2.ToolPart
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify schema requirements for ToolStatePending and compare with test fixture shape.
rg -n -C3 'export const ToolStatePending|status:\s*z\.literal\("pending"\)|input:\s*z\.record|raw:\s*z\.string' --type=ts
rg -n -C3 'function makeToolPart|status:\s*"pending"|state:\s*\{\s*status:\s*"pending"' packages/opencode/test/session/observation-mask.test.ts

Repository: AltimateAI/altimate-code

Length of output: 3210


Pending-state fixture in makeToolPart does not match ToolStatePending schema contract.

The fixture at line 60 only sets status: "pending" but omits the required input and raw fields. The force-cast with as MessageV2.ToolPart bypasses type validation and can mask schema regressions.

Proposed fix
   return {
     ...base,
-    state: { status: "pending" },
+    state: {
+      status: "pending",
+      input: overrides.input ?? {},
+      raw: "",
+    },
   } as MessageV2.ToolPart
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return {
...base,
state: { status: "pending" },
} as MessageV2.ToolPart
return {
...base,
state: {
status: "pending",
input: overrides.input ?? {},
raw: "",
},
} as MessageV2.ToolPart
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/session/observation-mask.test.ts` around lines 58 -
61, The pending-state fixture returned by makeToolPart currently sets state: {
status: "pending" } which violates the ToolStatePending contract (missing
required input and raw), and it hides the issue with a force-cast to
MessageV2.ToolPart; update makeToolPart so that when creating a pending state
(ToolStatePending) it includes the required fields (e.g., input and raw with
appropriate test values or nullability matching the schema) and remove or
replace the unsafe "as MessageV2.ToolPart" cast with a properly typed return or
a validated factory variant so the fixture matches the ToolStatePending shape
used by MessageV2.ToolPart.

Comment on lines +120 to +139
test("truncates long args without breaking surrogate pairs", () => {
// Create input with a value containing emoji (surrogate pairs in JS)
// U+1F600 = 😀 is represented as \uD83D\uDE00 in UTF-16
const emoji = "😀"
// Build a value string where the emoji sits right near the truncation boundary
const padding = "a".repeat(70)
const part = makeToolPart({
tool: "write",
input: { content: padding + emoji + "after" },
})
const mask = SessionCompaction.createObservationMask(part)

// The mask should not contain a lone high surrogate
// Verify the args portion is well-formed by checking the whole mask is valid
expect(mask).toBeDefined()
// Ensure no lone surrogates by round-tripping through TextEncoder
const encoded = new TextEncoder().encode(mask)
const decoded = new TextDecoder().decode(encoded)
expect(decoded).toBe(mask)
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Surrogate-pair test does not prove truncation path is executed.

This test currently validates UTF-8 round-trip safety, but it can still pass when no truncation occurs. Add an assertion that truncation happened (e.g., ellipsis present / suffix removed).

Proposed strengthening
   test("truncates long args without breaking surrogate pairs", () => {
@@
-    const padding = "a".repeat(70)
+    const padding = "a".repeat(120)
@@
     const mask = SessionCompaction.createObservationMask(part)
@@
+    expect(mask).toContain("…")
+    expect(mask).not.toContain("after")
     // The mask should not contain a lone high surrogate
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test("truncates long args without breaking surrogate pairs", () => {
// Create input with a value containing emoji (surrogate pairs in JS)
// U+1F600 = 😀 is represented as \uD83D\uDE00 in UTF-16
const emoji = "😀"
// Build a value string where the emoji sits right near the truncation boundary
const padding = "a".repeat(70)
const part = makeToolPart({
tool: "write",
input: { content: padding + emoji + "after" },
})
const mask = SessionCompaction.createObservationMask(part)
// The mask should not contain a lone high surrogate
// Verify the args portion is well-formed by checking the whole mask is valid
expect(mask).toBeDefined()
// Ensure no lone surrogates by round-tripping through TextEncoder
const encoded = new TextEncoder().encode(mask)
const decoded = new TextDecoder().decode(encoded)
expect(decoded).toBe(mask)
})
test("truncates long args without breaking surrogate pairs", () => {
// Create input with a value containing emoji (surrogate pairs in JS)
// U+1F600 = 😀 is represented as \uD83D\uDE00 in UTF-16
const emoji = "😀"
// Build a value string where the emoji sits right near the truncation boundary
const padding = "a".repeat(120)
const part = makeToolPart({
tool: "write",
input: { content: padding + emoji + "after" },
})
const mask = SessionCompaction.createObservationMask(part)
expect(mask).toContain("…")
expect(mask).not.toContain("after")
// The mask should not contain a lone high surrogate
// Verify the args portion is well-formed by checking the whole mask is valid
expect(mask).toBeDefined()
// Ensure no lone surrogates by round-tripping through TextEncoder
const encoded = new TextEncoder().encode(mask)
const decoded = new TextDecoder().decode(encoded)
expect(decoded).toBe(mask)
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/session/observation-mask.test.ts` around lines 120 -
139, The surrogate-pair test currently doesn't assert that truncation actually
ran; update the test that calls SessionCompaction.createObservationMask (the
test using makeToolPart and variable mask) to assert the truncation happened by
checking for an ellipsis or that the "after" suffix is removed (e.g.,
expect(mask).toContain("…") or expect(mask).not.toContain("after")); keep the
existing UTF-8 round-trip checks but add this additional assertion so the
truncation path is exercised and verified.

anandgupta42 added a commit that referenced this pull request Mar 28, 2026
… fixes

Consolidates PRs #515, #526, #527, #528, #530, #531, #532, #533, #534,
#535, #536, #537, #538, #539, #540, #541, #542, #543 into a single PR.

Changes:
- 30 files changed, ~3000 lines of new test coverage
- Deduplicated redundant tests:
  - `copilot-compat.test.ts`: removed duplicate `mapOpenAICompatibleFinishReason`
    tests (already covered in `copilot/finish-reason.test.ts`)
  - `lazy.test.ts`: removed duplicate error-retry and `reset()` tests
  - `transform.test.ts`: kept most comprehensive version (#535) over
    subset PRs (#539, #541)
- Bug fixes from PR #528:
  - `extractEquivalenceErrors`: `null` entries in `validation_errors`
    crashed with TypeError (`null.message` throws before `??` evaluates).
    Fixed with optional chaining: `e?.message`
  - `extractSemanticsErrors`: same fix applied
  - Updated test from `expect(...).toThrow(TypeError)` to verify the fix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anandgupta42
Copy link
Copy Markdown
Contributor Author

Consolidated into #545

anandgupta42 added a commit that referenced this pull request Mar 28, 2026
… fixes (#545)

* test: MCP auth — URL validation, token expiry, and client secret lifecycle

Cover security-critical McpAuth functions (getForUrl, isTokenExpired) and
McpOAuthProvider.clientInformation() expiry detection that had zero test coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01CqcvvXp5hUVsNU441DFTwb

* test: copilot provider — finish reason mapping and tool preparation

Add 27 unit tests for three previously untested copilot SDK functions
that are critical to the GitHub Copilot provider integration path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: log-buffer, RWLock concurrency, SSE chunk splitting — 13 new tests

Cover three untested risk areas: dbt ring buffer overflow (ties to #249 TUI
corruption fix), reader-writer lock starvation ordering, and SSE event parsing
across chunk boundaries and abort signals.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01153R7Dh9BMKiarndEUraBk

* test: SQL tool formatters — check, equivalence, semantics (38 tests)

Export and test pure formatting functions across three SQL analysis tools
that had zero test coverage. Discovered a real bug: null entries in
validation_errors crash extractEquivalenceErrors (TypeError on null.message).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01Lz8zxrbwHXfsC2FbHxXZh9

* test: stats display + MCP OAuth XSS prevention — 26 new tests

Add first-ever test coverage for the `altimate-code stats` CLI output formatting
and the MCP OAuth callback server's HTML escaping (XSS prevention boundary).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: util — proxy detection and lazy error recovery

Add tests for proxied() corporate proxy detection (6 tests) and
lazy() error recovery + reset behavior (2 tests) to cover untested
code paths that affect package installation and initialization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01EDCRjjHdb1dWvxyAfrLuhw

* test: session compaction — observation mask and arg truncation

Cover createObservationMask() which generates the replacement text when old
tool outputs are pruned during session compaction. Tests verify format
correctness, UTF-8 byte counting, arg truncation with surrogate pair safety,
unserializable input handling, and fingerprint capping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01SHDrUNHjUpTwPvcjQcJ4ug

* test: bus — publish/subscribe/once/unsubscribe mechanics

Zero dedicated tests existed for the core event Bus that powers session updates,
permission prompts, file watcher notifications, and SSE delivery. New coverage
includes subscriber delivery, unsubscribe correctness, wildcard subscriptions,
type isolation, and Bus.once auto-removal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01GchE7rUZayV1ouLEseVndK

* test: lazy utility and credential-store — error retry, reset, sensitive field coverage

Cover untested behaviors in lazy() (error non-caching and reset) that power shell
detection, plus complete isSensitiveField unit coverage for BigQuery/SSL/SSH fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01WoqeutgfwXNcktweCKoLwd

* test: provider/transform — temperature, topP, topK, smallOptions, maxOutputTokens

Add 35 tests for five previously untested ProviderTransform functions that
control model-specific inference parameters for all users.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_014NGgCMNXEg4Nn3JCpzDg5w

* test: fingerprint + context — fill coverage gaps in core utilities

Add tests for Fingerprint.refresh() cache invalidation and dbt-packages tag
detection (both untested code paths), plus first-ever unit tests for the
Context utility (AsyncLocalStorage wrapper) used by every module.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01N8kgPYhXX7SrYnZKJLiTfC

* test: session todo — CRUD lifecycle with database persistence

Adds 6 tests for the Todo module (zero prior coverage). Covers insert/get round-trip,
position ordering, empty-array clear, replacement semantics, bus event emission, and
cross-session isolation. These guard the TUI todo panel against stale or phantom tasks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: finops recommendations + dbt manifest edge cases — 12 new tests

Cover untested recommendation logic in warehouse-advisor and credit-analyzer
edge cases in dbt manifest parsing that affect real-world dbt projects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01XhZy7vaqdasKH5hQ6H9ee3

* test: provider — sampling parameter functions (temperature, topP, topK)

Add 28 tests for ProviderTransform.temperature(), topP(), and topK() which
had zero direct test coverage. These pure functions control LLM sampling
behavior per model family and wrong values cause degraded output quality.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_011NoVCnMW9Kw6eh92ayU7GB

* test: session utilities — isDefaultTitle, fromRow/toRow, createObservationMask

Add 17 tests covering two untested modules in the session subsystem:
session identity helpers and compaction observation masks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: provider — temperature, topP, topK model parameter defaults

Add 30 unit tests for ProviderTransform.temperature(), topP(), and topK()
which are pure functions that return model-specific sampling defaults.
These functions are the sole source of per-model parameter configuration
and were previously untested, risking silent regressions when adding or
modifying model ID patterns (e.g., kimi-k2 sub-variants, minimax-m2
dot/hyphen variants).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01WZthZmQczd51XXSjhiABNH

* test: agent — .env read protection and analyst write denial

Verify security-relevant agent permission defaults: builder agent asks before
reading .env files (preventing accidental secret exposure), and analyst agent
denies file modification tools (edit/write/todowrite/todoread).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01Wp9YaEvw6jAAL73VVdXFxA

* test: docker discovery + copilot provider compatibility

Add 20 new tests covering two previously untested modules:

1. Docker container discovery (containerToConfig) — verifies correct
   ConnectionConfig shape generation from discovered containers
2. Copilot provider finish-reason mapping and response metadata —
   ensures OpenAI-compatible finish reasons are correctly translated
   and response timestamps are properly converted

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01J8xz7ijLjbzEe3mu7ajdWh

* test: consolidate 18 test PRs — 434 new tests, deduplicated, with bug fixes

Consolidates PRs #515, #526, #527, #528, #530, #531, #532, #533, #534,
#535, #536, #537, #538, #539, #540, #541, #542, #543 into a single PR.

Changes:
- 30 files changed, ~3000 lines of new test coverage
- Deduplicated redundant tests:
  - `copilot-compat.test.ts`: removed duplicate `mapOpenAICompatibleFinishReason`
    tests (already covered in `copilot/finish-reason.test.ts`)
  - `lazy.test.ts`: removed duplicate error-retry and `reset()` tests
  - `transform.test.ts`: kept most comprehensive version (#535) over
    subset PRs (#539, #541)
- Bug fixes from PR #528:
  - `extractEquivalenceErrors`: `null` entries in `validation_errors`
    crashed with TypeError (`null.message` throws before `??` evaluates).
    Fixed with optional chaining: `e?.message`
  - `extractSemanticsErrors`: same fix applied
  - Updated test from `expect(...).toThrow(TypeError)` to verify the fix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve typecheck errors in test files

- `prepare-tools.test.ts`: use template literal type for provider tool `id`
- `compaction-mask.test.ts`: use `as unknown as` for branded type casts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove flaky `setTimeout` in todo bus event test

`Bus.publish` is synchronous — the event is delivered immediately,
no 50ms delay needed. Removes resource contention risk in parallel CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address CodeRabbit review feedback

- `formatCheck`: harden validation error formatting against null entries
  using optional chaining and filter (CodeRabbit + GPT consensus)
- `extractEquivalenceErrors`: propagate extracted errors into
  `formatEquivalence` output to prevent title/output inconsistency
- `todo.test.ts`: use `tmpdir({ git: true })` + `await using` for
  proper test isolation instead of shared project root

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants