evowitness

Data-contract evolution analyzer with minimal counterexample generation

schema-evolution
compatibility
contract-testing
wasm
moon add CJR-ai-nb/evowitness@0.1.0
Download zip
Author
Version
0.1.0
License
MIT
Last updated
7 hours ago
Downloads
2
README

#EvoWitness(演证)

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

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

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

#为什么值得做

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

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

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

#主要功能

  • 自包含的 Evo Contract DSL 解析器,提供稳定错误码和行号;
  • backwardforwardfull 三种兼容性方向;
  • 对象开放性、字段存在性、必填性、类型、枚举、数值边界和长度边界分析;
  • stringintnumberboolenumreflist 数据模型;
  • 为破坏性变化构造最小 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.0

在使用包的 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

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

输出格式可选 markdownjsonsarifwitness-jsonwitness-jsonlwitness-mdscore-jsonscore-mdreplay-jsonreplay-mdreplay-checklist

#兼容方向

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

#核心 API

  • parse_contract:解析 DSL,返回结构化契约或稳定诊断;
  • analyze:比较两个已解析契约;
  • analyze_text:从两段 DSL 直接完成比较;
  • validate_json / validate_value:校验 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.0
  • 文档地址: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.mdTHIRD_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 migration plan for automation, ticket generation 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.