Repository navigation
Releases: 0xD1g5/QU.I.R.K
Release list
v5.27.0
[5.27.0] - 2026-10-15
This is the first release since 5.25.0. It carries the untagged v5.26 Accessibility & Instrument
Truth and v5.27 Launch Readiness milestones: the contrast and keyboard accessibility drain,
the score gauge fix, the brand identity and dashboard re-theme, a claim-by-claim review of every
user-facing doc, and a round of pre-release security hardening.
Upgrade notes: quirk serve now exits with an error when its config file exists but cannot be
read, and protected API routes answer 503 in that state. This includes a config file that goes
missing or empty after a running quirk serve or quirk scheduler has read it with settings in
it: it is treated as unreadable until the file is restored or the process is restarted.
quirk sensor enroll and quirk sensor push require an https:// console URL for non-loopback
hosts unless --allow-insecure-console is given, so re-enroll existing sensors that use an
http:// console. No score-model changes: SCORING_VERSION stays 3.0.
Added
- Keyboard access to scrollable dashboard tables (KBD-01). A table too wide or too tall for
its space becomes a single Tab stop that the keyboard can scroll, shows a focus ring on keyboard
focus, and is announced to screen readers as a named region. A table that fits its space adds no
Tab stop. - QU.I.R.K. brand identity. The brand logo appears in the README (light and dark variants),
in the "Generated by" colophon of HTML, PDF, DOCX and dashboard-exported (/print) reports
(falling back to the text name if the logo cannot be embedded), as the dashboard favicon, and in
the sidebar. PDF reports now print the report footer, which the print stylesheet used to hide. --allow-insecure-consoleforquirk sensor enroll, for the rare case of enrolling a
sensor against a non-loopback console without TLS.- PyPI project links. The package now declares
[project.urls], so the PyPI page links to the
repository, documentation and issue tracker.
Changed
- The dashboard accent is Ink-violet. The primary and accent colour moved from teal to
Ink-violet (#af89f5in the dark theme,#6933ccin the light theme), as part of the dashboard
re-theme. - WCAG AA contrast across the dashboard. The v5.26 contrast drain and design calls restored AA
contrast on the CBOM Safe badge and across the remaining flagged pairs. The orange HIGH badges
on Compare, Scan History, Hardware and Motion, and the green badges on Certificates and Hardware,
now use dark text instead of white. The badge colours themselves are unchanged. security.trusted_targetscovers every host a scan contacts, includinginclude_ips,
connector host fields, dashboard jobs, schedules and scheduled runs.- Sensor push audit rows record the source address and sensor id, and rate-limited pushes are
audited. Error and log text for URL fetches, credential references and LDAP DNs is tightened,
andquirk tokenwording is clearer. - The Effective Config preview now shows the server's
allow_internal_targetssetting and
which credentials the form has filled. - The chaos lab's
storage-s3profile runs moto instead of MinIO. Theminioand
minio-seedservices now use themotoserver/moto:5.2.3image, because the pinned MinIO
images can no longer be pulled. - README images are pinned to the release tag, so they keep rendering after the default
branch moves.
Fixed
- Score gauge arcs drew mirrored. A 20/100 score rendered about 90% full. The gauges now draw
the arc that matches the score. - Install hints and the
quirk inittemplate named the wrong PyPI project. They now name
quirk-scanner. - QRAMM Calculate Score and the QRAMM compliance map no longer fail with HTTP 403. Both
dashboard calls now go through the dashboard's API client, which sends the CSRF request header. - The JWKS verify-disabled advisory is reported as a HIGH finding that does not change the
readiness score.
Security
- Hardened the cloud-metadata address block in outbound URL validation, which now also applies to IPv4 addresses carried in IPv6 forms.
- Hardened OpenAPI spec URL fetching: each redirect hop is re-validated against the scope and URL checks, and the REST fuzzer and the RabbitMQ management probe do not follow redirects.
- Hardened OpenAPI spec fetch error text, which is now allow-listed.
- Hardened credential-reference error text, which now names only the scheme and kind.
- Hardened dashboard operator-auth configuration loading, so a config that cannot be read no longer leaves the dashboard unprotected.
- Hardened the sensor enrollment console URL scheme policy: non-loopback consoles require
https://unless--allow-insecure-consoleis given.
Documentation
- Every user-facing doc was reviewed claim by claim against the code, with the install,
command and version claims corrected and the master guide regenerated. - The README hero image was retaken and the README refreshed for public launch with an
accurate scan list and working install commands.
Internal: branch-CI-aware phase verification, the accessibility ratchet and browser harness, and
vitest flake fixes keep the release gates honest.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-5.27.0.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-5.27.0.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.
v5.25.0
[5.25.0] - 2026-09-28
This release carries four development-complete milestones as a single publish, not three —
no tag was cut after v5.21.0 (2026-09-10), so v5.22, v5.23, v5.24 and v5.25 are all unreleased
together. v5.22 Release & Parity Tail published v5.21.0 to PyPI and closed out connector
and scan-behavior dashboard parity. v5.23 Deliverable Experience shipped consulting-grade
reporting CLI/config-side, a score-lift roadmap re-frame, and a finding storyline drawer.
v5.24 UAT Coverage Drain made the UAT gap worklist self-deriving, added a real browser E2E
tier, made v5.23's report artifacts dashboard-reachable, and hand-re-verified catalog freshness.
v5.25 Score Truth & Release Cut closed the score-parity gap between the report and dashboard
pipelines, corrected denominator semantics, recorded a measured decision to ship no P2b fix, and
fixed two shipped product defects. Several items below are qualified rather than unconditional —
the qualification is kept in the bullet, not smoothed away.
Breaking change in meaning, not mechanism: readiness scoring moved to v3 in this release (see
Changed, below) and denominator semantics were corrected in v5.25 — together these mean every
score this product has ever emitted moves, substantially and downward, and is not comparable to a
score computed after this release. Re-scan or re-score before comparing.
Added
- v5.22 Release & Parity Tail — 999.104 fully closed: Tier 2 (37 residual connector detail
fields dashboard-settable) and Tier 3 (19 scan-behavior fields — 11 timeouts, 2 backoff, 5
concurrency knobs,tls_designated_ports), via the lockstep-widened connectors overlay and
AdvancedScanFields(.planning/MILESTONES.md:150-152). - v5.23 Deliverable Experience — consulting-grade reporting shipped CLI/config-side
(RPT-01..05): report branding and templates. The dashboard exclusion was deliberate (RPT-03
guards it as a path-traversal surface), not an oversight — v5.24 later made those artifacts
dashboard-reachable. Also shipped: a score-lift roadmap re-frame (LIFT-01..05) surfacing
projected-score deltas, and a per-finding storyline drawer (STORY-01/02)
(.planning/MILESTONES.md:95-102). - v5.24 UAT Coverage Drain — the UAT gap worklist now derives itself (COV-01/02/03):
docs/uat-coverage-gaps.mdis generated and gated, regenerating byte-identically; open GAPs
went 47 → 43 → 41. A real Playwright browser tier exists where jsdom structurally could not
reach (COV-05, COV-10), and the consulting-grade report artifacts from v5.23 became reachable
through an auth-gated, containment-guarded dashboard route (DELIV-01/02)
(.planning/MILESTONES.md:19-34).
Changed
-
Readiness scoring is now v3: consequence is absolute rather than proportional, and a
quantum-blind estate can no longer score 100 (999.115).SCORING_VERSIONis bumped2.0→
3.0, and every score this product has ever emitted moves — substantially, and downward. This
is a change to what the number means, not a recalibration of it. Under v2 every penalty was
prevalence × weight, so a serious problem was diluted by everything around it that happened to
be fine: five open CRITICAL findings counted for less in a large estate than in a small one, and
the product's strongest possible statement about a catastrophic 31-host estate was the incoherent
"87 — FAIR", the digits saying one thing and the label another. Six changes land together:- An absolute consequence ceiling keyed to the count of open CRITICAL/HIGH findings, applied
to the score before the band is derived so the number and the label can never disagree again.
Its thresholds are derived from the published band table rather than chosen. The ceiling
compresses the score into the permitted range rather than clamping it flat — a capped estate
still gains points for remediation, and still responds to the strict/balanced/lenient profiles. - "No PQC, no 100" — an estate with no observed hybrid post-quantum key exchange is capped at
the top of GOOD. Implemented as a ceiling rather than a bonus because the existing +8.0 PQC
bonus was being absorbed entirely by the per-domain 25-point clamp and moved the score by
exactly zero. - A non-linear prevalence curve, so a small-but-real prevalence is no longer treated as
proportionally trivial. - Undetermined certificate key types no longer score as best-case, so the model stops
rewarding not looking. agility_high_impact_ratioremoved rather than re-denominated — a finding count is not a
population that badness is proportional to, and consequence now reaches the number directly.- Report drivers can no longer cite a domain the headline excluded as unassessed.
Phase 184.4's decision that severity caps the band but never the number is superseded; its
rationale is preserved in full at
.planning/decisions/999.115-severity-caps-the-number-supersedes-184.4-D-03.md. Its
comparability argument is discharged by the version marker rather than abandoned — every report
surface discloses that v3 and v2 scores are not comparable, and QU.I.R.K. does not back-migrate
stored rows. Whenever a ceiling binds, the score carries a reason naming the finding set that
capped it and the uncapped figure (e.g. "5 open CRITICAL findings — score limited to 18
(computed 81)"), so a capped number is never delivered as a computed one. Measured against
operator-set calibration bands, supplied blind: a pristine PQC-ready estate 100 (EXCELLENT), a
well-run estate with no PQC 78 (GOOD), a typical enterprise 46 (FAIR), a neglected estate 24
(POOR), and the 31-host purpose-built vulnerable estate 87 → 18. If you hold a previously
delivered score, re-scan or re-score the evidence before comparing it to anything produced after
this release. - An absolute consequence ceiling keyed to the count of open CRITICAL/HIGH findings, applied
-
v5.25 — cross-surface score parity (Phase 210) and denominator correctness (Phase 211).
One scan now yields the same headline score, CRITICAL count and certificate count from the
report pipeline and the dashboard pipeline. Phase 210 closed the CRITICAL-count and
certificate-count divergence but left the headline score itself 1 point apart (Success
Criterion 5 NOT MET by Phase 210's own work). Criterion 5 was subsequently satisfied by
Phase 211's denominator-correctness fix, not by Phase 210's — live measurement:
report 18/100 == dashboard 18/100, all six subscores matching, root-caused to a finding-title
vocabulary mismatch plus a LOW-severity-proxy structural zero. Every ratio penalty divides by
the population its numerator is drawn from (DENOM-01/02/03; this work had already landed via
0b0ed1c7before Phase 211 re-scoped to verify + investigate). One residual is disclosed and
explicitly not tag-blocking: DENOM-03's width-neutrality clause measured inverted
(narrow 2-port scan 20/100 vs. wide 14-port scan 18/100 on the same estate)
(.planning/ROADMAP.md:24-40). -
v5.25 — score dilution, decision only (Phase 212). A written, measured denominator
decision for the P2b scan-scope-dilution defect exists; no implementation ships in this
release. VERDICT: RECOMMEND NONE — no candidate cleared both measurement axes (scan-scope
normalisation showed zero mitigation; the distinct-hosts candidate was unfalsifiable by
construction and broke ladder monotonicity; the absolute-exposure candidate was structurally
uninformative on one axis). The P2b defect remains deferred, not fixed
(test_p2b_...staysxfail(strict=True)by design); its implementation is explicitly owned
by a post-v5.25, operator-reserved phase — not Phase 214
(.planning/ROADMAP.md:44-55,.planning/decisions/212-score-dilution-denominator-decision.md).
Fixed
sslyzeis now a declared dependency — it drives the primary TLS scanner and every
email/broker TLS probe, but was declared nowhere inpyproject.toml. Not in core
dependencies, and not in any extras group (emailwas an empty list;brokerheld only
redis), so a cleanpip install quirk-scanner— with or without extras — never installed it.
Nothing failed loudly because every consumer guards the import: the TLS scanner degraded
silently to its stdlibssl+cryptographyfallback, shipping the flagship scanner in reduced
mode with no error, while the email and broker connectors were refused outright by the
dashboard availability gate ("Scan rejected: Email / SMTP is not available in this
environment"). Across an 82-package dry-run resolution,quirk-scanneris the only package
that requiressslyze— there was no transitive path, so it worked in practice only where
sslyze happened to already be present. Declared in core (floor>=6.2.0, matching the
__version__-shape normalization already in_scan_one_sslyze); binary depnasslships
wheels for cp310-cp314 across macOS arm64, manylinux, musllinux and win_amd64, so no supported
platform needs a toolchain. Operators with an existing install must re-runpip install—
updating source alone will not install it, sincepyproject.tomlis install-time metadata the
running code never consults. Note the transitive constraint: sslyze pins
cryptography<47, so the effective core window is now44.0 <= cryptography < 47. A clean
install is unaffected even with[identity]— pip resolves cryptography 46.0.7 alongside
pyOpenSSL 26.2.0, which accepts it. An incrementalpip install sslyzeinto an environment
already holding pyOpenSSL >= 26.4 (which requirescryptography>=49) will downgrade
cryptography and leave pyOpenSSL unsatisfied, because pip's resolver does not reconsider
already-installed distributions; re-run the full install command to re-resolve, then
pip check. QUIRK imports pyOpenSSL nowhere, so only impacket-backed Kerberos/AD scanning is
...
v5.21.0
[5.21.0] - 2026-09-10
Two development-complete milestones, shipped as a single release: v5.20's readiness-score
correctness fixes and v5.21's dashboard parity and quantum-exposure capability work.
Added
- Connectors panel (PARITY-02, PARITY-03, Phase 193) — the scan-creation form gained a
Connectors panel exposing all 25enable_*connectors (Identity, Cloud, Database, Email &
Broker, OT/ICS, Source & API), each showing live availability with a disabled reason and
install hint when a connector's dependency is missing, masked (never-persisted) credential
inputs for enabled connectors, and a submit-time 422 gate that rejects a job before it is
created if a resolved connector is unavailable — whether explicitly toggled or auto-enabled by
a profile preset. - Advanced scan-fields panel (PARITY-04, Phase 194) — a collapsible Advanced section on the
scan form exposing TLS ports, TLS enumeration mode (Fast/Deep), discovery options, per-protocol
timeouts and retry count, and data classification, feeding the same live effective-config
preview the Connectors panel uses so the operator can see exactly what will be scanned before
submitting. - Executive Verdict layer (VERDICT-01, Phase 194) — the dashboard's executive page now shows
an always-on verdict band (safe / at-risk / vulnerable) driven exclusively by the scan's
server-computed rating, never re-derived from the raw score client-side, with an honest
"Verdict not available for this scan (pre-v5.21 data)" state for scans that predate this
feature and an inline note when a score has been capped. - Quantum Exposure Map dashboard tab (MAP-01, MAP-02, MAP-03, Phase 195) — a new dashboard
tab visualizing key-reuse relationships between scanned endpoints as a graph, built entirely
from real, already-collected scan evidence with zero fabricated or inferred edges and a
score-firewall guard proving the map can never influence the readiness score. Operator-declared
crown-jewel reachability scoring was investigated and deliberately deferred (parked as backlog
item 999.107) after confirming no scanned environment currently produces the live data that
feature would need. - Scan Coverage and Effective-Config visibility (OBS-01, OBS-02, PARITY-01, Phase 192) — scan
jobs now surface a Scan Coverage summary (what was actually scanned vs. what was configured)
and an Effective-Config panel with a live preview, including a Raw YAML tab, showing exactly
what configuration a scan will run with before it starts, with credential values fail-closed
redacted on every surface.
Fixed
- Phantom-certificate disclosure (DASH-09, Phase 194) — TLS endpoints that failed the
handshake (no subject, scan error) are no longer silently dropped from the certificate list on
both the dashboard and the print/PDF report; both surfaces now disclose "{N} TLS endpoints
failed handshake and are not shown" whenever endpoints are excluded, so an all-phantom scan
reads as a real, disclosed finding instead of a suppressed empty list.
Changed
-
Scoring v2 — not comparable with pre-5.20 scores (SCORE-06, SCORE-07, Phase 188). This is
the migration/communication decision record for the readiness-score integrity fixes shipped in
Phase 188 — write it here, not only in planning files, because a formula change that moves every
historical score is a silent drive-by unless a client can read what changed.-
Exclude-and-rescale.
compute_readiness_score()no longer credits a domain it never
assessed with a fabricated full 25/25. The headline score now rescales over only the domains
with assessable evidence:sum(assessed subscores) / (domains_assessed * 25) * 100, replacing
the old fixed÷ 1.5rollup. Every report surface (CLI markdown, HTML, DOCX, the dashboard
executive page, andintelligence-{stamp}.json) now discloses"N of 6 domains assessed"
alongside the score. -
Scores are NOT comparable with pre-5.20 scores. A scan that shows a lower number after
upgrading may simply be reporting honestly on fewer fabricated points, not a regression in
posture. Compare trend lines only within the samescoring_version. -
Historical database rows are deliberately NOT back-migrated. Rows written before this
change keep the old fixed-divisor arithmetic baked into their stored score; QU.I.R.K. does not
rewrite history to make old and new scores artificially comparable. -
Every score-bearing output now carries a scoring-version marker. New reports and API
responses carry the following note verbatim:scoring v2 — not comparable with pre-5.20 scores
-
A zero-assessed scan reports "not computed", never a fabricated 0 or 100. If no domain has
assessable evidence, the score isNone/absent rather than a misleading number. -
Severity-band thresholds now have a single producer (SCORE-07).
quirk/severity_bands.py
is the one source of truth for the EXCELLENT/GOOD/MODERATE/FAIR/POOR boundaries; the dashboard
gauge, the notify payload's severity mapping, and the report band all read the same thresholds.
The dashboard gauge's color boundaries shifted as a direct consequence (green now begins at 70,
not 80; amber covers 35-69, not roughly 50-79; red begins below 35, not below 50) — this is the
gauge now agreeing with the report band, not a new inconsistency.
-
Separately from the product changes above: the GSD release toolchain that authors this project's
own planning files had a second, semantic defect class (phase.complete/milestone.complete
reporting a phase closed without checking that phase's own plans actually finished) found and
filed open during this window, alongside continued hand-written closes under the pre-image +
signature-diff protocol. This is operator-machine-local tooling work, not a change to the shipped
product.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-*.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-<version>.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.
v5.19.0
[5.19.0] - 2026-09-07
Ten phases (182 through 186.1), one milestone: readiness-score correctness, drift-proof
test-suite honesty gates, an a11y baseline stabilization, and two carried-forward defects
drained — shipped as a single release.
Separately from the product changes below: the GSD release toolchain that authors this project's
own planning files had its state-corruption defect class (TOOL-01 through TOOL-05) closed on this
machine — 21 sites across 4 files in 2 separate installs were scoped after a run-time source scan
found 29 affected sites where planning had predicted 6, proven by a live re-demonstration against
the real, tracked .planning/STATE.md restored byte-identical. This is an operator-machine-local
tooling fix, not a change to the shipped product; a second, semantic defect class in the same
toolchain was found and filed open rather than folded into this closure.
Added
- Readiness-score correctness (SCORE-01..SCORE-05) — coverage-metric calculation corrected,
default out-of-the-box config now actually scans what it claims to, scan timestamps corrected,
and a single-producer severity-band contract (quirk/severity_bands.py) collapses previously
duplicated band logic into one source of truth. - Drift-proof test-suite honesty gates (DRIFT-01, DRIFT-02) — the fork-safety gate now derives
its covered file set from a live glob instead of a hand-maintained list, and the skip registry
keys entries by(file, qualname)with alias-aware AST resolution so an entry survives line
shifts and previously-invisible skip sites are now caught.
Fixed
- Carried-forward defect drain (TRIAGE-01, TRIAGE-02) — a stale Keycloak certificate fixture
and a plaintext-HTTP classifier gap, both carried forward from prior milestones' chaos-lab and
findings-model work, are cleared.
Changed
- Accessibility baseline environment stabilized (DRIFT-03) — the a11y test environment now
produces a reliable, hand-verified baseline for future violation tracking.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-*.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-<version>.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.
v5.18.0
[5.18.0] - 2026-09-02
The first release since 5.15.0 (2026-08-26). Two milestones of user-visible fixes — v5.16 Review
Drain & Gate Integrity (Phases 164-171) and v5.17 Defect Drain (Phases 172-176) — were developed,
merged, and archived but never tagged; both ship here as one release rather than being
retro-published separately, since their content was never a separable source-tree state. This
release also includes Phase 177's own release-toolchain repair.
Added
- UAT corpus integrity, permanently enforced (v5.16, UATREC-03/UATREC-04) — a standing gate
(tests/test_uat_zero_undispositioned_gate.py) keeps all 666 UAT case headings dispositioned
going forward; the corpus itself went from 377 undispositioned cases to zero. - First-run correctness (v5.16, FIRSTRUN-01/02/03) — the command the dashboard's empty state
instructs a new user to run now exists and works; a mistyped--targetsargument fails with a
coded error (TARGET-001/TARGET-002) instead of an uncaughtFileNotFoundErrortraceback. - Coded fuzzing safety (v5.17, SAFE-01/SAFE-02) —
--fuzzhard-aborts before issuing any
request when stdin is non-interactive, printing a coded error and exiting non-zero;--fuzz-budget
is enforced at its documented 500-request ceiling rather than only the 50 default.
Fixed
- Three screen-reader-blocking accessibility violations (v5.16, A11Y-02) — icon-only radix
dropdown triggers now carry discernible labels; all 291 previously-baselined axe violations
carry a recorded impact level and WCAG reference instead of accumulating silently (A11Y-01). - A CRITICAL evidence-injection vulnerability (v5.16, CR-01, found during Phase 169 code
review) — a newline-splicing defect inscripts/uat_disposition_apply.py's evidence-field
validation could fabricate a fully-[x] PASSUAT case past all three anti-fabrication guards at
once. Fixed in two layers, with 8 regression tests proven to fail against the pre-fix code. - A macOS
fork()-after-Network.frameworkSIGSEGV affecting subprocess-spawning CLI tests
under full-suite load (v5.16, GATE-03) — every CLI-runner test file now goes through a shared
run_fork_safe()helper, forward-locked by an AST-based gate requiringclose_fds=False. - Raw target URL disclosure in spec-parsing errors (v5.17, SAFE-03) —
SpecParsingErrorand
its sibling error paths now report a redacted URL preview, never the full raw target. - Dashboard score disagreed with the CLI score under non-default score profiles (v5.17,
DASH-06) — a dashboard-launched scan'slist_scanscall site now passes the samecalibration
its sibling call site already did, sostrict/balanced/lenientdashboard scores match their
CLI scorecards. - SSH scanner silently degraded to banner grabs (v5.17, TRIAGE-176-03, found during the
Phase 176 chaos-lab re-run) —_run_ssh_auditinvokedssh-auditwith host and port as two
positional arguments when the tool accepts onehost:porttarget, so the invocation exited 2
with empty stdout and every SSH scan since the ssh-audit integration shipped had silently lost
ssh_audit_json(and the algorithm data it feeds to the CBOM, QRAMM evidence bridge, hardware
scanner, and dashboard). Fixed with an argv-asserting regression test; live-verified against the
chaos lab (0 -> 7218 bytes, 30 algorithms classified). - Release toolchain repair (Phase 177, this release) — a package-name-migration residue left
three distributions (quirk4.4.0,qu-i-r-k4.10.0, plus an orphan Homebrew-globalquirk
4.0.0 editable install) all claiming thequirkimport package alongside the canonical
quirk-scanner, soimportlib.metadata.packages_distributions()['quirk']could resolve to a
stale distribution. Purged, with a new regression guard
(tests/test_version.py::test_single_distribution_provides_quirk) asserting exactly one
distribution claimsquirkgoing forward.
Changed
run_stats.timings_secno longer carries a stale key for a scanner phase that did not run
(v5.17, SCOPE-02) — e.g.broker_scanningno longer persists with a nonzero value when the row
count is 0.- CHANGELOG and cross-phase references backfilled and repaired (v5.16, TRACE-01..07) — v5.9
through v5.14 each gained an entry, v5.13/v5.14 honestly recorded as developed-but-never-released
rather than silently absent, and 22 stale sibling-phase references were rewritten to their real
archived paths. - Nine UAT cases corrected where the product was right and the case was wrong (v5.17,
CASEFIX-01..05) — includingUAT-6-08's cryptographically-incorrect claim that Ed25519 is
quantum-vulnerable, and theUAT-1-02false FAIL caused by an unsatisfiableuat_runner.py
version-string match.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-*.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-<version>.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.
v5.15.0
[5.15.0] - 2026-08-26
Lifecycle Tail Drain — Phases 161-163. Note that 5.9 through 5.14 were developed but
never released: their tags were two-component (v5.9, v5.13, v5.14), which never
matched the v*.*.* trigger glob in release.yml, so no release workflow ran. 5.15.0 is
the first published release since 5.12.0 and carries that accumulated work.
Added
- Hardware lifecycle notifications (Phase 161, HWLC-14) — opt-in email/webhook dispatch
when a monitored device drifts tier or crosses an EOL/EOS boundary. Gated behind
notify_on_hardware_lifecycleonNotifyCfg, reusing the Phase 101 dispatch foundation.
The trigger is a never-raising advisory hook onpersist_and_reconcile()'s success path —
a notification failure can never fail a scan. - Vendor PQC status trend surfacing (Phase 161, HWLC-19) — catalog-level vendor PQC trend
data rendered in the CLI technical markdown report, the HTML report, the DOCX report, and a
new section on the/hardwaredashboard tab, with cross-surface caption parity enforced by
test. Advisory-only: never contributes to the readiness score, guarded mechanically by
vendor-trend-advisory-guard.test.ts. - Scheduled check-in re-probes (Phase 162, HWLC-20) —
quirk schedule add --check-in
puts HWLC-13's lightweight re-probe on a recurring cadence.--targetbecomes optional for
check-ins (stored as a(known fleet)sentinel) and stays mandatory for profile scans. The
/schedulespage marks check-in jobs with an advisory chip. - Batch-granular discovery resume (Phase 163, DISC-08) — the chunked discovery loop now
writes adiscovery:batch-Ncheckpoint plus a per-batch cache payload after each completed
batch, and skips those batches on--resume-scan-id. A /16 interrupted at batch 60 of 64
previously re-probed all ~65,000 hosts on resume; it now re-probes only the ~4,000 in the
unfinished batches. No new table and no schema change — the existing checkpoint mechanism is
reused with a structured stage string. Requires no--cacheflag.
Fixed
- SCHED-02: every default-profile schedule died at argparse (Phase 162) —
_dispatch_schedule()fell back toschedule.profile or "balanced", a score profile value
thatrun_scan --profilerejects. Any CLI-created schedule without an explicit profile was
recorded "failed" with no reason recorded. Survived three months because the dispatched argv
was only reachable throughPopen;build_scan_argv()was extracted as a pure function so it
can be asserted directly.quirk schedule listalso stopped displaying "balanced" for a null
profile — a value that is neither valid nor what would actually run. - Resumed discovery scans under-reported their own coverage (Phase 163) — the per-batch
cache stored only discoveredports, so a skipped batch lost the per-host "undetermined"
ADVISORY records from its liveness pre-pass. A resumed scan reported only the coverage of the
batches it re-probed live: measured on a 4094-host range, a 3-batches-cached resume reported
1,014 hosts scanned against 4,034 for an uninterrupted reference. Discovered endpoint counts
were correct throughout, so the report did not look broken — it looked like a completed
smaller engagement.Confidenceis coverage-derived and was depressed by it. Found by human
UAT, fixed in-phase via alivenesskey in the batch cache payload.
Changed
operators-guide.mdgains section 13, "Discovery Batch Resume", covering the resume
mechanism, disk cost, cache data-handling class, and the unchanged-target-scope limitation.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-*.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-<version>.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.
v5.12.0
[5.12.0] - 2026-08-14
Release & Verification Integrity (Phases 148-153). The real, published v5.12.0 release —
PyPI + Windows operator zip + GitHub Release — closing the release-pipeline debt that had
accumulated since v5.9's silent tag-glob failure.
Added
- Release dry-run + tag-hygiene guards (Phase 148, RELEASE-01/02/03/04) —
release.yml
gained aworkflow_dispatchdry-run trigger and tag-ref guards; a scheduled tag-hygiene
workflow with a seeded historical baseline (.github/tag-hygiene-baseline.txt) detects
malformed version tags going forward; a Windows release asset gap from v5.11.0 was closed. - Suite-wide skip/xfail visibility (Phase 149, SUITE-01) — the AST walker used to audit the
test suite was extended to detectskip/xfaildecorators, surfacing previously invisible
disabled coverage. - Gating Linux full-suite CI job (Phase 150, SUITE-02/03) — a green, gating full-suite CI job
on Linux, plus idempotent per-profile chaos-lab certificate generation so cert expiry no longer
silently rots CI. - Phase-completion artifact gate (Phase 151, ARTIFACT-01/02/03/04) —
scripts/verify_phase_gates.pyplus a.githooks/pre-commitwrapper enforce that
VERIFICATION.md/VALIDATION.md/UAT-SERIES.md artifacts exist before a phase can close, and a
check_destructive_archive()guard prevents an uncheckedphases.clearfrom silently deleting
live phase directories (closing the incident that lost ~39 of ~58 v5.11 phase artifact files). - Segmented-network chaos lab profile (Phase 152, DISC-09/10/11) — a new gateway profile plus
a live-fire smoke test; the interactive nmap-discovery-first prompt now defaults to Y; the
Phase 144 nmap timing artifact was empirically confirmed to not reproduce. - Actual tag cut (Phase 153, RELEASE-01) — the real
v5.12.0tag proving the repaired
pipeline end-to-end.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-*.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-<version>.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.
v5.11.0 — PyPI-only release (no Windows asset)
QU.I.R.K. 5.11.0 — PyPI-only release (no Windows asset)
This release is PyPI-only. pip install quirk-scanner==5.11.0 works, but the
windows-package job failed at the "CI self-test — ephemeral cert signing round-trip" step —
before the Release-creation step ever ran — so no Windows asset was ever produced or attached to
this tag. Fixed in commit 1a6effc, already on main, but it landed after the v5.11.0 tag was
pushed. v5.12.0 is the first version with a verified Windows artifact.
This release intentionally has zero attached assets. If you were expecting a downloadable
zip and see none listed below, that is correct for this version — see the disposition above.
pip install quirk-scanner==5.11.0Full disposition and root-cause detail:
https://github.com/0xD1g5/QU.I.R.K/blob/main/docs/release-notes/5.11.0.md
v5.8.0
[5.8.0] - 2026-06-16
Added
- SNMP hardware fingerprinting (Phase 133) — pysnmp 7 HLAPI 3-OID probe (sysDescr / sysName / sysObjectID) with sysdescrparser dual-path parsing (structured MIB + regex fallback) to extract vendor, model, and hardware family from raw SNMP responses. Signal cascade ordering: SSH banner → HTTP management interface → SNMP (last resort, requires read-only community string). New
[hw]extras group (pysnmp,sysdescrparser); not included in[all]— opt-in required (pip install 'quirk-scanner[hw]'). Cisco IOS chaos-lab profile added on port 20223. - CBOM DEVICE/FIRMWARE component hierarchy (Phase 134) — hardware endpoints promoted to a CycloneDX
ComponentType.DEVICEparent component with aComponentType.FIRMWAREchild; separates the hardware platform from its firmware crypto posture in the CBOM graph. Dashboard "Hardware Inventory" section added to the CBOM tab. Hardware inventory is advisory-only and does not contribute to the quantum-readiness score.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-*.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-<version>.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.
v5.7.0
[5.7.0] - 2026-06-14
Added
- Hardening + Hardware Compatibility milestone (Phases 123–129) — SSRF cluster hardening across all outbound HTTP surfaces, scoring correctness fixes (clamp/aggregation alignment), and full audit drain of the 2026-05-27 codebase audit findings.
- Hardware fingerprinting via SSH/HTTP banner — SSH host-key banner and HTTP management-interface response classify network hardware vendor, model, and CNSA 2.0 remediation tier (quantum-safe / PQC-migration-required / quantum-vulnerable). Crypto-bridge detection identifies hardware devices where an upstream TLS terminator mitigates a quantum-vulnerable on-device cipher suite.
Windows Sensor Asset
UNSIGNED BINARY NOTICE
The quirk-windows-*.zip asset contains a Windows onedir bundle (quirk.exe)
that is NOT Authenticode-signed.
- SmartScreen warning: Windows may display a "Windows protected your PC"
prompt when runninginstall.ps1orquirk.exefor the first time.
Click "More info" and then "Run anyway" to proceed. - Authenticode signing is DEFERRED to a future milestone spike.
The binary is built reproducibly from source via this GitHub Actions
workflow — operators who require signed binaries should build from source
until Authenticode signing is implemented.
Quick install (PowerShell, no admin required)
# 1. Download and unpack the zip
Expand-Archive -Path quirk-windows-<version>.zip -DestinationPath C:\quirk-install
# 2. Install — registers per-user Scheduled Task
cd C:\quirk-install
pwsh -File install.ps1 `
-ConsoleUrl https://<console-host>:8512 `
-EnrollmentToken <per-sensor-token>See the Windows sensor deployment section in the Operators Guide
(docs/operators-guide.md §8.8) for full install / Scheduled Task /
uninstall documentation.