flaker core computation engine
Upgrading from 0.0.x / 0.1.x? See docs/how-to-use.md#config-migration for the full key rename map. Starting with 0.2.0, the CLI refuses to start on legacy configs and points to the migration guide.Upgrading from 0.4.x? See docs/migration-0.4-to-0.5.md or docs/migration-0.4-to-0.5.ja.md. 0.5.x keeps existing profiles working, but the recommended user-facing commands are now gate-oriented.Upgrading from 0.12.x? 0.13.0 is a breaking release: --profile / [profile.*] / FLAKER_PROFILE are gone, replaced by --gate / [gate.iteration|merge|release] / FLAKER_GATE; the random, gbdt, and coverage-guided strategies, cluster_mode, model_path, [coverage], adaptive* keys, dev train, and the ops command group are removed. See docs/migration-0.12-to-0.13.md / docs/migration-0.12-to-0.13.ja.md.
pnpm add -D @mizchi/flakerpnpm dlx @mizchi/flaker --help# In Claude Code
/plugin marketplace add mizchi/flaker
/plugin install flaker@flakerimport {
"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)
}moon run src/cmd/flaker --target js -- --help
moon run src/cmd/flaker --target native -- --version| Mental model | Current flaker shape (0.14.0) |
|---|---|
| Iteration Gate | [gate.iteration] |
| Merge Gate | [gate.merge] |
| Release Gate | usually a full run, backed by [gate.release] or a dedicated release workflow |
| Observation loop | flaker apply (runs import --ci when GITHUB_TOKEN is set) + flaker status |
| Triage loop | flaker status --gate merge --detail + flaker status --list flaky (apply with [quarantine].auto=true also handles suggest/apply) |
| Incident loop | flaker debug retry / debug confirm / debug diagnose |
pnpm add -D @mizchi/flaker
pnpm flaker init --adapter <playwright|vitest|jest|junit> --runner <same or actrun>
# edit [affected].resolver in flaker.toml (workspace | glob | bitflow)
pnpm flaker doctor
pnpm flaker plan # preview what apply will do
pnpm flaker apply # converge (safe to re-run)
pnpm flaker status # dashboard + promotion driftCanonical command forms (0.14.0)The primary surface is: init, plan, apply, status, run, calibrate, doctor, debug, query, explain, import, report. dev is a hidden maintainer-only group.
Canonical (0.14.0) Notes flaker apply reconciles the repo to flaker.toml; runs CI import + calibrate internally when needed flaker calibrate [--window-days <n>] [--dry-run] [--json] recommend and write [sampling] flaker import --ci [--days <n>] [--branch-filter <branch>] pull recent GitHub Actions results (needs GITHUB_TOKEN) flaker status --markdown / flaker explain insights weekly review artifacts flaker debug retry / debug confirm / debug diagnose incident investigation flaker apply --output <file> saves ApplyArtifact JSON flaker plan --output <file> saves PlanArtifact JSON The full list of 0.12.x forms these replace (and why) is in docs/migration-0.12-to-0.13.md. See docs/migration-0.12-to-0.13.md for the full breaking-change list and error messages.
flaker init --owner your-org --name your-repoexport GITHUB_TOKEN=$(gh auth token)
flaker import --ci --days 30flaker import <file> --adapter playwright --commit "$(git rev-parse HEAD)"flaker import <file> --adapter playwright --source ci --commit <sha>[runner]
type = "playwright"
command = "pnpm exec playwright test -c playwright.config.ts"
[runner.actrun]
workflow = ".github/workflows/ci.yml"
local = true
trust = true
# job = "e2e"flaker status
flaker status --gate merge --detail --json
flaker status --list flaky
flaker status --list quarantinedflaker explain reason
flaker explain insights
flaker explain cluster
flaker status --markdown
flaker status --markdown > .artifacts/flaker-review.mdflaker run --dry-run --strategy hybrid --count 25
flaker run --dry-run --strategy affected --changed src/foo.ts
flaker run --dry-run --gate iteration --changed src/foo.tsflaker run --strategy hybrid --count 25
flaker run --strategy affected --changed src/foo.ts
flaker run --gate iteration --changed src/foo.ts
flaker run --runner actrun| Gate | Config section | Purpose |
|---|---|---|
| iteration | [gate.iteration] | Fast local feedback for the author |
| merge | [gate.merge] | PR / mainline gate |
| release | [gate.release] | Full or near-full verification |
# Auto-detects the gate: merge on CI, iteration otherwise
flaker run
# Explicit gate selection
flaker run --gate iteration
flaker run --gate merge
flaker run --gate release[runner]
type = "playwright"
command = "pnpm exec playwright test -c playwright.config.ts"
flaky_tag_pattern = "@flaky"
[gate.release]
strategy = "full"
[gate.merge]
strategy = "hybrid"
sample_percentage = 30
skip_flaky_tagged = true
[gate.iteration]
strategy = "affected"
max_duration_seconds = 60
fallback_strategy = "weighted"
skip_flaky_tagged = trueflaker status --list flaky
flaker status --markdown > .artifacts/flaker-weekly.mdflaker run --dry-run --gate iteration --changed src/foo.ts
flaker run --gate iteration --changed src/foo.ts- name: Run flaker
run: flaker run --gate merge
- name: Post PR comment
if: github.event_name == 'pull_request'
run: |
flaker report summary --adapter vitest --input report.json --pr-comment \
| gh pr comment ${{ github.event.pull_request.number }} --body-file -
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}flaker quarantine suggest --json --output .artifacts/quarantine-plan.json
flaker quarantine apply --from .artifacts/quarantine-plan.json --create-issuesflaker import --ci --days 30
flaker import <file> --adapter playwrightflaker run --dry-run --strategy weighted --count 20
flaker run --dry-run --strategy affected
flaker run --dry-run --strategy hybrid --count 50
flaker run --strategy hybrid --count 50
flaker run --strategy affected --changed src/foo.tsResolution order (highest to lowest):
1. Explicit CLI flag (--strategy, --percentage, --count)
2. [gate.<name>] in flaker.toml (via --gate or auto-detection)
3. [sampling] in flaker.toml (project default)
4. Built-in defaults
Notes:
--count overrides --percentage when both are given
--changed overrides git auto-detection
--dry-run suppresses execution, still records selection telemetry
--explain can be combined with --dry-run or a real runflaker status --list flaky
flaker explain reason
flaker status --markdown
flaker calibrate
flaker query "SELECT * FROM test_results LIMIT 20"# Remote: triggers workflow_dispatch, waits for result
flaker debug confirm "tests/api.test.ts:handles timeout"
flaker debug confirm "tests/api.test.ts:handles timeout" --repeat 10
# Local: runs via test runner directly
flaker debug confirm "tests/api.test.ts:handles timeout" --runner local# Re-run failed tests from most recent CI failure
flaker debug retry
# From a specific workflow run
flaker debug retry --run 12345678flaker quarantine suggest --json --output .artifacts/quarantine-plan.json
flaker quarantine apply --from .artifacts/quarantine-plan.json --create-issues
flaker policy check
flaker exec affected --changed src/foo.tsflaker report summary --adapter vitest --input report.json --markdown
flaker report summary --adapter vitest --input report.json --pr-comment
flaker report diff --base base.json --head head.json[repo]
owner = "your-org"
name = "your-repo"
[storage]
path = ".flaker/data.duckdb"
[adapter]
type = "playwright"
[runner]
type = "playwright"
command = "pnpm exec playwright test"
flaky_tag_pattern = "@flaky"
[affected]
resolver = "workspace"
[flaky]
window_days = 14
detection_threshold_ratio = 0.02
[quarantine]
auto = true
flaky_rate_threshold_percentage = 30
min_runs = 10
[sampling]
strategy = "hybrid"
sample_percentage = 30
holdout_ratio = 0.1
co_failure_window_days = 90
[gate.release]
strategy = "full"
[gate.merge]
strategy = "hybrid"
sample_percentage = 30
skip_flaky_tagged = true
[gate.iteration]
strategy = "affected"
max_duration_seconds = 60
fallback_strategy = "weighted"
skip_flaky_tagged = truenode_modules/@mizchi/flaker/dist/cli/main.jsfn build_affected_report(targets : Array[AffectedTargetInput], direct_selections : Array[AffectedDirectSelectionInput], transitive_tasks : Array[AffectedTransitiveTaskInput], unmatched : Array[String]) -> AffectedReportCoreOutputfn build_sampling_meta(history_rows : Array[SamplingHistoryRowInput], listed_tests : Array[SamplingListedTestInput]) -> Array[TestMeta]fn compute_quarantine_exit_code(results : Array[QuarantineRuntimeResultInput], fallback_exit_code : Int) -> Intfn find_affected_nodes(graph : DependencyGraphInput, changed_files : Array[String]) -> Array[String]fn find_matching_quarantine(entries : Array[QuarantineEntryInput], task_id : String, spec : String, title : String) -> Intfn get_affected_test_patterns(graph : DependencyGraphInput, affected_ids : Array[String]) -> Array[String]fn run_config_check(listed_tests : Array[ConfigCheckListedTestInput], discovered_specs : Array[String], task_definitions : Array[ConfigCheckTaskDefinitionInput]) -> ConfigCheckCoreOutputfn summarize_quarantine(entries : Array[QuarantineEntryInput], tasks : Array[QuarantineTaskOwnershipInput], existing_specs : Array[String], now_date : String, expires_soon_days : Int) -> QuarantineSummaryCoreOutput