moonfetchledger

    Verified cross-version file updates, block-integrity audits and sparse recovery for existing clients.

    integrity
    audit
    repair
    recovery
    webdav
    delta
    update
    Download zip
    Author
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    2 hours ago
    Downloads
    2

    #Checked public API example

    A publisher can also provide full block records for independent file audits. The consumer requires their separately trusted exact-byte pin and still rereads all local storage; authentic reference records do not imply local coverage.

    ///|
    test {
    let bytes = b"abc"
    let object = @moonfetchledger.ObjectSpec::new(
    "https://example.test/a",
    3L,
    "\"v1\"",
    @moonfetchledger.digest(bytes),
    )
    let indexer = @moonfetchledger.StorageIndexer::new(object, chunk_size=3)
    indexer.push(bytes)
    let reference = indexer.block_reference()
    let recovered = reference.session()
    assert_eq(recovered.confirmed_bytes(), 0L)
    assert_true(recovered.reconcile_block({ start: 0L, end: 3L, }, Some(bytes)))
    recovered.finish_recovery()
    recovered.verify_complete(_ => bytes)
    }

    A publisher can distribute one identity manifest; parsing requires separately trusted input. The native loader additionally verifies an independent byte hash.

    ///|
    test {
    let object = @moonfetchledger.ObjectSpec::new(
    "https://example.test/a",
    3L,
    "\"v1\"",
    @moonfetchledger.digest(b"abc"),
    )
    let manifest = object.to_manifest()
    let restored = @moonfetchledger.ObjectSpec::from_manifest(manifest)
    assert_eq(restored, object)
    assert_eq(restored.to_manifest(), manifest)
    }

    ///|
    test {
    let bytes = b"abc"
    let object = @moonfetchledger.ObjectSpec::new(
    "https://example.test/a",
    3L,
    "\"v1\"",
    @moonfetchledger.digest(bytes),
    )
    let session = @moonfetchledger.Session::new(object, chunk_size=3)
    let lease = session.reserve_missing().unwrap()
    let prepared = session.prepare_chunk(
    lease,
    bytes,
    status=206,
    etag=object.etag,
    range=lease.range,
    total=3L,
    )
    session.commit_written(prepared, bytes)
    assert_true(session.unconfirmed_ranges().is_empty())
    session.verify_complete(_ => bytes)
    assert_eq(session.confirmed_bytes(), 3L)
    }

    An existing storage adapter can index complete local content without HTTP metadata:

    ///|
    test {
    let bytes = b"abc"
    let object = @moonfetchledger.ObjectSpec::new(
    "https://example.test/a",
    3L,
    "\"v1\"",
    @moonfetchledger.digest(bytes),
    )
    let indexer = @moonfetchledger.StorageIndexer::new(object, chunk_size=3)
    assert_eq(indexer.next_range(), Some({ start: 0L, end: 3L, }))
    indexer.push(bytes)
    let session = indexer.finish()
    assert_eq(session.confirmed_bytes(), 3L)
    assert_true(session.unconfirmed_ranges().is_empty())
    }

    LedgerError

    pub suberror LedgerError {
    InvalidSpec(String)
    InvalidCheckpoint(String)
    InvalidManifest(String)
    StaleLease
    InvalidResponse(String)
    ReadbackMismatch(Int64)
    RecoveryRequired
    Incomplete(Int64)
    DigestMismatch(String)
    } derive(
    Debug
    )

    Failures preserve the session's confirmed coverage. Storage failures belong to the caller; release its lease before retrying. Checkpoint failures require retaining the input and explicitly starting a new session.

    BlockReference

    pub struct BlockReference {
    spec : ObjectSpec
    chunk_size : Int
    // private fields
    }

    Immutable, complete block records authenticated by an independent byte pin. Uses the existing MFL1 schema, but is not a local progress checkpoint. Loading a reference never confirms local storage; every fresh session starts recovery.

    BlockReference::from_bytes

    fn BlockReference::from_bytes(bytes : Bytes, expected_sha256 : String, expected : ObjectSpec) -> BlockReference raise LedgerError

    Authenticate exact bytes BEFORE UTF-8/schema decoding. The pin must come from a separate trusted channel. Require the expected identity and every block, including the short final block. Partial checkpoints are not references.

    BlockReference::session

    fn BlockReference::session(self : BlockReference) -> Session raise LedgerError

    Return a fresh session with all records untrusted until actual block readback. Caller must reconcile storage and finish recovery before reserving repairs.

    BlockReference::to_checkpoint

    fn BlockReference::to_checkpoint(self : BlockReference) -> String

    Producers emit canonical MFL1; consumers retain the exact authenticated text, including whitespace. Do not recompute a supplied byte pin from re-encoded JSON.

    ByteRange

    pub(all) struct ByteRange {
    start : Int64
    end : Int64
    } derive(Eq,
    Debug
    )

    Half-open byte range [start, end).

    ByteRange::equal

    fn ByteRange::equal(ByteRange, ByteRange) -> Bool

    ByteRange::length

    fn ByteRange::length(self : ByteRange) -> Int64

    ByteRange::not_equal

    fn ByteRange::not_equal(x : ByteRange, y : ByteRange) -> Bool

    DeltaIndexer

    pub struct DeltaIndexer {
    // private fields
    }

    Streaming publisher. No metadata is released before whole-source verification.

    DeltaIndexer::finish

    DeltaIndexer::new

    fn DeltaIndexer::new(spec : ObjectSpec, chunk_size? : Int) -> DeltaIndexer raise LedgerError

    DeltaIndexer::next_range

    fn DeltaIndexer::next_range(self : DeltaIndexer) -> ByteRange?

    DeltaIndexer::push

    fn DeltaIndexer::push(self : DeltaIndexer, bytes : Bytes) -> Unit raise LedgerError

    DeltaReference

    pub struct DeltaReference {
    spec : ObjectSpec
    chunk_size : Int
    // private fields
    }

    Authenticated target-block index for cross-version reuse. The byte pin must arrive through an independent trusted channel; this format is not a signature and is not a zsync control file. MFL1 checkpoints remain unchanged.

    DeltaReference::block_reference

    fn DeltaReference::block_reference(self : DeltaReference) -> BlockReference

    DeltaReference::from_bytes

    fn DeltaReference::from_bytes(bytes : Bytes, expected_sha256 : String) -> DeltaReference raise LedgerError

    Authenticate before UTF-8 or JSON parsing. Unknown fields and incomplete block indexes are rejected. The authenticated identity includes URL, ETag and SHA-256.

    DeltaReference::prepare_reuse

    fn DeltaReference::prepare_reuse(self : DeltaReference, target : Session, lease : Lease, bytes : Bytes) -> PreparedChunk raise LedgerError

    Revalidate seed bytes immediately before writing. A rolling match alone never authorizes reuse. The lease is bound to the authenticated target and layout.

    DeltaReference::scanner

    DeltaReference::to_bytes

    fn DeltaReference::to_bytes(self : DeltaReference) -> Bytes

    Exact four-field positional schema, canonical output and full-width checksums.

    Lease

    pub struct Lease {
    range : ByteRange
    // private fields
    }

    Session-bound capability; cannot be constructed or reused across restores.

    ObjectSpec

    pub struct ObjectSpec {
    resource : String
    length : Int64
    etag : String
    sha256 : String
    } derive(Eq,
    Debug
    )

    Identity includes the resource, representation length, strong HTTP validator and independently obtained SHA-256. The ETag is not an integrity digest.

    ObjectSpec::equal

    fn ObjectSpec::equal(ObjectSpec, ObjectSpec) -> Bool

    ObjectSpec::from_manifest

    fn ObjectSpec::from_manifest(text : String) -> ObjectSpec raise LedgerError

    Exact five-field schema; unknown fields/versions are refused, never discarded. Length is a canonical decimal string so all targets preserve Int64 identity. Accepts JSON whitespace but never normalizes resource or validator values.

    ObjectSpec::new

    fn ObjectSpec::new(resource : String, length : Int64, etag : String, sha256 : String) -> ObjectSpec raise LedgerError

    ObjectSpec::not_equal

    fn ObjectSpec::not_equal(x : ObjectSpec, y : ObjectSpec) -> Bool

    ObjectSpec::to_manifest

    fn ObjectSpec::to_manifest(self : ObjectSpec) -> String

    Deterministic release identity, without coverage, credentials or local paths. Obtain the manifest or its exact-byte digest through an independent trusted channel. Parsing alone does not authenticate a publisher.

    PauseSignal

    pub struct PauseSignal {
    // private fields
    }

    One-shot cooperative pause intent. Serialize access on the application's async scheduler; this is not an OS-thread synchronization primitive.

    PauseSignal::is_requested

    fn PauseSignal::is_requested(self : PauseSignal) -> Bool

    PauseSignal::new

    PauseSignal::request_pause

    fn PauseSignal::request_pause(self : PauseSignal) -> Unit

    Request a pause without throwing or cancelling in-flight storage operations. Repeating this request is harmless. Create a fresh signal to resume.

    PreparedChunk

    pub struct PreparedChunk {
    // private fields
    }

    RecoveryReport

    pub(all) struct RecoveryReport {
    retained_bytes : Int64
    invalidated : Array[ByteRange]
    } derive(
    Debug
    )

    ScanStep

    pub struct ScanStep {
    consumed_bytes : Int
    hashed_bytes : Int64
    blocked : Bool
    }

    SeedMatch

    pub(all) struct SeedMatch {
    source : ByteRange
    target : ByteRange
    } derive(Eq,
    Debug
    )

    Byte ranges in ONE untrusted seed and the authenticated target. Target ranges are whole aligned target blocks; source ranges may begin at any byte offset.

    SeedMatch::equal

    fn SeedMatch::equal(SeedMatch, SeedMatch) -> Bool

    SeedMatch::not_equal

    fn SeedMatch::not_equal(x : SeedMatch, y : SeedMatch) -> Bool

    SeedPlan

    pub struct SeedPlan {
    scanned_bytes : Int64
    reused_bytes : Int64
    hashed_bytes : Int64
    // private fields
    }

    SeedPlan::download_bytes

    fn SeedPlan::download_bytes(self : SeedPlan) -> Int64

    Logical bytes not found in this seed, excluding HTTP overhead and retries.

    SeedPlan::matches

    fn SeedPlan::matches(self : SeedPlan) -> Array[SeedMatch]

    Fresh snapshot, sorted by target offset. First matching seed offset wins; duplicate target blocks may reuse the same source bytes.

    SeedPlan::missing_ranges

    fn SeedPlan::missing_ranges(self : SeedPlan) -> Array[ByteRange]

    Coalesced complement of verified reusable target blocks. Fresh snapshot.

    SeedPlan::to_json

    fn SeedPlan::to_json(self : SeedPlan) -> Json

    Deterministic MFLPLAN1 report. A preview is a snapshot, not write authority.

    SeedPool

    pub struct SeedPool {
    // private fields
    }

    Collect up to 32 independently scanned seeds. First seed wins each block.

    SeedPool::add

    fn SeedPool::add(self : SeedPool, plan : SeedPlan) -> Unit raise LedgerError

    Identity/layout errors and the input limit fail before modifying the pool.

    SeedPool::finish

    fn SeedPool::finish(self : SeedPool) -> SeedPoolPlan raise LedgerError

    Idempotent immutable snapshot; an empty pool is refused.

    SeedPool::new

    fn SeedPool::new(reference : DeltaReference) -> SeedPool

    SeedPoolPlan

    pub struct SeedPoolPlan {
    scanned_bytes : Int64
    reused_bytes : Int64
    hashed_bytes : Int64
    // private fields
    }

    SeedPoolPlan::download_bytes

    fn SeedPoolPlan::download_bytes(self : SeedPoolPlan) -> Int64

    SeedPoolPlan::matches

    SeedPoolPlan::missing_ranges

    fn SeedPoolPlan::missing_ranges(self : SeedPoolPlan) -> Array[ByteRange]

    SeedPoolPlan::per_seed_reused_bytes

    fn SeedPoolPlan::per_seed_reused_bytes(self : SeedPoolPlan) -> Array[Int64]

    SeedPoolPlan::to_json

    fn SeedPoolPlan::to_json(self : SeedPoolPlan) -> Json

    SeedScanner

    pub struct SeedScanner {
    // private fields
    }

    Streaming, bounded to two target-sized windows plus O(target block count). Splitting input at arbitrary boundaries does not change the plan.

    SeedScanner::finish

    fn SeedScanner::finish(self : SeedScanner) -> SeedPlan

    Idempotent. Subsequent push calls are rejected without changing this result.

    SeedScanner::push

    fn SeedScanner::push(self : SeedScanner, bytes : Bytes) -> Unit raise LedgerError

    SeedScanner::push_bounded

    fn SeedScanner::push_bounded(self : SeedScanner, bytes : Bytes, max_hash_bytes~ : Int64) -> ScanStep raise LedgerError

    Consume the longest prefix whose candidate SHA-256 input fits this CALL's budget. When blocked, replay bytes[consumed_bytes:] with a larger budget. Budget exhaustion is explicit and does not consume the blocked byte in any window. Rolling byte scanning itself is not charged as SHA work.

    SeedSourceMatch

    pub(all) struct SeedSourceMatch {
    seed_index : Int
    source : ByteRange
    target : ByteRange
    } derive(Eq,
    Debug
    )

    SeedSourceMatch::equal

    SeedSourceMatch::not_equal

    fn SeedSourceMatch::not_equal(x : SeedSourceMatch, y : SeedSourceMatch) -> Bool

    Session

    pub struct Session {
    spec : ObjectSpec
    chunk_size : Int
    // private fields
    }

    Session::checkpoint

    fn Session::checkpoint(self : Session) -> String raise LedgerError

    Strict positional JSON array. No object keys can be silently overwritten. Decimal strings avoid JS's floating-point integer precision limit.

    Session::commit_written

    fn Session::commit_written(self : Session, prepared : PreparedChunk, readback : Bytes) -> Unit raise LedgerError

    Call only with bytes read back from lease.range after a successful write/sync. Readback proves equality with the received payload, not durable-media honesty. Repeating an identical commit is idempotent.

    Session::confirmed_bytes

    fn Session::confirmed_bytes(self : Session) -> Int64

    Session::finish_recovery

    fn Session::finish_recovery(self : Session) -> Unit raise LedgerError

    Returns invalidated ranges from a caller-owned report; no silent recovery.

    Session::new

    fn Session::new(spec : ObjectSpec, chunk_size? : Int) -> Session raise LedgerError

    Create a fixed-block sparse receiver. At most 100,000 blocks, 4 MiB each. Calls are synchronous and must be serialized by the adapter; leases permit concurrent network requests, not unsynchronized threads mutating a session.

    Session::prepare_chunk

    fn Session::prepare_chunk(self : Session, lease : Lease, bytes : Bytes, status~ : Int, etag~ : String, range~ : ByteRange, total~ : Int64, content_encoding? : String) -> PreparedChunk raise LedgerError

    Adapter supplies parsed Content-Range as half-open bounds and complete length. Rejects full responses and representation changes before storage is touched.

    Session::reconcile_block

    fn Session::reconcile_block(self : Session, range : ByteRange, readback : Bytes?) -> Bool raise LedgerError

    Restore one block using actual storage. None means absent/truncated storage. I/O errors must be propagated by the adapter, not converted to None.

    Session::recovery_ranges

    fn Session::recovery_ranges(self : Session) -> Array[ByteRange]

    Restored blocks requiring readback, returned as a fresh array.

    Session::release

    fn Session::release(self : Session, lease : Lease) -> Unit raise LedgerError

    Cancel an outstanding request. Confirmed data is never released.

    Session::reserve_missing

    fn Session::reserve_missing(self : Session) -> Lease? raise LedgerError

    Reserve the earliest missing block, excluding all outstanding requests.

    Session::reserve_range

    fn Session::reserve_range(self : Session, range : ByteRange) -> Lease? raise LedgerError

    Reserve one exact aligned block, for a verified seed plan. Return None if it is already confirmed or reserved. Invalid ranges leave coverage unchanged.

    Session::unconfirmed_ranges

    fn Session::unconfirmed_ranges(self : Session) -> Array[ByteRange] raise LedgerError

    Fresh, sorted, coalesced half-open ranges not yet confirmed by readback. Outstanding reservations are included. Finish restoration before inspecting coverage; this method does not reserve requests or mutate the session.

    Session::verifier

    fn Session::verifier(self : Session) -> Verifier raise LedgerError

    Session::verify_complete

    fn Session::verify_complete(self : Session, read_at : (ByteRange) -> Bytes raise) -> Unit raise

    Bounded-memory verification. The callback must read the requested stored range; short reads and I/O exceptions abort verification without declaring completion.

    StorageIndexer

    pub struct StorageIndexer {
    // private fields
    }

    Index existing storage without inventing HTTP response metadata. No session or checkpoint is exposed until the trusted whole-file digest has matched.

    StorageIndexer::block_reference

    fn StorageIndexer::block_reference(self : StorageIndexer) -> BlockReference raise LedgerError

    Publish block records only after the entire indexed source digest verifies. Repeated calls produce identical MFL1 bytes and independent recovery sessions.

    StorageIndexer::finish

    fn StorageIndexer::finish(self : StorageIndexer) -> Session raise LedgerError

    Verify the entire digest and return a fresh complete session. Repeated finish is deterministic; incorrect digests never expose partial confirmed coverage.

    StorageIndexer::new

    fn StorageIndexer::new(spec : ObjectSpec, chunk_size? : Int) -> StorageIndexer raise LedgerError

    StorageIndexer::next_range

    fn StorageIndexer::next_range(self : StorageIndexer) -> ByteRange?

    StorageIndexer::prepare_repair

    fn StorageIndexer::prepare_repair(self : StorageIndexer, target : Session, lease : Lease, bytes : Bytes) -> PreparedChunk raise LedgerError

    Prepare a local repair from an entirely verified storage index. Identity and block layout must match the target. Re-read bytes must still match the indexed block digest; rejected input leaves the lease available for a corrected read.

    StorageIndexer::push

    fn StorageIndexer::push(self : StorageIndexer, bytes : Bytes) -> Unit raise LedgerError

    Supply exactly the next range read from storage. Rejected lengths leave the index and hash unchanged, permitting a corrected read to be supplied.

    Verifier

    pub struct Verifier {
    // private fields
    }

    Sequential bounded-memory verifier suitable for asynchronous storage adapters.

    Verifier::finish

    fn Verifier::finish(self : Verifier) -> Unit raise LedgerError

    Verifier::next_range

    fn Verifier::next_range(self : Verifier) -> ByteRange?

    Verifier::push

    fn Verifier::push(self : Verifier, bytes : Bytes) -> Unit raise LedgerError

    Feed exactly the next requested range. Bad lengths do not advance the hash.

    digest

    fn digest(bytes : Bytes) -> String

    SHA-256 of bytes, without decoding text. Provided for storage integration.

    restore

    fn restore(checkpoint : String, expected : ObjectSpec) -> Session raise LedgerError

    Exact schema and object identity required. All recorded coverage starts untrusted, reservations are discarded, and old capabilities cannot be reused.

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io