Skip to content

chore: release v0.9.4#309

Merged
Zious11 merged 25 commits into
mainfrom
release/0.9.4
Jun 23, 2026
Merged

chore: release v0.9.4#309
Zious11 merged 25 commits into
mainfrom
release/0.9.4

Conversation

@Zious11

@Zious11 Zious11 commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

This PR merges the release/0.9.4 branch into main and constitutes the v0.9.4 release of wirerust.

What's in this release (PRs #306 / #307 / #308)

Release checklist

  • Branch cut from develop @ 760b6ca
  • version = "0.9.4" in Cargo.toml / Cargo.lock
  • CHANGELOG.md ## [0.9.4] - 2026-06-23 section added
  • Commit chore: release v0.9.4 on release/0.9.4
  • Branch pushed; CI running
  • Human authorization to merge → main
  • Tag v0.9.4 on main after merge
  • Merge main back into develop

Zious11 added 25 commits June 22, 2026 16:19
…-conformant if_fcslen); resolve CORPUS-OBS-PCAPNG-IFFCSLEN-001
docs(e2e): record root cause for SPB fixture rejection; resolve CORPUS-OBS-PCAPNG-IFFCSLEN-001
rayon = "1" was present in [dependencies] but had zero usage across
src/, benches/, and tests/ (confirmed by grep). Removing it eliminates
an unnecessary direct dependency. rayon still resolves transitively via
criterion (dev-dep), so benchmark compilation is unaffected.
… RUSTSEC ignore

DEP-001: cargo update -p rand@0.8.5 --precise 0.8.6 clears RUSTSEC-2026-0097
(rand 0.8.x unsoundness). cargo audit now exits 0 with no advisories — the
--ignore RUSTSEC-2026-0097 flag in ci.yml is no longer needed and has been
removed. The comment block explaining the suppression is replaced with a
resolution note.

DEP-005: cargo update -p zerocopy bumps zerocopy 0.8.48→0.8.52 and
zerocopy-derive 0.8.48→0.8.52 (precautionary, within semver-compatible range).

All gates pass: build, test (all ok, 0 failed), clippy (-Dwarnings clean),
fmt (no drift), cargo audit (0 advisories).
DOC-001: CLAUDE.md .factory/ row — drop "STATE.md not yet initialized";
  reflect that STATE.md, stories, specs, research, and maintenance logs
  all exist under .factory/. Also add ADR-0009 to the docs/adr/ row.

DOC-003: README.md architecture table — Reader now parses both classic
  pcap and pcapng files (both formats, 5 link types); update component
  table row.

DOC-004: README.md features bullet — "pcap formats" replaced with
  "classic pcap and pcapng captures" to match the later Supported
  Capture Formats section and actual v0.9.3 behavior.

DOC-005: ADR-0002 — AnalysisSummary.detail type corrected from
  HashMap<String, serde_json::Value> to BTreeMap<String, serde_json::Value>
  (changed for deterministic JSON serialization per LESSON-P2.09 / NFR DET-001;
  src/analyzer/mod.rs line 52 is the source of truth).

DOC-006: ADR-0002 — StreamHandler::on_data signature corrected to include
  the fifth parameter (timestamp: u32) added for DNP3 windowed detection;
  matches src/reassembly/handler.rs exactly.

DOC-007: ADR-0003 — Replace stale src/main.rs line-number references in
  the Render-Mode Enum and Grouped-Mode Collapse sections with function-name
  anchors (run_analyze, run_summary, grouping_from_flag,
  collapse_findings_from_flag). Prose and behavioral claims are unchanged.

DOC-008: ADR-0002 — parse_error_count() reclassified from "Required" trait
  method to "Convention only" — it is an inherent method on specific analyzer
  structs for test access and appears in neither ProtocolAnalyzer nor
  StreamAnalyzer traits. Section renamed to "Required Methods and Conventional
  Accessors".

DOC-009: ADR-0001 struct snippet already showed modbus/dnp3 fields — no
  change needed (prior sweep had partially fixed this).
src/reader.rs references ADR-009 in 40+ inline comments and constants
but no public docs/adr/0009-*.md existed. This fills that gap.

Covers: dependency strategy (raw-block path via pcap-file 2.0.0, +0 new
crates); block-type coverage (SHB/IDB/EPB/SPB parsed; OPB/NRB/ISB/etc.
skipped); magic-byte content detection (not extension-based); timestamp
correction via BC-2.01.014 pure-core helper (crate high-level API silently
wrong for non-nanosecond captures); multi-IDB and multi-section policies;
IDB-after-first-packet rejection; SPB captured-len formula; error-code
assignment (E-INP-008 through E-INP-015); PcapSource::is_pcapng
discriminant; per-file isolation in directory mode; 4 GiB interim size
guard (E-INP-014, CWE-400); interface-table cap at 65535 (E-INP-015,
CWE-770); decode_epb_body extraction for Kani tractability; and string-
coupling regressions for SHB/IDB crate error messages. Verification
properties VP-025..031 summarised.

Authored to match existing docs/adr/0001-0007 style. Based on the
factory ADR-009 (rev 13, accepted 2026-06-20) and confirmed against
current src/reader.rs behavior.
chore: dependency hygiene sweep (maint-2026-06-22)
docs: fix documentation drift (maint-2026-06-22)
…N enrichment (BC-2.11.035)

Implements STORY-129 (issue #64): per-finding mitre_attack array in JSON output.

## src/mitre.rs
- Add `technique_tactic_id(id: &str) -> Option<&'static str>`: exhaustive match
  over all 17 MitreTactic variants to their canonical TA-prefix IDs per BC-2.11.035.
  Adding a new MitreTactic variant without updating this table is a compile error.
- Extend `vp007_catalog_drift_guard` test: cross-checks that every seeded ID returns
  Some from technique_tactic_id and that the canary T9999 returns None.

MitreTactic → TA-ID mapping:
  Reconnaissance→TA0043, ResourceDevelopment→TA0042, InitialAccess→TA0001,
  Execution→TA0002, Persistence→TA0003, PrivilegeEscalation→TA0004,
  DefenseEvasion→TA0005, CredentialAccess→TA0006, Discovery→TA0007,
  LateralMovement→TA0008, Collection→TA0009, CommandAndControl→TA0011,
  Exfiltration→TA0010, Impact→TA0040, IcsInhibitResponseFunction→TA0107,
  IcsImpairProcessControl→TA0106, IcsImpact→TA0105

## src/reporter/json_dto.rs
- Implement `From<&'a Finding> for FindingJsonDto<'a>`: builds mitre_attack array
  from mitre_techniques; id and reference always present; name/tactic_id/tactic_name
  skipped via skip_serializing_if when None (unknown technique ID).
  Order-preserving; duplicates not deduplicated (BC-2.11.035 inv2/inv3).
- Remove #[allow(dead_code)] now that types are wired and used.

## src/reporter/json.rs
- Serialize findings as `Vec<FindingJsonDto>` instead of raw `&[Finding]` so
  mitre_attack appears inside each findings[*] object.

## src/reporter/mod.rs
- Register `json_dto` as `pub(crate)` module.
…ment

VHS recordings demonstrating BC-2.11.035 implementation:
- AC-001: JSON output with populated mitre_attack array (modbus-write.pcap)
  shows 5-field resolved objects, multi-tag order, ICS tactic_id, unchanged
  mitre_techniques
- AC-009: CSV output showing no mitre_attack column (additive/non-breaking)
feat: emit per-finding mitre_attack array in JSON output
…nts (F5)

BC-2.10.002 v1.6 / BC-2.10.003 v1.5 / BC-2.10.007 v1.9 — ICS tactic-ID correctness fix.

New MitreTactic variants:
  IcsDiscovery     TA0102  — T0846, T0888 (remapped from Enterprise Discovery TA0007)
  IcsCollection    TA0100  — T0830 (remapped from LateralMovement TA0008)
  IcsCommandAndControl TA0101 — T0885 (remapped from Enterprise C2 TA0011)
  T0831 remapped IcsImpairProcessControl → IcsImpact (TA0105, MITRE ICS v19.1)

Display strings follow the D-069 "(ICS)" disambiguation convention:
  IcsDiscovery        → "Discovery (ICS)"
  IcsCollection       → "Collection (ICS)"
  IcsCommandAndControl → "Command and Control (ICS)"

all_tactics_in_report_order: length 17→20; new variants appended at [17][18][19].
technique_tactic_id: 3 new arms added; match remains exhaustive (compile-forced).
Fixed stale comment: ICS Discovery TA0111 → TA0102; updated merge-by-name rationale
to reflect that ICS Discovery/Collection/C2 now have dedicated variants.

All tests green; clippy clean; fmt clean.
…S tactic IDs

Re-record AC-001 (T0888 Discovery) after fix/ics-tactic-ids corrects the tactic
mapping: T0888 now resolves to TA0102 "Discovery (ICS)" (ICS matrix) instead of
the incorrect TA0007 "Discovery" (Enterprise matrix) shown in the PR #306 demo.
Update evidence-report.md to cite TA0102 and add T0888 corrected JSON snippet.
…ale T0830 tactic comments (F5 Pass-1)

FIX 1 (L-1 accuracy): corrected two stale comments in src/mitre.rs that still
attributed T0830 to the pre-F5 LateralMovement tactic:
  - src/mitre.rs:305 (Kani/emitted-ID list): LateralMovement → IcsCollection/TA0100
  - src/mitre.rs:371 (SEEDED_TECHNIQUE_IDS doc-comment): ICS LateralMovement → ICS IcsCollection/TA0100
Both comments now match the F5 remap confirmed by the authoritative research table
(f5-ics-technique-tactic-authoritative.md, MITRE ATT&CK for ICS v19).

FIX 2 (process-gap hardening): added test_ics_techniques_resolve_authoritative_tactic_ids
in tests/mitre_tests.rs. Asserts the exact technique_tactic_id() string for every ICS
technique in the catalog (12 assertions: T0888/T0846→TA0102, T0885→TA0101,
T0830→TA0100, T0831/T0827→TA0105, T0836/T0806/T0835/T1692.001→TA0106,
T0814/T1691.001→TA0107). Closes the Pass-1 process gap where a tactic-variant swap
would produce the correct tactic name but the wrong TA-id string, bypassing
tactic-variant tests silently. References the F5 authoritative table inline.
…CI fix)

Update 3 test files that still asserted pre-F5 Enterprise tactic values for ICS
techniques, causing CI failures after the F5 tactic-remap commits (719816e, cf22de9):

- tests/bc_2_09_100_multitag_tests.rs:
  - T0846 → IcsDiscovery (was Discovery/TA0007)
  - T0885 → IcsCommandAndControl (was CommandAndControl/TA0011)
  - T0831 → IcsImpact (was IcsImpairProcessControl/TA0106)
  - T0888 → IcsDiscovery (was Discovery/TA0007)
  - test_BC_2_10_007_t0888_maps_to_discovery_tactic: assert IcsDiscovery not Discovery

- tests/reporter_json_tests.rs:
  - test_BC_2_11_035_ec010_ics_lateral_movement → renamed ec010_ics_collection
  - T0830 tactic_id: TA0100 (was TA0008 LateralMovement)
  - T0830 tactic_name: "Collection (ICS)" (was "Lateral Movement")

- tests/bc_2_16_story114_arp_tests.rs:
  - T0830 → IcsCollection (was LateralMovement)
  - T0846 → IcsDiscovery (was Discovery)

All values verified against MITRE ATT&CK for ICS v19 authoritative table
(f5-ics-technique-tactic-authoritative.md).
Corrects ICS tactic IDs (T0830→Collection/TA0100, T0831→Impact/TA0105, T0846/T0888→Discovery/TA0102, T0885→C2/TA0101); 3 new MitreTactic variants; 5 BCs + 3 holdouts updated; 3-pass adversarial convergence + confirmation; security PASS. Textual pr-reviewer sign-off canonical (formal gh approve blocked by self-review policy).
…7 consistency)

F7-CV-001: README.md ARP detection table — D1 and D12 rows had "Adversary-in-the-Middle"
in the Tactic column, which is the technique name not the tactic. T0830 (ICS) maps to
Collection/TA0100; T1557.002 (Enterprise) maps to Credential Access/TA0006. Both rows
now show "Collection (ICS), Credential Access".

F7-CV-003: 2026-04-13 MITRE design spec — add SUPERSEDED banner (F5 ICS tactic-ID fix
deprecated the single-Discovery-variant approach; T0855/T0856 were remapped in v19).
Correct inline factual error TA0111 -> TA0102 for ICS Discovery with inline note.
README ARP tactic column corrected (T0830→Collection ICS/TA0100, T1557.002→Credential Access); design-doc SUPERSEDED banner + TA0111→TA0102 fix. F7 consistency-audit follow-up.
@Zious11 Zious11 merged commit 96b49e8 into main Jun 23, 2026
10 checks passed
@Zious11 Zious11 deleted the release/0.9.4 branch June 23, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant