fix(ui): bounded negative cache + in-page fallback for dynamic parser loader - #252
Open
claudegoogl-sudo wants to merge 2 commits into
Open
fix(ui): bounded negative cache + in-page fallback for dynamic parser loader#252claudegoogl-sudo wants to merge 2 commits into
claudegoogl-sudo wants to merge 2 commits into
Conversation
… loader The dynamic parser loader permanently cached Web-Worker init failures, so devices where the sandboxed worker never initialises rendered raw process-fallback output on run pages forever, regardless of reloads. - Failed loads (parser 404, worker-init failure, unusable fallback) are now negative-cached for 60s instead of permanently: retry is allowed after the TTL, and invalidateDynamicParser still clears it at once. - When the sandboxed worker fails to init, the parser is evaluated in-page via the same CJS-shim semantics the worker bootstrap uses (exports/module shims, self/globalThis shadowed, strict-mode block wrap). The parser source is board-served, display-only code from the same origin as the UI bundle, so the fallback runs it at the bundle's own trust level; only parseStdoutLine is wired up and parse errors degrade to [] exactly like the worker path. - Focused unit tests cover: worker path still preferred, in-page fallback activation + sync results, fallback parse-error degradation, 404 and worker+fallback failure TTLs, and invalidate clearing the negative cache. This formalises a hotfix that was previously only patched into built dist assets (a source rebuild would silently regress it). Co-Authored-By: Paperclip <noreply@paperclip.ing>
Owner
Author
|
SE sign-off posted on PLA-4433: APPROVED — mergeable as-is. One non-blocking should-fix: amend the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thinking Path
Linked Issues or Issue Description
No public GitHub issue exists. Problem description (bug-report shape):
masterof this repository (loader atui/src/adapters/dynamic-loader.ts); fix previously validated as a patched dist bundle on a live deployment before being ported to source here.What Changed
ui/src/adapters/dynamic-loader.tsfailedLoadsSet with a TTL-bounded negative cache (failedLoadRetryAtmap,FAILED_LOAD_RETRY_MS = 60_000): parser 404s, worker-init failures, and unusable fallbacks are all retried after ≤60s instead of never.buildInPageFallbackParser(): wheninitSandboxedWorkerrejects, the already-fetched parser source is evaluated in-page using the same semantics as the worker bootstrap (CJSexports/moduleshims,self/globalThisshadowed toundefined, strict-mode block wrap). OnlyparseStdoutLineis wired; parse errors degrade to[]exactly like the worker's own error handling. Trust level: the parser source is board-served, display-only code from the same origin as the UI bundle that evaluates it — strictly weaker isolation than the worker, but only reached after the worker path already failed.invalidateDynamicParserclears the negative cache immediately (unchanged semantics, new map).ui/src/adapters/dynamic-loader.test.ts(new): focused unit tests — worker path still preferred; in-page fallback activation with synchronous results; fallback parse-error degradation to[]; 404 TTL; worker+fallback-failure TTL; invalidate clears the negative cache.Verification
Local commands (from repo root, clean checkout of this branch):
Built-bundle evidence (production build,
ui/dist/assets/index-DiDXuyG0.jsat commit 9b0d178):new Function("exports","module","self","globalThis",\"use strict";\n{\n`+e+`\n}`)and theparseStdoutLineresolution +[]` degradation wrapper.SBt=6e4(60 000 ms TTL),function NBt(e){const t=qD.get(e);return t===void 0?!1:Date.now()>=t?(qD.delete(e),!1):!0}(lazy-expiring negative-cache check) andfunction Zfe(e){qD.set(e,Date.now()+SBt)}(TTL write) — both failure paths (!a.okand catch-after-fallback) route throughZfe; there is no unconditional permanent failure set.[adapter-ui-loader] sandboxed worker failed for "<type>"; trying in-page fallback:and[adapter-ui-loader] in-page fallback parser active for "<type>", but this repo'sui/vite.config.tssetsesbuild.drop: ["console"]for production builds, so no first-party console strings appear in any production bundle (this is pre-existing, repo-wide; the previously deployed hand-patched dist only contained the markers because it was patched after building). The markers do appear verbatim in a development-mode build of this branch (vite build --mode development,index-C8uWT6rm.js), and the unit tests assert the marker log lines fire.Manual steps for a reviewer with a worker-hostile browser configuration: install an external adapter with a ui-parser, block Blob-URL Workers (or run in such a webview), open a run page — structured entries should render (fallback path), and after fixing the worker condition the sandboxed path returns on the next load/invalidation.
Risks
self/globalThisare shadowed; the eval happens with CJS shims and a strict-mode block wrap mirroring the worker bootstrap. This mirrors the trust argument already validated for the deployed hotfix this PR formalises.esbuild.drop), so fallback activation is observable in dev builds/logs and unit tests but not in production console. No migration, no breaking API changes;loadDynamicParser/invalidateDynamicParsersignatures unchanged.Model Used
claude-sonnet-4-5-20250929), 200K context windowChecklist
Fixes: #/Closes: #/Refs: #OR (b) described the issue in-PR following the relevant issue template#NNN/github.com/paperclipai/paperclipURLs)docs/...,fix/...) and contains no internal Paperclip ticket id or instance-derived detailsFollows
CONTRIBUTING.mdPR template — sections present: Thinking Path (8 steps), Linked Issues or Issue Description (path B, bug-report shape), What Changed, Verification (commands + results), Risks, Model Used, Checklist. Path class: Path 1 (small, focused change — two files, one logical fix, no feature-roadmap overlap). The last three checklist boxes await CI/Greptile on the pushed branch and will be addressed before requesting merge.PR target note: this PR targets this repository (
claudegoogl-sudo/paperclip)masteronly. It is not directed at any upstream repository.