moonseal

MoonBit test adequacy and release quality gate toolkit.

moonbit
testing
quality-gate
mutation-testing
release-check
moon add LL728/moonseal@0.1.6
Download zip
Author
Version
0.1.6
License
Apache-2.0
Last updated
yesterday
Downloads
23
README

#MoonSeal

MoonSeal is a MoonBit release-readiness checker and test adequacy gate. It scans a MoonBit repository, reports package-level testing signals, executes optional mutation and coverage checks, and applies a configurable release policy before a package, competition submission, or public release.

#Requirements and installation

MoonSeal targets the MoonBit JavaScript/Node.js backend because it reads the project filesystem and launches moon test. The repository CI is pinned to MoonBit 0.10.3+16975d007.

On Linux or macOS:

curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash export PATH="$HOME/.moon/bin:$PATH" moon version --all

On Windows PowerShell:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser irm https://cli.moonbitlang.com/install/powershell.ps1 | iex $env:Path = "$env:USERPROFILE\.moon\bin;$env:Path" moon version --all

The version output should contain MoonBit 0.10.3 (the exact CI build is 0.10.3+16975d007). Then clone either public repository:

git clone https://github.com/LL728/moonseal.git cd moonseal

GitLink competition repository: https://gitlink.org.cn/LL1266/moonseal.

#Local verification

Run the fast checks first:

moon check --target js moon build --target js moon fmt --check moon info git diff --exit-code moon test --target js

Run the structural examples:

moon run --target js cmd/main -- scan fixtures/well_tested moon run --target js cmd/main -- gate fixtures/well_tested moon run --target js cmd/main -- gate fixtures/untested moon run --target js cmd/main -- mutants fixtures/mutation_targets moon run --target js cmd/main -- explain fixtures/well_tested moon run --target js cmd/main -- api fixtures/well_tested moon run --target js cmd/main -- manifest fixtures/well_tested

The well-tested fixture must print MoonSeal gate: PASS; the intentionally untested fixture must print MoonSeal gate: FAIL.

Run dynamic mutation and coverage checks when a measured gate is required:

moon run --target js cmd/main -- scan fixtures/well_tested --mutate --coverage moon run --target js cmd/main -- gate fixtures/well_tested --mutate --coverage

--mutate runs the test suite once for each candidate and reports killed and survived mutants. --coverage runs MoonBit coverage and parses its summary. Both measurements are restored before the command exits.

#Baselines, dashboards, and CI findings

Create a small, reviewable quality baseline after a release-quality scan:

moon run --target js cmd/main -- snapshot . --output moonseal-baseline.json moon run --target js cmd/main -- compare . --baseline moonseal-baseline.json moon run --target js cmd/main -- recommend .

The baseline stores stable quality metrics and package summaries. A comparison fails when project tests, mutation score, coverage, or package test counts decrease, or when warnings increase. Source/API growth is reported as a change but is not incorrectly treated as a failure. Use --mutate and --coverage with compare when the baseline contains measured values.

For a release dashboard or GitHub Code Scanning-compatible report, use the CLI or library APIs:

moon run --target js cmd/main -- sarif . --output moonseal.sarif

The library APIs dashboard, health_score, render_dashboard, and render_sarif are also available to integrations that already have a QualityReport and GateResult.

Public API coverage and historical quality evidence are first-class commands:

moon run --target js cmd/main -- api . moon run --target js cmd/main -- trend . --history _build/quality-history.json moon run --target js cmd/main -- manifest . --output _build/release-manifest.json

api associates public declarations with package test files and makes untested symbols visible. trend appends a versioned QualitySnapshot to a JSON archive and reports changes in tests, mutation score, coverage, and warnings. Integrations can normalize external LCOV and Cobertura reports with parse_external_coverage.

manifest creates a release-evidence artifact containing documentation, license, CI, test, API-coverage, and gate results. It can be stored as JSON or rendered as a reviewer-friendly text report.

#Configurable policy

Create moonseal.json in the project being checked:

{ "min_project_tests": 5, "require_package_tests": true, "require_tests_for_mutants": true, "require_readme": true, "require_license": true, "require_ci": true, "min_mutation_score": 60, "min_coverage": 70 }

The gate checks the README path declared by moon.mod, the root LICENSE file, and a .github/workflows/*.yml or .yaml workflow. Mutation and coverage thresholds are enforced against measured values; invoke gate with --mutate and/or --coverage when those thresholds are non-zero.

#Continuous integration

.github/workflows/ci.yml follows the MoonBit community workflow shape. It runs on Ubuntu, macOS, and Windows, installs the pinned MoonBit 0.10.3 toolchain, checks, builds, checks formatting and generated interfaces, runs tests, and executes both structural and dynamic quality-gate examples. The workflow has read-only contents permission and checks out code with persisted credentials disabled.

#Repository identity

  • GitLink: https://gitlink.org.cn/LL1266/moonseal
  • GitHub mirror: https://github.com/LL728/moonseal
  • Mooncakes package: LL728/moonseal
  • Proposal source: docs/competition/proposal.md
  • Proposal PDF: docs/competition/MoonSeal项目申报书.pdf
  • Baseline format: QualitySnapshot schema version 1; commit the generated moonseal-baseline.json when a project wants regression protection.
  • Acceptance checklist: docs/acceptance-checklist.md
  • Closeout notes: docs/closeout.md

#License

Apache-2.0. See LICENSE.

#
ApiCoverage

pub(all) struct ApiCoverage {
entries : Array[ApiCoverageEntry]
summary : ApiCoverageSummary
} derive(Eq)

Public API coverage for a scanned project.

#
ApiCoverageEntry

pub(all) struct ApiCoverageEntry {
name : String
kind : String
package_path : String
tested : Bool
test_files : Array[String]
} derive(Eq)

The test evidence associated with one public API symbol.

#
ApiCoverageSummary

pub(all) struct ApiCoverageSummary {
total : Int
covered : Int
uncovered : Int
percentage : Int
} derive(Eq)

Aggregate public-API test coverage.

#
ApiSymbol

pub(all) struct ApiSymbol {
name : String
kind : String
package_path : String
} derive(Eq)

A public symbol discovered in a generated MoonBit interface.
impl ToJson for ApiSymbol

#
ExternalCoverage

pub(all) struct ExternalCoverage {
format : String
total : Int
covered : Int
percentage : Int
files : Array[FileCoverage]
} derive(Eq)

A normalized report from a portable coverage interchange format.

#
FileCoverage

pub(all) struct FileCoverage {
path : String
covered : Int
total : Int
percentage : Int
} derive(Eq)

#
GatePolicy

pub(all) struct GatePolicy {
min_project_tests : Int
require_package_tests : Bool
require_tests_for_mutants : Bool
require_readme : Bool
require_license : Bool
require_ci : Bool
min_mutation_score : Int
min_coverage : Int
} derive(Eq)

#
GateResult

pub(all) struct GateResult {
passed : Bool
failures : Array[String]
warnings : Array[String]
} derive(Eq)

#
ImportInfo

pub(all) struct ImportInfo {
target : String
alias_name : String
owner : String
} derive(Eq)

#
ModuleMeta

pub(all) struct ModuleMeta {
name : String
version : String
readme : String
repository : String
license : String
} derive(Eq)

#
MutationCandidate

pub(all) struct MutationCandidate {
id : String
path : String
line : Int
kind : String
original : String
replacement : String
} derive(Eq)

#
PackageQuality

pub(all) struct PackageQuality {
path : String
source_count : Int
test_count : Int
public_api_count : Int
warnings : Array[String]
} derive(Eq)

#
PackageSnapshot

pub(all) struct PackageSnapshot {
path : String
source_count : Int
test_count : Int
public_api_count : Int
warning_count : Int
} derive(Eq)

A compact, versioned record of the quality signals that matter in CI. It is deliberately smaller than QualityReport, so it remains stable when the analyzer gains more diagnostic detail.

#
QualityDashboard

pub(all) struct QualityDashboard {
project : String
version : String
score : Int
label : String
source_files : Int
test_files : Int
package_count : Int
mutation_candidates : Int
mutation_score : Int
coverage_percentage : Int
warning_count : Int
recommendation_count : Int
risks : Array[String]
} derive(Eq)

A compact dashboard model for release pages and CI summaries.

#
QualityHistory

pub(all) struct QualityHistory {
schema_version : Int
snapshots : Array[QualitySnapshot]
} derive(Eq)

Historical quality snapshots are append-only release evidence.

#
QualityRecommendation

pub(all) struct QualityRecommendation {
id : String
priority : String
title : String
detail : String
} derive(Eq)

An actionable hint generated from observable quality signals.

#
QualityReport

pub(all) struct QualityReport {
name : String
version : String
readme : String
repository : String
license : String
packages : Array[PackageQuality]
imports : Array[ImportInfo]
source_files : Array[SourceFile]
test_files : Array[TestFile]
mutation_candidates : Array[MutationCandidate]
warnings : Array[String]
mutation_score : Int
mutants_killed : Int
mutants_tested : Int
survived_mutants : Array[MutationCandidate]
coverage_total_percentage : Int
coverage_files : Array[FileCoverage]
} derive(Eq)

#
QualitySnapshot

pub(all) struct QualitySnapshot {
schema_version : Int
name : String
version : String
source_files : Int
test_files : Int
package_count : Int
mutation_candidates : Int
mutants_tested : Int
mutation_score : Int
coverage_total_percentage : Int
warning_count : Int
packages : Array[PackageSnapshot]
} derive(Eq)

A serializable quality baseline suitable for committing to a repository.

#
ReleaseCheck

pub(all) struct ReleaseCheck {
id : String
status : String
detail : String
} derive(Eq)

A stable release evidence record for package publication and acceptance.

#
ReleaseManifest

pub(all) struct ReleaseManifest {
schema_version : Int
project : String
version : String
repository : String
source_files : Int
test_files : Int
api_coverage : Int
gate_passed : Bool
failed_checks : Int
checks : Array[ReleaseCheck]
} derive(Eq)

A machine-readable summary of the checks that support a release decision.

#
SealError

pub(all) enum SealError {
MissingProject(String)
MissingManifest(String)
FileReadFailed(String)
} derive(Eq)

#
SnapshotComparison

pub(all) struct SnapshotComparison {
passed : Bool
baseline_version : String
current_version : String
deltas : Array[SnapshotDelta]
regressions : Array[SnapshotRegression]
improvements : Array[SnapshotDelta]
summary : String
} derive(Eq)

The result of comparing a scan with a committed quality baseline.

#
SnapshotDelta

pub(all) struct SnapshotDelta {
metric : String
baseline : Int
current : Int
delta : Int
direction : String
} derive(Eq)

One metric changed between a baseline and the current scan.

#
SnapshotRegression

pub(all) struct SnapshotRegression {
metric : String
baseline : Int
current : Int
delta : Int
message : String
} derive(Eq)

A quality regression that should be visible in a pull request.

#
SourceFile

pub(all) struct SourceFile {
path : String
package_path : String
is_test : Bool
digest : String
mutation_points : Int
} derive(Eq)

#
TestFile

pub(all) struct TestFile {
path : String
package_path : String
kind : String
} derive(Eq)

impl ToJson for TestFile

#
TrendReport

pub(all) struct TrendReport {
sample_count : Int
first_version : String
latest_version : String
source_file_delta : Int
test_file_delta : Int
mutation_score_delta : Int
coverage_delta : Int
warning_delta : Int
direction : String
} derive(Eq)

Directional changes between the first and latest recorded snapshots.

#
analyze_api_coverage

fn analyze_api_coverage(root : String, report : QualityReport) -> ApiCoverage

Associate generated public declarations with test files in the same package. This is intentionally evidence-based: a symbol is covered when a package test mentions its name, making the result explainable and useful for directing stronger behavioral tests.

#
analyze_project

fn analyze_project(path : String) -> Result[QualityReport, SealError]

#
append_history

fn append_history(history : QualityHistory, snapshot : QualitySnapshot) -> QualityHistory

Append a snapshot without mutating the caller's history value.

#
compare_snapshot

fn compare_snapshot(current : QualitySnapshot, baseline : QualitySnapshot) -> SnapshotComparison

Compare quality signals. A decrease in tests, mutation score, coverage, or package-level test count is a regression; more warnings are also treated as a regression. Source and public API changes are reported but are neutral.

#
dashboard

fn dashboard(report : QualityReport) -> QualityDashboard

Create a dashboard without running any additional commands.

#
default_policy

fn default_policy() -> GatePolicy

#
evaluate_gate

fn evaluate_gate(report : QualityReport, policy : GatePolicy) -> GateResult

#
format_error

fn format_error(err : SealError) -> String

#
has_failure

fn has_failure(result : GateResult, failure : String) -> Bool

#
has_regression

fn has_regression(result : SnapshotComparison, metric : String) -> Bool

Return whether a named regression exists.

#
has_warning

fn has_warning(report : QualityReport, warning : String) -> Bool

#
health_label

fn health_label(score : Int) -> String

Provide a stable label for simple dashboards.

#
health_score

fn health_score(report : QualityReport) -> Int

Return a small health score for dashboards. The score is explainable and intentionally does not replace the strict gate.

#
load_policy

fn load_policy(root : String) -> GatePolicy

#
make_history

fn make_history(snapshots : Array[QualitySnapshot]) -> QualityHistory

Create an empty, versioned history document from an optional seed list.

#
make_release_manifest

fn make_release_manifest(report : QualityReport, gate : GateResult, api : ApiCoverage) -> ReleaseManifest

Build a release evidence manifest from one project scan.

#
make_snapshot

fn make_snapshot(report : QualityReport) -> QualitySnapshot

Build a baseline from a quality report.

#
manifest_check

fn manifest_check(manifest : ReleaseManifest, id : String) -> ReleaseCheck

Find one named check, returning a failed result when the id is absent.

#
manifest_check_ids

fn manifest_check_ids(manifest : ReleaseManifest) -> Array[String]

Return all check ids in the order shown to a reviewer.

#
manifest_failed_ids

fn manifest_failed_ids(manifest : ReleaseManifest) -> Array[String]

Return failed check ids in stable manifest order.

#
manifest_failure_summary

fn manifest_failure_summary(manifest : ReleaseManifest) -> String

Explain failed checks as a comma-separated reviewer hint.

#
manifest_has_check

fn manifest_has_check(manifest : ReleaseManifest, id : String) -> Bool

Return whether the manifest contains a named check.

#
manifest_is_complete

fn manifest_is_complete(manifest : ReleaseManifest) -> Bool

Return whether all expected evidence categories are represented.

#
manifest_is_ready

fn manifest_is_ready(manifest : ReleaseManifest) -> Bool

Return whether every release evidence check passed.

#
manifest_pass_rate

fn manifest_pass_rate(manifest : ReleaseManifest) -> Int

Return the percentage of evidence checks that passed.

#
manifest_status

fn manifest_status(manifest : ReleaseManifest) -> String

Return a stable one-word status for dashboards and CI annotations.

#
mutation_plan

fn mutation_plan(report : QualityReport) -> Array[MutationCandidate]

#
parse_external_coverage

fn parse_external_coverage(input : String, format : String) -> Result[ExternalCoverage, String]

Parse LCOV or Cobertura line coverage into MoonSeal's common model.

#
parse_history

fn parse_history(input : String) -> Result[QualityHistory, String]

Parse an append-only history document.

#
parse_moon_mod

fn parse_moon_mod(input : String) -> ModuleMeta

#
parse_pkg_imports

fn parse_pkg_imports(package_path : String, input : String) -> Array[ImportInfo]

#
parse_release_manifest

fn parse_release_manifest(input : String) -> Result[ReleaseManifest, String]

Parse a release manifest so a downstream publisher can enforce its checks.

#
parse_snapshot

fn parse_snapshot(input : String) -> Result[QualitySnapshot, String]

Read a baseline JSON document without making the caller depend on JS APIs.

#
read_history

fn read_history(path : String) -> Result[QualityHistory, String]

Read a history file created by write_history.

#
read_release_manifest

fn read_release_manifest(path : String) -> Result[ReleaseManifest, String]

Read a release manifest produced by write_release_manifest.

#
read_snapshot

fn read_snapshot(path : String) -> Result[QualitySnapshot, String]

Read a baseline file produced by write_snapshot.

#
recommendations

fn recommendations(report : QualityReport) -> Array[QualityRecommendation]

Generate prioritized remediation advice from a report.

#
render_api_coverage

fn render_api_coverage(value : ApiCoverage) -> String

Render API coverage as a concise CI report.

#
render_comparison

fn render_comparison(result : SnapshotComparison) -> String

Render a human-readable comparison for CI logs and pull requests.

#
render_dashboard

fn render_dashboard(value : QualityDashboard) -> String

Render a dashboard for release notes or a job summary.

#
render_external_coverage

fn render_external_coverage(report : ExternalCoverage) -> String

Render normalized external coverage for a CI log.

#
render_gate

fn render_gate(result : GateResult) -> String

#
render_history

fn render_history(report : TrendReport) -> String

Render a concise trend suitable for CI logs and release notes.

#
render_mutants

fn render_mutants(candidates : Array[MutationCandidate]) -> String

#
render_recommendations

fn render_recommendations(items : Array[QualityRecommendation]) -> String

Render remediation advice for terminal output.

#
render_release_manifest

fn render_release_manifest(manifest : ReleaseManifest) -> String

Render an evidence manifest for a human reviewer.

#
render_release_manifest_markdown

fn render_release_manifest_markdown(manifest : ReleaseManifest) -> String

Render a compact Markdown table suitable for a release PR description.

#
render_report

fn render_report(report : QualityReport) -> String

#
render_sarif

fn render_sarif(report : QualityReport, gate : GateResult) -> String

Emit SARIF 2.1.0 so GitHub code scanning or another CI viewer can display MoonSeal warnings and gate failures as structured findings.

#
run_coverage_analysis

fn run_coverage_analysis(root : String) -> (Int, Array[FileCoverage])

#
run_mutation_testing

fn run_mutation_testing(root : String, candidates : Array[MutationCandidate]) -> (Int, Int, Int, Array[MutationCandidate])

#
summarize

fn summarize(report : QualityReport) -> String

#
summarize_history

fn summarize_history(history : QualityHistory) -> TrendReport

Summarize changes from the first sample to the latest sample.

#
write_history

fn write_history(path : String, history : QualityHistory) -> Result[Unit, String]

Write a stable, human-readable history archive.

#
write_release_manifest

fn write_release_manifest(path : String, manifest : ReleaseManifest) -> Result[Unit, String]

Write a release manifest for CI artifacts or a submission archive.

#
write_snapshot

fn write_snapshot(path : String, snapshot : QualitySnapshot) -> Result[Unit, String]

Write a baseline file. The parent directory must already exist.

#
write_text

fn write_text(path : String, content : String) -> Result[Unit, String]

Write a generated integration artifact using the same JS filesystem bridge as snapshots. Keeping this operation in the library makes CLI wrappers and host integrations follow the same error contract.