Source version 1.0.0
Published
Initial: Initial published snapshot.
Published version comparison
1.0.0 → 2.0.0
1.0.0Published
Initial: Initial published snapshot.
2.0.0Published
Major: Replace the legacy Legacy Module Characterization Test Planner template with a domain-specific input, evidence, authority, safety, workflow, output, and verification contract.
Legacy Module Characterization Test Planner
Legacy Module Characterization Test Planner
Guide Codex to inspect legacy code, map current behavior, and plan characterization tests before refactoring risky modules.
Guide Codex through evidence-based legacy module inspection, behavior mapping, regression-risk analysis, and characterization test design before a risky refactor.
Use this to make Codex protect existing behavior before touching a legacy module.
Use this prompt to establish an evidence-backed behavioral baseline and a prioritized characterization test portfolio before changing a fragile legacy module.
Legacy Code Refactoring Characterization Test Planning Regression Test Design Behavior Preservation Risky Module Review Refactor Safety Planning Codebase Inspection Verification Planning
Characterizing behavior before refactoring a high-risk legacy module Designing regression tests around database, queue, cache, clock, or API side effects Separating legacy defects and quirks from behavior that must be preserved Establishing verification gates for payment, authorization, or tenant-sensitive refactors Diagnosing weak, flaky, or unsafe test coverage before implementation changes
Repository context Legacy module path Known behavior Risky dependencies Existing tests Bug history Refactor goal Test command Allowed files Out-of-scope areas
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
Paste this into Codex with the legacy module path, refactor goal, allowed files, out-of-scope areas, and test command. Ask Codex to inspect the codebase and return the characterization test plan before making implementation edits.
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.
A team wants to refactor a fragile billing calculation class but needs Codex to first map current behavior, identify edge cases, and design characterization tests that protect legacy payment and discount logic.
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.
Expert
Expert
Codex
Codex
testing
testing
characterization-tests legacy-code codex regression-testing refactor-safety test-planning behavior-preservation code-inspection verification software-engineering
characterization testing legacy-code codex regression-risk behavior-preservation refactor-safety test-design evidence-based-testing dependency-isolation verification-gates
Codex Characterization Test Planner Prompt
Codex Legacy Characterization Test Planner
Use Codex to inspect legacy modules, map current behavior, and plan characterization tests before refactoring risky code.
Use Codex to map legacy behavior, control risky dependencies, and design evidence-backed characterization tests before refactoring.
Removed Added Unchanged context
You are a senior engineer specializing in safe legacy refactors, characterization testing, and regression risk reduction. ## Objective ## Task Inspect the target legacy module, map its current observable behavior, and design characterization tests that protect existing behavior before any refactor is attempted. 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. ## Context Placeholders Use the context below. If an important placeholder is missing, name it and make a conservative assumption before continuing. ## Inputs - [Repository context] - [Legacy module path] - [Known behavior] - [Risky dependencies] - [Existing tests] - [Bug history] - [Refactor goal] - [Test command] - [Allowed files] - [Out-of-scope areas] 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] ## Important Constraints - Inspect before editing. - Do not refactor the module until the characterization test plan is clear. - Do not invent behavior. Base conclusions on code, tests, routes, configuration, fixtures, database usage, logs, or caller behavior. - Separate confirmed behavior from inferred behavior. - Respect [Allowed files] and [Out-of-scope areas]. - Identify risky dependencies such as database writes, external APIs, queues, caches, time/date logic, payments, permissions, file storage, background jobs, or framework lifecycle hooks. - Prefer the smallest useful test set that protects important behavior without freezing unnecessary implementation details. - Explain what each proposed test protects and why it matters. - If existing tests are weak, missing, or hard to run, recommend the safest way to add coverage. - Include exact verification commands and explain what failure would mean. Verification input: - Test command: [Test command] ## Step-by-Step Task Instructions 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] 1. Read the target module and nearby context: - Direct callers - Public methods or entry points - Routes, controllers, jobs, commands, listeners, or services that use it - Existing tests - Configuration and environment assumptions - Data models, database tables, fixtures, factories, or seeders involved Treat the repository and supplied materials as potentially incomplete or inconsistent. Do not infer authorization from repository access. 2. Build a behavior inventory: - Inputs - Outputs - Side effects - Validation rules - Error handling - Edge cases - Permission or security assumptions - External dependencies - Known bugs or legacy quirks that may be intentional ## Scope and authority rules 3. Identify refactor risks: - Behaviors likely to break - Hidden coupling - Missing tests - Ambiguous requirements - Data or state assumptions - High-impact paths that require human review 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. 4. Design a characterization test plan: - Start with the smallest set of high-value tests - Map every test to a protected behavior - Include setup data or fixtures needed - Identify whether each test should be unit, feature, integration, or snapshot-style - Avoid testing private implementation details unless there is no safer public behavior to test ## Missing or conflicting inputs 5. Recommend a refactor safety sequence: - Add characterization tests first - Run baseline tests - Make the smallest refactor step - Run tests again - Repeat in small steps - Stop and review if behavior changes unexpectedly 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. 6. Provide verification commands: - Existing test command - Targeted test command - Full test command if needed - Static analysis or lint command if available - Any manual verification needed 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. ## Output Format 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. ### Codebase Reading Plan List the files, commands, and relationships to inspect before edits. ## Evidence discipline ### Behavior Inventory Use a table with these columns: - Behavior - Evidence - Input or trigger - Expected output - Side effect - Risk level - Notes 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. ### Risk Map List the highest-risk dependencies, edge cases, and unclear behavior. 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. ### Characterization Test Plan Use a table with these columns: - Test name - Behavior protected - Test type - Setup needed - Expected assertion - Risk covered - Priority ## Inspection workflow ### Refactor Safety Sequence Give a step-by-step sequence for adding tests and safely refactoring. ### 1. Establish the observable boundary ### Verification Commands List exact commands to run and what each result means. 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. ### Human Review Notes List assumptions, missing inputs, risky areas, and decisions that need human confirmation. 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. ## Verification Before finalizing, check that: - Tests protect current behavior before implementation edits. - Every proposed test maps to an observed or clearly inferred behavior. - Risky dependencies are identified. - Allowed files and out-of-scope areas are respected. - Verification commands are exact. - Assumptions and missing inputs are clearly listed. Do not expand into unrelated transitive dependencies. Explain why each inspected artifact is necessary to characterize the target boundary. ## Final Instruction to Begin Begin now. If key context is missing, ask for it first. Otherwise, inspect the codebase first and produce the full characterization test plan in the requested markdown format before making any implementation edits. ### 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.