Skip to content

fix: scope jiti transform cache by OpenClaw install#87745

Merged
steipete merged 3 commits into
openclaw:mainfrom
fuller-stack-dev:fix/version-jiti-cache
May 28, 2026
Merged

fix: scope jiti transform cache by OpenClaw install#87745
steipete merged 3 commits into
openclaw:mainfrom
fuller-stack-dev:fix/version-jiti-cache

Conversation

@fuller-stack-dev

@fuller-stack-dev fuller-stack-dev commented May 28, 2026

Copy link
Copy Markdown
Member

Summary

  • Scope plugin-loader jiti filesystem caches under TMPDIR/jiti/openclaw/<package-version>/<package-json-mtime-size> so generated transforms cannot be reused across OpenClaw upgrades or package reinstall locations.
  • Apply the same cache scoping to the CJS plugin SDK root alias path, which creates its own jiti loader outside the central plugin module loader.
  • Preserve jiti's guarded tmpdir behavior when TMPDIR resolves to process.cwd(), and preserve the documented JITI_FS_CACHE=false / JITI_CACHE=false opt-out.
  • Add regression coverage for the shared loader options, the central cached plugin loader, and the root alias CJS path.

Evidence from affected logs

  • product-poller.log:113830 dispatched the SeasonalFlush build.
  • product-poller.log:113845 recorded builder run 29aa0d05 failing for builder-pipeline-31ab1d36.
  • product-poller.log:113846 recorded: TypeError: (0 , _agentHarnessRuntime.projectRuntimeToolInputSchema) is not a function.
  • session-registry.jsonl:32 recorded the same failed builder session and error at 2026-05-28T16:21:00Z.
  • Local cache inspection showed stale generated jiti files under TMPDIR/jiti while the currently installed OpenClaw package exported projectRuntimeToolInputSchema correctly, which matches a stale transform-cache upgrade failure rather than project code failure.

Verification

  • node scripts/run-vitest.mjs src/plugins/sdk-alias.test.ts src/plugins/plugin-module-loader-cache.test.ts src/plugins/contracts/plugin-sdk-root-alias.test.ts
    • Passed: 3 files, 118 tests.
  • git diff --check
    • Passed.
  • node scripts/build-all.mjs
    • Passed: total 74.1s; includes tsdown, CLI bootstrap import guard, runtime postbuild, plugin SDK DTS/export checks, plugin asset copy, UI build, build metadata, and CLI compat generation.
  • node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental false --tsBuildInfoFile .artifacts/tsgo-cache/core-test-pr87745-fresh.tsbuildinfo
    • Passed locally.
  • node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo
    • Passed locally.
  • AUTOREVIEW_AUTO_TESTS=0 .agents/skills/autoreview/scripts/autoreview --mode branch --base upstream/main
    • Passed: autoreview clean: no accepted/actionable findings reported.

Real behavior proof

Behavior addressed: stale unversioned TMPDIR/jiti transforms can survive upgrades and be reused by OpenClaw plugin/runtime jiti loaders; the repair must not regress jiti's TMPDIR == process.cwd() guard or filesystem-cache env opt-outs.

Real environment tested: local OpenClaw source checkout on macOS with Node 24.14.0 and real jiti 2.7.0. The proof used createJiti() against a TypeScript fixture with a stale unversioned cache sentinel present under TMPDIR/jiti.

Exact steps or command run after this patch: created a temporary TMPDIR, wrote TMPDIR/jiti/stale-sentinel.cjs, loaded a TypeScript fixture through real jiti using buildPluginLoaderJitiOptions() from this patch, listed generated cache files, and separately checked the JITI_FS_CACHE=false option path.

Evidence after fix:

{
  "loaded": "versioned-cache",
  "fsCache": "/var/folders/04/4nmxfbmn44d21bwf7cqknhgc0000gn/T/openclaw-jiti-proof-ajI2Bi/jiti/openclaw/2026.5.28/1779995946163-105060",
  "staleUnversionedStillPresent": true,
  "generatedFileCount": 1,
  "generatedFileSample": [
    "openclaw-jiti-proof-ajI2Bi-fixture.79ae0ab5.cjs"
  ],
  "disabledFsCache": false
}

Additional validation output:

Test Files  3 passed (3)
Tests       118 passed (118)
[build-all] phase timings: total 74.1s; slowest tsdown 44.9s; write-plugin-sdk-entry-dts 11.7s; write-cli-startup-metadata 8.19s; build:plugin-sdk:dts 6.82s; ui:build 867ms
autoreview clean: no accepted/actionable findings reported
overall: patch is correct (0.78)

Observed result after fix: real jiti transformed and loaded the fixture from the versioned OpenClaw cache directory while the stale unversioned sentinel stayed present and unused; the loader options also return fsCache: false when JITI_FS_CACHE=false disables jiti filesystem caching.

What was not tested: no package-manager upgrade E2E was run; the focused proof covers the loader/root-alias cache behavior, the real jiti cache placement path, the env opt-out, and the full local build.

@openclaw-barnacle openclaw-barnacle Bot added size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 28, 2026
@clawsweeper

clawsweeper Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 28, 2026, 4:49 PM ET / 20:49 UTC.

Summary
The PR scopes jiti filesystem cache directories for the central plugin loader and CJS plugin SDK root-alias loader by OpenClaw package version and install metadata, while adding focused regression tests.

PR surface: Source +161, Tests +142. Total +303 across 6 files.

Reproducibility: Partially. Source inspection confirms current main uses jiti without OpenClaw-scoped fsCache on the two affected loader paths, and the PR body provides affected logs plus after-fix real jiti proof; I did not independently reproduce the packaged upgrade failure.

Review metrics: 1 noteworthy metric.

  • Jiti cache surfaces changed: 2 loader surfaces changed. Both the central plugin module loader and the CJS plugin SDK root alias create jiti loaders, so both cache paths must remain compatible before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Verify current-head required checks are green before merge.
  • [P2] Decide whether focused real-jiti proof is enough or whether a packaged upgrade smoke is required.

Risk before merge

  • [P1] This deliberately changes filesystem cache placement for existing jiti-backed plugin and SDK loading paths, so a bad cache key or unwritable cache location could surface as plugin/runtime import failures.
  • [P1] The PR body reports focused real-jiti proof but no package-manager upgrade E2E; maintainers should decide whether that proof is enough for an upgrade-sensitive cache change.
  • [P1] The provided PR state is mergeable but unstable, so current-head required checks still need to be green before merge.

Maintainer options:

  1. Accept the focused cache proof
    If current-head CI is green, maintainers can accept the real jiti fixture proof and regression tests as sufficient for this bounded loader cache fix.
  2. Request a packaged upgrade smoke
    Maintainers can ask for an install-or-upgrade smoke that leaves an old unversioned TMPDIR/jiti transform in place and confirms the patched package bypasses it.
  3. Pause if cache ownership is broader
    If maintainers want a wider cache lifecycle policy instead of a loader-local fix, pause this PR and move the decision into a broader plugin runtime ownership review.

Next step before merge

  • [P2] The remaining action is maintainer judgment on compatibility-sensitive cache behavior and proof sufficiency, not a narrow repair for automation.

Security
Cleared: No concrete security or supply-chain issue was found; the diff changes runtime cache path calculation and tests without touching dependencies, lockfiles, workflows, permissions, or secrets handling.

Review details

Best possible solution:

Merge after current-head CI is green and maintainers accept the focused jiti proof, or request one packaged upgrade smoke if they want end-to-end upgrade evidence before changing cache placement.

Do we have a high-confidence way to reproduce the issue?

Partially. Source inspection confirms current main uses jiti without OpenClaw-scoped fsCache on the two affected loader paths, and the PR body provides affected logs plus after-fix real jiti proof; I did not independently reproduce the packaged upgrade failure.

Is this the best way to solve the issue?

Yes, with maintainer acceptance of the proof level. The fix is narrow because it changes the two jiti loader creation points and preserves jiti's documented fsCache opt-outs instead of adding a new OpenClaw config surface.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against b5d90ae4ec39.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix real jiti proof showing a fixture loaded from a versioned OpenClaw cache while a stale unversioned sentinel remained unused, plus env opt-out output.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority plugin runtime upgrade bugfix with limited but real user impact.
  • merge-risk: 🚨 compatibility: The PR changes jiti filesystem cache directory selection for existing plugin and SDK loading paths used across upgrades.
  • merge-risk: 🚨 availability: A wrong cache location, key, or opt-out behavior could break plugin/runtime imports at startup or execution time.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix real jiti proof showing a fixture loaded from a versioned OpenClaw cache while a stale unversioned sentinel remained unused, plus env opt-out output.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix real jiti proof showing a fixture loaded from a versioned OpenClaw cache while a stale unversioned sentinel remained unused, plus env opt-out output.
Evidence reviewed

PR surface:

Source +161, Tests +142. Total +303 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 3 163 2 +161
Tests 3 142 0 +142
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 6 305 2 +303

What I checked:

  • Current main plugin loader lacks cache scoping: Current main builds plugin loader jiti options with interopDefault, tryNative, extensions, and aliases but no fsCache override, so jiti's default shared filesystem cache location is used. (src/plugins/sdk-alias.ts:1166, b5d90ae4ec39)
  • Current main root alias lacks cache scoping: Current main creates the root-alias jiti loader without an fsCache override on the legacy root SDK path. (src/plugin-sdk/root-alias.cjs:333, b5d90ae4ec39)
  • PR scopes plugin loader fsCache: The PR head adds fsCache to buildPluginLoaderJitiOptions via resolvePluginLoaderJitiFsCacheOption, deriving TMPDIR/jiti/openclaw//. (src/plugins/sdk-alias.ts:1247, aff0746ebf26)
  • PR scopes root-alias fsCache: The PR head applies the same package-version/install-marker cache path to the CJS plugin SDK root alias loader and preserves env opt-outs. (src/plugin-sdk/root-alias.cjs:329, aff0746ebf26)
  • Regression coverage added: The PR adds tests for version/install cache paths, TMPDIR guard behavior, env opt-outs, central loader options, and root-alias lazy loading. (src/plugins/sdk-alias.test.ts:2117, aff0746ebf26)
  • Dependency contract checked: jiti 2.7.0 documents fsCache as boolean|string, defaults to true, honors JITI_FS_CACHE, and uses node_modules/.cache/jiti or TMPDIR/jiti when true; the type definition also allows a custom string cache directory. (package.json:1852, b5d90ae4ec39)

Likely related people:

  • gumadeiras: Commit 802b9f6 added the root-alias shim and plugin startup cache/docs work that this PR now adjusts. (role: feature-history owner; confidence: high; commits: 802b9f6b1910; files: src/plugin-sdk/root-alias.cjs, src/plugins/sdk-alias.ts)
  • steipete: Recent commits on the loader/SDK runtime area include 27ae826 and 30a94df, which touched runtime alias and plugin-boundary behavior. (role: recent area contributor; confidence: medium; commits: 27ae826f6525, 30a94dfd3b7c; files: src/plugins/sdk-alias.ts, src/plugins/plugin-module-loader-cache.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels May 28, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 28, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 28, 2026
@fuller-stack-dev
fuller-stack-dev force-pushed the fix/version-jiti-cache branch from 8aef277 to fdc2a91 Compare May 28, 2026 19:32
@openclaw-barnacle openclaw-barnacle Bot added size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. proof: supplied External PR includes structured after-fix real behavior proof. and removed size: S proof: sufficient ClawSweeper judged the real behavior proof convincing. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 28, 2026
@fuller-stack-dev
fuller-stack-dev force-pushed the fix/version-jiti-cache branch from fdc2a91 to a6d2da7 Compare May 28, 2026 19:42
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels May 28, 2026
@clawsweeper clawsweeper Bot added the status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. label May 28, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 28, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels May 28, 2026
@steipete steipete self-assigned this May 28, 2026
@steipete

Copy link
Copy Markdown
Contributor

Pre-merge verification for PR 87745:

Commands run locally before merge:

git status -sb
git pull --ff-only
gh pr view 87745 --repo openclaw/openclaw --json number,title,state,isDraft,mergeable,reviewDecision,maintainerCanModify,author,headRefOid,baseRefOid,additions,deletions,changedFiles,url,statusCheckRollup
gh pr checks 87745 --repo openclaw/openclaw --watch=false

Observed result:

Local checkout clean on main after fast-forward pull.
PR state OPEN, draft false, mergeable MERGEABLE, maintainerCanModify true.
Head SHA aff0746ebf266f4be6ec7f1d92c705dee7262330.
LOC +305/-2 across 6 files.
No blocking findings in maintainer review.

Relevant passing CI/proof runs:

CI run 26601117143: preflight, build-artifacts, check-lint, check-prod-types, check-test-types, check-guards, plugin/SDK/channel/runtime shards passed.
Real behavior proof run 26601445285: passed.
CodeQL run 26601117126: selected Security High checks passed.
CodeQL Critical Quality run 26601117074: plugin-boundary, plugin-sdk-package-contract, network-runtime-boundary passed; unrelated/unselected shards skipped.
OpenGrep PR diff run 26601117137: passed.

Known proof gaps:

No package-manager upgrade E2E rerun by maintainer; PR proof covers real jiti cache placement, env opt-out, focused tests, build, tsgo, and autoreview.

@steipete
steipete merged commit 1610b49 into openclaw:main May 28, 2026
117 of 119 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 29, 2026
Scope jiti filesystem transform caches for OpenClaw plugin loaders by package version and package.json install metadata so stale transforms cannot survive upgrades or package reinstalls.

Covers the central plugin module loader and the plugin SDK root alias CJS loader, while preserving jiti filesystem-cache env opt-outs and the TMPDIR cwd guard.

Verification: CI run 26601117143 passed; Real behavior proof run 26601445285 passed; CodeQL selected checks passed in run 26601117126; CodeQL Critical Quality plugin-boundary and plugin-sdk-package-contract passed in run 26601117074; OpenGrep PR diff passed in run 26601117137.

Refs: openclaw#87745
Thanks @fuller-stack-dev.
steipete pushed a commit that referenced this pull request May 29, 2026
Scope jiti filesystem transform caches for OpenClaw plugin loaders by package version and package.json install metadata so stale transforms cannot survive upgrades or package reinstalls.

Covers the central plugin module loader and the plugin SDK root alias CJS loader, while preserving jiti filesystem-cache env opt-outs and the TMPDIR cwd guard.

Verification: CI run 26601117143 passed; Real behavior proof run 26601445285 passed; CodeQL selected checks passed in run 26601117126; CodeQL Critical Quality plugin-boundary and plugin-sdk-package-contract passed in run 26601117074; OpenGrep PR diff passed in run 26601117137.

Refs: #87745
Thanks @fuller-stack-dev.
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
Scope jiti filesystem transform caches for OpenClaw plugin loaders by package version and package.json install metadata so stale transforms cannot survive upgrades or package reinstalls.

Covers the central plugin module loader and the plugin SDK root alias CJS loader, while preserving jiti filesystem-cache env opt-outs and the TMPDIR cwd guard.

Verification: CI run 26601117143 passed; Real behavior proof run 26601445285 passed; CodeQL selected checks passed in run 26601117126; CodeQL Critical Quality plugin-boundary and plugin-sdk-package-contract passed in run 26601117074; OpenGrep PR diff passed in run 26601117137.

Refs: openclaw#87745
Thanks @fuller-stack-dev.
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
Scope jiti filesystem transform caches for OpenClaw plugin loaders by package version and package.json install metadata so stale transforms cannot survive upgrades or package reinstalls.

Covers the central plugin module loader and the plugin SDK root alias CJS loader, while preserving jiti filesystem-cache env opt-outs and the TMPDIR cwd guard.

Verification: CI run 26601117143 passed; Real behavior proof run 26601445285 passed; CodeQL selected checks passed in run 26601117126; CodeQL Critical Quality plugin-boundary and plugin-sdk-package-contract passed in run 26601117074; OpenGrep PR diff passed in run 26601117137.

Refs: openclaw#87745
Thanks @fuller-stack-dev.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants