Code forensics and traceable findings

Code forensics: what a code investigation can establish

What code forensics can establish: revision, change history, dependencies, reproducible checks and the limits of an investigation.

I use code forensics here to mean a traceable technical investigation of existing software. It connects source code, change history, dependencies and agreed project evidence to answer specific questions. What matters is how a finding was established and which conclusion it supports.

If you use that evidence to decide on modernization or stabilization, a list of tool warnings is not enough for me. I want to identify the version examined, the checks performed and the significance for the system. The limits need to be equally clear. A noteworthy section of code is initially a reason to look more closely.

Establish exactly which version is being examined

The first question is which version the investigation concerns. Current development, the last deployed version and a failed release may differ. A finding about the wrong version offers little help in understanding the cause.

I would record the repository, specific revision and connection to the release concerned. Relevant configurations and analysis tool versions also belong in the record. In a later comparison, it needs to be clear whether the system changed or only the checks did.

A branch name alone is insufficient for that purpose. After further changes, it may point to a different commit. I use a specific commit for the technical reference and document which data snapshot the conclusion applies to. (Git references and revisions)

The same applies to supporting material. A test report or failure log needs to be linked to the version examined. If that connection is missing, the conclusion must reflect that limitation.

An observation does not yet establish a cause

Consider a hypothetical import process. The code has no apparent safeguard against processing the same message repeatedly. There is also a report of duplicate records.

Those observations may be related. Further checks are needed to establish whether this caused the reported failure. An upstream service may prevent repeated messages. A database constraint may apply. The failure report may also describe a different processing path.

I would therefore describe the finding precisely: which location was examined, which safeguard exists there, and which safeguard is not apparent within the agreed scope? The possible consequence follows, under stated conditions. Assigning a cause requires further evidence.

That distinction matters for decisions. An established cause calls for a different next step from a plausible explanation or an unanswered question about another system.

History provides context

Change history can show which areas were frequently modified together or needed further corrections after a release. That helps narrow down a deeper investigation. I would not derive a quality judgment from the number of changes alone.

Assigning lines of code to a commit also has a limited meaning. It initially shows which revision last changed each line. It explains neither the decision made at the time nor the entire development history. (Git documentation on blame)

Architecture knowledge and discussions with the team therefore belong in the investigation. A noteworthy change may have reflected a business requirement, an interface change or a necessary correction. The context determines what significance the pattern has.

A technical investigation should help the team understand risks. I do not consider such a metric sufficient evidence to judge an individual's performance.

Check tool findings against the system

Static analysis, tests and dependency checks examine different aspects of software. I would interpret their results together and state what each check covered. Running a tool does not tell me whether the specific investigation question has been examined sufficiently.

For tests, I want to understand which behavior they protect. High coverage alone does not establish high code quality. An important conclusion therefore also needs an examination of the inputs, failure paths and expectations being checked. (Microsoft on test quality)

For dependencies, looking only at directly referenced libraries is also insufficient. In a .NET application, those libraries can introduce further packages. The versions used through those dependencies belong in the investigation. (Microsoft on direct and transitive packages)

A reported risk then needs context within the system. Relevant points include the affected component, how it is used and the possible consequence. Anything not yet checked must remain explicit in the result.

Make a finding understandable to someone else

A useful finding can be followed using the agreed evidence and documented checks. That does not require the largest possible collection of screenshots. It requires a clear connection between the question, the observation and the conclusion.

The investigation should therefore start with the relevant repositories and releases, architecture material, build and test configurations, known failure patterns and responsible contacts. Access rights and confidentiality are agreed beforehand. The report should contain no secrets or unnecessary personal information.

For each prioritized finding, I record its source, version, checks, observed discrepancy and limits. This provides the basis for a next step: a reproducible test, an additional check or a defined change.

If the available data leaves the cause unresolved, that belongs in the result. A repository assessment does not automatically establish the observed behavior of a running environment. Runtime investigations require their own agreed scope.

Which questions your report should answer

  • Which version and evidence does the finding concern?
  • What was observed, and how can another person follow the checks?
  • Which explanation is established, and which remains a hypothesis?
  • Under which conditions does it create a relevant risk?
  • Which information is still missing for a decision?
  • Which next step is justified, and how will its result be checked?

Those questions also shape my Forensic Code Assessment. Technologies, investigation questions and depth of analysis are agreed beforehand. The investigation provides a technical decision basis; subsequent implementation needs a separate agreement.

For a business decision, I want to see which conclusion has sufficient support and where further investigation is needed. That makes it possible to explain why an area should be stabilized first, a change needs safeguards, or an assumption should be examined before a larger investment.

The appropriate next step

If the signals described here match your situation, the related service is linked below. You can also tell me what prompted your enquiry. In our first conversation, we will clarify whether and to what extent I can help.