Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Obsidian plugin that scans a vault for maintenance problems. Read-only by design — no file mutation except exported reports.

- Plugin ID: `vault-inspector`
- Current version: `0.4.13`
- Current version: `0.8.1`
- Min Obsidian version: `1.7.2`

## Commands
Expand Down
34 changes: 25 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@ Detection uses Obsidian's metadata cache. Automatic link removal only edits pars

### Orphan Attachments

Scans for attachment files not referenced by any Markdown file.
Scans for attachment files without indexed references from Markdown links,
embeds, frontmatter links, Canvas file nodes, or Canvas group backgrounds.

- `warning` — unreferenced file older than 24 hours
- `info` — unreferenced file modified within 24 hours
- Supported: png, jpg, jpeg, gif, webp, svg, pdf, mp3, mp4, wav, mov, zip

Orphan detection cannot account for references from CSS, Canvas, Dataview queries, or external tools.
Orphan detection cannot account for references from CSS, dynamic Dataview
queries, or external tools. Missing Markdown metadata and malformed or
unreadable Canvas files reduce reference coverage; trash actions are blocked
while reference coverage is incomplete. Orphan findings remain candidates, not
proof that an attachment is unused.

### Empty Notes

Expand All @@ -46,22 +51,28 @@ Flags notes that have no content beyond frontmatter and a title heading.

Opt-in scanner for checking HTTP/HTTPS URLs found in notes for availability. It is disabled by default because it makes network requests and depends on external sites, DNS, and rate limits.

- `warning` — HTTP status 400 or higher
- `info` — timed out, failed, or skipped URL checks
- `warning` — HTTP 404/410 (and other 4xx) dead-link candidates
- `info` — 401/403 access-restricted, 429 rate-limited, 5xx server errors, and timed-out, failed, blocked, or skipped checks
- Checks Markdown links, frontmatter links, images/embeds, and bare HTTP/HTTPS URLs in note bodies.
- Timeouts or blocked requests do not necessarily mean a URL is dead.

### Duplicate Files

Groups files by basename + extension, then by size. Files below the hash cap are verified with SHA-256.
Collects candidates using two independent groups: matching basename plus
extension, and matching byte size. Candidate files at or below the hash cap are
verified with SHA-256, so identical content can be detected across different
filenames. Files above the cap remain unverified candidates.

- `warning` — hash-identical files
- `info` — same-name or same-size candidates without hash

Deletion is offered only for files confirmed identical by content hash. By
default, Vault Inspector asks which file to keep. Automatic mode keeps the first
complete vault-relative path in alphabetical order. Modification time, access
time, and file size do not choose the keep file.
default, Vault Inspector asks which file to keep. Automatic selection prefers
the copy with the highest indexed inbound reference count; ties use the
lexicographically smallest vault-relative path. Groups with multiple referenced
copies require an explicit keep choice and are excluded from bulk actions.
References are never rewritten automatically. Modification time, access time,
and file size do not choose the keep file.

Duplicate detection above the hash cap reports candidates only (no content verification).

Expand Down Expand Up @@ -174,7 +185,7 @@ Obsidian's trash; it never permanently deletes them.
|---|---|---|
| Enabled Scanners | All local scanners on; External Links off | Toggle individual scanners |
| Enable fix actions | On | Allow batch delete of fixable issues |
| Duplicate file keep mode | Always ask | Require a keep-file choice, or automatically keep the alphabetically first vault-relative path |
| Duplicate file keep mode | Always ask | Require a keep-file choice, or automatically keep the most-referenced copy (ties: alphabetically first) |
| Large Markdown threshold | 100 KB | Markdown files above this size are flagged |
| Large attachment threshold | 5 MB | Attachments above this size are flagged |
| Ignored large Markdown frontmatter keys | excalidraw-plugin | Markdown files with these frontmatter keys are excluded from large file checks |
Expand All @@ -188,6 +199,11 @@ Obsidian's trash; it never permanently deletes them.
| Ignored properties | (none) | Frontmatter properties excluded from type checks |
| Report folder | Vault Inspector Reports | Folder for exported Markdown reports |

Automatic scans and network access are disabled by default: scans run only when
you start them, and the External Links scanner is opt-in. If a fix reports that
metadata synchronization did not complete, changes may still have been saved —
run another scan and review the result before retrying.

Global ignored folders apply to every scanner. Scanner-specific ignored folders
are additional exclusions. For example, add `syncTrash` only to Broken Links if
you want Duplicate Files to inspect that folder while broken-link checks skip it.
Expand Down
5 changes: 3 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,9 @@ CLI baseline comparison is separate from the Obsidian plugin lifecycle. CLI
output does not include plugin scan snapshots or the plugin's
resolved-history view.

The corrected reference, link, and YAML handling uses comparison semantics
version `3`; the JSON schema remains version `1`. Regenerate older profile
The corrected reference, link, and YAML handling, unverified link findings for
unavailable target metadata, and Obsidian-compatible heading-anchor matching use
comparison semantics version `4`; the JSON schema remains version `1`. Regenerate older profile
baselines with the current command and the same detection settings, without
passing `--baseline` to that regeneration run. `--fail-on none` does not bypass
an incompatible baseline error.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

> **Delivery status:** This umbrella roadmap is historical. Current 1.0.0
> release readiness work — core reliability fixes, CLI configuration validation,
> release gates, and native runtime acceptance — is tracked in
> [2026-09-13-v1-release-readiness.md](2026-09-13-v1-release-readiness.md) and
> `docs/validation/1.0.0-readiness.md`. Do not mark items complete here without
> renewed acceptance evidence.

**Goal:** Deepen Vault Inspector's existing eight-scanner maintenance workflow by reducing false positives, making destructive actions safer, strengthening repeat-scan value, and aligning CLI lifecycle semantics without expanding the product into new scanner categories.

**Architecture:** Preserve `ScanRunner`, `ScanContext`, deterministic issue fingerprints, the report view, verified fix pipeline, and read-only CLI as the primary boundaries. Deliver the roadmap as five independently releasable milestones: establish measurable precision fixtures, build a shared reference model and refine current scanners, add action-impact policy, add bounded history and conservative automatic scans, then bring compatible lifecycle comparison to the CLI.
Expand Down
28 changes: 14 additions & 14 deletions docs/superpowers/plans/2026-09-13-v1-release-readiness.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,20 @@ Record actual commits, commands, and evidence links as each item completes. Ther

| ID | Work | Status | Completion criterion/evidence |
|---|---|---|---|
| S0 | Baseline, isolation, and acceptance record | Planned | Reproducible baseline commands and HEAD |
| A1 | Atomic link fixes | Planned | Concurrency regression and source-preservation cases |
| A2 | Conservative handling of missing target metadata | Planned | Null/empty/populated cache matrix and old baseline invalidation |
| A3 | Native cache synchronization after writes | Planned | Event-order tests and native C1 acceptance |
| B1 | CLI configuration structure/field validation | Planned | Invalid input exits 2; valid zero values/empty lists remain supported |
| B2 | CLI smoke after tarball installation | Planned | Both commands, JSON, exit codes, baseline, and read-only checks |
| B3 | Supported runtime matrix | Planned | The same artifact passes on Node 18 and 24 |
| B4 | Release tag/version/commit gates | Planned | Wrong tags rejected; unverified commits not published |
| B5 | Documentation and protocol commitments | Planned | User documentation matches current behavior |
| C1 | Native desktop safety workflow | Planned | File-level assertions, UI outcomes, and environment restoration |
| C2 | Upgrade/minimum version | Planned | Upgrade from 0.8.1 and Obsidian 1.7.2 acceptance |
| C3 | Mobile | Planned | iOS/Android core workflow evidence |
| C4 | Large-vault interaction and batch operations | Planned | Recorded scale, timing, interaction, and resource evidence |
| C5 | Release candidate review | Planned | Evidence for all hard gates; no safety/correctness blockers |
| S0 | Baseline, isolation, and acceptance record | Passed | Baseline gates green at `69db84b`; recorded in `docs/validation/1.0.0-readiness.md` |
| A1 | Atomic link fixes | Passed | Commit `3759a05` (PR #179); RED/GREEN concurrency regression |
| A2 | Conservative handling of missing target metadata | Passed | Commit `1d0ad86` (PR #179); matrix + recovery; COMPARISON_VERSION=4 |
| A3 | Native cache synchronization after writes | Passed (code) / Blocked (native C1) | Commit `3557d43` (PR #179); event-order tests pass; native event evidence pending C1 |
| B1 | CLI configuration structure/field validation | Passed | Commit `d2d69a8` (PR #180); 18 invalid cases exit 2 pre-scan |
| B2 | CLI smoke after tarball installation | Passed | PR #181; RED on pre-B1 tarball, GREEN on candidate; integrity recorded |
| B3 | Supported runtime matrix | Passed | PR #181 CI: `installed-cli (18)` and `(24)` green on one tarball; ruleset updated |
| B4 | Release tag/version/commit gates | Passed | PR #181; version script + release workflow reruns full gates + smoke |
| B5 | Documentation and protocol commitments | Passed | docs PR; semantics=4 documented; CLAUDE.md synced |
| C1 | Native desktop safety workflow | Blocked | No desktop Obsidian available in this session; see validation record |
| C2 | Upgrade/minimum version | Blocked | Requires prior-version install, Obsidian 1.7.2, and a Windows device |
| C3 | Mobile | Blocked | No mobile devices available; narrowing scope needs owner authorization |
| C4 | Large-vault interaction and batch operations | Partially passed / Blocked (UI) | CLI benchmarks: −1.7% (10k) and −6.6% (400) vs 0.8.1, within budget; native UI rows blocked |
| C5 | Release candidate review | In progress | Automated gates pass; native acceptance blocks readiness |
| C6 | Formal release and channel verification | Not authorized by this plan | Run the release procedure after explicit release authorization |

Allowed states: Planned, In progress, Passed, Failed, Blocked, Already satisfied. Blocked entries must name the cause, exact missing device/permission, and resumption command; do not label them Passed with caveats.
Expand Down
56 changes: 56 additions & 0 deletions docs/validation/1.0.0-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# 1.0.0 Readiness Evidence

Status: Not ready

## Candidate
- Commit: `docs/v1-release-readiness` head at authoring; the release candidate is finalized at the C6 version-bump commit — re-verify before release
- Asset SHA-256: Not run (recorded at C6 from the release commit)
- Date and timezone: 2026-09-18, UTC+8 (Asia/Shanghai)
- Build Node/npm: Node v24.16.0, npm 11.13.0 (macOS arm64, darwin 27.0.0)
- Obsidian/device/OS: Desktop/mobile devices unavailable in this session — see Native acceptance

## Automated gates
| Check | Command | Exit code | Result | Evidence |
|---|---|---|---|---|
| S0 baseline | lint + obsidian lint + build + test:coverage + pack dry-run + `node cli.js --help` | 0 | Passed at `69db84b` (2026-09-17) | 929 tests, 8 package files, all gates green |
| A1 atomic link writes | focused RED/GREEN + full gates | 0 | Passed — commit `3759a05` (PR #179) | Concurrency regression failed pre-fix, passes post-fix; 932 tests |
| A2 conservative missing metadata | focused RED/GREEN + full gates + version bump | 0 | Passed — commit `1d0ad86` (PR #179) | null-cache matrix + recovery; COMPARISON_VERSION 3→4; 937 tests |
| A3 metadata write fence | focused RED/GREEN + full pipeline incl. pack | 0 | Passed — commit `3557d43` (PR #179) | 9 fence event-order tests; runner readiness regressions; 949 tests |
| B1 CLI config validation | focused RED/GREEN + full gates | 0 | Passed — commit `d2d69a8` (PR #180) | 18 invalid-config cases exit 2 before scan; zero thresholds keep findings; 949 tests |
| B2 installed-package smoke | `node scripts/smoke-installed-cli.mjs <tarball>` | 0/1 | Passed — commit `ci: gate release assets…` (PR #181) | RED against pre-B1 tarball `69db84b` failed at invalid-config assertion; GREEN `Installed CLI smoke passed on v24.16.0`; tarball integrity sha512-ZUDJfrOoJfh8… |
| B3 Node 18/24 matrix | CI `installed-cli (18)` / `installed-cli (24)` | 0 | Passed — PR #181 checks | verify + installed-cli (18) 14s + installed-cli (24) 1m18s all green; ruleset requires all three |
| B4 version/release gates | `node scripts/check-release-version.mjs [tag]` + release workflow | 0/1 | Passed — PR #181 | RED `999.0.0` exits nonzero; release workflow now verifies tag/ancestry + reruns full gates + smoke on Node 24 & 18 |
| B5 documentation alignment | docs review + logic suites | 0 | Passed — this PR | reference-index/duplicate-files/action-policy/scanner-precision suites pass (69 tests, logic only) |
| Full verification (post-A/B) | lint + obsidian lint + build + test | 0 | Passed | 969 tests |

## Native acceptance
| ID | Environment | Steps | Expected | Actual | Result | Evidence |
|---|---|---|---|---|---|---|
| C1.1–C1.10 | Obsidian desktop (stable) | See plan | See plan | Not run | Blocked | No desktop Obsidian application or interactive display available in this session; requires the repository owner on a desktop machine |
| C2 upgrade/minimum | 0.8.1 artifacts + Obsidian 1.7.2 | See plan | See plan | Not run | Blocked | Requires prior-version install + Obsidian 1.7.2 desktop environment |
| C2 Windows CLI | Windows + PowerShell | `.cmd` bins, exit codes, CJK/space paths | See plan | Not run | Blocked | No Windows device available in this session |
| C3 mobile | iOS + Android | Scan/filter/fix/export workflows | See plan | Not run | Blocked | No mobile devices available; publishing with C3 blocked would narrow the version commitment and needs explicit owner authorization |

## Performance
| Candidate | Device | Files/findings | Scenario | Three samples | Median | Result |
|---|---|---|---|---|---|---|
| 0.8.1 (`fdcc77d`) | macOS arm64, Node 24.16.0 | 400 notes / 150 attachments | CLI load+scan | (62+121)ms total | 183ms | Baseline |
| candidate (post-A/B) | same machine, serial | 400 notes / 150 attachments | CLI load+scan | (61+110)ms total | 171ms | −6.6% vs baseline — pass |
| 0.8.1 (`fdcc77d`) | macOS arm64, Node 24.16.0 | 10 000 notes / 2 000 attachments | CLI load+scan | (1561+5545)ms total | 7106ms | Baseline |
| candidate (post-A/B) | same machine, serial | 10 000 notes / 2 000 attachments | CLI load+scan | (1522+5460)ms total | 6982ms | −1.7% vs baseline — pass (budget ≤ +20%) |
| candidate | native UI | 10k notes ≈ 3k findings | first render / filter / batch-20 / memory | Not run | Not run | Blocked — requires desktop Obsidian (C4 native rows) |

Finding-count changes vs 0.8.1 stem from the corrected semantics (implicit block references and headings with links no longer confirmed-broken; tag hierarchy exemption), not from scan workload.

## Known boundaries
- Supported reference channels: Markdown links/embeds/frontmatter, Canvas file nodes and group backgrounds. CSS, dynamic Dataview, and external tools remain unaccounted; incomplete coverage blocks trash actions.
- Native acceptance (C1–C3, C4 UI rows, C2 Windows/upgrade rows) is Blocked in this session — no desktop/mobile devices. Automated gates, installed-package smoke on Node 18/24, and CLI benchmarks all pass.
- This document records logic-test evidence only for B5; it is not native Obsidian acceptance.

## Environment restoration
- All benchmarks and smoke runs used synthetic vaults under the system temporary directory; no user vault was scanned or written.
- Temporary worktrees (`/private/tmp/vi-smoke-before`, `/private/tmp/vi-bench-081`) and their tarballs were removed after use.
- No plugin `data.json`, vault files, or Obsidian settings were touched (no live environment available in this session).

## Release decision
Not ready until all required gates have evidence. Automated gates (S0, A, B) pass; native device acceptance (C1–C3, C4 UI) is Blocked and requires the repository owner. Releasing without native acceptance would narrow the plan's acceptance commitment and needs an explicit owner decision.
Loading