diff --git a/CLAUDE.md b/CLAUDE.md index ae066c9..bbbf040 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 diff --git a/README.md b/README.md index 69597f8..fc830bd 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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). @@ -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 | @@ -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. diff --git a/docs/cli.md b/docs/cli.md index b7112cd..25bf6cc 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -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. diff --git a/docs/superpowers/plans/2026-08-29-core-maintenance-deepening-roadmap.md b/docs/superpowers/plans/2026-08-29-core-maintenance-deepening-roadmap.md index b530aea..fed12ac 100644 --- a/docs/superpowers/plans/2026-08-29-core-maintenance-deepening-roadmap.md +++ b/docs/superpowers/plans/2026-08-29-core-maintenance-deepening-roadmap.md @@ -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. diff --git a/docs/superpowers/plans/2026-09-13-v1-release-readiness.md b/docs/superpowers/plans/2026-09-13-v1-release-readiness.md index d21fd80..6073475 100644 --- a/docs/superpowers/plans/2026-09-13-v1-release-readiness.md +++ b/docs/superpowers/plans/2026-09-13-v1-release-readiness.md @@ -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. diff --git a/docs/validation/1.0.0-readiness.md b/docs/validation/1.0.0-readiness.md new file mode 100644 index 0000000..ff781d5 --- /dev/null +++ b/docs/validation/1.0.0-readiness.md @@ -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 ` | 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.