name: expression-evaluator-extraction description: > Use this skill specifically for the custom expression evaluation / data transformation module in the VB codebase. This module acts as a business-rules engine and requires extreme care: golden-master tests MUST be in place before any extraction begins. Do not use the generic extractor skill for this module. argument-hint: "[VB file containing expression evaluator] [sample inputs to seed approval tests]"
Expression Evaluator Extraction Skill
Why This Module Gets Its Own Skill
- The expression evaluator is the most critical and opaque part of the codebase.
- It contains implicit business rules that are NOT documented anywhere.
- Any change to its behavior — even seemingly minor — can silently break downstream calculations.
- Standard unit tests are insufficient; golden-master (approval) tests are mandatory.
Phase 1: Understand Before Touching
Map the module's interface
Identify:
- Entry points: every public method/function that external code can call
- Input types: what data goes in (strings, numbers, DataRow values, expression strings?)
- Output types: what comes out (computed values, booleans, transformed strings?)
- Side effects: does it read from DB, call SOAP, or is it truly pure computation?
- State: does it maintain any state between calls, or is it stateless?
Document this as a contract table:
Method | Inputs | Output Type | Side Effects | Called From (VB handlers)
Catalog expression grammar (if applicable)
If the evaluator interprets an expression language (e.g., formula strings like "IF(A > B, X, Y)"):
- List all operators and functions supported
- Document precedence rules if any
- Collect all distinct expression patterns used at call sites
Phase 2: Approval Tests (MANDATORY — do not skip)
Minimum test corpus
Collect at least 20 representative input scenarios:
- Typical production-like inputs from each call site
- Boundary values: zero, negative numbers, empty strings, null-equivalent markers
- Maximum-length inputs
- Inputs that trigger each known conditional branch
- Inputs that have caused issues historically (if known)
Test setup
// tests/Approval/ExpressionEvaluatorApprovalTests.cs
public class ExpressionEvaluatorApprovalTests
{
// Use the ORIGINAL VB evaluator via interop OR a parallel C# port being verified
private readonly ExpressionEvaluator _evaluator = new();
[Theory]
[MemberData(nameof(GetTestCases))]
public async Task Evaluate_AllCases_MatchApprovedSnapshots(string caseId, object input)
{
var result = _evaluator.Evaluate(input);
await Verifier.Verify(result).UseParameters(caseId);
}
public static IEnumerable<object[]> GetTestCases() =>
TestCaseLoader.LoadFromJson("approval-inputs.json");
}
Store input corpus in /tests/Approval/data/expression-evaluator-inputs.json.
Store snapshots in /tests/Approval/snapshots/ — commit them as the approved behavior.
Stability gate
Run the approval tests 5 times. If any test produces different results across runs, investigate before proceeding. Non-determinism in the evaluator must be understood.
Phase 3: Extract to C# (only after Phase 2 passes)
Target structure
/src/Domain/
ExpressionEvaluation/
IExpressionEvaluator.cs ← interface
ExpressionEvaluator.cs ← C# implementation
ExpressionContext.cs ← input context record
EvaluationResult.cs ← output record
Grammar/
OperatorRegistry.cs ← if expression language is parsed
Extraction steps
- Re-implement one function at a time in C#, starting with the simplest (leaf) functions.
- After each function, run the approval test subset that exercises it.
- The C# output MUST produce identical results to the VB original on all approval inputs.
- When all functions are ported, run the full approval corpus: 100% match required.
Parallel running
During transition, run both VB and C# implementations and compare outputs in production (logging only, no functional impact) before switching. This catches inputs not in the approval corpus.
Phase 4: Verification
Final gate
dotnet test tests/Approval --filter Category=ExpressionEvaluator
All tests must pass with zero snapshots failing.
Divergence handling
If C# output diverges from VB output on any test case:
- Do NOT just change the snapshot to make it pass.
- Investigate which implementation is correct.
- If VB behavior was a bug — document it explicitly and decide with the team whether to preserve or fix.
- Update snapshot only with intentional, documented behavioral changes.