Skip to content

Releases: Dgotlieb/substantiate

v0.1.4

Choose a tag to compare

@Dgotlieb Dgotlieb released this 26 Aug 00:04
Release 0.1.4

v0.1.3

Choose a tag to compare

@Dgotlieb Dgotlieb released this 25 Aug 03:25
Release 0.1.3

v0.1.1

Choose a tag to compare

@Dgotlieb Dgotlieb released this 25 Aug 01:47

A bug fix release. Upgrade with pip install -U substantiate.

Fixed

Fabricated commit SHAs using no digits were not detected. A full-length hex string such as deadbeefdeadbeefdeadbeefdeadbeefdeadbeef was not extracted as a claim at all, so a report citing an invented commit of that shape passed without comment.

The rule that dropped it — a SHA must mix digits and letters — is correct for an abbreviated SHA, where accede and deadbeef are English words and 20190808 is a date. At full length no such ambiguity exists: no word is forty hex characters. And this was the case that mattered most, since a fabricated report reaching for a plausible commit reaches for deadbeef far more often than for a random mix.

Only the digit requirement is lifted, and only at full length. Forty digits is still not a commit, and abbreviated hex words are still rejected.

Also

The test fixture now commits with a fixed identity and timestamp, so its SHA is reproducible. It was random per build, and a test reading it was quietly betting that a twelve-character prefix would contain a hex letter — which failed one CI job in nine.

Known gaps

  • #3 — constants assembled by token pasting cannot be resolved without preprocessing
  • #4 — tree-sitter drops enum constants near multi-line deprecation macros

Full changelog: v0.1.0...v0.1.1

v0.1.0

Choose a tag to compare

@Dgotlieb Dgotlieb released this 24 Aug 00:03

An evidence gate for open-source contributions: check whether the claims in a report correspond to anything real.

Install

pip install substantiate            # zero dependencies
pip install 'substantiate[treesitter]'   # recommended: resolves enum constants

Use

substantiate check report.md --repo ~/src/yourproject --ref v1.2.3

What it checks

Checks Resolved against
Tier 1 file paths, symbols, line numbers, version ranges, commit SHAs the repository at --ref
Tier 2 CVE, CWE, RFC sections, link liveness OSV, MITRE, RFC Editor (--online)

Symbols resolve as declarations, not as strings — a mention in a comment, or in the report's own quoted diff, does not substantiate itself.

Three things to know

It is a filter, not an oracle. A fabricated report citing only real files, real symbols and a real CVE passes every check. This removes the cheapest fiction, which is most of it today.

It never auto-closes. Exit status is 0 even when nothing resolves, deliberately, so it cannot be wired up as a gate that buries a real report. Automation that must branch on the outcome can opt into --exit-code and read the JSON.

The false positive is the enemy. Marking down an honest reporter costs them credibility they earned, so every miss the tool can explain carries a hint, and claims it has no standing to judge are skipped rather than reported.

Measured

Against curl's 206 published advisories — real, human-written, accepted as valid — 7.3% of tier-1 claims are unresolved and unexplained when checked at HEAD. Against 150 documents of curl's own documentation, 32.0%. Both numbers, including the one that is too high, are in the README with the reasons.

Run the benchmarks yourself:

python3 benchmarks/real_advisories.py ~/src/curl
python3 benchmarks/false_positives.py ~/src/curl docs --limit 150

Known gaps

  • #3 — constants assembled by token pasting cannot be resolved without preprocessing
  • #4 — tree-sitter drops enum constants near multi-line deprecation macros

Reports of genuine work marked down without a hint are bugs. Please open an issue with the report and the repository.