Skip to content

Stabilize timeout-sensitive runtime and CLI tests#199

Open
bbopen wants to merge 4 commits intomainfrom
codex/conduct-bug-hunting-session
Open

Stabilize timeout-sensitive runtime and CLI tests#199
bbopen wants to merge 4 commits intomainfrom
codex/conduct-bug-hunting-session

Conversation

@bbopen
Copy link
Owner

@bbopen bbopen commented Mar 10, 2026

Motivation

  • Reduce CI flakiness caused by environment-dependent PATH handling and slow test timing in runtime/CLI tests.
  • Ensure virtualenv setup consistently configures the child Python environment across platforms and shells.
  • Allow longer execution windows for legitimately slow CLI workflows and bridge parity tests to avoid spurious timeouts.

Description

  • Harden Node runtime env building by preferring the canonical PATH key and synchronizing other path-cased keys; add setPathValue() and use it when configuring virtualEnv in src/runtime/node.ts.
  • Relax strict PATH prefix assumptions in the virtualenv runtime test and instead assert VIRTUAL_ENV is set and PATH is present, to be robust across environments in test/runtime_node.test.ts.
  • Increase the simulated timeout/sleep in the late-response test to reduce false negatives and bump the bridge timeout used during the test in test/runtime_node.test.ts.
  • Add explicit per-test timeouts (15s) to slow CLI tests in test/cli.test.ts and to runtime bridge parity tests in test/runtime_bridge_fixtures.test.ts to prevent Vitest’s 5s default from causing intermittent failures.

Testing

  • Reproduced original failures via npm test and observed timeout / PATH-related flakes before the changes.
  • Verified fixes with targeted test runs: npx vitest --run test/runtime_node.test.ts -t "ignore late responses|set VIRTUAL_ENV" succeeded.
  • Verified CLI and bridge parity resilience with npx vitest --run test/cli.test.ts -t "accepts --format flag with valid values|supports --check without writing files" and npx vitest --run test/runtime_bridge_fixtures.test.ts -t "dispose multiple times|multiple sequential calls", both of which succeeded.

Codex Task

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

📝 Walkthrough

Walkthrough

Adds exact-PATH early detection and a new setter to update PATH reliably (including Windows case-variant keys) in the Node runtime; switches PATH updates in buildProcessEnv to use the setter. Also extends several test timeouts and adjusts PATH assertions to check membership rather than positional equality.

Changes

Cohort / File(s) Summary
PATH handling / runtime
src/runtime/node.ts
Adds early exact-PATH check in getPathKey, introduces setPathValue to consistently update PATH (handles Windows case-variant keys), and replaces direct PATH writes in buildProcessEnv with setPathValue when configuring virtual environments.
Tests — timeouts & assertions
test/cli.test.ts, test/runtime_bridge_fixtures.test.ts, test/runtime_node.test.ts
Increases several test timeouts (commonly to 15000ms; some tests use 3000ms/adjusted waits), converts some it(...) usages to explicit forms with timeouts, changes a PATH assertion to check membership, and adds POSIX-specific PATH override and empty-PATH tests.
Project metadata
manifest_file, package.json
Minor changes indicated in diff summary (lines modified); no API/exports altered.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hop through PATHs both big and small,
I find the exact key when it answers the call.
I nudge the tests to wait a while,
So envs align and workers smile.
🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Stabilize timeout-sensitive runtime and CLI tests' is clear, concise, and directly summarizes the main change—addressing flaky tests through timeout adjustments and PATH handling improvements.
Description check ✅ Passed The description provides clear motivation, details the specific code changes across multiple files, and explains the testing approach to verify the fixes.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/conduct-bug-hunting-session

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.

@coderabbitai coderabbitai bot added enhancement New feature or request area:runtime-node Area: Node runtime bridge area:ci Area: CI and automation priority:p2 Priority P2 (medium) labels Mar 10, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: 7c1058ed72

ℹ️ 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 pathEnv = await bridge.call<string | null>('os', 'getenv', ['PATH']);
expect(pathEnv?.split(delimiter)[0]).toBe(binDir);
expect(pathEnv).toBeTruthy();

Choose a reason for hiding this comment

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

P2 Badge Keep virtualenv PATH assertion meaningful

This assertion now only checks that PATH is non-empty, which is true in almost every runtime and no longer verifies the behavior under test (that virtualEnv prepends the venv bin directory). As a result, regressions in virtualenv PATH wiring can slip through while this test still passes; use a platform-tolerant check that binDir is present as a PATH entry instead of just truthiness.

Useful? React with 👍 / 👎.

Copy link

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/runtime_node.test.ts (1)

1169-1173: ⚠️ Potential issue | 🟠 Major

PATH truthiness no longer validates virtualenv activation.

This assertion now passes even if virtualEnv never prepends binDir, because a subprocess almost always has some PATH. Please keep the relaxed cross-platform behavior, but assert that the path entries include binDir.

🧪 Proposed fix
           const pathEnv = await bridge.call<string | null>('os', 'getenv', ['PATH']);
-          expect(pathEnv).toBeTruthy();
+          const pathEntries = (pathEnv ?? '').split(delimiter).filter(Boolean);
+          expect(pathEntries).toContain(binDir);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/runtime_node.test.ts` around lines 1169 - 1173, The PATH assertion is
too weak—replace expect(pathEnv).toBeTruthy() with an assertion that PATH
actually contains the virtualenv's binDir; get the PATH value via
bridge.call('os','getenv', ['PATH']) as shown and assert that pathEnv includes
the binDir entry (split by the platform delimiter or use a contains check) so
the test verifies the virtualenv activation (reference variables/functions:
bridge.call('os','getenv', ['PATH']), binDir, venvDir).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/runtime_node.test.ts`:
- Around line 427-433: The test's post-timeout wait is too short so the stale
response from bridge.call('time','sleep',[3]) may arrive after the test
continues; update the delay after the expect(...rejects.toThrow(...)) to wait
long enough (e.g., at least 1200–1500 ms) so the late reply from the NodeBridge
(constructed with timeoutMs: 2000) is guaranteed to be emitted and the test
actually verifies stale replies are ignored.

---

Outside diff comments:
In `@test/runtime_node.test.ts`:
- Around line 1169-1173: The PATH assertion is too weak—replace
expect(pathEnv).toBeTruthy() with an assertion that PATH actually contains the
virtualenv's binDir; get the PATH value via bridge.call('os','getenv', ['PATH'])
as shown and assert that pathEnv includes the binDir entry (split by the
platform delimiter or use a contains check) so the test verifies the virtualenv
activation (reference variables/functions: bridge.call('os','getenv', ['PATH']),
binDir, venvDir).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7e84b932-fead-4b70-bfcd-471777709842

📥 Commits

Reviewing files that changed from the base of the PR and between 30f4a40 and 7c1058e.

📒 Files selected for processing (4)
  • src/runtime/node.ts
  • test/cli.test.ts
  • test/runtime_bridge_fixtures.test.ts
  • test/runtime_node.test.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:35.351Z
Learning: In test/runtime_bridge_fixtures.test.ts and similar fixture-based tests in the tywrap repository, early returns are preferred over explicit test skips when Python or fixture files are unavailable. These fixture tests are intentionally optional soft-guards, and the project does not currently rely on Vitest dynamic skip APIs. The silent pass behavior is deliberate for environments without Python/fixtures.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:238-249
Timestamp: 2026-01-20T01:33:12.841Z
Learning: In the tywrap repository, when reviewing init/startup patterns, prioritize cases that break core functionality over edge cases with diagnostic-only impact (e.g., missing bridgeInfo metadata). If workers are healthy and operational, defer low-impact defensive checks to follow-up PRs.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:37.032Z
Learning: In tywrap (src/runtime/bridge-core.ts and similar), environment variable parsing follows a tolerant/best-effort policy. For example, `TYWRAP_CODEC_MAX_BYTES=1024abc` should be accepted as 1024. Only reject clearly invalid values (non-numeric start or <=0). This avoids surprising failures from minor typos.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.
📚 Learning: 2026-01-19T21:00:30.825Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/adversarial_playground.test.ts:339-360
Timestamp: 2026-01-19T21:00:30.825Z
Learning: In adversarial tests for the bridge (test/adversarial_playground.test.ts), recovery assertions should be kept in the finally block adjacent to cleanup to verify resilience under stress, even if that means post-timeout checks might mask the original error. The goal is to surface recovery failures as legitimate test failures.

Applied to files:

  • test/runtime_bridge_fixtures.test.ts
  • test/runtime_node.test.ts
  • test/cli.test.ts
📚 Learning: 2026-01-19T21:48:27.823Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:27.823Z
Learning: In fixture-based tests (e.g., test/runtime_bridge_fixtures.test.ts) and similar tests in the tywrap repository, prefer early returns when Python or fixture files are unavailable. Do not rely on Vitest dynamic skip APIs; a silent pass is intentional for environments lacking Python/fixtures. Treat missing fixtures as optional soft-guards and ensure the test remains non-disruptive in non-availability scenarios.

Applied to files:

  • test/runtime_bridge_fixtures.test.ts
  • test/runtime_node.test.ts
  • test/cli.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In `src/runtime/node-bridge.ts` (NodeBridge), a test message is sent to the Python subprocess to confirm the bridge is responsive before marking it as ready.

Applied to files:

  • test/runtime_bridge_fixtures.test.ts
  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T01:34:07.064Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:444-458
Timestamp: 2026-01-20T01:34:07.064Z
Learning: When reviewing promise-based polling patterns (e.g., recursive setTimeout in waitForAvailableWorker functions), ensure that any recursive timer is tracked and cleared on timeout or promise resolution to prevent timer leaks. Do not rely on no-op checks after settlement; verify clearTimeout is invoked in all paths and consider using an explicit cancellation (e.g., AbortController) or a guard to cancel pending timers when the promise settles.

Applied to files:

  • test/runtime_bridge_fixtures.test.ts
  • test/runtime_node.test.ts
  • src/runtime/node.ts
  • test/cli.test.ts
📚 Learning: 2026-01-20T18:37:05.670Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: src/runtime/process-io.ts:37-40
Timestamp: 2026-01-20T18:37:05.670Z
Learning: In the tywrap repo, ESLint is used for linting (not Biome). Do not flag regex literals that contain control characters (e.g., \u001b, \u0000-\u001F) as lint errors, since the current ESLint configuration allows them. When reviewing TypeScript files (e.g., src/**/*.ts), rely on ESLint results and avoid raising issues about these specific control-character regex literals unless there is a competing config change or a policy requiring explicit escaping.

Applied to files:

  • test/runtime_bridge_fixtures.test.ts
  • test/runtime_node.test.ts
  • src/runtime/node.ts
  • test/cli.test.ts
📚 Learning: 2026-01-20T16:00:49.829Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:203-211
Timestamp: 2026-01-20T16:00:49.829Z
Learning: In the BridgeProtocol implementation (tywrap), reject Map and Set explicitly before serialization (e.g., in safeStringify or the serialization entrypoint) with a clear error like "Bridge protocol does not support Map/Set values". Do not rely on post-hoc checks of non-string keys at the point of JSON.stringify, since Maps/Sets cannot round-trip. This should be enforced at the boundary where data is prepared for serialization to ensure deterministic errors and prevent invalid data from propagating.

Applied to files:

  • test/runtime_bridge_fixtures.test.ts
  • test/runtime_node.test.ts
  • src/runtime/node.ts
  • test/cli.test.ts
📚 Learning: 2026-01-19T21:48:45.693Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-298
Timestamp: 2026-01-19T21:48:45.693Z
Learning: In `src/runtime/bridge-core.ts`, keep `normalizeErrorPayload` to validate error payloads from the Python subprocess. The subprocess boundary is effectively untrusted, and normalizing error responses prevents `undefined: undefined` errors on malformed payloads. Error responses are not the hot path, so the small validation overhead is acceptable for the added resilience.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In the tywrap repository, bridges currently use implicit ready detection: the first successful response from the Python subprocess proves the bridge is ready to handle requests.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:14:40.872Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:14:29.869Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:29.869Z
Learning: In the runtime env-var parsing (e.g., in src/runtime/bridge-core.ts and similar modules), adopt a tolerant, best-effort policy: numeric env values should parse by taking the leading numeric portion (e.g., TYWRAP_CODEC_MAX_BYTES=1024abc -> 1024). Only reject clearly invalid values (non-numeric start or <= 0). This reduces surprising failures from minor typos. Add tests to cover partial numeric prefixes, and ensure downstream logic documents the trusted range; consider a small helper to extract a positive integer from a string with a safe fallback.

Applied to files:

  • src/runtime/node.ts
📚 Learning: 2026-01-19T21:14:35.390Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:35.390Z
Learning: In src/runtime/bridge-core.ts and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (such as runtime, shape, or error-payload checks) inside tight loops unless the protocol boundary is untrusted or there is a concrete bug report. The Python bridge protocol is controlled via tests, so these checks add unnecessary branching overhead without meaningful benefit. Apply this guidance to other hot-path runtime loops in src/runtime/**/*.ts, and re-enable additional validations only when a documented risk or failure scenario is identified. Ensure tests cover protocol validation where applicable.

Applied to files:

  • src/runtime/node.ts
🔇 Additional comments (3)
test/runtime_bridge_fixtures.test.ts (1)

193-210: Explicit 15s budgets make sense for these parity loops.

These cases do multiple bridge startups, calls, and disposals, so pinning a higher per-test timeout should reduce default-timeout flakes without weakening the assertions.

Also applies to: 262-284

test/cli.test.ts (1)

380-403: Good call adding explicit test budgets around the slower CLI flows.

These cases chain sync subprocesses and disk I/O, so a per-test timeout above Vitest’s default should make them much less flaky while still keeping a bounded ceiling.

Also applies to: 526-586

src/runtime/node.ts (1)

164-185: Canonicalizing PATH updates across case variants is the right fix here.

Preferring PATH and synchronizing any existing path-cased aliases should make virtualenv activation much more stable across shells and Windows-style environments.

Also applies to: 686-693

@bbopen
Copy link
Owner Author

bbopen commented Mar 10, 2026

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@bbopen
Copy link
Owner Author

bbopen commented Mar 10, 2026

@codex review

@bbopen
Copy link
Owner Author

bbopen commented Mar 10, 2026

@claude review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: 5b6c85338c

ℹ️ 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".

Comment on lines +181 to +182
if (key !== 'PATH' && key.toLowerCase() === 'path') {
setEnvValue(env, key, value);

Choose a reason for hiding this comment

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

P2 Badge Restrict PATH alias synchronization to Windows

Updating every path-cased key unconditionally will clobber distinct environment variables on case-sensitive platforms: when virtualEnv is set, a user-provided path/Path variable (used for app config, not executable lookup) is overwritten with the computed PATH value. This behavior was introduced by setPathValue and can break subprocess behavior for callers that intentionally pass both PATH and another differently-cased key on Linux/macOS; the alias synchronization should be gated to Windows only.

Useful? React with 👍 / 👎.

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 10, 2026
Copy link

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/runtime/node.ts (1)

164-189: 🧹 Nitpick | 🔵 Trivial

Unify PATH-key resolution in one shared helper.

src/runtime/bridge-core.ts:404-413 and 487-494 already own PATH-key discovery. Keeping a second scanner here means the next PATH-casing fix has to land in two places. Please centralize the exact-PATH preference there and reuse it here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/runtime/node.ts` around lines 164 - 189, Replace the duplicated
PATH-casing logic in getPathKey and setPathValue with a call to the central
PATH-key discovery helper used by the bridge-core code (the same helper used by
the bridge-core PATH handling), i.e. remove the local scanner in getPathKey and
call the shared helper to determine the correct PATH key, and in setPathValue
call the shared helper to get the key(s) to set and then call setEnvValue with
that key(s); ensure behavior on win32 (setting alternate-cased keys) is
preserved by delegating to that shared helper rather than re-implementing the
loop.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/runtime/node.ts`:
- Around line 694-696: The code writes a trailing delimiter into PATH when no
prior PATH exists; update the logic around getPathKey/getEnvValue/setPathValue
so that you only prepend `${venv.binDir}${delimiter}${currentPath}` when
currentPath is non-empty, otherwise set PATH to just `venv.binDir`; use the
existing identifiers (pathKey, currentPath, venv.binDir, delimiter) and ensure
you check for empty string/null before concatenating the delimiter.

---

Outside diff comments:
In `@src/runtime/node.ts`:
- Around line 164-189: Replace the duplicated PATH-casing logic in getPathKey
and setPathValue with a call to the central PATH-key discovery helper used by
the bridge-core code (the same helper used by the bridge-core PATH handling),
i.e. remove the local scanner in getPathKey and call the shared helper to
determine the correct PATH key, and in setPathValue call the shared helper to
get the key(s) to set and then call setEnvValue with that key(s); ensure
behavior on win32 (setting alternate-cased keys) is preserved by delegating to
that shared helper rather than re-implementing the loop.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f1c7517c-2a62-4a7b-9fdc-dfd36f1a5103

📥 Commits

Reviewing files that changed from the base of the PR and between 5b6c853 and 8fd9e37.

📒 Files selected for processing (2)
  • src/runtime/node.ts
  • test/runtime_node.test.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:37.032Z
Learning: In tywrap (src/runtime/bridge-core.ts and similar), environment variable parsing follows a tolerant/best-effort policy. For example, `TYWRAP_CODEC_MAX_BYTES=1024abc` should be accepted as 1024. Only reject clearly invalid values (non-numeric start or <=0). This avoids surprising failures from minor typos.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:238-249
Timestamp: 2026-01-20T01:33:12.841Z
Learning: In the tywrap repository, when reviewing init/startup patterns, prioritize cases that break core functionality over edge cases with diagnostic-only impact (e.g., missing bridgeInfo metadata). If workers are healthy and operational, defer low-impact defensive checks to follow-up PRs.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:35.351Z
Learning: In test/runtime_bridge_fixtures.test.ts and similar fixture-based tests in the tywrap repository, early returns are preferred over explicit test skips when Python or fixture files are unavailable. These fixture tests are intentionally optional soft-guards, and the project does not currently rely on Vitest dynamic skip APIs. The silent pass behavior is deliberate for environments without Python/fixtures.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.
📚 Learning: 2026-01-19T21:14:29.869Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:29.869Z
Learning: In the runtime env-var parsing (e.g., in src/runtime/bridge-core.ts and similar modules), adopt a tolerant, best-effort policy: numeric env values should parse by taking the leading numeric portion (e.g., TYWRAP_CODEC_MAX_BYTES=1024abc -> 1024). Only reject clearly invalid values (non-numeric start or <= 0). This reduces surprising failures from minor typos. Add tests to cover partial numeric prefixes, and ensure downstream logic documents the trusted range; consider a small helper to extract a positive integer from a string with a safe fallback.

Applied to files:

  • src/runtime/node.ts
📚 Learning: 2026-01-19T21:14:35.390Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:35.390Z
Learning: In src/runtime/bridge-core.ts and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (such as runtime, shape, or error-payload checks) inside tight loops unless the protocol boundary is untrusted or there is a concrete bug report. The Python bridge protocol is controlled via tests, so these checks add unnecessary branching overhead without meaningful benefit. Apply this guidance to other hot-path runtime loops in src/runtime/**/*.ts, and re-enable additional validations only when a documented risk or failure scenario is identified. Ensure tests cover protocol validation where applicable.

Applied to files:

  • src/runtime/node.ts
📚 Learning: 2026-01-20T01:34:07.064Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:444-458
Timestamp: 2026-01-20T01:34:07.064Z
Learning: When reviewing promise-based polling patterns (e.g., recursive setTimeout in waitForAvailableWorker functions), ensure that any recursive timer is tracked and cleared on timeout or promise resolution to prevent timer leaks. Do not rely on no-op checks after settlement; verify clearTimeout is invoked in all paths and consider using an explicit cancellation (e.g., AbortController) or a guard to cancel pending timers when the promise settles.

Applied to files:

  • src/runtime/node.ts
  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T18:37:05.670Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: src/runtime/process-io.ts:37-40
Timestamp: 2026-01-20T18:37:05.670Z
Learning: In the tywrap repo, ESLint is used for linting (not Biome). Do not flag regex literals that contain control characters (e.g., \u001b, \u0000-\u001F) as lint errors, since the current ESLint configuration allows them. When reviewing TypeScript files (e.g., src/**/*.ts), rely on ESLint results and avoid raising issues about these specific control-character regex literals unless there is a competing config change or a policy requiring explicit escaping.

Applied to files:

  • src/runtime/node.ts
  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:00:49.829Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:203-211
Timestamp: 2026-01-20T16:00:49.829Z
Learning: In the BridgeProtocol implementation (tywrap), reject Map and Set explicitly before serialization (e.g., in safeStringify or the serialization entrypoint) with a clear error like "Bridge protocol does not support Map/Set values". Do not rely on post-hoc checks of non-string keys at the point of JSON.stringify, since Maps/Sets cannot round-trip. This should be enforced at the boundary where data is prepared for serialization to ensure deterministic errors and prevent invalid data from propagating.

Applied to files:

  • src/runtime/node.ts
  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:00:30.825Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/adversarial_playground.test.ts:339-360
Timestamp: 2026-01-19T21:00:30.825Z
Learning: In adversarial tests for the bridge (test/adversarial_playground.test.ts), recovery assertions should be kept in the finally block adjacent to cleanup to verify resilience under stress, even if that means post-timeout checks might mask the original error. The goal is to surface recovery failures as legitimate test failures.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In `src/runtime/node-bridge.ts` (NodeBridge), a test message is sent to the Python subprocess to confirm the bridge is responsive before marking it as ready.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:48:45.693Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-298
Timestamp: 2026-01-19T21:48:45.693Z
Learning: In `src/runtime/bridge-core.ts`, keep `normalizeErrorPayload` to validate error payloads from the Python subprocess. The subprocess boundary is effectively untrusted, and normalizing error responses prevents `undefined: undefined` errors on malformed payloads. Error responses are not the hot path, so the small validation overhead is acceptable for the added resilience.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:48:27.823Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:27.823Z
Learning: In fixture-based tests (e.g., test/runtime_bridge_fixtures.test.ts) and similar tests in the tywrap repository, prefer early returns when Python or fixture files are unavailable. Do not rely on Vitest dynamic skip APIs; a silent pass is intentional for environments lacking Python/fixtures. Treat missing fixtures as optional soft-guards and ensure the test remains non-disruptive in non-availability scenarios.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:14:40.872Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:00:52.689Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/fixtures/out_of_order_bridge.py:29-48
Timestamp: 2026-01-19T21:00:52.689Z
Learning: In `test/fixtures/out_of_order_bridge.py`, the fixture intentionally leaves a pending request unanswered at EOF to simulate missing/out-of-order responses and validate bridge behavior when requests never complete; this is the exact failure mode being tested and must be preserved.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T01:36:14.701Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:743-759
Timestamp: 2026-01-20T01:36:14.701Z
Learning: In the tywrap repository, when reviewing concurrent request handling patterns (especially with BridgeCore request multiplexing), flag uses of boolean `busy` flags that should be request counters instead. A boolean flag creates a race condition: when request A completes and sets `busy = false`, request B (still in flight via multiplexing) is incorrectly treated as idle. The fix is to use an `inFlightRequests: number` counter that increments on request start and decrements on completion, then check `worker.inFlightRequests === 0` before cleanup/termination.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In the tywrap repository, bridges currently use implicit ready detection: the first successful response from the Python subprocess proves the bridge is ready to handle requests.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:01:29.276Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:636-637
Timestamp: 2026-01-20T16:01:29.276Z
Learning: In the tywrap BridgeProtocol ProcessIO transport (ADR-002), when implementing `restartAfterRequests` functionality, use drain-before-restart as the default: wait for `pendingRequests.size === 0` before killing and restarting the process. This prevents rejecting in-flight requests during restart. Alternative graceful restart (spawn new process, drain old) adds complexity with two concurrent processes.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:14:37.032Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:37.032Z
Learning: In tywrap (src/runtime/bridge-core.ts and similar), environment variable parsing follows a tolerant/best-effort policy. For example, `TYWRAP_CODEC_MAX_BYTES=1024abc` should be accepted as 1024. Only reject clearly invalid values (non-numeric start or <=0). This avoids surprising failures from minor typos.

Applied to files:

  • test/runtime_node.test.ts
🔇 Additional comments (1)
test/runtime_node.test.ts (1)

1190-1230: Good regression coverage for distinct lowercase path overrides on POSIX.

This exercises the runtime change directly and avoids depending on PATH entry ordering.

Copy link

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/runtime_node.test.ts`:
- Around line 1216-1221: The test currently checks PATH contains binDir and that
the lowercase 'path' env equals customPathAlias, but doesn't prove PATH was
derived from that lowercase value; after obtaining pathEnv and computing
pathEntries (from bridge.call('os','getenv', ['PATH']) and split by delimiter),
also assert that pathEntries includes the lowercase value customPathAlias (the
value returned by bridge.call('os','getenv', ['path'])), i.e., add an assertion
that pathEntries contains customPathAlias so PATH is shown to include the
original lowercase alias in addition to binDir.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7b541a01-2071-4edf-b281-ce331f5a0723

📥 Commits

Reviewing files that changed from the base of the PR and between 8fd9e37 and 48adce8.

📒 Files selected for processing (2)
  • src/runtime/node.ts
  • test/runtime_node.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: os (windows-latest)
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:35.351Z
Learning: In test/runtime_bridge_fixtures.test.ts and similar fixture-based tests in the tywrap repository, early returns are preferred over explicit test skips when Python or fixture files are unavailable. These fixture tests are intentionally optional soft-guards, and the project does not currently rely on Vitest dynamic skip APIs. The silent pass behavior is deliberate for environments without Python/fixtures.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:37.032Z
Learning: In tywrap (src/runtime/bridge-core.ts and similar), environment variable parsing follows a tolerant/best-effort policy. For example, `TYWRAP_CODEC_MAX_BYTES=1024abc` should be accepted as 1024. Only reject clearly invalid values (non-numeric start or <=0). This avoids surprising failures from minor typos.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:238-249
Timestamp: 2026-01-20T01:33:12.841Z
Learning: In the tywrap repository, when reviewing init/startup patterns, prioritize cases that break core functionality over edge cases with diagnostic-only impact (e.g., missing bridgeInfo metadata). If workers are healthy and operational, defer low-impact defensive checks to follow-up PRs.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.
📚 Learning: 2026-01-19T21:14:29.869Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:29.869Z
Learning: In the runtime env-var parsing (e.g., in src/runtime/bridge-core.ts and similar modules), adopt a tolerant, best-effort policy: numeric env values should parse by taking the leading numeric portion (e.g., TYWRAP_CODEC_MAX_BYTES=1024abc -> 1024). Only reject clearly invalid values (non-numeric start or <= 0). This reduces surprising failures from minor typos. Add tests to cover partial numeric prefixes, and ensure downstream logic documents the trusted range; consider a small helper to extract a positive integer from a string with a safe fallback.

Applied to files:

  • src/runtime/node.ts
📚 Learning: 2026-01-19T21:14:35.390Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:35.390Z
Learning: In src/runtime/bridge-core.ts and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (such as runtime, shape, or error-payload checks) inside tight loops unless the protocol boundary is untrusted or there is a concrete bug report. The Python bridge protocol is controlled via tests, so these checks add unnecessary branching overhead without meaningful benefit. Apply this guidance to other hot-path runtime loops in src/runtime/**/*.ts, and re-enable additional validations only when a documented risk or failure scenario is identified. Ensure tests cover protocol validation where applicable.

Applied to files:

  • src/runtime/node.ts
📚 Learning: 2026-01-20T01:34:07.064Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:444-458
Timestamp: 2026-01-20T01:34:07.064Z
Learning: When reviewing promise-based polling patterns (e.g., recursive setTimeout in waitForAvailableWorker functions), ensure that any recursive timer is tracked and cleared on timeout or promise resolution to prevent timer leaks. Do not rely on no-op checks after settlement; verify clearTimeout is invoked in all paths and consider using an explicit cancellation (e.g., AbortController) or a guard to cancel pending timers when the promise settles.

Applied to files:

  • src/runtime/node.ts
  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T18:37:05.670Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: src/runtime/process-io.ts:37-40
Timestamp: 2026-01-20T18:37:05.670Z
Learning: In the tywrap repo, ESLint is used for linting (not Biome). Do not flag regex literals that contain control characters (e.g., \u001b, \u0000-\u001F) as lint errors, since the current ESLint configuration allows them. When reviewing TypeScript files (e.g., src/**/*.ts), rely on ESLint results and avoid raising issues about these specific control-character regex literals unless there is a competing config change or a policy requiring explicit escaping.

Applied to files:

  • src/runtime/node.ts
  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:00:49.829Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:203-211
Timestamp: 2026-01-20T16:00:49.829Z
Learning: In the BridgeProtocol implementation (tywrap), reject Map and Set explicitly before serialization (e.g., in safeStringify or the serialization entrypoint) with a clear error like "Bridge protocol does not support Map/Set values". Do not rely on post-hoc checks of non-string keys at the point of JSON.stringify, since Maps/Sets cannot round-trip. This should be enforced at the boundary where data is prepared for serialization to ensure deterministic errors and prevent invalid data from propagating.

Applied to files:

  • src/runtime/node.ts
  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:00:30.825Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/adversarial_playground.test.ts:339-360
Timestamp: 2026-01-19T21:00:30.825Z
Learning: In adversarial tests for the bridge (test/adversarial_playground.test.ts), recovery assertions should be kept in the finally block adjacent to cleanup to verify resilience under stress, even if that means post-timeout checks might mask the original error. The goal is to surface recovery failures as legitimate test failures.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In `src/runtime/node-bridge.ts` (NodeBridge), a test message is sent to the Python subprocess to confirm the bridge is responsive before marking it as ready.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:48:45.693Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-298
Timestamp: 2026-01-19T21:48:45.693Z
Learning: In `src/runtime/bridge-core.ts`, keep `normalizeErrorPayload` to validate error payloads from the Python subprocess. The subprocess boundary is effectively untrusted, and normalizing error responses prevents `undefined: undefined` errors on malformed payloads. Error responses are not the hot path, so the small validation overhead is acceptable for the added resilience.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:48:27.823Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:27.823Z
Learning: In fixture-based tests (e.g., test/runtime_bridge_fixtures.test.ts) and similar tests in the tywrap repository, prefer early returns when Python or fixture files are unavailable. Do not rely on Vitest dynamic skip APIs; a silent pass is intentional for environments lacking Python/fixtures. Treat missing fixtures as optional soft-guards and ensure the test remains non-disruptive in non-availability scenarios.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:00:52.689Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/fixtures/out_of_order_bridge.py:29-48
Timestamp: 2026-01-19T21:00:52.689Z
Learning: In `test/fixtures/out_of_order_bridge.py`, the fixture intentionally leaves a pending request unanswered at EOF to simulate missing/out-of-order responses and validate bridge behavior when requests never complete; this is the exact failure mode being tested and must be preserved.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:14:40.872Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T01:36:14.701Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:743-759
Timestamp: 2026-01-20T01:36:14.701Z
Learning: In the tywrap repository, when reviewing concurrent request handling patterns (especially with BridgeCore request multiplexing), flag uses of boolean `busy` flags that should be request counters instead. A boolean flag creates a race condition: when request A completes and sets `busy = false`, request B (still in flight via multiplexing) is incorrectly treated as idle. The fix is to use an `inFlightRequests: number` counter that increments on request start and decrements on completion, then check `worker.inFlightRequests === 0` before cleanup/termination.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In the tywrap repository, bridges currently use implicit ready detection: the first successful response from the Python subprocess proves the bridge is ready to handle requests.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-20T16:01:29.276Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:636-637
Timestamp: 2026-01-20T16:01:29.276Z
Learning: In the tywrap BridgeProtocol ProcessIO transport (ADR-002), when implementing `restartAfterRequests` functionality, use drain-before-restart as the default: wait for `pendingRequests.size === 0` before killing and restarting the process. This prevents rejecting in-flight requests during restart. Alternative graceful restart (spawn new process, drain old) adds complexity with two concurrent processes.

Applied to files:

  • test/runtime_node.test.ts
📚 Learning: 2026-01-19T21:14:37.032Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:37.032Z
Learning: In tywrap (src/runtime/bridge-core.ts and similar), environment variable parsing follows a tolerant/best-effort policy. For example, `TYWRAP_CODEC_MAX_BYTES=1024abc` should be accepted as 1024. Only reject clearly invalid values (non-numeric start or <=0). This avoids surprising failures from minor typos.

Applied to files:

  • test/runtime_node.test.ts
🔇 Additional comments (3)
src/runtime/node.ts (1)

164-189: PATH normalization logic looks correct.

Exact PATH preference plus Windows alias synchronization fixes the case-variant env handling without reintroducing the empty-segment bug.

Also applies to: 694-696

test/runtime_node.test.ts (2)

428-436: The stale-response timing is now exercised deterministically.

The new timeout/sleep pairing and recovery wait are long enough to let the stale frame arrive before the follow-up call.


1232-1271: Good regression coverage for blank PATH.

Resolving Python up front and then asserting PATH === binDir locks the no-empty-entry behavior directly.

Comment on lines +1216 to +1221
const pathEnv = await bridge.call<string | null>('os', 'getenv', ['PATH']);
const pathEntries = (pathEnv ?? '').split(delimiter).filter(Boolean);
expect(pathEntries).toContain(binDir);

const lowercasePathEnv = await bridge.call<string | null>('os', 'getenv', ['path']);
expect(lowercasePathEnv).toBe(customPathAlias);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Assert that PATH still includes the original lowercase alias.

This currently proves the lowercase path variable survives separately, but it does not prove PATH was derived from it. A regression that sets PATH to only binDir would still pass.

Proposed test tightening
           const pathEnv = await bridge.call<string | null>('os', 'getenv', ['PATH']);
           const pathEntries = (pathEnv ?? '').split(delimiter).filter(Boolean);
           expect(pathEntries).toContain(binDir);
+          expect(pathEntries).toContain(customPathAlias);
 
           const lowercasePathEnv = await bridge.call<string | null>('os', 'getenv', ['path']);
           expect(lowercasePathEnv).toBe(customPathAlias);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/runtime_node.test.ts` around lines 1216 - 1221, The test currently
checks PATH contains binDir and that the lowercase 'path' env equals
customPathAlias, but doesn't prove PATH was derived from that lowercase value;
after obtaining pathEnv and computing pathEntries (from
bridge.call('os','getenv', ['PATH']) and split by delimiter), also assert that
pathEntries includes the lowercase value customPathAlias (the value returned by
bridge.call('os','getenv', ['path'])), i.e., add an assertion that pathEntries
contains customPathAlias so PATH is shown to include the original lowercase
alias in addition to binDir.

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

Labels

area:ci Area: CI and automation area:runtime-node Area: Node runtime bridge codex enhancement New feature or request priority:p2 Priority P2 (medium)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant