Skip to content

Fix: lint doesn't validate raw/ source: paths or body links - #87

Closed
emercons wants to merge 189 commits into
nvk:masterfrom
emercons:fix/raw-source-provenance-check
Closed

Fix: lint doesn't validate raw/ source: paths or body links#87
emercons wants to merge 189 commits into
nvk:masterfrom
emercons:fix/raw-source-provenance-check

Conversation

@emercons

@emercons emercons commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The bug

check_source_provenance validates the sources: frontmatter list for wiki/ and inventory/ documents, but has no branch for raw/ — even though every raw/*.md file has a required source: field per the documented schema (references/wiki-structure.md, "Source File Format (raw/)": source: "URL or filepath or MANUAL"), and that field is frequently a local filepath, not just a URL.

check_links (the generic body markdown-link checker) has the identical gap: it's scoped to if rel.parts[0] not in {"wiki", "inventory"}: continue, so body links inside raw/*.md are never checked either.

Net effect: nothing under raw/ is ever checked for a broken source reference, neither in frontmatter nor in body prose, even though check_frontmatter_schema already requires the source field to be present.

How I found it

A downstream wiki instance (local .wiki/ init over an existing research corpus) had a generator script produce 144 raw/notes/ and raw/data/ pointer records whose source: field was one directory level too shallow (../../research/... instead of ../../../research/..., since raw/notes/ is three levels deep from the wiki root). None of those 144 broken references ever resolved to a real file. lint stayed green the entire time — 0 critical, 0 warnings — because raw/ simply isn't in scope for either check that would have caught it.

The fix

  • check_source_provenance: add a raw/ branch that resolves the source: scalar the same way inventory/ resolves its sources: list entries — skip http(s):// URLs and the literal MANUAL (per the documented "URL or filepath or MANUAL" contract), otherwise resolve via the existing resolve_source_ref helper and warn if it doesn't resolve.
  • check_links: add "raw" to the directory scope so body markdown links inside raw/*.md get the same broken-link check that wiki/ and inventory/ already have.

Tests

Added tests/fixtures/defects/raw-source-unresolved/ — a copy of golden-wiki with one raw/papers/*.md's source: pointed at a nonexistent local path — and wired it into test-local-cli-lint.sh right after the existing missing-index/bad-frontmatter cases, asserting the new "Raw source reference does not resolve" warning.

Verified locally (Windows/Git Bash):

  • golden-wiki lint output is byte-identical before/after this patch (same 3 pre-existing warnings — inbox/ missing, two staleness warnings from fixture date drift — none new).
  • The full existing suite's pass/fail set is unchanged by this patch: the same ~12 tests fail both with and without it. Those failures look environment-specific to this Windows/Git-Bash setup (temp-dir path handling, chmod-based permission simulation) rather than caused by this change — happy to dig into any of them further if useful, but wanted to flag it rather than claim a clean full-suite run I can't actually verify against your CI target platform.

nvk and others added 30 commits April 4, 2026 19:52
LLM-compiled knowledge base plugin inspired by Karpathy's wiki concept.
Claude Code replaces Obsidian as the IDE — no external dependencies.

Commands: /wiki (init/status), /wiki:ingest (URLs, files, text, inbox,
tweets via Grok), /wiki:compile (raw to articles), /wiki:query (Q&A
with citations), /wiki:search, /wiki:lint (health checks + auto-fix),
/wiki:output (summaries, reports, slides, glossaries).

Global wiki at ~/wiki/ by default, --local for project-specific,
sub-wikis via --topic, multi-wiki peek for cross-wiki overlap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code expects marketplaces to have:
- .claude-plugin/marketplace.json at root (lists available plugins)
- Plugin contents in a subdirectory (./claude-plugin/)

Moved commands/ and skills/ into claude-plugin/ to match
the autoresearch marketplace pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The !`command` syntax in ## Context sections is sandboxed to the
current working directory, which blocks access to ~/wiki/. Commands
now check wiki existence at runtime using Read tool instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Wiki articles now use both [[wikilinks]] (Obsidian graph view) and
  standard markdown links (Claude navigation) on the same line
- /wiki init creates .obsidian/ vault config with sane defaults
- Added aliases field to article frontmatter for Obsidian discovery
- Updated SKILL.md, compilation protocol, and wiki-structure reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- log.md: append-only activity log for all operations (init, ingest,
  compile, query, lint, research, output). Grep-friendly format.
- Multi-depth query: --quick (indexes only), standard (default,
  reads articles), --deep (everything + raw + sibling wikis)
- Confidence field: high/medium/low in article frontmatter, based
  on source quality and corroboration
- /wiki:research: multi-agent deep research command. Parallel web
  search → ingest → compile pipeline for automated topic research.

Inspired by community feedback on Karpathy's LLM wiki concept and
the rvk7895/llm-knowledge-bases implementation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added: /wiki:research, query depth table, Obsidian integration
section, activity log, confidence scoring, dual-linking, credits.
Updated links to Karpathy's gist and correct tweet URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prominent callout block showing the fastest path for new topics:
wiki init + research command. Reordered quick start to lead with
research workflow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New section explaining how dual-links work everywhere: Obsidian,
Claude, GitHub, any markdown viewer, or plain text editor. The
wiki is not locked into any single tool.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When running /wiki init --local, the init command now appends
.wiki/ to the project's .gitignore to keep wiki files untracked
by default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The global ~/wiki/ is now a lightweight hub. Content lives in
topic sub-wikis at ~/wiki/topics/<name>/ with isolated indexes.

- /wiki init <name> is now the default (not bare /wiki init)
- Init nudges toward topic sub-wikis, warns against dumping
  unrelated content in the global wiki
- SKILL.md updated to reflect topic-first philosophy
- README restructured: architecture diagram shows hub + topics,
  quick start uses topic wiki, commands table simplified

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clarify that opening ~/wiki/ shows the hub (no articles at root),
content lives inside topics/<name>/. Users can open the hub for
full graph or a single topic wiki for focused view.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Having .obsidian/ at both hub and sub-wiki levels causes nested
vault confusion in Obsidian. Now only topic sub-wikis and local
wikis get .obsidian/ config. Users can manually open the hub in
Obsidian if they want a cross-topic view.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Automatic lightweight structure checks that trigger after write
operations, when lint is stale (7+ days), when content lands in
the wrong place, or when user reports problems.

Auto-fixes: missing indexes, orphan files, unregistered wikis,
missing directories. Warns on: content in hub, stale indexes.
Runs inline without blocking the user's request.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The hub no longer has raw/, wiki/, output/, inbox/, config.md, or
.obsidian/. These were traps that invited content into the wrong
place. Hub is now just a registry. All content lives in topic
sub-wikis.

Updated: wiki-structure.md, wiki.md init command, SKILL.md
guardian, README architecture diagram. Init always requires a
topic name — no bare /wiki init.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Standard: 5 agents (academic, technical, applied, news, contrarian)
Deep (--deep): 8 agents (adds historical, adjacent, data/stats)

Each agent runs multiple search queries, fetches full content,
and returns ranked sources with quality scores. Deduplication
across agents. Confidence scoring based on cross-agent
corroboration. Detailed report with gap analysis and follow-up
suggestions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Retardmax = act first, think later. Inspired by Elisha Long's
retardmaxxing philosophy (anti-analysis-paralysis).

Research --retardmax: 10 parallel agents (adds 2 rabbit-hole
agents that chase links from search results). Skips Phase 1
planning, lower quality threshold, ingests aggressively,
compiles fast. Default 15 sources. Lint cleans up after.

Output --retardmax: reads ALL articles, generates immediately
without planning structure, includes everything, ships rough.
Polish comes in a second pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced quantum-computing/dementia examples with nutrition/
woodworking. Added Research Modes table (standard/deep/retardmax
with agent counts). Added retardmax credit. Reordered flow to
lead with research. Updated commands table with all flags.
Tightened Obsidian section. Added structural guardian mention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Compares a local repo against the wiki's research body and the
broader market. Parallel agents scan the repo (structure, features,
docs), scan the wiki, then search the web for competitors, best
practices, and emerging trends.

Produces a gap analysis report: alignment, research gaps,
opportunities, market gaps, competitive landscape, and
recommended actions. Supports --retardmax for wider net.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Single portable file containing the complete wiki protocol —
works with OpenAI Codex, Claude Code, Gemini Code Assist, or
any LLM agent that can read/write files and search the web.

Covers: architecture, file formats, all operations (init, ingest,
compile, query, research, lint, output, assess), structural
guardian, Obsidian compatibility, and platform tool mapping table.

Follows Karpathy's "idea file" pattern — paste into your agent
and it builds the wiki.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
--new-topic: Creates a topic wiki from the research topic and
starts researching immediately. Works from any directory. One
command to go from zero to a populated wiki.

--min-time <duration>: Keep running research rounds until the
time budget is spent (30m, 1h, 2h, 4h). Each round drills into
the top gaps from the previous round. Progressively narrows from
broad to niche. Auto-lints at the end.

Example: /wiki:research "CRISPR" --new-topic --deep --min-time 2h

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Thesis = scope constraint. Provide a specific claim, agents
research evidence for AND against, compile into a focused wiki,
deliver a verdict (supported/contradicted/mixed/insufficient).

Key design:
- Thesis is the bloat filter — irrelevant sources get skipped
- Agents split into supporting, opposing, mechanistic, meta, adjacent
- Anti-confirmation-bias: Round 2 of --min-time focuses on the
  weaker side of evidence from Round 1
- Produces a thesis file with evidence tables and falsification
  criteria
- Cross-references existing wiki knowledge instead of duplicating
- wiki/ gains a theses/ subdirectory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated plugin.json and marketplace.json with current feature
set: topic-isolated wikis, multi-agent research, thesis-driven
investigation, repo assessment, dual-linking, retardmax mode,
AGENTS.md cross-platform support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Research now detects whether input is a topic ("nutrition") or a
question ("What makes articles go viral?") and adapts:

Question mode:
- Decomposes into 3-5 sub-questions
- One agent per sub-question (focused, not generic angles)
- Compiles a synthesis topic article as the "playbook"
- Auto-generates an actionable playbook output artifact
- Suggests 2-3 testable theses derived from findings

The question itself is the scope constraint — keeps research
focused and produces a practical, actionable deliverable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated plugin.json, marketplace.json, and AGENTS.md with:
- Question auto-detection in /wiki:research (topic vs question
  with playbook generation)
- /wiki:thesis with verdicts and anti-confirmation-bias
- theses/ directory in wiki structure
- --new-topic and --min-time modifiers
- Full command descriptions in marketplace listing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Plugin name must match command name for Claude Code to show
/wiki:thesis instead of /llm-wiki:wiki:thesis. The marketplace
name stays 'llm-wiki' but the plugin name inside is now 'wiki'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
nvk and others added 26 commits May 4, 2026 10:21
Adds C18 lint rule (Warning) for compiled wiki articles missing `sources:`,
with an explicit `compiled-from: conversation` exemption for articles
authored from chat rather than fetchable raw files. Adds the schema field
to the article frontmatter spec and a librarian scoring exemption that
re-bases composite freshness to verification + compilation when sources
are conversational by design.

Adds a self-validation pass to compile (step 5.5) so the agent halts on
articles it wrote without `sources:`/`volatility:`/`verified:`/`confidence:`,
naming the exact reference section to consult — catches the silent skip
pattern observed when 11 home-networking articles compiled with empty
frontmatter.

Adds hub-level detection to /wiki:librarian and /wiki:refresh: instead of
silently no-op'ing when invoked at the hub root (which has no `wiki/`
subdir), they now present a numbered topic-wiki picker and accept
`--wiki all` for sequential iteration.

Tests: new `missing-sources` defect fixture + structure-test assertion
(168 passed, was 167). Codex/OpenCode mirrors regenerated via sync scripts.

Deferred to follow-up PRs (per the deploy order in
~/Library/Mobile Documents/com~apple~CloudDocs/wiki/topics/meta-llm-wiki/output/plan-bridge-onboarding-gap-2026-05-07.md):
counterintuitive-volatility warning at fix time, /wiki status Health block,
walkthrough.md doc, behavioral evals.

🪄
check_source_provenance validates the sources: frontmatter list for wiki/
and inventory/ documents, but silently skips raw/ — even though raw/*.md
has a required source: field per the documented schema (wiki-structure.md
"Source File Format (raw/)") that can be a local filepath, not just a URL.
check_links (the generic body markdown-link checker) has the same gap,
scoped to {"wiki", "inventory"} only.

Net effect: nothing in raw/ was ever checked for broken source references,
in frontmatter or in body prose. This surfaced downstream in a Knowmade-
based wiki where a script generated 144 raw/notes and raw/data pointer
records with a source: path one directory level too shallow — lint stayed
green (0 critical, 0 warnings) the whole time because raw/ simply wasn't in
scope for either check.

Fix:
- check_source_provenance: add a raw/ branch that resolves the source:
  scalar the same way inventory/ resolves its sources: list entries
  (skip http(s):// URLs and the literal MANUAL, since raw/ sources are
  documented as "URL or filepath or MANUAL").
- check_links: add "raw" to the directory scope so body markdown links
  inside raw/*.md are checked like they already are in wiki/ and
  inventory/.

Adds tests/fixtures/defects/raw-source-unresolved/ (golden-wiki with one
raw/papers source: pointed at a nonexistent local path) and wires it into
test-local-cli-lint.sh next to the existing missing-index/bad-frontmatter
cases, asserting the new "Raw source reference does not resolve" warning.

Verified: golden-wiki lint output is unchanged by this patch (same 3
pre-existing warnings, none new); the full existing test suite's pass/fail
set is identical before and after this change on this (Windows/Git Bash)
environment — the ~12 pre-existing failures unrelated to this patch appear
to be environment-specific (temp-dir path handling, chmod-based permission
simulation) rather than caused by it.
@emercons

Copy link
Copy Markdown
Contributor Author

Reopened cleanly as #88 — this branch had drifted 273 commits behind master (and carried 189 unrelated commits), which is why the diff here ballooned to 787 files instead of the intended single-file fix. #88 is cut fresh from current master and contains only that fix + its test fixture.

emercons added a commit to emercons/llm-wiki that referenced this pull request Aug 24, 2026
check_source_provenance validates the sources: frontmatter list for wiki/
and inventory/ documents, but silently skips raw/ -- even though raw/*.md
has a required source: field per the documented schema (wiki-structure.md
"Source File Format (raw/)") that can be a local filepath, not just a URL.
check_links (the generic body markdown-link checker) has the same gap,
scoped to {"wiki", "inventory"} only.

Net effect: nothing in raw/ was ever checked for broken source references,
in frontmatter or in body prose. This surfaced downstream in a downstream wiki instance where a script generated 144 raw/notes and raw/data pointer
records with a source: path one directory level too shallow -- lint stayed
green (0 critical, 0 warnings) the whole time because raw/ simply wasn't in
scope for either check.

Fix:
- check_source_provenance: add a raw/ branch that resolves the source:
  scalar the same way inventory/ resolves its sources: list entries (skip
  http(s):// URLs and the literal MANUAL, since raw/ sources are documented
  as "URL or filepath or MANUAL").
- check_links: add "raw" to the directory scope so body markdown links
  inside raw/*.md are checked like they already are in wiki/ and
  inventory/.
- Applied identically to scripts/llm-wiki and its three bundled bin/
  mirrors (claude-plugin/bin/llm-wiki, plugins/llm-wiki/bin/llm-wiki,
  plugins/llm-wiki-opencode/bin/llm-wiki) via the project's own
  sync-codex-plugin.sh / sync-opencode-plugin.sh scripts (their `cp
  "$LOCAL_HELPER" ...` steps only; the rsync-dependent skill-asset sync was
  skipped since this change touches no skill content and rsync isn't
  available on this machine).

Adds tests/fixtures/defects/raw-source-unresolved/ (golden-wiki with one
raw/papers source: pointed at a nonexistent local path) and wires it into
test-local-cli-lint.sh next to the existing missing-index/bad-frontmatter
cases, asserting the new "Raw source reference does not resolve" warning.

Verified against current upstream/master (d78e119):
- golden-wiki lint output is unchanged by this patch (same 2 pre-existing
  staleness warnings, none new -- confirms no false positives on existing
  raw/ pointer records).
- Full test suite: 37/42 pass before this patch, 38/43 pass after (the one
  new test, passing; the same 5 pre-existing failures before and after,
  which look environment-specific -- Windows/Git-Bash temp-dir and
  chmod-permission-simulation cases -- rather than caused by this change).

This branch is rebased directly onto the current upstream/master rather
than an out-of-date fork branch, so the diff is scoped to just this fix
(this supersedes PR nvk#87, which was opened from a branch 273 commits behind
master and unrelated to it by 189 commits, producing an unreviewable
787-file diff that was closed unmerged).
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.

4 participants