feat: revised-vs-superseded disambiguation via lead-signature fingerprint (almanac-template#11 item 3)#20
Merged
Conversation
…rint (almanac-template#11 item 3) Closes SCHEMA-V2.md open item #2 (compute observed.fingerprint_result) and resolves the ambiguity in open item #5: on a redirect + content drift, is the resource moved (same thing, relocated) or superseded (different thing now)? Adds a second, narrower fingerprint -- fingerprint.lead_hash, a hash of the normalized title + lead excerpt -- so drift can be classified as cosmetic (nav/ads/footer churn) vs substantive (the actual claim changed) without storing or hosting page content (schema rule: catalog, don't host). Disambiguation, cheapest signal first: 1. Full-artifact hash still matches after redirect -> moved (strongest). 2. Full hash drifted but lead_hash still matches -> moved. 3. lead_hash also drifted -> superseded. 4. No lead_hash baseline to check -> honest default -> redirected. Same-URL drift is unambiguous per the existing status table (revised, full stop) and needs no lead-signature check at all. Per item 5's leaning: this PROPOSES via issue (reusing the GitHub client from alert_on_dead_links.py / alert_on_recovery_rot.py), never auto-writes status, status_since, or status_source. Read-only otherwise.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements item 3 of almanac-template#11: revised vs superseded disambiguation. Also closes SCHEMA-V2.md open item #2 (
observed.fingerprint_resultcomputation, previously unbuilt) since it's a hard prerequisite.The genuine ambiguity flagged in SCHEMA-V2.md open item #5 is only on redirect: is the resource
moved(same thing, relocated) orsuperseded(something else now sits there)? Same-URL drift is already unambiguous per the existing status table (revised, full stop).Design: adds
fingerprint.lead_hash— a second, narrower fingerprint (hash of normalized title + lead excerpt) captured alongside the existing full-artifactsha256. This lets drift be classified as cosmetic (nav/ads/footer churn) vs substantive (the actual claim changed) without storing or hosting page content — consistent with the schema's "catalog, don't host" rule; it's a hash, same assha256, just over a narrower, more stable region.Disambiguation, cheapest signal first:
moved(strongest evidence)lead_hashstill matches →movedlead_hashalso drifted →supersededlead_hashbaseline to check → honest default →redirectedPer item 5's leaning, this proposes via issue (reusing the
GitHubclient fromalert_on_dead_links.py/alert_on_recovery_rot.py— third reuse now) and never auto-writesstatus/status_since/status_source. Read-only otherwise.Test plan
pytest tests/ -q— 32 passed (17 existing + 15 new), no regressionspython scripts/validate.py— schema still valid, live catalog entry still validates against the extended schemaruff check— cleanhttps://example.com, confirmed_fetch/sha256_hex/lead_hash/classifywork end-to-end against a real responsecheck_revision_drift.py --jsonagainst the live catalog — clean[](no entries have afingerprint.sha256baseline yet, expected for this early-stage catalog)Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com