fix(reliability): fail closed for stale toolbar image uploads - #158
fix(reliability): fail closed for stale toolbar image uploads#158seonghobae wants to merge 13 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Validation for exact current head 1f5b6f5:\n\n- Updated the two Toolbar keyboard tests to match the PR's intentional customer-facing title change from Insert inline (base64) image to Insert inline image.\n- TypeScript typecheck passed.\n- Toolbar.test.tsx and ToolbarCustomerCopy.test.tsx passed: 2 files, 15 tests.\n- A full local coverage run reached 146 passed files / 829 passed tests and one existing SafeClipboard.wordCapacity test timed out at the default 5 seconds; this is not claimed as full local coverage proof. Hosted checks are re-running on this head.\n\nThe prior build-and-test annotations for this PR were the two stale-label assertions; no implementation behavior was reverted. |
|
Hosted validation update for exact current head 1f5b6f5: build-and-test and Cross-engine Clipboard / Playwright 1.62.0 both passed in run 33148143891. No completed required check is failing at this head; remaining checks are queued or in progress. Current-head formal reviews and approvals remain 0, and the PR remains Draft/blocked pending the remaining gates. |
|
Hosted gate update for exact current head 1f5b6f5: coverage-evidence completed successfully in run 33148142331 (job 98774679606). There are no completed required-check failures at this head; Strix remains the only substantive gate in progress. The PR remains Draft/blocked with 0 current-head approvals. |
|
Terminal current-head OpenCode update for 1f5b6f5: the required opencode-review job failed closed at Fail closed without a current-head OpenCode verdict, job https://github.com/ContextualWisdomLab/inkspan/actions/runs/33148142331/job/98775377775. This is not a source finding or a review approval. Build-and-test, cross-engine, and coverage-evidence passed at this head; current-head formal reviews and approvals remain 0, so the Draft PR remains blocked. |
|
Terminal current-head Strix update for 1f5b6f5: required job https://github.com/ContextualWisdomLab/inkspan/actions/runs/33148142409/job/98774461877 failed during Run Strix (quick). The uploaded artifact records provider-side failures: contextual-orchestrator HTTP 400 invalid_tools (tool.function.description over 1024 characters), followed by HTTP 500 internal_error and STRIX_PROVIDER_UNAVAILABLE. No usable scan verdict was emitted; the displayed Vulnerabilities 0 is not vulnerability-clear evidence. Build-and-test, cross-engine, and coverage-evidence passed at this head. Current-head approvals remain 0 and the Draft PR stays blocked. |
Closes #157.
Current boundary
Protected shipped truth is independently resolved as
main@128a239f8b71ca16add4b9e15e21752d1ad63ff0. Current exact Draft head is4f4f7db37f2ff488e061f9b69d6a0c4b019e0c0donfix/toolbar-image-lifecycle-20260811.The branch is non-destructively synchronized with that exact protected tip. The synchronization commit keeps the previous #158 head as first parent and protected main as the second parent; no force push or destructive rebase was used. Fresh comparison resolves the merge base exactly to protected main, reports
ahead_by=13,behind_by=0, and exactly five intended changed paths:src/components/Toolbar.tsx;src/components/Toolbar.test.tsx;src/components/ToolbarCustomerCopy.test.tsx;src/components/ToolbarImageLifecycle.test.tsx; andsrc/components/ToolbarLinkPolicy.test.tsx.The customer-facing image-action label/accessibility contract formerly duplicated by #391 is now represented only by this earlier canonical Toolbar writer; #391 is closed unmerged. The synchronization inherited current protected-main release controls rather than reviving historical release-workflow snapshots.
This lane owns adjacent
Toolbar.tsxtrust/lifecycle boundaries: stale asynchronous image upload continuations, hostile conversion-value redaction, host image-error observer isolation, toolbar SafeLink preflight, and the customer-facing image-action accessible name. It adds no transport, persistence, credentials, tenancy, collaboration-provider, durable audit, model, database, network, or deployment authority.Stale image-upload lifecycle lineage (#157)
RED —
3f3afc373c4a23951e40963bb5d7d4bdfea53fcd. Hosted CI failed the new lifecycle regressions because the alternative-text prompt still ran after the editor became read-only or was destroyed while conversion was pending.GREEN —
6da5eab43f4a05918df5ce520b5f3ce90d9144cf. Production recheckseditor.isDestroyed || !editor.isEditableafter asynchronous conversion and before prompt/focus/image insertion.Hostile conversion-value redaction lineage
RED —
6e767611315e7427f9c7b1c5018cc81aab200413. A hostile thrown Proxy from image conversion could cross the hostonImageErrorboundary by identity.GREEN —
84cb2b1e5fb94b587bf29dd9024c5288f54c7636. Conversion failures are replaced with stableError('Image processing failed.'); hostile thrown values are neither reflected nor propagated. Genuine Blob size is read intrinsically so typed oversize rejection does not trust a caller-owned accessor.Toolbar SafeLink preflight lineage
RED —
98ee151ee52d5792765f71f35408dee8550e3505. CI31933462011failed the new toolbar-link regression while Security31933462001and SAST31933462012succeeded. The test requiresjavascript:alert(1)to be rejected beforesetLink()or editor command execution.GREEN —
0693ba351c2b325e59e45a41e36c861800b1f732. The toolbar calls the existingisSafeLinkHref(url)policy before any link editor command; safe-link behavior and empty-input unlink behavior remain intact.Host observer isolation lineage
A later reliability sweep found another defect on the same owned image-failure boundary: both oversize rejection and conversion rejection invoked host
onImageErrordirectly. Because image conversion is asynchronous, a throwing host observer could turn an otherwise-contained rejection into an unhandled Promise rejection and alter Inkspan control flow.RED — exact test-only head
041e726b010e96cc8b9b4946de52012d719c3141. CI31949613767checked out that exact SHA, passed immutable install and typecheck, and ran all 143 test files / 823 tests successfully, but Vitest correctly failed the run because it caught one unhandled rejection:Error: private toolbar observer sentinel, originating fromcontains host image-error observer failures after conversion rejection. The production coverage table still reached 100% statements/branches/functions/lines; Office Python 3.11–3.14 succeeded on the same RED generation. Those parallel successes do not convert the intentional RED to passing evidence.GREEN source repair — predecessor
d448a9dd8296fca5f905a7371d22abf75f647f75. A narrowreportImageError()helper invokes the host observer inside a fail-closed best-effort boundary. Both typed oversize rejection and stable conversion-error delivery use the helper. No image conversion, size, lifecycle, prompt, editor-command, transport, persistence, or policy semantics changed.Exact-current-head evidence
The synchronization moved the exact contributor head to
4f4f7db37f2ff488e061f9b69d6a0c4b019e0c0d; all predecessor workflow/review results are historical and are not transferred. Current-head required workflows must become terminal and must be inspected down to required steps and checkout/source SHA before they count. Pending, queued, skipped-required, cancelled, absent, neutral, failed, stale, predecessor, status-only, model-only, wrong-checkout, synthetic-source-only, or otherwise vacuous evidence is non-passing.Formal qualifying approvals on this exact head: 0. Unresolved inline review threads: 0.
Integration boundary
Keep this PR Draft and unmerged while #118 owns exact protected
v0.6.0publication/provenance/digest operational acceptance and qualifying independent approval remains absent. Live governance requires a qualifying approval of the latest push by someone other than the pusher, stale-review dismissal after pushes, review-thread resolution, and the applicable central required workflows. Revalidate exact head, protected main, reviews/threads, rules and every required workflow before any later Ready/merge transition. Do not self-approve, weaken gates, transfer predecessor evidence, or fabricate tag/release identity.