Skip to content

v1.8.1: shadow:check names the database it audited - #8

Merged
NeverEndingCode merged 1 commit into
mainfrom
v1.8.1-shadow-source
Aug 8, 2026
Merged

v1.8.1: shadow:check names the database it audited#8
NeverEndingCode merged 1 commit into
mainfrom
v1.8.1-shadow-source

Conversation

@NeverEndingCode

Copy link
Copy Markdown
Owner

Closes the gap noticed right after the production gate run: the report proved
100% but never said which database produced that number.

What changed

npm run shadow:check now names the database, twice:

[shadow] auditing sqlite /app/data/rackstack.db
[shadow] MATCH github:37058311 -> github:37058311

=== SuperTokens shadow-mode report ===
database:             sqlite    /app/data/rackstack.db
identities compared:  1
...
GATE: PASS - 100% of comparable identities matched.

Once before the run, so a run that dies partway — missing identities
table, unreadable media — has still said what it was pointed at. That is
exactly the run where an operator most needs to know. And once inside the
report block
, because that is the part people tee to a file and paste into
tickets, and a PASS is only meaningful next to the database that produced it.

The gate's own NOT RUN guidance says the usual cause is the wrong database,
so not naming it was a real omission.

The password is stripped

DATABASE_URL carries the database password, and this output gets
screenshotted and shared. So:

postgresql://rackstack_user:hunter2@192.168.1.10:5432/rackstack
  ->  postgres  postgresql://rackstack_user@192.168.1.10:5432/rackstack

Redaction goes through the URL parser, not a regex, so a password containing an
@ cannot survive half-masked — asserted by test. An unparseable
DATABASE_URL says so rather than being echoed back.

Docs brought in line with the production run

The gate passed on 2026-08-08 (Unraid, 6 identities, 6 matched, 0 mismatched,
0 orphaned, GATE: PASS), so several docs were stale:

  • The runbook's "what has NOT been verified" list had shadow mode as never run.
    Now struck through with the result — cutover to dual is cleared.
  • authentication-methods.md Phase 0 dropped the "supply a production export"
    prerequisite. Running the gate on the container audits the live database,
    which is strictly better than auditing a copy.
  • Phase 0's v1.7-on-Postgres item is now honest that the status is unconfirmed
    — and notes the SuperTokens core needs its own Postgres database in Phase 2
    whatever RackStack itself runs on.
  • The v1.8.0 changelog entry still says shadow mode had not been run, which was
    accurate at that release; v1.8.1 records that it has.

Verification

  • 634 tests SQLite / 660 Postgres (npm run test:all), 39 smoke assertions
  • New tests cover: SQLite path shown, Postgres host/database shown, password
    absent, @-containing password not half-masked, unparseable URL handled,
    DATABASE_URL preferred over DB_PATH to match openReader, the line
    present in the report block and above the GATE: line, and omitted entirely
    when no source is supplied (the live per-login path has no single database)

Version bumped to 1.8.1; client/package.json deliberately untouched.

🤖 Generated with Claude Code

The gate's own guidance says a NOT RUN result is usually the wrong database -
but the report never said which one it read, so a PASS could not be checked
against the box you meant to audit. Printed twice on purpose: once before the
run, so a run that dies partway (missing identities table, unreadable media)
has still said what it was pointed at, and once inside the report block, which
is the part that gets teed to a file and pasted into tickets.

The Postgres password is stripped. That output is screenshotted and shared, and
a connection string carrying rackstack_user:hunter2 would leak the database
password into every copy. Redaction goes through the URL parser rather than a
regex, so a password containing an @ cannot survive half-masked - asserted by
test.

Also brings the docs into line with reality now that the gate has been run
against production (2026-08-08, Unraid, 6/6, GATE: PASS):

- The runbook's "what has NOT been verified" list had shadow mode as never run.
  It is now struck through and records the result. Cutover to dual is cleared.
- authentication-methods.md Phase 0 dropped the "supply a production export"
  prerequisite - running the gate on the container audits the live database and
  is strictly better than auditing a copy.
- Phase 0's v1.7-on-Postgres item is now honest that the status is unconfirmed,
  and notes the SuperTokens core needs its own Postgres database in Phase 2
  whatever RackStack itself runs on.
- The v1.8.0 changelog entry still says shadow mode had not been run, which was
  true at that release; the v1.8.1 entry records that it has.

634 tests green on SQLite, 660 on Postgres, 39 smoke assertions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@NeverEndingCode
NeverEndingCode merged commit 8c00843 into main Aug 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant