-
Notifications
You must be signed in to change notification settings - Fork 292
[Lean Squad] feat: formal verification infrastructure β research & CI automation #7799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Evangelink
merged 5 commits into
main
from
lean-squad/research-and-ci-2026-04-24-a3943919f2a5931a
Apr 24, 2026
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
61c6c04
feat: add formal verification infrastructure and CI workflow
github-actions[bot] 8691ca9
Bump version + ignore folder from markdownlint
9a1a3ab
fix: update elan to v4.2.1 and remove missing .sha256 check
3ebcac2
Cleanup + review comments
ee657c2
feat: add informal spec for ArgumentArity (Task 2)
github-actions[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| name: Lean Proofs | ||
|
|
||
| # π¬ Lean Squad β CI workflow for formal verification proofs. | ||
| # Runs `lake build` to verify Lean 4 proofs in formal-verification/lean/. | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - "formal-verification/lean/**" | ||
| - ".github/workflows/lean-proofs.yml" | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - "formal-verification/lean/**" | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
| lean-build: | ||
| name: Build Lean proofs | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Install elan (Lean version manager) | ||
| run: | | ||
| ELAN_VERSION="v4.2.1" | ||
| ELAN_TARGET="x86_64-unknown-linux-gnu" | ||
| ELAN_ARCHIVE="elan-${ELAN_TARGET}.tar.gz" | ||
| ELAN_BASE_URL="https://github.com/leanprover/elan/releases/download/${ELAN_VERSION}" | ||
| ELAN_TMP_DIR="$(mktemp -d)" | ||
|
|
||
| LEAN_TOOLCHAIN_FILE="formal-verification/lean/lean-toolchain" | ||
|
|
||
| if [ ! -f "${LEAN_TOOLCHAIN_FILE}" ]; then | ||
| echo "Missing Lean toolchain file: ${LEAN_TOOLCHAIN_FILE}" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| LEAN_TOOLCHAIN="$(tr -d '\r\n' < "${LEAN_TOOLCHAIN_FILE}")" | ||
|
|
||
| if [ -z "${LEAN_TOOLCHAIN}" ]; then | ||
| echo "Lean toolchain file is empty: ${LEAN_TOOLCHAIN_FILE}" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| curl -sSfL "${ELAN_BASE_URL}/${ELAN_ARCHIVE}" -o "${ELAN_TMP_DIR}/${ELAN_ARCHIVE}" | ||
| cd "${ELAN_TMP_DIR}" | ||
| echo "4e717523217af592fa2d7b9c479410a31816c065d66ccbf0c2149337cfec0f5c ${ELAN_ARCHIVE}" | sha256sum -c - | ||
| tar -xzf "${ELAN_ARCHIVE}" | ||
| ./elan-init -y --default-toolchain "${LEAN_TOOLCHAIN}" | ||
| rm -rf "${ELAN_TMP_DIR}" | ||
|
|
||
| - name: Add elan to PATH | ||
| run: echo "$HOME/.elan/bin" >> "$GITHUB_PATH" | ||
|
|
||
| - name: Show Lean version | ||
| run: lean --version | ||
|
|
||
| - name: Cache Lean / Lake build artifacts | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: | | ||
| formal-verification/lean/.lake | ||
| ~/.elan | ||
| key: lean-${{ runner.os }}-${{ hashFiles('formal-verification/lean/lakefile.toml', 'formal-verification/lean/lake-manifest.json') }} | ||
| restore-keys: | | ||
| lean-${{ runner.os }}- | ||
|
Evangelink marked this conversation as resolved.
|
||
|
|
||
| - name: Build Lean proofs | ||
| working-directory: formal-verification/lean | ||
| run: lake build | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ trigger: | |
| exclude: | ||
| - .github/** | ||
| - .gitignore | ||
| - formal-verification/** | ||
|
|
||
| parameters: | ||
| - name: isRTM | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # LeanβC# Correspondence | ||
|
|
||
| > π¬ **Lean Squad** β auto-generated and maintained by the Lean Squad FV agent. | ||
|
|
||
| This document records how each Lean 4 model corresponds to the C# source it is meant to represent, including deliberate approximations and abstractions. | ||
|
|
||
| _No targets have reached Phase 4 (implementation extraction) yet. This document will be populated as targets advance._ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # FV Critique | ||
|
|
||
| > π¬ **Lean Squad** β auto-generated and maintained by the Lean Squad FV agent. | ||
|
|
||
| This document records an ongoing assessment of the utility and coverage of the formal verification work in this repository. | ||
|
|
||
| _No targets have been proved yet. Critique will be added as proofs are completed._ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # FV Project Report | ||
|
|
||
| > π¬ **Lean Squad** β auto-generated and maintained by the Lean Squad FV agent. | ||
|
|
||
| ## Status | ||
|
|
||
| **Phase**: Early β Research complete, informal spec for `ArgumentArity` extracted. | ||
|
|
||
| ## Summary | ||
|
|
||
| The Lean Squad has surveyed the `microsoft/testfx` codebase and identified five high-quality FV targets in the command-line infrastructure of Microsoft.Testing.Platform. All five targets are pure or near-pure functions with clear algebraic properties, making them suitable for Lean 4 formal verification. | ||
|
|
||
| An informal specification has been extracted for `ArgumentArity` (highest-priority target): 14 properties across four groups (predefined constants, well-formedness, equality, distinctness). One open question identified: the constructor does not enforce `Min β€ Max`, so ill-formed arities are silently accepted. This is a potential source of undefined validator behavior. | ||
|
|
||
| The next steps are: | ||
| 1. Write the Lean 4 formal spec for `ArgumentArity` (types + theorem stubs). | ||
| 2. Attempt decidable proofs with `decide`. | ||
| 3. Advance to `CommandLineParser.TryUnescape`. | ||
|
|
||
| ## Targets Identified | ||
|
|
||
| | Target | Phase | Notes | | ||
| |--------|-------|-------| | ||
| | `ArgumentArity` | 2 | Informal spec extracted β 14 properties, open question on ill-formed arity | | ||
| | `CommandLineParser.TryUnescape` | 1 | Security-relevant string unescaping | | ||
| | `CommandLineParser.ParseOptionAndSeparators` | 1 | Pure option-splitting function | | ||
| | `CommandLineOptionsValidator` arity validation | 1 | Arity bounds checking | | ||
| | `CommandLineParseResult.Equals` | 1 | Structural equality laws | | ||
|
|
||
| ## Run History | ||
|
|
||
| | Date | Tasks | Outcome | | ||
| |------|-------|---------| | ||
| | 2026-04-24 | Task 1 (Research), Task 2 (Informal Spec), Task 9 (CI Automation) | Identified 5 targets; extracted informal spec for ArgumentArity (14 properties, open question on ill-formed arity); set up CI workflow | | ||
| | 2026-04-24 | Task 1 (Research), Task 9 (CI Automation) | Identified targets, created FV directory, set up CI workflow | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| # Formal Verification Research | ||
|
|
||
| > π¬ **Lean Squad** β auto-generated and maintained by the Lean Squad FV agent. | ||
|
|
||
| ## Repository Overview | ||
|
|
||
| **Repository**: `microsoft/testfx` | ||
| **Primary Language**: C# (.NET) | ||
| **Codebase Components**: | ||
| - **MSTest** (`src/TestFramework/`): The MSTest v3 testing framework for .NET β assertion APIs, test attributes, data-driven tests. | ||
| - **Microsoft.Testing.Platform** (`src/Platform/Microsoft.Testing.Platform/`): A modern, extensible test runner platform β command-line parsing, server mode, extensions. | ||
| - **Adapters and Extensions** (`src/Adapter/`, `src/Platform/Microsoft.Testing.Extensions.*/`): VSTest bridge, telemetry, coverage, retry, crash dump, etc. | ||
| - **Analyzers** (`src/Analyzers/`): Roslyn-based diagnostic analyzers for MSTest usage. | ||
|
|
||
| ## FV Tool Choice | ||
|
|
||
| **Lean 4** with **Mathlib** (standard Lean 4 library for mathematics and formal proofs). | ||
|
|
||
| **Rationale**: | ||
| - Lean 4 has excellent decidable-proposition support (`decide` tactic). | ||
| - Mathlib provides rich libraries for lists, strings, and algebraic structures. | ||
| - Lean 4's dependent type system allows encoding invariants as types. | ||
| - Active ecosystem with CI integration via `lake build`. | ||
|
|
||
| ## FV Strategy | ||
|
|
||
| This project applies formal verification **incrementally**, one target at a time: | ||
|
|
||
| 1. Identify **pure or near-pure functions** with clear algebraic properties. | ||
| 2. Write **informal specs** capturing intent from code, tests, and documentation. | ||
| 3. Translate to **Lean 4 type definitions and theorem statements** (with `sorry`). | ||
| 4. **Attempt proofs** using `decide`, `omega`, `simp`, `induction`, etc. | ||
| 5. Report **bugs** when a proposition cannot be proved and the spec is correct. | ||
|
|
||
| We focus on **structural properties** and **invariants** rather than full functional equivalence (which would require modelling all of .NET's runtime semantics). | ||
|
|
||
| ## Identified FV-Amenable Targets | ||
|
|
||
| ### Target 1 β `ArgumentArity` β β β β β | ||
|
|
||
| **File**: `src/Platform/Microsoft.Testing.Extensions.CommandLine/ArgumentArity.cs` | ||
|
Evangelink marked this conversation as resolved.
|
||
| **Type**: `readonly struct ArgumentArity(int min, int max)` | ||
|
|
||
| A simple value struct for describing how many arguments a command-line option accepts. | ||
|
|
||
| **Why ideal for FV**: | ||
| - Tiny, self-contained type with only two integer fields. | ||
| - Five predefined constants with documented semantics. | ||
| - `IEquatable<T>` implementation to verify. | ||
| - Invariant: for all well-formed arities, `Min β€ Max` β **not enforced by the constructor**. | ||
| - Equality properties (reflexivity, symmetry, transitivity) are easily decidable. | ||
|
|
||
| **Properties to verify**: | ||
| 1. All five predefined constants satisfy `Min β€ Max`. | ||
| 2. `Zero` has Min=0, Max=0. | ||
| 3. `ZeroOrOne` has Min=0, Max=1. | ||
| 4. `ZeroOrMore` has Min=0, Max=`maxInt32`. | ||
| 5. `OneOrMore` has Min=1, Max=`maxInt32`. | ||
| 6. `ExactlyOne` has Min=1, Max=1. | ||
| 7. `Equals` is an equivalence relation (reflexive, symmetric, transitive). | ||
| 8. `==` and `!=` agree with `Equals`. | ||
|
|
||
| **Approximations**: Model `int.MaxValue` with an explicit Lean sentinel constant, for example `def maxInt32 : Int := 2^31 - 1`. | ||
|
|
||
| --- | ||
|
|
||
| ### Target 2 β `CommandLineParser.TryUnescape` β β β β β | ||
|
|
||
| **File**: `src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs` (inner function) | ||
| **Informal signature**: command-line text Γ optional quote context Γ environment β either unescaped text or an error message | ||
|
|
||
| A pure function that unescapes command-line argument strings β handling single-quote and double-quote conventions. | ||
|
|
||
| **Why good for FV**: | ||
| - Pure (no side effects, no I/O). | ||
| - Well-documented convention via comments in source. | ||
| - Clear case analysis: plain string / single-quoted / double-quoted. | ||
|
|
||
| **Properties to verify**: | ||
| 1. Single-quoted strings without interior quotes β strip outer quotes. | ||
| 2. Single-quoted strings with interior quotes β error. | ||
| 3. Double-quoted strings β strip quotes and apply backslash-escape rules. | ||
| 4. Unquoted strings β returned unchanged. | ||
| 5. Result of successful unescaping never starts or ends with the outer quote character. | ||
|
|
||
| **Approximations**: Lean model abstracts `IEnvironment.NewLine` as a parameter; does not model environment variable expansion. | ||
|
|
||
| --- | ||
|
|
||
| ### Target 3 β `CommandLineParser.ParseOptionAndSeparators` β β β β β | ||
|
|
||
| **File**: `src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs` (inner function) | ||
| **Type**: `string β string Γ option(string)` | ||
|
|
||
| Splits a raw argument like `--option=value` or `--option:value` or `--option` into option name and argument. | ||
|
|
||
| **Properties to verify**: | ||
| 1. If the input contains no `:` or `=`, the result argument is `none`. | ||
| 2. If the input contains `:` or `=`, the option name is `input[..delimiterIndex]` and argument is the rest. | ||
| 3. The returned option name has all leading `-` characters stripped. | ||
| 4. If the delimiter is the first character, the option name is empty string. | ||
|
|
||
| **Approximations**: Models `IndexOfAny` over two characters; string indexing. | ||
|
|
||
| --- | ||
|
|
||
| ### Target 4 β `CommandLineOptionsValidator` arity validation β β β ββ | ||
|
|
||
| **File**: `src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs` | ||
| **Function**: `ValidateOptionsArgumentArity` | ||
|
|
||
| Checks that each parsed option has an argument count within its registered arity bounds. | ||
|
|
||
| **Properties to verify**: | ||
| 1. If an option has `Max=0` and `argumentCount > 0` β error. | ||
| 2. If `argumentCount < Min` β error. | ||
| 3. If `argumentCount > Max` (and `Max > 0`) β error. | ||
| 4. If `Min β€ argumentCount β€ Max` β no error for that option. | ||
| 5. An option with `Arity = Zero` and zero arguments produces no error. | ||
|
|
||
| **Approximations**: Must model a simplified option registry; abstracts over provider identity. | ||
|
|
||
| --- | ||
|
|
||
| ### Target 5 β `CommandLineParseResult` structural equality β β β ββ | ||
|
|
||
| **File**: `src/Platform/Microsoft.Testing.Platform/CommandLine/ParseResult.cs` | ||
| **Function**: `Equals(CommandLineParseResult?)` | ||
|
|
||
| Structural equality over a parse result: tool name, list of options (name + argument list), and list of errors. | ||
|
|
||
| **Properties to verify**: | ||
| 1. Reflexivity: `r.Equals(r)` is always true. | ||
| 2. Symmetry: `r1.Equals(r2) β r2.Equals(r1)`. | ||
| 3. Transitivity: `r1.Equals(r2) β§ r2.Equals(r3) β r1.Equals(r3)`. | ||
| 4. Empty parse result equals itself. | ||
| 5. Two results differing only in tool name are not equal. | ||
|
|
||
| **Approximations**: Model strings as `String` (Lean), argument lists as `List String`. | ||
|
|
||
| --- | ||
|
|
||
| ## Approach Notes | ||
|
|
||
| - We use Lean 4 with Mathlib for all proofs. | ||
| - We translate C# business logic into **pure functional Lean models**, explicitly noting what is abstracted away. | ||
| - `sorry` is used liberally early on; the goal is to get theorems stated correctly, then fill proofs. | ||
| - For simple finite types (like `ArgumentArity` constants), we rely on `decide` for closed proofs. | ||
| - We track which theorems are `sorry`-guarded vs. fully proved in `TARGETS.md`. | ||
|
|
||
| ## Open Questions | ||
|
|
||
| - Should we model `int.MaxValue` as an explicit Lean constant (e.g., `def maxInt32 : Int := 2^31 - 1`) or leave it as an opaque constant? | ||
| - The `TryUnescape` function handles environment `NewLine` β should we abstract over this or assume `"\n"`? | ||
| - Is the lack of a `Min β€ Max` invariant in `ArgumentArity` a real bug or an accepted API choice? Worth filing an issue if a "bad" arity causes unexpected validator behaviour. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # FV Targets | ||
|
|
||
| > π¬ **Lean Squad** β auto-generated and maintained by the Lean Squad FV agent. | ||
|
|
||
| ## Legend | ||
|
|
||
| | Phase | Description | | ||
| |-------|-------------| | ||
| | 1 | Research β identified, rationale documented | | ||
| | 2 | Informal spec extracted | | ||
| | 3 | Lean 4 formal spec written (type signatures + theorem stubs) | | ||
| | 4 | Lean 4 implementation model extracted | | ||
| | 5 | Proofs attempted / completed | | ||
|
|
||
| ## Target List | ||
|
|
||
| | # | Name | File | Phase | Status | PR/Issue | | ||
| |---|------|------|-------|--------|----------| | ||
| | 1 | `ArgumentArity` | `src/Platform/Microsoft.Testing.Platform/CommandLine/ArgumentArity.cs` | 2 | Informal spec extracted | [PR #7799](https://github.com/microsoft/testfx/pull/7799) | | ||
| | 2 | `CommandLineParser.TryUnescape` | `src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs` | 1 | Identified | β | | ||
| | 3 | `CommandLineParser.ParseOptionAndSeparators` | `src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs` | 1 | Identified | β | | ||
|
Evangelink marked this conversation as resolved.
|
||
| | 4 | `CommandLineOptionsValidator` arity validation | `src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs` | 1 | Identified | β | | ||
| | 5 | `CommandLineParseResult.Equals` | `src/Platform/Microsoft.Testing.Platform/CommandLine/ParseResult.cs` | 1 | Identified | β | | ||
|
|
||
| ## Priority Order | ||
|
|
||
| 1. **`ArgumentArity`** β highest priority. Smallest self-contained target; decidable properties; good warm-up for setting up the Lean environment. | ||
| 2. **`CommandLineParser.TryUnescape`** β second priority. Pure function with clear specification; security-relevant string processing. | ||
| 3. **`CommandLineParser.ParseOptionAndSeparators`** β third priority. Small pure function; useful for verifying parser correctness. | ||
| 4. **`CommandLineOptionsValidator` arity validation** β fourth priority. Validation logic with clear input/output contract. | ||
| 5. **`CommandLineParseResult.Equals`** β fifth priority. Structural equality; good for verifying equivalence-relation laws. | ||
|
|
||
| ## Notes | ||
|
|
||
| - All five targets are in the command-line infrastructure (`src/Platform/Microsoft.Testing.Platform/CommandLine/`). | ||
| - This focus makes sense: command-line parsing is pure and testable, with clear specification from the POSIX/CLI conventions. | ||
| - MSTest assertion APIs (e.g., `Assert.AreEqual`, `Assert.IsTrue`) are interesting but harder to model formally due to generic type constraints and exception-based control flow. | ||
| - Future targets may include the test-filter grammar and the server-mode protocol state machine. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.