Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Refactor: extract defineInlineTextRedactRule factory#170

Merged
twschiller merged 1 commit into
mainfrom
refactor/text-redact-factory
Jun 5, 2026
Merged

Refactor: extract defineInlineTextRedactRule factory#170
twschiller merged 1 commit into
mainfrom
refactor/text-redact-factory

Conversation

@twschiller

Copy link
Copy Markdown
Contributor

Summary

Three text-walker rules — pii-redact, secrets-redact, and encoded-payload-redact — duplicated the same five-primitive lifecycle around a one-line difference in collectMatches:

const lifecycle = new ReusableAbortController();
let unsubscribeRouteChange: (() => void) | null = null;
function scanAndMask(root) { walkTextNodesChunked(root, { signal, minLength, process }); }
const watcher = createSubtreeWatcher({ skipPlaceholderSubtrees: true, onSubtrees });
function apply(root) { unsubscribeRouteChange ??= subscribeRouteChange(...); scanAndMask(root); watcher.start(root); }
teardown: () => { watcher.stop(); lifecycle.abortAndReset(); unsubscribeRouteChange?.(); unsubscribeRouteChange = null; }

The new defineInlineTextRedactRule in lib/inline-text-redact.ts owns that scaffolding. Each rule file now declares its detection logic — regex patterns (pii-redact), prefix patterns + entropy scoring (secrets-redact), candidate-window decoding (encoded-payload-redact) — and hands id, label, description, minLength, and collectMatches to the factory.

What this changes

  • New: extension/src/lib/inline-text-redact.ts (100 LOC) — factory, plus an InlineTextRedactRule type that tightens teardown to non-optional so existing tests can keep calling rule.teardown() directly.
  • Migrated: pii-redact (135 → 81), secrets-redact (202 → 153), encoded-payload-redact (350 → 301).
  • Net: -52 LOC across the four files. Lifecycle state now lives in a closure rather than at module scope, so a hypothetical hot reload or repeated apply/teardown can't leak stale unsubscribeRouteChange.

Out of scope

  • prompt-injection-redact is a text-walker too but a different shape — it inserts a block placeholder against a walked-up container, doesn't use the subtree watcher, and runs a second-pass dedupe via onComplete with filterToOutermost. A future defineBlockTextRedactRule could absorb it if more rules adopt that shape.
  • The other two findings from the recent architecture review (Rule.id: RuleId tightening, subtree-watcher decomposition) are deferred to keep this PR focused. The Rule.id tightening in particular would break existing test fixtures that use synthetic ids, so it needs its own treatment.

Test plan

  • bun run test — 1354 tests pass (was 1354).
  • bun run typecheck — clean.
  • bun run check (Biome + ESLint) — clean.
  • bun run knip — no unused exports.
  • Targeted re-run of pii-redact, secrets-redact, encoded-payload-redact test suites (57 tests) — all green, including the property tests.

🤖 Generated with Claude Code

Three text-walker rules — pii-redact, secrets-redact, and
encoded-payload-redact — duplicated the same five-primitive lifecycle
around a one-line difference in `collectMatches`: a
ReusableAbortController + lazy subscribeRouteChange + createSubtreeWatcher
with skipPlaceholderSubtrees + walkTextNodesChunked + a teardown that
unwinds all of them.

The new `defineInlineTextRedactRule` in `lib/inline-text-redact.ts` owns
that scaffolding. Each rule file now declares its detection logic
(regex patterns, decoding, entropy scoring) and hands `id`, `label`,
`description`, `minLength`, and `collectMatches` to the factory. Net
-52 LOC across the four files, and lifecycle state now lives in a
closure rather than at module scope.

prompt-injection-redact deliberately stays bespoke — it inserts block
placeholders against a walked-up container, doesn't use the subtree
watcher, and runs a second-pass dedupe via `onComplete`. A future
`defineBlockTextRedactRule` could absorb it if more rules adopt that
shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@vercel

vercel Bot commented Jun 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-browser-shield-demo-site Ready Ready Preview, Comment Jun 5, 2026 4:53pm

Request Review

@twschiller twschiller merged commit 48655c4 into main Jun 5, 2026
7 checks passed
@twschiller twschiller deleted the refactor/text-redact-factory branch June 5, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant