Skip to content

[Chore] Correct Turbo cache inputs and add a build cache input contract - #2324

Draft
zoomote2[bot] wants to merge 2 commits into
mainfrom
fix/turbo-cache-inputs-2290
Draft

zoomote2[bot] wants to merge 2 commits into
mainfrom
fix/turbo-cache-inputs-2290

Conversation

@zoomote2

@zoomote2 zoomote2 Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

​Created by Roomote. Follow up by mentioning @roomote, in the web UI, or in Discord.

Related GitHub Issue

Closes: #2290

Description

This PR corrects the Turbo cache inputs for the build and static tasks. Identical inputs now reuse the cache. Changed inputs now invalidate the right tasks. The commits are split: the input corrections land first. The verification harness lands second.

Correctness fixes (commit 1):

  • turbo.json: build uses $TURBO_DEFAULT$ again. The old src/** list is package-relative. It missed package-root entry files such as webview-ui/index.html and public/**.
  • webview-ui/turbo.json: the webview build now hashes $TURBO_ROOT$/src/shared/** and $TURBO_ROOT$/src/package.json. Vite imports the shared source through the @roo/* alias. Vite reads the package version into PKG_VERSION. The build declares PKG_RELEASE_CHANNEL and VSCODE_TEXTMATE_DEBUG as env inputs. Both are embedded in the bundle by vite.config.ts. Webview check-types hashes the shared source too. Its tsconfig includes ../src/shared.
  • src/turbo.json: the extension bundle now hashes $TURBO_ROOT$/README.md, CHANGELOG.md, LICENSE, .env, and $TURBO_ROOT$/webview-ui/audio/**. esbuild copies all of these into dist. The bundle declares PKG_RELEASE_CHANNEL and POSTHOG_API_KEY as env inputs. Both are embedded by esbuild.mjs defines. vsix now hashes $TURBO_DEFAULT$, dist/**, and the generated packaging files. vsce reads README, CHANGELOG, LICENSE, and package.nls*.json; the old dist/**-only list missed them.
  • turbo.json: check-types depends on @roo-code/types#build. Consumers typecheck against the types package source (see its exports map). A types source change must invalidate every dependent typecheck.

Key discovery: Turbo 2.11.10 drops ../..-style input globs without any warning. Only $TURBO_ROOT$-prefixed paths hash files outside a package.

Reuse evaluation (issue step 3, no code change): code-qa.yml already persists .turbo/cache per OS with a lockfile and commit key. That is the simplest justified reuse. A shared Turbo remote cache would add credentials and a fork-PR write-permission boundary, and its cross-OS safety still needs proof. It stays an evaluation. No new cache service ships here. Release workflows run direct package scripts without Turbo, so release artifacts never come from a cache.

Audit notes:

  • The webview process.platform and PKG_SHA (git SHA) defines are unreferenced in webview source. The bundle output is OS- and SHA-independent today. Git metadata cannot cause false hits. CI cache keys already include the commit SHA.
  • Build outputs are byte-equivalent across Linux and Windows today. Turbo hashes do not carry the OS, so cache storage must stay OS-scoped. The existing per-OS keys do this.

Test Procedure

  • Run pnpm --dir src run verify:build-cache-inputs. The new contract creates a detached git worktree and probes turbo --dry=json hashes. It checks eleven cases: shared source, entry HTML, package version, repo-root packaging files, audio assets, release and debug env inputs, unrelated env isolation, types source coupling, and reuse stability.
  • Run pnpm --dir src run verify:coverage-cache-inputs. The existing contract still passes (9/9).
  • Before/after dry-run evidence: on the base commit, edits to index.html, src/shared/**, src/package.json, root README.md, webview audio, and PKG_RELEASE_CHANNEL changed none of the relevant hashes. On this branch, each edit invalidates the correct tasks, and identical inputs keep hashes stable.
  • Full gates: pnpm test passes (14/14 Turbo tasks; 12,455 tests). pnpm --dir src exec eslint --prune-suppressions --max-warnings=0 scripts/verify-build-cache-inputs.mjs adds no suppression entries. Prettier passes on all touched files.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I reviewed my own code with care.
  • Writing Style: The PR title and description use Simplified Technical English (ASD-STE100): short sentences, plain words, active voice, one idea per sentence, no contractions.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Test Helpers (test changes only): Shared test helpers (src/test-utils/, @/utils/test-utils) are used only for mechanical duplication; test intent and scenario-specific mocks remain visible.
  • Visual Snapshot (UI changes only): No UI change ships in this PR.
  • Documentation Impact: I checked if my changes need documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I read and agree to the Contributor Guidelines.

Visual Snapshots

None. This is a CI-only change. No rendered surface changes.

Videos (interaction / animation only)

None.

Documentation Updates

  • No documentation updates are required. The change is CI-only. No product behavior changes.

Additional Notes

  • Restoration time, bytes, hit rate, and runner-minute metrics need real CI runs. They will be read from this PR's first code-qa runs and reported on the issue.
  • Cache saves stay gated on job success. A cache miss or cache outage runs tasks normally. Fork PRs keep contents: read and no new credentials.

- Restore default ($TURBO_DEFAULT$) build inputs; the restrictive src/**
  list omitted package-root entry files such as the webview index.html.
- Hash shared extension source and src/package.json into the webview
  build, and shared source into webview typechecking, via $TURBO_ROOT$
  inputs (plain ../.. globs are silently dropped by Turbo).
- Declare PKG_RELEASE_CHANNEL and VSCODE_TEXTMATE_DEBUG as webview build
  env inputs, and PKG_RELEASE_CHANNEL and POSTHOG_API_KEY for the
  extension bundle; both are embedded in build output by esbuild/vite.
- Hash repo-root README, CHANGELOG, LICENSE, .env, and webview audio
  assets into the extension bundle; vsce packages copies of these that
  the old dist-only vsix inputs never invalidated.
- Couple check-types to @roo-code/types#build; consumers typecheck
  against the types package source, so its changes must invalidate.
Add src/scripts/verify-build-cache-inputs.mjs, following the existing
coverage cache-input contract pattern: a detached git worktree plus
turbo --dry=json probes assert that shared source, the webview entry
HTML, package version, repo-root packaging files, webview audio assets,
and release/debug env inputs invalidate the right tasks; identical
inputs stay reusable; unrelated env stays out of every hash.

Wire the contract into code-qa on both OS lanes so a stale webview or
extension bundle is never restored as a cache hit.
@coderabbitai

coderabbitai Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one): 1

  • coderabbit-review-active

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@zoomote2

zoomote2 Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor Author

3 issues outstanding. See session

  • webview-ui/turbo.json:7 — webview build/check-types hash only src/shared/**, but the shared import closure escapes into src/core/** (modes.ts → custom-instructions.ts → services/roo-config) and src/services/** (tools.ts → type-only runner.ts); edits there can restore a stale webview bundle or typecheck verdict, and the contract never probes the escape closure.
  • src/scripts/verify-build-cache-inputs.mjs:56 — worktreeCommit() silently falls back to HEAD when git stash create fails; the sibling coverage contract throws in this case, because the fallback silently verifies committed configs instead of the working tree (Windows quiet exit-1 with dirty tracked changes, real git errors).
  • src/turbo.json:240 — $TURBO_ROOT$/.env never reaches bundle outputs (define reads process env; the copy lands at src/.env, which .vscodeignore strips from the VSIX) — conservative cache misses only; keep with a comment or drop.

Reviewed ce56479

Comment thread webview-ui/turbo.json
"build": {
"outputs": ["../src/webview-ui/**"]
"outputs": ["../src/webview-ui/**"],
"inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/src/shared/**", "$TURBO_ROOT$/src/package.json"],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The hashed inputs stop at src/shared/**, but the shared-source import closure escapes the directory:

  • src/shared/modes.ts:12 runtime-imports ../core/prompts/sections/custom-instructions, which imports src/services/roo-config (@roo/modes is imported by 19 webview files, so the check-types closure typechecks both files, and the bundle includes them unless tree-shaking drops the function).
  • src/shared/tools.ts:5 type-imports ../services/destructive-command-guard/runner, which check-types also typechecks.

An edit to src/core/prompts/sections/custom-instructions.ts, src/services/roo-config/**, or src/services/destructive-command-guard/runner.ts changes the real typecheck/build results while the @roo-code/vscode-webview#build and #check-types hashes stay identical, so CI can restore a stale webview bundle or a stale typecheck verdict — the same false-hit class this PR exists to fix. The new contract only probes src/shared/package.ts, so it cannot catch this.

Suggested fix: hash the escape roots and pin the choice with a contract probe.

Suggested change
"inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/src/shared/**", "$TURBO_ROOT$/src/package.json"],
"build": {
"outputs": ["../src/webview-ui/**"],
"inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/src/shared/**", "$TURBO_ROOT$/src/core/**", "$TURBO_ROOT$/src/services/**", "$TURBO_ROOT$/src/package.json"],
"env": ["PKG_RELEASE_CHANNEL", "VSCODE_TEXTMATE_DEBUG"]
},
"check-types": {
"dependsOn": ["@roo-code/types#build"],
"inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/src/shared/**", "$TURBO_ROOT$/src/core/**", "$TURBO_ROOT$/src/services/**"]
}

Whole-directory globs trade hit rate for correctness; the narrower alternative is per-file entries for the three escape targets, but those rot when src/shared imports change. A contract case that edits custom-instructions.ts and asserts both tasks invalidate would pin whichever set you pick.

Comment on lines +56 to +60
const worktreeCommit = () => {
const result = spawnSync("git", ["stash", "create"], { cwd: root, encoding: "utf8" })
if (result.status === 0 && result.stdout.trim()) return result.stdout.trim()
return "HEAD"
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This silent HEAD fallback drops the guard the sibling contract has for the same call. git stash create can exit 1 with empty output on Windows when stale index metadata refreshes to a clean tracked tree — but if the tracked tree is actually dirty, falling back to HEAD here silently probes the last commit's committed turbo.json files instead of the working tree, so all eleven cases pass against stale config. Real git failures (lock contention, safe.directory) also land in this branch.

verify-coverage-cache-inputs.mjs:65-78 (stashCommit) handles exactly this: a quiet exit-1 is trusted only after git status --porcelain --untracked-files=no confirms a clean tracked tree, and everything else throws. Reusing that guard keeps local runs honest.

Comment thread src/turbo.json
"$TURBO_ROOT$/README.md",
"$TURBO_ROOT$/CHANGELOG.md",
"$TURBO_ROOT$/LICENSE",
"$TURBO_ROOT$/.env",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

.env never reaches the bundle output: esbuild.mjs takes POSTHOG_API_KEY from the process environment rather than the file, copyPaths lands it at src/.env, .vscodeignore has no !.env so vsce strips it from the VSIX, and it is not a declared task output. Hashing it can only add cache misses, never prevent a stale hit.

Fine to keep as intentional hardening — but then say so in a comment next to the entry, and consider correcting the PR description, which currently says esbuild copies all of these "into dist" (the copies land in the src/ package dir).

@codecov

codecov Bot commented Nov 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Review status

This PR was opened by an automated account. A human maintainer must verify the change intent, provenance, and validation before merging.

Current step: Mark the PR ready. Required CI must pass before CodeRabbit starts.

Review-state labels are managed by this workflow; do not edit them manually. community-approved is managed the same way — do not add or remove it manually. It signals a fresh community code approval for the current head as an advisory priority only; maintainer review is still required.

This branch has not been deployed

No deployments
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.

CI: correct Turbo cache inputs and improve shared task reuse

1 participant