A MoonBit project manifest and supply-chain policy auditor.
Dependencies
moon add Noverberrain/moonmodguardmoon test
moon run cmd/mainMoonModGuard demo
project=wyc060514/moonmodguard
dependencies=2
risks=0
--- markdown ---
# MoonModGuard Audit Report///|
test "audit a project" {
let manifest = match @moonmodguard.parse_mod(
"name = \"wyc060514/tool\"\nlicense = \"Apache-2.0\"\nreadme = \"README.md\"\nrepository = \"https://example.test/repo\"",
) {
Ok(value) => value
Err(err) => fail(@moonmodguard.format_error(err))
}
let report = @moonmodguard.evaluate_policy(
@moonmodguard.project_from(manifest, []),
@moonmodguard.default_policy(),
)
assert_eq(report.risk_count, 0)
}# Audit a moon.mod file, output Markdown report
moon run cmd/main -- moon.mod
# Output JSON instead of Markdown
moon run cmd/main -- moon.mod --json
# Use EnhancedPolicy with trust grading
moon run cmd/main -- moon.mod --enhancedlet manifest = match @moonmodguard.parse_mod(mod_text) {
Ok(m) => m
Err(_) => abort("parse error")
}
let project = @moonmodguard.project_from(manifest, [])
let report = @moonmodguard.evaluate_enhanced(project, @moonmodguard.EnhancedPolicy::default())
println(@moonmodguard.render_full_report(report))let policy = @moonmodguard.TrustPolicy::new()
.trust("moonbitlang/")
.allow("github.com/")
.block("bad-domain/")
.default_level(@moonmodguard.Blocked)
let level = policy.check("moonbitlang/x")
// level is Trustedlet snapshots = [
@moonmodguard.ProjectSnapshot::{ module_manifest: m1, packages: [] },
@moonmodguard.ProjectSnapshot::{ module_manifest: m2, packages: [] },
]
let summary = @moonmodguard.batch_audit(snapshots)
println(@moonmodguard.render_batch_summary(summary))import { "moonbitlang/x@0.4.46" @x }let json = @moonmodguard.render_json(report)
// All string values are properly escaped (quotes, backslashes, newlines, tabs)let sarif = @moonmodguard.render_sarif(report, "MoonModGuard")
// Valid SARIF v2.1.0 JSON for GitHub Code Scanning upload# Recursively audit all packages under a directory
moon run cmd/main -- --workspace .let pkgs = @moonmodguard.discover_packages(".") raise
let summary = @moonmodguard.audit_workspace(".") raise
println(@moonmodguard.render_batch_summary(summary))# Output as GitHub Actions workflow commands
moon run cmd/main -- moon.mod --annotationslet mooncake = match @moonmodguard.parse_mooncake(yaml_text) {
Ok(m) => m
Err(_) => abort("parse error")
}
let diags = @moonmodguard.check_mooncake_consistency(mod_manifest, mooncake)
// Reports name/version/license/repository/description/keywords mismatcheslet report = @moonmodguard.full_audit(manifest, packages)
// Combines evaluate_policy with:
// check_unused_dependency, check_missing_versioned_dep,
// check_version_consistency, check_version_conflicts,
// check_self_dependency// Same source declared with two versions -> "version-conflict"
let conflicts = @moonmodguard.check_version_conflicts(manifest, packages)
// Module imports its own name -> "self-dependency"
let self = @moonmodguard.check_self_dependency(manifest)@moonmodguard.is_valid_repository_url("https://github.com/a/b") // true
@moonmodguard.is_valid_repository_url("not-a-url") // falsepub(all) struct AuditReport {
project : ProjectModel
diagnostics : Array[Diagnostic]
risk_count : Int
dependency_count : Int
} derive(Eq)pub(all) struct AuditSummary {
total_projects : Int
total_diagnostics : Int
projects_clean : Int
projects_risky : Int
} derive(Eq)pub(all) struct DiscoveredPackage {
dir : String
mod_text : String
pkg_text : String
mooncake_text : String?
} derive(Eq)pub(all) struct EnhancedPolicy {
trust_policy : TrustPolicy
require_readme : Bool
require_repository : Bool
require_license : Bool
require_description : Bool
min_description_length : Int
require_keywords : Bool
min_keywords : Int
require_version : Bool
max_dependencies : Int
} derive(Eq)pub(all) struct ModuleManifest {
name : String
version : String
readme : String
repository : String
license : String
keywords : Array[String]
description : String
imports : Array[Dependency]
} derive(Eq)pub(all) struct Policy {
allowed_licenses : Array[String]
trusted_prefixes : Array[String]
require_readme : Bool
require_repository : Bool
require_license : Bool
require_description : Bool
min_description_length : Int
require_keywords : Bool
min_keywords : Int
require_valid_version : Bool
require_valid_repository : Bool
} derive(Eq)pub(all) struct PositionedDiagnostic {
code : String
message : String
severity : String
file : String
line : Int
} derive(Eq)pub(all) struct ProjectModel {
name : String
version : String
license : String
readme : String
repository : String
description : String
keywords : Array[String]
dependencies : Array[Dependency]
} derive(Eq)pub(all) struct ProjectSnapshot {
module_manifest : ModuleManifest
packages : Array[PackageManifest]
} derive(Eq)fn check_missing_versioned_dep(manifest : ModuleManifest, packages : Array[PackageManifest]) -> Array[Diagnostic]fn check_mooncake_consistency(mod_manifest : ModuleManifest, mooncake : MooncakeManifest) -> Array[Diagnostic]fn check_unused_dependency(manifest : ModuleManifest, packages : Array[PackageManifest]) -> Array[Diagnostic]fn check_version_conflicts(manifest : ModuleManifest, packages : Array[PackageManifest]) -> Array[Diagnostic]fn is_risky_license(license : String) -> Boolfn is_valid_repository_url(repository : String) -> Boolfn positioned_diagnostic(code : String, message : String, file : String, line : Int) -> PositionedDiagnosticfn report_from(name : String, license : String, readme : String, repository : String, description : String, keywords : Array[String], deps : Array[Dependency]) -> AuditReportfn validate_name(name : String) -> Boolfn validate_version(version : String) -> BoolA MoonBit project manifest and supply-chain policy auditor.
Dependencies