Sign in

    moonportcheck

    Identity-based file delivery planning and independent plan auditing, with Windows portability checks.

    delivery
    planning
    audit
    portability
    cli
    Download zip
    Version
    0.3.0
    License
    Apache-2.0
    Last updated
    8 days ago
    Downloads
    27

    No dependencies

    #MoonPortCheck

    用 MoonBit 编写的文件交付规划与独立验证库,附离线 CLI。给定初始快照和 Copy/Move 意图,检查每步前置条件及最终文件来源;同时保留跨平台路径预检能力。

    当前源码版本:0.3.0。 基于初态来源身份规划与审计交付:同样的路径集合,也能分辨正确交换和错误覆盖。旧路径检查、glob、快照差异及基线继续保留。使用与语义、案例及生态差异、验收与复现、实施账本。发布状态以远端实际记录为准。

    moonportcheck plan examples/delivery/swap/spec.json --format json moonportcheck audit-plan examples/delivery/swap/spec.json plan.json --format markdown

    源码运行时加前缀 node bin/moonportcheck.mjs,将第一条命令的stdout保存为plan.json再审计。仅生成和验证计划,绝不执行Copy/Move/Mkdir。需要真实文件状态时先用已有snapshot命令采集,再在Spec中引用对应文件。

    固定目标规则为 portable-windows-v1。既有发布与CI的历史记录见 v0.2 账本 和 发布审计,不能替代v0.3本地验证。

    CLI ZIP 下载入口:GitHub v0.3.0 Release。解包后以 node bin/moonportcheck.mjs --help 运行,需 Node.js 24,无需 MoonBit 编译器。归档附带 LICENSE、使用文档、样例与文件校验和;库发布入口为 Mooncakes。发布验证状态以发布审计和远端实际记录为准。

    results/A.csv + results/a.csv → PATH_CASE_COLLISION assets/CON.txt → NAME_RESERVED notes/report.md. → NAME_TRAILING_DOT_SPACE

    核心检查、JSON 解析、冲突分组和报告渲染均由纯 MoonBit 完成,仅依赖标准库。Node.js 适配层读取文件名、文件类型及 UTF-8 清单,不读取被扫描文件的内容,不修改输入目录。

    #从源码运行

    要求 Node.js 24,MoonBit 使用项目隔离的 v0.10.14。不需要 npm install,也不要求修改全局 MoonBit。Windows 命令从本项目目录运行:

    pwsh -File scripts/toolchain.ps1 -Install pwsh -File run_build.ps1 node bin/moonportcheck.mjs --version node bin/moonportcheck.mjs check examples/windows-problems.json --format text

    Linux 的等价入口:

    bash scripts/toolchain.sh install bash run_build.sh node bin/moonportcheck.mjs --version node bin/moonportcheck.mjs check examples/windows-problems.json --format text

    最后一个命令发现问题时退出 1,这是预期行为。首次安装访问官方完整版本 0.10.14%2B7d59c7ec9 的固定归档地址,并核对 scripts/toolchain.lock.json 中的 SHA-256;下载或校验失败会停止,不回退 latest。安装器在 Linux 上恢复经过校验的原生 ELF 工具的执行权限。保留 .toolchains 缓存可用于离线恢复;构建和检查入口不自动联网安装。完整版本、归档来源与校验值以锁文件及安装器输出为准。

    node scripts/cold-install.mjs 使用新的临时安装目录和空下载缓存验证冷安装,保存下载哈希、完整版本及 core 构建证据。MOONPORT_TOOLCHAIN_HOME 和 MOONPORT_TOOLCHAIN_CACHE 可显式选择隔离目录;CI 直接复用其冷安装结果。CI 检查精确 PR 提交,只对 main push 和 PR 更新运行,常规证据保留 30 天。

    #检查目录或清单

    moonportcheck scan ROOT [--config FILE] [--exclude PATTERN]... [--baseline FILE] [--fail-on new] [--format text|json|markdown|sarif] moonportcheck snapshot ROOT [--config FILE] [--exclude PATTERN]... moonportcheck check MANIFEST [--config FILE] [--exclude PATTERN]... [--format text|json|markdown|sarif] moonportcheck diff BEFORE.json AFTER.json [--format text|json|markdown] moonportcheck baseline create REPORT.json moonportcheck rules [--format text|json] moonportcheck explain CODE [--format text|json] moonportcheck --help moonportcheck --version

    源码环境用 node bin/moonportcheck.mjs 代替 moonportcheck;打包后的 bin 入口同名。

    snapshot ROOT 把真实目录导出为固定 JSON 快照文档({"format":"moonportcheck-snapshot","version":1,...},不接受 --format):完整导出退出 0、扫描不完整退出 3。check MANIFEST 同时接受原数组清单与该快照文档:检查快照时继承其排除范围,--config/--exclude 的额外排除只能缩小范围,不完整快照始终保持不完整(退出 3),报告 source 为 "snapshot"。diff BEFORE.json AFTER.json 比较两份快照:退出 0=无变化、1=有变化、2=文档损坏或范围不同、3=任一输入不完整,绝不推测重命名或内容变化。

    # 实际目录:包含隐藏项,输出相对于根目录的路径。 node bin/moonportcheck.mjs scan ./delivery --format text # 清单:可在 Windows 上预检本机无法创建的 Linux 文件名。 node bin/moonportcheck.mjs check examples/windows-problems.json --format json

    清单是 UTF-8 JSON 数组;path 为使用 / 分隔的相对路径,kind 为 file 或 directory。目录名不附加尾部 /。

    [ { "path": "README.md", "kind": "file" }, { "path": "results/实验记录.csv", "kind": "file" } ]

    中间目录不必显式列出。反斜杠不会被转换为分隔符。合法清单里的非法路径属于规则发现;损坏 JSON 或字段类型错误属于输入错误。

    可以用 --exclude PATTERN(可重复)或 --config FILE 缩小检查范围,两者取并集;模式语法与含义见 PATTERNS.md。配置文件是带版本号的 JSON,schema_version 必须为 1:

    { "schema_version": 1, "exclude": ["**/cache", "*.tmp"] }

    被排除条目不进入审计,也不产生诊断;被整棵排除的目录不再枚举其子树(扫描)。任何人不得隐式读取 .gitignore。配置结构错误退出 2,无法读取或非法 UTF-8 分别退出 3 与 2。

    退出码含义
    0检查完整,已覆盖规则未发现问题
    1检查完整,存在路径或冲突问题
    2参数、编码或清单结构错误
    3I/O 失败或扫描不完整,优先于 1

    报告写入标准输出。v0.2 CLI 的审计和错误 JSON 明确使用 schema 2。审计报告保留原有平面字段,详细诊断增加原始来源、成员计数和稳定组身份;扫描问题独立放在 scan_issues,不再混入 diagnostics。scope、excluded_entries、pruned_directories 在 M06 起反映实际排除范围:scope 为去重排序后的有效模式,excluded_entries 只统计已知输入中实际被排除的条目,pruned_directories 列出最顶层被剪枝目录。诊断分组与排序固定,不附时间戳。错误使用独立错误响应,不输出误导性的空成功报告。字段与消费迁移见 SCHEMA2.md。

    #作为 MoonBit 库使用

    模块名称为 AlexenderSokolov/moonportcheck,根包提供以下公共接口。正式包发布后使用 moon add AlexenderSokolov/moonportcheck@0.2.0;也可通过 moon.work 引用本地模块。验收脚本创建独立模块、包和工作区验证原 v1 公共接口,公共注册表安装验证单独记录。

    接口用途
    EntryKind:File / Directory路径条目类型
    PathEntry:path、kind输入条目
    parse_manifest(String)返回 Result[Array[PathEntry], InputError]
    audit(Array[PathEntry])返回结构化 Report
    render_json(Report)生成 JSON 报告
    render_text(Report)生成可读文本报告

    这些原接口及 Report 保持 v1 行为,render_json 仍输出 schema 1,已有库消费者无需修改。需要详细报告时,使用不透明的 AuditOptions 及 default_audit_options(),调用 audit_with_options(entries, options) 返回 DetailedReport,再用 render_detailed_json / render_detailed_text 渲染。ScanIssue 与 with_scan_issues 用于附入扫描完整性问题。

    详细诊断的 members 保留全量原始 (path, kind, count),source_examples 最多展示 5 条,不能代替完整成员或组身份;occurrences 保留旧含义。纯库只检查传入集合,不访问文件系统。CLI 使用详细接口汇总来源与扫描完整性。核心库的 JS 与 wasm-gc 行为通过同一组测试和报告比对;新旧接口选择及字段说明见 schema 2 迁移说明。

    #演示与验证

    Windows:

    pwsh -File run_demo.ps1 pwsh -File run_check.ps1 pwsh -File run_acceptance.ps1

    Linux:

    bash run_demo.sh bash run_check.sh bash run_acceptance.sh

    演示会重新构建,再调用真实 CLI 并断言退出码、完整性与诊断编号;不是预先写好的终端截图。

    演示文件展示内容预期退出码
    portable.json中文、空格、点开头名称正常通过0
    windows-problems.json大小写冲突、设备保留名、尾点1
    hierarchy-conflicts.json三次重复、隐含目录大小写冲突、文件与目录冲突1

    run_check 汇总工具链检查、格式检查、构建、双目标核心测试、Node CLI 测试和跨目标报告比对。run_acceptance 包含这些检查,并依次运行演示、十万条路径规模测试、独立库消费及不带编译器的 CLI 运行验证;日志、工具链身份和源码文件哈希保存在 artifacts/acceptance-<平台>-<时间>/。规模测试也可单独运行 node scripts/bench.mjs;时间与内存以当次输出为准。v0.1 本地结果及验证边界见 ACCEPTANCE.md,v0.2 各提交的实际检查和公开 CI 见 执行账本。Mooncakes 发布和十月活动验收仍需后续授权与实际结果。

    #覆盖范围

    完整规则见 RULES.md。当前覆盖 Windows 常见非法名称、设备名、尾点或尾空格、路径结构、重复、ASCII 大小写及文件/目录冲突。

    符号链接和 junction 不跟随;跳过链接、不支持的类型、无法无损解码的名称或读目录失败会使扫描不完整。中文名称原样保留,完整 Unicode 大小写等价、规范化、长路径、8.3 别名及特定文件系统限制不在首版范围内。工具不执行改名,不解析压缩包,也不判断文件内容。

    complete=true 表示本次输入在已覆盖规则内检查完整;清单检查不证明实际目录与清单一致,退出 0 不保证所有 Windows 环境都能成功复制或打开。

    设计与长期维护约定见 PROJECT.md,申报草稿见 APPLICATION.md,版本变更见 CHANGELOG.md。许可证为 Apache-2.0。

    #查询规则原因与建议

    moonportcheck rules --format json moonportcheck explain NAME_RESERVED

    rules 列出 11 个审计规则和 4 个扫描完整性问题;explain CODE 精确匹配编号并显示原因、触发例子和整改建议。两者支持 text/JSON,JSON 为稳定排序的规则数组,查询单条时数组长度为 1。未知编号退出 2,已知规则查询退出 0;这不表示执行了目录检查。

    库还提供 parse_pattern 与 pattern_matches 进行纯路径范围匹配,M06 再以 parse_scope / entry_excluded / audit_with_exclusions 接入配置与 CLI 排除,完整语义见 PATTERNS.md。M07 增加快照模型 Snapshot 与 build_snapshot / parse_snapshot / render_snapshot_json,把唯一排序条目、范围、完整性与扫描问题持久化为可往返的独立 JSON 文档(不含内容、时间戳或主机绝对路径),供后续快照命令与差异比较使用。

    AuditOptions

    pub struct AuditOptions {
    // private fields
    }

    Validated audit settings. Use default_audit_options to create v0.2 settings.

    Baseline

    pub struct Baseline {
    format : String
    schema_version : Int
    profile : String
    rules_version : String
    scope : Array[String]
    groups : Array[BaselineGroup]
    } derive(Eq,
    Debug
    )

    The baseline document: created only from a complete schema 2 audit report, binding the profile, rule version and effective scan scope to its groups.

    Baseline::equal

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

    Baseline::not_equal

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

    Baseline::to_repr

    BaselineChange

    pub struct BaselineChange {
    code : String
    anchor : String
    status : BaselineStatus
    members : Array[SourceMember]
    source_total : Int
    } derive(Eq,
    Debug
    )

    One classified group after comparing a report against a baseline. members and source_total describe the current report state; a resolved group is empty.

    BaselineChange::equal

    BaselineChange::not_equal

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

    BaselineDiff

    pub struct BaselineDiff {
    changes : Array[BaselineChange]
    } derive(Eq,
    Debug
    )

    BaselineDiff::equal

    BaselineDiff::not_equal

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

    BaselineGroup

    pub struct BaselineGroup {
    code : String
    anchor : String
    members : Array[SourceMember]
    source_total : Int
    } derive(Eq,
    Debug
    )

    An immutable group in a baseline document, identified by rule code and the stable path anchor. members is the full member list with per-member counts.

    BaselineGroup::equal

    BaselineGroup::not_equal

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

    BaselineStatus

    pub enum BaselineStatus {
    New
    Existing
    Worsened
    Resolved
    } derive(Eq,
    Debug
    )

    Classification of a diagnostic group relative to a historical baseline.

    BaselineStatus::equal

    BaselineStatus::not_equal

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

    DeliveryAudit

    pub(all) struct DeliveryAudit {
    status : String
    valid : Bool
    first_failed_step : Int
    diagnostics : Array[DeliveryDiagnostic]
    final_entries : Array[DeliveryStateEntry]
    trace : Array[DeliveryTrace]
    } derive(Eq,
    Debug
    )

    DeliveryAudit::equal

    DeliveryAudit::not_equal

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

    DeliveryDiagnostic

    pub(all) struct DeliveryDiagnostic {
    code : String
    path : String
    message : String
    step : Int
    } derive(Eq,
    Debug
    )

    DeliveryDiagnostic::equal

    DeliveryDiagnostic::not_equal

    DeliveryIntent

    type DeliveryIntent derive(Eq,
    Debug
    )

    DeliveryIntent::equal

    DeliveryIntent::not_equal

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

    DeliveryMapping

    pub(all) struct DeliveryMapping {
    mode : String
    source : String
    from : String
    to : String
    } derive(Eq,
    Debug
    )

    DeliveryMapping::equal

    DeliveryMapping::not_equal

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

    DeliveryOperation

    pub(all) struct DeliveryOperation {
    kind : String
    source : String
    from : String
    to : String
    origin : DeliveryOrigin
    } derive(Eq,
    Debug
    )

    DeliveryOperation::equal

    DeliveryOperation::not_equal

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

    DeliveryOrigin

    pub(all) struct DeliveryOrigin {
    root : String
    path : String
    } derive(Eq,
    Debug
    )

    DeliveryOrigin::equal

    DeliveryOrigin::not_equal

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

    DeliveryPlan

    pub(all) struct DeliveryPlan {
    status : String
    basis : String
    operations : Array[DeliveryOperation]
    temporary_paths : Array[String]
    diagnostics : Array[DeliveryDiagnostic]
    } derive(Eq,
    Debug
    )

    DeliveryPlan::equal

    DeliveryPlan::not_equal

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

    DeliverySpec

    pub(all) struct DeliverySpec {
    sources : Array[DeliveryTree]
    target : DeliveryTree
    mappings : Array[DeliveryMapping]
    } derive(Eq,
    Debug
    )

    DeliverySpec::equal

    DeliverySpec::not_equal

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

    DeliveryStateEntry

    pub(all) struct DeliveryStateEntry {
    path : String
    kind : EntryKind
    origin : DeliveryOrigin
    } derive(Eq,
    Debug
    )

    DeliveryStateEntry::equal

    DeliveryStateEntry::not_equal

    DeliveryTrace

    pub(all) struct DeliveryTrace {
    step : Int
    kind : String
    from : String
    to : String
    origin : DeliveryOrigin
    } derive(Eq,
    Debug
    )

    DeliveryTrace::equal

    DeliveryTrace::not_equal

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

    DeliveryTree

    pub(all) struct DeliveryTree {
    id : String
    snapshot : Snapshot
    } derive(Eq,
    Debug
    )

    DeliveryTree::equal

    DeliveryTree::not_equal

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

    DetailedDiagnostic

    pub(all) struct DetailedDiagnostic {
    code : String
    severity : String
    paths : Array[String]
    occurrences : Int
    message : String
    anchor : String
    group_key : String
    members : Array[SourceMember]
    source_examples : Array[SourceMember]
    source_total : Int
    sources_truncated : Bool
    } derive(Eq,
    Debug
    )

    DetailedDiagnostic::equal

    DetailedDiagnostic::not_equal

    DetailedReport

    pub(all) struct DetailedReport {
    schema_version : Int
    profile : String
    source : String
    complete : Bool
    summary : Summary
    diagnostics : Array[DetailedDiagnostic]
    limitations : Array[String]
    scan_issues : Array[ScanIssue]
    scope : Array[String]
    excluded_entries : Int
    pruned_directories : Array[String]
    } derive(Eq,
    Debug
    )

    DetailedReport::equal

    DetailedReport::not_equal

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

    Diagnostic

    pub(all) struct Diagnostic {
    code : String
    severity : String
    paths : Array[String]
    occurrences : Int
    message : String
    } derive(Eq,
    Debug
    )

    Diagnostic::equal

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

    Diagnostic::not_equal

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

    DiffKind

    pub enum DiffKind {
    Added
    Removed
    KindChanged
    CaseChanged
    } derive(Eq,
    Debug
    )

    A kind of change between two snapshots.

    DiffKind::equal

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

    DiffKind::not_equal

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

    DiffKind::to_repr

    EntryKind

    pub(all) enum EntryKind {
    File
    Directory
    } derive(Eq,
    Debug
    )

    A path entry describes a root-relative file or directory, never the scan root.

    EntryKind::equal

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

    EntryKind::not_equal

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

    ExclusionScope

    pub struct ExclusionScope {
    // private fields
    }

    A validated, deduplicated exclusion scope. Build with parse_scope.

    InputError

    pub(all) struct InputError {
    code : String
    message : String
    } derive(Eq,
    Debug
    )

    InputError::equal

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

    InputError::not_equal

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

    PathEntry

    pub(all) struct PathEntry {
    path : String
    kind : EntryKind
    } derive(Eq,
    Debug
    )

    PathEntry::equal

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

    PathEntry::not_equal

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

    PathPattern

    pub struct PathPattern {
    // private fields
    }

    A validated exclusion glob. Construct patterns with parse_pattern.

    Report

    pub(all) struct Report {
    schema_version : Int
    profile : String
    source : String
    complete : Bool
    summary : Summary
    diagnostics : Array[Diagnostic]
    limitations : Array[String]
    } derive(Eq,
    Debug
    )

    Report::equal

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

    Report::not_equal

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

    Report::to_repr

    RuleInfo

    pub(all) struct RuleInfo {
    code : String
    title : String
    reason : String
    examples : Array[String]
    suggestion : String
    } derive(Eq,
    Debug
    )

    Human-readable guidance for an existing audit rule or scan issue.

    RuleInfo::equal

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

    RuleInfo::not_equal

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

    RuleInfo::to_repr

    ScanIssue

    pub(all) struct ScanIssue {
    code : String
    path : String
    message : String
    } derive(Eq,
    Debug
    )

    ScanIssue::equal

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

    ScanIssue::not_equal

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

    Snapshot

    pub struct Snapshot {
    profile : String
    complete : Bool
    scope : Array[String]
    entries : Array[PathEntry]
    scan_issues : Array[ScanIssue]
    } derive(Eq,
    Debug
    )

    A persisted scan state: unique, sorted entries plus the effective scope, completeness and scan issues of the scan that produced them. Snapshots never store file content, timestamps or host-specific absolute paths.

    Snapshot::equal

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

    Snapshot::not_equal

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

    Snapshot::to_repr

    SnapshotChange

    pub struct SnapshotChange {
    kind : DiffKind
    path : String
    paired_with : String
    before_kind : String
    after_kind : String
    } derive(Eq,
    Debug
    )

    SnapshotChange::equal

    SnapshotChange::not_equal

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

    SnapshotDiff

    pub struct SnapshotDiff {
    complete : Bool
    changes : Array[SnapshotChange]
    } derive(Eq,
    Debug
    )

    SnapshotDiff::equal

    SnapshotDiff::not_equal

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

    SourceMember

    pub(all) struct SourceMember {
    path : String
    kind : EntryKind
    count : Int
    } derive(Eq,
    Debug
    )

    SourceMember::equal

    SourceMember::not_equal

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

    Summary

    pub(all) struct Summary {
    entries : Int
    files : Int
    directories : Int
    diagnostic_groups : Int
    scan_issues : Int
    } derive(Eq,
    Debug
    )

    Summary::equal

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

    Summary::not_equal

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

    Summary::to_repr

    audit

    fn audit(entries : Array[PathEntry]) -> Report

    not that it describes every file in a directory or every filesystem rule.

    audit_delivery_plan

    fn audit_delivery_plan(spec : DeliverySpec, plan : DeliveryPlan) -> DeliveryAudit

    audit_snapshot

    fn audit_snapshot(snapshot : Snapshot, extra_scope : Array[String]) -> Result[DetailedReport, InputError]

    Audit a snapshot for the current profile. The snapshot's own effective scope is inherited; any extra exclusions can only shrink the checked set. The snapshot's stored scan issues remain: an incomplete snapshot always stays incomplete. The source is recorded as "snapshot".

    audit_with_exclusions

    fn audit_with_exclusions(entries : Array[PathEntry], options : AuditOptions, scope : ExclusionScope) -> DetailedReport

    Filter input by the scope first, then audit the retained entries. Excluded entries leave the summary and diagnostics but are counted, and the scope, known excluded count and actually pruned directories are recorded.

    audit_with_options

    fn audit_with_options(entries : Array[PathEntry], options : AuditOptions) -> DetailedReport

    Preserve v1 diagnostic meaning and add original input evidence only where needed.

    build_baseline

    fn build_baseline(report : DetailedReport) -> Result[Baseline, InputError]

    Build a baseline from a complete schema 2 audit report. Incomplete reports and non-schema-2 documents are rejected with structured input errors.

    build_snapshot

    fn build_snapshot(entries : Array[PathEntry], scan_issues : Array[ScanIssue], scope : Array[String]) -> Result[Snapshot, InputError]

    Build a canonical snapshot from scanned entries. Duplicated identical entries collapse, a path with conflicting kinds is rejected, and the scope is validated and normalized. A snapshot with no scan issues is complete.

    default_audit_options

    fn default_audit_options() -> AuditOptions

    diff_snapshots

    fn diff_snapshots(before : Snapshot, after : Snapshot) -> Result[SnapshotDiff, InputError]

    Compare the entries of two snapshots. Exact path pairs come first; the remaining entries are then compared by ASCII folding. A case change is only reported when exactly one before entry folds to exactly one after entry with the same kind. Renames and content changes are never inferred.

    diff_with_baseline

    fn diff_with_baseline(baseline : Baseline, report : DetailedReport) -> BaselineDiff

    Classify every diagnostic group of a report against a historical baseline. Groups are associated by rule code plus stable path anchor; members and their counts are compared as multisets. Returns a stable diff document.

    effective_scope_patterns

    fn effective_scope_patterns(scope : ExclusionScope) -> Array[String]

    The normalized scope recorded in reports: unique patterns in ordinal order.

    entry_excluded

    fn entry_excluded(scope : ExclusionScope, entry : PathEntry) -> Bool

    True when any pattern matches the entry. Structurally invalid paths never match (pattern_matches guards on path structure), so they stay in scope.

    explain

    fn explain(code : String) -> RuleInfo?

    Look up an exact, case-sensitive diagnostic code.

    parse_baseline

    fn parse_baseline(text : String) -> Result[Baseline, InputError]

    Parse a baseline document produced by render_baseline_json. Field names are strict so a baseline cannot silently drop a newly added future field.

    parse_delivery_plan

    fn parse_delivery_plan(text : String) -> Result[DeliveryPlan, InputError]

    Strict external plan parser. Operation sequencing and identity are audited separately.

    parse_delivery_spec

    fn parse_delivery_spec(text : String) -> Result[DeliverySpec, InputError]

    Parse structure only; path, namespace and mapping feasibility belong to planning.

    parse_detailed_report

    fn parse_detailed_report(text : String) -> Result[DetailedReport, InputError]

    Parse a schema 2 report document produced by render_detailed_json. The parser is strict about field names and rejects unknown members so a baseline cannot silently drop a newly added report field.

    parse_manifest

    fn parse_manifest(text : String) -> Result[Array[PathEntry], InputError]

    Parse a JSON array of {path, kind} entries. Paths are audited separately.

    parse_pattern

    fn parse_pattern(text : String) -> Result[PathPattern, InputError]

    Parse a case-sensitive exclusion glob. No normalization or extension syntax is inferred.

    parse_scope

    fn parse_scope(patterns : Array[String]) -> Result[ExclusionScope, InputError]

    Validate every pattern; the whole scope fails on the first invalid one. Patterns are deduplicated by exact spelling and kept in ordinal order so the delivered report is independent of config and command-line ordering.

    parse_snapshot

    fn parse_snapshot(text : String) -> Result[Snapshot, InputError]

    Parse a snapshot document. The document must be canonical: entries sorted and unique, scope normalized, scan issues well-formed, and only known fields present. Corrupted or non-canonical input is rejected.

    pattern_matches

    fn pattern_matches(pattern : PathPattern, entry : PathEntry) -> Bool

    Match an entry or any implicit directory prefix. Invalid path structure never matches.

    plan_delivery

    fn plan_delivery(spec : DeliverySpec) -> Result[DeliveryPlan, InputError]

    Plan entirely against initial identities. Slots model portable target names; immutable source indexes retain exact spelling. A wait-list keyed by slots wakes only affected operations, including the parent of a pending mkdir.

    render_baseline_diff_json

    fn render_baseline_diff_json(diff : BaselineDiff) -> String

    Stable serialization of a classification document with fixed field order.

    render_baseline_diff_text

    fn render_baseline_diff_text(diff : BaselineDiff) -> String

    Stable human-readable classification for text output.

    render_baseline_json

    fn render_baseline_json(baseline : Baseline) -> String

    Stable serialization of a baseline document with fixed field order.

    render_check_sarif

    fn render_check_sarif(report : DetailedReport) -> String

    A complete SARIF 2.1.0 document for a schema 2 report. The document never encodes timestamps, absolute paths or source line numbers.

    render_delivery_audit_json

    fn render_delivery_audit_json(audit : DeliveryAudit) -> String

    render_delivery_audit_markdown

    fn render_delivery_audit_markdown(audit : DeliveryAudit) -> String

    render_delivery_audit_text

    fn render_delivery_audit_text(audit : DeliveryAudit) -> String

    render_delivery_plan_json

    fn render_delivery_plan_json(plan : DeliveryPlan) -> String

    render_delivery_plan_markdown

    fn render_delivery_plan_markdown(plan : DeliveryPlan) -> String

    render_delivery_plan_text

    fn render_delivery_plan_text(plan : DeliveryPlan) -> String

    render_delivery_spec_json

    fn render_delivery_spec_json(spec : DeliverySpec) -> String

    Canonical expanded spec content used as a plan's basis; caller order is irrelevant.

    render_detailed_json

    fn render_detailed_json(report : DetailedReport) -> String

    Deterministic schema 2 serialization; v1 render_json remains unchanged.

    render_detailed_markdown

    fn render_detailed_markdown(report : DetailedReport) -> String

    Markdown rendering of a schema 2 report. The status, scopes, diagnostics and scan issues mirror render_detailed_text so every format reaches the same conclusion; paths are escaped so a hostile name cannot break a table.

    render_detailed_text

    fn render_detailed_text(report : DetailedReport) -> String

    Human-readable schema 2 findings with bounded original-entry witnesses.

    render_json

    fn render_json(report : Report) -> String

    Serialize the report with stable field and diagnostic ordering.

    render_rules_json

    fn render_rules_json(items : Array[RuleInfo]) -> String

    Serialize a catalog or selected rules as an array, sorted by diagnostic code.

    render_rules_text

    fn render_rules_text(items : Array[RuleInfo]) -> String

    Render guidance in code order. Example paths are quoted so controls remain data.

    render_snapshot_diff_json

    fn render_snapshot_diff_json(diff : SnapshotDiff) -> String

    Stable serialization of a snapshot diff with fixed field order.

    render_snapshot_diff_markdown

    fn render_snapshot_diff_markdown(diff : SnapshotDiff) -> String

    Stable Markdown rendering of a snapshot diff. An incomplete input is flagged with a block quote before the table.

    render_snapshot_diff_text

    fn render_snapshot_diff_text(diff : SnapshotDiff) -> String

    Stable human-readable diff. An incomplete input is flagged on the first line so callers can see why the process exits 3 for a potentially stale diff.

    render_snapshot_json

    fn render_snapshot_json(snapshot : Snapshot) -> String

    Stable schema 1 snapshot serialization with fixed field order.

    render_text

    fn render_text(report : Report) -> String

    Human-readable output quotes paths so control characters remain data.

    rules

    fn rules() -> Array[RuleInfo]

    Return all portable-windows-v1 rules and scan issues in ordinal code order. Each call owns its arrays; editing the returned examples does not change the catalog.

    rules_version

    fn rules_version() -> String

    Return the absolute rule-version string for the current catalog. A baseline records this value so a later report from different rules can be rejected.

    uri_escape_path

    fn uri_escape_path(value : String) -> String

    Percent-encode a relative path as a URI reference, preserving / separators.

    with_scan_issues

    fn with_scan_issues(report : DetailedReport, issues : Array[ScanIssue]) -> DetailedReport

    Add scan issues without inventing file/directory evidence or losing prior issues.