Skip to content

fix: normalize OpenAPI metadata before Forge generation - #462

Merged
srikrsna merged 12 commits into
cloudflare:mainfrom
Swimburger:codex/forge-native-metadata
Nov 2, 2026
Merged

srikrsna merged 12 commits into
cloudflare:mainfrom
Swimburger:codex/forge-native-metadata

Conversation

@Swimburger

@Swimburger Swimburger commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Stream the prepared OpenAPI document through forge normalize --leave-old-extensions -.
  • Pipe the normalized document directly into the Forge generator plugin over stdin.
  • Propagate normalization, generation, and stream failures.
  • Use the same normalization contract in the synchronous generator test helper.
  • Add regression coverage for converting Fern command metadata before generation.

Why

Forge now reads only native x-forge-* metadata extensions. cf still consumes OpenAPI documents containing compatibility metadata from Fern, Cloudflare, and other sources, so it must normalize that metadata before invoking Forge.

--leave-old-extensions preserves the original vendor extensions for plugins while native x-forge-* keys drive Forge’s parser.

This PR pins the published Forge main artifact containing:

Output compatibility

The generated cf command surface is unchanged:

  • CI regenerated packages/cli/src/commands/_generated and found no drift.
  • Published commands.json and schemas.json are byte-identical to main.
  • cf --help and cf cli search "list zones" produce identical output.

Validation

  • pnpm check
  • Generated-command drift check
  • CLI tests on Linux, macOS, and Windows
  • Wrangler compatibility tests
  • CLI startup benchmark

@Swimburger
Swimburger requested a review from a team as a code owner October 30, 2026 19:57
@Swimburger
Swimburger requested a review from edmundhung October 30, 2026 19:57
@pkg-pr-new

pkg-pr-new Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
npm i https://pkg.pr.new/cf@462

commit: a5f97a5

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 71cd50fb.

This review, of 39972ab5

💬 Approved with comments — One WARNING: the Forge capability check scrapes --help with a regex, so normalization can be skipped silently. Also one INFO about tests and one SUGGESTION about the docs; nothing blocks the merge.

Findings: 1 warning · 1 info · 1 suggestion (1 is an inline comment on the diff)

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (1)

### [Code Quality] Capability detection scrapes `forge --help` with a regex. If the help layout changes, normalization is skipped with only a warning, and after the native-only parser lands that silently changes the generated commands.
- **File:** packages/cli/generator/normalize.ts:16

## INFO (1)

### [Code Quality] `normalizeOpenApi` has no direct test for either branch, and the test harness ignores its return value, so a broken detection would not show up in tests.
- **File:** packages/cli/src/__tests__/helpers/forge-cli.ts:222

## SUGGESTION (1)

### [Documentation] The pipeline docs say normalization always runs, but it is skipped when the installed Forge has no `normalize` command (as with the current pin). Say that it is conditional during the transition.
- **File:** docs/architecture.md:148

📋 Code Quality: ⚠️ 1 warning · 1 info

Capability detection by scraping help text can fail quietly, and the new helper has no direct tests.

Recommendation: 📝 Minor Comments

  • [WARNING] Capability detection scrapes forge --help with a regex. If the help layout changes, normalization is skipped with only a warning, and after the native-only parser lands that silently changes the generated commands. (packages/cli/generator/normalize.ts:16)
  • [INFO] normalizeOpenApi has no direct test for either branch, and the test harness ignores its return value, so a broken detection would not show up in tests. (packages/cli/src/__tests__/helpers/forge-cli.ts:222)
View full review
  • Capability detection (packages/cli/generator/normalize.ts:13-18): the check matches /^\s+normalize\b/m against the text of forge --help. If Forge changes how it lays out its help, the check returns false and normalization is skipped. In generate.ts that only prints a warning; in the test helper nothing is printed at all. Once the pin includes the native-only parser (cloudflare/forge#78), skipping normalization means Forge never sees the x-fern-* naming keys. Generated command groups and method names would then change, and that output gets committed. Asking Forge directly would be sturdier: run forge normalize --help and check the exit status. Better still, make a missing normalize a hard error once the pin is bumped.
  • Tests: no test covers either branch of normalizeOpenApi. The test harness at packages/cli/src/__tests__/helpers/forge-cli.ts:222 ignores the return value, so tests also run without normalization if detection breaks.

📝 Documentation: 💬 1 suggestion

The docs describe normalization as unconditional, but it is capability-detected.

Recommendation: 💬 Optional Nits

  • [SUGGESTION] The pipeline docs say normalization always runs, but it is skipped when the installed Forge has no normalize command (as with the current pin). Say that it is conditional during the transition. (docs/architecture.md:148)
View full review
  • packages/cli/AGENTS.md:74-75, packages/cli/AGENTS.md:163-164 and docs/architecture.md:148 describe normalization as an unconditional step. With the current Forge pin, normalizeOpenApi returns false and the step is skipped. Saying it runs "when the installed Forge supports normalize" would match the transition until the pin moves.

Reviewed commit: 39972ab5

Comment thread packages/cli/generator/normalize.ts Resolved

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 89688636.

This review, of 71cd50fb

⚠️ Minor issues — Two WARNINGs. When the Forge pin moves, forge normalize output larger than 1 MiB will make execFileSync throw and break pnpm generate. Capability detection by scraping --help can still skip normalization silently.

Findings: 2 warnings · 1 question · 1 info · 1 suggestion (2 are inline comments on the diff)

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (2)

### [Code Quality] The normalized OpenAPI document is read from stdout with `execFileSync`'s default 1 MiB `maxBuffer`. Once the Forge pin supports `normalize`, the full Cloudflare spec will exceed it, `ENOBUFS` is thrown and `pnpm generate` fails.
- **File:** packages/cli/generator/normalize.ts:19

### [Code Quality] Capability detection scrapes `forge --help` with a regex. If the help layout changes, normalization is skipped with at most a warning, and once Forge reads only native metadata the generated command names change.
- **File:** packages/cli/generator/normalize.ts:16

## INFO (1)

### [Code Quality] No test covers either branch of `normalizeOpenApi`, and the test harness falls back silently with `normalized ?? openapi`, so broken detection would not show up in tests.
- **File:** packages/cli/src/__tests__/helpers/forge-cli.ts:218

## SUGGESTION (1)

### [Documentation] Say that normalization is conditional during the Forge transition. It is skipped when the installed Forge has no `normalize` command.
- **File:** docs/architecture.md:149

## QUESTIONS (1)

### [Code Quality] Forge is now given `-` as its input path, with the spec on stdin. Does the currently pinned Forge build accept `-`? If not, generation breaks on the current pin.
- **File:** packages/cli/generate.ts:54

📋 Code Quality: ⚠️ 2 warnings · 1 question · 1 info

The normalize stdout read is capped by the default maxBuffer, the --help regex detection is still fragile, and the helper's branches have no tests. Also an open question on whether the current Forge pin accepts -.

Recommendation: ⚠️ Major Comments

  • [WARNING] The normalized OpenAPI document is read from stdout with execFileSync's default 1 MiB maxBuffer. Once the Forge pin supports normalize, the full Cloudflare spec will exceed it, ENOBUFS is thrown and pnpm generate fails. (packages/cli/generator/normalize.ts:19)
  • [WARNING] Capability detection scrapes forge --help with a regex. If the help layout changes, normalization is skipped with at most a warning, and once Forge reads only native metadata the generated command names change. (packages/cli/generator/normalize.ts:16)
  • [QUESTION] Forge is now given - as its input path, with the spec on stdin. Does the currently pinned Forge build accept -? If not, generation breaks on the current pin. (packages/cli/generate.ts:54)
  • [INFO] No test covers either branch of normalizeOpenApi, and the test harness falls back silently with normalized ?? openapi, so broken detection would not show up in tests. (packages/cli/src/__tests__/helpers/forge-cli.ts:218)
View full review
  • maxBuffer on the normalize call (packages/cli/generator/normalize.ts:19-23). Since 71cd50f, the normalized document comes back on stdout through execFileSync without a maxBuffer. Node's default is 1 MiB, and the serialized Cloudflare OpenAPI document is far larger. As soon as the Forge pin includes normalize, the call will throw ENOBUFS and stop pnpm generate and the Forge-backed test harness. The description promises the opposite: that normalization "turns on automatically" when the pin moves. Raise maxBuffer, or have Forge write to a temp file again.
  • Capability detection (packages/cli/generator/normalize.ts:16), still open. The check matches /^\s+normalize\b/m against the text of forge --help. If Forge changes its help layout, normalization is skipped: generate.ts prints only a warning, and the test helper prints nothing. Once Forge reads only native x-forge-* metadata, the generated group and method names change. Probing forge normalize --help and checking the exit status would be sturdier. A hard error once the pin moves would be better still.
  • Tests (packages/cli/src/__tests__/helpers/forge-cli.ts:222), still open. No test covers either branch of normalizeOpenApi. The harness falls back with normalized ?? openapi and never checks which branch ran.
  • Question: generate.ts and the test helper now pass - as the input path to Forge. That only keeps the current Forge pin working if the pinned build already reads a spec from stdin when given -. Can you confirm that?

📝 Documentation: 💬 1 suggestion

The pipeline docs still describe normalization as unconditional.

Recommendation: 💬 Optional Nits

  • [SUGGESTION] Say that normalization is conditional during the Forge transition. It is skipped when the installed Forge has no normalize command. (docs/architecture.md:149)
View full review

docs/architecture.md and packages/cli/AGENTS.md (around lines 74-75 and 163-165) describe normalization as an unconditional step. With the current Forge pin, normalizeOpenApi returns undefined and Forge gets the original document. Saying the step runs "when the installed Forge supports normalize" would match the code until the pin moves.


Reviewed commit: 71cd50fb

Comment thread packages/cli/generator/normalize.ts Resolved
Comment thread packages/cli/generator/normalize.ts Resolved

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of b3880076.

This review, of 89688636

💬 Approved with comments — The maxBuffer issue is fixed. One WARNING remains: brittle --help capability detection can silently skip normalization. There is also an open QUESTION on whether the pinned Forge accepts - as stdin input.

Findings: 1 warning · 1 question · 2 info · 1 suggestion (1 is an inline comment on the diff)

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (1)

### [Code Quality] Capability detection still scrapes `forge --help` with a regex, now duplicated in generate.ts and the test helper. If the help layout changes, normalization is skipped with only a warning, and once Forge reads only native `x-forge-*` metadata the generated group and method names change.
- **File:** packages/cli/generate.ts:254

## INFO (2)

### [Code Quality] No test covers either normalization branch. The harness picks the branch with the same regex and falls back to the raw spec, so a broken detection cannot fail a test.
- **File:** packages/cli/src/__tests__/helpers/forge-cli.ts:220

### [Code Quality] Forge is spawned before the `--help` probe, and its stdin streams have no `error` listeners. An early child exit can surface as an unhandled EPIPE instead of the `waitFor` error. Probe first and use `stream/promises` `pipeline`.
- **File:** packages/cli/generate.ts:261

## SUGGESTION (1)

### [Documentation] Update the architecture guide to describe the stdin pipeline and that normalization runs only when the installed Forge has `normalize`.
- **File:** docs/architecture.md:149

## QUESTIONS (1)

### [Code Quality] Does the currently pinned Forge build accept `-` as its input path and read the spec from stdin? generate.ts and the test harness now always pass `-`, including when `normalize` is absent. If the pinned build does not accept it, generation breaks on the current pin.
- **File:** packages/cli/generate.ts:246

📋 Code Quality: ⚠️ 1 warning · 1 question · 2 info

maxBuffer issue fixed. The --help regex detection, the missing test coverage and the - stdin question remain open, plus a small stream error-handling note.

Recommendation: 📝 Minor Comments

  • [WARNING] Capability detection still scrapes forge --help with a regex, now duplicated in generate.ts and the test helper. If the help layout changes, normalization is skipped with only a warning, and once Forge reads only native x-forge-* metadata the generated group and method names change. (packages/cli/generate.ts:254)
  • [QUESTION] Does the currently pinned Forge build accept - as its input path and read the spec from stdin? generate.ts and the test harness now always pass -, including when normalize is absent. If the pinned build does not accept it, generation breaks on the current pin. (packages/cli/generate.ts:246)
  • [INFO] No test covers either normalization branch. The harness picks the branch with the same regex and falls back to the raw spec, so a broken detection cannot fail a test. (packages/cli/src/__tests__/helpers/forge-cli.ts:220)
  • [INFO] Forge is spawned before the --help probe, and its stdin streams have no error listeners. An early child exit can surface as an unhandled EPIPE instead of the waitFor error. Probe first and use stream/promises pipeline. (packages/cli/generate.ts:261)
View full review
  • maxBuffer (fixed in generate.ts). The normalize output is now piped straight into Forge, so pnpm generate no longer depends on a stdout buffer. The test helper still uses execFileSync with the default 1 MiB limit (forge-cli.ts:226). Test specs are small, so this does not cause a failure today.
  • Capability detection (still open). packages/cli/generate.ts:254-256 and packages/cli/src/__tests__/helpers/forge-cli.ts:220-224 both match /^\s+normalize\b/m against the text of forge --help. Running forge normalize --help and checking its exit status would hold up better, and one shared helper would remove the duplicated check. A hard failure once the pin is known to support normalize would be safer than a warning.
  • Tests (still open). Nothing checks that normalization actually ran. A harness test with x-fern-sdk-* keys, skipped when normalize is unavailable, would catch a broken detection.
  • - as input (still open). See the QUESTION below.
  • Stream ordering and errors (generate.ts:242-271). Forge is spawned before the synchronous --help probe, and neither forge.stdin nor normalize.stdin has an error listener. If either child exits early, writing to its stdin can raise an unhandled EPIPE and crash with a confusing stack. The child's stderr is inherited, so the real error still reaches the terminal. Running the probe before spawning and using pipeline from node:stream/promises would make failures cleaner.

📝 Documentation: 💬 1 suggestion

The architecture guide still describes Forge reading openapi.json directly.

Recommendation: 💬 Optional Nits

  • [SUGGESTION] Update the architecture guide to describe the stdin pipeline and that normalization runs only when the installed Forge has normalize. (docs/architecture.md:149)
View full review
  • docs/architecture.md:149 still shows Forge reading openapi.json directly. The generator now sends the document through stdin. When the installed Forge supports it, the document goes through forge normalize - first (packages/cli/generate.ts:254-270). Update the pipeline description to match, and say that normalization is conditional during the transition.

Reviewed commit: 89688636

Comment thread packages/cli/generate.ts Resolved

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 2db0dc10.

This review, of b3880076

⚠️ Minor issues — The latest commit drops the --help capability detection. That fixes the earlier WARNING and answers the earlier stdin QUESTION. One WARNING remains with a build impact: generation now always calls forge normalize - and forge -, but the Forge pin at packages/cli/package.json:88 has not changed, so pnpm generate/pnpm build will fail until the pin is bumped.

Findings: 1 warning · 2 info · 1 suggestion (1 is an inline comment on the diff)

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (1)

### [Code Quality] Generation now always requires `forge normalize -` and stdin input (`forge -`), but the Forge pin at `packages/cli/package.json:88` is still `260488a2`, which the description says lacks cloudflare/forge#75 and #78. Merging before the pin bump breaks `pnpm generate`/`pnpm build` and the generator tests.
- **File:** packages/cli/generate.ts:241

## INFO (2)

### [Code Quality] The child stdin streams have no `error` handlers. An early exit of `normalize` or `forge` can surface as an unhandled EPIPE instead of the exit-code error. Use `pipeline` from `node:stream/promises`.
- **File:** packages/cli/generate.ts:244

### [Code Quality] No test checks that normalization converts compatibility metadata. The helper's `normalize` call also uses the default 1 MiB `maxBuffer`.
- **File:** packages/cli/src/__tests__/helpers/forge-cli.ts:221

## SUGGESTION (1)

### [Documentation] Update the architecture pipeline to show the prepared OpenAPI streamed through `forge normalize -` and then into Forge on stdin.
- **File:** docs/architecture.md:149

📋 Code Quality: ⚠️ 1 warning · 2 info

The --help scraping is gone and normalization is now always required. That is cleaner, but it needs a Forge pin bump this pull request does not include. The stream error handling is still fragile.

Recommendation: 📝 Minor Comments

  • [WARNING] Generation now always requires forge normalize - and stdin input (forge -), but the Forge pin at packages/cli/package.json:88 is still 260488a2, which the description says lacks cloudflare/forge#75 and #78. Merging before the pin bump breaks pnpm generate/pnpm build and the generator tests. (packages/cli/generate.ts:241)
  • [INFO] The child stdin streams have no error handlers. An early exit of normalize or forge can surface as an unhandled EPIPE instead of the exit-code error. Use pipeline from node:stream/promises. (packages/cli/generate.ts:244)
  • [INFO] No test checks that normalization converts compatibility metadata. The helper's normalize call also uses the default 1 MiB maxBuffer. (packages/cli/src/__tests__/helpers/forge-cli.ts:221)
View full review

Since the last review, the --help regex detection has been removed from both generate.ts and the test helper. The earlier WARNING about brittle capability detection, and the note about an untestable fallback branch, no longer apply. The earlier QUESTION about - as stdin input is now answered: it depends on the Forge pin, and the pin has not moved.

Hard dependency on a Forge build that is not pinned yet (packages/cli/generate.ts:229-245, packages/cli/src/__tests__/helpers/forge-cli.ts:220-236)

  • Both call sites now always run forge normalize - and pipe the result into forge - --target wasm://....
  • packages/cli/package.json:88 still pins @cloudflare/forge to 260488a2. The description says that build does not yet contain both cloudflare/forge#75 and cloudflare/forge#78.
  • Until the pin moves, pnpm generate fails, and so do pnpm build and pnpm check, which run generation, and every test that uses generateFiles. The description names this merge-order dependency, but nothing in the code enforces it. Bump the pin in this pull request, or hold the merge until the pin update can be included.

Early child exit (packages/cli/generate.ts:244-245)

  • Readable.from([openapi]).pipe(normalize.stdin!) and normalize.stdout!.pipe(forge.stdin!) do not handle error on the destination streams.
  • If normalize or forge exits early, for example on a Forge without the subcommand, writing to its stdin can emit an unhandled EPIPE. You then get a crash stack instead of the clear forge normalize exited with ... message. Using pipeline from node:stream/promises, or adding error listeners, would make the exit-code errors reliable.

Tests (packages/cli/src/__tests__/helpers/forge-cli.ts:220-224)

  • No test checks that normalization actually changes the document, for example that a spec with compatibility x-fern-* keys produces native-metadata output.
  • The helper's normalize execFileSync call uses the default 1 MiB maxBuffer. Today's test specs are small, so this is fine for now.

📝 Documentation: 💬 1 suggestion

The architecture guide still describes the old file-based Forge invocation.

Recommendation: 💬 Optional Nits

  • [SUGGESTION] Update the architecture pipeline to show the prepared OpenAPI streamed through forge normalize - and then into Forge on stdin. (docs/architecture.md:149)
View full review

docs/architecture.md:149 still shows Forge reading openapi.json directly. Generation now always streams the prepared document through forge normalize - and pipes the normalized output into Forge on stdin (packages/cli/generate.ts:229-245). Update the pipeline description to show this flow.


Reviewed commit: b3880076

Comment thread packages/cli/generate.ts Resolved

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 9f3b60ab.

This review, of 2db0dc10

⚠️ Minor issues — The earlier blocker is fixed: the Forge pin now points at a build with both Forge changes. One WARNING remains. That build is a release tarball on a personal fork, so the build and the tracked generated commands depend on an artifact outside cloudflare/forge, and the commit-pinned update flow cannot track it.

Findings: 1 warning · 2 info · 1 suggestion (1 is an inline comment on the diff)

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (1)

### [Code Quality] `@cloudflare/forge` is now pinned to a release tarball on a personal fork, not a commit-pinned cloudflare/forge pkg.pr.new build. Generated commands would be built from an artifact outside the upstream repository; the asset can be deleted, which breaks installs; and the commit-digest update flow cannot track the pin.
- **File:** packages/cli/package.json:88

## INFO (2)

### [Code Quality] The child stdin pipes have no `error` handlers. An early exit of `normalize` or `forge` can surface as an unhandled EPIPE instead of the exit-code error. Use `pipeline` from `node:stream/promises`.
- **File:** packages/cli/generate.ts:244

### [Code Quality] No test checks that normalization converts compatibility metadata. The helper's synchronous `normalize` call also uses the default 1 MiB `maxBuffer`.
- **File:** packages/cli/src/__tests__/helpers/forge-cli.ts:221

## SUGGESTION (1)

### [Documentation] Update the architecture pipeline to show the prepared OpenAPI streamed through `forge normalize -` and then into Forge on stdin.
- **File:** docs/architecture.md:149

📋 Code Quality: ⚠️ 1 warning · 2 info

The Forge pin now uses a personal-fork release tarball. Two earlier INFO notes still apply.

Recommendation: 📝 Minor Comments

  • [WARNING] @cloudflare/forge is now pinned to a release tarball on a personal fork, not a commit-pinned cloudflare/forge pkg.pr.new build. Generated commands would be built from an artifact outside the upstream repository; the asset can be deleted, which breaks installs; and the commit-digest update flow cannot track the pin. (packages/cli/package.json:88)
  • [INFO] The child stdin pipes have no error handlers. An early exit of normalize or forge can surface as an unhandled EPIPE instead of the exit-code error. Use pipeline from node:stream/promises. (packages/cli/generate.ts:244)
  • [INFO] No test checks that normalization converts compatibility metadata. The helper's synchronous normalize call also uses the default 1 MiB maxBuffer. (packages/cli/src/__tests__/helpers/forge-cli.ts:221)
View full review

The earlier WARNING is fixed. packages/cli/package.json:88 now pins a Forge build that includes cloudflare/forge#75 and #78, and generation needs that build for forge normalize - and forge -.

Forge pinned to a personal-fork release asset (packages/cli/package.json:88, pnpm-lock.yaml:297,723)

  • The pin moved from https://pkg.pr.new/cloudflare/forge/@cloudflare/forge@<sha> to https://github.com/Swimburger/forge/releases/download/cf-462-forge-native-5bd8f6e/cloudflare-forge-0.1.0.tgz.
  • The repository convention is to install Forge from a commit-pinned pkg.pr.new build of cloudflare/forge. docs/architecture.md:153,753,838 say the same.
  • The generator runs this package, and its output becomes the tracked _generated/ commands. That code would come from an artifact outside the upstream repository, built from unmerged changes.
  • A release asset on a fork can be replaced or deleted. The lockfile integrity hash catches a replaced file, but it cannot keep the install working once the asset is gone.
  • The commit-digest update flow cannot bump or validate a release-URL pin.
  • If the pin is meant as a temporary preview, hold the merge. Once cloudflare/forge has a pkg.pr.new build with both changes, pin that commit, regenerate the lockfile, and commit any _generated/ changes the new build produces.

Early child exit (packages/cli/generate.ts:244-245)

  • Readable.from([openapi]).pipe(normalize.stdin!) and normalize.stdout!.pipe(forge.stdin!) do not handle error events on the destination streams.
  • If a child exits early, writing to its stdin can raise an unhandled EPIPE. The clear exit-code message is then never reached.
  • pipeline from node:stream/promises propagates these errors.

Test helper (packages/cli/src/__tests__/helpers/forge-cli.ts)

  • No test checks that compatibility metadata becomes native x-forge-* metadata.
  • The synchronous normalize call uses the default 1 MiB maxBuffer.

📝 Documentation: 💬 1 suggestion

The architecture pipeline does not yet show the normalize step.

Recommendation: 💬 Optional Nits

  • [SUGGESTION] Update the architecture pipeline to show the prepared OpenAPI streamed through forge normalize - and then into Forge on stdin. (docs/architecture.md:149)
View full review

docs/architecture.md:149 still shows Forge reading openapi.json directly. Generation now streams the prepared document through forge normalize - and pipes the result into Forge on stdin. The lines in that file that say Forge comes from pkg.pr.new (153, 753, 838) are correct only once the pin goes back to a pkg.pr.new build. That is covered by the pin finding.


Reviewed commit: 2db0dc10

Comment thread packages/cli/package.json Resolved

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 2fc94608.

This review, of 9f3b60ab

⚠️ Minor issues — One WARNING is still open. @cloudflare/forge is pinned to a release tarball on a personal fork, so the tracked generated commands are built from an artifact outside cloudflare/forge. If that asset is removed, installs break.

Findings: 1 warning (1 is an inline comment on the diff)

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (1)

### [Code Quality] `@cloudflare/forge` is pinned to a release tarball on the personal fork Swimburger/forge, not a commit-pinned cloudflare/forge pkg.pr.new build. Generated commands come from an artifact outside the upstream repository, and installs break if that asset is removed.
- **File:** packages/cli/package.json:88

📋 Code Quality: ⚠️ 1 warning

The Forge pin still points at a release tarball on a personal fork. The streaming changes look correct.

Recommendation: 📝 Minor Comments

  • [WARNING] @cloudflare/forge is pinned to a release tarball on the personal fork Swimburger/forge, not a commit-pinned cloudflare/forge pkg.pr.new build. Generated commands come from an artifact outside the upstream repository, and installs break if that asset is removed. (packages/cli/package.json:88)
View full review

Forge pinned to a release asset on a personal fork (packages/cli/package.json:88, pnpm-lock.yaml)

  • The pin is https://github.com/Swimburger/forge/releases/download/cf-462-forge-native-5bd8f6e/cloudflare-forge-0.1.0.tgz. The repository's rule is that shared Forge code comes from a commit-pinned pkg.pr.new build of cloudflare/forge.
  • The generator runs this package, and its output becomes the tracked _generated/ commands. Those commands would be built from unmerged changes in an artifact outside the upstream repository.
  • A release asset on a fork can be deleted, which breaks installs. The lockfile integrity hash catches a replaced file, but not a missing one.
  • The commit-digest update flow cannot bump or validate a pin that points at a release URL.
  • If the pin is meant to be temporary, hold the merge. Once cloudflare/forge has a pkg.pr.new build with both #75 and #78, pin that commit, regenerate the lockfile, and commit any _generated/ changes the new build produces.

The streaming refactor in packages/cli/generate.ts is clean. execFileSync is still used, and the temp-file helpers that are no longer needed have been removed.

Two earlier INFO notes on unchanged code are still open: the child stdin pipes have no error handlers, and no test checks that normalization converts compatibility metadata.


✅ All other checks passed

📝 Documentation: ✅ LGTM

No new documentation issues. One earlier suggestion is still open: update the pipeline in docs/architecture.md to show the prepared document going through forge normalize - and then into Forge on stdin.


Reviewed commit: 9f3b60ab

Comment thread packages/cli/package.json Resolved

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 478011b9.

This review, of 2fc94608

⚠️ Minor issues — One WARNING is still open. @cloudflare/forge is pinned to a release tarball on a personal fork, so the tracked generated commands are built from an artifact outside cloudflare/forge, and installs break if that asset is removed.

Findings: 1 warning · 1 info · 1 suggestion

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (1)

### [Code Quality] `@cloudflare/forge` is pinned to a release tarball on the personal fork Swimburger/forge, not a commit-pinned cloudflare/forge pkg.pr.new build. Generated commands come from an artifact outside the upstream repository, and installs break if that asset is removed.
- **File:** packages/cli/package.json:88

## INFO (1)

### [Code Quality] The child stdin pipes have no `error` handlers. If forge exits early, the write to its stdin fails with an unhandled EPIPE, and the script crashes with a stack trace instead of the clear exit-code error. `stream.pipeline` would handle this.
- **File:** packages/cli/generate.ts:241

## SUGGESTION (1)

### [Documentation] Update the pipeline in `docs/architecture.md` to show the prepared document going through `forge normalize --leave-old-extensions -` and then into Forge on stdin.
- **File:** docs/architecture.md:146

📋 Code Quality: ⚠️ 1 warning · 1 info

The Forge pin still points at a release asset on a personal fork (WARNING). The child stdin pipes still have no error handling (INFO).

Recommendation: 📝 Minor Comments

  • [WARNING] @cloudflare/forge is pinned to a release tarball on the personal fork Swimburger/forge, not a commit-pinned cloudflare/forge pkg.pr.new build. Generated commands come from an artifact outside the upstream repository, and installs break if that asset is removed. (packages/cli/package.json:88)
  • [INFO] The child stdin pipes have no error handlers. If forge exits early, the write to its stdin fails with an unhandled EPIPE, and the script crashes with a stack trace instead of the clear exit-code error. stream.pipeline would handle this. (packages/cli/generate.ts:241)
View full review

Forge pinned to a release asset on a personal fork (packages/cli/package.json:88, pnpm-lock.yaml)

  • The pin is https://github.com/Swimburger/forge/releases/download/cf-462-forge-native-5bd8f6e/cloudflare-forge-0.1.0.tgz. The repository's rule is that shared Forge code comes from a commit-pinned pkg.pr.new build of cloudflare/forge.
  • generate.ts runs this package, and its output becomes the tracked _generated/ commands. Those commands would be built from an artifact outside the upstream repository.
  • A release asset on a fork can be deleted, which breaks installs. The lockfile integrity hash catches a replaced file, but not a missing one.
  • If the pin is meant to be temporary, hold the merge. Once cloudflare/forge has a pkg.pr.new build with #75, #78 and the --leave-old-extensions option, pin that commit, regenerate the lockfile, and commit any _generated/ changes the new build produces.

stdin pipe error handling (packages/cli/generate.ts:240-241)

  • Readable.from(...).pipe(normalize.stdin!) and normalize.stdout!.pipe(forge.stdin!) have no error listeners.
  • If forge exits early, for example on a plugin error, the write to forge.stdin fails with EPIPE. That error is unhandled, so the script crashes with a stack trace instead of the clear forge exited with … message.
  • stream.pipeline would handle this. So would error handlers on both stdin streams.

The streaming change and the test helper's execFileSync normalize step look correct. One earlier note is still open: no test checks that normalization actually converts compatibility metadata.


📝 Documentation: 💬 1 suggestion

The architecture reference still shows the old generation pipeline.

Recommendation: 💬 Optional Nits

  • [SUGGESTION] Update the pipeline in docs/architecture.md to show the prepared document going through forge normalize --leave-old-extensions - and then into Forge on stdin. (docs/architecture.md:146)
View full review
  • docs/architecture.md:146-150 still shows forge openapi.json as the generation step. Update it to show the prepared JSON going through forge normalize --leave-old-extensions - and then into Forge on stdin. Once the pin is fixed, also make sure the Forge install description (docs/architecture.md:153) matches the actual pin.

Reviewed commit: 2fc94608

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of a0fe388c.

This review, of 478011b9

⚠️ Minor issues — One WARNING is still open, with a production impact: the shipped generated commands are built from a Forge release tarball on a personal fork, and installs break if that asset is removed. The pipeline fixes from the last review are in place.

Findings: 1 warning · 1 info

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #462.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (1)

### [Code Quality] `@cloudflare/forge` is pinned to a release tarball on the personal fork Swimburger/forge, not a commit-pinned cloudflare/forge build. The generated commands that ship would come from an artifact outside the upstream repository, and installs break if the asset is removed.
- **File:** packages/cli/package.json:88

## INFO (1)

### [Documentation] `docs/architecture.md` (dependency-update sections) and `scripts/README.md` still describe Forge as installed from pkg.pr.new. They become accurate again once the temporary fork pin is replaced. Update them only if the fork pin stays.
- **File:** scripts/README.md:10

📋 Code Quality: ⚠️ 1 warning

The stdin error handling is fixed with pipeline. The Forge pin to a personal-fork release asset is still open.

Recommendation: 📝 Minor Comments

  • [WARNING] @cloudflare/forge is pinned to a release tarball on the personal fork Swimburger/forge, not a commit-pinned cloudflare/forge build. The generated commands that ship would come from an artifact outside the upstream repository, and installs break if the asset is removed. (packages/cli/package.json:88)
View full review

Forge pinned to a release asset on a personal fork (packages/cli/package.json:88, pnpm-lock.yaml)

  • The pin is https://github.com/Swimburger/forge/releases/download/cf-462-forge-native-5bd8f6e/cloudflare-forge-0.1.0.tgz. The repository rule is that shared Forge code comes from a commit-pinned pkg.pr.new build.
  • generate.ts runs this package, and its output becomes the tracked _generated/ commands that ship in the CLI. Those commands would come from an artifact outside cloudflare/forge.
  • A release asset on a fork can be deleted. The lockfile integrity hash catches a replaced file, but not a missing one, so installs would break.
  • Fix: once cloudflare/forge has a build with #75 and #78, pin that commit, regenerate the lockfile and commit any _generated/ changes.

Pipeline error handling (packages/cli/generate.ts:231-258): fixed. Both transfers go through pipeline, and exit codes are checked before the pipeline error, so the error messages are clear.


📝 Documentation: 💬 1 info

The pipeline diagram is updated. Other docs still describe Forge as installed from pkg.pr.new.

Recommendation: 💬 Optional Nits

  • [INFO] docs/architecture.md (dependency-update sections) and scripts/README.md still describe Forge as installed from pkg.pr.new. They become accurate again once the temporary fork pin is replaced. Update them only if the fork pin stays. (scripts/README.md:10)
View full review
  • The previous suggestion is fixed: docs/architecture.md:149-150 shows the normalize step piped into Forge.
  • docs/architecture.md (dependency-update sections around lines 751-754 and 839) and scripts/README.md:10-12 still say Forge is installed from pkg.pr.new and that Renovate tracks those builds. These docs describe the intended state, so they become accurate again once the pin goes back to a cloudflare/forge build. If the fork pin is kept, update them.

✅ All other checks passed

🔒 Security: ✅ LGTM

The normalization and generation steps pass the document over stdin and stdout. spawn and execFileSync take argument arrays and no shell, so there is no injection risk. The supply-chain side of the Forge pin to a personal fork (one account controls the asset, and the tarball is not proven to be built from reviewed source) is part of the Code Quality finding at packages/cli/package.json:88.


📖 AGENTS.md: ✅ LGTM

AGENTS.md says shared Forge code comes from a commit-pinned pkg.pr.new build. That is the intended state, and the fork pin breaks it. This is covered by the Code Quality finding at packages/cli/package.json:88, so AGENTS.md itself does not need to change.


⚡ Performance: ✅ LGTM

Streaming the prepared JSON through forge normalize into forge replaces a temp-file write and runs once per generation. The test helper's synchronous calls only run in tests.


Reviewed commit: 478011b9

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 3b2f51c1.

This review, of a0fe388c

✅ Approved — The Forge pin now points to a commit-pinned pkg.pr.new build of upstream cloudflare/forge, which fixes the one open warning. No new issues were found.

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.


✅ All checks passed

🔒 Security: ✅ LGTM

  • Forge dependency: it is now pinned to a full commit hash of upstream cloudflare/forge, and the lockfile records an integrity hash. This closes the earlier concern about an artifact hosted on a personal fork.
  • Commands: spawn and execFileSync take argument arrays and no shell, so there is no injection risk.

📖 AGENTS.md: ✅ LGTM

The change now follows the repository rule that shared Forge code is installed from a commit-pinned pkg.pr.new build.


📋 Code Quality: ✅ LGTM

  • Forge pin: fixed. packages/cli/package.json:88 now pins https://pkg.pr.new/cloudflare/forge/@cloudflare/forge@5bd8f6e096e864f99f8a6346745d8021dc6e4ba0, and pnpm-lock.yaml uses the same specifier and tarball.
  • generate.ts pipeline: a failure to start a process rejects. Exit codes are checked before pipeline errors, and EPIPE from an early exit is captured.
  • Test helper: it follows the same normalize-then-generate flow, and the new normalization test checks that compatibility metadata is converted before Forge parses it.

⚡ Performance: ✅ LGTM

The prepared JSON is streamed through forge normalize into forge without a temp file, once per generation. The synchronous calls in the test helper only run in tests.


📝 Documentation: ✅ LGTM

The Forge pin is back on pkg.pr.new, so docs/architecture.md and scripts/README.md are accurate again. docs/architecture.md describes the normalize step piped into Forge.


Reviewed commit: a0fe388c

@petebacondarwin

Copy link
Copy Markdown
Collaborator

Blocked on merge of cloudflare/forge#78

Comment thread packages/cli/package.json Resolved

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of 3c84b480.

This review, of 3b2f51c1

✅ Approved — The only change since the last approved review moves the Forge pin to another full-commit pkg.pr.new build of upstream cloudflare/forge. package.json and the lockfile agree on it, and no issues were found. Merging still has to wait for cloudflare/forge#78, as @​petebacondarwin noted.

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.


✅ All checks passed

🔒 Security: ✅ LGTM

  • Forge dependency: still pinned to a full commit hash on the upstream cloudflare/forge pkg.pr.new path, and the lockfile records an integrity hash.
  • Commands: spawn and execFileSync still take argument arrays with no shell, so there is no injection risk.

📖 AGENTS.md: ✅ LGTM

The change still follows the repository rule that shared Forge code is installed from a commit-pinned pkg.pr.new build.


📋 Code Quality: ✅ LGTM

  • Forge pin: packages/cli/package.json:88 now points to https://pkg.pr.new/cloudflare/forge/@cloudflare/forge@ae774751262f6da3fee1a3b8941b089973de50a2. pnpm-lock.yaml uses the same specifier and tarball and records an integrity hash.
  • generate.ts pipeline and test helper: these have not changed since the last review. The normalize-then-generate flow and its error handling are still as reviewed there.
  • Merge timing: @​petebacondarwin pointed out that the pinned build comes from a pull request, not from Forge main. This pull request should wait until cloudflare/forge#78 is merged and the pin points to a build that contains it.

⚡ Performance: ✅ LGTM

Nothing that affects performance has changed since the last review.


📝 Documentation: ✅ LGTM

The documentation still matches the code: the Forge package is installed from a commit-pinned pkg.pr.new build, and the normalize step is piped into Forge.


Reviewed commit: 3b2f51c1

@Swimburger
Swimburger force-pushed the codex/forge-native-metadata branch from 3b2f51c to 3c84b48 Compare November 2, 2026 18:29

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of f1e38216.

This review, of 3c84b480

💬 Approved with comments — The normalize-then-generate pipeline is correct and the dependency pin is consistent; the only note is an INFO about contributor docs in packages/cli/AGENTS.md not mentioning the normalize step. Merging still has to wait for cloudflare/forge#78.

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.


✅ All checks passed

🔒 Security: ✅ LGTM

The Forge dependency is pinned to a full commit hash on the upstream pkg.pr.new path, and the lockfile records its integrity. spawn and execFileSync take argument arrays and use no shell, so there is no command injection risk.


📖 AGENTS.md: ✅ LGTM

  • packages/cli/AGENTS.md:73-77 says pnpm generate prepares the document and runs forge --target wasm://generator/cli.wasm on it. It does not mention the forge normalize --leave-old-extensions - step that is now required, or that the normalized output is piped into Forge on stdin. One sentence there would help contributors who change generation keep normalization in place.

📋 Code Quality: ✅ LGTM

  • packages/cli/generate.ts: both spawn calls are awaited through once(..., "close"). A spawn failure rejects the same Promise.all that waits on the stream transfer, so generation cannot hang. Exit codes are checked normalize first, then forge, then the pipeline error, and signal exits are reported through the ?? signal fallback.
  • packages/cli/src/__tests__/helpers/forge-cli.ts: the helper follows the same normalize-then-generate contract through execFileSync with input. Failures from either step go through the existing stderr-to-Error handling.
  • normalization.test.ts: the test expects Fern-named commands in the generated output, so it would fail if normalization were skipped.
  • packages/cli/package.json / pnpm-lock.yaml: the specifier, tarball and version match in both files, and the lockfile records an integrity hash. The pin is still a pull request build, so merging has to wait for cloudflare/forge#78.

⚡ Performance: ✅ LGTM

The pipeline in generate.ts streams the document, so it does not hold a second buffer or write a temp file. The synchronous test helper buffers output through execFileSync's default maxBuffer, which is enough for the small test specs it handles.


📝 Documentation: ✅ LGTM

docs/architecture.md describes the new normalize-then-generate pipeline, and the description matches the code.


Reviewed commit: 3c84b480

@clanky-the-clanker clanky-the-clanker Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superseded by the review of a5f97a50.

This review, of f1e38216

✅ Approved — No new issues: the updated Forge pin matches between package.json and the lockfile, and the pipeline code has not changed since the last review. Merging still depends on the pinned Forge build containing cloudflare/forge#78.

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.


✅ All checks passed

🔒 Security: ✅ LGTM

The dependency is pinned to a full commit hash, and the lockfile records its integrity. The child-process calls pass argument arrays without a shell.


📖 AGENTS.md: ✅ LGTM

No new issues in the changed files.


📋 Code Quality: ✅ LGTM

The Forge pin in packages/cli/package.json and pnpm-lock.yaml uses the same commit hash 5879d90b… for the specifier, version, tarball and snapshot key, and the lockfile has a new integrity hash. The generator, test helper and normalization test have not changed since the last review.


⚡ Performance: ✅ LGTM

No performance concerns.


📝 Documentation: ✅ LGTM

docs/architecture.md describes the normalize-then-generate pipeline accurately.


Reviewed commit: f1e38216

@Swimburger Swimburger changed the title fix: normalize metadata before Forge generation fix: normalize OpenAPI metadata before Forge generation Nov 2, 2026
@srikrsna
srikrsna enabled auto-merge November 2, 2026 19:23

@clanky-the-clanker clanky-the-clanker Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Approved — No issues found. The updated Forge pin matches between package.json and the lockfile, and the pipeline code has not changed since the last review. Merging still depends on the pinned Forge build containing cloudflare/forge#78.

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.


✅ All checks passed

🔒 Security: ✅ LGTM

The dependency is pinned to a full commit hash, and the lockfile records its integrity. The child-process calls pass argument arrays without a shell.


📖 AGENTS.md: ✅ LGTM

No issues in the changed files.


📋 Code Quality: ✅ LGTM

The Forge pin in packages/cli/package.json and pnpm-lock.yaml uses the same commit hash for the specifier, version, tarball and snapshot key, and the lockfile has a new integrity hash. The pipeline in generate.ts, the test helper and the normalization test have not changed since the last review. They still handle errors correctly.


⚡ Performance: ✅ LGTM

No performance concerns. The pipeline now streams the document between processes.


📝 Documentation: ✅ LGTM

docs/architecture.md describes the normalize-then-generate pipeline accurately.


Reviewed commit: a5f97a50

@srikrsna
srikrsna added this pull request to the merge queue Nov 2, 2026
@srikrsna srikrsna removed the blocked label Nov 2, 2026
Merged via the queue into cloudflare:main with commit 08cc496 Nov 2, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants