Skip to content

luhmann lint reports false-positive dangling links for piped wiki-link syntax #1

Description

@ozten

Component: tools/luhmann/ — luhmann lint subcommand
Severity: Low (cosmetic — no incorrect data, just noise)
Impact: Across a 26-note batch, ~8 false-positive FAILs per note (≈200 total) drowned out any real lint findings. Subagents wasted tool calls verifying
each "dangling" target on disk to confirm it actually existed.

Behavior

The linter treats Obsidian-style aliased wiki-links as dangling when the target file exists.

Example: A note containing:

This relies on [[sanity-perspectives-let-one-dataset-serve-many-query-time-views|perspectives]].

…where notes/sanity-perspectives-let-one-dataset-serve-many-query-time-views.md exists on disk.

Expected: PASS — target file exists.
Actual: FAIL — "dangling wiki-link" reported for the full string sanity-perspectives-let-one-dataset-serve-many-query-time-views|perspectives.

Root cause (hypothesis)

The link-extraction regex appears to capture everything between [[ and ]] and pass that as the lookup key, rather than splitting on | first and using
only the pre-pipe portion as the filename. So [[target|display]] is looked up as target|display.md, which never exists.

Reproduction

  1. In any note in the vault, write [[draft-and-published-are-document-properties-not-environment-properties-in-modern-cmses|the per-doc draft model]]
    (target exists).
  2. Run luhmann lint .
  3. Observe a "dangling wiki-link" FAIL listing the entire target|alias string.

Suggested fix

Where wiki-links are extracted (likely a regex like [[([^\]]+)]]), post-process the capture:

let target = capture.split('|').next().unwrap().trim();

Then resolve notes/{target}.md against the filesystem. The display alias is informational and should be ignored by the linter.

Adjacent observations

  • The source: frontmatter field intentionally points to documents in inbox/ (e.g., PDFs), not to .md notes. Lint currently flags these as dangling too.
    Worth either excluding the source: field from link validation or resolving it against inbox/**/* in addition to notes/.
  • The aliased-link syntax is used heavily across the existing vault — fixing this single bug likely silences the vast majority of current lint noise.

Pipeline-level workaround (already in place)

Subagents have been instructed to tolerate "dangling" FAILs that match the piped pattern after verifying the target exists. This works but is wasteful —
each subagent re-derives this every run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions