| name | behavior-harness |
| description | Use before any destructive refactor or UX/backend change to capture the legacy system's current behavior as characterization tests and golden-master fixtures — the safety net that catches regressions. This is the harness gate; it must be green before modernization code begins. |
Behavior Harness
The heart of harness-driven renovation. Before changing legacy code, pin its
current behavior with characterization tests (Michael Feathers) and golden-master
fixtures. These tests describe what the system does today — bugs included — so any
later change that alters behavior is caught immediately.
When to use
- After
requirements-grilling, before ux-modernization / strangler-backend.
- This is the harness gate — the orchestrator blocks destructive change until it is green.
Method
- Pick seams. Use the seam inventory from
architecture-recovery as the
starting point (API edges, engine hand-off, DB2DB/TCP/API integration points, key
UI flows) — don't re-derive them. Test at the highest stable seam first (HTTP/API
level, end-to-end flow) — cheaper and more robust than internal unit seams for
legacy code. Each seam pinned here flips to green in the orchestrator's per-seam
harness map.
- Characterize, don't judge. Capture actual current outputs as golden master:
send-report shapes, approval-history records, status payloads, screen-flow
outcomes. Record real inputs → real outputs; assert equality to the captured value.
- Cover the acceptance criteria from
requirements-grilling — each in-scope
requirement's current behavior gets a pinning test.
- Cover the risky edges grilling surfaced: bulk send, failure/delay, concurrent
approval, partial send.
- Make it run green & fast. All characterization tests pass against the current
system and run in CI. Commit fixtures.
Output
- Tests under the project's test tree, tagged e.g.
@characterization.
- Golden-master fixtures committed.
docs/renovation/04-harness.md: what is pinned, what seams are covered, known
gaps (behavior deliberately not pinned and why).
Staged goals
- 30: harness plan + seams identified (design-level).
- 60 / 100: harness implemented and green for the flows being modernized;
expands to cover realtime send-status and system-status once those are touched.
Gate rule
The harness gate is tracked per seam, not globally. A seam flips to green in
plan.md's harness map only when its characterization suite passes. A downstream
change may proceed in code mode only when every seam it declares as touched is
green. A global "harness passed" is a loophole — a new, unpinned seam could slip
through. Report per-seam status to renovate-orchestrator.
The harness itself is the safety foundation, so harness additions and fixture
changes go through strict-code-review before a seam is marked green — the review
checks seam coverage, fixture determinism, and that the pinned cases actually match
the downstream touched behavior. A shallow or wrong harness falsely authorizes
destructive work.
Behavior-change protocol (guards against laundering drift)
Pinning tests exist to catch behavior changes. So updating a golden master must be a
deliberate, reviewed act — never a quick edit to make a red test pass:
- Link the fixture/test change to a requirement id from
requirements-grilling.
- Record old behavior → new expected behavior in
docs/renovation/04-harness.md
(and the removed-feature or cutover log).
- Get explicit user/stakeholder approval for the behavior change.
strict-code-review blocks the change if this evidence is missing.
Transition
On green (per seam) → ux-modernization / strangler-backend may complete the
design handoff, and frontend-code-implementation / backend-slice-implementation
may begin code work on those seams. Every subsequent change must keep the harness green, or follow
the behavior-change protocol above to update a pinned expectation.
Output template and helper script
- Korean template: OUTPUT_TEMPLATE.md
- Scaffold script:
scripts/create-harness-doc.sh <repo-root> <target-name>