- Intake
- pull upstream sources
- extract candidate driver/workaround deltas
- canonical miner entrypoint:
python3 pipeline/agent/mine_upstream_quirks.py --source-root <upstream-root> --source-repo <repo> --source-commit <commit> --vendor <vendor> --api <api> --output bench/out/mined-quirks.json --manifest-output bench/out/mined-quirks.manifest.jsonminer output is deterministic and hash-linked (config/quirk-mining-manifest.schema.json).
- Normalize
- convert deltas into structured quirk records
- validate schema
- Verify
- apply deterministic guards for all quirks
- apply Lean obligations from
verificationModepolicy:guard_only: no Lean proof requirementlean_preferred: Lean preferred, not required in v0lean_required: proof requirement is blocking (proofLevel=proven)
- optional safety-class overrides may be configured in
gates.json; in v0 they are empty
- Bind
- generate runtime config inputs and optional validator artifacts
- build specialization targets
- target path: apply proof-driven elimination when Lean discharges a runtime condition, then hoist into artifacts/config and remove the corresponding runtime branch.
- current v0 state: keep explicit Zig runtime branches unless elimination is wired end-to-end through build/CI artifacts.
- Gate
- run schema + correctness + trace gates (blocking in v0)
- run verification + performance gates (advisory in v0)
- run drop-in compatibility gate (blocking for drop-in artifact lanes)
- current v0 CI does not execute Lean toolchain proofs as a blocking step.
- run schema hard gate:
python3 bench/schema_gate.py - run comparability parity verification gate (advisory unless explicitly enabled in gate orchestration):
python3 bench/comparability_obligation_parity_gate.py - run correctness hard gate from comparison report artifacts:
python3 bench/check_correctness.py --gates config/gates.json --quirk examples/quirks/intel_gen12_temp_buffer.json --report bench/out/dawn-vs-doe.json - run replay hard gate from comparison report artifacts:
python3 bench/trace_gate.py --report bench/out/dawn-vs-doe.json --semantic-parity-mode autoCI must run without--skip-missingand fail hard if any sample is missing or fails replay checks. For runtime-to-runtime reference lanes (for example Zig vs Lean trace parity), run with--semantic-parity-mode requiredso the gate fails unless semantic parity checks execute and pass. - run drop-in compatibility hard gate from a built shared-library artifact:
python3 bench/drop-in/dropin_gate.py --artifact runtime/zig/zig-out/lib/libwebgpu_doe.so --report bench/out/dropin_report.jsonCI must fail hard if symbol completeness, black-box behavior, or drop-in benchmark execution fails, and must emit a drop-in report on every run. - run release claimability hard gate from comparison report artifacts:
python3 bench/claim_gate.py --report bench/out/dawn-vs-doe.json --require-claimability-mode release --require-claim-status claimable --require-comparison-status comparable --require-min-timed-samples 15CI must fail hard if report claim metadata is not explicit release mode claimable/comparable. - run cycle lock + rollback hard gate for claim-lane governance:
python3 bench/cycle_gate.py --cycle config/claim-cycle.active.json --report bench/out/dawn-vs-doe.json --artifact-class claimclaim lanes must fail if contract hashes drift, comparable workload identity drifts, enabled rollback criteria trigger, or claim artifacts violate namespace policy. - benchmark and drop-in pipeline scripts timestamp output artifacts by default (
YYYYMMDDTHHMMSSZ) and place them under per-run folders (bench/out/<timestamp>/...) to avoid clobbering and keep directory ordering chronological. Release pipeline compare HTML is generated by default in the same run folder unless--no-compare-html-outputis set. For fixed report paths in manual command chains, either pass--no-timestamp-outputto the producing command or feed the resolved stamped path into gates. - each timestamped run folder emits
run_manifest.json(runType,config,fullRun,claimGateRan,dropinGateRan, and status metadata) for quick human+automation audit. - ad-hoc/manual artifact names are routed under
bench/out/scratch/<timestamp>/...to keep canonical run folders and dashboard inputs clean. - canonical CI/script entrypoint for blocking gate sequence:
python3 bench/run_blocking_gates.py --report bench/out/dawn-vs-doe.json --trace-semantic-parity-mode auto --with-comparability-parity-gate --with-dropin-gate --dropin-artifact runtime/zig/zig-out/lib/libwebgpu_doe.so --with-claim-gate --claim-require-claimability-mode release --claim-require-claim-status claimable --claim-require-comparison-status comparable --claim-require-min-timed-samples 15when--with-claim-gateis enabled,run_blocking_gates.pyalso auto-enablesstructural_equivalence_gate.pyso path asymmetry and timing-phase mismatch block the claim lane before publication. runs without--with-claim-gatevalidate blocking quality gates but are not release-claim readiness evidence; use--require-claim-gateto enforce this contract in local automation. - canonical CI/script entrypoint for full release pipeline (preflight + compare + gates):
python3 bench/run_release_pipeline.py --config bench/native-compare/compare_dawn_vs_doe.config.amd.vulkan.release.json --strict-amd-vulkan --trace-semantic-parity-mode auto --with-dropin-gate --dropin-artifact runtime/zig/zig-out/lib/libwebgpu_doe.so --with-claim-gatethe release config now targets the governed AMD Vulkan native-supported comparable contract, not the older default-only file and not the broader aspirational extended matrix. when--with-claim-gateis enabled, the pipeline now emits claim rehearsal artifacts by default: claim gate result, tail-health table, timing-invariant audit, and contract-hash manifest (disable only for diagnostics via--no-with-claim-rehearsal-artifacts). when--with-claim-gateis enabled, cycle-lock/rollback enforcement also runs by default viacycle_gate.py(disable only for diagnostics via--no-with-cycle-gate). - standalone claim rehearsal artifact builder:
python3 bench/build_claim_rehearsal_artifacts.py --report bench/out/dawn-vs-doe.json --require-comparison-status comparable --require-claim-status claimable --require-claimability-mode release --require-min-timed-samples 15 - canonical trend/substantiation entrypoint for repeated release windows:
python3 bench/run_release_claim_windows.py --config bench/native-compare/compare_dawn_vs_doe.config.amd.vulkan.release.json --windows 3 --strict-amd-vulkan --with-substantiation-gate --substantiation-policy config/substantiation-policy.jsonthis emits a timestamped window summary, per-window claim rehearsal artifacts (default-on), and a substantiation report with policy-backed report-count and profile-diversity checks. - substantiation policy can enforce target profile diversity as a hard failure:
releaseEvidence.enforceTargetUniqueLeftProfiles=truemakestargetUniqueLeftProfilesblocking (not warning-only). - for strict Dawn-vs-Doe upload comparability, fail fast if the executed
doe-zig-runtimebinary does not expose/validate upload knobs or appears older than key upload/runtime Zig sources. - comparability decisions must be emitted as machine-checkable per-workload obligations in benchmark reports; release claim gates must validate obligation schema + blocking-pass status, not only summary strings.
- native D3D12 lane contract (
doe_d3d12):- backend routing must stay direct (
backendKind=native_d3d12), with no delegate fallback on strict D3D12 lanes. - legacy simulator/runtime-state modules are not part of the D3D12 lane; command execution must flow through the instance-owned native backend implementation.
- command support must be capability-gated via
backend/common/capabilities.zig; unsupported commands fail fast with typed taxonomy and capability name. - comparability/timing labeling must be derived from shared artifact classification (
backend/common/artifact_meta.zig): GPU timestamp valid => strict; attempted-but-invalid or no-attempt => directional CPU timing classes. - the first governed D3D12 comparable workload scope is compute/upload/pipeline/p0-resource only, sourced from
bench/backend-workload-catalog.jsonand generated intobench/workloads.local.d3d12.{smoke,extended}.json. - Windows preflight is explicit and blocking before compare execution:
python3 bench/preflight_d3d12_host.py --json - first compare configs:
- smoke:
bench/native-compare/compare_dawn_vs_doe.config.local.d3d12.smoke.json - comparable:
bench/native-compare/compare_dawn_vs_doe.config.local.d3d12.extended.comparable.json - release scaffold:
bench/native-compare/compare_dawn_vs_doe.config.local.d3d12.release.json(contract only until a Windows host produces evidence)
- smoke:
- Windows handoff runner for the first governed D3D12 lane:
python3 bench/run_local_d3d12_lane.py - backend workload catalog drift is now blocked by both generation verify and catalog tests:
python3 bench/generate_backend_workloads.py --verifypython3 bench/test_backend_workload_catalog.py
- render/texture contracts remain out of scope for strict D3D12 claim lanes until native D3D12 coverage expands beyond the current compute-first backend.
- backend routing must stay direct (
- Benchmark
- run self-contained benchmark matrix
- publish deltas against Dawn/wgpu baselines
- generate post-benchmark visualization artifacts from comparison reports
- build/update tested-profile inventory + dashboard from comparison artifacts:
python3 bench/build_test_inventory_dashboard.py --report-glob "bench/out/**/dawn-vs-doe*.json"this maintains a canonical latest inventory file (bench/out/test-inventory.latest.json) plus dashboard (bench/out/test-dashboard.latest.html) and timestamped snapshots for audit. - build/update baseline trend package from comparison artifacts:
python3 bench/build_baseline_dataset.py --report-glob "bench/out/**/dawn-vs-doe*.json"this maintains timestamped JSON+markdown baseline summaries plus stable latest outputs. - include distribution diagnostics in benchmark reporting (ECDF overlays, KS/p-value, Wasserstein, superiority probability, and bootstrap CI summaries)
- claimability rules (sample floors, tail consistency, structural equivalence) are defined in
docs/performance-strategy.md - run claim-mode (
--claimability local|release) for benchmark artifacts that will be used in performance claims
- Release
- commit only when blocking gates are green
- mandatory release precondition in CI: gate scripts must fail hard when schema, correctness, replay, drop-in compatibility, or release-claimability checks fail.
- scheduled claim-trend publication should run the substantiation gate policy over repeated windows; single-run release CI remains focused on per-run blocking gates.
v0 is speed-first. Blocking vs advisory:
- Schema gate: blocking
- Correctness gate: blocking
- Trace gate: blocking
- Drop-in compatibility gate: blocking for artifact-lane acceptance (
dropin_gate.py) - Verification gate: blocking (proof artifact must pass comptime validation when
-Dlean-verified=true; per-quirk obligation is blocking whenverificationMode=lean_required) - Structural work equivalence gate: blocking for claimable results
- both sides must execute the same commands with matching dispatch counts (all domains, not only compute)
- both sides must report non-trivial timing in the same phases (setup, encode, submit_wait)
- hardware-path asymmetries must be annotated with
pathAsymmetry: trueand transferability caveats - universally-zero timing phases on one side while the other reports material values is a blocking failure
- see
bench/benchmark-writing-guide.mdsection 5.1 for full checklist
- Performance gate: advisory (ratchet report)
This keeps process weight aligned with v0 maturity.
Promoted Track B (modules) follow the same blocking schema, correctness, and trace requirements as other core runtime modules. python3 bench/run_blocking_gates.py --with-modules enables those promoted-module gates in the canonical blocking runner. Track B (modules) performance gates remain advisory and are not required for M6 governance promotion, but no Track B module may carry claimability assertions until explicit advisory performance coverage is added.
Promoted Track A (browser) diagnostics are governed through the lane-wrapper browser gate in bench/browser/browser_gate.py. python3 bench/run_blocking_gates.py --with-browser-gate runs the macOS/host browser preflight plus fresh Playwright smoke and strict layered-superset validation with required browser promotion approvals. That default browser gate remains diagnostic-only by contract.
Track A (browser) claimability is now a separate repeated-window lane in bench/browser/browser_claim_gate.py, controlled by config/browser-claim-policy.json. python3 bench/run_blocking_gates.py --with-browser-claim-gate runs the claim gate instead of the single-window browser gate, aggregates repeated strict browser windows, and requires positive local-claim percentiles before reporting claimStatus=claimable. Browser claimability remains local-only until a release-grade browser claim policy is explicitly added.
verificationModeis the primary selector for Lean obligation.safetyClasscan impose stricter requirements only ifrequireProofLevelForSafetyClassis non-empty.- If both apply, the stricter
proofLevelrequirement wins.
- Runtime/hot-path behavior should land in Zig first with deterministic trace evidence.
- Lean proofs may eliminate runtime checks by moving decisions to bind/build artifacts.
- Elimination requires deleting the runtime branch, not leaving placeholder behavior.
- If proof is unavailable, keep explicit Zig behavior and benchmark it.
Benchmark categories:
- command encode overhead
- validation overhead
- submit latency (
p50,p95,p99) - allocation churn
Each benchmark run must emit reproducible metadata from run-metadata.schema.json.
Matrix definition comes from config/benchmarks.json.
Performance ratchet uses submit_latency_p95_ms in gates.json.
Fawn removes recurring human bureaucracy, not machine-readable controls.
- no recurring committee approval loops for routine decisions
- policies are explicit in config and executed automatically
- human escalation is reserved for policy exceptions
Tracing is binary and deterministic:
- fixed ring buffer settings from
config/tracing.json - required event fields:
module,opCode,seq,timestampMonoNs,hashes - crash artifact: binary dump + metadata JSON
- replay tool must reproduce module sequence and hash chain
- semantic operator debugging extends the same deterministic contract: semantic IDs must be explicit command-stream inputs, trace rows must preserve them verbatim, and any capture/repro artifact emitted from a trace run must be hash-linked back to the originating trace anchor and shader manifest.
Some thresholds in gates.json are bootstrap placeholders.
Rules:
- placeholders must be marked explicitly in config
- placeholders are non-blocking in v0
- thresholds become blocking only after baseline stabilization window
- placeholder policy applies to thresholds/reports only; runtime execution paths must be explicit implementations or explicit unsupported errors
Toolchains are pinned in toolchains.json.
Upgrade flow:
- open dedicated upgrade branch
- bump toolchain config
- run blocking + advisory gates
- compare delta reports
- merge only if blocking gates pass
Apple Metal lanes are additive and must not weaken AMD Vulkan strict defaults.
- preflight
- run
python3 bench/preflight_metal_host.py
- compare
- use Apple Metal config presets:
bench/native-compare/compare_dawn_vs_doe.config.apple.metal.extended.comparable.json- for release-claim checks, reuse the same config with
--claimability release(and optional explicit--outpath) - optional Dawn-baseline lane forcing for baseline checks:
--local-metal-lane metal_dawn_release - render/bundle rows may still select encode-only timing for strict comparability, but claim evaluation must use
timingInterpretation.headlineProcessWallwhenselectedTiming.scopeClass=narrow-hot-path - repeat-asymmetric rows must normalize both selected operation timing and
headlineProcessWallto one workload unit viacommandRepeatbefore comparability or claimability is evaluated - strict comparable workloads may now declare
strictNormalizationUnitin the workload contract when the comparable unit is not raw command-row count:dispatch: divisor must match repeated dispatch countcycle: divisor must match repeated full-workload cycles- otherwise strict divisors default to repeated command-row count gate evaluation must reject any comparable row whose configured divisor disagrees with the trace-derived physical-op count for the declared unit.
- blocking gates
- run backend/timing/sync/shader checks through
run_blocking_gates.py:--with-backend-selection-gate--with-metal-sync-conformance-gate--with-metal-timing-policy-gate--with-shader-artifact-gate--with-spirv-val-gate(validates .spv binaries with spirv-val; skips when not installed)
- strict lane policy
- strict Apple Metal lanes must fail on fallback (
fallbackUsed=true) - strict release claims should require backend telemetry and backend identity
doe_metal - shader manifest checks may be required per lane (
metal_doe_release,metal_doe_app)
- cutover verification (metal_doe_app)
- for app-lane rollout verification, run local-metal gate execution with explicit lane override:
--with-local-metal-gates --local-metal-lane metal_doe_app - validate rollback readiness by running
bench/cycle_gate.py(via release pipeline with--with-cycle-gate --cycle-enforce-rollbacks) under the same comparable/release evidence policy. - runtime backend routing is strict no-fallback by contract across all lanes (
allowFallback=false,strictNoFallback=trueinconfig/backend-runtime-policy.json).
AMD Vulkan extended lanes are additive and must not weaken the governed AMD Vulkan release defaults.
- preflight
- run
python3 bench/preflight_vulkan_host.py
- compare
- use AMD Vulkan extended config presets:
bench/native-compare/compare_dawn_vs_doe.config.amd.vulkan.extended.comparable.jsonlegacy compatibility alias for the strict extended comparable contractbench/native-compare/compare_dawn_vs_doe.config.amd.vulkan.extended.strict.directional.jsonbench/native-compare/compare_dawn_vs_doe.config.amd.vulkan.extended.strict.comparable.jsonbench/native-compare/compare_dawn_vs_doe.config.amd.vulkan.extended.strict.release.json
- blocking gates
- run backend/sync/timing/shader checks in
bench/run_blocking_gates.py:--with-backend-selection-gate--with-vulkan-sync-conformance-gate--with-vulkan-timing-policy-gate--with-shader-artifact-gate--with-spirv-val-gate(validates .spv binaries with spirv-val; skips when not installed)
- strict lane policy
- strict AMD Vulkan extended lanes must fail on fallback (
fallbackUsed=true) - strict AMD Vulkan extended release claims should require backend telemetry and backend identity
doe_vulkan - shader manifest checks may be required per lane (
vulkan_doe_comparable,vulkan_doe_release)
This flow is additive and does not replace blocking v0 runtime gates. Its role is external claim scoping and repeatable buyer-facing evidence packaging.
- produce strict compare evidence
- run
bench/run_release_pipeline.py(orbench/run_market_readiness_bundle.pywrapper) on a strict comparable config.
- scope claim statements
- run
bench/build_claim_scope_report.pyand require:comparisonStatus=comparableclaimStatus=claimableclaimabilityPolicy.mode=release(or lane-appropriate mode)
- every external statement must cite workload/domain + timing source/class + backend profile + artifact path.
- publish runtime footprint evidence
- run
bench/measure_runtime_footprint.pyand publish raw + stripped sizes and dependency counts. - if build timing claims are made, include
--doe-build-cmdand--dawn-build-cmdmeasured wall-time outputs.
- publish CTS trend evidence
- run
bench/run_cts_subset.pywith a versioned query config (for examplebench/cts_subset.fawn-node.json). - report exact pass/fail counts and query list used.
- publish model ceiling matrix (when AI/ML positioning is in scope)
- run
bench/build_model_capacity_matrix.pywith measured row inputs (hardware, model, quantization, status, TTFT/decode/prefill, peak VRAM, artifact path). - do not generalize beyond measured rows.
- canonical one-command wrapper
- use
bench/run_market_readiness_bundle.pyto run steps 1-5 and emit a linked manifest.