Route OPF Progress to stderr · Entire

Why you see this output

The lines come from the redact package's OPF progress UX (redact/opf.go, redact/batch.go, redact/redact.go). The key detail is where they're written:

var opfStderr = openTTYOrDiscard()   // opens /dev/tty, falls back to io.Discard

opfStderr is wired to /dev/tty, not stdout or stderr. That's deliberate for production: the post-commit hook runs with 2>/dev/null, so writing to the controlling terminal directly lets the "scanning…/done" progress survive that redirect.

The side effect: because it goes straight to your terminal, it bypasses go test's output capture and shows up interleaved with PASS lines.

The tests producing it are the strategy-package OPF tests (manual_commit_opf_rewrite_test.go and friends). They configure a fake OPF runtime via configureFakeOPF:

redact.ConfigurePrivacyFilterWithRuntime(redact.OPFConfig{
    Enabled: true, Categories: {"private_person": true}, Command: "/tmp/test-opf",
}, rt)   // rt is an in-memory fake

…but unlike the redact package's own tests (which set opfStderr = io.Discard), these tests never silence opfStderr. So the progress messages leak to /dev/tty. The × unavailable (/tmp/test-opf) line is the fail-closed test exercising the "OPF binary missing → fall back to regex layers" path; /tmp/test-opf is a deliberately bogus command path.

Is it doing anything expensive?

No. Everything you saw is cheap, in-memory work:

So this is harmless cosmetic leakage, not a performance concern.

If you want to silence it

The clean fix is to make configureFakeOPF redirect opfStderr to io.Discard for the duration of the test (matching what redact's own tests already do), via a small exported test helper in redact — there's currently no exported setter, only the unexported var.

Summary

Confirmed Changes

This is local to the redact/strategy area and unrelated to your clean working tree's prior state.