Skip to content
Merged
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
14 changes: 14 additions & 0 deletions .squad/agents/fenster/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,17 @@ Applied `[ExcludeFromCodeCoverage]` to genuinely untestable code following exist

These properties are pass-through wrappers marked `[Obsolete]` that exist purely for backward compatibility. They contain no testable logic and cannot be meaningfully covered in isolation from the properties they wrap. Exclusion improves the coverage denominator while preserving accurate metrics.

### Issue #944 — Unicode XML documentation sanitization — 2026-03-06

- `src\Refitter.Core\XmlDocumentationGenerator.cs` is the shared production sink for OpenAPI response descriptions: normal `<returns>` docs use `method.ResultDescription`, while status-code tables render `response.ExceptionDescription` through `BuildResponseDescription()`.
- Response descriptions can reach the generator in JSON-escaped form (`\uXXXX`, `\"`, `\n`) even when the original OpenAPI document contains readable Unicode, so generator code should decode JSON-style escapes before emitting XML comments.
- Only sanitize user-sourced response description text; keep hardcoded XML doc fragments like `<see cref="Task"/>` and `<list>` markup untouched, then XML-escape reserved characters (`&`, `<`, `>`) at the point where response text is inserted.
- Focused Refitter tests are fastest through `src\Refitter.Tests\bin\Release\net10.0\Refitter.Tests.exe` with `--treenode-filter`, since `dotnet test --filter ...` is not supported by this TUnit/Microsoft.Testing.Platform setup.

### Issue #944 Implementation — 2026-03-06

Successfully implemented fix for non-ASCII characters in XML status-code comments:
- Added `DecodeJsonEscapedText()` method to decode `\uXXXX` escapes before XML-escaping in response descriptions
- Tests confirmed: Cyrillic Unicode renders correctly, escape sequences absent, compilation succeeds
- All 1415 tests pass with no regressions

373 changes: 15 additions & 358 deletions .squad/agents/hockney/history.md

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions .squad/agents/keaton/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,22 @@ Performed comprehensive audit of Refitter documentation vs actual codebase featu
5. POLICY: Establish "all new CLI options must have README examples" and "all new settings must have .refitter format docs"

**Full Report:** Written to `.squad/temp-docs-audit.md` (15KB detailed analysis). Report includes verification of all mappings, example snippets for missing docs, and prioritized recommendations. No breaking changes needed — all gaps are documentation-only.

### Issue #944 Review — Non-ASCII in XML Status-Code Comments (2026-03-06)

**Reviewed and APPROVED** the patch for issue #944. Root cause: NSwag's `CSharpResponseModel.ExceptionDescription` calls `ConversionUtilities.ConvertToStringLiteral()` which encodes non-ASCII characters as `\uXXXX` C# string literal escapes. The fix adds a `DecodeJsonEscapedText()` method in `XmlDocumentationGenerator` that decodes these before XML-escaping. Key validation points:

1. **Scope is correctly narrow:** Only `ExceptionDescription` uses `ConvertToStringLiteral`; other NSwag model fields (Summary, Description) surface raw strings. No other call sites need the fix.
2. **Ordering matters:** `EscapeSymbols(DecodeJsonEscapedText(...))` — decode first, then XML-escape — prevents decoded `<`, `>`, `&` from breaking XML.
3. **Bounds checking correct:** `index + 4 < input.Length` guard on `\uXXXX` parsing matches `Substring(index + 1, 4)` requirements.
4. **Surrogate pairs work:** Each `\uXXXX` decoded to `(char)` is valid C# UTF-16, so surrogate pairs naturally compose.
5. **Tests prove the fix:** Unit test against generator directly + integration test from YAML spec through full pipeline + compilation check. All 1415 tests pass.

**Key learning:** When NSwag model properties use `ConvertToStringLiteral` (designed for C# code generation), the output contains escape sequences unsuitable for XML documentation. Any future properties that exhibit this pattern will need similar decode-before-escape treatment.

### Issue #944 Test Coverage — 2026-03-06

Added comprehensive regression testing for non-ASCII XML documentation fix:
- Unit test in `XmlDocumentationGeneratorTests.cs` validates readable Unicode and absence of `\uXXXX` escape sequences
- Integration test in `GenerateStatusCodeCommentsTests.cs` confirms full pipeline compilation success with Unicode content
- Tests follow existing pattern: direct assertion + compilation verification
22 changes: 22 additions & 0 deletions .squad/agents/mcmanus/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,25 @@ Key workflows: `build.yml` (main), `smoke-tests.yml` (quick), `release.yml` + `r
**Grade:** B+ (87%) — Production-ready, but token exposure and non-functional squad-ci.yml are immediate concerns.

Full assessment written to `.squad/decisions/inbox/mcmanus-cicd-review.md`

## Validation Gate: Issue #944 (2026-03-06)

**Objective:** Validate patch for non-ASCII XML comment handling via the 3-step PR gate.

**Results:**

1. **Build (`dotnet build -c Release src/Refitter.slnx`):** ✅ PASS
- All projects compiled successfully
- Exit code: 0

2. **Tests (`dotnet test --solution src/Refitter.slnx -c Release`):** ✅ PASS
- **1,451 tests total:** 1,415 (Refitter.Tests) + 18 (SourceGenerator net8.0) + 18 (SourceGenerator net10.0)
- **Failed:** 0, **Skipped:** 0
- Duration: 38s 178ms
- Exit code: 0

3. **Format Verification (`dotnet format --verify-no-changes src/Refitter.slnx`):** ✅ PASS
- No violations detected
- Exit code: 0

**Conclusion:** Issue #944 patch is **READY FOR MERGE**. All validation gates passed.
52 changes: 52 additions & 0 deletions .squad/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,4 +302,56 @@ Recommendations: Merge both branches; fix 3 SourceGenerator interface casing tes

---

### 7. Issue #944 — Non-ASCII XML Status-Code Comments (2026-03-06)

**Status:** ✅ APPROVED FOR MERGE
**Date:** 2026-03-06

#### Summary

Fixed XML documentation generation to properly handle non-ASCII characters in OpenAPI response descriptions. Root cause: NSwag's `CSharpResponseModel.ExceptionDescription` encodes non-ASCII characters as JSON-style escape sequences (`\uXXXX`), which were being written raw into XML comments, rendering as literal backslash sequences instead of Unicode characters.

#### Solution

**Production Fix (Fenster):**
- File: `src/Refitter.Core/XmlDocumentationGenerator.cs`
- Added `DecodeJsonEscapedText()` method that safely decodes `\uXXXX`, `\"`, `\\`, `\n`, `\r`, `\t` sequences
- Applied decoding in `BuildResponseDescription()` before XML-escaping, preventing both escape sequence leakage and XML injection
- Preserves hardcoded XML markup (`<see cref="..."/>`, `<list>` elements)

**Test Coverage (Hockney):**
- Unit test: `XmlDocumentationGeneratorTests.cs` — validates readable Unicode output and absence of raw escape sequences
- Integration test: `GenerateStatusCodeCommentsTests.cs` — end-to-end spec→generation→compilation verification

**Review (Keaton):**
- Scope correctly narrow: only `ExceptionDescription` affected
- Ordering correct: decode first, then XML-escape (prevents injection)
- Bounds checking valid for `\uXXXX` parsing
- Surrogate pairs handled naturally via C# UTF-16
- All 1415 tests pass; no regressions

#### Files Modified

- `src/Refitter.Core/XmlDocumentationGenerator.cs` — decode logic
- `src/Refitter.Tests/XmlDocumentationGeneratorTests.cs` — unit tests
- `src/Refitter.Tests/Examples/GenerateStatusCodeCommentsTests.cs` — integration tests

#### Gates

✅ Build passing
✅ All tests passing (1451/1451)
✅ Code formatting verified
Comment thread
coderabbitai[bot] marked this conversation as resolved.

---

### 8. User Directive: Commit Message Style (2026-03-06)

**Status:** ℹ️ Process Update
**Date:** 2026-03-06
**By:** Christian Helle (via Copilot)

Commit changes in small logical groups with one-liner commit messages without a co-author trailer.

---

*Maintained by Scribe. Agents write to `.squad/decisions/inbox/` and Scribe merges, deduplicates, and consolidates here.*
11 changes: 5 additions & 6 deletions .squad/identity/now.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
---
updated_at: 2026-03-02T15:49:46Z
focus_area: Post-review backlog — bugs, tests, CI fixes
active_issues: []
updated_at: 2026-03-06T16:09:05.259Z
focus_area: Issue #944 implementation and validation
active_issues:
- 944
---

# What We're Focused On

Full codebase review completed (2026-03-02). Keaton, Fenster, Hockney, McManus all ran. Findings are in `.squad/decisions.md` and `.squad/identity/backlog.md`.

Next session: pick from the backlog in priority order. Start with the security fix (Codecov token), then the bug trio (GetInterfaceName, ContractsOutputFolder, ParameterExtractor mutation), then test gaps.
Implementing and validating the fix for issue #944. The patch is in `src\Refitter.Core\XmlDocumentationGenerator.cs` with regression coverage in `src\Refitter.Tests\XmlDocumentationGeneratorTests.cs` and `src\Refitter.Tests\Examples\GenerateStatusCodeCommentsTests.cs`; full PR-gate validation is now running.
20 changes: 20 additions & 0 deletions .squad/orchestration-log/2026-03-06T16-29-27Z-fenster.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Fenster — Issue #944 Orchestration Log — 2026-03-06T16-29-27Z

## Task: Implement production fix for non-ASCII XML documentation

**Outcome:** ✅ COMPLETE

Fixed `src/Refitter.Core/XmlDocumentationGenerator.cs` to decode JSON-style escaped Unicode sequences (`\uXXXX`) from NSwag response descriptions before XML-escaping. The `DecodeJsonEscapedText()` method safely handles:
- `\uXXXX` four-hex-digit Unicode escape sequences
- `\"` escaped quotes
- `\\` escaped backslashes
- `\n`, `\r`, `\t` whitespace escapes
- Preserves hardcoded XML markup (`<see cref="..."/>`, `<list>`, etc.)
- XML-escapes `&`, `<`, `>` in user text after decoding

**Files Modified:**
- `src/Refitter.Core/XmlDocumentationGenerator.cs` — added `DecodeJsonEscapedText()` helper and applied to `BuildResponseDescription()` method

**Build Status:** Passed
**Test Status:** Targeted tests passed
**Gates:** Build ✅ | Tests ✅ | Format ✅
24 changes: 24 additions & 0 deletions .squad/orchestration-log/2026-03-06T16-29-27Z-hockney.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Hockney — Issue #944 Orchestration Log — 2026-03-06T16-29-27Z

## Task: Add regression coverage for non-ASCII XML documentation fix

**Outcome:** ✅ COMPLETE

Added comprehensive regression test coverage at two levels:

1. **Unit Tests** — `src/Refitter.Tests/XmlDocumentationGeneratorTests.cs`
- Direct assertion on `XmlDocumentationGenerator.BuildResponseDescription()`
- Validates that readable Unicode (Cyrillic example: `Возврат`) is preserved in XML output
- Verifies that `\uXXXX` escape sequences are decoded, not emitted raw

2. **Integration Tests** — `src/Refitter.Tests/Examples/GenerateStatusCodeCommentsTests.cs`
- End-to-end test: inline OpenAPI spec → full generator pipeline → C# code generation
- Verifies generated code compiles successfully via `BuildHelper.BuildCSharp()`
- Protects against regressions in the full compilation workflow

**Files Modified:**
- `src/Refitter.Tests/XmlDocumentationGeneratorTests.cs` — new unit tests
- `src/Refitter.Tests/Examples/GenerateStatusCodeCommentsTests.cs` — new integration tests

**Test Results:** All targeted tests passed
**Scope:** Narrow, focused coverage; no production code touched in test project
29 changes: 29 additions & 0 deletions .squad/orchestration-log/2026-03-06T16-29-27Z-keaton.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Keaton — Issue #944 Orchestration Log — 2026-03-06T16-29-27Z

## Task: Review and validate Issue #944 patch

**Outcome:** ✅ APPROVED

Conducted thorough review of the non-ASCII XML documentation fix. Validated:

**Correctness:**
- Root cause correctly identified: NSwag's `ConversionUtilities.ConvertToStringLiteral()` encodes non-ASCII as `\uXXXX` escape sequences
- Fix location is precise: only `ExceptionDescription` uses this encoding; other NSwag fields (Summary, Description) are raw strings
- Decode-then-XML-escape ordering prevents injection attacks on decoded `<`, `>`, `&` characters
- Bounds checking on `\uXXXX` parsing is correct: `index + 4 < input.Length`
- Surrogate pairs handled correctly via C# UTF-16 char semantics
- Fast-path optimization for ASCII-only strings (early return if no backslashes)

**Testing:**
- Unit test: readable Cyrillic assertion validates decoding
- Integration test: compilation verification of generated code
- All 1415 tests pass; no regressions

**Gates:** Build ✅ | Tests ✅ (1415/1415) | Format ✅

**Files Affected:**
- `src/Refitter.Core/XmlDocumentationGenerator.cs`
- `src/Refitter.Tests/XmlDocumentationGeneratorTests.cs`
- `src/Refitter.Tests/Examples/GenerateStatusCodeCommentsTests.cs`

**Recommendation:** READY FOR MERGE
37 changes: 37 additions & 0 deletions .squad/skills/tunit-test-filtering/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: "tunit-test-filtering"
description: "Run focused Refitter tests with TUnit treenode filters"
domain: "testing"
confidence: "high"
source: "manual"
---

## Context
Refitter test projects use TUnit on Microsoft.Testing.Platform. In this repo, `dotnet test --filter ...` is not supported by the compiled test application, so the fastest reliable way to run a tiny subset of tests is through the generated test executable and a tree-node filter.

## Pattern

### Use the compiled test executable
- Test app path: `src\Refitter.Tests\bin\Release\net10.0\Refitter.Tests.exe`
- Note: The examples use Windows-style backslashes (`\`). On Linux/macOS or in bash/zsh, use forward slashes (`/`), e.g., `src/Refitter.Tests/bin/Release/net10.0/Refitter.Tests.exe`.
- Source-generator test discovery means you should build the test project first if you added or renamed tests.

### Tree filter syntax
- Format: `/*/<Namespace>/<Class>/<Test>`
- Example:

```powershell
& 'src\Refitter.Tests\bin\Release\net10.0\Refitter.Tests.exe' `
--treenode-filter '/*/Refitter.Tests.Examples/GenerateStatusCodeCommentsTests/Generated_Code_With_Unicode_Status_Code_Comments_Can_Build' `
--disable-logo `
--no-progress
```

### Verified repo-specific examples
- `/*/Refitter.Tests/XmlDocumentationGeneratorTests/Can_Generate_Method_Throws_With_Readable_Unicode_Status_Code_Comments`
- `/*/Refitter.Tests.Examples/GenerateStatusCodeCommentsTests/Generated_Code_Preserves_Readable_Unicode_In_Status_Code_Comments`
- `/*/Refitter.Tests.Examples/GenerateStatusCodeCommentsTests/Generated_Code_With_Unicode_Status_Code_Comments_Can_Build`

## Anti-Patterns
- Do **not** rely on `dotnet test --filter ...` here; the TUnit/Microsoft.Testing.Platform test app rejects that option.
- Do **not** assume OR expressions are necessary for a tiny run; separate single-test invocations are often simpler and more reliable.
31 changes: 31 additions & 0 deletions .squad/skills/xml-doc-description-sanitization/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: "xml-doc-description-sanitization"
description: "Preserve readable Unicode when copying OpenAPI response descriptions into XML doc comments"
domain: "code-generation"
confidence: "high"
source: "manual"
---

## Context
`src\Refitter.Core\XmlDocumentationGenerator.cs` writes OpenAPI response descriptions into generated XML documentation comments. Those descriptions may arrive from NSwag in JSON-escaped form (`\uXXXX`, `\"`, `\n`) even though the source OpenAPI file already contains readable Unicode.

## Pattern

### Sanitize user-sourced response descriptions only
- Decode JSON-style escape sequences before writing the text into XML docs.
- After decoding, escape XML-reserved characters (`&`, `<`, `>`) so the generated comments remain valid XML.
- Apply this only to OpenAPI-sourced response description text such as `method.ResultDescription` and `response.ExceptionDescription`.

### Preserve intentional XML doc markup
- Do **not** run the same sanitization over hardcoded fallback strings that intentionally contain `<see cref="..."/>`, `<list>`, or other XML doc tags.
- Sanitize at the insertion point where raw API text enters the XML comment output.

## Example

```csharp
var description = this.EscapeSymbols(this.DecodeJsonEscapedText(responseDescription));
```

## Anti-Patterns
- Appending `method.ResultDescription` or `response.ExceptionDescription` directly into XML comments.
- XML-escaping entire doc fragments that intentionally contain XML doc markup.
Loading
Loading