Skip to content

refactor(intune): thin Framework v1 extraction (mapping, test support, invariant docs) - #543

Merged
adamgell merged 5 commits into
mainfrom
framework/pr4-thin-extraction
Aug 10, 2026
Merged

refactor(intune): thin Framework v1 extraction (mapping, test support, invariant docs)#543
adamgell merged 5 commits into
mainfrom
framework/pr4-thin-extraction

Conversation

@adamgell

@adamgell adamgell commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Thin PR 4 of the Reducer Framework. An inspection cycle concluded that almost nothing should be extracted; this implements exactly the three items that survived that conclusion. No reducer behavior changes.

1. Extracted: the IntuneAccessState <-> IntuneArtifactStatus mapping

Three copies of a pure 7-arm total bijection existed. Every arm was verified identical before replacing (see "arm-by-arm verification" below). Both directions now live in crates/cmtraceopen-parser/src/intune/evidence.rs, beside the two enums:

  • artifact_status_for_access_state(&IntuneAccessState) -> IntuneArtifactStatus
  • access_state_for_artifact_status(&IntuneArtifactStatus) -> IntuneAccessState

Both are exhaustive match with no _ arm, so a new variant on either enum is a compile error rather than a silently defaulted status in whichever lane copied the table last. Signatures take & because neither enum is Copy and adding Copy would be an unrelated public API change.

The exhaustiveness test moved from win32/sources.rs to evidence.rs and now also pins the inverse direction (the Store lane's half), which nothing tested before.

Lane updates:

Lane Before After
apps/windows/win32/sources.rs local coverage_status calls artifact_status_for_access_state
apps/windows/microsoft_store/reducer.rs local access_state_for calls access_state_for_artifact_status
enrollment/windows/autopilot/sources.rs declared_status and access_state, both 7-arm tables over the lane-local AutopilotCaptureState access_state kept (it is this lane's own collector vocabulary); declared_status is now artifact_status_for_access_state(&self.access_state())

Autopilot keeps access_state because its source enum is AutopilotCaptureState, which is not shared and should not be. Only the second hop, IntuneAccessState -> IntuneArtifactStatus, was ever the shared part.

Arm-by-arm verification

IntuneAccessState IntuneArtifactStatus win32 coverage_status store access_state_for (inverse) autopilot declared_status / access_state
Available Available match match Captured -> both, consistent
Missing Missing match match Absent -> both, consistent
PermissionDenied PermissionDenied match match AccessDenied -> both, consistent
Capped Capped match match Capped -> both, consistent
Skipped Skipped match match Skipped -> both, consistent
Failed ParseFailed match match ParseFailed -> ParseFailed / Failed, consistent
Unsupported Unsupported match match Unsupported -> both, consistent

No lane had a divergent arm. declared_status(x) == artifact_status_for_access_state(&access_state(x)) held for all seven Autopilot capture states, which is why the composition is a pure dedup and not a normalization.

2. Mechanical test-support consolidation

Added to crates/cmtraceopen-parser/tests/support/mod.rs:

  • scenario_root(corpus, scenario) — replaces 5 local copies (win32 spelled it corpus().join(...)).
  • artifact_status_for_capture_state(&str) -> IntuneArtifactStatus — replaces 3 local copies (microsoft_store::status_for, compliance::capture_status, configuration::status_for), which were byte-identical.
  • access_state_for_capture_state(&str) -> IntuneAccessState — the Win32 adapter. Implemented as the status table composed with the crate's own access_state_for_artifact_status, rather than a second hand-written table, so a fixture can never disagree with the crate about what parseFailed means.
  • wire<T: Serialize>(&T) -> Value — replaces the identical configuration::wire and autopilot::wire (one generic, one impl Trait).
  • sorted_evidence_ids(&Value) -> Vec<String> — explicitly named, for consumers where citation order is not part of the contract.

configuration::status_for carried a comment claiming it was "kept explicit rather than derived from the harness table so a drift in either direction is a compile-visible change here". That rationale was aimed at the CAPTURE_STATE_COVERAGE string-pair table, not at a typed helper; the typed helper it now calls is strictly more drift-resistant. Flagging it because it was an explicit anti-consolidation note and reviewers should agree with removing it.

evidence_ids determination, per consumer

Investigated before touching either copy. They are not two spellings of one helper; they assert different contracts.

Consumer Contract Determination Evidence
intune_windows_compliance.rsassert_settings (settings[].evidence) set order not meaningful, use shared helper Local evidence_ids sorted, and it was paired against strings(&want[...]) which also sorts. Both sides normalized, so no assertion could ever observe order.
intune_windows_compliance.rsassert_access (access[].matchedEvidence) set order not meaningful, use shared helper Same: sorted vs strings (sorted).
intune_windows_compliance.rsassert_findings (findings[].evidence) set order not meaningful, use shared helper Same: sorted vs strings (sorted). Note the sibling coverageGapIds assertion in the same function is strings vs strings, i.e. the whole leaf is consistently set-valued.
intune_windows_microsoft_store.rsassert_transactions (transactions[].evidence) sequence order IS meaningful, left local Local evidence_ids preserves insertion order and is paired against expected_strings, which does not sort, so assert_eq! on two Vec<String> asserts order directly. Immediately below it, the same function asserts observations.len() == evidence.len() with the message "observations and evidence must stay in step" — a positional pairing between the two arrays. Sorting the evidence side would silently retire that pairing with no test failing.
intune_windows_microsoft_store.rsassert_findings (findings[].evidence) sequence order IS meaningful, left local Same helper, same unsorted expected_strings counterpart.

So: compliance moved to support::sorted_evidence_ids (all three call sites); Microsoft Store kept its local version, now carrying a doc comment stating why it is deliberately not the shared helper. The two were not forced onto one helper.

The store copy also panics where compliance's defaults to "" on a missing evidenceId. That difference is preserved too: in the store corpus a missing evidenceId is a corpus bug, and defaulting it would let a broken fixture compare equal.

Deliberately NOT extracted (one line each)

  • Autopilot capture_state (test helper) — returns the lane-local AutopilotCaptureState via serde rename_all, not IntuneArtifactStatus; routing it through the shared helper would mean re-deriving a lane enum from a status, which is backwards.
  • Autopilot AutopilotCaptureState::access_state — the collector-vocabulary hop is genuinely Autopilot's to own; only the second hop was shared.
  • Microsoft Store evidence_ids — asserts citation order and positional step with observations; see the table above.
  • Assessability helpers — Win32 treats Capped as able to prove a terminal outcome while Autopilot/Compliance do not; the predicates contradict each other by contract.
  • Confidence degradation — Store maps degraded to Low, Win32 to Medium; contradictory by contract, both correct.
  • Linkage / supersession — four different source contracts (Store asymmetric activity_id pairwise, Autopilot orderless activity_id sets, Win32 two grammars plus transitive closure, Configuration refuses and returns Contested); a shared helper would have to be the loosest of the four.
  • The ADR-001 directional gate — shared as prose only; Autopilot gates on the envelope plus a failure-shaped signal, Configuration gates on a readable envelope whose result token is unreadable. Neither predicate can express the other's case.
  • Redaction projection and equality scope — the grammar already has one owner; which fields a lane classifies sensitive is that lane's contract.
  • Permutation runtime and test helpers, CandidateOrder, evidence-resolution assertions — out of scope for this PR by instruction; untouched.

3. Documentation

  • docs/architecture/decisions/ADR-001-evidence-strength-confidence.md — addendum: the directional doctrine ("non-assessable evidence cannot prove, but a recorded non-assessable failure must still block a success") is shared prose, its mechanism is per-lane. Cites both sites: Autopilot enrollment/windows/autopilot/reducer.rs ~650-707 (recorded_non_assessable_failure_sections / ..._observations) enforced ~1668-1688, and Configuration device/windows/configuration/sources.rs ~163-174 (is_unassessable_failure) enforced in .../configuration/reducer.rs ~246-263.
  • docs/architecture/shared-vs-workload-invariants.md (new) — a table of what is shared vs deliberately workload-specific, explicitly protecting the tested divergences so a future "consistency" PR cannot delete them: the Win32 capped-but-terminal rule and its test, Autopilot's ungated time_basis and its AutopilotKeyGate::Detecting/Proving split, Configuration admitting IntuneParseState::Raw, the Store-vs-Win32 degradation constants, the four linkage contracts, and the redaction grammar-vs-projection line. Closes with a three-part extraction test.

Gates

Gate Result
cargo test -p cmtraceopen-parser 2442 passed, 0 failed, 1 ignored across 51 test binaries. Count did not drop.
cargo clippy -p cmtraceopen-parser --all-targets -- -D warnings clean
cargo check --workspace clean
cargo check -p cmtraceopen-parser --target wasm32-unknown-unknown clean
git diff --check clean

No tauri::test::mock_app(). No rustfmt run on files not created in this PR.

Defects found

None. No lane had a divergent arm, and nothing required a RED-first follow-up.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Standardized status handling across Intune Windows evidence, compliance, configuration, Win32, Microsoft Store, and Autopilot scenarios.
    • Improved consistency when translating access states, artifact statuses, and failed parsing outcomes.
  • Documentation

    • Clarified evidence confidence rules and workload-specific enforcement behavior.
    • Added guidance on shared invariants, intentional behavioral differences, redaction, evidence ordering, and fixture conventions.
  • Tests

    • Expanded coverage for status conversions and improved scenario and evidence validation across Intune Windows workflows.

…, invariant docs)

Three items, all behavior-preserving.

1. The IntuneAccessState <-> IntuneArtifactStatus bijection existed as three
   copies. Both directions now live in intune/evidence.rs beside the enums,
   with exhaustive matches (no `_` arm) so a new variant is a compile error.
   Win32 and Microsoft Store call the shared pair directly; Autopilot's
   declared_status is now the composition of its own lane-local capture-state
   mapping with the shared one. Verified arm by arm as identical first.

2. Mechanical test-support consolidation into tests/support/mod.rs:
   scenario_root, artifact_status_for_capture_state (plus an
   access_state_for_capture_state adapter for Win32), wire, and
   sorted_evidence_ids.

   Deliberately left local: Microsoft Store's insertion-ordered evidence_ids
   (that leaf asserts citation order), and Autopilot's capture_state (returns a
   lane-local enum via serde, not IntuneArtifactStatus).

3. Docs: an ADR-001 addendum recording that the directional doctrine is shared
   prose while its mechanism is per-lane, and a new
   docs/architecture/shared-vs-workload-invariants.md protecting the tested
   divergences from a future "consistency" PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added enhancement New feature or request intune Microsoft Intune related parser Log parser related labels Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR centralizes bidirectional Intune status mappings, updates runtime consumers, adds shared fixture helpers, migrates workload tests, and documents shared invariants and workload-specific evidence rules.

Changes

Intune status centralization

Layer / File(s) Summary
Shared evidence mappings
crates/cmtraceopen-parser/src/intune/evidence.rs
Adds exhaustive conversions between IntuneAccessState and IntuneArtifactStatus, including inverse round-trip tests.
Runtime consumer migration
crates/cmtraceopen-parser/src/intune/apps/windows/microsoft_store/reducer.rs, crates/cmtraceopen-parser/src/intune/apps/windows/win32/sources.rs, crates/cmtraceopen-parser/src/intune/enrollment/windows/autopilot/sources.rs
Replaces local status mapping functions with the shared evidence conversions.
Shared fixture support
crates/cmtraceopen-parser/tests/support/mod.rs, crates/cmtraceopen-parser/tests/intune_windows_*.rs
Adds shared scenario, capture-state, serialization, and evidence-ID helpers. Workload tests use the shared helpers.
Architecture invariants
docs/architecture/decisions/ADR-001-evidence-strength-confidence.md, docs/architecture/shared-vs-workload-invariants.md
Documents directional evidence rules, shared reducer invariants, and protected workload-specific differences.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commits and accurately describes the Intune refactoring changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch framework/pr4-thin-extraction

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the test Testing related label Aug 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/architecture/decisions/ADR-001-evidence-strength-confidence.md`:
- Around line 24-27: Update the Autopilot row in the architecture decision table
to explicitly define assessability as access_state == Available && parse_state
== Parsed, and express the non-assessable condition as its negation where
applicable. Preserve the existing failure-signal gating and Configuration row
wording.
- Around line 31-42: Normalize all source references in the architecture
documents to verified repository-relative paths. In
docs/architecture/decisions/ADR-001-evidence-strength-confidence.md:31-42,
replace the abbreviated configuration reducer reference with its full path; in
docs/architecture/shared-vs-workload-invariants.md:26-30, :40-47, :63-64,
:81-82, :90-92, :106-108, :138-142, and :146-153, replace every abbreviated
evidence, test-support, reducer, source, Autopilot, Compliance, Store, Win32,
redaction, and Microsoft Store reference with its corresponding full repository
path. Preserve the existing symbols and line-range references while ensuring
every path resolves from the repository root.

In `@docs/architecture/shared-vs-workload-invariants.md`:
- Around line 6-8: Update the lane-count wording in the sentence beginning “Four
lanes” to “Five lanes,” matching the five listed lanes: Win32, Microsoft Store,
Autopilot, Configuration, and Compliance.
- Around line 25-26: Revise the “Additive-only” guidance for the evidence
envelope types in the shared-vs-workload invariants table so it applies only to
wire-format evolution, not general Rust API compatibility. Document the separate
Rust API release policy for these constructible public types, including the
impact of new enum variants and public struct fields, or adjust the types to
hide construction and matching for extensibility.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97eaf6cb-fdeb-49f7-8b48-084e7189c3ca

📥 Commits

Reviewing files that changed from the base of the PR and between 0897d0a and 036672b.

📒 Files selected for processing (12)
  • crates/cmtraceopen-parser/src/intune/apps/windows/microsoft_store/reducer.rs
  • crates/cmtraceopen-parser/src/intune/apps/windows/win32/sources.rs
  • crates/cmtraceopen-parser/src/intune/enrollment/windows/autopilot/sources.rs
  • crates/cmtraceopen-parser/src/intune/evidence.rs
  • crates/cmtraceopen-parser/tests/intune_windows_autopilot.rs
  • crates/cmtraceopen-parser/tests/intune_windows_compliance.rs
  • crates/cmtraceopen-parser/tests/intune_windows_configuration.rs
  • crates/cmtraceopen-parser/tests/intune_windows_microsoft_store.rs
  • crates/cmtraceopen-parser/tests/intune_windows_win32.rs
  • crates/cmtraceopen-parser/tests/support/mod.rs
  • docs/architecture/decisions/ADR-001-evidence-strength-confidence.md
  • docs/architecture/shared-vs-workload-invariants.md

Comment thread docs/architecture/decisions/ADR-001-evidence-strength-confidence.md
Comment thread docs/architecture/decisions/ADR-001-evidence-strength-confidence.md
Comment thread docs/architecture/shared-vs-workload-invariants.md Outdated
Comment thread docs/architecture/shared-vs-workload-invariants.md Outdated
@adamgell

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@adamgell

Copy link
Copy Markdown
Owner Author

Hermes charter review

Verdict

Behavior-preservation verdict: PASS for the authorized code/test extraction. At exact head 036672bf977caec44ce8d2e26509df88daa5e762 against base 0897d0ac1fd76117ae53b539603fbee2d1e0a81f, I found no reducer behavior change in the scoped implementation. The seven-arm mappings, Autopilot composition, helper consolidation, and lane-local semantics preserve the pre-PR contracts.

Findings (ranked)

P1 — The protective architecture document is not accurate/reproducible as written

docs/architecture/shared-vs-workload-invariants.md:6-7 says “Four lanes” while listing five lanes (Win32, Microsoft Store, Autopilot, Configuration, Compliance). More importantly, many code references are abbreviated with ... or omit the repository-root prefix (:27, :40-47, :63-64, :81-92, :106-108, :138-153). A reader cannot use those references as written, and the document’s claim that the protected divergences are tested is weakened by references that do not resolve. The same document says “Every reduction path in the Autopilot reducer passes through is_assessable” (:56) while immediately identifying time_basis as the deliberate ungated exception (:57-60); that wording should be narrowed to the paths where assessability is actually the admission rule. This is blocking for the documentation deliverable: an inaccurate guardrail is worse than no guardrail.

The requested divergence descriptions themselves are directionally correct after checking the exact-head code: Win32 capped-still-proves with confidence demotion; Autopilot ungated time_basis; Autopilot Detecting-versus-Proving split; Configuration Raw admission; Store Low versus Win32 Medium degradation; four distinct linkage contracts; and shared redaction grammar with local projections. The issue is precision and navigability, not a recommendation to unify those semantics.

P2 — Full repository formatting is not a clean exact-head gate

cargo fmt --all -- --check fails on pre-existing formatting outside this PR as well as on some touched files. The exact scoped tests, full parser test suite, strict parser Clippy, and git diff --check pass; this remains a gate-state issue rather than evidence of behavior drift. No files were changed to “fix” formatting.

Behavior-preservation evidence

  • Mapping arms: I compared the three former origin/main copies arm-by-arm, not merely by shape. They were byte-identical in their seven mappings:
    Available→Available, Missing→Missing, PermissionDenied→PermissionDenied, Capped→Capped, Skipped→Skipped, Failed↔ParseFailed, and Unsupported→Unsupported. The shared functions reproduce each arm exactly with exhaustive matches and no wildcard/default arm. The shared unit test checks all seven forward arms and all seven inverse arms.
  • Autopilot: AutopilotCaptureState::declared_status() now composes access_state() with the shared access-state→status function. The seven former direct results are therefore preserved exactly, including ParseFailed→Failed through the inverse direction. The Autopilot focused suite passed 47 tests (1 ignored golden rewrite).
  • Test helpers: Microsoft Store’s local evidence_ids remains insertion-ordered and panicking; its positional evidence/observation assertion remains intact. Compliance alone uses the sorted shared helper, and both actual and expected citation sides were already sorted. The Compliance, Store, Autopilot, and Win32 focused suites all passed.
  • Lane semantics: The extraction changes only mapping/helper call sites. No coverage, confidence, assessability, linkage, chronology, terminal precedence, or redaction projection logic moved. The documented divergences remain workload-local.

Ruling on the configuration::status_for override

Sound, with one qualification: approve this override. The old comment correctly protected against drift between a string-pair fixture table and local code, but the PR does not replace it with an untyped shared string table. It uses the existing typed test-support capture-state boundary for the fixture string vocabulary, then uses the shared exhaustive typed mapping for the library vocabulary. That is more drift-resistant for the seven enum semantics: adding an IntuneAccessState variant or changing the status mapping produces compile-visible failures in the shared match and its inverse test. The string-to-fixture vocabulary remains intentionally runtime-validated by an explicit panic for unknown capture states; that is the correct boundary and does not justify retaining three identical status tables.

Charter layers

  • Contract layer: PASS for the scoped behavior-preservation question. Evidence/coverage strength, identity/linkage, chronology/terminal precedence, coverage honesty, and redaction scope are unchanged; the new documentation correctly warns against cross-lane semantic unification, subject to the P1 wording/path corrections.
  • Adversarial layer: PASS for this extraction. I checked the false-story surfaces relevant to the change: silent arm normalization, Autopilot status composition, sorted-vs-positional citations, and accidental movement of lane semantics. No concrete behavior-preservation failure survived verification.
  • Mechanical layer: PASS for the scoped code: full cargo test --locked -p cmtraceopen-parser passed (995 unit tests, all parser integration targets, 6 doctests); strict parser Clippy passed; git diff --check passed. The repository-wide formatter check is not clean as noted above.

Gate states

  • Exact head: PASS — remote head is 036672bf...; working checkout was not changed.
  • CI: NOT CLEAR at review time — Rust, MSRV, TypeScript, E2E, CodeQL, and ESP Diagnostics checks were successful; macOS, Windows, and Linux build checks were still in progress when checked.
  • CodeRabbit: BLOCKED — CHANGES_REQUESTED, not approved_at_head for this exact head. Its actionable documentation findings overlap the P1 above and should be resolved before merge.
  • Hermes charter review: POSTED by this comment; P1 documentation finding remains open.
  • Native/lab validation: NOT RUN / not applicable to this pure parser extraction; synthetic fixture success is not native Windows acceptance.
  • Merge readiness: BLOCKED by the P1 documentation accuracy issue, CodeRabbit not approved at head, and incomplete CI build state. This is not a merge verdict; Adam owns the merge decision after those gates clear.

Coverage statement

This review covered the exact PR diff and affected context only: the Intune mapping extraction, Autopilot composition, test-support consolidation, documentation accuracy, and preservation of the named reducer invariants. It did not review unrelated repository changes, perform native Windows/Intune collection validation, or modify files, resolve threads, merge, or check out the PR branch.

adamgell and others added 3 commits August 10, 2026 12:29
…able

The invariant document and the ADR-001 addendum were meant to protect
deliberate cross-lane divergences from a future consistency PR, but three
defects made them unusable as guardrails:

- the lane count said "Four" while listing five lanes;
- code references were abbreviated to `.../autopilot/reducer.rs`, which a
  reader cannot resolve from the repository root;
- the Autopilot section claimed every reduction path passes through
  `is_assessable`, then identified `time_basis` as an exception two lines
  later, and section 3 documents a second one.

Paths are now repository-root relative with line numbers, and the
assessability claim is replaced by what the reducer actually does: gated
status paths, two deliberately inverted coverage-gap filters
(reducer.rs:672, :705), and two deliberately ungated paths (time_basis at
:541, Detecting at :1350). The ADR's Autopilot trigger states the boolean
predicate instead of the ambiguous "envelope not Available + Parsed".

An inaccurate guardrail is worse than no guardrail: it invites the reader to
distrust the divergences it exists to protect. Documentation only; no code
or test changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ust API

The evidence envelope row read as a compatibility guarantee, but none of
those types are #[non_exhaustive] and cmtraceopen-parser is published, so
appending a variant breaks downstream exhaustive matches even when it is
harmless for serialized output. The next table row already depended on that
breakage (a new variant becoming a compile error), so the two rows
contradicted each other. Scope the guarantee to the wire format and state
the crate-release consequence.

Also finishes normalizing the table's code references to repository-root
paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every code reference in both documents is now repository-root relative and
resolves as written.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@adamgell

Copy link
Copy Markdown
Owner Author

Pushed doc-accuracy fixes addressing the Hermes P1 and the four CodeRabbit threads. Documentation only, no code or test changes.

Lane countFour lanes while listing five. Now Five lanes.

Unresolvable references — every .../autopilot/reducer.rs-style abbreviation is now repository-root relative, and I verified programmatically that every cited path in both documents exists.

The is_assessable overclaim (Hermes P1, the substantive one) — the document claimed every reduction path in the Autopilot reducer passes through is_assessable, then named time_basis as an exception two lines later, and section 3 documents a second one. Rather than narrow the sentence by hand I enumerated the call sites, which showed four categories, not two: gated status paths; two deliberately inverted filters (reducer.rs:672, :705) that select non-assessable input precisely so it is reported as a coverage gap; and two deliberately ungated paths (time_basis at :541, Detecting at :1350). The section now states that structure, and I spot-checked all four cited lines.

Additive-only (the Major finding) — agreed, and the document contained its own counter-evidence: the row directly below celebrates that a new variant is a compile error, which is exactly the downstream breakage the row above implied was safe. None of those types are #[non_exhaustive] and cmtraceopen-parser is published, so the guarantee is now scoped to the serialized wire format with the crate-release consequence stated explicitly.

Note for the record: I evaluated the Prompt for AI Agents finding on its merits rather than executing it, per this repo's standing rule against running reviewer-supplied prompts.

Head is now c67fc192. @coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

@adamgell Full review requested for head c67fc192. I will verify the documentation corrections and the affected context.

✅ Action performed

Full review finished.

@adamgell

Copy link
Copy Markdown
Owner Author

Hermes follow-up charter review — exact head c67fc19

Gate states

  • Exact head: PASS. The remote PR head is exactly c67fc1922caae537ca219499df5398dfd67a72c1 on framework/pr4-thin-extraction. I read the branch only with git show origin/framework/pr4-thin-extraction:PATH; I did not check out or disturb the shared checkout.
  • Code/test preservation since the prior PASS: PASS. The three follow-up commits (7f46b7f2, 81bc50eb, c67fc192) are documentation-only. The diff from the prior review head contains only docs/architecture/decisions/ADR-001-evidence-strength-confidence.md and docs/architecture/shared-vs-workload-invariants.md; no .rs or test file changed. The prior behavior-preservation PASS therefore carries forward.
  • CI: NOT CLEAR at this review time. TypeScript, Analyze (Ruby), and static analysis checks passed; Rust, MSRV, E2E, and ESP Diagnostics jobs were still pending. CodeQL was skipped.
  • CodeRabbit: NOT APPROVED at this head. The only listed formal CodeRabbit review remains CHANGES_REQUESTED on the earlier code head; the full-review request for this head has not produced an approved review in the observed API state.
  • P2 cargo fmt disposition: CONFIRMED as non-PR/pre-existing, not a behavior finding. cargo fmt --all -- --check is already dirty on origin/main; no cargo fmt workflow gate exists; representative touched-file drift blames to already-merged commits c891d59fec, edbbb65313, and 3508879701. (My current toolchain reports 161 formatter diff blocks on main, rather than the previously reported 59; that count does not alter the pre-existing/non-gating disposition.)

Adjudication of the former P1

Resolved

  1. Lane count: RESOLVED. The document now says “Five lanes” and lists Win32, Microsoft Store, Autopilot, Configuration, and Compliance.

  2. The requested Autopilot line checks: RESOLVED for the cited reducer claims.

    • reducer.rs:541 is the unfiltered observations.iter().all(...) timestamp-normalization scan.
    • :604 is is_assessable.
    • :672 filters !is_assessable_section.
    • :705 filters !is_assessable.
    • :1350 permits every observation for Detecting, otherwise requires is_assessable.
      The prose’s narrowed claim is materially accurate: ordinary status/phase/signal paths are gated; the two coverage-gap paths deliberately invert the predicate; time_basis is deliberately ungated; and Detecting is deliberately ungated. This is true of the code, not merely internally consistent prose. The two “ungated” items are grouped in one bullet, but both are explicitly named and separately documented in the following sections, so I do not treat that presentation choice as a defect.
  3. Additive-only scope: PARTIALLY RESOLVED, but one material overclaim remains. It is correct that the guarantee is now expressly limited to the serialized wire format, that the listed public types are not #[non_exhaustive], and that adding variants/public fields can break downstream exhaustive matches and struct literals. However, the sentence still says wire-format evolution may “append variants” so older readers keep parsing newer output. That is not true for the ordinary serde enums in evidence.rs (for example IntuneTimestampKind, IntuneSensitivity, IntuneParseState, and IntuneAccessState): their derived deserializers reject an unknown newly added variant. Only the raw-preserving string-enum macro has an unknown-value path. The guarantee must either restrict additive wire evolution to optional fields and explicitly raw-preserving enum types, or explain/version the enum compatibility policy. As written, the wire-format claim is still broader than the implementation.

Remaining P1

  1. Citation normalization: NOT FULLY RESOLVED. Almost all paths are repository-root relative and resolve, including the ADR addendum paths. But the shared invariants document still cites tests/intune_windows_microsoft_store.rs at its test-helper section (shared-vs-workload-invariants.md:162) without the repository-root crates/cmtraceopen-parser/ prefix. The actual file is crates/cmtraceopen-parser/tests/intune_windows_microsoft_store.rs. Therefore the requirement that every code citation be repository-root relative and resolve as written is not met. The cited reducer lines themselves resolve and support the claims above; this is a remaining navigability defect.

Result

The original P1 is NOT fully resolved. Lane count and assessability accuracy are resolved, and the code/test preservation PASS carries forward. Two documentation blockers remain: one unresolved non-root-relative test-file citation, and the overbroad “append variants so older readers keep parsing” wire-format statement. The review reports gate states only; it is not a merge verdict.

Coverage: exact PR head, the three follow-up commit diffs, both architecture documents, the cited Autopilot reducer lines and surrounding call paths, evidence type declarations/serde behavior, formatter baseline/workflow/blame disposition, and current PR checks/reviews. No files were modified.

…st citation

Two follow-up defects from the charter re-review, one of them mine.

The additive-only cell claimed appending enum variants keeps older readers
parsing. That is false for the plain derived enums in evidence.rs
(IntuneTimestampKind, IntuneSensitivity, IntuneParseState, IntuneAccessState,
IntuneArtifactStatus): none carries a #[serde(other)] arm, so an unknown
variant is a hard decode error. Only intune_raw_preserving_string_enum! types
have an Unknown(String) path. The crate already states the correct rule on
INTUNE_EVIDENCE_SCHEMA_VERSION at evidence.rs:23-24, and the document
contradicted it. The cell now separates the wire-format question from the
Rust API question and matches the crate on both.

The remaining non-root-relative citation
(tests/intune_windows_microsoft_store.rs) is now prefixed. The verifier that
was supposed to catch it only validated paths already beginning with crates/
or docs/, so a bare tests/ reference was invisible to the check written to
find exactly that defect; the check is now prefix-agnostic.

Documentation only; no code or test changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@adamgell

Copy link
Copy Markdown
Owner Author

Both remaining findings fixed at 7d1150ab. Documentation only.

The wire-format overclaim was my error, and it's the important one. In fixing the original inaccurate guardrail I introduced a second inaccuracy: I wrote that appending enum variants keeps older readers parsing. That is false for the plain derived enums here. IntuneTimestampKind, IntuneSensitivity, IntuneParseState, IntuneAccessState, and IntuneArtifactStatus all derive Deserialize with no #[serde(other)] arm, so an unknown variant is a hard decode error, not a tolerated one. Only intune_raw_preserving_string_enum! types have the Unknown(String) path.

The crate already stated the correct rule on INTUNE_EVIDENCE_SCHEMA_VERSION at crates/cmtraceopen-parser/src/intune/evidence.rs:23-24 — optional field, or a variant on a raw-preserving enum. My text contradicted the source of truth it was documenting. The cell now separates the wire-format question from the Rust API question and matches the crate on both.

Citationtests/intune_windows_microsoft_store.rs is now prefixed. Worth recording why it survived a check written to catch exactly this: my verifier only validated paths that already began with crates/ or docs/, so a bare tests/ reference was invisible to it. The verifier is now prefix-agnostic and passes across both documents.

P2 (cargo fmt) — thanks for the independent confirmation, including the differing block count. Pre-existing and non-gating either way.

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr view 543 --repo adamgell/cmtraceopen --json headRefOid,headRefName -q '.'
git fetch origin pull/543/head 2>&1 | tail -5 || true
git show 7d1150ab --stat 2>&1 | head -30 || true
echo "---evidence.rs schema comment---"
git show 7d1150ab:crates/cmtraceopen-parser/src/intune/evidence.rs 2>/dev/null | sed -n '1,40p'
echo "---shared-vs-workload doc wire format section---"
git show 7d1150ab:docs/architecture/shared-vs-workload-invariants.md 2>/dev/null | grep -n -i "wire" -A5 -B5
echo "---tests/ citation check---"
git show 7d1150ab:docs/architecture/shared-vs-workload-invariants.md 2>/dev/null | grep -n "intune_windows_microsoft_store.rs"
git show 7d1150ab:docs/architecture/decisions/ADR-001-evidence-strength-confidence.md 2>/dev/null | grep -n "tests/"

Length of output: 7581


@adamgell Verified at 7d1150ab.

Wire-format claim. Line 25 of docs/architecture/shared-vs-workload-invariants.md now states the wire-format rule separately from the Rust API rule. It matches the comment at crates/cmtraceopen-parser/src/intune/evidence.rs:23-24: only an optional field, or a new variant on an intune_raw_preserving_string_enum! type, is additive. It also names the five plain derived enums with no #[serde(other)] arm and states that an unknown variant is a hard decode error for them. This is accurate.

Citation. Line 162 now reads crates/cmtraceopen-parser/tests/intune_windows_microsoft_store.rs. The path resolves and matches the file location.

Both findings are resolved. The diff is docs-only, as stated.

Note: this confirms document accuracy against the current source. It does not substitute for CI or a CodeRabbit approval on this head, both separate gates you already track in your own review.

You are interacting with an AI system.

@adamgell

Copy link
Copy Markdown
Owner Author

Hermes final adjudication — exact head 7d1150a

Adjudication of the two remaining blockers

1. Wire-format compatibility claim — RESOLVED

I read crates/cmtraceopen-parser/src/intune/evidence.rs directly at the exact remote head with git show origin/framework/pr4-thin-extraction:PATH.

  • INTUNE_EVIDENCE_SCHEMA_VERSION's own doc comment at evidence.rs:23-24 says that only an optional field, or a variant on an intune_raw_preserving_string_enum! enum, is additive without a schema bump. The revised cell matches that rule.
  • The macro's generated enum has an explicit Unknown(String) variant and its Deserialize implementation maps every unrecognized wire string to Unknown(raw). IntuneSourceKind is the only enum in this file using that unknown-value path.
  • IntuneTimestampKind, IntuneSensitivity, IntuneParseState, IntuneAccessState, and IntuneArtifactStatus are ordinary #[derive(Serialize, Deserialize)] enums. None has a #[serde(other)] arm. Adding a wire variant therefore makes an older reader reject that value during deserialization; it is not an additive wire change and requires a schema-version bump.
  • I also checked the remaining derived public enums, IntuneFindingSeverity and IntuneFindingConfidence; neither has an unknown-value path. No enum with a tolerated unknown value was missed by the revised characterization.
  • The separate Rust API statement is accurate: these public enums/structs are not #[non_exhaustive], and adding public enum variants or struct fields can break downstream exhaustive matches or struct literals. There is no general additive Rust API guarantee here.

The former overbroad wire-format blocker is closed.

2. Repository-root citations — RESOLVED

I independently re-swept both architecture documents at the exact remote head, using the complete repository tree from git ls-tree and checking every path-shaped citation without assuming a crates/ or docs/ prefix. All actual path citations resolve from the repository root, including:

crates/cmtraceopen-parser/tests/intune_windows_microsoft_store.rs

The only non-resolving tokens surfaced by the deliberately broad lexical scan were ordinary prose fragments (success/failure and file/manifest), not citations. No unprefixed or otherwise non-root-relative path-shaped citation remains.

The citation blocker is closed.

Preservation and scope

  • Exact head: PASS — origin/framework/pr4-thin-extraction resolves to 7d1150ab643b09d76ed192c1e0607a2920aa53a1.
  • Documentation-only follow-up: PASS — the diff from the prior review head c67fc1922caae537ca219499df5398dfd67a72c1 contains only docs/architecture/shared-vs-workload-invariants.md; the diff from the original reviewed code head likewise contains no .rs or test-file change in these follow-ups. The prior behavior-preservation PASS carries forward.
  • Cargo fmt P2: remains CONFIRMED pre-existing/non-PR from the prior review; no code or test change was introduced here.
  • Contract/adversarial scope: PASS for these two documentation blockers. The corrected compatibility statement and citation sweep introduce no reducer behavior change.

Gate states

  • CI: NOT CLEAR at this observation — the current checks show multiple jobs pending (including Rust, MSRV, TypeScript, E2E, ESP Diagnostics, and CodeRabbit); Ruby passed and CodeQL is skipped.
  • CodeRabbit: NOT APPROVED at this head — the current check is pending; no approved_at_head approval was observed.
  • Hermes charter review: POSTED by this report; the two previously blocking findings are resolved.
  • Native/lab validation: NOT RUN / not applicable to this documentation-only follow-up.

This is a gate-state report, not a merge verdict. Coverage was limited to the two requested blockers, the exact-head evidence declarations, both architecture documents, the follow-up diff, and current PR gate state; no files were modified and the branch was not checked out.

@adamgell
adamgell marked this pull request as ready for review August 10, 2026 17:36
Copilot AI lite review requested due to automatic review settings August 10, 2026 17:36
@adamgell
adamgell merged commit 2678f1f into main Aug 10, 2026
17 checks passed
@adamgell
adamgell deleted the framework/pr4-thin-extraction branch August 10, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR performs a thin “Framework v1” extraction in the Intune Windows reducer ecosystem, focusing on deduplicating a shared IntuneAccessStateIntuneArtifactStatus mapping, consolidating repeated test-harness helpers, and documenting which invariants are shared vs intentionally workload-specific.

Changes:

  • Centralizes the 7-arm bijective mapping between IntuneAccessState and IntuneArtifactStatus into crates/cmtraceopen-parser/src/intune/evidence.rs (both directions) and moves/expands the exhaustiveness test alongside it.
  • Consolidates repeated Intune fixture test helpers into crates/cmtraceopen-parser/tests/support/mod.rs (scenario roots, captureState mappings, JSON “wire” serialization, and sorted evidence-id extraction where order is not part of the contract).
  • Adds/updates architecture documentation to explicitly distinguish shared invariants from protected divergences and to clarify ADR-001’s “directional doctrine” as shared prose with workload-specific mechanisms.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/architecture/shared-vs-workload-invariants.md New catalogue of shared vs workload-specific invariants; documents protected divergences and extraction criteria.
docs/architecture/decisions/ADR-001-evidence-strength-confidence.md Adds an ADR addendum clarifying shared doctrine vs per-lane implementation mechanisms.
crates/cmtraceopen-parser/tests/support/mod.rs Adds shared test-support helpers (scenario root, captureState mappings, wire serialization, sorted evidence ids).
crates/cmtraceopen-parser/tests/intune_windows_win32.rs Switches Win32 tests to shared captureState/access-state helpers and shared scenario-root helper.
crates/cmtraceopen-parser/tests/intune_windows_microsoft_store.rs Switches Store tests to shared captureState→status helper; preserves local ordered evidence-id helper (documented).
crates/cmtraceopen-parser/tests/intune_windows_configuration.rs Switches Configuration tests to shared captureState→status helper, scenario-root helper, and shared wire.
crates/cmtraceopen-parser/tests/intune_windows_compliance.rs Switches Compliance tests to shared captureState→status helper, scenario-root helper, and shared sorted evidence ids helper.
crates/cmtraceopen-parser/tests/intune_windows_autopilot.rs Switches Autopilot tests to shared scenario-root and shared wire; keeps lane-local captureState enum conversion (documented).
crates/cmtraceopen-parser/src/intune/evidence.rs Introduces the shared mapping functions and a bijection test colocated with the enums.
crates/cmtraceopen-parser/src/intune/enrollment/windows/autopilot/sources.rs Refactors Autopilot declared-status derivation to use the shared access-state→status mapping.
crates/cmtraceopen-parser/src/intune/apps/windows/win32/sources.rs Replaces local access-state→coverage-status mapping with shared helper; relocates the related test.
crates/cmtraceopen-parser/src/intune/apps/windows/microsoft_store/reducer.rs Replaces local status→access-state mapping with shared helper.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


| Concern | Owner | Notes |
|---|---|---|
| Evidence envelope types (`IntuneObservationContext`, `IntuneEvidenceRef`, `IntuneProvenance`, `IntuneArtifactCoverage`, `IntuneFinding`, ...) | `crates/cmtraceopen-parser/src/intune/evidence.rs` | Two separate compatibility questions, and only one of them has an "additive" answer. **Wire format:** exactly as `INTUNE_EVIDENCE_SCHEMA_VERSION` states at `crates/cmtraceopen-parser/src/intune/evidence.rs:23-24` — only an optional field, or a variant on an `intune_raw_preserving_string_enum!` type, is additive. The plain `#[derive(Deserialize)]` enums (`IntuneTimestampKind`, `IntuneSensitivity`, `IntuneParseState`, `IntuneAccessState`, `IntuneArtifactStatus`) have no `#[serde(other)]` arm, so an unknown variant is a hard decode error: adding one breaks older readers and bumps the schema version. **Rust API:** no additive guarantee at all. None of these types are `#[non_exhaustive]` and `cmtraceopen-parser` is published, so a new variant or public field breaks downstream `match` arms and struct literals and needs a semver-major release, or `#[non_exhaustive]` first. |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request intune Microsoft Intune related parser Log parser related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants