Skip to main content

Sieve Redact v0.5

A command-line tool that removes sensitive information from documents — deterministically, while preserving byte-for-byte integrity of everything else.

CI License: MIT Python Version

English | 日本語

💡 Concept

Personal information in resumes, reports and logs is converted into a second file that is safe to publish and share.

  • Deterministic — Same input plus same rules always produces the same output. Character selection in noise is derived from SHA-256; it depends on nothing else — not on the environment, the clock, or any RNG.
  • Byte-for-byte integrity — Bytes outside a match are left untouched, down to the last byte. CRLF line endings survive. Integrity is verified mechanically before output; --strict refuses to write on failure (exit code 3).
  • No guessing — The user specifies what is sensitive. The engine never guesses.
  • Receipts — The receipt records the facts of processing (positions, lengths, modes, hashes) but never the sensitive body itself. Even "no pattern remains" is reported as a measurement (pattern_appearance_in_output), not a promise.

The name refers to a sieve: drop only what is specified, and leave everything else unharmed, byte for byte.

Companion tool to Sieve Lens (observation of invisible content) — Lens observes, Redact masks.


🔥 Features

Six redaction modes

MODE Operation Content
delete remove the region empty string
mosaic fill per character █ repeated for the original character count
label numbered labels prefix (default [REDACTED]) + sequence number
noise same-class replacement picked deterministically within the same character class (hiragana / katakana / kanji / upper / lower / digit)
decor wrap ARG + original + ARG
replace bulk replace ARG

Built-in matchers (--builtin)

NAME Target
postal-jp Japanese postal codes NNN-NNNN
phone-jp Japanese phone numbers (090-… / 03-… / 050-… / 0120-… / 4-digit area codes 01XX-07XX)
email Email addresses (ASCII)
chars All occurrences of given codepoints (U+200B,U+00AD form)

Image masking (--region)

PNG images (8-bit RGB/RGBA, non-interlaced, non-animated) are masked by explicit regions: --region x,y,w,h:MODE[:ARG] (repeatable; overlapping regions are discarded in declaration order; zero-area or out-of-bounds regions are usage errors; --rule cannot be combined with --region).

MODE Effect
delete opaque white fill
mosaic block average over all channels (blocks align to the region origin; ARG = block size, default 8)
noise per-pixel deterministic replacement — SHA-256(img:x:y:R,G,B) drives the new RGB; alpha is kept, so semi-transparent pixels keep their visibility (content changes, visibility does not)
label black band with [REDACTED]n (bundled bitmap font)
decor 2px border in the ARG color (RRGGBB hex)
replace ARG text drawn on a white fill (bundled bitmap font)

Image receipts set byte_integrity_verified to null (not applicable — PNG re-encoding changes file bytes structurally) and report pixel integrity outside every region as pixel_integrity_verified; --strict exits 3 when it fails. File metadata (EXIF etc.) is always dropped on save — a privacy-friendly default by design. Output bytes are deterministic across platforms and pinned in CI (with Pillow 12.3.0; future Pillow updates may change encoded bytes, never pixels).

Word-unit matching (+ prefix)

太郎:label also matches the 太郎 inside 田中太郎; 太郎:+label matches only at word boundaries (adjacent characters of the same class, or both alphanumeric, cause rejection).

Config files and Lens integration

  • --config rules.cfg: load rules from a file (rule <spec> / builtin <spec> line format).
  • --from-lens catalog.json: generate masking rules from an observation catalog (JSON) produced by Sieve Lens. Invisible characters become deletions; look-alike letters (Cyrillic/Greek → Latin) become replacements based on the twin field.

💻 Quick start

git clone https://github.com/neguseatama/sieve-redact.git
cd sieve-redact

# Mosaic a name, label phone numbers
python sieve_redact.py in.txt -o out.txt \
  --rule "田中太郎:mosaic" \
  --builtin phone-jp:label \
  --receipt receipt.json

Example receipt (stdout) — in.txt contains x秘密y, run with --rule "秘密:delete":

Sieve Redact v0.5 — レシート
入力: 8 バイト -> 出力: 2 バイト
redact 件数: 1
  #1 rule=1 matcher=literal mode=delete pos=1..7 len=6B -> 0B sha256=062a2931da68...
他バイト完全性: 検証済み
出力内パターン残留: none

The sensitive body never appears in the receipt — hashes only. In image mode (--region) byte_integrity_verified is null (not applicable) and pixel integrity is measured by pixel_integrity_verified instead.

Integration with Sieve Lens

# (1) Lens produces an observation catalog
python -m sieve_lens_ext.redact_bridge input.txt catalog.json
# (2) Redact masks everything
python sieve_redact.py input.txt -o clean.txt --from-lens catalog.json

🔬 Determinism guarantees

Character selection in noise is fully determined by:

char = POOL[ SHA-256("<pattern>:<byte_offset>:<original char>").digest()[0] % len(POOL) ]

No seed. No environment dependence. Same input, same output, always. The bundled tests verify exact agreement with this formula by recomputation.

Overlapping matches are resolved deterministically as well: rules are tried in declaration order, each rule scans leftmost-first, later matches that overlap a confirmed region are discarded, and confirmed regions are applied in ascending order of position.


🔬 Tests

python -m unittest discover -s tests -v

113 tests (five modes, built-in matchers, word-unit matching, config files, Lens integration, CLI boundaries). No additional dependencies.


⚠️ Known limitations

  1. No regex — patterns are literal, exact-match strings only
  2. No case-insensitive matching — matching is case-sensitive
  3. No automatic sensitive-data detection — the user specifies what is sensitive (by design)
  4. Text and PNG images — PDF and Office formats are not supported; image masking is PNG-only (8-bit RGB/RGBA) and JPEG is explicitly out of scope; PDF masking is out of scope (observation is Sieve Lens's domain)
  5. Full-width digits and non-ASCII hyphens are out of scope for postal/phone
  6. 4-digit area codes starting with 08/09 (except 0800) and short numbers such as 117/104 are out of scope for phone-jp — match them explicitly with --rule

📄 License

MIT. See LICENSE.


👤 Author

  • Kai IWASAKI

Metadata

Release files for sieve-redact 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sieve-redact 0.5.0
File Size Uploaded
sieve_redact-0.5.0.tar.gz 36.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sieve-redact 0.5.0
File Interpreter ABI Platform
sieve_redact-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 57.2 kB

Release files / sieve_redact-0.5.0.tar.gz

Download URL sieve_redact-0.5.0.tar.gz
Size 36.6 kB
Tags Source
SHA-256 checksum
How to use checksums
71b35c56f0a82eb662cdeee9b9c3cb67a932d02b3b799be46ca0ea417f0e288a
BLAKE2b-256 checksum
How to use checksums
e19e2695b1e67486b09616beb8a6ee2a8d930301821f0b8353e9cd9626d3cb0b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / sieve_redact-0.5.0-py3-none-any.whl

Download URL sieve_redact-0.5.0-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dc22c6f8c8bcbf97d6faa7e3c0e33d4a28c6430aac8d6de80ca8c388f65ac5e4
BLAKE2b-256 checksum
How to use checksums
9118aa1ca94a6086cbd9a72ce3eb6bf60820de6932f82404735f8fc4370a959c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

This release

0.5.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page