Sign in

    moongrammata

    Structure-aware feedback-guided fuzzing toolkit for MoonBit

    fuzzing
    grammar
    testing
    structured-input
    quality-assurance
    Download zip
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    22 days ago
    Downloads
    56

    No dependencies

    #MoonGrammata

    Structure-aware, feedback-guided fuzzing for MoonBit.

    ///|
    let builder = @grammata.GrammarBuilder::new()

    ///|
    let digit = builder.ascii_range('0', '9')

    ///|
    let document = builder.repeat(digit, minimum=1, maximum=16)

    ///|
    let grammar = builder.set_start(document).build().unwrap()

    ///|
    let tree = grammar.generate(seed=42L).unwrap()

    The core provides bounded grammar generation, derivation-tree mutation and crossover, novelty corpus scheduling, failure-preserving reduction, differential/metamorphic oracles, deterministic replay, and evidence reports. See the repository README for the full contract and runnable examples.

    AdmissionDecision

    pub(all) enum AdmissionDecision {
    Admitted(Int, AdmissionReason)
    Rejected(RejectionReason)
    } derive(Eq,
    Debug
    )

    AdmissionReason

    pub(all) enum AdmissionReason {
    FirstInput
    NovelFeature(Int)
    NovelSignature
    NewFailure(FailureFingerprint)
    } derive(Eq,
    Debug
    )

    Alternative

    pub(all) struct Alternative {
    rule : RuleId
    weight : Int
    label : String
    } derive(Eq,
    Debug
    )

    AnalysisError

    pub(all) enum AnalysisError {
    UnproductiveStartRule(Int)
    UnproductiveRule(Int)
    NoTerminatingAlternative(Int)
    MinimumCostOverflow(Int)
    } derive(Eq,
    Debug
    )

    CampaignConfig

    pub(all) struct CampaignConfig {
    seed : Int64
    executions : Int
    initial_inputs : Int
    crossover_percent : Int
    generation_budget : GenerationBudget
    mutation_config : MutationConfig
    crossover_config : CrossoverConfig
    corpus_limits : CorpusLimits
    max_events : Int
    } derive(Eq,
    Debug
    )

    CampaignConfig::default

    fn CampaignConfig::default(seed? : Int64) -> CampaignConfig

    CampaignError

    pub(all) enum CampaignError {
    InvalidCampaignConfig(String)
    InitialGenerationFailed(GenerationError)
    CorpusCouldNotBeSeeded
    } derive(Eq,
    Debug
    )

    CampaignEvent

    pub(all) struct CampaignEvent {
    execution : Int
    input_bytes : Int
    corpus_entries : Int
    kind : CampaignEventKind
    } derive(Eq,
    Debug
    )

    CampaignEventKind

    pub(all) enum CampaignEventKind {
    Generated
    Mutated(MutationStrategy)
    Crossed
    Admitted(AdmissionReason)
    RejectedInput(RejectionReason)
    FailureFound(FailureFingerprint)
    MutationSkipped
    } derive(Eq,
    Debug
    )

    CampaignResult

    pub(all) struct CampaignResult {
    statistics : CampaignStatistics
    corpus : Array[CorpusEntry]
    failures : Array[ReplayRecord]
    events : Array[CampaignEvent]
    } derive(Eq,
    Debug
    )

    CampaignResult::json_report

    fn CampaignResult::json_report(self : CampaignResult) -> String

    CampaignResult::markdown_report

    fn CampaignResult::markdown_report(self : CampaignResult, title? : String) -> String

    CampaignResult::strategy_evidence

    fn CampaignResult::strategy_evidence(self : CampaignResult, name : String) -> StrategyEvidence

    CampaignStatistics

    pub(all) struct CampaignStatistics {
    requested_executions : Int
    completed_executions : Int
    generated_inputs : Int
    mutated_inputs : Int
    crossed_inputs : Int
    admitted_inputs : Int
    rejected_inputs : Int
    unique_failures : Int
    mutation_failures : Int
    final_corpus : CorpusStatistics
    } derive(Eq,
    Debug
    )

    Corpus

    pub struct Corpus {
    entries : Array[CorpusEntry]
    limits : CorpusLimits
    registry : FeatureRegistry
    input_ids :
    HashMap
    [String, Int]
    failure_ids :
    HashMap
    [FailureFingerprint, Int]
    total_bytes : Int
    failure_count : Int
    }

    Corpus::consider

    fn Corpus::consider(self : Corpus, tree : DerivationTree, observation : TargetObservation, origin : CorpusOrigin) -> AdmissionDecision

    Corpus::entries

    fn Corpus::entries(self : Corpus) -> Array[CorpusEntry]

    Corpus::entry

    fn Corpus::entry(self : Corpus, id : Int) -> CorpusEntry?

    Corpus::failure_entry

    fn Corpus::failure_entry(self : Corpus, fingerprint : FailureFingerprint) -> CorpusEntry?

    Corpus::feature_frequency

    fn Corpus::feature_frequency(self : Corpus, value : Feature) -> Int

    Corpus::find_input

    fn Corpus::find_input(self : Corpus, input : Bytes) -> CorpusEntry?

    Corpus::is_empty

    fn Corpus::is_empty(self : Corpus) -> Bool

    Corpus::length

    fn Corpus::length(self : Corpus) -> Int

    Corpus::new

    fn Corpus::new(limits? : CorpusLimits) -> Corpus

    Corpus::signature_frequency

    fn Corpus::signature_frequency(self : Corpus, value : FeedbackSignature) -> Int

    Corpus::smallest_failure

    fn Corpus::smallest_failure(self : Corpus, fingerprint : FailureFingerprint) -> CorpusEntry?

    Corpus::statistics

    fn Corpus::statistics(self : Corpus) -> CorpusStatistics

    CorpusEntry

    pub(all) struct CorpusEntry {
    id : Int
    tree : DerivationTree
    observation : TargetObservation
    signature : FeedbackSignature
    failure : FailureFingerprint?
    origin : CorpusOrigin
    input_key : String
    executions : Int
    selections : Int
    discoveries : Int
    energy : Int
    } derive(Eq,
    Debug
    )

    CorpusEntry::is_failure

    fn CorpusEntry::is_failure(self : CorpusEntry) -> Bool

    CorpusEntry::observation

    fn CorpusEntry::observation(self : CorpusEntry) -> TargetObservation

    CorpusEntry::record_discovery

    fn CorpusEntry::record_discovery(self : CorpusEntry) -> Unit

    CorpusEntry::record_execution

    fn CorpusEntry::record_execution(self : CorpusEntry) -> Unit

    CorpusEntry::record_selection

    fn CorpusEntry::record_selection(self : CorpusEntry) -> Unit

    CorpusEntry::set_energy

    fn CorpusEntry::set_energy(self : CorpusEntry, value : Int) -> Unit

    CorpusEntry::tree

    CorpusLimits

    pub(all) struct CorpusLimits {
    max_entries : Int
    max_total_bytes : Int
    max_failures : Int
    max_input_bytes : Int
    } derive(Eq,
    Debug
    )

    CorpusLimits::default

    fn CorpusLimits::default() -> CorpusLimits

    CorpusOrigin

    pub(all) enum CorpusOrigin {
    Seeded(Int64)
    Generated(Int64)
    Mutated(Int, String)
    Crossed(Int, Int)
    Reduced(Int)
    Replayed
    } derive(Eq,
    Debug
    )

    CorpusStatistics

    pub(all) struct CorpusStatistics {
    entries : Int
    failures : Int
    total_bytes : Int
    unique_inputs : Int
    unique_features : Int
    unique_signatures : Int
    unique_failures : Int
    } derive(Eq,
    Debug
    )

    CrossoverConfig

    pub(all) struct CrossoverConfig {
    maximum_output_bytes : Int
    maximum_nodes : Int
    maximum_depth : Int
    attempts : Int
    } derive(Eq,
    Debug
    )

    CrossoverConfig::default

    CrossoverError

    pub(all) enum CrossoverError {
    NoCompatibleSubtree
    CrossoverBudgetExceeded(String, Int)
    NoEffectiveCrossover
    } derive(Eq,
    Debug
    )

    CrossoverResult

    pub(all) struct CrossoverResult {
    tree : DerivationTree
    recipient_node : Int
    donor_node : Int
    rule : RuleId
    } derive(Eq,
    Debug
    )

    DerivationKind

    pub(all) enum DerivationKind {
    LiteralLeaf
    ByteLeaf
    IntegerLeaf(Int)
    DictionaryLeaf(Int)
    SequenceNode
    ChoiceNode(Int, String)
    RepeatNode(Int)
    OptionalNode(Bool)
    ReferenceNode(String)
    } derive(Eq,
    Debug
    )

    DerivationTree

    pub(all) struct DerivationTree {
    node_id : Int
    rule : RuleId
    kind : DerivationKind
    payload : Array[Byte]
    children : Array[DerivationTree]
    } derive(Eq,
    Debug
    )

    DerivationTree::branch

    fn DerivationTree::branch(node_id : Int, rule : RuleId, kind : DerivationKind, children : Array[DerivationTree]) -> DerivationTree

    DerivationTree::byte_length

    fn DerivationTree::byte_length(self : DerivationTree) -> Int

    DerivationTree::children

    DerivationTree::depth

    fn DerivationTree::depth(self : DerivationTree) -> Int

    DerivationTree::descendants

    DerivationTree::find

    fn DerivationTree::find(self : DerivationTree, node_id : Int) -> DerivationTree?

    DerivationTree::kind

    DerivationTree::leaf

    fn DerivationTree::leaf(node_id : Int, rule : RuleId, kind : DerivationKind, payload : Array[Byte]) -> DerivationTree

    DerivationTree::node_count

    fn DerivationTree::node_count(self : DerivationTree) -> Int

    DerivationTree::node_id

    fn DerivationTree::node_id(self : DerivationTree) -> Int

    DerivationTree::nodes_for_rule

    fn DerivationTree::nodes_for_rule(self : DerivationTree, rule : RuleId) -> Array[DerivationTree]

    DerivationTree::payload

    fn DerivationTree::payload(self : DerivationTree) -> Array[Byte]

    DerivationTree::render

    fn DerivationTree::render(self : DerivationTree) -> Bytes

    DerivationTree::render_text

    fn DerivationTree::render_text(self : DerivationTree) -> Result[String, String]

    DerivationTree::renumber

    DerivationTree::replace

    fn DerivationTree::replace(self : DerivationTree, node_id : Int, replacement : DerivationTree) -> DerivationTree

    DerivationTree::rule

    DerivationTree::structural_summary

    fn DerivationTree::structural_summary(self : DerivationTree) -> String

    DerivationTree::without_child

    fn DerivationTree::without_child(self : DerivationTree, child_index : Int) -> DerivationTree?

    DifferentialPolicy

    pub(all) enum DifferentialPolicy {
    CompareDisposition
    CompareResultDigest
    CompareDispositionAndDigest
    } derive(Eq,
    Debug
    )

    EnergyScheduler

    pub struct EnergyScheduler {
    config : ScheduleConfig
    random : Random
    rounds : Int
    }

    EnergyScheduler::energy_for

    fn EnergyScheduler::energy_for(self : EnergyScheduler, corpus : Corpus, entry : CorpusEntry) -> Int

    EnergyScheduler::new

    fn EnergyScheduler::new(seed : Int64, config? : ScheduleConfig) -> EnergyScheduler

    EnergyScheduler::rank

    EnergyScheduler::refresh

    fn EnergyScheduler::refresh(self : EnergyScheduler, corpus : Corpus) -> Array[Int]

    EnergyScheduler::rounds

    fn EnergyScheduler::rounds(self : EnergyScheduler) -> Int

    EnergyScheduler::seed

    fn EnergyScheduler::seed(self : EnergyScheduler) -> Int64

    EnergyScheduler::select

    fn EnergyScheduler::select(self : EnergyScheduler, corpus : Corpus) -> ScheduleDecision?

    ExecutionDisposition

    pub(all) enum ExecutionDisposition {
    Accepted
    Rejected(String)
    Failed(String, String)
    } derive(Eq,
    Debug
    )

    FailureFingerprint

    pub(all) struct FailureFingerprint(String) derive(Eq, Hash,
    Debug
    )

    FailureFingerprint::value

    fn FailureFingerprint::value(self : FailureFingerprint) -> String

    Feature

    pub(all) struct Feature {
    domain : String
    value : String
    } derive(Eq, Hash,
    Debug
    )

    Feature::canonical

    fn Feature::canonical(self : Feature) -> String

    FeatureDelta

    pub(all) struct FeatureDelta {
    signature : FeedbackSignature
    novel_features : Array[Feature]
    all_features : Array[Feature]
    } derive(Eq,
    Debug
    )

    FeatureRegistry

    pub struct FeatureRegistry {
    seen :
    HashMap
    [Feature, Int]
    signatures :
    HashMap
    [FeedbackSignature, Int]
    observations : Int
    }

    FeatureRegistry::feature_frequency

    fn FeatureRegistry::feature_frequency(self : FeatureRegistry, value : Feature) -> Int

    FeatureRegistry::new

    FeatureRegistry::observation_count

    fn FeatureRegistry::observation_count(self : FeatureRegistry) -> Int

    FeatureRegistry::observe

    fn FeatureRegistry::observe(self : FeatureRegistry, observation : TargetObservation) -> FeatureDelta

    FeatureRegistry::signature_frequency

    fn FeatureRegistry::signature_frequency(self : FeatureRegistry, value : FeedbackSignature) -> Int

    FeatureRegistry::unique_feature_count

    fn FeatureRegistry::unique_feature_count(self : FeatureRegistry) -> Int

    FeatureRegistry::unique_signature_count

    fn FeatureRegistry::unique_signature_count(self : FeatureRegistry) -> Int

    FeedbackSignature

    pub(all) struct FeedbackSignature(String) derive(Eq, Hash,
    Debug
    )

    FeedbackSignature::value

    fn FeedbackSignature::value(self : FeedbackSignature) -> String

    GenerationBudget

    pub(all) struct GenerationBudget {
    max_depth : Int
    max_nodes : Int
    max_bytes : Int
    max_repeat : Int
    } derive(Eq,
    Debug
    )

    GenerationBudget::default

    GenerationBudget::new

    fn GenerationBudget::new(max_depth? : Int, max_nodes? : Int, max_bytes? : Int, max_repeat? : Int) -> GenerationBudget

    GenerationError

    pub(all) enum GenerationError {
    InvalidBudget(String)
    UnproductiveGrammar(AnalysisError)
    DepthBudgetExceeded(Int)
    NodeBudgetExceeded(Int)
    ByteBudgetExceeded(Int)
    NoViableAlternative(Int)
    InvalidGeneratedInteger(Int, Int)
    } derive(Eq,
    Debug
    )

    Grammar

    pub struct Grammar {
    rules : Array[RuleDefinition]
    start : RuleId
    names :
    HashMap
    [String, RuleId]
    }

    Grammar::analyze

    fn Grammar::analyze(self : Grammar) -> GrammarAnalysis

    Grammar::generate

    fn Grammar::generate(self : Grammar, seed~ : Int64, budget? : GenerationBudget) -> Result[DerivationTree, GenerationError]

    Grammar::generate_from

    fn Grammar::generate_from(self : Grammar, rule : RuleId, seed~ : Int64, budget? : GenerationBudget) -> Result[DerivationTree, GenerationError]

    Generate a standalone subtree for an existing grammar rule. This is the primitive used by structure-preserving mutation and crossover repair.

    Grammar::mutate

    fn Grammar::mutate(self : Grammar, tree : DerivationTree, seed~ : Int64, config? : MutationConfig) -> Result[MutationResult, MutationError]

    Grammar::mutate_with

    fn Grammar::mutate_with(self : Grammar, tree : DerivationTree, strategy : MutationStrategy, seed~ : Int64, config? : MutationConfig) -> Result[MutationResult, MutationError]

    Grammar::name_of

    fn Grammar::name_of(self : Grammar, id : RuleId) -> String?

    Grammar::reduce_failure

    fn Grammar::reduce_failure(self : Grammar, tree : DerivationTree, target : Target, fingerprint? : FailureFingerprint, seed? : Int64, config? : ReductionConfig) -> Result[ReductionResult, ReductionError]

    Grammar::resolve

    fn Grammar::resolve(self : Grammar, name : String) -> RuleId?

    Grammar::rule

    fn Grammar::rule(self : Grammar, id : RuleId) -> RuleDefinition?

    Grammar::rule_count

    fn Grammar::rule_count(self : Grammar) -> Int

    Grammar::rules

    fn Grammar::rules(self : Grammar) -> Array[RuleDefinition]

    Grammar::start

    fn Grammar::start(self : Grammar) -> RuleId

    Grammar::validate_productivity

    fn Grammar::validate_productivity(self : Grammar) -> Result[GrammarAnalysis, AnalysisError]

    GrammarAnalysis

    pub(all) struct GrammarAnalysis {
    rules : Array[RuleProperties]
    reachable_count : Int
    unreachable_count : Int
    recursive_count : Int
    nullable_count : Int
    productive_count : Int
    } derive(Eq,
    Debug
    )

    GrammarAnalysis::properties

    fn GrammarAnalysis::properties(self : GrammarAnalysis, id : RuleId) -> RuleProperties?

    GrammarAnalysis::rules

    GrammarBuilder

    pub struct GrammarBuilder {
    rules : Array[RuleDefinition]
    start_rule : RuleId?
    }

    GrammarBuilder::ascii_range

    fn GrammarBuilder::ascii_range(self : GrammarBuilder, first : Char, last : Char, name? : String) -> RuleId

    GrammarBuilder::build

    fn GrammarBuilder::build(self : GrammarBuilder) -> Result[Grammar, GrammarError]

    GrammarBuilder::bytes

    fn GrammarBuilder::bytes(self : GrammarBuilder, values : Array[Int], name? : String) -> RuleId

    GrammarBuilder::choice

    fn GrammarBuilder::choice(self : GrammarBuilder, alternatives : Array[Alternative], name? : String) -> RuleId

    GrammarBuilder::dictionary

    fn GrammarBuilder::dictionary(self : GrammarBuilder, values : Array[String], name? : String) -> RuleId

    GrammarBuilder::integer

    fn GrammarBuilder::integer(self : GrammarBuilder, minimum : Int, maximum : Int, name? : String) -> RuleId

    GrammarBuilder::literal

    fn GrammarBuilder::literal(self : GrammarBuilder, value : String, name? : String) -> RuleId

    GrammarBuilder::new

    GrammarBuilder::optional

    fn GrammarBuilder::optional(self : GrammarBuilder, child : RuleId, present_weight? : Int, name? : String) -> RuleId

    GrammarBuilder::reference

    fn GrammarBuilder::reference(self : GrammarBuilder, target_name : String, name? : String) -> RuleId

    GrammarBuilder::repeat

    fn GrammarBuilder::repeat(self : GrammarBuilder, child : RuleId, minimum? : Int, maximum? : Int, name? : String) -> RuleId

    GrammarBuilder::sequence

    fn GrammarBuilder::sequence(self : GrammarBuilder, children : Array[RuleId], name? : String) -> RuleId

    GrammarBuilder::set_start

    fn GrammarBuilder::set_start(self : GrammarBuilder, start : RuleId) -> GrammarBuilder

    GrammarError

    pub(all) enum GrammarError {
    EmptyGrammar
    InvalidStartRule(Int)
    InvalidRuleReference(Int, Int)
    MissingNamedRule(String)
    DuplicateRuleName(String)
    EmptyByteSet(Int)
    InvalidByteValue(Int, Int)
    EmptyDictionary(Int)
    EmptyChoice(Int)
    NonPositiveWeight(Int, Int)
    InvalidRepeatBounds(Int, Int, Int)
    InvalidIntegerBounds(Int, Int, Int)
    InvalidOptionalWeight(Int, Int)
    } derive(Eq,
    Debug
    )

    MetamorphicTransform

    pub struct MetamorphicTransform {
    name : String
    apply : (Bytes) -> Bytes
    relation : (TargetObservation, TargetObservation) -> Bool
    }

    MetamorphicTransform::name

    fn MetamorphicTransform::name(self : MetamorphicTransform) -> String

    MetamorphicTransform::new

    fn MetamorphicTransform::new(name : String, apply : (Bytes) -> Bytes, relation : (TargetObservation, TargetObservation) -> Bool) -> MetamorphicTransform

    MutationConfig

    pub(all) struct MutationConfig {
    budget : GenerationBudget
    attempts : Int
    maximum_output_bytes : Int
    } derive(Eq,
    Debug
    )

    MutationConfig::default

    MutationError

    pub(all) enum MutationError {
    EmptyTree
    NoApplicableMutation
    GenerationFailed(GenerationError)
    OutputBudgetExceeded(Int)
    } derive(Eq,
    Debug
    )

    MutationResult

    pub(all) struct MutationResult {
    tree : DerivationTree
    strategy : MutationStrategy
    changed_node : Int
    detail : String
    } derive(Eq,
    Debug
    )

    MutationStrategy

    pub(all) enum MutationStrategy {
    RegenerateSubtree
    DeleteRepeatedChild
    ToggleOptional
    ReplaceIntegerBoundary
    ReplaceDictionaryEntry
    DuplicateRepeatedChild
    } derive(Eq,
    Debug
    )

    Random

    pub(all) struct Random {
    state : Int64
    initial_seed : Int64
    draws : Int
    }

    Stable pseudo-random generator used by every generative operation. The Park-Miller recurrence is intentionally small and reproducible on all MoonBit targets; it is not a cryptographic generator.

    Random::advance

    fn Random::advance(self : Random, count : Int) -> Unit

    Random::below

    fn Random::below(self : Random, exclusive : Int) -> Int

    Random::between

    fn Random::between(self : Random, minimum : Int, maximum : Int) -> Int

    Random::chance

    fn Random::chance(self : Random, numerator : Int, denominator : Int) -> Bool

    Random::choose_index

    fn Random::choose_index(self : Random, length : Int) -> Int?

    Random::draw_count

    fn Random::draw_count(self : Random) -> Int

    Random::fork

    fn Random::fork(self : Random, stream : Int) -> Random

    Random::new

    fn Random::new(seed : Int64) -> Random

    Random::next_raw

    fn Random::next_raw(self : Random) -> Int

    Random::restore

    fn Random::restore(snapshot : RandomSnapshot) -> Random

    Random::sample_without_replacement

    fn Random::sample_without_replacement(self : Random, population : Int, requested : Int) -> Array[Int]

    Random::seed

    fn Random::seed(self : Random) -> Int64

    Random::shuffle

    fn[T] Random::shuffle(self : Random, input : Array[T]) -> Array[T]

    Random::snapshot

    fn Random::snapshot(self : Random) -> RandomSnapshot

    Random::weighted_index

    fn Random::weighted_index(self : Random, weights : Array[Int]) -> Int?

    RandomSnapshot

    pub(all) struct RandomSnapshot {
    seed : Int64
    state : Int64
    draws : Int
    } derive(Eq,
    Debug
    )

    ReductionConfig

    pub(all) struct ReductionConfig {
    max_attempts : Int
    generation_trials : Int
    generation_budget : GenerationBudget
    } derive(Eq,
    Debug
    )

    ReductionConfig::default

    ReductionError

    pub(all) enum ReductionError {
    InputDoesNotFail
    FingerprintMismatch(FailureFingerprint, FailureFingerprint)
    NoReductionPossible
    } derive(Eq,
    Debug
    )

    ReductionKind

    pub(all) enum ReductionKind {
    RemoveRepeatedChild
    RemoveOptionalChild
    ReplaceWithSmallerSubtree
    SimplifyInteger
    SimplifyDictionary
    } derive(Eq,
    Debug
    )

    ReductionResult

    pub(all) struct ReductionResult {
    original : DerivationTree
    reduced : DerivationTree
    fingerprint : FailureFingerprint
    attempts : Int
    accepted_steps : Array[ReductionStep]
    } derive(Eq,
    Debug
    )

    ReductionResult::bytes_removed

    fn ReductionResult::bytes_removed(self : ReductionResult) -> Int

    ReductionResult::nodes_removed

    fn ReductionResult::nodes_removed(self : ReductionResult) -> Int

    ReductionStep

    pub(all) struct ReductionStep {
    kind : ReductionKind
    node_id : Int
    before_bytes : Int
    after_bytes : Int
    before_nodes : Int
    after_nodes : Int
    } derive(Eq,
    Debug
    )

    RejectionReason

    pub(all) enum RejectionReason {
    DuplicateInput
    NoNovelty
    EntryCapacity
    ByteCapacity
    FailureCapacity
    InputTooLarge(Int)
    } derive(Eq,
    Debug
    )

    ReplayError

    pub(all) enum ReplayError {
    InvalidJson
    MissingField(String)
    InvalidField(String)
    UnsupportedReplayVersion(Int)
    ArtifactLimitExceeded(Int)
    InputLimitExceeded(Int)
    InvalidHexInput(Int)
    TargetNameMismatch(String, String)
    } derive(Eq,
    Debug
    )

    ReplayOutcome

    pub(all) struct ReplayOutcome {
    observation : TargetObservation
    feedback_matches : Bool
    failure_matches : Bool
    result_matches : Bool
    } derive(Eq,
    Debug
    )

    ReplayOutcome::matches

    fn ReplayOutcome::matches(self : ReplayOutcome) -> Bool

    ReplayRecord

    pub(all) struct ReplayRecord {
    schema_version : Int
    target_name : String
    seed : Int64
    input : Bytes
    feedback_signature : FeedbackSignature
    failure_fingerprint : FailureFingerprint?
    result_digest : String?
    generation_budget : GenerationBudget
    } derive(Eq,
    Debug
    )

    ReplayRecord::decode_json

    fn ReplayRecord::decode_json(text : String, max_input_bytes? : Int, max_artifact_bytes? : Int) -> Result[ReplayRecord, ReplayError]

    ReplayRecord::encode_json

    fn ReplayRecord::encode_json(self : ReplayRecord) -> String

    ReplayRecord::new

    fn ReplayRecord::new(target_name~ : String, seed~ : Int64, input~ : Bytes, observation~ : TargetObservation, generation_budget? : GenerationBudget) -> ReplayRecord

    RuleDefinition

    pub(all) struct RuleDefinition {
    id : RuleId
    name : String?
    kind : RuleKind
    } derive(Eq,
    Debug
    )

    RuleId

    pub(all) struct RuleId(Int) derive(Eq, Hash,
    Debug
    )

    Stable integer identity of one grammar rule.

    RuleId::value

    fn RuleId::value(self : RuleId) -> Int

    RuleKind

    pub(all) enum RuleKind {
    Literal(String)
    Bytes(Array[Int])
    Integer(Int, Int)
    Dictionary(Array[String])
    Sequence(Array[RuleId])
    Choice(Array[Alternative])
    Repeat(RuleId, Int, Int)
    Optional(RuleId, Int)
    Reference(String)
    } derive(Eq,
    Debug
    )

    Composable rule kinds. References are resolved by name when the grammar is sealed, which allows explicit recursion without mutable placeholder nodes.

    RuleProperties

    pub(all) struct RuleProperties {
    rule : RuleId
    reachable : Bool
    nullable : Bool
    productive : Bool
    recursive : Bool
    minimum_bytes : Int?
    minimum_nodes : Int?
    } derive(Eq,
    Debug
    )

    ScheduleConfig

    pub(all) struct ScheduleConfig {
    base_energy : Int
    maximum_energy : Int
    novelty_bonus : Int
    discovery_bonus : Int
    failure_bonus : Int
    cost_penalty : Int
    selection_penalty : Int
    } derive(Eq,
    Debug
    )

    ScheduleConfig::default

    ScheduleDecision

    pub(all) struct ScheduleDecision {
    entry_id : Int
    energy : Int
    reason : String
    } derive(Eq,
    Debug
    )

    StrategyEvidence

    pub(all) struct StrategyEvidence {
    name : String
    executions : Int
    unique_features : Int
    unique_signatures : Int
    unique_failures : Int
    corpus_entries : Int
    } derive(Eq,
    Debug
    )

    Target

    pub struct Target {
    name : String
    evaluate : (Bytes) -> TargetObservation
    }

    Target::name

    fn Target::name(self : Target) -> String

    Target::new

    fn Target::new(name : String, evaluate : (Bytes) -> TargetObservation) -> Target

    Target::replay

    fn Target::replay(self : Target, record : ReplayRecord) -> Result[ReplayOutcome, ReplayError]

    Target::run

    fn Target::run(self : Target, input : Bytes) -> TargetObservation

    TargetObservation

    pub(all) struct TargetObservation {
    disposition : ExecutionDisposition
    features : Array[Feature]
    result_digest : String?
    cost_class : Int
    } derive(Eq,
    Debug
    )

    TargetObservation::canonical_features

    fn TargetObservation::canonical_features(self : TargetObservation) -> Array[Feature]

    TargetObservation::failure_fingerprint

    fn TargetObservation::failure_fingerprint(self : TargetObservation) -> FailureFingerprint?

    TargetObservation::feature_count

    fn TargetObservation::feature_count(self : TargetObservation) -> Int

    TargetObservation::is_failure

    fn TargetObservation::is_failure(self : TargetObservation) -> Bool

    TargetObservation::signature

    accepted

    fn accepted(features? : Array[Feature], result_digest? : String, cost_class? : Int) -> TargetObservation

    agreement_target

    fn agreement_target(name : String, targets : Array[Target], minimum_agreement? : Int) -> Target

    alternative

    fn alternative(rule : RuleId, weight? : Int, label? : String) -> Alternative

    compare_strategies

    fn compare_strategies(values : Array[StrategyEvidence]) -> String

    crossover

    fn crossover(recipient : DerivationTree, donor : DerivationTree, seed~ : Int64, config? : CrossoverConfig) -> Result[CrossoverResult, CrossoverError]

    crossover_compatible_rule_count

    fn crossover_compatible_rule_count(left : DerivationTree, right : DerivationTree) -> Int

    deterministic_permutation

    fn deterministic_permutation(seed : Int64, size : Int) -> Array[Int]

    differential_target

    fn differential_target(name : String, left : Target, right : Target, policy? : DifferentialPolicy) -> Target

    failed

    fn failed(kind : String, detail : String, features? : Array[Feature]) -> TargetObservation

    feature

    fn feature(domain : String, value : String) -> Feature

    feedback_signature

    fn feedback_signature(features : Array[Feature]) -> FeedbackSignature

    metamorphic_target

    fn metamorphic_target(name : String, base : Target, transforms : Array[MetamorphicTransform]) -> Target

    observation

    fn observation(disposition : ExecutionDisposition, features? : Array[Feature], result_digest? : String, cost_class? : Int) -> TargetObservation

    rejected

    fn rejected(reason : String, features? : Array[Feature]) -> TargetObservation

    replay_schema_version

    let replay_schema_version : Int

    run_campaign

    fn run_campaign(grammar : Grammar, target : Target, config : CampaignConfig) -> Result[CampaignResult, CampaignError]

    same_digest_transform

    fn same_digest_transform(name : String, apply : (Bytes) -> Bytes) -> MetamorphicTransform

    same_disposition_transform

    fn same_disposition_transform(name : String, apply : (Bytes) -> Bytes) -> MetamorphicTransform