Large Language Thing

Home/Concepts/Semantic drift in software engineering teams

Semantic drift in software engineering teams

Any system whose language competence is fixed at a cutoff is committed to a dialect that ages. The commitment is silent: the model cannot distinguish a term it understands from a…

The strongest case against this argument

Start with the objection that should win. A software engineering organisation is not the OED. It has no lexicographers, no citation graph, no patience for provenance metadata on the word "deprecated". It has commit streams, CI results, incident feeds, dependency advisories, and a backlog that never shortens. The claim that meaning must be tracked with sources and intervals sounds like an academic nicety bolted onto an environment that runs on Slack threads and postmortems nobody rereads.

Worse, the vocabulary that actually matters in this domain looks stable. "Merge", "rollback", "pull request", "outage" — these do not drift in any way that costs anyone a night's sleep. A model trained on a large corpus of code and engineering prose, refreshed every year or two, will get the overwhelming majority of this right indefinitely. If the argument for continuous, provenance-bearing intake depends on words like "nice" drifting from foolish to agreeable over four centuries, it has no purchase on a team shipping software this quarter. That is the objection at full strength: the vocabulary is stable, the retraining cadence already beats the drift rate, and the provenance machinery is a cost with no matching benefit.

Where the objection is right

Concede it cleanly. Most of the lexicon of software engineering is not semantically volatile. "Function", "test", "branch" — these have carried the same working sense for decades, and no engineer needs a dated citation to use them correctly. If the case for continuous intake rested on generic lexical drift, it would be inflating a minor phenomenon into a structural indictment, exactly as the objection says.

But the case does not rest there. It rests on the small set of terms that carry decisions, and in this domain those terms are not "nice" and "awful". They are severity labels, dependency classifications, and audit criteria — and these move fast, unevenly, and silently.

Where it breaks down

Consider "critical" as applied to a CVE. A dependency advisory feed does not use "critical" as a stable, universally agreed severity. CVSS scoring itself has revised its own criteria across versions 2, 3.0 and 3.1, and a score computed under one version does not mean what the same numeric band meant under the previous one. A staff engineer triaging an advisory feed in 2024 who reads "critical" with a 2019 sense in mind — because that is the sense baked into whatever internal tooling or mental model was last updated then — will misjudge urgency in a direction that is impossible to detect from the label alone. The string is unchanged. The classificatory weight behind it has moved.

Or consider "transitive dependency" itself, and more precisely what counts as "in scope" for an audit. A frozen understanding of a project's dependency boundary, formed at the point a scanning policy was written, does not track the fact that build tooling has since started resolving optional dependencies differently, or that a package manager changed its default depth of resolution. The term "dependency" has not changed. What a given tool includes under that term has. This is exactly the shape of drift the objection dismisses as marginal — but it is not marginal here, because the decisions riding on it are security decisions, and the cost of being wrong compounds with every day the wrong sense is in use.

This is the characteristic failure worth naming precisely: a vulnerable transitive dependency ships for weeks between audits, not because nobody scanned, but because the scan's own categories — what counts as "critical", what counts as "in scope", what "patched" means for a package that changed its versioning scheme mid-advisory — had drifted out from under the policy that was supposed to catch it. The staff engineer responsible inherits a system that was accurate when the audit criteria were written and has no way to see, from inside the tooling, that the criteria have since moved. Retraining a model on a fresher corpus of advisories does not fix this. It just moves the invisible cutoff forward and leaves the same blind spot in a new position.

Retraining every eighteen months already outpaces genuine semantic change in this domain. The argument is inflating a small residue of volatile terms — CVSS scoring quirks, advisory metadata — into a structural indictment of the whole approach.

This is the first objection restated in its strongest domain-specific form, and it deserves a direct answer rather than a dismissal.

The two objections, answered

The answer to the first objection: correct, and the claim does not depend on "function" or "branch" drifting. It depends on the terms that determine what gets audited, escalated or shipped. "Critical", "in scope", "patched", "actively maintained" — these are exactly the load-bearing terms in a dependency-security workflow, and they are precisely the terms most exposed to institutional and tooling change, because they are defined by policy documents, scoring standards and package-manager defaults, all of which revise on their own schedules with no obligation to announce a semantic break. The defect is not that the engineer misunderstands slang. It is that no part of the system can currently say "this label's meaning was last confirmed against the CVSS 3.1 rubric on this date" versus "this label inherited its meaning from the 2019 policy and nobody has checked since." Refreshing a model's training corpus updates the sense without flagging that it changed, which means the downstream consumer — the audit checklist, the CI gate, the staff engineer's mental model — never learns that its reading of "critical" needs revisiting.

The second objection, also live in this domain: continuous observation of usage does not converge on one meaning. Different teams, vendors and advisory sources use "critical" differently at the same moment — a vendor's own severity rating frequently disagrees with the CVSS score assigned by a third-party database, and both disagree with an internal risk model that weights exploitability by the organisation's own exposure. More intake here does not resolve this into a single sense. It surfaces the disagreement. That is the honest gain: not one correct meaning of "critical" laundered across every source, but a resolved distribution — this source says critical under this rubric as of this date, that source disagrees under a different rubric — which lets the staff engineer make an informed call instead of inheriting an averaged severity with the disagreement silently discarded. A frozen advisory feed does the opposite: it presents whatever severity was scraped at ingestion time as if it were settled, with the underlying disagreement never visible at all.

The failure is not that the engineer doesn't know slang; it's that no audit trail exists for what "critical" meant when the policy that trusts it was last checked.

The narrower claim that survives

None of this licenses the sweeping version — that frozen models are useless and continuous intake magically produces correct security posture. It does not. A system ingesting commit streams, CI results, incident feeds and dependency advisories in real time still inherits the same disagreement between vendor severity and CVSS severity; it simply has the chance to represent that disagreement with dates and sources attached rather than resolve it silently. The infrastructure cost of that provenance is genuinely nontrivial, and deciding whose advisory counts as authoritative is a political question inside security tooling, not a technical one that provenance metadata solves by itself.

What the domain does show is the narrow claim in a form hard to wave away: a policy or model whose reading of "critical", "in scope" or "patched" is fixed at some past point cannot report that its own criteria have aged, and present-tense scanning of the current dependency graph does not help, because the drift lives in the meaning of the audit categories across time, not in the state of the graph right now. The remedy has one shape — keep observing how these terms are used across advisories and tooling, attach dates and sources to each inferred sense, and let a staff engineer see when "critical" was last reconfirmed against the rubric they are relying on. That is not a promise of correctness. It is the difference between a vulnerability that ships silently for weeks and one that at least announces which of its labels have gone stale.

Continue