Back to buildsBUILD RECORD

RedactionCore / Swift text-processing package / 2026

Redaction that preserves the surrounding document.

RedactionCore gives Omitto a reusable Swift engine that selects sensitive spans, resolves competing matches and replaces them without reconstructing the document.

THE WORK

The project.

RedactionCore is the text-processing package behind Omitto's review workflow. It accepts a string and a redaction policy, then returns redacted text, masked findings and a report. Replacements happen inside the original document, preserving the surrounding indentation, comments, key order and line endings that can make a developer snippet useful to someone else.

Choosing what to replace happens before changing the string. Detectors contribute candidate spans; disabled groups are removed before overlapping matches compete. The selected spans receive placeholders that remain consistent for repeated values within one call, then replacement proceeds from right to left so earlier offsets remain valid.

The package uses Foundation and owns no interface, clipboard, storage or networking. Omitto supplies background scheduling and the review experience. Manual phrases and explicit Keep decisions travel with the current policy, keeping the automatic scan part of a review process rather than a claim that every possible secret has been removed.

In this record

IMPLEMENTATION

Design choices.

  1. Replace spans in the original string instead of rebuilding the document from a parsed representation. This preserves useful surrounding context across text formats, while leaving detection quality as a separate problem to evaluate.
  2. Filter detector groups before selecting overlap winners. An ineligible high-priority candidate must not discard an enabled fallback and then disappear itself, leaving a value untouched.
  3. Allocate placeholders within one call instead of keeping a persistent secret-to-label table. Repeated values remain easy to follow inside a result, but their labels do not become stable identities across documents.
  4. Keep manual phrases active independently of automatic detector groups and make per-finding overrides explicit. These controls let the review address omissions and false positives without presenting automatic detection as complete.
  5. Leave task scheduling, source-text lifetime and output destinations with the caller. The small package boundary supports reuse; it does not certify the safety of a publication or erase the original bytes.

HOW IT FITS TOGETHER

Architecture.

  • Redactor is a synchronous Sendable value API. It receives input and policy and returns text, findings and a report, allowing the same processing logic to be used without an app window or clipboard service.
  • CompositeDetector collects and deduplicates candidates. Redactor removes disabled groups before resolving overlaps with priority, confidence and span-length scores, then applies the confidence threshold to the selected candidates.
  • Each call creates a new PlaceholderAllocator. Repeated values share a placeholder within that result, different values are numbered by kind, and per-finding Keep choices explicitly leave selected text unchanged.
  • Accepted findings use UTF-16 spans and are applied from the end of the string toward the start. This preserves earlier positions and leaves untouched document structure in place instead of parsing and serializing it again.
  • Public findings carry ranges, kinds, confidence, fixed reasons and masked previews rather than an original-value field. Omitto uses that metadata for review and remains responsible for scheduling and copying.
Explore the architecture map11 components · 14 connections

RedactionCore's value-based transformation

The library selects spans and returns reviewable values; the calling application owns UI, scheduling, storage and export.

Direct callResponse / return
Calling application
RedactionCore library
Returned values

Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.

Choose a component to explore

Select a numbered component on the map or use the component menu. Its details and connections will appear here.

No component selected.

All connections (14)
  1. 01 · Input string → 03 · CompositeDetectorText to inspect · Direct call
  2. 02 · Options and review policy → 03 · CompositeDetectorManual and mode options · Direct call
  3. 03 · CompositeDetector → 04 · Detector-group filterCandidate spans · Direct call
  4. 02 · Options and review policy → 04 · Detector-group filterEnabled detector groups · Direct call
  5. 04 · Detector-group filter → 05 · Overlap resolverEligible candidates · Direct call
  6. 05 · Overlap resolver → 06 · Confidence policySelected spans · Direct call
  7. 02 · Options and review policy → 06 · Confidence policyConfidence policy · Direct call
  8. 06 · Confidence policy → 07 · Per-call placeholder allocatorAccepted candidates · Direct call
  9. 07 · Per-call placeholder allocator → 09 · Finding metadataAssigned replacements · Direct call
  10. 02 · Options and review policy → 09 · Finding metadataPer-finding Keep decisions · Direct call
  11. 09 · Finding metadata → 08 · Right-to-left span replacementEnabled spans and replacement text · Direct call
  12. 01 · Input string → 08 · Right-to-left span replacementOriginal string · Direct call
  13. 08 · Right-to-left span replacement → 10 · Transformed stringReturn transformed text · Response / return
  14. 09 · Finding metadata → 11 · RedactionReportAggregate finding metadata · Direct call

MADE WITH

Swift · Foundation · Swift Package Manager · XCTest

ACCESS & INPUT

Security controls.

  • The package imports Foundation and has no external package dependencies. A repository boundary check rejects UI, pasteboard, persistence, networking and telemetry symbols in the core.
  • Public findings omit an original-value field, and custom debug descriptions omit both input and output text. The review metadata can describe a finding without reproducing its detected value.
  • The library uses manual phrases for the current call and does not persist them. These phrases remain active even when all automatic detector groups are disabled.
  • Placeholder allocation checks whether a proposed replacement equals the original value. If it does, the allocator changes the token so that an accepted redaction does not silently preserve the same text.
  • Explicit Keep choices can leave findings in place, and unfamiliar formats can escape heuristic detection. The returned document still needs review before it is shared.
  • The caller owns the lifetime of raw input, options, output and any clipboard copy. Nothing in this API promises secure memory erasure.
Explore the security map9 components · 14 connections

Detection policy and caller-owned disclosure

RedactionCore returns selected spans and transformed text; review, raw-value lifetime and clipboard or file export remain outside the library.

Direct callResponse / return
Calling application
Foundation-only core
Returned values

Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.

Choose a component to explore

Select a numbered component on the map or use the component menu. Its details and connections will appear here.

No component selected.

All connections (14)
  1. 01 · Caller-owned raw input → 03 · Composite detectionText value to inspect · Direct call
  2. 02 · Per-call redaction policy → 03 · Composite detectionManual phrases and detection mode · Direct call
  3. 03 · Composite detection → 04 · Policy and overlap selectionCandidate spans · Direct call
  4. 02 · Per-call redaction policy → 04 · Policy and overlap selectionEligibility and confidence rules · Direct call
  5. 04 · Policy and overlap selection → 05 · Reviewable finding metadataSelected spans and placeholders · Direct call
  6. 02 · Per-call redaction policy → 05 · Reviewable finding metadataPer-finding Keep choices · Direct call
  7. 05 · Reviewable finding metadata → 06 · Caller review and policy choiceReview metadata · Response / return
  8. 06 · Caller review and policy choice → 02 · Per-call redaction policyUpdated options for a later call · Response / return
  9. 05 · Reviewable finding metadata → 07 · Enabled-span replacementApply enabled findings only · Direct call
  10. 01 · Caller-owned raw input → 07 · Enabled-span replacementOriginal replacement base · Direct call
  11. 07 · Enabled-span replacement → 08 · Transformed string and reportTransformed value · Response / return
  12. 05 · Reviewable finding metadata → 08 · Transformed string and reportAggregate report metadata · Response / return
  13. 08 · Transformed string and report → 06 · Caller review and policy choiceInspect any residual text · Response / return
  14. 08 · Transformed string and report → 09 · Caller-owned clipboard or file exportCaller controls subsequent disclosure · Response / return

CHECKS & RESULTS

What was checked.

A source review shows what the code does. It is not a fresh test of the running app.

  1. Code and development records reviewedReviewed

    The code, tests and available development records were checked. Reported test results keep their original scope. No fresh app or live deployment check was run for this write-up.

    Scope of this check
    Code review, not a fresh run of the app

NEXT

Still to work through.

The July correctness audit records 57 core tests passing, but those tests were not rerun here. A detection-rate claim needs a versioned, independently reviewed benchmark with both sensitive examples and ordinary text that should remain unchanged. The synchronous core also does not poll cancellation; Omitto handles task scheduling and rejects results that no longer belong to the current input.