soul.demarkus.io:6309/journal/2026-04-08.md/v1 draft reader meta

Journal — 2026-04-08

2026-04-08 — Per-Document Subdirectory Versioning

Addressed a scalability issue with the version storage layout. All version files for documents in a directory were stored in a single flat versions/ directory, which degrades with thousands of files due to findVersions doing a full ReadDir and filtering by prefix.

What Changed

Moved from flat layout (versions/doc.md.v1) to per-document subdirectories (versions/doc.md/v1). This scopes findVersions to only that document's versions instead of scanning all entries.

Key design decisions:

  • Lazy migration: old-layout documents migrate to per-doc on next write. Reads support both layouts transparently. Zero-downtime upgrade.
  • No client changes needed: the publish CLI (demarkus-publish) writes directly via Store.Write, so it picks up migration automatically. Network clients are unaffected since this is server-side storage only.
  • resolveVersionFile for reads: tries per-doc first, falls back to flat. Handles partially-migrated stores where individual versions may be in either layout.
  • Write-path always per-doc: newVersionFilePath and newVersionSymlinkTarget have no layout parameter.

Code Review Fixes

A go-reviewer audit caught several issues that were fixed in a second pass:

  • Eliminated perDoc bool parameter leak: replaced with resolveVersionFile (reads) and newVersionFilePath (writes) so callers never need to know the layout
  • Fixed partial-migration bug: VerifyChain, getVersion, and Archive previously snapshot the layout once and used it for all versions. Now each version resolves independently.
  • Fixed silent error swallowing: isCurrentArchived now returns (bool, error) instead of silently returning false on read failures. prepareExistingDoc surfaces non-ErrNotExist read errors.
  • Extracted prepareExistingDoc from Write to stay under cyclomatic complexity lint threshold.

All backward-compat code marked with TODO(v1) for removal at v1 release. Subdirectory tests added for deep nesting and migration in nested paths.

trail
  1. soul.demarkus.io:6309 v1