Sign in

    moonvcs

    Native MoonBit VCS core with typed SHA-256 objects, lazy storage and policy boundaries.

    version-control
    content-addressed-storage
    wasm
    moonbit
    Download zip
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    4 days ago
    Downloads
    25

    #MoonVCS Core

    Native MoonBit source module for the MoonVCS research prototype: typed Blob, Tree and Commit objects, canonical SHA-256 encoding, object stores, lazy history, and repository operations with policy validation boundaries.

    Candidate module: any07557-wq/moonvcs@0.1.0, prepared for the maintainer's confirmed Mooncakes username any07557-wq. Not published yet; authenticated publication permissions and version availability remain unverified. A local package archive is not a published release; do not assume moon add any07557-wq/moonvcs is available.

    #Scope

    The module contains the MoonBit core and native CLI source. It does not ship the Rust/Wasmtime Host, compiled Wasm policies, WIT, runtime configuration, toolchain archives, or a prebuilt moonvcs executable. Installing this module alone does not provision the complete policy-enforced VCS.

    Use the full source repository and its installation instructions for the end-to-end CLI and policies. The repository-only bypass test client is excluded from this module archive; it remains available in the repository tests.

    #Minimal library example

    After making the module available as a local dependency (or after its actual publication under a confirmed namespace), import it in your moon.pkg:

    import {
    "any07557-wq/moonvcs" @vcs,
    }

    pkgtype(kind: "executable")

    fn main {
    try {
    let id = @vcs.object_id_for(@vcs.BlobObject({ content: b"", }))
    println(id.to_string())
    } catch {
    _ => println("object encoding failed")
    }
    }

    The empty Blob ID is 3f2f7192ae4599c2d0886683b3b2833896f695ed1a83af663117e49a894deaa7. It hashes MoonVCS's typed encoding, not just the empty payload and not Git's object encoding.

    #Compatibility and limitations

    • Native backend; verified in Linux x86-64 environments. This is not a claim of browser, JS, Wasm-GC or cross-platform support for the entire module.
    • Candidate 0.1.0 API is experimental, not a stable production API commitment.
    • Real repository commits/receives need a valid policy context and external Host/plugins. Do not replace required policy validation with a mock validator.
    • Included white-box tests also contain repository integration tests requiring the full repository and built runtime. A standalone module check/build is not a standalone pass of the complete test suite.
    • File-system/stdio remotes have no authentication, ACL, TLS or server OS privilege separation. This is not a production Git replacement.

    For test evidence and security boundaries see the repository's CI validation and SECURITY.md. The CI result applies to its recorded commit, not automatically to this later packaging preparation.

    #License

    Apache-2.0; the module includes the same LICENSE notice as the repository.

    ObjectStore

    pub(open) trait ObjectStore {
    async fn put(Self, VcsObject) -> ObjectId
    async fn get(Self, ObjectId) -> VcsObject
    async fn has(Self, ObjectId) -> Bool
    async fn verify(Self, ObjectId) -> Bool
    }

    PolicyValidator

    pub(open) trait PolicyValidator {
    async fn validate(Self, CommitCandidate) -> PolicyDecision
    }

    VcsError

    pub(all) suberror VcsError {
    InvalidObjectId(String)
    InvalidObject(String)
    InvalidTree(String)
    InvalidPath(String)
    ObjectNotFound(String)
    UnknownObject(String)
    ObjectUnavailableOffline(String)
    RemoteUnavailable(String)
    RemoteObjectMissing(String)
    InvalidPromise(String)
    RemoteRefChanged(String)
    RepositoryNotFound(String)
    RepositoryExists(String)
    RefConflict(String)
    StagingBusy(String)
    PublicationUncertain(String)
    ReceiveRejected(String)
    ReceiveInvalid(String)
    ReceivePolicyError(String)
    ReceiveProcessExit(Int)
    PolicyRejected(String)
    PolicyExecutionFailed(String)
    InvalidCommand(String)
    DiffFailed(String)
    CheckoutFailed(String)
    SwitchIncomplete(String)
    } derive(
    Debug
    )

    VcsError::to_repr

    Blob

    pub(all) struct Blob {
    content : Bytes
    } derive(Eq,
    Debug
    )

    Blob::equal

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

    Blob::not_equal

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

    Blob::to_repr

    CandidateFile

    pub(all) struct CandidateFile {
    path : String
    blob_id : ObjectId
    content : Bytes
    } derive(Eq,
    Debug
    )

    CandidateFile::equal

    CandidateFile::not_equal

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

    Commit

    pub(all) struct Commit {
    tree_id : ObjectId
    parents : Array[ObjectId]
    author : String
    timestamp : UInt64
    message : String
    } derive(Eq,
    Debug
    )

    Commit::equal

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

    Commit::not_equal

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

    Commit::to_repr

    CommitCandidate

    pub(all) struct CommitCandidate {
    tree_id : ObjectId
    parents : Array[ObjectId]
    author : String
    timestamp : UInt64
    message : String
    staged_files : Array[CandidateFile]
    } derive(Eq,
    Debug
    )

    CommitCandidate::equal

    CommitCandidate::not_equal

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

    ConfiguredRule

    pub struct ConfiguredRule {
    id : String
    literal : String
    } derive(ToJson,
    FromJson
    )

    DiffMode

    pub(all) enum DiffMode {
    WorkingDiff
    StagedDiff
    HeadDiff
    } derive(Eq,
    Debug
    )

    DiffMode::equal

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

    DiffMode::not_equal

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

    DiffMode::to_repr

    EngineDecision

    pub(all) enum EngineDecision {
    Accept
    Warning(Array[PolicyDiagnostic])
    Reject(Array[PolicyDiagnostic])
    EngineError(String)
    }

    FileObjectStore

    pub struct FileObjectStore {
    objects_dir : String
    }

    FileObjectStore::get

    async fn FileObjectStore::get(self : FileObjectStore, id : ObjectId) -> VcsObject

    FileObjectStore::has

    async fn FileObjectStore::has(self : FileObjectStore, id : ObjectId) -> Bool

    FileObjectStore::new

    fn FileObjectStore::new(repository_root : String) -> FileObjectStore

    FileObjectStore::object_path

    fn FileObjectStore::object_path(self : FileObjectStore, id : ObjectId) -> String

    FileObjectStore::put

    async fn FileObjectStore::put(self : FileObjectStore, object : VcsObject) -> ObjectId

    FileObjectStore::verify

    async fn FileObjectStore::verify(self : FileObjectStore, id : ObjectId) -> Bool

    Index

    pub(all) struct Index {
    entries : Array[IndexEntry]
    } derive(Eq,
    Debug
    )

    Index::equal

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

    Index::not_equal

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

    Index::to_repr

    IndexEntry

    pub(all) struct IndexEntry {
    path : String
    blob_id : ObjectId
    } derive(Eq,
    Debug
    )

    IndexEntry::equal

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

    IndexEntry::not_equal

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

    LazyObjectStore

    pub struct LazyObjectStore {
    root : String
    cache : LocalObjectStore
    offline : Bool
    fetch_events : Bool
    }

    LazyObjectStore::get

    async fn LazyObjectStore::get(self : LazyObjectStore, id : ObjectId) -> VcsObject

    LazyObjectStore::has

    async fn LazyObjectStore::has(self : LazyObjectStore, id : ObjectId) -> Bool

    LazyObjectStore::new

    fn LazyObjectStore::new(root : String, offline? : Bool, fetch_events? : Bool) -> LazyObjectStore

    LazyObjectStore::object_path

    fn LazyObjectStore::object_path(self : LazyObjectStore, id : ObjectId) -> String

    LazyObjectStore::put

    async fn LazyObjectStore::put(self : LazyObjectStore, object : VcsObject) -> ObjectId

    LazyObjectStore::state

    async fn LazyObjectStore::state(self : LazyObjectStore, id : ObjectId) -> ObjectState

    LazyObjectStore::transfer_stats

    async fn LazyObjectStore::transfer_stats(self : LazyObjectStore) -> TransferStats

    LazyObjectStore::verify

    async fn LazyObjectStore::verify(self : LazyObjectStore, id : ObjectId) -> Bool

    LocalObjectStore

    pub struct LocalObjectStore {
    disk : FileObjectStore
    }

    LocalObjectStore::get

    async fn LocalObjectStore::get(self : LocalObjectStore, id : ObjectId) -> VcsObject

    LocalObjectStore::has

    async fn LocalObjectStore::has(self : LocalObjectStore, id : ObjectId) -> Bool

    LocalObjectStore::new

    fn LocalObjectStore::new(root : String) -> LocalObjectStore

    LocalObjectStore::put

    async fn LocalObjectStore::put(self : LocalObjectStore, object : VcsObject) -> ObjectId

    LocalObjectStore::verify

    async fn LocalObjectStore::verify(self : LocalObjectStore, id : ObjectId) -> Bool

    MemoryObjectStore

    pub struct MemoryObjectStore {
    objects : Map[String, Bytes]
    }

    MemoryObjectStore::corrupt_for_test

    fn MemoryObjectStore::corrupt_for_test(self : MemoryObjectStore, id : ObjectId, bytes : Bytes) -> Unit

    MemoryObjectStore::count

    fn MemoryObjectStore::count(self : MemoryObjectStore) -> Int

    MemoryObjectStore::get

    async fn MemoryObjectStore::get(self : MemoryObjectStore, id : ObjectId) -> VcsObject

    MemoryObjectStore::has

    async fn MemoryObjectStore::has(self : MemoryObjectStore, id : ObjectId) -> Bool

    MemoryObjectStore::new

    MemoryObjectStore::put

    async fn MemoryObjectStore::put(self : MemoryObjectStore, object : VcsObject) -> ObjectId

    MemoryObjectStore::verify

    async fn MemoryObjectStore::verify(self : MemoryObjectStore, id : ObjectId) -> Bool

    MockPolicyValidator

    pub struct MockPolicyValidator {
    allow : Bool
    reason : String
    }

    MockPolicyValidator::pass

    MockPolicyValidator::reject

    fn MockPolicyValidator::reject(reason : String) -> MockPolicyValidator

    MockPolicyValidator::validate

    ObjectId

    pub struct ObjectId {
    hex : String
    } derive(Eq,
    Debug
    )

    ObjectId::equal

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

    ObjectId::not_equal

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

    ObjectId::parse

    fn ObjectId::parse(value : String) -> ObjectId raise VcsError

    ObjectId::to_repr

    ObjectId::to_string

    fn ObjectId::to_string(self : ObjectId) -> String

    ObjectState

    pub(all) enum ObjectState {
    Local
    PromisedRemote
    Unknown
    } derive(Eq,
    Debug
    )

    ObjectState::equal

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

    ObjectState::not_equal

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

    PolicyContext

    pub struct PolicyContext {
    schema : Int
    host : String
    required : Array[RequiredPolicy]
    allowed_capabilities : Array[String]
    limits : PolicyLimits
    custom_rules : Array[ConfiguredRule]
    } derive(ToJson,
    FromJson
    )

    PolicyDecision

    pub(all) enum PolicyDecision {
    PolicyPass
    PolicyReject(String)
    PolicyError(String)
    } derive(Eq,
    Debug
    )

    PolicyDecision::equal

    PolicyDecision::not_equal

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

    PolicyDiagnostic

    pub struct PolicyDiagnostic {
    plugin : String
    rule : String
    file : String?
    line : Int?
    severity : String
    message : String
    }

    PolicyLimits

    pub struct PolicyLimits {
    fuel : Int
    timeout_ms : Int
    max_memory_bytes : Int
    max_input_bytes : Int
    max_output_bytes : Int
    max_log_bytes : Int
    } derive(ToJson,
    FromJson
    )

    ReceiveReport

    pub struct ReceiveReport {
    ref_name : String
    target : ObjectId
    checked_commits : Int
    promoted_objects : Int
    policy_revision : String
    }

    ReceiveRequest

    pub(all) struct ReceiveRequest {
    ref_name : String
    expected_old : ObjectId?
    target : ObjectId
    objects : Array[ReceivedObject]
    }

    ReceivedObject

    pub(all) struct ReceivedObject {
    id : ObjectId
    encoded : Bytes
    }

    Ref

    pub(all) struct Ref {
    name : String
    target : ObjectId
    } derive(Eq,
    Debug
    )

    Ref::equal

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

    Ref::not_equal

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

    Ref::to_repr

    RemoteObjectStore

    pub struct RemoteObjectStore {
    root : String
    }

    RemoteObjectStore::fetch_encoded

    async fn RemoteObjectStore::fetch_encoded(self : RemoteObjectStore, id : ObjectId) -> Bytes

    RemoteObjectStore::get

    async fn RemoteObjectStore::get(self : RemoteObjectStore, id : ObjectId) -> VcsObject

    RemoteObjectStore::has

    async fn RemoteObjectStore::has(self : RemoteObjectStore, id : ObjectId) -> Bool

    RemoteObjectStore::new

    fn RemoteObjectStore::new(root : String) -> RemoteObjectStore

    RemoteObjectStore::put

    RemoteObjectStore::verify

    async fn RemoteObjectStore::verify(self : RemoteObjectStore, id : ObjectId) -> Bool

    Repository

    pub struct Repository {
    root : String
    store : LazyObjectStore
    }

    Repository::add

    async fn Repository::add(self : Repository, paths : Array[String]) -> Array[IndexEntry]

    Repository::at

    fn Repository::at(root : String, offline? : Bool, fetch_events? : Bool) -> Repository

    Repository::branches

    async fn Repository::branches(self : Repository) -> Array[String]

    Repository::commit

    async fn Repository::commit(self : Repository, author : String, timestamp : UInt64, message : String) -> ObjectId

    Repository::commit_with_validator

    async fn[V : PolicyValidator] Repository::commit_with_validator(self : Repository, author : String, timestamp : UInt64, message : String, validator : V) -> ObjectId

    Repository::create_branch

    async fn Repository::create_branch(self : Repository, name : String) -> ObjectId

    Repository::diff

    async fn Repository::diff(self : Repository, mode : DiffMode, paths? : Array[String]) -> String

    Repository::get_object

    async fn Repository::get_object(self : Repository, id : ObjectId) -> VcsObject

    Repository::head

    async fn Repository::head(self : Repository) -> ObjectId?

    Repository::head_ref_name

    async fn Repository::head_ref_name(self : Repository) -> String

    Repository::load_index

    async fn Repository::load_index(self : Repository) -> Index

    Repository::log

    async fn Repository::log(self : Repository, max_count? : Int) -> Array[(ObjectId, Commit)]

    Repository::make_candidate

    async fn Repository::make_candidate(self : Repository, author : String, timestamp : UInt64, message : String) -> CommitCandidate

    Repository::read_ref

    async fn Repository::read_ref(self : Repository, name : String) -> ObjectId?

    Repository::root

    fn Repository::root(self : Repository) -> String

    Repository::status

    async fn Repository::status(self : Repository) -> Array[String]

    Repository::switch_branch

    async fn Repository::switch_branch(self : Repository, name : String) -> SwitchPlan

    Repository::switch_plan

    async fn Repository::switch_plan(self : Repository, name : String) -> SwitchPlan

    RequiredPolicy

    pub struct RequiredPolicy {
    name : String
    version : String
    module_digest : String
    component : String
    manifest : String
    granted_capabilities : Array[String]
    } derive(ToJson,
    FromJson
    )

    SwitchPlan

    pub(all) struct SwitchPlan {
    from_ref : String
    target_ref : String
    from_commit : String?
    target_commit : String
    additions : Array[String]
    replacements : Array[String]
    deletions : Array[String]
    } derive(ToJson)

    SwitchPlan::to_json

    fn SwitchPlan::to_json(SwitchPlan) -> Json

    TransferStats

    pub struct TransferStats {
    requests : UInt64
    received_objects : UInt64
    received_bytes : UInt64
    cached_objects : UInt64
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    TransferStats::equal

    TransferStats::not_equal

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

    TransferStats::to_json

    Tree

    pub(all) struct Tree {
    entries : Array[TreeEntry]
    } derive(Eq,
    Debug
    )

    Tree::equal

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

    Tree::new

    fn Tree::new(entries : Array[TreeEntry]) -> Tree raise VcsError

    Tree::not_equal

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

    Tree::to_repr

    TreeEntry

    pub(all) struct TreeEntry {
    name : String
    kind : TreeEntryKind
    object_id : ObjectId
    } derive(Eq,
    Debug
    )

    TreeEntry::equal

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

    TreeEntry::not_equal

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

    TreeEntryKind

    pub(all) enum TreeEntryKind {
    BlobEntry
    TreeEntry
    } derive(Eq,
    Debug
    )

    TreeEntryKind::equal

    TreeEntryKind::not_equal

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

    VcsObject

    pub(all) enum VcsObject {
    BlobObject(Blob)
    TreeObject(Tree)
    CommitObject(Commit)
    } derive(Eq,
    Debug
    )

    VcsObject::equal

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

    VcsObject::not_equal

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

    clone_repository

    async fn clone_repository(remote : String, destination : String, policy_config? : String, fetch_events? : Bool) -> Repository

    decode_object

    fn decode_object(encoded : Bytes) -> VcsObject raise

    decode_receive_request

    fn decode_receive_request(bytes : Bytes) -> ReceiveRequest raise

    encode_object

    fn encode_object(object : VcsObject) -> Bytes raise VcsError

    encode_receive_request

    fn encode_receive_request(request : ReceiveRequest) -> Bytes raise

    find_repository_root

    async fn find_repository_root(start : String) -> String

    init_repository

    async fn init_repository(root : String, policy_config? : String) -> Repository

    install_receive_policy

    async fn install_receive_policy(server : Repository, text : String, initialize? : Bool) -> Unit

    normalize_repository_path

    fn normalize_repository_path(path : String) -> String raise

    object_id_for

    fn object_id_for(object : VcsObject) -> ObjectId raise VcsError

    object_id_for_bytes

    fn object_id_for_bytes(encoded : Bytes) -> ObjectId

    parse_policy_context

    fn parse_policy_context(text : String) -> PolicyContext raise

    prepare_receive_request

    async fn prepare_receive_request(source : Repository, ref_name : String, expected_old : ObjectId?, target : ObjectId) -> ReceiveRequest

    receive_bundle_file

    async fn receive_bundle_file(server : Repository, path : String) -> ReceiveReport

    receive_candidate

    async fn receive_candidate(server : Repository, request : ReceiveRequest) -> ReceiveReport

    run_cli

    async fn run_cli(argv : ArrayView[String]) -> Unit

    validate_policies

    async fn validate_policies(candidate : CommitCandidate, context : PolicyContext, hook? : String) -> EngineDecision