Skip to content

[codex] fix: address follow-up promotion bugs#207

Merged
bbopen merged 3 commits intomainfrom
feat/tywrap-promotion
Mar 18, 2026
Merged

[codex] fix: address follow-up promotion bugs#207
bbopen merged 3 commits intomainfrom
feat/tywrap-promotion

Conversation

@bbopen
Copy link
Owner

@bbopen bbopen commented Mar 17, 2026

Summary

This follow-up PR addresses the post-promotion issues found during review and two additional bug-hunting passes.

It fixes the docs and AI discovery files so they match the current runtime and configuration surface, hardens the npm release workflow so it can run the full test suite on a fresh GitHub runner, and closes several correctness bugs in runtime generation and Python IR extraction.

Root Cause And User Impact

The docs migration left several stale runtime examples and environment variable references in published pages and llms-full.txt, which could send users toward unsupported config keys and nonexistent debug flags.

The npm release job ran npm test without setting up Python or installing tywrap_ir, so releases depended on undeclared runner state.

At runtime and during generation, ProcessIO could ignore unexpected response IDs, check mode could trust stale cached IR, async generators were misclassified in the Python IR, and optimized extraction could both leak option state across calls and drop warnings from failed parallel extraction.

Fixes

  • update docs/index, configuration, Node runtime, troubleshooting, and regenerate llms-full.txt
  • set up Python and install tywrap_ir in release.yml before build and test
  • fail fast on truly unexpected response IDs while still ignoring late responses from timed-out or cancelled requests
  • bypass IR cache in generate(..., { check: true })
  • mark async generators as generators in tywrap_ir
  • keep extract_module_ir_optimized option toggles from mutating global extractor state
  • surface parallel optimized IR extraction failures in the returned warnings array

Validation

  • npm run docs:build
  • npm run build
  • NODE_OPTIONS=--expose-gc npm test -- test/transport.test.ts test/runtime_node.test.ts test/integration.test.ts
  • PYTHONPATH=tywrap_ir python3 -m unittest discover -s tywrap_ir/tests -p 'test_*.py' -v

@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 949f781c-0ab7-40b7-a5b2-e7171644c011

📥 Commits

Reviewing files that changed from the base of the PR and between 31dfda4 and d248b9e.

📒 Files selected for processing (1)
  • tywrap_ir/tests/test_ir_async_generator_flags.py
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
tywrap_ir/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Python code must follow PEP 8 and use type hints

Follow PEP 8 and use type hints in Python code

Files:

  • tywrap_ir/tests/test_ir_async_generator_flags.py
🧠 Learnings (3)
📓 Common learnings
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.
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.
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.
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to tywrap_ir/**/*.py : Follow PEP 8 and use type hints in Python code

Applied to files:

  • tywrap_ir/tests/test_ir_async_generator_flags.py
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to tywrap_ir/**/*.py : Python code must follow PEP 8 and use type hints

Applied to files:

  • tywrap_ir/tests/test_ir_async_generator_flags.py
🔇 Additional comments (1)
tywrap_ir/tests/test_ir_async_generator_flags.py (1)

1-40: LGTM!

The test file is well-structured and correctly validates the _extract_function behavior for the three key cases (async generator, async coroutine, sync generator). All previously raised review comments have been addressed:

  • Return type hints added to all sample functions
  • Simplified assertion pattern using assert result is not None for type narrowing
  • Imports moved from typing to collections.abc per UP035

The tests align with the implementation logic in ir.py that uses inspect.isasyncgenfunction() to correctly classify async generators as both async and generators.


📝 Walkthrough

Walkthrough

Adds late-response filtering for timed-out IPC requests, skips cache reads in check-mode, shifts docs toward TypeScript NodeBridge examples, configures Python 3.11 in the release workflow, and adds tests and IR improvements for async-generator classification and optimized extractor behavior.

Changes

Cohort / File(s) Summary
CI/Workflow Setup
​.github/workflows/release.yml
Adds Python 3.11 setup and installs Python dependencies (pip install -e . in tywrap_ir) before npm publish steps.
Documentation – Configuration & Runtimes
docs/guide/configuration.md, docs/guide/runtimes/node.md, docs/troubleshooting/index.md, docs/public/llms-full.txt, docs/index.md
Replaces JSON runtime examples with TypeScript NodeBridge usage and programmatic config; updates debugging, env-var guidance, and references (CHANGELOG → Releases).
Runtime Transport – Late Response Handling
src/runtime/process-io.ts
Adds a TimedOutRequestTracker to mark timed-out/aborted requests and ignore late responses; clears tracker on transport disposal.
Runtime Cache Logic
src/tywrap.ts
Prevents reading cached IR when generate() is invoked with check mode enabled; write path unchanged.
TypeScript Tests – Integration & Transport
test/integration.test.ts, test/transport.test.ts
Adds integration test ensuring check-mode bypasses stale IR cache; adds transport tests for unexpected response IDs and ignoring late responses for timed-out requests.
Python Tests – IR Extraction
tywrap_ir/tests/test_ir_async_generator_flags.py, tywrap_ir/tests/test_optimized_ir_options.py, tywrap_ir/tests/test_optimized_ir_parallel_warnings.py
Adds tests for async-generator/coroutine/generator flag semantics, optimized extractor options isolation, and warning propagation from parallel extraction failures.
Python IR Logic
tywrap_ir/tywrap_ir/ir.py, tywrap_ir/tywrap_ir/optimized_ir.py
Classifies async generators as generators as well as async functions; avoids mutating global extractor state by creating local extractors when options differ and collects per-task warnings in parallel extraction.
Package Manifest
package.json
Minor manifest change referenced by ProcessIO edits (contextual).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ProcessIO
    participant Transport
    participant TimedOutTracker

    Client->>ProcessIO: send request (messageId)
    ProcessIO->>Transport: write(message)
    Transport-->>ProcessIO: response(messageId)   Note right of Transport: response arrives before timeout
    ProcessIO->>Client: resolve response

    alt request times out/aborted
        ProcessIO->>TimedOutTracker: mark(messageId)
    end

    Transport-->>ProcessIO: late response(messageId)
    ProcessIO->>TimedOutTracker: consume(messageId)
    alt TimedOutTracker had entry
        ProcessIO--xClient: ignore late response
    else
        ProcessIO->>Client: treat as protocol error
    end

    ProcessIO->>TimedOutTracker: clear() upon transport disposal
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I marked the late replies and hopped away,
Caches sleep when checks rule the day,
Async hops now counted twice,
Bridges wired up nice and precise,
A tidy burrow of tests and play. 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.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 '[codex] fix: address follow-up promotion bugs' clearly summarizes the main change as a follow-up fix to address issues from a recent promotion, which aligns with the PR's purpose of fixing post-promotion bugs.
Description check ✅ Passed The description comprehensively explains the root causes, fixes, and validation steps, directly relating to all major changes in the changeset including docs updates, CI workflow hardening, and runtime correctness fixes.

✏️ 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 feat/tywrap-promotion
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@github-actions github-actions bot added area:docs Area: documentation area:ci Area: CI and automation area:runtime area:codegen labels Mar 17, 2026
@codecov-commenter
Copy link

codecov-commenter commented Mar 17, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/runtime/process-io.ts 87.50% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@bbopen bbopen marked this pull request as ready for review March 17, 2026 22:37
@coderabbitai coderabbitai bot added bug Something isn't working documentation Improvements or additions to documentation codex area:runtime-node Area: Node runtime bridge area:tooling Area: tooling and CLI priority:p2 Priority P2 (medium) labels Mar 17, 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: 434233588e

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

return;
}
// Unknown IDs while requests are pending indicate protocol desync.
this.handleProtocolError(`Unexpected response id ${messageId}`, line);

Choose a reason for hiding this comment

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

P1 Badge Ignore evicted late-response IDs before raising protocol errors

When a response arrives for a request that already timed out/cancelled, this branch now treats any tracker miss as a protocol desync and rejects all pending requests. That is unsafe once TimedOutRequestTracker has pruned old IDs (TTL/max-size): under sustained timeouts/cancellations, a legitimate late response for an older timed-out request will miss the tracker and trigger handleProtocolError, aborting unrelated in-flight calls. This turns expected late traffic into cross-request failures in long-running/high-timeout workloads.

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

🤖 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/integration.test.ts`:
- Around line 126-127: The finally block currently restores PYTHONPATH by
assigning process.env.PYTHONPATH = originalPythonPath which can set the string
"undefined"; change it to conditionally restore or remove the env var: if
originalPythonPath is strictly undefined (or null) then delete
process.env.PYTHONPATH, otherwise set process.env.PYTHONPATH =
originalPythonPath; reference the variables process.env.PYTHONPATH and
originalPythonPath and update the finally cleanup in the test to perform this
conditional delete/restore.

In `@test/transport.test.ts`:
- Around line 641-660: Add a companion unit test that verifies a response
arriving after its request has already timed out is ignored (i.e., does not
reject the original promise with Unexpected response id). Use the same setup as
the existing test: instantiate ProcessIO, cast to ProcessIOInternals, set _state
= 'ready', processExited = false and provide a mock stdin.write, then call
transport.send(...) with a short timeout to produce a pending promise; after the
send times out (await the rejection or wait past the timeout), call
internals.handleResponseLine(...) with the original message id (the late
response) and assert that it does not cause an additional rejection or throw
BridgeProtocolError for that id—use the same identifiers ProcessIO,
ProcessIOInternals, send, handleResponseLine, and BridgeProtocolError to locate
code.

In `@tywrap_ir/tests/test_ir_async_generator_flags.py`:
- Around line 19-26: Replace the redundant assertIsNotNone plus explicit
None-check in test_async_generator_is_marked_as_generator with a single assert
result is not None to both simplify the test and provide type-narrowing for the
remainder of the test; locate the assertion around the call to
_extract_function(sample_async_generator, "tests.sample_async_generator") and
remove the subsequent if result is None: self.fail(...) block so the test
continues to assert result.is_async and result.is_generator.
- Around line 6-16: Add explicit return type annotations to the sample
functions: annotate sample_async_generator as returning AsyncIterator[int],
sample_async_coroutine as returning int (i.e., -> int for the async coroutine),
and sample_sync_generator as returning Iterator[int]; also add the required
imports from typing (AsyncIterator, Iterator) at the top of the file so the
annotations resolve. Ensure the async generator and sync generator signatures
use the AsyncIterator/Iterator types respectively and the async coroutine uses a
plain int return type annotation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8a224a05-8b7c-4279-ac54-9ccac141b67d

📥 Commits

Reviewing files that changed from the base of the PR and between bab9301 and 4342335.

📒 Files selected for processing (15)
  • .github/workflows/release.yml
  • docs/guide/configuration.md
  • docs/guide/runtimes/node.md
  • docs/index.md
  • docs/public/llms-full.txt
  • docs/troubleshooting/index.md
  • src/runtime/process-io.ts
  • src/tywrap.ts
  • test/integration.test.ts
  • test/transport.test.ts
  • tywrap_ir/tests/test_ir_async_generator_flags.py
  • tywrap_ir/tests/test_optimized_ir_options.py
  • tywrap_ir/tests/test_optimized_ir_parallel_warnings.py
  • tywrap_ir/tywrap_ir/ir.py
  • tywrap_ir/tywrap_ir/optimized_ir.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

TypeScript strict mode; avoid any — use unknown and type guards instead

Files:

  • src/runtime/process-io.ts
  • src/tywrap.ts
src/runtime/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Runtime bridges code should be located in src/runtime/ with corresponding tests in test/runtime_*.test.ts

Files:

  • src/runtime/process-io.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode and avoid any — use unknown and type guards instead

Files:

  • src/runtime/process-io.ts
  • src/tywrap.ts
test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use NODE_OPTIONS=--expose-gc environment variable for GC-sensitive tests

Files:

  • test/integration.test.ts
  • test/transport.test.ts
tywrap_ir/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Python code must follow PEP 8 and use type hints

Follow PEP 8 and use type hints in Python code

Files:

  • tywrap_ir/tywrap_ir/ir.py
  • tywrap_ir/tests/test_optimized_ir_parallel_warnings.py
  • tywrap_ir/tests/test_optimized_ir_options.py
  • tywrap_ir/tests/test_ir_async_generator_flags.py
  • tywrap_ir/tywrap_ir/optimized_ir.py
🧠 Learnings (26)
📓 Common learnings
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.
📚 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:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/guide/configuration.md
  • docs/public/llms-full.txt
  • test/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Place runtime bridge implementations in `src/runtime/` with corresponding tests in `test/runtime_*.test.ts`

Applied to files:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to src/runtime/**/*.ts : Runtime bridges code should be located in `src/runtime/` with corresponding tests in `test/runtime_*.test.ts`

Applied to files:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following the `test/runtime_*.test.ts` patterns

Applied to files:

  • docs/guide/runtimes/node.md
  • src/tywrap.ts
  • test/integration.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:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/guide/configuration.md
  • docs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following patterns in `test/runtime_*.test.ts`

Applied to files:

  • docs/guide/runtimes/node.md
  • src/tywrap.ts
  • test/integration.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:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/public/llms-full.txt
  • test/transport.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:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/public/llms-full.txt
  • test/transport.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:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/public/llms-full.txt
  • test/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Set `NODE_OPTIONS=--expose-gc` for running GC-sensitive tests

Applied to files:

  • docs/guide/runtimes/node.md
  • docs/public/llms-full.txt
📚 Learning: 2026-01-19T21:49:05.612Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: runtime/python_bridge.py:99-123
Timestamp: 2026-01-19T21:49:05.612Z
Learning: In the tywrap repository, TYWRAP_REQUEST_MAX_BYTES uses strict integer parsing that rejects values with trailing characters (e.g., "1024abc"). This differs from TYWRAP_CODEC_MAX_BYTES, which uses tolerant/best-effort parsing that accepts numeric prefixes. The strict policy for REQUEST_MAX_BYTES ensures explicit integer values and consistent parse behavior across Node/Python implementations.

Applied to files:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/guide/configuration.md
  • docs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Set `TYWRAP_PERF_BUDGETS=1` to enable performance budget assertions in tests

Applied to files:

  • docs/guide/runtimes/node.md
  • docs/troubleshooting/index.md
  • docs/public/llms-full.txt
📚 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:

  • src/runtime/process-io.ts
  • test/transport.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/process-io.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/process-io.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/process-io.ts
  • src/tywrap.ts
  • test/integration.test.ts
  • test/transport.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/process-io.ts
  • src/tywrap.ts
  • test/integration.test.ts
  • test/transport.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/process-io.ts
  • src/tywrap.ts
  • test/integration.test.ts
  • test/transport.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/integration.test.ts
  • test/transport.test.ts
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/**/*.test.ts : Use `NODE_OPTIONS=--expose-gc` environment variable for GC-sensitive tests

Applied to files:

  • test/integration.test.ts
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to tywrap_ir/**/*.py : Python code must follow PEP 8 and use type hints

Applied to files:

  • docs/troubleshooting/index.md
  • docs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to tywrap_ir/**/*.py : Follow PEP 8 and use type hints in Python code

Applied to files:

  • docs/troubleshooting/index.md
  • docs/public/llms-full.txt
📚 Learning: 2026-01-19T21:48:35.351Z
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.

Applied to files:

  • docs/guide/configuration.md
  • docs/public/llms-full.txt
📚 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/transport.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/transport.test.ts
🪛 Ruff (0.15.6)
tywrap_ir/tests/test_optimized_ir_parallel_warnings.py

[warning] 19-19: Boolean positional value in function call

(FBT003)


[warning] 21-21: Use a regular assert instead of unittest-style assertEqual

Replace assertEqual(...) with assert ...

(PT009)


[warning] 22-22: Use a regular assert instead of unittest-style assertIn

Replace assertIn(...) with assert ...

(PT009)


[warning] 23-23: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)

tywrap_ir/tests/test_optimized_ir_options.py

[warning] 26-26: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


[warning] 27-27: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


[warning] 28-28: Use a regular assert instead of unittest-style assertIs

Replace assertIs(...) with assert ...

(PT009)


[warning] 37-37: Use a regular assert instead of unittest-style assertGreaterEqual

Replace assertGreaterEqual(...) with assert ...

(PT009)

tywrap_ir/tests/test_ir_async_generator_flags.py

[warning] 21-21: Use a regular assert instead of unittest-style assertIsNotNone

Replace assertIsNotNone(...) with assert ...

(PT009)


[warning] 24-24: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


[warning] 25-25: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


[warning] 29-29: Use a regular assert instead of unittest-style assertIsNotNone

Replace assertIsNotNone(...) with assert ...

(PT009)


[warning] 32-32: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)


[warning] 33-33: Use a regular assert instead of unittest-style assertFalse

Replace assertFalse(...) with assert ...

(PT009)


[warning] 37-37: Use a regular assert instead of unittest-style assertIsNotNone

Replace assertIsNotNone(...) with assert ...

(PT009)


[warning] 40-40: Use a regular assert instead of unittest-style assertFalse

Replace assertFalse(...) with assert ...

(PT009)


[warning] 41-41: Use a regular assert instead of unittest-style assertTrue

Replace assertTrue(...) with assert ...

(PT009)

tywrap_ir/tywrap_ir/optimized_ir.py

[warning] 230-230: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (16)
docs/index.md (1)

49-49: Looks good — release link now points to the right source for breaking changes.

tywrap_ir/tywrap_ir/ir.py (1)

235-237: Good fix for async-generator classification.

Marking async generators as generators here is the correct IR behavior.

docs/guide/configuration.md (1)

331-365: Nice clarification of config precedence and env-var scope.

This makes runtime setup expectations much clearer for users.

.github/workflows/release.yml (1)

44-47: CI hardening looks correct.

Bootstrapping Python + tywrap_ir in the release job removes implicit environment assumptions.

Also applies to: 50-54

src/tywrap.ts (1)

150-150: Correct check-mode cache bypass.

This closes the stale-IR path for check runs while preserving normal caching behavior.

test/integration.test.ts (1)

3-3: Good cross-platform setup for the cache-bypass integration test.

Using path.delimiter and isolating cache state via temp cwd is the right approach.

Also applies to: 83-125

src/runtime/process-io.ts (1)

24-24: Strong transport fix: late timed-out responses are ignored, true unknown IDs still fail fast.

The tracker wiring and disposal cleanup are consistent, and the unmatched-ID handling now cleanly separates expected late arrivals from protocol desync.

Also applies to: 40-42, 186-188, 270-271, 284-285, 371-371, 609-615

docs/public/llms-full.txt (1)

55-55: Documentation updates align well with the bridge-centric configuration approach.

The shift from environment-variable-driven configuration to programmatic NodeBridge construction is consistently applied throughout the documentation. The updated experimental note correctly references the Releases page, and the environment variables section now appropriately emphasizes that Python path and virtual environment selection are configured via code or config files rather than env vars.

Also applies to: 772-806

docs/troubleshooting/index.md (1)

249-260: Consistent TypeScript bridge patterns in troubleshooting guidance.

The updated examples properly demonstrate NodeBridge instantiation with env options for thread tuning (OMP_NUM_THREADS, MKL_NUM_THREADS). This aligns with the bridge-centric configuration approach and provides actionable guidance for common runtime issues.

Also applies to: 296-306

docs/guide/runtimes/node.md (1)

293-317: Clear distinction between generation-time and runtime debugging.

The updated debugging section properly separates:

  1. CLI's --debug flag for wrapper generation diagnostics
  2. TYWRAP_LOG_LEVEL and TYWRAP_LOG_JSON for subprocess diagnostics
  3. Bridge instance options (timeoutMs: 0, env) for debugging-specific configurations

This provides a clear mental model for users troubleshooting different parts of the system.

tywrap_ir/tywrap_ir/optimized_ir.py (2)

208-246: Per-task warning collection and propagation implemented correctly.

The warning collection logic properly:

  1. Initializes a local warnings list per extraction
  2. Captures both timeout and general extraction errors
  3. Emits structured stderr output with emoji prefixes
  4. Passes warnings to IRModule construction

The broad Exception catch at line 230 is appropriate here since extraction failures should degrade gracefully to warnings rather than crashing the entire extraction process.


431-447: Global state preservation logic is well-designed.

The branching logic correctly:

  • Reuses _global_extractor for the default fast path (both caching and parallel enabled)
  • Creates a new local OptimizedIRExtractor for non-default options to avoid mutating global state

This ensures that calling extract_module_ir_optimized(..., enable_caching=False, ...) doesn't affect subsequent calls that rely on the default behavior.

tywrap_ir/tests/test_optimized_ir_parallel_warnings.py (2)

12-14: Clever error injection technique.

The generator throw pattern (_ for _ in ()).throw(RuntimeError("boom")) effectively creates a callable that raises when evaluated. This is a valid approach for injecting failures into the extraction pipeline.


19-23: Test correctly validates warning propagation.

The test verifies that:

  1. The result contains the expected module name
  2. A warnings key exists in the result
  3. The warning message includes the expected error format

The warning string "Error extracting functions from math: boom" matches the format defined in _extract_parallel at line 231 of optimized_ir.py.

tywrap_ir/tests/test_optimized_ir_options.py (2)

11-21: Proper test isolation with setUp/tearDown.

The explicit restoration of global extractor state in both setUp and tearDown ensures test isolation. This is important since the tests verify behavior that depends on global state (_global_extractor and _global_cache).


23-37: Tests correctly validate global state preservation and cache behavior.

The tests verify the two key behaviors from the implementation:

  1. Non-default options (enable_caching=False, enable_parallel=False) don't mutate the global extractor
  2. Default options use the shared cache, evidenced by cache hits increasing between extractions

Both tests align with the branching logic in extract_module_ir_optimized at lines 434-441 of optimized_ir.py.

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 `@tywrap_ir/tests/test_ir_async_generator_flags.py`:
- Line 2: Replace the typing-based iterator imports with the modern
collections.abc imports to satisfy Ruff UP035: change the import line that
currently reads using AsyncIterator and Iterator from the typing module to
import AsyncIterator and Iterator from collections.abc (look for the import
statement in test_ir_async_generator_flags.py that imports AsyncIterator,
Iterator).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fb1c0fef-0cb1-43f2-a32d-5f6fc175608d

📥 Commits

Reviewing files that changed from the base of the PR and between 4342335 and 31dfda4.

📒 Files selected for processing (3)
  • test/integration.test.ts
  • test/transport.test.ts
  • tywrap_ir/tests/test_ir_async_generator_flags.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use NODE_OPTIONS=--expose-gc environment variable for GC-sensitive tests

Files:

  • test/integration.test.ts
  • test/transport.test.ts
tywrap_ir/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Python code must follow PEP 8 and use type hints

Follow PEP 8 and use type hints in Python code

Files:

  • tywrap_ir/tests/test_ir_async_generator_flags.py
🧠 Learnings (18)
📓 Common learnings
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-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.
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following the `test/runtime_*.test.ts` patterns

Applied to files:

  • test/integration.test.ts
  • test/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following patterns in `test/runtime_*.test.ts`

Applied to files:

  • test/integration.test.ts
  • test/transport.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/integration.test.ts
  • test/transport.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/integration.test.ts
  • test/transport.test.ts
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/**/*.test.ts : Use `NODE_OPTIONS=--expose-gc` environment variable for GC-sensitive tests

Applied to files:

  • test/integration.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/integration.test.ts
  • test/transport.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/integration.test.ts
  • test/transport.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/integration.test.ts
  • test/transport.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/transport.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/transport.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/transport.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/transport.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/transport.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/transport.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/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to tywrap_ir/**/*.py : Follow PEP 8 and use type hints in Python code

Applied to files:

  • tywrap_ir/tests/test_ir_async_generator_flags.py
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to tywrap_ir/**/*.py : Python code must follow PEP 8 and use type hints

Applied to files:

  • tywrap_ir/tests/test_ir_async_generator_flags.py
🪛 Ruff (0.15.6)
tywrap_ir/tests/test_ir_async_generator_flags.py

[warning] 2-2: Import from collections.abc instead: AsyncIterator, Iterator

Import from collections.abc

(UP035)

🔇 Additional comments (5)
test/integration.test.ts (2)

3-3: LGTM!

The delimiter import is correctly added to support cross-platform PATH separator handling used in line 96 for constructing PYTHONPATH.


83-135: Well-structured test for cache bypass behavior.

The test correctly validates that check: true bypasses the IR cache:

  1. First run with caching: true populates the cache
  2. Python module is modified to introduce staleness
  3. Second run with check: true detects the stale file despite cached IR

The PYTHONPATH restoration in the finally block (lines 126-130) now correctly handles the undefined case by using delete instead of assignment, which prevents the Node.js coercion to the string "undefined".

test/transport.test.ts (2)

641-660: LGTM!

The test correctly validates the unexpected-response-ID failure path. The setup pattern is consistent with other ProcessIO tests, and the assertions properly verify both the error type and message content.


662-681: LGTM — addresses the late-response coverage gap.

This test validates the timedOutRequests.consume() path from process-io.ts: when a response arrives for an already-timed-out request, it's silently ignored instead of triggering a protocol error.

The sequence (await timeout → feed late response → assert no throw) correctly exercises the intended behavior.

tywrap_ir/tests/test_ir_async_generator_flags.py (1)

7-36: Good coverage of IR async/generator flag behavior.

The three tests validate the expected flag matrix clearly and directly.

Copy link
Owner Author

bbopen commented Mar 18, 2026

@CodeRabbit incremental review

A small follow-up fix just landed in d248b9e to address the Ruff UP035 import comment in tywrap_ir/tests/test_ir_async_generator_flags.py. Please take another look at the PR from that commit onward.

@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
git show d248b9e --stat
echo "---DIFF---"
git show d248b9e

Length of output: 897


@bbopen: The incremental change in d248b9e looks good. ✅

tywrap_ir/tests/test_ir_async_generator_flags.py

-from typing import AsyncIterator, Iterator
+from collections.abc import AsyncIterator, Iterator

This correctly resolves the Ruff UP035 violation — AsyncIterator and Iterator are canonical in collections.abc (the typing aliases have been deprecated since Python 3.9 and are slated for removal in a future Python release). The fix is minimal, accurate, and non-breaking. Nothing else changed in this commit, so there's nothing further to flag here.


🧠 Learnings used
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.

Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: runtime/python_bridge.py:99-123
Timestamp: 2026-01-19T21:49:05.612Z
Learning: In the tywrap repository, TYWRAP_REQUEST_MAX_BYTES uses strict integer parsing that rejects values with trailing characters (e.g., "1024abc"). This differs from TYWRAP_CODEC_MAX_BYTES, which uses tolerant/best-effort parsing that accepts numeric prefixes. The strict policy for REQUEST_MAX_BYTES ensures explicit integer values and consistent parse behavior across Node/Python implementations.

@bbopen bbopen merged commit 4114581 into main Mar 18, 2026
21 checks passed
@bbopen bbopen deleted the feat/tywrap-promotion branch March 18, 2026 01:28
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:codegen area:docs Area: documentation area:runtime area:runtime-node Area: Node runtime bridge area:tooling Area: tooling and CLI bug Something isn't working codex documentation Improvements or additions to documentation priority:p2 Priority P2 (medium)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants