BuildNot yet confirmed elsewhere1 publisher3 min readPublished
A redaction placeholder became a primary key, and it closed other people's promises
One catch-all regex rewrote long task slugs to TOKEN_REDACTED, a ledger keyed accounts on that constant, and a single done line marked two owners' work finished.
The Engineer · Build desk

What happened
- A scrubber on a shared log runs named-secret patterns, then a catch-all that rewrites any unprefixed high-entropy run of 35 or more characters to the literal TOKEN_REDACTED.
- Because the placeholder never varies, every redacted slug across authors and days lands in that one account, where a single done zeroes the entire row.
- The author's repair ignores token shape and pins identity to grammatical position: the token following task, taking, verify, done, chat-review, chat-review/ or task:.
Why it matters
- exposure Any dedup, cache or GROUP BY placed downstream of a masker inherits the collapse, which puts error trackers and analytics tables inside the blast radius of a scrubber their owners did not write.
- constraint The allowlist route has no end state: three prior widenings each left the next identifier redacted, so a shape-based catch-all has to be paid for again on every new naming scheme.
- cost The quiet variant deletes its own audit trail, so the bill falls on whoever's obligation was closed without being met, and the report itself offers nothing to find them with.
- decision Anyone running both halves has to pick a side to enforce on: a masker that never touches key material, or a consumer that refuses a constant as an account key.
Two failures came out of the same substitution, and they do not deserve equal weight. The unclosable liability is loud: the ledger opened `promises:health:token-redacted`, no `[done]` citing the real slug could ever bind that key, and the tool was still reporting finished work as leaked six hours later [8]. That one is visible and can be repaired by hand. The collision is the one that matters, because the placeholder is the same string on every line from every author, so separate obligations land in one account and a single `[done]` nets the row to zero [3].
In the reproduction, two owners held two tasks sharing one key and only one of them filed a `[done]`; `mesh-promises --report` printed no leaked promises, `0/0/0/0 open`, one kept [4]. One obligation was genuinely outstanding and the report accounted for none of it, so the open count was wrong by the entire quantity it exists to measure [13]. The author's observation about the merged row is the transferable part: it looks exactly like one healthy row, so the anonymisation removed the evidence that anything had been anonymised [9].
The mechanism is stated plainly in the post. A redaction function returns a constant, and a constant is never an identity, so a masked field that reaches a key, a fingerprint, a cache key or a `GROUP BY` turns the masker into an equality operator asserting that everything it could not read is the same thing [10]. The author gives two other shapes it takes: an error tracker that fingerprints on a message containing a scrubbed user ID merges unrelated crashes into one issue, and resolving that issue resolves all of them [14]; a pipeline that rewrites `user_id` to a fixed `<REDACTED>` whenever a value fails validation makes every such user the same user, with `COUNT(DISTINCT user)` reporting one [15].
The repair the post calls obvious, teaching the catch-all that this particular string is an identifier, had already been attempted three times, for a review slug, a git SHA and a filename, and each widened alphabet left the next case redacted, because "long, high-entropy, no prefix" describes secrets and identifiers equally well [11]. What worked instead was refusing to look at the token at all: the log's grammar fixes the slug's position, immediately after `[task]`, `[taking]`, `[verify]`, `[done]` or `[chat-review]`, after a `chat-review/` prefix, or after the close-key `task:`, and a token in that slot is an identifier by construction whatever its shape [2]. The guarantee is bounded by that enumeration, so a slug quoted in prose, or one written under a verb added later, is back to being judged on entropy.
Scope matters here. This is one machine, one person's scrubber and a homegrown double-entry ledger, with the author stating that every number, listing and command output was re-measured while writing [12]. The bug class is the finding, not the tool. The question it hands everyone else is narrower than a policy review: where does your masker sit relative to the first thing downstream that parses what it wrote.
What to watch
- Whether slugs appearing outside the pinned grammatical slots, in prose or under a log verb added later, still get redacted and re-key to the placeholder.
- Whether the ledger gains its own guard that rejects the placeholder string as an account key, instead of trusting the scrubber to be correct.
- Whether the same collapse gets reported in a production error tracker or analytics warehouse rather than a personal ledger.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence58
- Adoption
- Insufficient
- Hype gap+12
- Incentives22
- Confidence55
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
A log scrubber sits between every writer and the shared log on the author's machine; last week it did its job and silently marked two people's unfinished work as finished.
ReportedSupportedSource: Author of the dev.to post2 sources— create a free account to open themView cited source - [2]
The fix uses the log's grammar rather than the token's shape: the slug is the token right after [task], [taking], [verify], [done] or [chat-review], after a chat-review/ prefix, or after the machine close-key task:, and a token in that slot is an identifier by construction whatever its shape. The check is implemented as a _BOARD_SLUG_POS regex.
- [3]
The placeholder is the same string every time, so every redacted slug from every author on every day keys to token-redacted; distinct obligations become one row and a single [done] nets the whole row to zero.
- [4]
In a reproduction with two owners and two separate tasks sharing one key, and one [done] from only one of them, mesh-promises --report printed: no leaked promises/claims/holds/asks (0/0/0/0 open, all within threshold; 1 kept).
- [5]
Every line written to the shared log passes through a regex pipeline: named secrets first (BOT_TOKEN=, ya29., sk-, AKIA, Bearer), then pattern 8, a catch-all that treats any unprefixed high-entropy run of 35 or more characters as a credential and replaces it with the literal string TOKEN_REDACTED.
- [6]
A separate tool replays the same log as double-entry bookkeeping: a [task] <slug> opens a liability, a [done] <slug> discharges it, and anything still open past a threshold is reported as a leaked promise. The slug is the account key.
- [7]
The author's slugs are routinely 35 or more characters and sometimes quote a machine ID inside themselves, putting an uppercase run in the middle of an otherwise lowercase slug, as in [task] tailscale-node-n2sbt7yy6t11CNTRL-lost-its-tag owner: health.
- [8]
That line entered the log as [task] TOKEN_REDACTED owner: health, and the ledger opened the liability promises:health:token-redacted, which no [done] citing the real slug can ever bind; the work was actually finished but the ledger was still reporting it as leaked six hours later.
- [9]
The author writes that the anonymisation did not just lose information, it erased the evidence that information was lost, because the merged rows look exactly like one healthy row.
- [10]
The rule the post states: the output of a redaction function is a constant, and a constant is never an identity; if a masked field can reach a key, a fingerprint, a cache key or a GROUP BY, the masker has become an equality operator saying everything it could not read is the same thing.
- [11]
The author had already widened the catch-all three times, once for a review slug, once for a git SHA and once for a filename, and each widening of the alphabet left the next case redacted, because "long, high-entropy, no prefix" describes both secrets and identifiers.
- [12]
The author states that every number, listing and command output in the post was re-measured on the machine while writing, and that measurements not personally re-run are marked as such.
- [13]
In the reproduced run, one of the two merged obligations was genuinely outstanding while the report showed zero open, so the report omitted all of the truly open obligations.
- [14]
The author gives a generic case: an error tracker that fingerprints on a message containing a scrubbed user ID merges unrelated crashes into one issue, and resolving the issue resolves all of them.
- [15]
The author gives a second generic case: a pipeline that pseudonymises user_id to a fixed <REDACTED> on any value failing a validity check makes every such user the same user, collapsing session counts, flattering retention, and making COUNT(DISTINCT user) report one.
- [16]
Any dedup, cache or GROUP BY downstream of a masker inherits the same collapse, according to the post.
Sources
1 independent publisher whose own reporting we read for this story.
- dev.toNever key anything on a redaction placeholder
1 article · August 22, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.