Skip to content

fix(model): resolve a dangling link's parent before judging where it points - #27

Merged
indykish merged 2 commits into
mainfrom
fix/loader-coverage
Aug 27, 2026
Merged

fix(model): resolve a dangling link's parent before judging where it points#27
indykish merged 2 commits into
mainfrom
fix/loader-coverage

Conversation

@indykish

Copy link
Copy Markdown
Contributor

Chasing src/loaders.ts to 100% coverage turned up a bug rather than a missing test.

One branch was unreachable — the verdict for a CLAUDE.md symlink orly cannot resolve — and it was unreachable because the write guard refused the whole install before ever reaching it, reporting a link that pointed squarely inside the repository as "outside the target repository".

safeRealpath resolved a dangling link lexically:

resolve(dirname(path), readlink(path))     // "/var/folders/…/repo/nowhere.md"

while its caller compares that answer against a realpath'd root:

isBelow(resolvedDestination, realpathSync(root))   // "/private/var/folders/…/repo"

Wherever the repository itself sits behind a symlink — every macOS temporary directory, and plenty of real checkouts — the two sides were never comparable and the in-repo link lost. Resolving the parent makes both canonical. A link that genuinely points out of the repository is refused exactly as before, and the existing escape test still proves it.

Coverage

src/loaders.ts goes from 95.38% to 100% line and function coverage. Three tests, one per path that had none:

  • a stale pointer block is replaced in place, and nothing either side of it
  • a CLAUDE.md orly wrote itself is refreshed rather than left stale
  • a dangling CLAUDE.md symlink is left alone, not written through

The third is the one that found the bug.

Session notes 1

The README's loader section promised orly leaves your own CLAUDE.md alone, "symlink included" — which a dangling one disproved. It now says which links are left alone and which are refused, and why.

src/model.ts keeps its two uncovered lines: they are the RulesModel class declaration, and they were uncovered before this branch.

Review

No findings. orly gate pr green on every criterion, make conform green, 173 tests pass.

Make

$ bun test src --coverage
 src/loaders.ts            |  100.00 |  100.00 |
 173 pass, 0 fail

$ bash bin/orly gate pr
🟢 docs.updated: 1 user-surface file(s), 1 docs file(s) updated
🟢 PR boundary open — CHORE(close) is the next motion

Ships as 0.9.1.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DTMFyrbXJo3UrzQygaNtcn

indykish and others added 2 commits August 27, 2026 22:54
…points

Coverage found this. src/loaders.ts had one unreachable branch — the
verdict for a CLAUDE.md symlink orly cannot resolve — and it was
unreachable because the write guard refused the install first, naming the
file as "outside the target repository" while it pointed squarely inside.

safeRealpath resolved a dangling link lexically: `resolve(dirname(path),
readlink(path))` against a caller that compares the answer to a realpath'd
root. Wherever the repository itself sits behind a symlink — every macOS
temporary directory, and plenty of real checkouts — the two sides were
never comparable, and an in-repo link lost the comparison. Resolving the
parent makes both sides canonical. A link that genuinely points out of the
repository is refused exactly as before.

src/loaders.ts is now at 100% line and function coverage: the stale-block
replacement, the refresh of a CLAUDE.md orly wrote itself, and the dangling
link the guard used to swallow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DTMFyrbXJo3UrzQygaNtcn
…olve

The loader section promised orly leaves your own CLAUDE.md alone, symlink
included. Until the previous commit a dangling one refused the install
instead, so the sentence was aspirational — and it did not say which links
are refused and why. Both halves are now stated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DTMFyrbXJo3UrzQygaNtcn
@indykish
indykish merged commit 069bc7d into main Aug 27, 2026
4 checks passed
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@indykish
indykish deleted the fix/loader-coverage branch August 27, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants