Skip to content

v0.13.0 — raw binary ingestion, measured CWRU benchmark, guarded documentation restructure

Latest

Choose a tag to compare

@LGDiMaggio LGDiMaggio released this 14 Aug 08:05
· 22 commits to main since this release
50a01dd

Three additions. load_signal now opens headerless raw binary waveforms
(.bin, .raw, .dat) when — and only when — the caller declares how to
decode them: vendor-neutral by design, no format parsers ship in the core and
nothing is inferred from file content or names; translating a vendor's
metadata into the declaration is the user's (or an external adapter's) job.
A blind, reproducible CWRU diagnostic benchmark measures the pipeline on
public data and commits the results as a re-runnable, drift-guarded artifact.
And the public documentation is restructured around audience entry paths,
with every count, version, and coverage figure on every public surface
guarded by CI against the code itself.

Added

  • Blind, reproducible CWRU diagnostic benchmark (benchmarks/cwru/,
    python -m benchmarks.cwru all). Measures the deterministic diagnostic
    pipeline on the CWRU Bearing Data Center 12 kHz drive-end subset (60 fault
    records + 4 normal baselines): download-on-demand with vendored SHA-256
    pins (fail-closed; no data redistributed), opaque signal ids with a
    data-level ops/label split so the scorer is the only label reader,
    a symmetric hit criterion (including the CWRU 2×BSF ball-fault convention),
    and results stratified by the Smith & Randall (2015) per-record
    diagnosability grades. Measured results are committed as a re-runnable
    artifact (benchmarks/cwru/results/results.json); README and methodology
    numbers are slot-bound to that artifact and drift-guarded by CI-run tests,
    alongside executable blindness, checksum and determinism guards. Full
    methodology: docs/benchmark-methodology.md.
  • Raw binary ingestion via declaration parameters on load_signal.
    Additive keyword parameters describe the layout: sample_format
    (float32/float64/int16/int32), byte_order (documented default
    little), n_channels/channel_index (interleaved extraction; a
    multi-channel derived id gains a _ch<k> suffix so channels never
    collide), header_offset, and an optional scale_factor. Required for a
    raw file: sample_format AND sampling_rate — explicit or from the
    companion <stem>_metadata.json (explicit wins) — because a headerless
    file has zero self-description; a load missing either is refused with ONE
    message naming everything missing and both remedies. The declaration is
    validated, never trusted blindly: payload-divisibility failures show the
    arithmetic (the best detector of a wrong dtype/channel count), and a float
    payload decoding to NaN/Inf is refused as a likely endianness/dtype
    mismatch. Declaring raw parameters on a self-describing format (CSV, WAV,
    ...) is refused as a contradiction — no-inference cuts both ways. Integer
    formats decode to raw ADC counts; scale_factor is the user's declared
    calibration multiplier into the physical unit — without it, declaring a
    unit on raw counts would have produced dangerously wrong ISO verdicts.
  • raw_format provenance on stored signals. The six EFFECTIVE decode
    parameters (after the explicit > companion > default merge) are recorded
    on StoredSignalInfo, so get_signal_info can answer "how was this file
    decoded" after the fact instead of leaving the decode contract implicit.
  • PMM_MAX_SIGNAL_SIZE pre-read size cap (bytes, default 500 MB) for
    raw loads, checked with stat() before a single byte is read — an
    explicit refusal with the env-var remedy instead of an OOM. Read from the
    environment at each call (the PMM_SIGNAL_CACHE_GB pattern), so it is
    overridable at runtime and testable. The 100 MB figure CLAUDE.md promised
    was never implemented and is too low for legitimate captures (1 h at
    25.6 kHz float32 ≈ 368 MB). Extending the cap to the other formats is
    follow-up work.
  • docs/TOOL_CATALOG.md — the complete endpoint reference. The full
    tool/prompt catalog migrated out of the README onto a dedicated page,
    guarded by CI against the registered surface: the set of listed names
    must equal the registered endpoints exactly, so the catalog can neither
    list a phantom endpoint nor silently omit a real one.
  • docs/ADAPTER_GUIDE.md — external adapter guide. Documents how an
    external adapter translates vendor metadata into the load_signal
    declaration and companion-file parameters. The guide's parameter table —
    names, allowed values, defaults, required flags — is guarded by CI
    against the code's own exports, in both directions.

Changed

  • README restructured around audience entry paths. Readers are routed
    by goal (use, evaluate, extend, contribute), with the measured-benchmark
    section above the fold; the full tool catalog moved to its own page
    (docs/TOOL_CATALOG.md), leaving the README a short guarded summary.

Fixed

  • .dat was listed but unloadable. The extension sat in
    SUPPORTED_EXTENSIONS — so list_signals(scope="disk") showed such
    files — but no loader branch existed, so every load failed. .dat is now
    raw-eligible on the same terms as .bin/.raw: it loads with a declared
    decode contract and is refused with the full remedy message without one.
  • Stale public claims corrected and guarded. Endpoint counts, the
    plugin skill count, the landing page's software version, and the test
    coverage figure (now stated as the CI-enforced minimum rather than a
    measured snapshot) had drifted on public surfaces; the CI guards now
    scan every copy on every public surface, so the next drift goes red
    instead of shipping.

Security

  • Path-containment tests extended to raw reads: relative traversal,
    Windows backslash traversal, and sibling-directory escapes with .bin
    paths are asserted rejected on the same closed-oracle terms as the
    existing formats (refusals reveal neither external file content nor
    directory listings).