Sign in

    flaker

    flaker core computation engine

    Download zip
    Author
    Version
    0.0.1
    License
    MIT
    Last updated
    6 months ago
    Downloads
    70

    #flaker

    flaker is a test-intelligence toolkit for:

    • sampling a smaller local test run from history and changed files
    • detecting flaky tests in noisy CI environments
    • measuring how well local sampled runs predict CI
    • embedding the same core logic in MoonBit as a library

    It is designed for repositories where:

    • the full test suite is too expensive to run on every change
    • CI failures are noisy because flaky tests are mixed with real regressions
    • developers need a smaller local test run that still correlates well with CI

    flaker helps answer:

    • Which tests should I run for this change?
    • How much can I shrink local execution without losing too much confidence?
    • Which tests are actually flaky?
    • How well does local sampled execution predict CI outcomes?

    #Install as a CLI

    pnpm add -D @mizchi/flaker

    Or run it without installing:

    pnpm dlx @mizchi/flaker --help

    Requirements:

    • Node.js 24+
    • pnpm 10+

    #Use as a MoonBit Library

    flaker also publishes a MoonBit library surface at mizchi/flaker.

    The root package re-exports both:

    • pure computation APIs
    • the shared contract types they consume and return

    If you prefer a stricter import boundary, the same types are still available from mizchi/flaker/contracts.

    import {
    "mizchi/flaker" @flaker,
    }

    test "sample from historical runs" {
    let meta = @flaker.build_sampling_meta(
    [
    @flaker.SamplingHistoryRowInput::{
    suite: "tests/login.spec.ts",
    test_name: "login works",
    task_id: Some("web-login"),
    filter: None,
    variant: None,
    test_id: None,
    status: "passed",
    retry_count: 0,
    duration_ms: 1200,
    created_at: "2026-04-03T00:00:00.000Z",
    },
    ],
    [
    @flaker.SamplingListedTestInput::{
    suite: "tests/login.spec.ts",
    test_name: "login works",
    task_id: Some("web-login"),
    filter: None,
    variant: None,
    test_id: None,
    },
    ],
    )

    let sampled = @flaker.sample_weighted(meta, count=1, seed=1UL)
    assert_eq(sampled.length(), 1)
    }

    The root library surface intentionally re-exports pure logic only:

    • flaky detection: detect_flaky
    • sampling: build_sampling_meta, sample_random, sample_weighted, sample_hybrid
    • affected analysis: resolve_affected, build_affected_report, build_affected_report_from_input
    • stable identity: create_stable_test_id, resolve_test_identity
    • graph helpers: find_affected_nodes, expand_transitive, topological_sort
    • report reducers: summarize_report, classify_report_diff, aggregate_report
    • policy: summarize_quarantine, compute_quarantine_exit_code, run_config_check
    • metrics: build_sampling_kpi

    Contracts remain separate so the API boundary stays explicit and reusable from other packages.

    #Experimental Direct MoonBit CLI

    The MoonBit command package at mizchi/flaker/cmd/flaker is now directly executable on both JS and native targets:

    moon run src/cmd/flaker --target js -- --help moon run src/cmd/flaker --target native -- --version

    This direct entrypoint is intentionally narrow for now:

    • --help
    • --version
    • JS bridge exports used by the npm CLI

    Host and integration features such as GitHub collection, DuckDB-backed storage, artifact ingestion, and archive handling will be migrated incrementally through target-specific _js.mbt / _native.mbt modules.

    #Core Workflow

    flaker is most useful when you repeat this loop:

    1. Collect or import test results from CI and local runs.
    2. Build history for flaky detection and sampling.
    3. Ask flaker to choose a smaller local test set.
    4. Run the sampled tests and compare local outcomes with CI.
    5. Evaluate whether the sampling strategy is actually trustworthy.

    #Quick Start

    #1. Initialize

    flaker init --owner your-org --name your-repo

    This creates flaker.toml.

    #2. Collect test history

    From GitHub Actions:

    export GITHUB_TOKEN=$(gh auth token) flaker collect --last 30

    From a local report file:

    flaker import report.json --adapter playwright --commit "$(git rev-parse HEAD)"

    From actrun local history:

    flaker collect-local --last 20

    #3. Inspect flakiness

    flaker flaky flaker reason flaker eval

    Useful evaluation outputs:

    flaker eval --json flaker eval --markdown --window 7

    The markdown mode is meant for weekly review notes. It summarizes:

    • health score
    • flaky counts
    • local/CI sampling correlation
    • average sample ratio
    • average saved minutes
    • fallback rate

    #4. Sample tests before pushing

    flaker sample --strategy hybrid --count 25 flaker sample --strategy affected --changed src/foo.ts

    #5. Sample and execute

    flaker run --strategy hybrid --count 25 flaker run --strategy affected --changed src/foo.ts

    flaker run stores the local sampled run and records sampling telemetry so you can later measure:

    • P(CI pass | local pass)
    • P(CI fail | local fail)
    • false negatives / false positives
    • average saved minutes

    Start with advisory mode, not CI gating.

    The most practical rollout looks like this:

    • use flaker run --strategy hybrid --count N locally
    • keep full CI as the source of truth
    • collect local and CI results into the same database
    • review flaker eval weekly
    • only tighten the workflow after local-to-CI correlation looks strong

    This works best in repositories with:

    • long CI times
    • flaky tests
    • structured reports such as Playwright JSON, JUnit XML, or Vitest JSON

    #Main Commands

    #Collection and import

    flaker collect flaker collect-local flaker import report.json --adapter playwright

    #Sampling and execution

    flaker sample --strategy random --count 20 flaker sample --strategy weighted --count 20 flaker sample --strategy affected flaker sample --strategy hybrid --count 50 flaker run --strategy hybrid --count 50 flaker run --strategy affected --changed src/foo.ts

    #Analysis

    flaker flaky flaker reason flaker eval flaker query "SELECT * FROM test_results LIMIT 20"

    #Policy and ownership

    flaker quarantine flaker check flaker affected --changed src/foo.ts

    #Minimal Configuration

    [repo] owner = "your-org" name = "your-repo" [storage] path = ".flaker/data.duckdb" [adapter] type = "playwright" [runner] type = "vitest" command = "pnpm vitest" [affected] resolver = "workspace" [flaky] window_days = 14 detection_threshold = 2.0 [quarantine] auto = true flaky_rate_threshold = 30.0 min_runs = 10

    #Docs

    #Release

    The published npm entry point is:

    node_modules/@mizchi/flaker/dist/cli/main.js

    The package is built with Rolldown and includes the bundled MoonBit core in dist/moonbit/flaker.js.

    AffectedDirectSelectionInput

    Shared data contracts

    AffectedReportCoreOutput

    Shared data contracts

    AffectedReportInput

    Shared data contracts

    AffectedReportSummaryOutput

    Shared data contracts

    AffectedSelectionOutput

    Shared data contracts

    AffectedTargetInput

    Shared data contracts

    AffectedTransitiveTaskInput

    Shared data contracts

    ConfigCheckCoreOutput

    Shared data contracts

    ConfigCheckIssueOutput

    Shared data contracts

    ConfigCheckListedTestInput

    Shared data contracts

    ConfigCheckSummaryOutput

    Shared data contracts

    ConfigCheckTaskDefinitionInput

    Shared data contracts

    ConfigOwnershipClaimOutput

    Shared data contracts

    ConfigOwnershipEntryOutput

    Shared data contracts

    ConfigTaskSummaryOutput

    Shared data contracts

    DependencyGraphInput

    Shared data contracts

    DetectInput

    Shared data contracts

    DetectOutput

    Shared data contracts

    EvalCommitSignalInput

    Shared data contracts

    FlakyResult

    Shared data contracts

    GraphNodeInput

    Shared data contracts

    QuarantineEntryInput

    Shared data contracts

    QuarantineIssueOutput

    Shared data contracts

    QuarantineModeCountsOutput

    Shared data contracts

    QuarantineRuntimeResultInput

    Shared data contracts

    QuarantineScopeCountsOutput

    Shared data contracts

    QuarantineSummaryCoreOutput

    Shared data contracts

    QuarantineTaskOwnershipInput

    Shared data contracts

    ReportAggregateOutput

    Shared data contracts

    ReportAggregateShardInput

    Shared data contracts

    ReportAggregateUnstableBuckets

    Shared data contracts

    ReportAggregateUnstableStatusInput

    Shared data contracts

    ReportDiffBuckets

    Shared data contracts

    ReportDiffStatusInput

    Shared data contracts

    ReportFileTotalsOutput

    Shared data contracts

    ReportSummaryOutput

    Shared data contracts

    ReportSummaryTestInput

    Shared data contracts

    ReportTotalsInput

    Shared data contracts

    ResolvedQuarantineEntryOutput

    Shared data contracts

    ResolvedStableTestIdentityOutput

    Shared data contracts

    ReverseDepEntry

    Shared data contracts

    SamplingHistoryRowInput

    Shared data contracts

    SamplingKpiConfusionMatrixOutput

    Shared data contracts

    SamplingKpiMissesOutput

    Shared data contracts

    SamplingKpiOutput

    Shared data contracts

    SamplingKpiSignalOutput

    Shared data contracts

    SamplingListedTestInput

    Shared data contracts

    StableTestIdentityInput

    Shared data contracts

    StableVariantEntryInput

    Shared data contracts

    TestMeta

    Shared data contracts

    TestRunEntry

    Shared data contracts

    compute_quarantine_exit_code

    fn compute_quarantine_exit_code(results : Array[
    QuarantineRuntimeResultInput
    ], fallback_exit_code : Int) -> Int

    create_stable_test_id

    expand_transitive

    fn expand_transitive(graph :
    DependencyGraphInput
    , initial : Array[String]) -> Array[String]

    find_affected_nodes

    fn find_affected_nodes(graph :
    DependencyGraphInput
    , changed_files : Array[String]) -> Array[String]

    find_matching_quarantine

    fn find_matching_quarantine(entries : Array[
    QuarantineEntryInput
    ], task_id : String, spec : String, title : String) -> Int

    get_affected_test_patterns

    fn get_affected_test_patterns(graph :
    DependencyGraphInput
    , affected_ids : Array[String]) -> Array[String]

    is_blocking_failure

    resolve_affected

    fn resolve_affected(workflow_text : String, changed_paths : Array[String]) -> Array[String]

    Parse a Starlark workflow definition and find affected test targets given a list of changed file paths. Returns task IDs that are directly matched or transitively dependent.

    sample_hybrid

    fn sample_hybrid(meta : Array[
    TestMeta
    ], affected_suites~ : Array[String], count~ : Int, seed~ : UInt64) -> Array[
    TestMeta
    ]

    sample_random

    fn sample_random(meta : Array[
    TestMeta
    ], count~ : Int, seed~ : UInt64) -> Array[
    TestMeta
    ]

    sample_weighted

    fn sample_weighted(meta : Array[
    TestMeta
    ], count~ : Int, seed~ : UInt64) -> Array[
    TestMeta
    ]

    topological_sort

    Source Files

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io