git:20261008.193dd3e to git:20261009.700b6e2

5 added, 0 removed. Audit A to A.

---
name: skraft-quality-bar
description: Use before running, verifying, or reporting any quality gate. States the one permanent threshold for mutation score and line coverage, and the enforcement level of every gate. Load when about to invoke a mutation run, when deciding whether a gate blocks or merely warns, when writing or reviewing an evidence record, when a skill or descriptor appears to state a threshold of its own, and whenever a number would otherwise be copied from memory or from an older document. There are no tiers, no advisory level, and no override. Does not choose the toolchain command (resolving-stack-commands), classify survivors (mutation-testing), define the evidence schema (quality-gates-evidence-contract), or set the reviewer lens count (each review-criteria skill owns its own).
---
<!-- markdownlint-disable-file -->
# SKRAFT Quality Bar
The single place a threshold is authored. Every other mention in this framework is a
reference to this file, never a second definition.
There is no strictness dial. The bar below applies to every repository, every work
item, and every phase. A previous version of this framework carried a `depthTier`
setting that could lower it; that dial is gone, and with it the `advisory` and
`warning` levels and the rationale that used to buy an exemption.
## The bar
| Gate | Value | Scope |
| --- | --- | --- |
| Mutation score | 100% | Domain, Application |
| Mutation score | 80% | API, Infrastructure |
| Line coverage | 100% | Domain, Application |
TDD variant is Outside-In double-loop, always. `outside-in-tdd` owns the sequence.
## Enforcement
Every gate blocks. There is no advisory level, no warning level, no override, and no
rationale that grants an exemption.
| Gate | Level |
| --- | --- |
| Clean Architecture boundaries | blocking |
| TDD cycle respected | blocking |
| Test integrity | blocking |
| Mutation Domain/Application meets the bar | blocking |
| Mutation API/Infrastructure meets the bar | blocking |
| Gherkin gate (user-approved scenarios) | blocking |
| ADR for non-trivial decisions | blocking |
| Object Calisthenics (Domain) | blocking |
A gate that cannot run is not a passed gate. Report it as a failure and stop.
## Running the gate
The comparison is never made by reading a number and judging it. Each
`quality-gates-<tech>` adapter owns two durable scope configs plus deterministic runners
that return verdicts as exit codes:
1. **Core first** -- Domain and Application, expects 100.
2. **Boundary second** -- API and Infrastructure, expects 80.
Core runs first and short-circuits: there is nothing to learn from mutating adapters
while the domain is unproven. `resolving-stack-commands` detects the stack and routes
to the adapter; the adapter owns the invocation.
For .NET, [configure-mutation.sh](../quality-gates-dotnet/scripts/configure-mutation.sh)
scaffolds `stryker-config-core.json` and `stryker-config-boundary.json` at consumer
repository root. [mutation-core.sh](../quality-gates-dotnet/scripts/mutation-core.sh)
and [mutation-boundary.sh](../quality-gates-dotnet/scripts/mutation-boundary.sh) validate
and execute them. Checked-in configs are also local-debug and CI/CD interface.
For Python, [configure-mutation.mjs](../quality-gates-python/scripts/configure-mutation.mjs)
scaffolds `cosmic-ray-core.toml` and `cosmic-ray-boundary.toml`;
[mutation-gate.mjs](../quality-gates-python/scripts/mutation-gate.mjs) runs one scope per call
and carries both thresholds as literals.
+ For TypeScript with Vitest, [configure-mutation.mjs](../quality-gates-typescript/scripts/configure-mutation.mjs)
+ scaffolds `stryker.core.json` and `stryker.boundary.json`;
+ [mutation-gate.mjs](../quality-gates-typescript/scripts/mutation-gate.mjs) runs one scope per
+ call with the thresholds of [gate-policy.mjs](../quality-gates-typescript/scripts/gate-policy.mjs).
+
## Threshold flags
Stated once so recipes copy rather than invent. Adapter scripts and the config scaffold
carry each value as a literal, and guard tests assert those literals still equal the
table above — checked restatements, not independent definitions.
| Scope | Mutation | Coverage |
| --- | --- | --- |
| Domain, Application | `thresholds.break = 100` in the checked-in core Stryker config (written by the adapter's scaffold) | 100% line coverage, enforced by the adapter's coverage script |
| API, Infrastructure | `thresholds.break = 80` in the checked-in boundary config | not gated on coverage |
The runner reads the threshold from its config and exits non-zero below it; the
coverage script exits non-zero below the bar. That exit code is the verdict. A run
whose score is read from a report and judged in prose is not a gate — it is an
opinion about a gate. No caller argument sets a threshold: the scripts refuse one.