audit-harness — @intentsolutions/audit-harness one-pager + operator audit + changelog
Deterministic test-enforcement toolkit — hash-pinned policy, escape-scan refusal gates, CRAP scoring, architecture checks, and signed evidence emission, installed in the repo it governs.
A zero-runtime-dependency CLI (Node dispatcher + bash/Python scripts) that makes test-quality policy enforceable on fresh clones. Companion to the audit-tests and implement-tests Claude Code skills, and the deterministic-gates layer of the Intent Eval Platform — but usable standalone in any repo.
Links:
- GitHub: https://github.com/jeremylongshore/intent-audit-harness
- npm: https://www.npmjs.com/package/@intentsolutions/audit-harness
AI-assisted repositories need enforcement that travels with the code. A coding agent (or a hurried human) can lower a coverage threshold, delete a failing test, or relax an architecture rule in the same diff that adds a feature — and review does not reliably catch it. Quality gates that live on one developer's machine, or in a globally-installed skill, do not reproduce on a fresh clone, so the policy is unenforceable exactly where it matters: in someone else's CI.
Install the harness in the target repo and pin the policy. Engineer-owned files (tests/TESTING.md, feature files, architecture configs, mutation configs) are hashed into a committed .harness-hash manifest. Any diff that changes their content without a fresh, deliberate audit-harness init is caught at pre-commit and in CI and REFUSED. Around that core, the CLI ships deterministic gates (escape-scan, CRAP, architecture, bias, Gherkin lint) and read-only audit verbs (classify, conform, audit, scan, currency) that emit machine-readable gate-result/v1 rows suitable for signing as in-toto evidence.
The rule the harness enforces: policy changes must be conscious, not silent. AI agents stay useful — they can read policy and implement within constraints. What they cannot do is silently weaken the constraints.
| Question | Answer |
|---|---|
| Who | Teams running AI-assisted development that need test policy enforced in-repo; consumed by the Intent Eval Platform repos and the audit-tests / implement-tests Claude Code skills |
| What | An 18-command CLI: hash-pin (verify/init/list), escape-scan, cred-gate, arch, bias, gherkin-lint, crap, emit-evidence, migration-notes, plus read-only audit verbs classify, conform, audit, scan, fp-rate, currency, gen-layer-applicability |
| When | Pre-commit hooks (escape-scan + verify), CI on every PR (verify + range escape-scan), nightly self-check; audit verbs on demand |
| Where | Installed in the target repo via npm, PyPI, crates.io, or curl-vendored into .audit-harness/ for any other ecosystem |
| Why | Enforcement must travel with the code — fresh clones reproduce every gate, and thresholds are read from the repo's own tests/TESTING.md, never hardcoded |
| Layer | Technology |
|---|---|
| CLI dispatcher | Node ≥ 18, zero runtime dependencies (bin/audit-harness.js, thin spawn wrapper) |
| Gate scripts | Bash + Python 3 stdlib (scripts/*.sh, scripts/*.py) — the canonical implementations |
| Schemas | JSON Schema: audit-profile/v1 + canonical gate registry, conform/v1 content-addressed artifact schemas, currency pin relation |
| Evidence | in-toto Statement v1 envelope; gate-result/v1 predicate (canonical schema in @intentsolutions/core) |
| Distribution | npm (@intentsolutions/audit-harness) + PyPI (intent-audit-harness) + crates.io (intent-audit-harness) + install.sh vendoring |
| CI | GitHub Actions — 3-Node matrix (18/20/22), pinned shellcheck v0.10.0 + ruff 0.15.4, nightly cron |
| Release | Tag-triggered release.yml, npm publish --provenance (sigstore, OIDC) |
- Refuse-at-pre-commit escape detection.
escape-scanclassifies diff hunks against an escape grammar: exit 0 clean, exit 1 CHALLENGE (requires an engineer-approved comment), exit 2 REFUSE (pipeline halted). Threshold-lowering, test deletion, and architecture-rule bypass are caught before they merge. - Hash-pinned policy. Pinned files changed without re-init →
HARNESS_TAMPERED(exit 2) blocks the PR. The harness self-pins its own scripts and dispatcher via.harness-hash-extra-patterns, so a silent edit to the gate that does the refusing is itself refused. - Golden-master suites. The raw stdout of
gherkin-lintandcrap-score --jsonis pinned byte-stable against a deliberate-failure corpus — a silent reshape of scorer output (renamed field, dropped WARN line) fails CI even when the per-row schema gate cannot see it. - Reproducible evidence by design.
conformvalidates artifacts against schemas bundled in the harness (never live-fetched), records each schema's sha256 in the row'spolicy_hash, and uses an embedded subset validator instead of ajv so the same commit + same harness version always produce an identical verdict. - Read-only audit verbs.
classify/conform/audit/scan/currencynever write to the target repo, andauditdeliberately does not execute the repo's test suite — it reports test-layer presence; execution verdicts stay in the repo's own CI. - Safety levers.
AUDIT_HARNESS_DISABLE=1kill-switch,AUDIT_HARNESS_TIMEOUTper-command supervision (hung gate killed, exit 124), and an engineer-owned.audit-harness.ymlper-repo override.
The design rule is explicit: scripts are the source of truth. bin/audit-harness.js is a ~200-line dispatcher that resolves a command name to a canonical bash or Python implementation in scripts/ and spawns it with inherited stdio. There is no TypeScript port and no npm dependency — dependencies and devDependencies are empty, and the published tarball contains only bin/, scripts/, schemas/, docs/, and the license/changelog files. This is what makes the same CLI surface shippable identically through npm, PyPI, crates.io, and a curl-vendored .audit-harness/ tree.
Command surface (18 commands):
| Command | Script | Purpose |
|---|---|---|
verify / init / list |
harness-hash.sh |
Verify / (re-)pin / enumerate the hash-pinned policy manifest |
escape-scan |
escape-scan.sh |
Scan a diff (--staged, --range A..B, stdin, patch file) for escape attempts |
cred-gate |
cred-gate.sh |
Provider-credential PASS/FAIL gate — FAILs (exit 1) if a declared secret value leaks verbatim, a known provider-key shape is embedded, or the artifact serializes the process environment; offline + read-only |
arch |
arch-check.sh |
Language-appropriate architecture-rule checker (dependency-cruiser / import-linter / ArchUnit / deptrac / arch-go) |
bias |
bias-count.sh |
Count test-bias patterns (tautology, smoke-only, …) |
gherkin-lint |
gherkin-lint.sh |
Advisory Gherkin quality check |
crap |
crap-score.py |
CRAP (complexity × coverage) scorer — Python, Go, JS/TS, Rust backends |
emit-evidence |
emit-evidence.sh |
Wrap a gate-result JSON envelope in an in-toto Statement v1 (predicate https://evals.intentsolutions.io/gate-result/v1) |
migration-notes |
migration-notes.py |
Read-only adopter-facing migration-notes generator — turns CHANGELOG.md + SEMVER.md into a single migration doc per version boundary; --json emits a migration-notes/v1 envelope; surfaces authored release-log text, never fabricates steps |
classify |
classify.py |
Read-only repo classifier → audit-profile/v1 (UNION of detected classifications + resolved gate set, registry_hash recorded) |
conform |
conform.py |
Read-only conformance gate-runner → gate-result/v1 rows against bundled content-addressed schemas |
audit |
audit.py |
Read-only testing-depth gate-runner — per-pyramid-layer presence heuristics; --deep adds crap-score |
scan |
scan.py |
Read-only security/hygiene/skill-quality gate-runner — shells out to gitleaks / osv-scanner / semgrep / syft / markdownlint / lychee; missing tool → ADVISORY indeterminate, never a false FAIL |
fp-rate |
fp-rate.py |
Measures per-gate false-positive/false-negative rate over a labeled corpus — the metric gating advisory→blocking promotion (≤ 5% bar) |
currency |
currency.py |
Advisory upstream-currency report from a per-upstream pin relation; no exit-code authority (always exit 0), no live-fetch |
gen-layer-applicability |
gen-layer-applicability.py |
Projects the canonical gate registry into layer-applicability.md; --check fails CI on drift |
All gates support --json for machine-readable gate-result envelopes pipeable to emit-evidence. The schemas/ directory ships in the package: audit-profile/ (the v1 schema, the canonical registry.v1.json gate registry, and its generated projection), conform/v1/ (skillmd-frontmatter, mcp-config, plugin-manifest, agent-frontmatter), and currency/pins.v1.json.
Exit codes (CI contract):
| Exit | Command | Meaning |
|---|---|---|
| 0 | any | Clean |
| 1 | escape-scan | CHALLENGE — engineer-approved comment required |
| 2 | verify | HARNESS_TAMPERED — pinned file changed without re-init |
| 2 | escape-scan | REFUSE — pipeline halted |
| 3 | verify | No manifest (fresh repo, not an error) |
| 124 | any gate | Killed by AUDIT_HARNESS_TIMEOUT supervision (INDETERMINATE) |
Within the 7-layer testing taxonomy the harness serves L1 (escape-scan in pre-commit + CI — the cheapest gate) and L3 (CRAP, architecture, bias, hash-pin — code-level correctness).
Install — pick the ecosystem:
# Node / JS / TS
pnpm add -D @intentsolutions/audit-harness # or npm install --save-dev / yarn add --dev
# Python
pip install intent-audit-harness
# Rust
cargo install intent-audit-harness
# Anything else (Go, Ruby, PHP, Java, .NET, shell) — vendor the scripts
curl -sSL https://raw.githubusercontent.com/jeremylongshore/intent-audit-harness/main/install.sh | bashThe vendored path copies the scripts, the Node dispatcher, NOTICE (Apache-2.0 § 4(d) — it must travel with any distribution), and a PROVENANCE file recording source repo, version, tarball URL, and install timestamp.
Pre-commit hook:
#!/usr/bin/env sh
pnpm exec audit-harness escape-scan --staged
pnpm exec audit-harness verifyCI step:
- run: pnpm exec audit-harness verify
- run: pnpm exec audit-harness escape-scan --range origin/main..HEADChanging a policy threshold (the conscious path):
# 1. Edit tests/TESTING.md (e.g., coverage.line 80 → 75)
# 2. Re-init to accept the change
pnpm exec audit-harness init
# 3. Commit the regenerated manifest alongside the policy change
git add tests/TESTING.md .harness-hash
git commit -m "chore(test): lower coverage floor to 75"Language support:
| Language | CRAP | Arch |
|---|---|---|
| Python | radon + coverage.py | import-linter |
| JS/TS | complexity-report + c8 | dependency-cruiser |
| Go | gocyclo + go test -cover | arch-go |
| Rust | rust-code-analysis + tarpaulin | (custom) |
| Java/Kotlin / .NET / PHP | — | ArchUnit / ArchUnitNET / deptrac |
- License + distribution integrity. Apache-2.0 since v1.0.0 (0.x releases remain MIT under their original terms). A
version-canonical-checkCI gate enforces that all tracked polyglot manifests (package.jsoncanonical,version.txt,python/pyproject.toml,python/src/intent_audit_harness/__init__.py,rust/Cargo.toml) agree on both version and Apache-2.0 license — drift fails the build. (rust/Cargo.lockis gitignored — it is not a committed canonical manifest; cargo regenerates it atcargo packageon publish.) - Signed releases. npm publishing runs only through the tag-triggered
release.ymlwithid-token: writeandnpm publish --provenance(sigstore: Fulcio OIDC + Rekor). The workflow verifies the pushed tag matchespackage.json#versionbefore publishing. - Self-containment. The harness's own enforcement surface (
scripts/*.sh,scripts/*.py,bin/audit-harness.js, and the extra-patterns file itself) is hash-pinned at the repo root; CI hard-failsharness-hash --verifyon any byte change without a committed re-init. The harness tests itself: every PR's diff passes through its own escape-scan. - Pinned toolchain. shellcheck (v0.10.0) and ruff (0.15.4) are version-pinned in CI so a linter release cannot surface new findings silently against merged code.
- No network at gate time.
conformnever live-fetches schemas; verdicts re-verify against the exact bundled schema version viapolicy_hash.currency— the one verb whose subject is inherently network-bound (upstream freshness) — is deliberately advisory-only with no exit-code authority. - Demonstrated catch. The
scanverb's first run against this repo's own tree caught a PyPI publish token pasted as a literal in a docs file; HEAD was redacted in the same release and the rotation tracked separately (documented in the changelog — the gate worked on its own author). - Signed self-evidence. A CI-only emitter (
ci/, excluded from the published tarball to preserve the zero-dependency guarantee) runs the realharness-hash --verifyself-gate, shapes it into a kernelgate-result/v1+ Evidence Bundle, cosign-signs the canonical bytes, and publishes a manifest as a Release asset for downstream re-verification.
- v1.3.0 on npm (latest) with sigstore provenance; tags through
v1.3.0, all three registries at1.3.0. The GitHub repo isintent-audit-harness(npm package name, CLI binary, and PyPI/crates package names unchanged). - v1.3.0 (2026-07-05) shipped the
migration-notessubcommand — an adopter-facing migration-notes generator (scripts/migration-notes.py, stdlib-only, read-only, no network). It turns the two existing sources of truth —CHANGELOG.md(Keep a Changelog) andSEMVER.md(the breaking-change table + stability guarantees) — into one migration document per version boundary: no arg = latest release,<version>= one version,--from A --to B= cumulative notes across the half-open(A, B]range. A MAJOR boundary surfaces the release'sRemoved/Changed/Deprecatedsections plus theSEMVER.mdbreaking-change rules; a minor/patch boundary reports "no action required".--jsonemits amigration-notes/v1envelope. It surfaces authored release-log text rather than fabricating steps, so the notes stay traceable. This closed the fourth and final acceptance criterion of theiah-E05SemVer-regression epic. Additive minor. - Polyglot signed distribution is live — the same tag publishes to npm (sigstore), PyPI (sigstore-python), and crates.io (cargo build-provenance attestation) from one
release.yml. Thecred-gateprovider-credential gate (iah-E08) and the locked OTel runtime-event surface (agent.rollout.gate.evaluated+gate.decision.emitted, iah-E07) landed in the 1.2.x line, all additive with the zero-runtime-dependency guarantee preserved. - The deterministic CI suite is the required merge gate on
main. The CI workflow (ci.yml, push + PR + nightly cron) covers: dispatcher self-check across Node 18/20/22, shellcheck (pinned 0.10.0), ruff (pinned 0.15.4), Python compile-check, manifest version/license alignment (version-canonical-check), backward-compat regression, a SemVer contract suite (frozen subcommand roster, exit codes,--jsonstream contract, predicate URI), golden suites forclassify/conform/audit/scan/currency/migration-notes, a crap-score join-regression suite with stubbed providers, the golden-master stdout suite, the wrapper-byte-sync drift guard, layer-applicability projection drift, and advisory FP-rate measurement — plus the separatecodeql.yml,actionlint.yml,doc-quality.yml, andtypos.ymlworkflows. - Platform role: this repo is the deterministic-gates layer of the Intent Eval Platform — it emits
gate-result/v1rows into the shared Evidence Bundle schema (canonical contracts in@intentsolutions/core); downstream tooling consumes them.
Source: CHANGELOG.md (Keep a Changelog format), verbatim — the [Unreleased] section plus the six most recent headered releases ([1.3.0] through [1.1.8]). Latest published tag: v1.3.0.
Riding a future v2.1 routine release (descoped from 1.2.0): OTel event-name polish (iah-E07b/c). The
agent.rollout.gate.evaluatedandgate.decision.emittedevent names are already locked + tested on main (PRs #78, #81 per NORMATIVEintent-eval-lab/000-docs/067-AT-SPEC). Any further attribute-schema polish on those events is deferred to a routine v2.1 release rather than headlined here — it is additive telemetry refinement, not a 1.2.0 capability boundary.
migration-notessubcommand — adopter-facing migration-notes generator (iah-E05d). The fourth and final acceptance criterion of theiah-E05SemVer regression epic (the first three — CLI surface snapshot, breaking-change detector, CI gate — ship intests/semver/run-semver-tests.sh).audit-harness migration-notes [version](scripts/migration-notes.py, stdlib-only, read-only, no network) turns the two existing sources of truth —CHANGELOG.md(Keep a Changelog) andSEMVER.md(the breaking-change classification table + stability guarantees) — into a single migration document per000-docs/012-AT-ARCH § 11.3("a MAJOR bump ships migration notes"). No arg = the latest release;<version>= one version;--from A --to B= the cumulative notes across the half-open(A, B]range. A MAJOR boundary surfaces the release'sRemoved/Changed/Deprecatedsections and appends theSEMVER.mdbreaking-change rules + "what we will never do" guarantees; a minor/patch boundary reports "no action required".--jsonemits amigration-notes/v1envelope. The generator does not fabricate migration steps — it surfaces authored release-log text, keeping notes traceable. Wired as a dedicated CI suite (tests/migration-notes/, 12 assertions). Additive minor.
A patch release shipping a correctness fix to the CLI emit-evidence command. No
CLI surface, no new commands — the evidence emitter now produces kernel-valid
output where it previously did not.
emit-evidencenow emits kernel-validgate-result/v1predicate bodies (#103). The CLIemit-evidencewrapped gate rows in an in-toto Statement declaringpredicateType: https://evals.intentsolutions.io/gate-result/v1, but the predicate body carried the legacy draft envelope (result/timestamp), which fails@intentsolutions/core'sGateResultV1Schema(it forbids additional properties) — so a downstreamintent-rollout-gaterejected the bundle. The emitter now builds the canonical body (gate_decision,gate_name,gate_version,gate_reasons,coverage,policy_ref,evaluated_at), bringing the general-purpose CLI path to parity with the internalci/emit-evidence.tsself-gate (which already emitted kernel-valid rows). The post-emit predicate is now validated against a full-kernel fixture (tests/fixtures/gate-result-v1.schema.json); the partial input-envelope fixture stays for the gate emitters' raw rows. Surfaced by the first external-adopter convergence run; verifiedconform | emit-evidence→ 9/9 kernel-valid →intent-rollout-gatedecisionblock → allow.
A patch release closing the polyglot publish loop. No CLI surface, runtime behavior, or API boundary changes — only the release machinery moved. v1.2.1 published to npm but failed PyPI (a twine bug) and crates.io (an account email-verification gate); this release publishes all three registries cleanly.
- twine now uploads only built distributions, not the
.sigstore.jsonbundles (#92). Thepublish-pypileg'stwine uploadcall is scoped todist/*.whl dist/*.tar.gz, so the sigstore signature bundles emitted alongside the wheel + sdist are no longer passed to twine (which rejected them and failed the v1.2.1 PyPI publish). - crates.io publish goes live. The account email-verification gate that blocked the v1.2.1 crates.io publish is now resolved, so the
publish-cratesleg publishes on this tag — closing the npm + PyPI + crates polyglot publish loop.
- Release-preparation chore for v1.2.2 (#93).
A patch release: release-pipeline supply-chain hardening (polyglot signing) plus dev-dependency bumps. No CLI surface, runtime behavior, or API boundary changes — the published artifacts are byte-identical in behavior to 1.2.0; only the release machinery and dev tooling moved.
- sigstore-python wheel + sdist signing (#90). The
publish-pypileg now signs the built wheel and sdist withsigstore-python(keyless Fulcio OIDC + Rekor), so the PyPI distribution carries verifiable provenance alongside the existing npm sigstore path. - crates.io build-provenance attestation (#90). The
publish-cratesleg now emits a GitHub build-provenance attestation for the published crate artifact, extending the signed-supply-chain guarantee to the Rust distribution.
- crates.io publish is now active (#90). With
CARGO_REGISTRY_TOKENprovisioned as a repository secret, thepublish-cratesleg goes live on this tag — closing the polyglot publish loop (npm + PyPI + crates.io all publish + sign from one tag). - Bump
eslintfrom 9.39.4 to 10.5.0 (#71). - Bump
jeremylongshore/intent-rollout-gateGitHub Action pin from 0.1.0 to 0.2.0 (#86). - Bump
crate-ci/typosfrom 1.29.4 to 1.47.2 (#87). - Release-preparation chore for v1.2.1 (#91).
A minor release: the provider credential gate (cred-gate, iah-E08), the locked
OTel runtime-event surface (agent.rollout.gate.evaluated + gate.decision.emitted,
iah-E07), shared vendorable lint configs, wrapper-mirror drift-guard CI, and tailnet
CI-failure alerting — all additive, with the zero-runtime-dependency guarantee
preserved.
Why minor, not patch: A new CLI-adjacent gate surface (
cred-gate) and new authored feature surfaces (shared lint configs, the locked OTel event taxonomy, the wrapper drift-guard lane). Per SemVer this is a minor bump. No CLI command was renamed or removed; the change is purely additive and the published tarball stays zero-runtime-dependency.
- Provider credential gate (
cred-gate, iah-E08) (#77). A new gate that asserts provider credentials PASS/FAIL with full redaction + spillover coverage (scripts/cred-gate.sh). - Credential-leak fixtures + failure-mode docs (#80). Full-catalog fixture coverage for the cred-gate's redaction + spillover behavior (iah-E08a/E08b).
- OTel runtime events on
emit-evidence(iah-E07) (#81). Emitsagent.rollout.gate.evaluated(the per-gate evaluation event, name + attributes locked + tested, iah-E07a) andgate.decision.emitted(the gate-decision event, iah-E07b) per the NORMATIVEintent-eval-lab/000-docs/067-AT-SPECruntime-event taxonomy. - Shared, vendorable lint configs (#85).
.audit-harness-configs/(markdownlint / yamllint / ruff / shellcheck) is the canonical config set the IEP repos vendor + extend;install.shnow vendors bothscripts/andconfigs/. CLAUDE.md cross-references the lab specs. - Advisory
typosspell-check CI lane (#83) and advisoryactionlintCI lane (#84). - ntfy CI-failure alert over the tailnet (#79). CI failures fan out a notification to the private tailnet ntfy topic.
- Provider credential gate + OTel head landed first (#77). The
cred-gatehead and the OTelgate.decision.emitteddecision event landed together; PR #78 then renamed the gate-decision event togate.decision.emittedto align with the 067-AT-SPEC runtime-event taxonomy. - Dogfood AAR (iah-E10d) (#88). First-downstream-adopter run captured at
000-docs/013-AA-AACR-rollout-gate-dogfood-iah-E10-2026-06-15.md. - Release-preparation chore for v1.2.0 (#89).
- Bundled wrapper mirrors resynced to canonical + drift-guard CI lane (iah-65k4) (#82). The Python (
python/src/intent_audit_harness/scripts/) and Rust (rust/scripts/) bundled copies ofcrap-score.pywere stale mirrors of canonicalscripts/; this resyncs them and adds a CI lane that fails on any future drift between canonical and the bundled mirrors.
Ships the iah-E06 production-signing pre-flight gate to downstream consumers, plus the comprehensive PP-PLAN-040 supply-chain + hygiene wave, crap-score backend repairs, and a SemVer contract-pin test suite.
Why patch, not minor: The pre-flight scripts shipped to the repo in earlier PRs (#70, #75); this patch propagates them to npm consumers via a version bump. No new public CLI commands or flag changes in this release boundary.
- DNSSEC + CAA production-signing pre-flight (iah-E06) (#70). Before a production-mode
emit-evidencerun signs canonical bytes, two deterministic pre-flight scripts assert the signing domain (evals.intentsolutions.io) is cryptographically sound —scripts/dnssec-check.shverifies the DNSSEC chain is present and validates;scripts/caa-check.shverifies the CAA records authorize the signing certificate authority. Both fail closed: any error, missing record, or unreachable resolver blocks the signing path rather than emitting an unverifiable attestation. Staging/draft emit is unaffected. - Supply-chain + hygiene + kernel-shadow detector (#69). PyPI/crates publish wiring, dependabot polyglot coverage, lefthook, eslint, a bash-version floor, a kernel-shadow detector, and a crap-score dot-dir fix landed as one supply-chain wave.
install.shcompleteness + per-repo blueprint + golden-master stdout suite (#63). The vendored-install path now ships a complete traceable copy, plus a golden-master fitness function pinning the raw stdout of the scorers whose output is a downstream contract.- SemVer CLI/output-contract pin test (#65). A test that pins the CLI + output contract so a MAJOR-worthy change fails CI rather than slipping out as a patch.
currency: one pin per upstream surface + advisory poll-freshness SLA rename (#68). Each tracked upstream (mcp-spec, skill-md-schema, claude-code, gate-result-predicate, anthropic-sdk, agentskills-spec) carries its own pin relation so the pin's own staleness is detectable per-upstream rather than as one opaque scalar.- Version bumped to 1.1.8 across all manifests (#76). Per the
version-canonical-checkCI gate:package.json(canonical),version.txt,python/pyproject.toml,python/src/intent_audit_harness/__init__.py, andrust/Cargo.tomlall report1.1.8. - audit-harness self-adopts the intent-rollout-gate Action (#74). CI dogfoods the downstream rollout-gate Action — graduation criterion 5 / M6 first downstream adopter.
- Bump
DavidAnson/markdownlint-cli2-actionfrom 17 to 23 (#49); bumpactions/setup-nodefrom 4 to 6 (#61); record the public gist id for sweep/release tooling (#67).
- Query a trusted validating resolver in the DNSSEC + CAA pre-flight (#75). The pre-flight previously trusted the ambient resolver, which may not validate DNSSEC. Both scripts now query known validating resolvers (
1.1.1.1,8.8.8.8) and require the authenticated-data (AD) flag plus anRRSIGon the answer. A resolver that does not set AD, or an answer with no RRSIG, is treated as a validation failure (fail-closed) rather than a pass. - crap-score Go/JS scoring backends repaired + 3 bash defects from the umbrella review (#66).
- Evidence-integrity bugs + SHA256 portability + kernel schema URL (#64).