Three gaps in docs/design/security.md:
- The Console is absent from the threat model. The doc covers launcher config, injection, symlinks, SQLite, cleanup, and secrets — but has no section on the product's only network listener.
src/ui/server.ts implements loopback-only binding, a per-run token compared in constant time (tokenEquals), and a Host-header allowlist; none of these protections are reviewable against the security doc.
- Stale requirement ID: the redaction rule is labeled "FR-J08", but the current
docs/design/srs.md defines FR-J08 as "Human sanitization" and the redactor as FR-J12–J15 (the split is recorded in the SRS mapping). Code agrees with the SRS: src/format.ts cites FR-J08 for sanitizeHuman and "FR-J14 redaction rule" for redaction.
- Fictional mechanism: the doc says doctor/setup report "whether the variables they check are
set or unset, never a value", but no code reports any env variable's state — src/doctor.ts and src/setup/index.ts probe only executable presence via isExecutableOnPath. The credential-name list exists only as CREDENTIAL_KEY in src/format.ts for keyed-pair redaction, with a different word set.
Impact: the threat-model doc omits the one component that accepts network requests, mislabels traceability into the SRS, and describes a leak-prevention mechanism that doesn't exist (the no-leak property holds, but for a different reason), making audits against it misleading.
Acceptance: a Console section covering token auth, loopback binding, Host allowlist, and the secret-URL caveat; the redaction rule relabeled FR-J12–J15; the env-probing passage rewritten to the actual mechanisms (executable-presence probing plus redactSecrets' real pattern list).
Three gaps in
docs/design/security.md:src/ui/server.tsimplements loopback-only binding, a per-run token compared in constant time (tokenEquals), and a Host-header allowlist; none of these protections are reviewable against the security doc.docs/design/srs.mddefines FR-J08 as "Human sanitization" and the redactor as FR-J12–J15 (the split is recorded in the SRS mapping). Code agrees with the SRS:src/format.tscites FR-J08 forsanitizeHumanand "FR-J14 redaction rule" for redaction.setorunset, never a value", but no code reports any env variable's state —src/doctor.tsandsrc/setup/index.tsprobe only executable presence viaisExecutableOnPath. The credential-name list exists only asCREDENTIAL_KEYinsrc/format.tsfor keyed-pair redaction, with a different word set.Impact: the threat-model doc omits the one component that accepts network requests, mislabels traceability into the SRS, and describes a leak-prevention mechanism that doesn't exist (the no-leak property holds, but for a different reason), making audits against it misleading.
Acceptance: a Console section covering token auth, loopback binding, Host allowlist, and the secret-URL caveat; the redaction rule relabeled FR-J12–J15; the env-probing passage rewritten to the actual mechanisms (executable-presence probing plus
redactSecrets' real pattern list).