Skip to content

feat(digstore-subscription): canonical chain-watch Subscription with full-history backfill (#979) - #26

Merged
MichaelTaylor3d merged 3 commits into
mainfrom
feat/subscription-primitive
Jul 18, 2026
Merged

feat(digstore-subscription): canonical chain-watch Subscription with full-history backfill (#979)#26
MichaelTaylor3d merged 3 commits into
mainfrom
feat/subscription-primitive

Conversation

@MichaelTaylor3d

Copy link
Copy Markdown
Contributor

Closes #979 (Phase 1).

Builds the canonical Subscription primitive as a NEW leaf sub-crate digstore-subscription in the dig-store workspace, per the #979 loop-decider plan.

A Subscription follows ONE CHIP-0035 store singleton: it (1) tracks tip progression, (2) syncs the new tip's .dig down, (3) backfills EVERY historical tip's .dig best-effort with missing-tip retry, over injected chain/network seams so the decision core is networkless + unit-testable.

Extracted + generalized from dig-node's chainwatch.rs (decide_watch/WatchAction/run_tick) + subscription.rs (SubscriptionSet/SubscriptionsDoc) — single-latest-tip gap-fill generalized to FULL-HISTORY backfill. dig-node consumes this in Phase 2 (deferred; no dig-node change here — single-writer).

Adversarial-verify focus: fail-closed (never fetch/verify against an unconfirmable root) + reorg/permanence (a superseded root MUST NOT evict an already-held .dig, §5.1).

WIP — do not merge.

…979)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d force-pushed the feat/subscription-primitive branch from 692668b to f57eb34 Compare July 18, 2026 16:15
@MichaelTaylor3d MichaelTaylor3d changed the title feat(digstore-subscription): canonical chain-watch Subscription primitive with full-history backfill (#979) feat(digstore-subscription): canonical chain-watch Subscription with full-history backfill (#979) Jul 18, 2026
…full-history backfill (#979)

Build the Subscription primitive as a new leaf sub-crate in the dig-store
workspace: a per-store managed object that watches one CHIP-0035 singleton's
lineage and keeps the local set of .dig files in sync with its full on-chain
history.

- Networkless decision core (decide) + state machine (Subscription) driven over
  four injected seams (ChainWatch/CapsuleFetcher/HeldCheck/Persistence), so the
  policy is pure + unit-testable with no chain and no network.
- Generalizes dig-node's single-latest-tip gap-fill to full-history backfill:
  tip-first then oldest to newest, missing-tip retry with accruing attempts.
- Two load-bearing invariants, tested: fail-closed (never fetch/verify against
  an unconfirmable root) and reorg/permanence (a superseded root is retained,
  never evicting an already-held .dig -- CLAUDE.md 5.1).
- Extracts + canonicalizes the SubscriptionSet + subscription-set codec from
  dig-node subscription.rs (dig-node consumes this in Phase 2, deferred).

SPEC-first normative contract in crates/digstore-subscription/SPEC.md.
Workspace version 0.15.1 -> 0.16.0 (minor: new crate/capability).

Refs #979

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d force-pushed the feat/subscription-primitive branch from f57eb34 to 3c5b65d Compare July 18, 2026 16:21
…d, real-flow test (#979)

The retry attempt counter reset to 1 every tick in the real reconcile flow:
reconcile_tick calls mark_pending (status -> Pending) immediately before
record_fetch_result, whose Err branch only read a prior Failed record, so the
in-flight Pending clobbered the accrued count. Carry the prior failed-attempt
count through the Pending transition (Pending { attempts }) so a capsule that
fails N consecutive ticks records Failed { attempts: N }.

- New real-flow test drives reconcile_tick across 3 failing ticks and asserts
  attempts == 1,2,3 (the prior test bypassed mark_pending and masked the bug),
  then a success flips to Held.
- observe_lineage now ignores a lineage whose store_id != the subscription's, so
  a buggy ChainWatch cannot repoint the history to a foreign store (+ test).
- SPEC: align the attempt-accrual wording with the real flow; note the store_id
  guard; note CapsuleFetcher MUST land-before-Ok or the capsule re-fetches forever.

Refs #979

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d force-pushed the feat/subscription-primitive branch from 13a37fc to 775ae6e Compare July 18, 2026 17:10
@MichaelTaylor3d
MichaelTaylor3d marked this pull request as ready for review July 18, 2026 17:25
@MichaelTaylor3d
MichaelTaylor3d merged commit e2a21cb into main Jul 18, 2026
10 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the feat/subscription-primitive branch July 18, 2026 17:25
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