Skip to content

fix(cache): unify the cached-capsule artifact on .dig (Closes #1896) - #139

Merged
MichaelTaylor3d merged 2 commits into
mainfrom
fix/1896-cache-extension-dig
Aug 2, 2026
Merged

fix(cache): unify the cached-capsule artifact on .dig (Closes #1896)#139
MichaelTaylor3d merged 2 commits into
mainfrom
fix/1896-cache-extension-dig

Conversation

@MichaelTaylor3d

Copy link
Copy Markdown
Contributor

What changed

Closes DIG-Network/dig_ecosystem#1896.

The cache landed a capsule as <store>/<root>.module while staging wrote <store>-<root>.dig — one artifact, two extensions. .dig is the format's name everywhere else (the CLI, the spec, the staging path). This unifies the cache landing on .dig, keeping the reader backward-compatible so no upgraded node ever silently stops being a holder.

Load-bearing context: the existence of the cache file IS the DHT holder announcement (cache_list_cachedrefresh_dht_inventory → provider records, SPEC §21.3). A naive rename would orphan every existing .module file — the node would keep the bytes but silently cease announcing itself as a holder for content it already has (an invisible flywheel regression). This change makes that outcome impossible.

Mechanism — reader-tolerance (the guarantee) + idempotent startup rename (convergence)

  • Reader-tolerance (load-bearing). Every cache read/stat/scan/remove resolves .dig first and falls back to legacy .module; the holder-scan strips either suffix. An un-migrated, half-migrated, or crash-interrupted cache stays fully discoverable-as-holder AND servable.
  • Startup rename (convergence). At node bring-up — after set_self_ref, before the first inventory announce — migrate_legacy_module_extensions renames *.module*.dig (deleting a redundant .module if .dig already exists). Idempotent and crash-safe because reader-tolerance covers any leftover, so a future release can drop the .module fallback cleanly (documented two-release deprecation).

Shape (DRY — one authority)

capsule_key.rs gains CACHED_MODULE_EXT="dig" + LEGACY_MODULE_EXT="module"; module_path builds .dig; new resolve_cached_path (prefer .dig → legacy .module.dig) and cached_root_stem (strips either suffix — the single scan authority). Every read site routes through these so no site re-derives the fallback. Write sites keep calling module_path (now .dig); staging is unchanged.

The one direct-glob site — capsule_store.rs cache_list_cached (the holder-announcement source) — now uses cached_root_stem. Sibling check clean: dig-wallet, control.rs, dispatch.rs, peer.rs all read holders exclusively via cache_list_cached; no other crate globs the cache. Blast radius is entirely within dig-node-core.

Verification

  • 10 new tests pass, including the holder-continuity guards:
    • cache_list_cached_discovers_a_legacy_dot_module_file — a legacy .module with no .dig is still returned, held, and announced.
    • mid_upgrade_partial_rename_loses_no_holder — a half-migrated cache reports the FULL holder set.
    • serve_and_held_check_resolve_a_legacy_dot_module — a legacy-only capsule both serves bytes and reads as held.
    • startup_migration_renames_module_to_dig_and_is_idempotent — mixed corpus converges to .dig, redundant .module removed, zero lost, re-run is a no-op.
    • cache_remove_removes_either_suffix, cache_list_cached_discovers_a_new_dot_dig_file, resolve_cached_path_*, cached_root_stem_*, a_landed_capsule_is_written_with_the_dig_extension.
  • cargo fmt --all -- --check → exit 0 · cargo clippy -p dig-node-core --all-targets --all-features -- -D warnings → clean · cargo test -p dig-node-core → all sync/cache-path + the 10 new tests green. (9 pre-existing port-binding/dual-stack env tests fail identically on a clean tree — not from this diff; they pass in CI.)
  • SPEC.md §21.3 (availability-source line + promotion ladder → .dig, plus the reader-accepts-legacy + startup-rename clause and the "cache-filename only, §5.1 store-format compat does not apply" note) updated in the same unit of work.

Version

fix: (internal cache-filename consistency, behaviour-preserving with a backward-compatible reader) → patch bump [workspace.package].version 0.74.2 → 0.74.3. §5.1 store-format backward-compat does not apply — this is the local cache filename, not the .dig byte format; the bytes inside are untouched.


Generated by Claude Code

MichaelTaylor3d and others added 2 commits August 2, 2026 08:53
Co-Authored-By: Claude <noreply@anthropic.com>
Close the #1896 split where a landed capsule was cached as `.module` while
staging wrote `.dig`. The cache landing now writes `.dig` (module_path), so a
capsule has ONE artifact extension end-to-end.

Mechanism (c): reader-tolerance + idempotent startup rename.
- capsule_key: CACHED_MODULE_EXT/LEGACY_MODULE_EXT consts; module_path builds
  `.dig`; resolve_cached_path (prefer .dig, else legacy .module) is the single
  read authority; cached_root_stem strips either suffix for the inventory scan;
  migrate_legacy_module_extensions renames .module -> .dig at bring-up.
- Every read site (module_exists, serve_local_blocking, read_public_manifest,
  cache_list_cached scan, cache_remove_cached, cache_fetch_and_cache stat,
  describe_module, read_module_window) routes through the shared authority, so a
  legacy .module cache keeps a node a discoverable holder through an upgrade.
- Startup migration runs before the first refresh_dht_inventory; idempotent and
  crash-safe (dedup when both exist), reader-tolerance covers any interrupted run.

Cache-filename change only; the immutable .dig byte format (SPEC 5.1) is
untouched. SPEC.md promotion-ladder + availability-source updated.

10 new tests (holder-continuity, partial-upgrade, either-suffix removal,
idempotent migration). Version 0.74.2 -> 0.74.3 (patch).

Closes #1896

Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d merged commit 8724b5f into main Aug 2, 2026
15 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the fix/1896-cache-extension-dig branch August 2, 2026 09:42
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