sigwood v0.4.0
Added
-
dnsblockis now available as an opt-in detector for Pi-hole blocked-name
activity.sigwood dnsblock PATHand--detect=allrun it through normal public
discovery; the curated default hunt remains unchanged. It reports bounded first-activity
and query-burst findings plus recurring-activity context, states how much history the run
actually consulted, and treats the operator's own blocklist outcomes as input rather than
shipping a reputation verdict or feed. -
sigwood erameasures a whole dated Zeek archive as an allowlist-blind
retrospective. It reads traffic before hunt suppression so the report includes traffic
that an allowlist would hide. The ten-card report writes to stdout unless--out=PATHis
given and does not use the configured report directory; it has no timeframe flags because
it covers the archive as a whole. It prints plain text by default, and--format=htmlor
--format=pdfpresents the same measured cards as a self-contained page for reading in a
browser or handing to someone - the page fetches nothing from the network and carries no
scripts, and a PDF aimed at a terminal is refused rather than written as binary. Short or gappy archives still
produce an honest short report: cards that lack enough usable history abstain and explain
why, while an archive with no usable dated data is refused. Large archives ask for
confirmation before a long run. -
A bounded streaming foundation in the loader for detectors that need to analyze a
large archive without holding it in memory. The streaming path is opt-in per run and no
shipped detector binds it yet: an ordinary hunt takes the same single-pass read path as
before and never pays the new snapshot hashing; records within the new 1 MiB limit load
exactly as they did. On the streaming path, input is processed in bounded chunks (at
most 65,536 rows and 32 MiB of decoded text at a time) from a content-stable snapshot
of the selected files: a file replaced, truncated, or rewritten mid-run is detected and
refused rather than silently misread, while a plain log that merely grows mid-run is
read to its captured boundary and the appended tail waits for the next run. Per-file
results commit only when the whole file read cleanly. Measured on the same 3.2 GB
Pi-hole archive: a full-archive streaming pass completed with a peak under 150 MB of
memory, where the previous release's whole-frame path was stopped at an 8 GB memory
safety ceiling without completing. -
Exports now carry content-bound availability provenance. Each completed export
directory gains a private.sigwood-export-provenance.jsonmanifest that binds the
written files to their requested half-open UTC interval, size, and SHA-256. Export
commits stage private data and serialize the manifest-last replacement with a directory
lock, so a write interrupted after data replacement but before manifest replacement
leaves a torn pair that reads as unknown instead of claiming coverage it cannot prove;
interruption before any replacement preserves the prior state untouched. The manifest, lock, and private staging namespace are reserved product
artifacts: log discovery excludes them, and explicitly selecting one reports how to
choose the exported data instead.
Changed
-
The release workflow now drafts the GitHub Release itself after a successful PyPI
upload, with the tag's own changelog section as the notes. It creates a draft only;
publishing it remains a maintainer's step after reading the rendered notes. Previously
the Release was created entirely by hand as the step after the irreversible PyPI
approval, and a release could reach PyPI while the repository's Releases page kept
advertising the prior version - which is what happened with 0.3.0 for ten days. The
maintainer checklist (docs/RELEASING.md) now verifies that the published Release is
the repository's latest. -
A single log record larger than 1 MiB of decoded text is now skipped and disclosed
with a per-file warning naming the file and the skipped count, instead of being passed
whole into parsing and analysis. Real log lines are thousands of times smaller; the
limit keeps an oversized record out of every parser, frame, and analysis result and
makes the omission visible. The count also appears in the load's quality accounting.
Fixed
- Graph help now presents source-kind and source-path forms as alternatives, matching the
parser's exclusive choice.