evowitness

    Minimal compatibility counterexample witness generator for MoonBit

    counterexample
    witness
    compatibility
    wasm
    Download zip
    Author
    Version
    0.1.1
    License
    MIT
    Last updated
    2 months ago
    Downloads
    36

    No dependencies

    #EvoWitness(演证)

    CI License: MIT

    EvoWitness 是一个原生 MoonBit 兼容性反例生成库与可移植 CLI。它比较两个版本的结构化契约,分别判断向后兼容、向前兼容或双向兼容,并把每项破坏性变更转化为可回放的最小 JSON witness case。

    普通结构差异只能回答“哪里变了”;EvoWitness 的核心问题更窄、更尖锐:

    • 变化是否会拒绝原本合法的数据;
    • 影响的是旧生产者还是旧消费者;
    • 哪一条最小数据可以稳定复现问题;
    • 这条数据应在旧/新契约下分别得到什么验证结论;
    • 如何把反例作为证据包交给评审、CI 或回归测试系统。

    #为什么值得做

    API、事件、配置文件和存档格式都会随版本演进。新增必填字段、删除枚举值、关闭开放对象或收紧长度边界,看似只是几行结构修改,却可能在滚动发布、离线客户端和异步消息场景中造成兼容事故。

    EvoWitness 不做通用 JSON Schema 校验器或数据契约治理平台的重复实现。它专注于 MoonBit 生态中尚缺少的“版本间可接受值集合包含判断 + 最小反例证据包”,并可编译到 WebAssembly,用于本地工具、浏览器、边缘环境和 CI。

    它也不是提交准备检查器、README 示例验证器、开源来源证明工具、初审反馈补正规划器或验收轨迹库。EvoWitness 只围绕一个边界工作:当两个契约版本的可接受 JSON 集合不同,构造并导出能证明差异的最小反例。

    #复审边界声明

    针对 2026-08-24 初审反馈,本仓库已把公开定位收窄为“最小兼容性反例 witness 生成器”:

    • 与 lyjttio/moon-data-contract 的关系:EvoWitness 不是数据契约治理平台,不提供 schema registry、审批台账、发布门禁、JUnit/HTML 治理报告、跨格式代码生成、迁移执行或外部工单自动化;也不复用或扩展 moon-data-contract 的代码。
    • EvoWitness 的独立功能点:输入两段轻量 Evo Contract 文本,判断旧/新版本可接受 JSON 集合是否存在包含关系,并构造一个最小 payload 作为“源版本接受、目标版本拒绝”的可回放证据。
    • validate_json、evaluate_policy、plan_migration 等能力只服务于已生成 witness 的本地复核、评分和人工处理清单,不构成通用校验器、治理套件或迁移平台。
    • 提交作者关系、查重结论和复审说明见 docs/AUTHORSHIP.md、docs/UNIQUENESS.md 与 docs/REVIEW_RESPONSE.md。

    #主要功能

    • 自包含的 Evo Contract DSL 解析器,提供稳定错误码和行号;
    • backward、forward、full 三种兼容性方向;
    • 对象开放性、字段存在性、必填性、类型、枚举、数值边界和长度边界分析;
    • string、int、number、bool、enum、ref、list 数据模型;
    • 为破坏性变化构造最小 JSON 反例;
    • 内置实例验证器,可证明反例在源契约有效、在目标契约无效;
    • Markdown、JSON、SARIF 2.1.0 和 witness-pack/JSONL 证据导出;
    • witness 质量评分,检查覆盖率、稳定 ID、重复 payload、敏感字段信号和弱解释;
    • replay suite/checklist,把每个反例展开为源版本接受、目标版本拒绝和回归守护步骤;
    • 可作为 MoonBit 库使用,也提供可运行 CLI 与完整示例;
    • 无第三方运行时依赖,仅使用 MoonBit 标准库。

    #契约示例

    contract Checkout 1.0.0 type Order closed field id string required minlen=1 maxlen=64 field total int required min=0 max=100000 field status enum:pending|paid|failed required field note string optional maxlen=200 end

    升级到以下版本会删除 failed、收紧 id 长度并新增必填字段:

    contract Checkout 2.0.0 type Order closed field id string required minlen=8 maxlen=64 field total int required min=1 max=100000 field status enum:pending|paid required field note string optional maxlen=200 field currency string required minlen=3 maxlen=3 end

    EvoWitness 会生成类似下面的反例:

    {"id":"a","total":0,"status":"failed"}

    该对象满足 1.0.0,却会被 2.0.0 拒绝,因此报告给出的不是抽象猜测,而是可以重新验证的兼容性证据。

    #安装

    Mooncakes 模块名为 CJR-ai-nb/evowitness。

    moon add CJR-ai-nb/evowitness@0.1.1

    在使用包的 moon.pkg 中导入:

    import { "CJR-ai-nb/evowitness" @evowitness, }

    #最小使用示例

    let old_source =
    #|contract C 1
    #|type Item closed
    #|field id string required
    #|end
    let new_source =
    #|contract C 2
    #|type Item closed
    #|field id string required
    #|field region string required
    #|end

    match @evowitness.analyze_text(
    old_source,
    new_source,
    mode=@evowitness.Backward,
    ) {
    Ok(report) => println(report.to_markdown())
    Err(error) => println(error.render())
    }

    #本地运行

    需要当前稳定版 MoonBit 工具链:

    moon check --deny-warn moon build moon test --deny-warn moon run examples/checkout moon run cmd/evowitness -- demo json moon run cmd/evowitness -- demo witness-jsonl moon run cmd/evowitness -- demo score-json moon run cmd/evowitness -- demo replay-checklist

    Windows / PowerShell 用户也可以直接运行验收脚本:

    powershell -ExecutionPolicy Bypass -File scripts/verify_acceptance.ps1

    在 moon whoami 已经显示 CJR-ai-nb 后,可以带上 Mooncakes 发布预检:

    powershell -ExecutionPolicy Bypass -File scripts/verify_acceptance.ps1 -IncludePublishDryRun

    CLI 支持内置演示和单行比较。单行比较用分号代替换行:

    moon run cmd/evowitness -- compare backward \ "contract C 1;type Item closed;field id string required;end" \ "contract C 2;type Item closed;field id string required;field zone string required;end" \ markdown

    输出格式可选 markdown、json、sarif、witness-json、witness-jsonl、witness-md、score-json、score-md、replay-json、replay-md 或 replay-checklist。

    #兼容方向

    模式判断的问题常见部署场景
    backward新契约能否读取全部旧数据先升级消费者
    forward旧契约能否读取全部新数据先升级生产者或存在旧客户端
    full两个方向是否都安全滚动发布、离线同步、事件总线

    #核心 API

    • parse_contract:解析 DSL,返回结构化契约或稳定诊断;
    • analyze:比较两个已解析契约;
    • analyze_text:从两段 DSL 直接完成比较;
    • validate_json / validate_value:为 witness 复核校验 JSON 实例;
    • verify_witness:在新旧契约上重新验证反例;
    • AnalysisReport::to_markdown:生成评审友好的报告;
    • AnalysisReport::to_json:生成机器可读报告;
    • AnalysisReport::to_sarif:生成代码扫描平台可接收的 SARIF。
    • AnalysisReport::to_witness_pack:提取可回放 witness cases;
    • AnalysisReport::to_witness_jsonl:为 CI 或回归测试系统生成一行一个反例的证据流;
    • AnalysisReport::score_witness_evidence:评估反例证据是否完整、稳定、可安全流转,并给出 ready / needs-review / blocked 状态;
    • AnalysisReport::to_replay_suite:把 witness cases 转成可执行回放步骤;
    • evaluate_policy:对 witness 质量、兼容模式和已记录例外执行轻量本地检查,不作为发布治理门禁;
    • plan_migration:根据 witness 指向的风险位置生成辅助处理清单,不执行数据迁移或外部工单自动化;
    • canonicalize:生成稳定、便于审查的规范化契约;
    • analyze_series / analyze_support_window:检查相邻版本及完整支持窗口。

    更完整的语法见 docs/DSL.md,算法与边界见 docs/DESIGN.md,证据包设计见 docs/WITNESS_PACKS.md,查重与差异说明见 docs/UNIQUENESS.md。

    #支持范围

    • 多对象契约和前向 ref 引用;
    • 递归对象引用,反例生成带深度与环保护;
    • 开放/封闭对象;
    • 可选/必填字段;
    • 基础标量、枚举、引用和同质列表;
    • 整数数值上下界;
    • Unicode 字符串长度和列表长度上下界;
    • 未知字段、类型、枚举、嵌套对象和列表实例校验;
    • 可确定、可排序、适合 CI 的稳定错误码与变化码。

    #暂不支持

    • JSON Schema、OpenAPI 或 Protobuf 文件的直接导入;
    • 正则表达式、浮点专用边界、联合类型和条件约束;
    • 自动改写生产契约;
    • schema registry、契约所有权目录、JUnit 报告或外部工单自动创建;
    • CLI 直接读取本地文件;当前文件集成应由调用方读取内容后使用库 API;
    • 将 SARIF 自动上传到第三方服务。

    这些边界是有意保留的:0.1.x 优先保证演进语义、反例正确性、证据可回放性和跨目标可移植性,后续格式适配器可以作为独立包扩展。

    #测试与验收

    测试覆盖正常输入、错误输入、边界值、引用结构、兼容性双向推理、报告导出、JSON 实例验证、递归环和反例再验证:

    moon check --deny-warn moon build moon test --deny-warn moon run examples/checkout moon run cmd/evowitness -- demo json moon run cmd/evowitness -- demo witness-jsonl moon publish --dry-run

    GitHub Actions 会执行检查、构建、全部测试、示例和 CLI smoke test。

    验收证据入口:

    #Mooncakes 与版本

    • 模块:CJR-ai-nb/evowitness
    • 版本:0.1.1
    • 文档地址:https://mooncakes.io/docs/CJR-ai-nb/evowitness
    • 清单地址:https://mooncakes.io/api/v0/manifest/CJR-ai-nb/evowitness

    发布命令:

    moon login moon publish --dry-run moon publish

    #开源许可与第三方说明

    项目采用 MIT License。核心源代码、测试 fixture 和文档均为本项目原创,不移植第三方源码,不包含图片、字体、音频或来源不明素材。运行时仅依赖 MoonBit 标准库;开发流程使用的 GitHub Action 不进入发布包。详细调研与边界说明见 docs/RESEARCH.md、docs/AI_USAGE.md 和 THIRD_PARTY.md。

    AnalysisPolicy

    pub(all) struct AnalysisPolicy {
    name : String
    required_mode : CompatibilityMode?
    max_unallowed_breaking : Int
    max_warnings : Int
    forbidden_codes : Array[String]
    require_witness : Bool
    allowances : Array[ChangeAllowance]
    } derive(Eq,
    Debug
    )

    CI policy applied after compatibility analysis.

    AnalysisPolicy::allow

    fn AnalysisPolicy::allow(self : AnalysisPolicy, code : String, path_prefix? : String, direction? : String, reason~ : String) -> AnalysisPolicy

    Return a copy of the policy with one documented compatibility exception.

    AnalysisPolicy::consumer_first

    fn AnalysisPolicy::consumer_first() -> AnalysisPolicy

    Backward-compatible rollout policy for consumer-first deployments.

    AnalysisPolicy::development

    fn AnalysisPolicy::development(budget? : Int) -> AnalysisPolicy

    Development policy that records breaks while enforcing witness quality.

    AnalysisPolicy::strict

    Strict release policy: full compatibility and no unapproved breaking change.

    AnalysisReport

    pub(all) struct AnalysisReport {
    contract_name : String
    old_version : String
    new_version : String
    mode : CompatibilityMode
    changes : Array[Change]
    } derive(Eq,
    Debug
    )

    Complete analysis result for two contract versions.

    AnalysisReport::breaking_count

    fn AnalysisReport::breaking_count(self : AnalysisReport) -> Int

    AnalysisReport::info_count

    fn AnalysisReport::info_count(self : AnalysisReport) -> Int

    AnalysisReport::is_compatible

    fn AnalysisReport::is_compatible(self : AnalysisReport) -> Bool

    AnalysisReport::score_witness_evidence

    fn AnalysisReport::score_witness_evidence(self : AnalysisReport) -> EvidenceScorecard

    Score a full analysis report and its derived witness pack.

    AnalysisReport::to_json

    fn AnalysisReport::to_json(self : AnalysisReport) -> String

    Render a stable JSON document for custom CI integrations.

    AnalysisReport::to_markdown

    fn AnalysisReport::to_markdown(self : AnalysisReport) -> String

    Render a concise Markdown report for reviews and release notes.

    AnalysisReport::to_replay_checklist

    fn AnalysisReport::to_replay_checklist(self : AnalysisReport) -> String

    AnalysisReport::to_replay_json

    fn AnalysisReport::to_replay_json(self : AnalysisReport) -> String

    AnalysisReport::to_replay_markdown

    fn AnalysisReport::to_replay_markdown(self : AnalysisReport) -> String

    AnalysisReport::to_replay_suite

    fn AnalysisReport::to_replay_suite(self : AnalysisReport) -> ReplaySuite

    AnalysisReport::to_sarif

    fn AnalysisReport::to_sarif(self : AnalysisReport) -> String

    Render SARIF 2.1.0 so findings can be uploaded to code-scanning systems.

    AnalysisReport::to_witness_json

    fn AnalysisReport::to_witness_json(self : AnalysisReport) -> String

    AnalysisReport::to_witness_jsonl

    fn AnalysisReport::to_witness_jsonl(self : AnalysisReport) -> String

    AnalysisReport::to_witness_markdown

    fn AnalysisReport::to_witness_markdown(self : AnalysisReport) -> String

    AnalysisReport::to_witness_pack

    fn AnalysisReport::to_witness_pack(self : AnalysisReport) -> WitnessPack

    Build a replayable evidence pack from all generated witnesses in a report.

    AnalysisReport::verdict

    fn AnalysisReport::verdict(self : AnalysisReport) -> String

    AnalysisReport::warning_count

    fn AnalysisReport::warning_count(self : AnalysisReport) -> Int

    Change

    pub(all) struct Change {
    code : String
    severity : Severity
    direction : String
    path : String
    message : String
    hint : String
    witness : Witness?
    } derive(Eq,
    Debug
    )

    One stable, path-addressable contract evolution finding.

    ChangeAllowance

    pub(all) struct ChangeAllowance {
    code : String
    direction : String
    path_prefix : String
    reason : String
    } derive(Eq,
    Debug
    )

    A narrowly scoped exception for one known compatibility break.

    CompatibilityMode

    pub(all) enum CompatibilityMode {
    Backward
    Forward
    Full
    } derive(Eq,
    Debug
    )

    Compatibility direction requested by the caller.

    CompatibilityMode::render

    fn CompatibilityMode::render(self : CompatibilityMode) -> String

    Constraints

    pub(all) struct Constraints {
    min_int : Int?
    max_int : Int?
    min_len : Int?
    max_len : Int?
    default_value : String?
    } derive(Eq,
    Debug
    )

    Validation constraints attached to one field.

    Constraints::none

    fn Constraints::none() -> Constraints

    Construct an unconstrained field rule.

    Contract

    pub(all) struct Contract {
    name : String
    version : String
    objects : Array[ObjectType]
    } derive(Eq,
    Debug
    )

    A complete named and versioned contract.

    Contract::find_object

    fn Contract::find_object(self : Contract, name : String) -> ObjectType?

    Return the object named name when it exists.

    Contract::to_dsl

    fn Contract::to_dsl(self : Contract) -> String

    Render a contract in EvoWitness's canonical, review-stable DSL form.

    EvidenceScoreIssue

    pub(all) struct EvidenceScoreIssue {
    code : String
    level : EvidenceScoreLevel
    case_id : String?
    path : String
    message : String
    suggestion : String
    } derive(Eq,
    Debug
    )

    One quality issue found in a witness pack or source report.

    EvidenceScoreLevel

    pub(all) enum EvidenceScoreLevel {
    EvidenceError
    EvidenceWarning
    EvidenceNote
    } derive(Eq,
    Debug
    )

    Severity of an evidence-quality finding.

    EvidenceScoreLevel::render

    fn EvidenceScoreLevel::render(self : EvidenceScoreLevel) -> String

    EvidenceScorecard

    pub(all) struct EvidenceScorecard {
    contract_name : String
    old_version : String
    new_version : String
    mode : CompatibilityMode
    breaking_count : Int
    covered_breaking_count : Int
    case_count : Int
    duplicate_case_ids : Int
    duplicate_payloads : Int
    sensitive_case_count : Int
    weak_reason_count : Int
    issues : Array[EvidenceScoreIssue]
    } derive(Eq,
    Debug
    )

    Summary of whether generated witnesses are ready to be used as evidence.

    EvidenceScorecard::error_count

    fn EvidenceScorecard::error_count(self : EvidenceScorecard) -> Int

    EvidenceScorecard::next_action

    fn EvidenceScorecard::next_action(self : EvidenceScorecard) -> String

    Suggest the next local action without turning EvoWitness into a submission checker.

    EvidenceScorecard::note_count

    fn EvidenceScorecard::note_count(self : EvidenceScorecard) -> Int

    EvidenceScorecard::passed

    fn EvidenceScorecard::passed(self : EvidenceScorecard) -> Bool

    EvidenceScorecard::quality_score

    fn EvidenceScorecard::quality_score(self : EvidenceScorecard) -> Int

    Score the pack as a release-review artifact. The score is deterministic and intentionally simple so CI can set a threshold without hidden weights.

    EvidenceScorecard::readiness

    fn EvidenceScorecard::readiness(self : EvidenceScorecard) -> String

    Compact readiness state for humans and CI summaries.

    EvidenceScorecard::readiness_reason

    fn EvidenceScorecard::readiness_reason(self : EvidenceScorecard) -> String

    Explain why the current readiness label was selected.

    EvidenceScorecard::to_json

    fn EvidenceScorecard::to_json(self : EvidenceScorecard) -> String

    EvidenceScorecard::to_markdown

    fn EvidenceScorecard::to_markdown(self : EvidenceScorecard) -> String

    EvidenceScorecard::warning_count

    fn EvidenceScorecard::warning_count(self : EvidenceScorecard) -> Int

    Field

    pub(all) struct Field {
    name : String
    type_expr : TypeExpr
    required : Bool
    constraints : Constraints
    line : Int
    } derive(Eq,
    Debug
    )

    One named field in an object contract.

    InstanceError

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

    Failure that prevents validation from starting.

    MigrationPhase

    pub(all) enum MigrationPhase {
    ExpandReceivers
    MigrateProducers
    MigrateStoredData
    EnforceTarget
    ObserveRollout
    } derive(Eq,
    Debug
    )

    Safe rollout phase assigned to a generated migration step.

    MigrationPhase::render

    fn MigrationPhase::render(self : MigrationPhase) -> String

    MigrationPlan

    pub(all) struct MigrationPlan {
    contract_name : String
    from_version : String
    to_version : String
    risk : String
    steps : Array[MigrationStep]
    } derive(Eq,
    Debug
    )

    Ordered rollout plan synthesized from compatibility findings.

    MigrationPlan::to_json

    fn MigrationPlan::to_json(self : MigrationPlan) -> String

    Render a witness-local rollout checklist for automation or dashboards.

    MigrationPlan::to_markdown

    fn MigrationPlan::to_markdown(self : MigrationPlan) -> String

    MigrationStep

    pub(all) struct MigrationStep {
    id : String
    phase : MigrationPhase
    path : String
    action : String
    verification : String
    related_codes : Array[String]
    } derive(Eq,
    Debug
    )

    One actionable, verifiable migration task.

    ObjectType

    pub(all) struct ObjectType {
    name : String
    open : Bool
    fields : Array[Field]
    line : Int
    } derive(Eq,
    Debug
    )

    One object type. Open objects accept unknown fields; closed objects reject them.

    ObjectType::find_field

    fn ObjectType::find_field(self : ObjectType, name : String) -> Field?

    Return the field named name when it exists.

    ObjectType::has_field

    fn ObjectType::has_field(self : ObjectType, name : String) -> Bool

    Check whether this object contains a field with the given name.

    ParseError

    pub(all) struct ParseError {
    line : Int
    column : Int
    code : String
    message : String
    source_line : String
    } derive(Eq,
    Debug
    )

    Stable parser diagnostic suitable for editors and CI logs.

    ParseError::render

    fn ParseError::render(self : ParseError) -> String

    Render one parse error in a compiler-style single-line format.

    PolicyResult

    pub(all) struct PolicyResult {
    policy_name : String
    violations : Array[PolicyViolation]
    allowed_breaking : Array[Change]
    unallowed_breaking : Array[Change]
    } derive(Eq,
    Debug
    )

    Deterministic outcome of applying an analysis policy.

    PolicyResult::passed

    fn PolicyResult::passed(self : PolicyResult) -> Bool

    PolicyResult::to_json

    fn PolicyResult::to_json(self : PolicyResult) -> String

    Render a machine-readable policy decision for CI systems.

    PolicyResult::to_markdown

    fn PolicyResult::to_markdown(self : PolicyResult) -> String

    Render a compact CI-friendly policy result.

    PolicyViolation

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

    One reason an analysis report does not satisfy policy.

    ReplayStep

    pub(all) struct ReplayStep {
    id : String
    case_id : String
    kind : ReplayStepKind
    contract_version : String
    expected_valid : Bool
    path : String
    payload : String
    assertion : String
    note : String
    } derive(Eq,
    Debug
    )

    One deterministic action a downstream test runner can perform.

    ReplayStepKind

    pub(all) enum ReplayStepKind {
    ExpectSourceAccept
    ExpectTargetReject
    PreserveRegression
    } derive(Eq,
    Debug
    )

    A replay step kind derived from one witness case.

    ReplayStepKind::render

    fn ReplayStepKind::render(self : ReplayStepKind) -> String

    ReplayStepKind::title

    fn ReplayStepKind::title(self : ReplayStepKind) -> String

    ReplaySuite

    pub(all) struct ReplaySuite {
    contract_name : String
    old_version : String
    new_version : String
    mode : CompatibilityMode
    case_count : Int
    steps : Array[ReplayStep]
    } derive(Eq,
    Debug
    )

    A portable replay plan for turning witness cases into negative tests.

    ReplaySuite::accept_step_count

    fn ReplaySuite::accept_step_count(self : ReplaySuite) -> Int

    ReplaySuite::guard_step_count

    fn ReplaySuite::guard_step_count(self : ReplaySuite) -> Int

    ReplaySuite::reject_step_count

    fn ReplaySuite::reject_step_count(self : ReplaySuite) -> Int

    ReplaySuite::to_checklist

    fn ReplaySuite::to_checklist(self : ReplaySuite) -> String

    ReplaySuite::to_json

    fn ReplaySuite::to_json(self : ReplaySuite) -> String

    ReplaySuite::to_markdown

    fn ReplaySuite::to_markdown(self : ReplaySuite) -> String

    Severity

    pub(all) enum Severity {
    Breaking
    Warning
    Info
    } derive(Eq,
    Debug
    )

    Importance assigned to an evolution finding.

    Severity::render

    fn Severity::render(self : Severity) -> String

    TypeExpr

    pub(all) enum TypeExpr {
    StringType
    IntType
    BoolType
    NumberType
    EnumType(Array[String])
    RefType(String)
    ListType(String)
    } derive(Eq,
    Debug
    )

    A scalar or reference expression accepted by an EvoWitness field.

    TypeExpr::referenced_name

    fn TypeExpr::referenced_name(self : TypeExpr) -> String?

    Whether the expression points to another object in the contract.

    TypeExpr::render

    fn TypeExpr::render(self : TypeExpr) -> String

    Render a compact, stable type spelling used in diagnostics.

    ValidationIssue

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

    One path-addressable payload validation problem.

    ValidationResult

    pub(all) struct ValidationResult {
    object_name : String
    issues : Array[ValidationIssue]
    } derive(Eq,
    Debug
    )

    Result of validating one JSON payload against one object type.

    ValidationResult::is_valid

    fn ValidationResult::is_valid(self : ValidationResult) -> Bool

    Witness

    pub(all) struct Witness {
    payload : String
    accepted_by : String
    rejected_by : String
    reason : String
    } derive(Eq,
    Debug
    )

    A concrete payload showing why a compatibility rule fails.

    WitnessCase

    pub(all) struct WitnessCase {
    id : String
    code : String
    direction : String
    path : String
    payload : String
    accepted_by : String
    rejected_by : String
    reason : String
    assertion : String
    } derive(Eq,
    Debug
    )

    A replayable evidence case derived from one generated counterexample.

    WitnessPack

    pub(all) struct WitnessPack {
    contract_name : String
    old_version : String
    new_version : String
    mode : CompatibilityMode
    cases : Array[WitnessCase]
    } derive(Eq,
    Debug
    )

    A deterministic pack of negative compatibility evidence.

    WitnessPack::score_standalone

    fn WitnessPack::score_standalone(self : WitnessPack) -> EvidenceScorecard

    Score a standalone witness pack when the original report is unavailable.

    WitnessPack::to_json

    fn WitnessPack::to_json(self : WitnessPack) -> String

    Render the witness pack as JSON for archival or review systems.

    WitnessPack::to_jsonl

    fn WitnessPack::to_jsonl(self : WitnessPack) -> String

    Render one witness per line so CI can turn each case into a separate test.

    WitnessPack::to_markdown

    fn WitnessPack::to_markdown(self : WitnessPack) -> String

    Render a human-readable evidence pack centered on replay assertions.

    WitnessPack::to_replay_suite

    fn WitnessPack::to_replay_suite(self : WitnessPack) -> ReplaySuite

    WitnessVerification

    pub(all) struct WitnessVerification {
    source_valid : Bool
    target_valid : Bool
    source_issues : Array[ValidationIssue]
    target_issues : Array[ValidationIssue]
    } derive(Eq,
    Debug
    )

    Independent validation results for a generated compatibility witness.

    analyze

    fn analyze(old_contract : Contract, new_contract : Contract, mode? : CompatibilityMode) -> AnalysisReport

    Compare two parsed contracts and explain compatibility changes.

    Backward mode asks whether every payload accepted by old_contract is also accepted by new_contract. Forward mode reverses that data flow. Full mode checks both directions.

    analyze_series

    fn analyze_series(contracts : Array[Contract], mode? : CompatibilityMode) -> Array[AnalysisReport]

    Analyze every adjacent transition in an ordered contract history.

    analyze_support_window

    fn analyze_support_window(contracts : Array[Contract], mode? : CompatibilityMode) -> Array[AnalysisReport]

    Analyze every older/newer pair in an ordered contract history. This catches a sequence that is safe per-step but violates a longer support window.

    analyze_text

    fn analyze_text(old_source : String, new_source : String, mode? : CompatibilityMode) -> Result[AnalysisReport, ParseError]

    Convenience API for callers that keep both contracts as text.

    canonicalize

    fn canonicalize(source : String) -> Result[String, ParseError]

    Parse and re-render a source document, removing comments and normalizing layout.

    evaluate_policy

    fn evaluate_policy(report : AnalysisReport, policy : AnalysisPolicy) -> PolicyResult

    Evaluate a report against budgets, forbidden rules and scoped allowances.

    field_path

    fn field_path(object_name : String, field_name : String) -> String

    Return a machine-stable path for a field.

    parse_contract

    fn parse_contract(input : String) -> Result[Contract, ParseError]

    Parse the EvoWitness line-oriented contract language.

    Grammar (whitespace is insignificant):

    contract <name> <version> type <name> <open|closed> field <name> <kind> <required|optional> [constraint=value ...] end

    plan_migration

    fn plan_migration(report : AnalysisReport) -> MigrationPlan

    Build an ordered plan from breaking findings. Compatible reports still get a final observation step so releases have an explicit verification point.

    series_verdict

    fn series_verdict(reports : Array[AnalysisReport]) -> String

    Highest-risk verdict across a version series.

    validate_json

    fn validate_json(contract : Contract, object_name : String, input : String) -> Result[ValidationResult, InstanceError]

    Parse and validate a JSON payload against a named object in the contract.

    validate_value

    fn validate_value(contract : Contract, object_name : String, value : Json) -> Result[ValidationResult, InstanceError]

    Validate an already parsed JSON value.

    verify_witness

    fn verify_witness(source : Contract, target : Contract, object_name : String, witness : Witness) -> Result[WitnessVerification, InstanceError]

    Re-run a generated witness through both contracts.