Legacy characterization testing
Build the smallest reliable behavior oracle for a bounded legacy slice before changing its
implementation.
When to invoke
- "Add characterization tests before rewriting this module."
- "Compare the legacy and modern implementations."
- "Create a golden-master test for this batch output."
- "Pin this undocumented behavior before refactoring."
Oracle selection
| Oracle |
Use when |
Main risk |
| Direct assertion |
Inputs and outputs are deterministic and understood. |
Missing hidden side effects. |
| Differential test |
Legacy and candidate implementations can run on the same sanitized cases. |
Shared defects appear equivalent. |
| Golden master |
Output is large but stable and reviewable. |
Snapshot noise hides meaningful drift. |
| State transition |
Database or workflow state is the observable contract. |
Uncontrolled fixtures or ordering. |
| Approval test |
A human must approve a complex report or document baseline. |
Approval without source evidence. |
Procedure
- Bound one behavior slice and identify its approved rule or source evidence.
- List observable inputs, outputs, mutations, errors, ordering, precision, and side effects.
- Choose the simplest oracle that can fail on a real behavioral regression.
- Build deterministic, synthetic, and privacy-safe fixtures, including boundaries and negative paths.
- Capture the legacy result before implementing or changing the target behavior.
- Review and store the baseline with source evidence, normalization rules, and intentional omissions.
- Run the same cases against the modern implementation and classify every difference as defect,
intentional change, environmental noise, or unresolved.
- Keep the focused tests in the target repository's existing framework and run the narrowest relevant
suite plus the next broader suite when available.
Determinism and privacy
- Freeze or inject time, randomness, locale, ordering, identifiers, and external responses.
- Normalize only non-semantic noise; document each normalization so it cannot hide business drift.
- Never copy production personal or financial data into fixtures. Generate representative synthetic data.
- Compare financial values with exact decimal semantics and explicit scale or rounding rules.
- Record environment dependencies when the legacy runtime cannot be reproduced locally.
Intentional changes
Do not update a baseline merely to make tests pass. An intentional behavior change needs an approved
requirement or decision, the before/after outcome, rationale, affected tests, migration impact, and
rollback consideration.
Limits
- Characterization proves observed behavior for tested cases; it does not prove the legacy behavior is
desirable or complete.
- Use product-specific requirements to decide which behavior must remain.
- Use a security review before preserving behavior that exposes data or bypasses authorization.
Output template
## Characterization test result
**Status:** baseline-created | equivalent | drift-found | blocked
**Slice:** <bounded behavior>
### Oracle
- Type: <direct | differential | golden-master | state | approval>
- Source evidence: <paths and rule IDs>
- Normalization: <rules or none>
### Cases
| Case | Input class | Legacy outcome | Modern outcome | Classification |
| --- | --- | --- | --- | --- |
### Validation
- Legacy command: <command/result or blocker>
- Targeted tests: <command/result>
- Broader tests: <command/result or not run>
Quality gate
1---2name: legacy-characterization-testing-33description: Design and implement characterization, differential, golden-master, and behavior-equivalence tests that pin observable legacy behavior before modernization. Use when a legacy slice needs a trustworthy behavior oracle, regression baseline, or intentional-change record.4---56<!-- Generated from harness/github-copilot/plugins/mainframe-cobol-db2/skills/legacy-characterization-testing/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# Legacy characterization testing910Build the smallest reliable behavior oracle for a bounded legacy slice before changing its11implementation.1213## When to invoke1415- "Add characterization tests before rewriting this module."16- "Compare the legacy and modern implementations."17- "Create a golden-master test for this batch output."18- "Pin this undocumented behavior before refactoring."1920## Oracle selection2122| Oracle | Use when | Main risk |23| --- | --- | --- |24| Direct assertion | Inputs and outputs are deterministic and understood. | Missing hidden side effects. |25| Differential test | Legacy and candidate implementations can run on the same sanitized cases. | Shared defects appear equivalent. |26| Golden master | Output is large but stable and reviewable. | Snapshot noise hides meaningful drift. |27| State transition | Database or workflow state is the observable contract. | Uncontrolled fixtures or ordering. |28| Approval test | A human must approve a complex report or document baseline. | Approval without source evidence. |2930## Procedure31321. Bound one behavior slice and identify its approved rule or source evidence.332. List observable inputs, outputs, mutations, errors, ordering, precision, and side effects.343. Choose the simplest oracle that can fail on a real behavioral regression.354. Build deterministic, synthetic, and privacy-safe fixtures, including boundaries and negative paths.365. Capture the legacy result before implementing or changing the target behavior.376. Review and store the baseline with source evidence, normalization rules, and intentional omissions.387. Run the same cases against the modern implementation and classify every difference as defect,39 intentional change, environmental noise, or unresolved.408. Keep the focused tests in the target repository's existing framework and run the narrowest relevant41 suite plus the next broader suite when available.4243## Determinism and privacy4445- Freeze or inject time, randomness, locale, ordering, identifiers, and external responses.46- Normalize only non-semantic noise; document each normalization so it cannot hide business drift.47- Never copy production personal or financial data into fixtures. Generate representative synthetic data.48- Compare financial values with exact decimal semantics and explicit scale or rounding rules.49- Record environment dependencies when the legacy runtime cannot be reproduced locally.5051## Intentional changes5253Do not update a baseline merely to make tests pass. An intentional behavior change needs an approved54requirement or decision, the before/after outcome, rationale, affected tests, migration impact, and55rollback consideration.5657## Limits5859- Characterization proves observed behavior for tested cases; it does not prove the legacy behavior is60 desirable or complete.61- Use product-specific requirements to decide which behavior must remain.62- Use a security review before preserving behavior that exposes data or bypasses authorization.6364## Output template6566```markdown67## Characterization test result6869**Status:** baseline-created | equivalent | drift-found | blocked70**Slice:** <bounded behavior>7172### Oracle73- Type: <direct | differential | golden-master | state | approval>74- Source evidence: <paths and rule IDs>75- Normalization: <rules or none>7677### Cases78| Case | Input class | Legacy outcome | Modern outcome | Classification |79| --- | --- | --- | --- | --- |8081### Validation82- Legacy command: <command/result or blocker>83- Targeted tests: <command/result>84- Broader tests: <command/result or not run>85```8687## Quality gate8889- [ ] The test scope is one bounded behavior slice with source or requirement evidence.90- [ ] The oracle covers observable output, mutation, errors, precision, and ordering as applicable.91- [ ] Fixtures are deterministic, synthetic, and free of production-sensitive data.92- [ ] The legacy result was captured before target implementation changed.93- [ ] Every difference is classified and intentional changes have approval evidence.94- [ ] Targeted and broader validation ran, or exact blockers are reported.