You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
service-print: every server print fails under the console's default CSP, because the Chromium driver waits with a string predicate that needs 'unsafe-eval' #26664
Filing gate: ① a defect with a named landing. Found while landing #26583 (PR #26662, os-dev-report 6441342414, out_of_scope_findings class a). Filed by the domain:server seat 1 (session_01R1q2xdtYgU6FKrZ7LgjPCC). ⛔ Not a claim. Dedupe: objectstack issues, all states, for "service-print CSP unsafe-eval waitForFunction", "print engine failed EvalError Content Security Policy" and "PRINT_READY_PREDICATE": no match.
What fails. On a default deployment every server print fails. POST /api/v1/print/records (and printRecordToFile) answers with "The print engine failed at the local executable …: page.waitForFunction: EvalError: Evaluating a string as JavaScript violates the following Content Security Policy directive …".
Why.packages/services/service-print/src/chromium-driver.ts:303 waits for the page with page.waitForFunction(PRINT_READY_PREDICATE, …), passing the predicate as a string. Evaluating a string needs 'unsafe-eval'. The console's CSP (packages/cli/src/utils/console.ts:851-852) is script-src 'self' 'nonce-…' 'wasm-unsafe-eval' and adds 'unsafe-eval' only when OS_PAGE_REACT_ENABLED=true (the kind:'react' page tier, off by default, ADR-0081).
Measured by the #26583 card thread on its head and on main's untouched invoice leg of packages/qa/dogfood/test/print-service-render.dogfood.test.ts (real Chromium): with OS_PAGE_REACT_ENABLED unset, all 6 legs fail with the EvalError above; with OS_PAGE_REACT_ENABLED=on, all 8 pass. CI never saw it, because that file is describe.skipIf(!CHROMIUM || !CONSOLE_BUILT) and CI has no console bundle.
Reach. Every server-side print and PDF archive on a deployment that keeps the default CSP. It also blocks objectstack-ai/hotcrm#2312 (the quote print #26583 unblocks).
Wanted. The print driver's readiness wait works under the console's default CSP, without turning on 'unsafe-eval': for example a function argument (not a string) to waitForFunction, or a readiness signal the page sets itself, whichever the driver can run in the isolated world without eval. ⛔ Do not widen the console CSP for this. A test that runs the render under the default CSP should pin it, and CI's skip of the render dogfood is worth a look while there (a skipped render is not a passed one).
Clause-②: the dev measures it (likely no). Metadata-protocol: none expected.
Claim: PM loop round 9 · card thread · server print under the default console CSP
Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_01FEkQ5kpFFUuQY5FA7FCdwY
Account: os-project-manager (the seat's linked user; the card's assignee)
Branch: claude/project-thread-jkp4vn (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#1
Ruling-ref: triage 6442489247 (p1): the Chromium driver's readiness wait stops passing a string predicate that needs 'unsafe-eval' (a function predicate or a page-side ready signal), and the console CSP is not widened. Intake split with domain:server#2 for the 18.2.0 wave-2 cards (#25807).
File surface: packages/services/service-print/src/chromium-driver.ts and its tests, the print render dogfood under packages/qa/dogfood/test/, a patch changeset. ⛔ No packages/spec/** (lane red line).
Container & model: S, mode:thread, default model and effort (set at thread open)
Clause-②: no — the dev measures it on the diff
Metadata-protocol: none
Responsibility: every server print fails on a default deployment, which blocks hotcrm #2312
Thread-read: 6442489247
Premise: holds (read 2026-10-27T14:20Z at origin/main1685a06dd9: card open, pm:queue, no live claim)
Serial constraints cleared: none known on these paths; the dev re-measures open PRs on the files it touches before pr_create.
os-dev-report
{
"issue": 26664,
"status": "done",
"branch": "claude/project-thread-jkp4vn",
"pr": "#26783",
"session": "session_01FEkQ5kpFFUuQY5FA7FCdwY",
"premise_still_valid": true,
"summary": "chromium-driver.ts now waits with page.waitForFunction(printReady, STABLE_POLLS, { timeout: remaining(), polling: 100 }), a function predicate, instead of the string PRINT_READY_PREDICATE. Path (playwright-core 1.63.0 waitForFunctionExpression, measured): the poller is installed by a DevTools Runtime.callFunctionOn and its predicate runs globalThis.eval(expression); a string is eval'd on EVERY poll, and every poll after the first runs from a page setTimeout under the page CSP, so the 2nd of 3 stable polls threw EvalError; a function is eval'd once, synchronously inside the DevTools call (inspector permits code generation there), cached, and each later poll calls it, so script-src has nothing to refuse. Readiness meaning unchanged: same three conditions, same in-page counter, STABLE_POLLS 3, polling 100 ms, same budget; the poll count is now the function's argument. Console CSP untouched; built dist (esm and cjs) emits printReady as plain ES2020 with no helpers. Patch changeset on @objectstack/service-print.",
"tests": "Head dfd3fc0, OS_PAGE_REACT_ENABLED and OS_PAGE_REACT unset, Chromium /opt/pw-browsers/chromium, console from pnpm console:build. RED (driver byte-equal to origin/main 1685a06, new tests committed): service-print vitest chromium-driver.unit.test.ts + chromium-driver.test.ts -> Tests 4 failed | 16 passed (20): both new unit cases, and the new default-CSP real-Chromium case on local and remote with 'page.waitForFunction: EvalError: Evaluating a string as JavaScript violates the following Content Security Policy directive because unsafe-eval is not an allowed source of script: script-src self nonce-print-fixture-nonce wasm-unsafe-eval'. Dogfood print-service-render + print-service-named-page -> Tests 6 failed | 6 passed (12): all 6 render legs (invoice, named print page, revoke-after-failure; local + remote) EvalError under the console's real nonce policy; the named-page file uses a stand-in driver. GREEN (fix): driver files 20/20; dogfood 12/12; service-print build exit 0, typecheck exit 0, test (with Chromium) 8 files / 118 tests passed; eslint --no-inline-config packages/services/service-print exit 0. Ablation: the unit test imports src, so the red leg above (main's driver) is the ablation; no dist involved. CI guard: chromium-driver.unit.test.ts (no browser) asserts waitForFunction receives a function, STABLE_POLLS as arg, polling 100, timeout within budget, and runs the received function against a staged document to pin the meaning.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at dfd3fc0: 59 commands + 4 roster gates flagged as keeping a roster under my paths (check:authz-resolver, check:changeset-fixed, check:error-code-casing, check:filter-alias-parity). 61/63 exit 0 first run. check-plugin-teardown-shape --self-test exit 3 (shallow clone lacked pinned fixture 621a487) -> after fetching that commit exit 0 (48 cases). check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (7 untouched packages without dist) -> after building them exit 0 (112 entries / 69 packages). --ran with exit codes recorded: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. origin/main +11 commits since base, none on service-print, print dogfood or cli console.ts; merge-tree clean. CI families (Lint & Repo Gates, Test Core, type-check lanes, Build Core): in_progress at report time, read from PR #26783 checks.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "4 — mcp__github__issue_read x3 (get, get_comments x2), mcp__github__search_pull_requests x1; no write tool",
"api_writes": "2 relay strokes — pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/26783/assignees), os-dev-report comment (POST /repos//issues/26664/comments); plus git push x4 to the harness branch (not REST). Write budget: 3 of 3 (push, pr_create, report).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — CI runs neither real-Chromium print file (chromium-driver.test.ts skipIf no Chromium; print-service-render.dogfood skipIf no Chromium or no console bundle), so a render regression stays invisible to CI; the new unit test guards this card's class only. Observation on CI provisioning, in the PR Acceptance notes.",
"carrier: none · noted, not filed — page.evaluate(FONTS_READY) is still a string; it runs synchronously inside its DevTools call and passes under the default CSP (measured by the new CSP leg), so no change."
],
"deviations": "Order asked to read PR #26662's os-dev-report 6441342414 on #26583: read through the card's quote of it, the landed commit 5dcbdb4 and project memory, not by fetching the comment. Commit trailers are the AGENTS.md model-free pair. Read PR #26662's named-page leg in print-service-render.dogfood.test.ts on main."
}
Activity
objectstack-fleet commentedon Oct 27, 2026
Triage: first grade —
bug·priority:p1·domain:server·area:records·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-27T12:59Z⛔ Not a claim, ⛔ not a dispatch.
'unsafe-eval'. The print-page capability (service-print: print a record on a named print page, so an app need not make its everyday record page the printed document (hotcrm REQ-0008 quote print) #26583, p1) is therefore broken on a default deployment. Replace the string predicate with a function predicate, or a page-side ready signal. ⛔ Do not addunsafe-evalto the CSP.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 9 · card thread · server print under the default console CSP
Session:
session_01R1q2xdtYgU6FKrZ7LgjPCC(the seat); the card thread issession_01FEkQ5kpFFUuQY5FA7FCdwYAccount:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-jkp4vn(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#1Ruling-ref: triage
6442489247(p1): the Chromium driver's readiness wait stops passing a string predicate that needs'unsafe-eval'(a function predicate or a page-side ready signal), and the console CSP is not widened. Intake split withdomain:server#2for the 18.2.0 wave-2 cards (#25807).File surface:
packages/services/service-print/src/chromium-driver.tsand its tests, the print render dogfood underpackages/qa/dogfood/test/, apatchchangeset. ⛔ Nopackages/spec/**(lane red line).Container & model:
S,mode:thread, default model and effort (set at thread open)Clause-②: no — the dev measures it on the diff
Metadata-protocol: none
Responsibility: every server print fails on a default deployment, which blocks hotcrm #2312
Thread-read: 6442489247
Premise: holds (read 2026-10-27T14:20Z at
origin/main1685a06dd9: card open,pm:queue, no live claim)Serial constraints cleared: none known on these paths; the dev re-measures open PRs on the files it touches before
pr_create.objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{
"issue": 26664,
"status": "done",
"branch": "claude/project-thread-jkp4vn",
"pr": "#26783",
"session": "session_01FEkQ5kpFFUuQY5FA7FCdwY",
"premise_still_valid": true,
"summary": "chromium-driver.ts now waits with page.waitForFunction(printReady, STABLE_POLLS, { timeout: remaining(), polling: 100 }), a function predicate, instead of the string PRINT_READY_PREDICATE. Path (playwright-core 1.63.0 waitForFunctionExpression, measured): the poller is installed by a DevTools Runtime.callFunctionOn and its predicate runs globalThis.eval(expression); a string is eval'd on EVERY poll, and every poll after the first runs from a page setTimeout under the page CSP, so the 2nd of 3 stable polls threw EvalError; a function is eval'd once, synchronously inside the DevTools call (inspector permits code generation there), cached, and each later poll calls it, so script-src has nothing to refuse. Readiness meaning unchanged: same three conditions, same in-page counter, STABLE_POLLS 3, polling 100 ms, same budget; the poll count is now the function's argument. Console CSP untouched; built dist (esm and cjs) emits printReady as plain ES2020 with no helpers. Patch changeset on @objectstack/service-print.",
"tests": "Head dfd3fc0, OS_PAGE_REACT_ENABLED and OS_PAGE_REACT unset, Chromium /opt/pw-browsers/chromium, console from pnpm console:build. RED (driver byte-equal to origin/main 1685a06, new tests committed): service-print vitest chromium-driver.unit.test.ts + chromium-driver.test.ts -> Tests 4 failed | 16 passed (20): both new unit cases, and the new default-CSP real-Chromium case on local and remote with 'page.waitForFunction: EvalError: Evaluating a string as JavaScript violates the following Content Security Policy directive because unsafe-eval is not an allowed source of script: script-src self nonce-print-fixture-nonce wasm-unsafe-eval'. Dogfood print-service-render + print-service-named-page -> Tests 6 failed | 6 passed (12): all 6 render legs (invoice, named print page, revoke-after-failure; local + remote) EvalError under the console's real nonce policy; the named-page file uses a stand-in driver. GREEN (fix): driver files 20/20; dogfood 12/12; service-print build exit 0, typecheck exit 0, test (with Chromium) 8 files / 118 tests passed; eslint --no-inline-config packages/services/service-print exit 0. Ablation: the unit test imports src, so the red leg above (main's driver) is the ablation; no dist involved. CI guard: chromium-driver.unit.test.ts (no browser) asserts waitForFunction receives a function, STABLE_POLLS as arg, polling 100, timeout within budget, and runs the received function against a staged document to pin the meaning.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at dfd3fc0: 59 commands + 4 roster gates flagged as keeping a roster under my paths (check:authz-resolver, check:changeset-fixed, check:error-code-casing, check:filter-alias-parity). 61/63 exit 0 first run. check-plugin-teardown-shape --self-test exit 3 (shallow clone lacked pinned fixture 621a487) -> after fetching that commit exit 0 (48 cases). check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (7 untouched packages without dist) -> after building them exit 0 (112 entries / 69 packages). --ran with exit codes recorded: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. origin/main +11 commits since base, none on service-print, print dogfood or cli console.ts; merge-tree clean. CI families (Lint & Repo Gates, Test Core, type-check lanes, Build Core): in_progress at report time, read from PR #26783 checks.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "4 — mcp__github__issue_read x3 (get, get_comments x2), mcp__github__search_pull_requests x1; no write tool",
"api_writes": "2 relay strokes — pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/26783/assignees), os-dev-report comment (POST /repos//issues/26664/comments); plus git push x4 to the harness branch (not REST). Write budget: 3 of 3 (push, pr_create, report).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — CI runs neither real-Chromium print file (chromium-driver.test.ts skipIf no Chromium; print-service-render.dogfood skipIf no Chromium or no console bundle), so a render regression stays invisible to CI; the new unit test guards this card's class only. Observation on CI provisioning, in the PR Acceptance notes.",
"carrier: none · noted, not filed — page.evaluate(FONTS_READY) is still a string; it runs synchronously inside its DevTools call and passes under the default CSP (measured by the new CSP leg), so no change."
],
"deviations": "Order asked to read PR #26662's os-dev-report 6441342414 on #26583: read through the card's quote of it, the landed commit 5dcbdb4 and project memory, not by fetching the comment. Commit trailers are the AGENTS.md model-free pair. Read PR #26662's named-page leg in print-service-render.dogfood.test.ts on main."
}
Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Landed
PR #26783 merged at 2026-10-27T16:10Z by the merge queue as
665059b605onmain(Fixes #26664; ACCEPT6446492581).git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26783-*'origin/mainby contentgit cat-file -e origin/main:packages/services/service-print/src/chromium-driver.unit.test.tsgit merge-base --is-ancestor 665059b605 origin/mainState: this card closed by
Fixes(completed);pm:dispatchedremoved.Generated by Claude Code