Skip to content

Redaction: solid-block default (drop gaussian, warn mosaic)#66

Merged
My-Denia merged 5 commits into
mainfrom
feat/enable-blur
Jul 4, 2026
Merged

Redaction: solid-block default (drop gaussian, warn mosaic)#66
My-Denia merged 5 commits into
mainfrom
feat/enable-blur

Conversation

@My-Denia

@My-Denia My-Denia commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Redaction rework

Reworks the blur feature into a redaction feature with a safe default.

Deep research (Hill et al. PoPETs 2016; Bishop Fox Unredacter; NSA Redacting with Confidence; Signal/The Register) established that mosaic and gaussian blur are recoverable for structured text (passwords, IDs), and that the only method endorsed for redaction is a solid opaque block burned into the export. Video is higher-risk than screenshots (multi-frame).

Changes

  • Solid obscuring type (new default): 100% opaque color fill of the region, burned into the MP4/GIF export and shown in the live editor preview.
  • Dropped gaussian (blurData.type === "blur"): renderer branch, preview branch, intensity control, and its tests. Removes the round-3 gaussian half-wiring at the root, with no security loss (gaussian was the weakest method).
  • Mosaic kept as a non-default, explicitly-warned "not secure for text" option; new Solid/Mosaic type selector in the inspector; the mosaic block-size control is gated to mosaic regions.
  • Migration: a persisted type: "blur" (legacy gaussian) loads as solid (normalizeBlurType) — safety-forward, never reveals content.
  • EOF fix: getPlayheadRegionSpan clamps the start so a blur added at the video end keeps its full duration — a zero-length region never renders/exports (renderAnnotations filters with currentTimeMs < endMs).
  • i18n: blurTypeSolid + mosaicSecurityWarning across all 13 locales.

Verification

Full suite 412/412, tsc --noEmit + biome clean. The solid path is proven fully opaque at the pixel level (an inside pixel equals the opaque fill — the original frame is entirely replaced). Migration, EOF clamp, and getSolidFillColor are unit-tested; gaussian tests were removed together with the feature.

Codex round-3 disposition

  • EOF zero-length → fixed.
  • Gaussian-intensity mismatch → resolved by dropping gaussian.
  • Freehand only via import → freehand stays renderer- and persistence-honored for imported/legacy projects; a freehand drawing tool is a tracked follow-up (out of scope for this safe-redaction MVP), not shipped half-wired.

Copilot AI review requested due to automatic review settings July 4, 2026 00:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

  • No follow-up code changes were needed: the trigger and PR context only contain the PR summary/verification, and there are no reviewer-requested changes or CI failure details.
  • The working tree is clean, so I did not create a commit and did not call make_pr.

Checks

  • pwd && rg --files -g 'AGENTS.md' -g '!node_modules' -g '!dist' | xargs -r -I{} sh -c 'echo --- {}; cat {}' && git status --short && git log --oneline -5
  • git status --short; find .. -name AGENTS.md -print

View task →

@My-Denia

My-Denia commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1fbea7e5b1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/e2e/blur-redaction.spec.ts Outdated
Comment thread src/components/video-editor/timelineClipboardUtils.ts Outdated
Comment thread src/components/video-editor/timeline/timelineCycleSelection.ts Outdated
Comment thread tests/e2e/blur-redaction.spec.ts
Comment thread tests/e2e/blur-redaction.spec.ts
…ound, e2e robustness, i18n

Codex cloud review + execution-audit follow-ups on the blur-enable PR (#66):

- timelineClipboardUtils: clamp the duplicated annotation/blur position to the
  canvas (getDuplicatedAnnotationPosition) so a full-frame or edge blur can't be
  nudged off-canvas and briefly expose an unredacted strip (Codex P2).
- timelineCycleSelection: use an exclusive endMs bound so Tab-cycle selection
  matches the renderer/exporter active window (currentTimeMs < endMs) (Codex P3).
- blur-redaction e2e: honor process.env.HEADLESS (default "true") instead of
  forcing headed runs; degrade gracefully when ffmpeg is absent (structural
  checks still run); remove the temp export dir in finally (Codex P2/P2/P3).
- BlurSettingsPanel: replace the hardcoded "Duplicate" label with
  t("annotation.duplicateAnnotation"); add the key to all 13 locales.
- Tests: cover cycle empty/single/edge cases and the duplicate clamp for
  full-frame and edge blurs.

Full suite 405/405, tsc clean, biome clean.
@My-Denia

My-Denia commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a9e118374f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/blurEffects.ts Outdated
Codex round-2 finding (blurEffects.ts:19 thread): BlurSettingsPanel's
shape/color/block-size handlers hard-coded blurData.type = "mosaic", so editing
any setting silently converted an imported gaussian ("blur") region back to
mosaic — losing the effect the renderer/exporter/persistence already support and
test (annotationRenderer.ts:245, annotationRenderer.test.ts:356/410-412,
projectPersistence.ts:400).

- blurEffects: add withBlurDataPatch(current, patch) — merges an edit while
  preserving the existing blur type (mosaic default for a new region).
- BlurSettingsPanel: route all three edit handlers through it; no more type
  clobbering.
- blurEffects.test: gaussian type preserved across shape/color/blockSize edits,
  mosaic default for new regions, patched field applied.

Full suite 408/408, tsc clean, biome clean. Note: there is still no UI to
create/switch to gaussian, and gaussian is a weaker redaction than the mosaic
default — selector-vs-drop is a separate product decision, not this round.
@My-Denia

My-Denia commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7512f61bd5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/video-editor/BlurSettingsPanel.tsx Outdated
Comment thread src/components/video-editor/featureFlags.ts
Comment thread src/components/video-editor/BlurSettingsPanel.tsx
…arn mosaic, fix EOF

Reworks the blur feature into a redaction feature with a safe default. Research
(Hill et al. PoPETs 2016; Bishop Fox Unredacter; NSA) shows mosaic and gaussian blur
are recoverable for text; only a solid opaque block, burned into the export, is safe.

- New obscuring type "solid": 100% opaque color fill of the region, burned into the
  MP4/GIF export and shown in the live preview. Now the default for new regions.
- Drop gaussian ("blur" type): renderer branch, preview branch, intensity slider, and
  its tests. Removes the round-3 gaussian half-wiring findings at the root.
- Keep mosaic as a non-default, warned "not secure for text" option; add a Solid/Mosaic
  type selector to the inspector; gate the block-size control behind mosaic.
- Migrate persisted type "blur" -> "solid" on load (normalizeBlurType); never reveals.
- Fix EOF zero-length blur: getPlayheadRegionSpan clamps the start so a blur added at the
  video end keeps full duration (a zero-length region never renders/exports: < endMs).
- i18n: blurTypeSolid + mosaicSecurityWarning across all 13 locales.

Tests: solid render + full-opacity proof (inside pixel == opaque fill), normalizeBlurType
migration, getSolidFillColor, getPlayheadRegionSpan EOF clamp; gaussian tests removed with
the feature. Full suite 412/412, tsc + biome clean.

Addresses Codex round-3 (#66): EOF zero-length, gaussian-intensity, freehand-import-only.
Freehand stays renderer-honored for imported data; a freehand drawing tool is a follow-up.
@My-Denia My-Denia changed the title Enable blur redaction Redaction: solid-block default (drop gaussian, warn mosaic) Jul 4, 2026
@My-Denia

My-Denia commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@My-Denia

My-Denia commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

@claude review

@claude

claude Bot commented Jul 4, 2026

Copy link
Copy Markdown

Claude finished @My-Denia's task in 2m 46s —— View job


Review complete

  • Gather context (diff, CLAUDE.md, changed files)
  • Review redaction rework changes (solid default, gaussian removal, mosaic warning)
  • Review EOF-clamp fix, cycle-selection exclusivity, duplicate-blur clamping
  • Review i18n additions
  • Review e2e test additions
  • Post final review feedback

No CLAUDE.md exists in this repo, so no repo-specific conventions to check against. I was not able to run npm ci/vitest/tsc/biome in this sandbox (network install requires interactive approval I don't have here), so the "412/412, tsc/biome clean" claim in the PR body is unverified by me — I reviewed by reading the diff (git diff origin/main...HEAD) and the resulting source directly.

Round-4 fixes verified as actually applied

All four previously-flagged Codex items from earlier rounds check out in the current tree, not just in commit messages:

  • EOF zero-length blurhandleAddBlur (src/components/video-editor/timeline/TimelineEditor.tsx:1364) now delegates to getPlayheadRegionSpan (timelineClipboardUtils.ts:75), which clamps start to totalMs - durationMs, so start === end can no longer happen at end-of-video.
  • Duplicated-blur off-canvas clampgetDuplicatedAnnotationPosition (timelineClipboardUtils.ts:~155) clamps to [0, 100 - size] after the +4% nudge; a full-frame or edge redaction duplicate stays on-canvas.
  • Cycle-selection exclusive end boundgetNextOverlappingRegionId (timelineCycleSelection.ts:17) now filters with currentTimeMs < region.endMs, matching the renderer/exporter's active window.
  • e2e robustnessblur-redaction.spec.ts now probes ffmpegAvailable() before pixel-delta assertions (falls back to structural checks), respects HEADLESS ?? "true", and rmSyncs tempDir in finally.

Core redaction logic

  • renderBlur (src/lib/exporter/annotationRenderer.ts:203) for type === "solid" clips to the shape path and fills with getSolidFillColor directly — no drawImage/sampling of the source frame at all, so nothing of the original pixels can leak through. This matches the PR's opacity claim and is backed by a real pixel-level test (annotationRenderer.test.ts:415, "fully replaces the region with an opaque block").
  • Migration (normalizeBlurType, blurEffects.ts:16) maps legacy "blur" (gaussian) and any unrecognized value to "solid", and only an explicit "mosaic" stays mosaic — safety-forward as claimed. projectPersistence.test.ts exercises this.
  • withBlurDataPatch (blurEffects.ts:~40) is now used consistently by all three settings-panel edit handlers (shape/color/blockSize), so editing a preserved gaussian/imported region no longer silently flips it back to mosaic — confirms the round-3 fix is real, not just claimed.
  • BlurSettingsPanel gates the mosaic block-size slider to activeType === "mosaic" and shows mosaicSecurityWarning only for mosaic — consistent with dropping the gaussian intensity control entirely rather than leaving it mismatched.

Minor / non-blocking

  1. Orphaned i18n keysannotation.typeBlur and annotation.blurTypeBlur (present in all 13 locale files, e.g. src/i18n/locales/en/settings.json:132,152) are no longer referenced anywhere in src/ now that gaussian ("blur" as a BlurType) has been dropped. Not a bug, but worth pruning in a follow-up so the locale files don't carry dead strings for a redaction mode that no longer exists.
  2. Vestigial intensity fieldsMIN_BLUR_INTENSITY/MAX_BLUR_INTENSITY/DEFAULT_BLUR_INTENSITY and BlurData.intensity (types.ts:270-281,380) are still defined and defaulted, but nothing reads blurData.intensity anymore (renderer, overlay, and panel all removed their usages). Harmless — old persisted values are just ignored — but it's the last remnant of the "gaussian half-wiring" the PR otherwise removes at the root; could be deleted together in the same cleanup pass.
  3. Freehand scope note — confirmed as described: blurShapeOptions in the inspector only offers rectangle/oval, while drawBlurPath/projectPersistence still fully honor freehand for imported/legacy regions. That's a reasonable, explicitly-scoped MVP boundary rather than dead code, since existing freehand blur data keeps rendering and round-tripping correctly.

Overall

The redaction rework is sound: the solid path performs a genuine opaque replacement with no source sampling, the gaussian removal is clean (no dangling intensity UI or renderer branch), migration is safety-forward, and all four issues raised in the last Codex review round are verifiably fixed in code (not just asserted in commit messages). The two "minor" items above are cleanup, not correctness or security concerns — happy to see this merged as-is, with the orphaned i18n keys/intensity fields as an optional fast-follow.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8310ea7be9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/video-editor/AnnotationOverlay.tsx Outdated
Codex round-4: AnnotationOverlay forced solid opacity to 1 unconditionally. Since
freehand blur regions span the full video surface and shapeMaskStyle drops the clip
while isFreehandDrawing, a solid freehand region became a full-screen opaque panel
during redraw, hiding the frame and the path being traced. Gate solid opacity with the
same shouldShowFreehandBlurFill guard mosaic already uses (1 for rect/oval and for a
settled freehand, 0 only while actively drawing).
@My-Denia

My-Denia commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 2583c67903

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@My-Denia My-Denia merged commit 0a5d8ca into main Jul 4, 2026
11 checks passed
@My-Denia My-Denia deleted the feat/enable-blur branch July 4, 2026 02:36
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.

2 participants