Infra, Ops & WorkflowAttention7373/100
Hypothesis Driven Debugging (.NET)
Investigate compiler failures, test errors, or unexpected behavior through systematic minimal reproduction, 3-hypothesis testing, and verification. Always re-run builds and tests after changes.
ou envoie-le directement à ton agent.
Installer dans ton projet
$ curl -fsSL https://arboristhree.xyz/cli/install-skill.mjs -o /tmp/arboris-install-skill.mjs && node /tmp/arboris-install-skill.mjs hypothesis-driven-debugging__dotnet-dotnet__src-fsharp-github-skills-5643bc67b46a.NET
dotnet/dotnet
Contenu à copier
---
name: hypothesis-driven-debugging
description: Investigate compiler failures, test errors, or unexpected behavior through systematic minimal reproduction, 3-hypothesis testing, and verification. Always re-run builds and tests after changes.
metadata:
origin: .NET
---
# Hypothesis-Driven Debugging
A systematic, rigorous approach to debugging failures in the F# compiler codebase.
## When to Use This Skill
Use this skill when:
- Investigating test failures (unit tests, integration tests, end-to-end tests)
- Debugging build errors or compilation failures
- Analyzing unexpected runtime behavior
- Troubleshooting performance regressions
- Examining warning/error message issues
> **Related:** for a build / compile / restore failure, run the `binlog-analysis` skill first — it fetches the build's MSBuild binary log and analyzes it live via the `binlog-mcp` MCP (structured errors + root-cause diagnosis), a fast way to scope the minimal reproduction below.
## Core Principles
1. **Always start with a minimal reproduction**
2. **Form multiple competing hypotheses**
3. **Design verification for each hypothesis**
4. **Document findings rigorously**
5. **Re-run builds and tests after every change**
## Process
### Step 1: Create Minimal Reproduction
Before forming hypotheses, create the smallest possible reproduction:
1. **Extract the failure**:
```bash
# For test failures - run just the failing test
dotnet test -- --filter-method "*YourTest*"
# For build failures - try to isolate the problematic file
# Create a minimal .fs file that reproduces the issue
```
2. **Reduce to essentials**:
- Remove unrelated code
- Simplify to the core issue
- Verify the minimal case still fails
3. **Document the repro**:
```markdown
## Minimal Reproduction
File: test-case.fs
Command: dotnet test -- --filter-method "*TestName*"
Expected: <expected behavior>
Actual: <actual behavior>
```
### Step 2: Form 3 Hypotheses
Always form **at least 3 competing hypotheses** about the root cause:
```markdown
## Hypothesis 1: [Brief description]
**Theory**: The failure occurs because...
**How to verify**: Run/change X and observe Y
**Verification result**: [To be filled]
**Implications**: If true, this means...
## Hypothesis 2: [Brief description]
**Theory**: The failure occurs because...
**How to verify**: Add instrumentation/logging at point Z
**Verification result**: [To be filled]
**Implications**: If true, this means...
## Hypothesis 3: [Brief description]
**Theory**: The failure occurs because...
**How to verify**: Check assumption A by running test B
**Verification result**: [To be filled]
**Implications**: If true, this means...
```
### Step 3: Verification Methods
For each hypothesis, use one or more verification methods:
#### Code Instrumentation
```fsharp
// Add temporary debugging output
printfn "DEBUG: Value at checkpoint: %A" someValue
printfn "DEBUG: Entering function X with args: %A %A" arg1 arg2
```
#### Minimal Test Cases
```fsharp
// Create focused test to verify specific behavior
[<Test>]
let ``Hypothesis 1 verification test`` () =
let result = functionUnderTest input
result |> should equal expectedValue
```
#### Build with Different Flags
```bash
# Try different configurations
./build.sh -c Debug
./build.sh -c Release
# Compare outputs
diff debug-output.log release-output.log
```
#### Targeted Logging
```bash
# Enable verbose logging for specific component
export FSHARP_COMPILER_VERBOSE=1
dotnet build
```
### Step 4: Document Findings
Maintain a `HYPOTHESIS.md` file in the working directory:
```markdown
# Hypothesis Investigation
## Issue Summary
Brief description of the failure/bug being investigated.
## Minimal Reproduction
[Code/commands to reproduce]
## Hypotheses
### Hypothesis 1: Token position tracking issue
**Theory**: The warning check compares line numbers but lastNonCommentTokenLine is not being updated correctly.
**How to verify**: Add printfn debugging in LexFilter.fs to log every token and its line number.
**Verification result**: ✅ CONFIRMED - Logging showed LBRACE tokens were updating the tracking when they shouldn't.
**Implications**: Need to exclude LBRACE and potentially other structural tokens from tracking.
### Hypothesis 2: Lexer pattern matching order
**Theory**: The /// pattern might be matched after other patterns, losing context.
**How to verify**: Check lex.fsl pattern order and add logging in the /// rule.
**Verification result**: ❌ DENIED - Pattern order is correct; /// is matched specifically.
**Implications**: Issue is not in the lexer pattern matching.
### Hypothesis 3: Test expectations wrong
**Theory**: The test expectations might not match actual compiler behavior.
**How to verify**: Manually compile test code and check actual warning positions.
**Verification result**: ⚠️ PARTIAL - Some tests had wrong expectations, but underlying issue still exists.
**Implications**: Fixed test expectations, but still need to address token tracking.
## Resolution
[Final solution and verification]
## Lessons Learned
- What worked well
- What to do differently next time
- Patterns to remember
```
### Step 5: Critical - Always Re-run Tests
**ABSOLUTELY REQUIRED**: After implementing any fix:
1. **Build from scratch**:
```bash
./build.sh -c Release
# Record: Time, exit code, number of errors
```
2. **Run affected tests**:
```bash
# For targeted testing
dotnet test -- --filter-class "*AffectedTestSuite*"
# Record: Passed, Failed, Skipped, Time
```
3. **Verify the fix**:
- Run the minimal reproduction - confirm it passes
- Run related tests - confirm no regressions
- Build the full project - confirm no new errors
4. **Document results**:
```markdown
## Verification Results
Build:
- Command: ./build.sh -c Release
- Time: 4m 23s
- Errors: 0
Tests:
- Command: dotnet test -- --filter-class "*XmlDocTests*"
- Total: 61
- Passed: 56
- Failed: 0
- Skipped: 5
- Time: 2.1s
Minimal Repro:
- Status: ✅ PASSING
```
## Example Workflow
```bash
# 1. Observe failure
dotnet test -- --filter-class "*XmlDocTests*"
# Result: 15 tests failing
# 2. Create minimal repro
cat > test-case.fs <<EOF
type R = { /// field doc
Field: int
}
EOF
dotnet fsc test-case.fs
# Observe: Warning FS3879 incorrectly triggered
# 3. Form hypotheses (in HYPOTHESIS.md)
# - H1: LBRACE token incorrectly tracked
# - H2: Lexer pattern issue
# - H3: Test expectations wrong
# 4. Verify H1
# Add: printfn "DEBUG: Token %A at line %d" token lineNum
./build.sh -c Release && dotnet test ...
# Result: Confirms LBRACE is being tracked
# 5. Implement fix
# Exclude LBRACE from tracking in LexFilter.fs
# 6. CRITICAL: Re-run everything
./build.sh -c Release
# 4m 44.9s, 0 errors
dotnet test -- --filter-class "*XmlDocTests*"
# 61 total, 56 passed, 0 failed, 5 skipped, 2s
# 7. Verify minimal repro
dotnet fsc test-case.fs
# No warning - ✅ FIXED
# 8. Update HYPOTHESIS.md with results
# 9. Commit with evidence
```
## Anti-Patterns to Avoid
❌ **Don't**:
- Skip the minimal reproduction
- Form only one hypothesis
- Make changes without verification
- Forget to re-run tests after fixes
- Claim "fixed" without build evidence
✅ **Do**:
- Start with smallest possible repro
- Consider multiple explanations
- Verify each hypothesis systematically
- Always re-run build and tests
- Document commands, timings, and results
## Integration with Development Workflow
After using this skill:
1. Clean up temporary debugging code
2. Remove or archive `HYPOTHESIS.md`
3. Update documentation with lessons learned
4. Add regression tests if appropriate
5. Consider whether findings reveal deeper issues
## References
- [Software Debugging Techniques](https://en.wikipedia.org/wiki/Debugging#Techniques)
- [Scientific Method Applied to Software](https://en.wikipedia.org/wiki/Scientific_method)
- F# Compiler build guide: `docs/DEVGUIDE.md`
- F# Compiler testing guide: `docs/testing.md`Colle ce Markdown dans ton agent ou utilise les boutons ci-dessus pour l’écrire dans ton projet.
Ce que fait Hypothesis Driven Debugging (.NET)
Investigating test failures (unit tests, integration tests, end-to-end tests)
Debugging build errors or compilation failures
Analyzing unexpected runtime behavior
Troubleshooting performance regressions
Comment utiliser Hypothesis Driven Debugging (.NET)
1
Copie le prompt
Un clic copie le prompt packagé (ou l'envoie à ton agent).
2
L'agent installe le skill
Il ajoute le SKILL.md et ses ressources à ton projet.
3
Activation automatique
Le skill s'active dès que le contexte correspond.
Déclencheurs pour Hypothesis Driven Debugging (.NET)
Dis simplement à ton agent quelque chose comme :
Applique le skill hypothesis-driven-debugging__dotnet-dotnet__src-fsharp-github-skills-5643bc67b46a à cette tâche
Utilise hypothesis-driven-debugging__dotnet-dotnet__src-fsharp-github-skills-5643bc67b46a pour améliorer cette implémentation
Passe en revue ce sujet avec hypothesis-driven-debugging__dotnet-dotnet__src-fsharp-github-skills-5643bc67b46a
Skills liés à Hypothesis Driven Debugging (.NET)
Add CLI Command (.NET)
Add or change a dotnet CLI command, subcommand, or option across the relevant CLI projects. USE FOR: adding or changing a dotnet CLI command/subcommand, adding a new Option<T> or Argument<T>, registering a subcommand in the command tree, changing an option's help description or a command's runtime message, wiring a command parser, or updating --help output.Add Dotnet Aot Command (.NET)
Add, enable, or review a dotnet CLI command or feature in the Native AOT CLI (src/Cli/dotnet-aot) and prove its compatibility. USE FOR: migrating a command or option to AOT, reviewing an AOT migration PR, defining conservative eligibility and managed fallback, changing AotSourceFiles.props or AotDependencies.props, validating AOT/managed parity, NativeAOT-publishing tests, checking binary-size impact, or using the dn harness and separated SDK layout. DO NOT USE FOR: resolving IL trim/AOT analyzer warnings alone (use dotnet-aot-compat), running dotnet.Tests incrementally (use incremental-test), or pure managed CLI work.Add Net Analyzer (.NET)
Add, port, or change a .NET code analysis rule (CA####) under src/Microsoft.CodeAnalysis.NetAnalyzers. USE FOR: implementing a new CA analyzer and its code fixer, porting a rule or PR from the retired dotnet/roslyn-analyzers repo, allocating a diagnostic ID from DiagnosticCategoryAndIdRanges.txt, choosing RuleLevel/severity/category, wiring resx + xlf strings, recording the rule in AnalyzerReleases.Unshipped.md, regenerating the analyzer documentation/sarif files, and writing MSTest analyzer/code-fix tests with the VerifyCS/VerifyVB harness. DO NOT USE FOR: NETSDK#### MSBuild diagnostics (src/Tasks), CS####/BC#### compiler diagnostics or IDE#### analyzers (dotnet/roslyn), or CONTAINER#### diagnostics (src/Containers).