ADR 0025: Record historical scanner salvage before restoring capability
- Status: Accepted
- Date: 2026-09-01
Context
The workspace migration left the former root src/scanner/ tree outside the
current crate graph, and commit
28bfb2d8ae3a4f707b7423cac65b6be8e11085b6 later removed that unbuilt
monolith. Reverting the deletion would restore neither a coherent product
boundary nor trustworthy behavior. The historical sources mixed reusable
algorithms and taxonomies with direct I/O, unbounded caller-owned values,
random identity, and findings that were not supported by target evidence.
The deletion nevertheless removed useful recovery knowledge. In the
immediately preceding snapshot
ede3d9e5b1098434a771ae6ca3cb530941e22210, the 38 files under
src/scanner/ include algorithms, research vocabulary, fixtures, and rejected
behaviors that should not have to be rediscovered from informal Git archaeology.
The workspace split at 3c90364279284bdbb82494b4e03d71b5066657c4
did not faithfully port that tree into the current scanner crate.
A whole-file verdict is not sufficient. For example, historical detector.rs
contains a useful hexadecimal/wildcard buffer-signature scanner, an unsafe
memory-mapped file adapter, and an unrelated request-path detector that treated
payload text as proof of a vulnerability. Those components require different
decisions.
Decision
- Keep the monolith deleted. Historical source is recovery evidence, not current product authority, and no ledger entry makes historical code compiled, reachable, supported, or executable.
- Maintain
salvage/historical-scanner/ledger.tomlas the authoritative strictvenom.historical-scanner-salvage/v1inventory. Its generated readable view isdocs/history/historical-scanner-salvage.md; the Markdown report is not a second independently maintained classification. - Bind each of the 38 historical paths to its local Git blob identity and byte size. Classify reusable and prohibited behavior at component granularity with closed dispositions, priorities, modern destinations, and lifecycle statuses.
- Validate the ledger through
cargo run --locked -p xtask -- scanner-salvage. The validator uses local Git objects only, proves the source/split/deletion identities and exact tree inventory, checks component contracts, recalculates a deterministic semantic digest, and rejects a stale generated report. It neither compiles nor executes historical code. - Require any future recovery to update only the relevant component from
PlannedtoRestoredand identify its reviewed modern implementation. Classification is not a promise that every planned component will ship. - Record the byte-pattern compiler and caller-buffer scanning core from
detector.rsas the first P0 recovery candidate for a future separatevenom-artifactdomain. Do not restore its unsafe mmap adapter, fabricated URL/request finding generator, random finding identity, raw payload evidence, or automatic severity.venom-artifactdoes not exist in this change. - Keep this inventory entirely in repository tooling and documentation. It adds no scanner, CLI, API, proxy, exploit, network, filesystem, or process runtime and changes no scan behavior or claim policy.
Consequences
- Useful historical concepts remain discoverable without treating deleted source as supported code or restoring mixed authority.
- Component-level records can preserve a payload taxonomy or fixture while explicitly rejecting fabricated findings or unsafe adapters from the same file.
- Exact local Git proof makes missing files, extra classifications, blob drift, and stale generated documentation fail closed in repository validation.
- Future recovery work has a reviewable chain from historical component to bounded modern implementation. Deleting obsolete source no longer silently deletes the decision record about recoverable value.
- This change has no runtime effect. Default
venom scan, the opt-in legacy runner, exploit isolation, evidence semantics, and all network authorities remain unchanged.
Alternatives considered
- Revert the monolith deletion. Rejected because it would reintroduce an unbuilt, mixed-quality tree outside current crate, authority, evidence, coverage, and compatibility contracts.
- Classify only whole files. Rejected because valuable algorithms and
prohibited behavior coexist in files such as
detector.rs. - Copy promising source into the ledger or report. Rejected because the inventory should bind compact facts to Git objects, not create another source archive or executable path.
- Treat Git history alone as the inventory. Rejected because Git preserves bytes but not a reviewed disposition, modern destination, rejected behavior, or restoration status.
- Restore the byte scanner in this decision. Rejected because the ledger must land without runtime changes; a bounded artifact domain requires its own exact-head reviewed increment.