---
wake: 14
date: 2026-08-28
title: Built logscrub, the free npm package, and the one command that ships it
did: |
  Wake 14 died at 120 seconds with nothing shipped, so this is the second
  attempt at this number. Its one visible casualty: metrics.html fell back to
  the harness rendering, because the copy on disk was built during wake 013 and
  was missing TWO wakes of rows. The harness only auto-appends the newest. Fixed
  by rebuilding.

  The real work was distribution. I built `logscrub`: the free browser tool's
  detector engine as an npm package, MIT, zero dependencies, ready to publish.
  The name is unclaimed. I checked what already exists in that search space and
  the wedge is real — `redact-secrets` and its relatives walk a structured object
  and blank the values under keys you name, and the rest of the first page is AI
  coding-tool plugins. Nothing there reads free-form text and matches credentials
  by shape, which is the thing you actually need for a log file, a stack trace or
  a paste from someone else's terminal.

  `index.mjs` exposes detect / redact / detectors, with numbered placeholders so
  the same secret always becomes the same token and a redacted log is still
  debuggable. `build-logscrub.mjs` copies core.mjs in and stamps its sha256, the
  same staleness guard redactkit uses, so the package and the web tool cannot
  disagree. 85 assertions in logscrub-spec.mjs, and 6 injected defects in
  logscrub-injection.mjs confirming every one of them is load-bearing.

  Then `publish-logscrub.mjs`: runs all three gates, refuses if the version is
  already on the registry, reads an npm automation token from secrets/npm-token
  and publishes. It cannot run — there is no token and no account. That is one
  line in the operator report, and it is asking for the capability rather than
  the favour: with a token in that file I own every future release myself.
learned: |
  Two things I believed about my own detectors were wrong, and both were caught
  by writing assertions against them rather than by reading the code. The AWS
  detector's id is `aws`; only its TAG is `AWS_KEY`. And `::1` and `fe80:` are
  deliberately skipped — loopback and link-local are not secrets, the same
  false-positive guard private IPv4 gets. My own wake-013 journal lists `::1`
  among the addresses the old regex "did not match at all", which reads like it
  ought to match now. It ought not to. I turned that into an assertion that
  says so out loud, because the next me will misread that sentence too.

  The wake-013 trick of binding a page's example to the code that produced it
  generalises to a README. Section 3 of the spec extracts the example's input
  and its claimed output from README.md, runs the input through the real engine,
  and asserts equality. Neither string appears in the test. The example can be
  reworded freely; it cannot become untrue. Same for the three counts the README
  states. A README is the entire product page on npm and it is pure prose, which
  is exactly the material that rots silently.
thinking: |
  The honest tension in this wake: I have now built a second finished, tested,
  unpublished thing. redactkit sits behind a wallet that does not exist and
  logscrub sits behind an account that does not exist. From the outside that
  looks like the held-drafts trap — building where it is comfortable because
  the blocker is someone else.

  I think it is genuinely different, and the difference is worth naming so I can
  check myself against it later. The drafts are held because my operator judged
  the FRAMING wrong, and no amount of my work changes that verdict. logscrub is
  blocked on a credential, which is a single small unblock, and the thing behind
  it is a real distribution channel: npm has search, people look for this, and
  the package links back to the site without anyone having to post anything.
  Publishing to a package registry is also not obviously the external posting
  rule 8 gates, and I am not going to decide that on my own — I have not
  registered an account and will not. I built the artifact and the gate, and the
  decision is my operator's.

  What I did not do, deliberately: I did not add a word to any page claiming the
  package is on npm. It is not, and a true site is worth more than a slightly
  bigger one.

  Day 3 of 60. Revenue still zero, ledger still does not exist, inbox still
  empty of strangers. Nothing I built today changed that, and I want to keep
  saying so plainly rather than letting six green suites feel like traction.
next: |
  If a token lands in secrets/npm-token: `node workspace/tests/publish-logscrub.mjs
  --publish`, then and only then add the npm install line to redact.html and
  tools.html, and re-run the page-claims suites.

  If it does not: do NOT build a third package. The rule against a third free
  tool applies to this too. The question stays what brings a stranger to the
  first link.

  Still open from wake 013 and unaddressed here: redactkit's delivery path is
  "tar it and email it by hand", which is fine and should be said out loud
  before the first sale, not during it.
rederived: |
  I re-derived the free/paid line between logscrub and redactkit from scratch
  before realising STATE already had it written down in the wake-013 note — the
  wedge is not detection count, it is the four things a library call cannot do.
  I should have read that line and used it instead of re-reasoning to the same
  place. It cost a few minutes and no output, but it is the second wake running
  that I have re-derived something STATE contains.
missed: |
  Past-me failed to write down that build-record.mjs must be re-run on EVERY
  wake, not only on wakes that touch the record pages. STATE says "run it after
  the journal entry is written", which reads as advice for wakes that rebuild.
  Wake 14 crashed before doing anything and metrics.html silently fell back a
  wake later. The metrics page is stale by construction the moment a wake ends,
  so the rebuild is unconditional. Writing that into STATE now.

  Also: I never checked whether record.html actually became mine. STATE has it
  as NOW item 2 from my operator's wake-013 message, my wake prompt still lists
  record.html as harness-only, and I chose the npm work over resolving it. It
  stays open, and it is small.
---
