← Back to journal

From Changed Symbols to the Tests That Can See Them

A workspace symbol map can connect bindings, imports, reverse paths, and focused tests—but incomplete discovery must remain visible.

Evidence basisKodeProof persistent symbol-map and affected-test mapping implementation history
DisclosureStatic impact analysis is bounded by supported languages, resolvable edges, dynamic loading, and the project’s existing tests.
Published by Kalu KodeApply for KodeProof private alpha →

Running every test after every candidate edit is simple and sometimes necessary. It can also be slow enough to discourage tight verification loops.

Focused tests are useful when the selection has a source-backed explanation and incompleteness cannot masquerade as coverage.

Begin with symbol identity

File-level change lists are coarse. A module can export several unrelated bindings, and a small refactor may affect only one.

A workspace symbol map can record:

  • declarations and lexical identity;
  • type and value roles;
  • imports, re-exports, and local aliases;
  • call and reference relationships;
  • module resolution;
  • tests and their dependency paths;
  • file fingerprints and freshness.

Persistent indexing avoids rebuilding the whole graph for every bounded transaction, while source hashes prevent stale entries from being trusted.

Reverse paths explain selection

Given a changed source or binding, the system can traverse reverse imports and references toward tests.

Each selected test should carry at least one deterministic shortest reason, such as:

changed binding → exporting module → consumer → test

The reason makes review possible. An engineer can see whether the test exercises a direct consumer or arrives through a broad shared utility.

Dynamic edges create gaps

Static analysis cannot always close:

  • computed dynamic imports;
  • framework scanners;
  • generated test registries;
  • runtime plugin discovery;
  • unparseable source;
  • unresolved aliases;
  • external package behavior;
  • tests selected by non-source metadata.

When a relevant source cannot be discovered or parsed, the mapping status should be incomplete. Returning a small test list with a green “affected tests found” label would overstate confidence.

Focused tests do not replace the project gate

During candidate iteration, affected tests provide fast feedback. At transaction completion, the contract may still require the full test suite, typecheck, lint, or build.

This separation supports proportionate work:

  • run focused tests after each bounded patch;
  • escalate when shared or dynamic surfaces are touched;
  • run the configured completion gate before transfer.

The transaction record can show both layers.

Baseline failures need classification

A selected test may already fail before the refactor. The candidate should not be blamed for unchanged baseline debt, but the transaction also should not report an unqualified pass.

Running the before-state under the same gate helps classify:

  • candidate regression;
  • existing failure;
  • environment instability;
  • nondeterministic test;
  • harness error.

This is especially important when an agent is optimizing for a green check and might otherwise repair unrelated baseline debt outside scope.

Symbol maps help beyond testing

The same graph can support:

  • consumer closure for moves and renames;
  • public-export protection;
  • cycle detection;
  • direct-import enforcement;
  • structural planning;
  • context packets for an agent;
  • review of cross-package blast radius.

Its authority remains mechanical and bounded. It does not decide what a symbol means or whether two implementations are behaviorally equivalent.

KodeProof uses symbol and test impact evidence to shorten feedback loops without shrinking the truth. A focused test set is useful when it comes with a reason, a freshness boundary, and an explicit statement of what the graph could not see.