Conversation
klappy
added a commit
to klappy/oddkit
that referenced
this pull request
Apr 26, 2026
…ssion (#140) Phase 2 of the link-rot-elimination campaign. Implements oddkit_resolve per klappy://docs/oddkit/specs/oddkit-resolve (DRAFT v4 — KISS) and klappy://canon/principles/identity-resolved-by-protocol. URI in, current canonical answer out. Walks superseded_by chains in existing frontmatter to terminus, normalizing across three shapes used in canon authoring (full klappy:// URI, path with .md, path without). Backward-compatible — purely additive net-new action; existing callers unchanged. Reads only the existing index. Status enum: FOUND | NOT_FOUND | INVALID_INPUT | CIRCULAR_SUPERSESSION Vodka discipline applied. v3 of the spec proposed a richer surface (batch action, resolve_links flag, aliases field, supersession_response field, identity-by-meaning queries). v4 cut to the minimum: one input, one job. Cuts captured with explicit revisit triggers in klappy://docs/planning/link-rot-deferred-concerns. Co-authored-by: Cursor Agent <bugbot@cursor.com> Caught in review: - VALID_ACTIONS array missing 'resolve' (Cursor Agent fix) - supersession_chain field-name inconsistency in error branches (Cursor Agent fix) - state-threading parity with peer actions (Cursor Agent fix) - mixed-shape superseded_by lookup failure (independent Sonnet 4.6 validator fix per E0008.3 release-validation-gate) Version bump: 0.24.0 → 0.25.0 Canon basis: klappy://canon/constraints/release-validation-gate, klappy://canon/principles/vodka-architecture, klappy://canon/methods/supersession Canon PR: klappy/klappy.dev#142
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
Phase 1 of the link-rot-elimination campaign. Lands the four planning/canon artifacts that scope and govern the work:
docs/oddkit/specs/oddkit-resolve.md—oddkit_resolveaction spec (DRAFT v4 — KISS)docs/oddkit/specs/oddkit-audit.md—oddkit_auditaction spec (DRAFT v2 — KISS)canon/principles/identity-resolved-by-protocol.md— tier-1 canon principle (sibling to anti-cache-lying)docs/planning/link-rot-deferred-concerns.md— ledger of cuts and revisit conditionsdocs/planning/link-rot-elimination-campaign.md— campaign sequencing docAll five docs are one coherent design. Splitting into separate PRs would create review windows where each doc references siblings that don't yet exist. Landing as a unit keeps the canon graph consistent.
Why this campaign exists
Recurring broken-link reports on klappy.dev. The April 9, 2026 reference integrity audit found 85 broken references; a 2026-04-24 scan found 11 more in writings authored just weeks earlier. Discipline alone has empirically failed.
The architectural answer
Authors write
klappy://URIs (identity). The protocol layer (oddkit) resolves to current location at request time, walking supersession transparently. Consumers (Lovable, claude.ai, agents, future renderers) call the resolver and render whatever it returns — never hardcode URLs in source.This is anti-cache-lying applied to references. A hardcoded
/page/some-slugis a cached projection of "this article currently lives at this URL"; supersession metadata exists but cannot help if references don't go through resolution.Vodka discipline
The campaign was redrafted from a 6-phase / ~15-PR / four-action-with-bundled-checks shape down to a 3-phase / 8-PR / two-thin-actions shape. Cuts:
oddkit_resolve_batchactionresolve_linksflag on get/searchaliasesandsupersession_responsefrontmatter fieldsaudit_allow:frontmatter fieldEach is captured in
docs/planning/link-rot-deferred-concerns.mdwith an explicit revisit trigger. Use Only What Hurts.What's NOT in this PR
klappy/oddkit, gated on E0008.3 release-validation-gate)/page/...and relative-path patterns toklappy://URIs (Phase 2)canon-quality.ymlworkflow (Phase 3)Lineage
Cross-references this PR establishes
The five docs reference each other. The principle cites the resolver spec for implementation; the resolver spec cites the principle for axiom; the audit spec cites the resolver as its dependency; the campaign references all three; the deferred ledger references the campaign for context. Landing together, every cross-reference resolves on day one.
Note
Low Risk
Low risk because this PR only adds documentation/spec artifacts (no runtime code or workflow enforcement changes), though it sets contracts that later implementation PRs will need to follow.
Overview
Defines the Phase-1 foundation for eliminating link rot by standardizing on
klappy://identity references that are resolved by the protocol rather than hardcoded URLs/paths.Adds draft specs for
oddkit_resolve(supersession-aware URI→current location resolution with partial-data reporting) andoddkit_audit(CI-oriented scan that flags unresolvedklappy://URIs and legacy/page/.../relative markdown link patterns, with a line-level allowlist).Adds planning docs that capture the campaign sequencing and a deferred-concerns ledger enumerating cut scope and explicit triggers for reintroducing it.
Reviewed by Cursor Bugbot for commit cbd06d6. Bugbot is set up for automated code reviews on this repo. Configure here.