Skip to content

qmd-bootstrap: collection name derived from template (shared) instead of qmd_index (per-vault) — non-idempotent when qmd_index != template #105

@breferrari

Description

@breferrari

Summary

The qmd bootstrap derives the collection name from vault-manifest.json's template field, not from the per-vault qmd_index. So even after a vault personalizes qmd_index (the workaround in shardmind#137), the bootstrap still tries to register/verify a collection named after the shared template identity (obsidian-mind) instead of the vault's own name. On any vault where qmd_index != template, the bootstrap exits non-zero and the collection identity is wrong.

This is a sibling of shardmind#137, not a duplicate. shardmind#137 is about the index (qmd_index) shipping as a hardcoded literal. This issue is about the collection name being sourced from a different field (template) that shardmind#137's proposed fix never touches — so fixing shardmind#137 alone leaves this bug intact.

Root cause

scripts/qmd-bootstrap.ts:188 (obsidian-mind):

const collectionName = manifest.template ?? index;

manifest.template is the shared package identity (obsidian-mind), the same for every install. index here is the (now personalizable) qmd_index. Because template is set, it always wins, so collectionName is obsidian-mind regardless of the vault. That value then flows into:

  • buildCollectionAddArgs(index, collectionName) — registration
  • qmd://${collectionName}/ — the context path
  • collection show ${collectionName} — verification (hard run, not idempotent)
  • the context add/rm round-trip

Evidence (real install: breferrari/obsidian-mind@6.2.1, shardmind schema_version 2)

Vault: /Users/.../tr-mind. After applying the #137 workaround, vault-manifest.json has qmd_index: "tr-mind" while template: "obsidian-mind".

The existing collection (created under the vault/folder name) is tr-mind:

$ qmd --index tr-mind collection list
Collections (1):
tr-mind (qmd://tr-mind/)
  Pattern:  **/*.md
  Files:    236

But the v6.2.1 adopt bootstrap computed collectionName = "obsidian-mind" and exited 1:

→ Bootstrapping QMD index 'tr-mind'
→ Registering collection 'obsidian-mind' (mask **/*.md)
→ Verifying collection 'obsidian-mind' is registered

A collection already exists for this path and pattern:
  Name: tr-mind (qmd://tr-mind/)
⚠ qmd exited with code 1 during: Registering collection 'obsidian-mind'
Collection not found: obsidian-mind
qmd exited with code 1 during: Verifying collection 'obsidian-mind' is registered

Registration is refused (a collection already exists for that path+pattern under the name tr-mind), then the non-idempotent collection show obsidian-mind verification fails with Collection not found. Search itself keeps working because the MCP server scopes by index (--index tr-mind), so the mis-named collection is latent — but every bootstrap/update re-run reports failure, and the context string is attached to the wrong qmd:// path.

Impact

  • Bootstrap is non-idempotent on any vault where qmd_index != template — re-runs and shardmind update always exit non-zero on the verify step.
  • Re-introduces #137's collision at the collection level. Even with qmd_index personalized per vault, every install's collection is still named obsidian-mind. Two vaults sharing an index would collide on the collection name; the context summary (qmd://obsidian-mind/) is shared identity, not per-vault.
  • The template field is the wrong source: it's the package identity, deliberately shared. The collection should carry the vault's own identity, same as the index.

Proposed fix

Derive the collection name from the per-vault identity, not the template. Simplest:

const collectionName = index; // = qmd_index, which #137 makes folder-derived & unique

Drop the manifest.template ?? preference entirely (and the "template field value …" wording in the adjacent isValidQmdIndex error). This pairs naturally with shardmind#137: once qmd_index is folder-derived and unique, the collection name follows it and matches the existing folder-named collection, making the bootstrap idempotent. Update the error message at scripts/qmd-bootstrap.ts:196 to reference qmd_index instead of template.

Workaround for existing installs

The current on-disk collection (tr-mind, folder-named) is already correct — do not rename it to obsidian-mind. The only artifact is the non-zero bootstrap exit until the script is patched.

Notes

This is an obsidian-mind bug: the collection-naming logic ships in and is owned by this repo's bootstrap hook (scripts/qmd-bootstrap.ts). shardmind is a generic template package manager with no knowledge of QMD collections — its only qmd concern is personalizing qmd_index (shardmind#137). The two are complementary: shardmind#137 makes qmd_index unique per vault; this issue makes the collection name follow qmd_index instead of the shared template identity. Related closed work here: #85 (positional vs --name), #86 (context-rm idempotency matcher).

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