Development record
scanner isPathSegmentByte includes the slash so a third partys home path inside a file URL escapes stage-one redaction
scanner isPathSegmentByte includes the slash so a third partys home path inside a file URL escapes stage-one redaction
Evidence
internal/adapter/scanner/identity.go:454 — isPathSegmentByte includes '/' in its class, so leadingBoundaryOK suppresses a genericHomeRe match preceded by a slash. Empirically open file:///home/alice/notes.md with a different caller identity → 0 findings (home_path_other missed); see file:///Users/bob/secret.txt → 0. A third party's home path inside a file:// URL passes Stage-1 redaction unredacted — a privacy false NEGATIVE on the redaction path.
Adversarial verdict: CONFIRMED (minor) — RECORD-ONLY
Surfaced as a spin-off of the iss-305 repolint fix (which deliberately uses repolint's slash-EXCLUDING isPathSegmentChar to avoid importing this FN). Not fixed this round: changing the scanner's isPathSegmentByte to exclude / has its own false-POSITIVE surface on the redaction path that needs independent measurement before it is safe — recording it is the correct outcome. Distinct from iss-305 (repolint over-detection); this is scanner under-detection.
Grounds
- pursued: a third-party home inside a file URL is redacted while relative paths and web URL paths are not reported; a file-URL home stored verbatim, or a relative docs path now redacted, would show it wrong
Frontmatter
| id | iss-324 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-324-scanner-ispathsegmentbyte-includes-the.md
open on GitHub ↗ · commit history ↗
mentions4
- iss-305abcd lint privacy-hygiene hard-fails on ordinary committed content because hasAbsHomePath lacks the leading-boundary predicate its scanner twin has
- iss-2608231000561060The repo-conformance lint runs in no gate while the record says it gates CI, and it is not currently gate-ready, which are two problems needing separate decisions. Verified 2026-08-23 on origin/main. brief/04-surfaces/README.md row 16 describes /abcd:lint as checking the three-tier layout, AGENTS.md router, durable decisions, docs currency, privacy hygiene and identity positioning, and states it 'backs prepare-this-repo and gates CI (itd-85)'. It does not gate CI. The Makefile's preflight target is lint-reviews record-lint docs-lint plus build, vet, test and race, with no abcd lint, and the Makefile has no abcd lint or repolint target at all. Searching .github/workflows for an invocation of the repo-conformance lint, excluding the unrelated 'abcd docs lint', returns nothing in ci.yml or release.yml, whose only lint steps are go run ./cmd/record-lint and go run ./cmd/abcd docs lint. The surface runs only when a human types it. The second problem is why simply wiring it up does not work. On current main the lint emits 19 privacy-hygiene findings, 17 at blocker severity, and the sampled ones are not leaks. Nine of the 19 are in the scanner's own source or in ledger entries about the scanner, where the patterns appear as subject matter. Three sampled outside that set are documentation examples: a Linuxbrew prefix in a spec table and again in [dcn-2608200000000006](../../decisions/dcn-2608200000000006-homebrew-distribution-recorded-and.md), and a CHANGELOG entry recording that certain path shapes stopped being read as usernames. So gating it today would fail every build on content that is correct. iss-305, resolved, records the mechanism -- hasAbsHomePath lacks the leading-boundary predicate its scanner twin has -- and iss-307, iss-308 and iss-324 are adjacent boundary defects in the same family. A waiver marker exists, abcd-lint:allow with the legacy spelling abcd-audit:allow, and the rule's own source uses it on two lines, so the mechanism is available but is not applied across the corpus. What makes this worth deciding rather than filing and forgetting: the rule is right about the case that actually bit. An absolute home path written into a ledger issue body is exactly what its pattern catches, and on 2026-08-23 two sessions independently wrote one. Neither was caught by an instrument. record-lint did not see them because its roots are ['.abcd/development'] and the ledger is in .abcd/work; the lint that would have seen them does not run. Note the two are not interchangeable, since record-lint is scoped to the durable record while privacy-hygiene scans every tracked file, so widening record-lint's roots is a different fix from running the lint. Decide in order: whether the record's gates-CI claim is corrected or made true, and if made true, whether the false-positive rate is addressed by waivers, by the iss-305 boundary fix, or by narrowing what blocks. Leaving the claim standing while the surface runs nowhere is the shape enforcement-claims-are-facts names, and iss-2608230847432286 records the class.
- iss-2608270645473170The capture/scanner redaction over-masks the owner segment of a public 'owner/repo' string, replacing a legitimate public GitHub org/user name with [redacted-user] even when it is the very repository the record lives in. Observed 2026-08-27 when a captured issue body referencing this repo's own owner/repo slug had the owner masked. Not harmful (the slug still reads), but a false positive: the identity/path redaction treats an owner/repo owner as a sensitive identifier unconditionally. Consider exempting the repo's own owner (and public org names) from identity redaction, or narrowing the owner-segment match. Adjacent: iss-324 (scanner ispathsegmentbyte includes the slash in a third-party path).
- iss-2609290055092630fsutil.RedactRoot and the scanner's home sweep still disagree on the LEADING boundary for a home of two or more segments under a longer root: SweepCallerHome sweeps '/Volumes/T7/srv/qzhome/x' to '/Volumes/T7~/x' (iss-324: a longer root does not make the name someone else's), while RedactRoot, and so RedactHome, the CLI error scrub and the install receipt, leave it whole because the byte before the root is a path-segment byte (iss-2609230641546141 chose that to stop '/private~/wt/a' mangles). The identity survives in CLI output wherever a message names a home under a backup volume or mount. Closing it needs a choice between the two rules for the '~' polarity (the '.' repo polarity has no counterpart); found while unifying the trailing half under iss-2608292037564347.