Changelog0.4.0

Decisions

Decisions in fragcap 0.4.0.

2026-08-14 Added the optional Wireshark extcap registration to the Windows installer (crates/fragcap-cli/wix/main.wxs, release-adjacent and pinned), implementing the slice 041 decision D-4. Both scopes are offered: per-user by default, machine-wide for administrators. Per-user is a deferred, user-impersonated WiX custom action running the installed fragcap.exe extcap install, so the target resolves to the installing user's profile rather than SYSTEM; machine-wide is a non-impersonated action running extcap install --dir <WiresharkDir>\extcap, gated on a registry search that detects Wireshark. Both use the Defender-exclusion command pattern (immediate action sets CustomActionData, deferred WixQuietExec, Return="ignore" so a failure never fails the install) and add no new WiX extension, keeping the release job's cargo wix invocation unchanged. No fragcap CLI surface changed; the installer drives the already-shipped extcap install and --dir.

Registration is deliberately forward-only: unlike the Defender exclusion, it has no rollback and no unregister-on-uninstall. extcap registration is user-managed, idempotent state (a user may register or unregister independently with fragcap extcap install / uninstall), so an installer-owned undo would delete a registration this install does not own, on uninstall, on a major upgrade, or on rollback of an unrelated failure. Users unregister with fragcap extcap uninstall. This reverses the "paired rollback and removal" half of D-4, which assumed the Defender-exclusion symmetry applied; it does not, because registration state is shared with the user and the CLI. fragcap doctor probes the per-user extcap directory only, so it confirms the per-user scope; a machine-wide-only registration is confirmed by Wireshark listing fragcap as a source. Teaching doctor to also recognize the system extcap directory is a separate follow-up.

2026-08-14 Corrected the master schema's $id host from fragcap.dev to fragcap.com (https://fragcap.com/schema/target/v1.json), in the published copy docs/schema/target-schema.v1.json, the byte-identical embedded asset crates/fragcap-profile/assets/target-schema.v1.json, the CLI test that asserts the exact string (crates/fragcap-cli/tests/cli_schema.rs), and the identity contract example (specs/025-master-json-schema/contracts/master-schema.contract.md). Resolves issue #117.

This is recorded as a deliberate decision because the S025 identity contract states the $id host is fixed at authoring time and never changed for a published version. The change is made anyway, and it is safe: fragcap.dev was never a domain the project owned or served, fragcap.com is the project's real registered domain (the docs site), and the $id is an opaque stable identifier that nothing in the project dereferences over the network, so this is an identifier correction rather than a hosting change (no schema route is served at that URL, and none is added here). Schema version 1 is embedded in the binary and not published to any schema registry, so overwriting the v1 identity before 1.0 breaks no external consumer. The two schema copies are edited identically and remain byte-identical, enforced by the drift test in crates/fragcap-profile/tests/schema_conformance.rs.

2026-08-14 Adopted a single required/recommended/optional model for fragcap's external dependencies: npcap is required (the capture driver), Wireshark is recommended (the analyzer, whose installer also provides npcap), and the Wireshark extcap integration is optional (it ships with Wireshark and only needs fragcap registered as a source). fragcap doctor severities follow this model, and the documentation pass in a later slice single-sources the same wording so the tool and the docs cannot drift.

2026-08-14 De-hardcoded the release version from the release-runbook documentation in two pinned artifacts. release.toml's step-3 comment and scripts/New-Release.ps1's minor-bump .EXAMPLE both named a literal v0.2.0 / release/0.2.0, which went stale the moment the version moved and would misdirect an operator who read the file rather than the script's printed next steps. Both now use a vX.Y.Z / release/X.Y.Z placeholder, so they stay correct across releases. No behavior changed: release.toml still tags, pushes, and publishes nothing (tag, push, and publish are all false), and the scripts already print the tag command with the actual bumped version at runtime (git tag v${version} ...), which is unaffected. Recorded here because both files are pinned artifacts (surfaced by the Codex review of the v0.3.0 release, pull request 99).

2026-08-14 Corrected the MSI build in the release workflow (.github/workflows/release.yml) after the re-pointed v0.3.0 run reached the MSI step for the first time and failed on the cargo wix invocation. The step passed --ext WixUtilExtension, which cargo-wix's wix subcommand does not accept, and it omitted --target-bin-dir, which is required alongside --no-build so the hand-authored main.wxs can resolve $(var.CargoTargetBinDir) to the staged payload. The invocation now passes no extension flags (cargo-wix already links both WixUIExtension and WixUtilExtension, so adding either again makes light fail with duplicate-table and duplicate-symbol collisions) and sets --target-bin-dir to the release output directory.

Two main.wxs defects were fixed in the same change (that file is not a pinned artifact): an explicit ARPNOMODIFY property collided with the one WixUI_InstallDir already defines, and the WixUILicenseRtf path was relative to the package directory rather than the repository root where cargo wix runs.

The whole MSI build was then validated end to end offline against WiX 3.14: the installer compiles and links with no errors, and an administrative extract confirms it carries fragcap.exe, hint.db, LICENSE, and NOTICE under a fragcap directory with product name fragcap, version 0.3.0, and manufacturer ShruggieTech. This is a fix-forward: the v0.3.0 tag builds from the workflow as it was at the tag, so consuming it requires re-pointing the tag.

2026-08-14 Fixed two defects in the release workflow (.github/workflows/release.yml) that only surfaced when the release path first ran for real at the v0.3.0 tag; both had sat latent because the affected steps run only on a tag push and none had occurred since they were added.

First, the "Assert the featured binary starts without npcap" step (added with the release capability features, issue #62) accepted doctor exiting 0 or 1 in its guard and printed its success message, but never reset $LASTEXITCODE. On a runner without npcap, doctor correctly exits 1 (its "not ready" code), so the step inherited that 1 and GitHub Actions failed a check that had in fact passed, which blocked the whole release before any artifact was assembled. The step now ends with an explicit exit 0 on the success path; a doctor that fails to start (any exit other than 0 or 1) still fails the step through the existing guard.

Second, the "Install WiX and cargo-wix" step (added for the MSI, issue #96) installed WiX through choco but did not propagate the WIX environment variable and its bin directory to the later "Build the MSI installer" step, which runs in a fresh shell that does not inherit a mid-job machine-environment change. cargo-wix resolves the WiX binaries through the WIX variable, so the MSI build would not have found them. The step now reads the machine WIX variable after install and appends it to $GITHUB_ENV and its bin to $GITHUB_PATH, failing loudly if WiX is absent. This is a fix-forward: the v0.3.0 tag builds from the workflow as it was at the tag, so consuming the fix requires the operator to re-point the tag or cut the next version.