Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .hermes/conveyor/work-3d8d9b32/adr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# ADR-0013: Close Issue #289 — Severity::Info Already Maps to "info"

## Status
Accepted

## Context

Issue #289 reported that `checkstyle.rs` had `Severity::Info` and `Severity::Warn` both mapping to the string `"warning"`, causing a `clippy::match_same_arms` warning and making the Info arm dead code.

However, prior investigation found that:
- The bug was already fixed in PR #460 (commit b31d836)
- The current code at `checkstyle.rs:71-75` correctly maps all three severities
- All 28 checkstyle tests pass
- Clippy is clean with no warnings

The issue remains OPEN on GitHub despite the fix being merged.

## Decision

**No code changes are needed.** Issue #289 should be closed as "Already resolved" referencing PR #460.

The current implementation is correct:
```rust
let severity_str = match f.severity {
Severity::Error => "error",
Severity::Warn => "warning",
Severity::Info => "info", // ← Correct
};
```

## Consequences

### Tradeoffs

| Alternative | Why Rejected |
|-------------|--------------|
| Create new PR with identical fix | Duplicates PR #460, wastes review time, risks new bugs |
| Leave issue open | Misleads contributors, suggests bug still exists |
| Modify working code | Unnecessary churn, no benefit |

### Benefits
- No risk of introducing regressions
- Preserves existing test coverage (`info_maps_to_info` test)
- Issue closure provides clear signal to contributors

### Risks
- Issue #289 must be closed on GitHub to prevent confusion
- If future refactoring moves the severity mapping, regression tests must catch it

## Alternatives Considered

1. **Create duplicate PR** — Rejected: PR #460 already contains the correct fix
2. **Do nothing** — Rejected: Open issue misleads contributors
3. **Modify working code** — Rejected: No benefit, introduces risk

## References

- Issue #289: `checkstyle.rs:50-51: Severity::Info and Severity::Warn produce identical "warning"`
- PR #460: `fix(checkstyle): Severity::Info maps to 'info' not 'warning'`
- Commit `b31d836`: Merge commit that applied the fix
35 changes: 35 additions & 0 deletions .hermes/conveyor/work-3d8d9b32/specs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Spec — work-3d8d9b32: Close Issue #289 (Already Resolved)

## Feature/Behavior Description

This work item concerns closing GitHub issue #289 which reports a bug in `checkstyle.rs` where `Severity::Info` and `Severity::Warn` produce identical `"warning"` strings. Investigation reveals the bug was already fixed in PR #460. No code changes are needed.

## Acceptance Criteria

1. **Issue Closure** — Issue #289 on GitHub is closed with resolution "Already resolved" and reference to PR #460 as the fix.

2. **No Code Changes** — No modifications are made to `checkstyle.rs` or any other source files, since the bug was already fixed in PR #460.

3. **Existing Tests Pass** — All 28 checkstyle-related tests continue to pass, ensuring no regression.

## Non-Goals

- No new code, tests, or functionality is being added
- No changes to severity mapping logic (already correct)
- No modifications to output format (already correct per checkstyle.org schema)

## Dependencies

- PR #460 must remain merged (contains the fix)
- Existing `info_maps_to_info` test in `checkstyle.rs` must remain (prevents regression)

## Current State Verification

| Aspect | Status |
|--------|--------|
| `Severity::Error` → `"error"` | ✓ Correct |
| `Severity::Warn` → `"warning"` | ✓ Correct |
| `Severity::Info` → `"info"` | ✓ Correct |
| Clippy `match_same_arms` | ✓ No warning |
| Checkstyle tests | ✓ All 28 pass |
| Module documentation | ✓ Matches implementation |
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Windows target triple detection for MSYS/MINGW environments
- Concurrency control on SARIF upload to prevent race conditions across workflow runs
- Improved error handling with user-visible warning messages for fallback installation paths
- **`parse_unified_diff` now requires explicit Result handling** — Added `#[must_use]` to `parse_unified_diff` so the compiler warns when callers ignore the `Result`. This prevents silent parse failures where malformed diffs are silently ignored. Callers must now explicitly handle the `Result` or use `let _ = ...` to indicate intentional ignore. Closes #329.

### Changed

Expand Down
Empty file added StringSyntax::CStyle
Empty file.
110 changes: 110 additions & 0 deletions adr-012-redundant-match-arm-452.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# ADR-012: Remove Redundant `Language::Json` Match Arm in `string_syntax()` (Issue #452)

**Status:** Proposed

**Date:** 2026-04-27

**Work Item:** work-1f927a4d

**Supersedes:** ADR-011 (work-5d83e2c9, issue #136) — same decision applied to issue #452

---

## Context

GitHub issue #452 reports a redundant match arm in `preprocess.rs` where `Language::Yaml | Language::Toml | Language::Json` is explicitly matched in the `string_syntax()` function alongside a wildcard (`_`) pattern that produces the same result (`StringSyntax::CStyle`).

**However**, the issue's core premise is factually incorrect. The issue claims that "the wildcard `_` already covers Yaml, Toml, and Json." This is wrong — in Rust, the wildcard only catches variants NOT explicitly matched. Currently:

- Line 107 explicitly handles `Yaml | Toml | Json`
- Line 109 wildcard catches `C, Cpp, CSharp, Java, Kotlin, Unknown` — NOT Yaml/Toml/Json

The arm is **redundant** (removable without behavior change), not **unreachable** (already caught by wildcard).

This work item (issue #452) requests the same fix as ADR-011 (issue #136): remove only `Json` from the arm, keeping `Yaml | Language::Toml` explicit.

---

## Decision

Follow ADR-011's decision: **remove only `Language::Json`** from the match arm, keeping `Yaml | Language::Toml` explicit.

**Changes to `string_syntax()` (lines 106-109):**

Before:
```rust
// YAML/TOML/JSON strings are C-style-like in this best-effort model
Language::Yaml | Language::Toml | Language::Json => StringSyntax::CStyle,
// All other languages (C, C++, Java, etc.) use C-style strings
_ => StringSyntax::CStyle,
```

After:
```rust
// YAML/TOML strings are C-style-like in this best-effort model
// (JSON is handled by the wildcard below since JSON uses C-style strings)
Language::Yaml | Language::Toml => StringSyntax::CStyle,
// All other languages (including JSON, C, C++, Java, etc.) use C-style strings
_ => StringSyntax::CStyle,
```

---

## Alternatives Considered

### Option A: Remove entire arm (Yaml | Toml | Json) — as literal issue #452 request
- ❌ Issue's premise is factually incorrect (wildcard doesn't cover explicitly-matched arms)
- ❌ Conflicts with ADR-011 decision
- ❌ Would break existing tests (`yaml_and_toml_have_explicit_arms_not_wildcard`)
- ❌ Removes valuable type-level documentation that YAML/TOML are intentional special cases
- ❌ Less clear about YAML/TOML configuration-language special case

### Option B: Remove only Json, keep Yaml | Toml explicit (ADR-011 approach) ✅
- ✅ Aligns with existing ADR-011
- ✅ Matches pattern in `comment_syntax()` which explicitly handles YAML/TOML
- ✅ Preserves explicit handling for configuration languages (YAML/TOML may need distinct handling in future)
- ✅ Existing tests pass without modification
- ✅ Maintains code-as-documentation

**Selected:** Option B

---

## Consequences

**Positive:**
- Eliminates redundant match arm warning from clippy (if any)
- Improves code clarity by documenting JSON is handled by wildcard
- Consistency with `comment_syntax()` function pattern
- No functional change — behavior is identical
- YAML/TOML remain explicit for future maintainability

**Negative:**
- Does not fully "resolve" issue #452's literal request (which was based on incorrect premise)

**Neutral:**
- The change is purely cosmetic — no runtime behavior changes
- This ADR is essentially a re-affirmation of ADR-011 for issue #452

---

## Risk Assessment

- **Severity:** Very Low (cosmetic/code cleanup)
- **Functional change:** None — both paths produce `StringSyntax::CStyle`
- **Regression risk:** Negligible
- **Test impact:** Existing tests in `red_tests_work_5d83e2c9.rs` remain valid

---

## Files Affected

- `crates/diffguard-domain/src/preprocess.rs` — modify `string_syntax()` match arm (lines 106-109)

---

## References

- [ADR-011: Remove Redundant `Language::Json` Match Arm](adr-011-redundant-match-arm.md) — prior decision for issue #136
- [Issue #452](https://github.com/EffortlessMetrics/diffguard/issues/452) — this work item's source issue
- [Issue #136](https://github.com/EffortlessMetrics/diffguard/issues/136) — similar issue addressed by ADR-011
85 changes: 85 additions & 0 deletions adr-work-38635ea1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# ADR: Inline Named Format Arguments in `bail!` Macro Calls

## Status
**Accepted**

## Context

The `xtask/src/conform_real.rs` file contains 5 `bail!` macro invocations that use old-style positional format arguments (`{}` with a trailing separate argument) instead of Rust 2021+ inline named format syntax.

The affected calls are:

| Line | Current Pattern | Issue |
|------|----------------|-------|
| 368-371 | `bail!("...{}", String::from_utf8_lossy(&output.stderr))` | Positional `{}` |
| 620-623 | `bail!("sensor report failed schema validation:\n{}", error_messages.join("\n"))` | Positional `{}` |
| 769-772 | `bail!("cockpit mode did not exit 0: {}", String::from_utf8_lossy(&output.stderr))` | Positional `{}` |
| 1105-1108 | `bail!("cockpit mode did not exit 0: {}", String::from_utf8_lossy(&output.stderr))` | Positional `{}` |
| 1167 | `bail!("expected 7 artifacts, got {}: {:?}", artifacts.len(), paths)` | Positional `{}` and `{:?}` |

The project uses Rust 2024 edition (MSRV Rust 1.92), which fully supports inline named format arguments. The `anyhow::bail!` macro supports named inline format arguments via `bail!("message {var}", var = expr)` syntax, which forwards directly to `format_args!()`.

## Decision

Convert all 5 `bail!` calls to use inline named format arguments:

```rust
// Before
bail!("cockpit mode did not exit 0: {}", String::from_utf8_lossy(&output.stderr));

// After
bail!("cockpit mode did not exit 0: {stderr}", stderr = String::from_utf8_lossy(&output.stderr));
```

For the single call with two placeholders (line 1167):
```rust
// Before
bail!("expected 7 artifacts, got {}: {:?}", artifacts.len(), paths);

// After
bail!("expected 7 artifacts, got {n}: {paths:?}", n = artifacts.len(), paths = paths);
```

## Consequences

### Benefits
1. **Improved readability**: Named placeholders make it immediately clear which variable maps to which placeholder without counting positional arguments
2. **Resolves style-check CI failures**: If the project has a lint enforcing inline format arguments, this resolves those failures
3. **Modern Rust idiom**: Consistent with Rust 2021+ conventions and the project's stated trajectory toward clean, modern code

### Tradeoffs
1. **Minor reformatting**: Four of the five calls are multi-line. Converting to named-argument syntax will change line breaks; `cargo fmt` will handle this automatically
2. **No semantic change**: The transformation is purely syntactic — expression evaluation order and borrowing semantics are unchanged

## Alternatives Considered

### 1. No change (leave positional format args)
Rejected because:
- The issue title implies a style lint flags these calls
- Modern Rust idiom strongly favors named inline format arguments
- The codebase uses Rust 2024 edition, making positional args an anomaly

### 2. Fix entire codebase in a single PR
Rejected because:
- Issue scope is explicitly limited to `xtask/conform_real.rs`
- A follow-up issue/PR should address other files
- Keeping scope narrow reduces review burden and blast radius

## Scope Boundaries

**In scope:**
- `xtask/src/conform_real.rs` — the 5 `bail!` calls listed above

**Out of scope:**
- `format!()` calls inside `.context()` invocations (e.g., `.context(format!("get findings[{i}].severity"))?;`) — these are a separate code smell and should be addressed in a follow-up issue
- Any other files in the codebase
- Any `bail!` calls that already use inline format syntax

## Verification

After the fix:
```bash
cargo check -p xtask && cargo fmt -- --check
```

Both commands must pass for the PR to be mergeable.
1 change: 1 addition & 0 deletions crates/diffguard-analytics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ diffguard-types = { version = "0.2", path = "../diffguard-types" }

[dev-dependencies]
proptest.workspace = true
insta.workspace = true
Loading
Loading