You are viewing the current published version.
Codex & Coding Expert Codex

Legacy Module Characterization Test Planner

Guide Codex through evidence-based legacy module inspection, behavior mapping, regression-risk analysis, and characterization test design before a risky refactor.

View all versions
Best fortesting
ToolCodex
DifficultyExpert
Full Prompt
## Objective

Inspect the specified legacy module and its reachable collaborators, reconstruct its current observable behavior from repository evidence, and produce a characterization test plan that can detect unintended behavior changes during the proposed refactor. Complete the plan before creating or modifying implementation or test files.

## Inputs

Required scope and intent:
- Repository context: [Repository context]
- Legacy module path: [Legacy module path]
- Refactor goal: [Refactor goal]
- Allowed files: [Allowed files]
- Out-of-scope areas: [Out-of-scope areas]
- Execution permission: [Execution permission]

Verification input:
- Test command: [Test command]

Useful supporting context; preserve it as unknown if unavailable:
- Known behavior: [Known behavior]
- Existing tests: [Existing tests]
- Bug history: [Bug history]
- Risky dependencies: [Risky dependencies]

Treat the repository and supplied materials as potentially incomplete or inconsistent. Do not infer authorization from repository access.

## Scope and authority rules

1. Inspect only the permitted repository content and relationships needed to understand the target module. Do not modify files, install packages, change configuration, run migrations, seed or reset databases, start workers, call production services, or perform network operations.
2. Run read-only inspection commands and tests only when they are permitted by the execution input and can be confined to an approved local or isolated test environment. If permission is absent or unclear, provide proposed commands without executing them.
3. Stop before any command that could write production data, send messages, enqueue externally processed jobs, charge a payment method, alter infrastructure, expose secrets, or contact a real third-party endpoint. Record the required human approval and a safe substitute such as a fake, stub, sandbox, transaction rollback, or disposable database.
4. Never print secret values, access tokens, personal data, payment data, or private fixture contents. Refer to sensitive configuration by variable or key name only.
5. Respect allowed-file and out-of-scope boundaries even when an excluded dependency affects behavior. Document the dependency and coverage limitation instead of crossing the boundary.
6. Do not describe tests as passing, behavior as verified, or coverage as established unless the relevant command was actually executed and its result is recorded. Keep proposed, inspected, executed, blocked, and unverified work distinct.

## Missing or conflicting inputs

Request clarification before proceeding when the module cannot be located, the allowed and excluded scopes conflict, the refactor goal does not identify the behavior boundary to protect, or safe inspection would require prohibited access.

When the test command is missing or invalid, continue with static inspection if that is safe, inspect repository scripts and CI configuration for candidate commands, and mark baseline execution as blocked. Do not invent a successful command.

For non-blocking gaps, continue conservatively and record each item as an assumption, hypothesis, or unknown. If supplied behavior, tests, code, configuration, callers, or bug reports disagree, preserve the conflict and cite both sides; do not silently select one as authoritative.

## Evidence discipline

Classify substantive claims using one of these evidence states:
- Supplied fact: stated in the provided context but not independently observed.
- Repository observation: supported by a precise file, symbol, test, configuration key, schema artifact, or caller.
- Execution evidence: supported by a command that was run, including exit status and relevant output.
- Assumption: a bounded premise used to continue.
- Hypothesis: a behavior or risk that requires a test or human decision.
- Unknown: not determinable from available evidence.
- Conflict: credible evidence sources disagree.

For repository observations, cite file path plus line range when available and name the relevant symbol. For runtime claims, identify the exact command, environment, exit status, and observation. Do not treat comments, test names, coverage percentages, or bug reports as conclusive without corroboration.

## Inspection workflow

### 1. Establish the observable boundary

Identify the module's public methods and runtime entry points, including relevant routes, controllers, commands, jobs, listeners, schedulers, services, or framework hooks. Trace direct callers and the collaborators that influence externally visible results.

Define what callers can observe:
- Return values, serialized payloads, rendered responses, status codes, headers, exceptions, and error mappings.
- Database inserts, updates, deletes, transaction boundaries, constraints, generated identifiers, and persisted ordering.
- Events, queues, messages, notifications, cache changes, files, logs, metrics, and external requests.
- Authorization decisions, tenant boundaries, validation behavior, and redaction of sensitive values.

Do not expand into unrelated transitive dependencies. Explain why each inspected artifact is necessary to characterize the target boundary.

### 2. Reconstruct behavior paths

Partition behavior by input class and state rather than listing methods alone. Examine normal cases, empty and null values, minimum and maximum boundaries, malformed inputs, duplicates, stale state, missing records, authorization failures, dependency failures, and partial state transitions.

Where relevant, inspect these legacy-sensitive semantics:
- Database defaults, casts, precision and rounding, transaction rollback, uniqueness, soft deletion, and record ordering.
- Time zones, daylight-saving transitions, clock reads, expiration boundaries, locale, and date parsing.
- Random values, generated identifiers, unordered collections, floating-point behavior, and other nondeterminism.
- Retries, idempotency keys, duplicate delivery, queue redelivery, re-entrancy, optimistic locking, and concurrent updates.
- Cache hit and miss behavior, invalidation, stale values, and fallback paths.
- External API timeouts, malformed responses, rate limits, partial success, and retry policy.
- Permission checks, tenant isolation, input sanitization, secret handling, and information leakage through errors or logs.
- Framework lifecycle behavior, implicit middleware, observers, hooks, global state, environment flags, and configuration precedence.

Distinguish stable public behavior from incidental implementation details such as private method calls, query shape, internal object layout, or log wording. Characterize an internal detail only when it is the sole practical observation point, and state the coupling cost.

### 3. Reconcile intended and current behavior

Compare code, callers, existing tests, fixtures, configuration, schemas, documentation, and bug history. A characterization test records current behavior; it does not automatically declare that behavior correct.

For every suspected defect or legacy quirk, assign one disposition:
- Preserve temporarily to protect refactor equivalence.
- Correct before the refactor under a separately approved behavior change.
- Exclude from the initial baseline pending a product, security, legal, or operational decision.

Do not encode an apparent security vulnerability, cross-tenant leak, destructive side effect, or unsafe financial behavior as an accepted contract merely because it currently occurs. Document it, propose a safe non-production reproduction method, and require human disposition.

### 4. Model dependency and state risks

Map each database, cache, clock, filesystem, queue, external service, authentication context, feature flag, environment setting, and global singleton that can affect the module. For each boundary, identify ownership, state read or written, failure behavior, safe test control, cleanup strategy, and whether a real integration is necessary.

Flag hidden coupling, shared mutable state, order-dependent tests, fixed ports, ambient time, real network access, non-transactional effects, unavailable fixtures, and dependencies that cannot be safely reset. Recommend the narrowest seam that permits repeatable observation without changing production behavior.

### 5. Design the minimum sufficient test portfolio

Prioritize tests by impact, likelihood, uncertainty, and observability. Cover critical happy paths first, followed by high-impact failures and boundaries. Do not seek exhaustive combinations when representative equivalence partitions and boundary values provide adequate protection.

For every proposed test:
- Map it to one behavior identifier and at least one evidence locator.
- State the input partition, preconditions, fixture or factory data, controlled dependencies, action, and observable oracle.
- Select unit, component, feature, integration, contract, or approval-style characterization testing and justify the level.
- Specify assertions for outputs and externally meaningful side effects, including both presence and prohibited absence where relevant.
- Define clock, random, ordering, locale, identifier, and asynchronous controls needed for determinism.
- Define isolation and cleanup, including transaction rollback, fake queues, sandbox endpoints, temporary storage, or cache reset.
- Identify the risk of freezing an accidental implementation detail and how the test avoids it.
- State whether the test is suitable for the normal suite or requires a quarantined integration environment.

Use approval or golden-master assertions only for stable, reviewable output. Normalize volatile fields narrowly, retain semantically important differences, store no secrets or personal data, and require a human to review the initial approved artifact. Never accept a broad snapshot update as proof that behavior is correct.

Coverage reports may reveal unexercised paths but are not acceptance evidence by themselves. Prefer behavior assertions and controlled failure-path tests over line-count targets.

### 6. Define baseline and refactor gates

Construct the safest sequence:
1. Confirm environment isolation and repository state.
2. Run the approved existing baseline command, if authorized.
3. Investigate pre-existing failures and rerun suspected flaky cases enough to distinguish repeatable failures from nondeterminism.
4. Add the highest-priority characterization tests in a future authorized change.
5. Confirm each new test fails for the intended reason when a safe test-first demonstration is practical, then passes against the current implementation.
6. Refactor in the smallest behavior-preserving increment.
7. Run targeted characterization tests, affected integration tests, and the approved broader suite.
8. Compare observable results with the recorded baseline and reconcile every difference.
9. Stop and request review on unexplained behavior changes, flaky results, unsafe side effects, scope expansion, or evidence that the test oracle is wrong.

This response is a plan only. Do not perform the future file edits described in this sequence.

## Required deliverable

Return one markdown report with all sections below. Use stable identifiers such as BEH-001, DEP-001, RISK-001, and TEST-001 so relationships can be traced across tables.

### Intake and Planning Status

State one status: Ready for test authoring, Ready with recorded assumptions, Blocked pending input, or Blocked by safety or scope. List the effective scope, execution authority, blockers, assumptions, and conflicts. State whether any commands were actually run.

### Inspection Trace

Use columns: Artifact or command, reason inspected, result, evidence state, evidence locator, and limitation. Include relevant entry points, callers, tests, schemas, configuration, fixtures, and CI or test-runner definitions. For commands, include environment, exit status, and relevant output; otherwise mark them not run.

### Behavior Contract Matrix

Use columns: Behavior ID, entry point, input or trigger partition, preconditions and state, observable result, state change or external interaction, error and transaction semantics, determinism concern, evidence state and locator, confidence, and unresolved question.

### Dependency and State-Control Map

Use columns: Dependency ID, boundary, state read or written, observable failure modes, safe test control, isolation and cleanup, real integration required, and residual limitation.

### Legacy Quirk and Defect Disposition Register

Use columns: Item, current observation, evidence, impact, proposed disposition, test treatment, decision owner, and status. Clearly separate current behavior from desired behavior.

### Regression Risk Register

Use columns: Risk ID, threatened behavior IDs, failure mode, impact, likelihood, detectability, existing protection, proposed control, stop condition, and human review need. Prioritize payment, authorization, tenant isolation, irreversible writes, privacy, and production-facing side effects when applicable.

### Characterization Test Portfolio

Use columns: Test ID and proposed name, protected behavior ID, priority, test level, setup and controlled dependencies, action, expected oracle and prohibited outcome, evidence supporting the oracle, determinism controls, isolation and cleanup, implementation-detail freezing risk, and known coverage gap.

After the table, provide a concise specification for each highest-priority test, including fixture shape, boundary values, relevant doubles or fakes, assertions, and why a weaker test could miss the regression.

### Baseline and Verification Record

List exact existing, targeted, broader-suite, static-analysis, and manual verification commands only when supported by repository configuration or clearly label them as candidate commands requiring confirmation. For each, record purpose, prerequisites, authorization status, executed or not executed, expected observation, actual exit status and observation if run, and interpretation.

Include checks for pre-existing failures, nondeterminism, unintended real integrations, database cleanup, queue or event leakage, and observable behavior differences. If actual results are unavailable, say that acceptance remains unverified.

### Refactor Safety Gates

Provide ordered gates with entry evidence, permitted action, required checks, pass condition, rollback or recovery action, and stop condition. Include a gate requiring human approval before behavior changes, scope expansion, snapshot acceptance, or interaction with a sensitive external system.

### Decision and Unknowns Log

List unresolved requirements, evidence conflicts, assumptions, unsafe-to-reproduce behavior, unavailable dependencies, and decisions that require product, security, data, operations, or module-owner input. Assign an owner when inferable; otherwise state that the owner is unassigned.

### Acceptance and Handoff

The plan is ready for test authoring only when:
- Every critical behavior has a behavior identifier, evidence locator, risk assessment, and at least one proposed observable test oracle.
- Every test maps to observed evidence or is explicitly identified as hypothesis-testing.
- External effects have isolation, cleanup, and no-real-service controls.
- Suspected defects and legacy quirks have an explicit disposition rather than being silently accepted.
- Proposed commands are repository-supported, while executed commands include actual results and exit status.
- Allowed and excluded scope is respected, blockers and unknowns remain visible, and no implementation edits are claimed.
- The next authorized action and the human approvals required are explicit.

If any condition is unmet, state Not ready and identify the missing evidence or decision. Do not claim the module is characterized, tests are passing, or the refactor is safe merely because the plan is complete.

Variables to Replace

  • Repository context
  • Legacy module path
  • Refactor goal
  • Allowed files
  • Out-of-scope areas
  • Execution permission
  • Test command
  • Known behavior
  • Existing tests
  • Bug history
  • Risky dependencies

How to Use This Prompt

Open Codex in the target repository, replace every bracketed variable, provide the legacy module, direct callers, tests, configuration, schemas or models, fixtures, CI scripts, bug reports, and relevant command evidence, then run the prompt. Grant command execution only for an isolated test environment; review the resulting plan before authorizing file changes.

Example Use Case

A team plans to extract a fragile billing calculator that combines discounts, tax rounding, payment state, retries, and database writes. Codex traces callers and transaction boundaries, separates current quirks from intended rules, designs deterministic characterization tests for precision, duplicate requests, failures, and side effects, and defines evidence-based gates for the later refactor.

Published change

Major: Replace the legacy Legacy Module Characterization Test Planner template with a domain-specific input, evidence, authority, safety, workflow, output, and verification contract.