Skip to content

Report a media href that reaches its file only under case folding - #47

Merged
imnasnainaec merged 6 commits into
mainfrom
media-href-mismatch
Oct 8, 2026
Merged

imnasnainaec merged 6 commits into
mainfrom
media-href-mismatch

Conversation

@imnasnainaec

@imnasnainaec imnasnainaec commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #34.

  • New media-href-mismatch warning: a media href that reaches its file only under case folding or NFC. missing-media narrows to "no file under any spelling", and now includes an empty href.
  • Resolution reads the directory instead of probing the href's spelling, so the verdict is the same on a case-folding host as on a case-sensitive one. Directory components fold too; the conventional audio//pictures/ subfolder folds silently, since sil-lift guesses it rather than the document writing it.
  • A misspelled folder reports once per folder, with no entry; a misspelled filename reports per reference.
  • missing_media() → check_media(), returning a MediaResolution per reference that did not resolve cleanly.
  • check-media reports mismatches and exits 1 on them, and no longer calls a misspelled file orphaned as well as missing. --no-check-media covers both media codes.
  • PROVENANCE.md states a rule for negative/ fixtures instead of listing them; CONTRIBUTING follows.

Decisions recorded in #34.

🤖 Generated with Claude Code


This change is Reviewable

A media href is now resolved against the folder the way a companion
.lift-ranges already is, so a Windows-authored folder read on a case-sensitive
filesystem no longer reports as missing-media files that are right there.
Unlike a companion, whose spelling only sil-lift reads, a media href is read by
whatever serves the folder afterwards -- a web export, an APK build -- so the
fold is reported rather than resolved silently: a new media-href-mismatch
warning says the file is here but a case-sensitive host will not find it, and
missing-media narrows to no file under any spelling.

Resolution reads the directory rather than probing the href's spelling, so the
verdict is the same on a case-folding filesystem as on a case-sensitive one; an
exact probe answers for a name it can never report, since SDD.PNG stats true
against an on-disk sdd.png. Every component folds, not just the last. The
conventional audio/pictures subfolder is sil-lift's own guess, so a folder
spelling it another way resolves without being reported, while a folder the
href itself misspells is one rename however many references cross it, and is
reported once with no entry. A href reaching outside the folder is probed as
written, since which directory to fold in would be a guess.

check-media reports the same mismatches and exits 1 for them, and no longer
calls a misspelled file orphaned as well as missing: it compares folded
relative paths rather than resolved ones, which is what the library now means
by a href naming a file. --no-check-media suppresses both media codes, since
the media it exists for lives outside the folder, where no spelling can be
verified at all.

missing_media() is replaced by check_media(), which classifies each reference
rather than answering one boolean, and returns only the references that did not
resolve cleanly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@imnasnainaec imnasnainaec self-assigned this Sep 23, 2026
@imnasnainaec imnasnainaec added the 🟨Medium Medium-priority PR label Sep 23, 2026
imnasnainaec and others added 3 commits September 23, 2026 12:28
check-media built its referenced set from the paths the hrefs spell rather than
the files they reach, so a href crossing a dot segment -- audio/sub/../one.wav
against an on-disk audio/one.wav -- matched nothing the folder walk found and
printed as orphaned though it resolves. The set now holds the files media
resolution returns, compared by identity, which also spares the command from
re-deriving rules the model owns.

A folder mismatch was keyed by the one component that differs, so A/Foo and
B/Foo collapsed into one finding although each is its own rename. The key is
the whole path the href reached, which the message now names too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A folder mismatch was keyed by the whole path an href spells, so one folder
reached through two spellings of its parent -- A/Foo and a/Foo over a single
a/foo -- reported twice although both name the one rename. The key is now the
on-disk path the href reaches, together with the component it spells that
folder with: enough to tell a/foo from b/foo, and no longer split by an
ancestor that has nothing to do with either.

The message names that component and the path it reaches rather than the whole
written path, so it identifies a real folder instead of one href's way of
writing its way down to it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A folder finding was keyed by a path aligned against the href, which describes
a/foo and pictures/a/foo identically: the conventional subfolder that separates
them is the lookup's, and the document never wrote it. Two such folders merged
into one finding, and the survivor named the wrong path. The key is now the
directory the resolved file sits in, together with the component the href
spells it with, so one folder written two ways still reports twice.

Folder paths are reported relative to the folder holding the .lift, which is
what lets the message tell pictures/a/foo from a/foo. Every path that was
already unambiguous reads exactly as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@jasonleenaylor jasonleenaylor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall. Two things to fix before merge, one nit, one question, all inline.

This review was assisted by Claude Fable 5.1.

Comment thread src/sil_lift/_model.py
Comment thread src/sil_lift/_model.py Outdated
Comment thread src/sil_lift/_model.py
Comment thread tests/corpus/PROVENANCE.md
imnasnainaec and others added 2 commits October 8, 2026 14:23
Brings in validate --allow. The semantic-check count in validate.md stays
at thirteen with media-href-mismatch, and the --allow description joins
the bulleted validate options list in cli.md, in synopsis order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An href of "" or "." has no components, so appending it to the
conventional subfolder named the subfolder itself; a regular file called
pictures or audio then matched, and comparing the href's spelling against
it raised ValueError. check_media() now reports such an href missing
before any probe, and check-media's orphan scan skips it.

The folder walk in _media_matches stats entries through helpers that
treat any OSError as "not there": before Python 3.14, pathlib lets a
PermissionError escape is_file()/is_dir().

Folder listings are sorted, so which of several folding matches is
reported, and the folder a mismatch is grouped under, is the same on
every filesystem.

CONTRIBUTING now asks for a PROVENANCE.md entry only for fetched
fixtures, matching the rule that file states for hand-authored negative/
fixtures. The CLI guide's exit codes count misspelled media as a finding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@imnasnainaec imnasnainaec left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imnasnainaec reviewed all commit messages and made 4 comments.
Reviewable status: 0 of 19 files reviewed, all discussions resolved (waiting on imnasnainaec).

Comment thread src/sil_lift/_model.py Outdated
Comment thread src/sil_lift/_model.py
Comment thread src/sil_lift/_model.py
Comment thread tests/corpus/PROVENANCE.md

@jasonleenaylor jasonleenaylor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, all four addressed. LGTM.

This review was assisted by Claude Opus 5.5.

@imnasnainaec
imnasnainaec merged commit 600de9e into main Oct 8, 2026
12 of 13 checks passed
@imnasnainaec
imnasnainaec deleted the media-href-mismatch branch October 8, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🟨Medium Medium-priority PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Media hrefs resolve case-sensitively: Windows-authored folders get false missing-media on Linux

2 participants