Skip to content

Emit Obsidian URIs using internal vault id (0.4) - #13

Merged
sksizer merged 6 commits into
mainfrom
feat/2026-05-19-obsidian-vault-id-uri
May 20, 2026
Merged

sksizer merged 6 commits into
mainfrom
feat/2026-05-19-obsidian-vault-id-uri

Conversation

@sksizer

@sksizer sksizer commented May 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Switch build_uri to emit obsidian://open?vault=<id> instead of vault=<name>. Eliminates non-deterministic launches when two registered Obsidian vaults share a folder basename (e.g. ~/work/notes and ~/personal/notes).
  • Vault.id becomes load-bearing; #[allow(dead_code)] moves to Vault.name (still retained for diagnostic context and test fixtures).
  • Bumps to 0.4.0 with a BREAKING-IF-OBSERVED note for downstream consumers that scrape the URI.

Task

docs/planning/tasks/2026-05-19-obsidian-vault-id-uri.md

Acceptance criteria

  • AC-1: build_uri emits vault=<id> for both vault-root and file-in-vault arms; path fallback is unchanged. (auto — cargo test obsidian::tests::)
  • AC-2: New test uri_disambiguates_vaults_with_identical_basename proves two same-name vaults produce distinct URIs. (auto)
  • AC-3: Existing emission tests pass with updated expected URIs. (auto — 20 unit tests + 6 doctests pass)
  • AC-4: Vault.id is no longer #[allow(dead_code)]. (auto — cargo clippy -- --deny warnings via just full-check)
  • AC-5: CHANGELOG.md documents the 0.4.0 behavior change with the BREAKING-IF-OBSERVED callout. (auto — visible in diff)
  • AC-6: path-opener 0.4.0 published to crates.io. (deferred-user — cargo publish is irreversible and must be authorized by the maintainer; will run after merge)
  • AC-7: just full-check passes. (auto)

Test plan

  • Maintainer authorizes cargo publish post-merge for AC-6.
  • Spot-check post-publish: downstream consumer (sksizer/polish) bumps to path-opener = "0.4" and confirms duplicate-name vaults route to the right one. Tracked in polish task 2026-05-19-obsidian-uri-vault-id.

Follow-up tasks spawned

Plugin-side gaps surfaced during the run were filed against sksizer/dev (the plugin repo), not this project — see https://github.com/sksizer/dev/pull/42:

  • 2026-05-20-setup-obsidian-backlog-dir-mismatch — /sdlc:setup --obsidian writes into singular backlog/ dir; needed manual fix mid-run.
  • 2026-05-20-task-work-rebase-frontmatter-conflict — Step 5b's gate-then-flip produces a deterministic rebase conflict every run.
  • 2026-05-20-task-work-worktree-init-language-agnostic — Step 4's init block assumes JS/pnpm/lefthook; no-op on pure-Rust repos.

sksizer added 6 commits May 19, 2026 23:36
Adds docs/planning/{backlogs,epics,milestones,tasks}/ from the
sdlc plugin's /sdlc:setup, with Obsidian Bases files per entity.
Includes the obsidian-vault-id-uri task spec.
Emit Obsidian URIs using internal vault id (0.4)
Switch `build_uri` to format URIs as `vault=<id>` instead of
`vault=<name>`. When two registered Obsidian vaults share a folder
basename (e.g. `~/work/notes` and `~/personal/notes`), the basename
form was ambiguous and Obsidian's URI resolver picked one
non-deterministically. The internal vault id is stable and unique,
so launches are now deterministic.

- `Vault.id` is now load-bearing; `#[allow(dead_code)]` moves to `name`
  (retained for diagnostic context and test fixtures).
- New test `uri_disambiguates_vaults_with_identical_basename` proves
  the fix.
- `vault=<name>` and `vault=<id>` are equivalent in Obsidian's URI
  scheme, so unique-name vaults behave identically.
- Bumps version to 0.4.0 with a BREAKING-IF-OBSERVED note for
  downstream consumers that scrape the URI.
@sksizer
sksizer merged commit a0e65b5 into main May 20, 2026
1 check passed
sksizer added a commit that referenced this pull request May 20, 2026
@sksizer
sksizer deleted the feat/2026-05-19-obsidian-vault-id-uri branch May 20, 2026 06:05
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.

1 participant