The problem: AI's Salesforce knowledge is structurally stale
Salesforce ships three releases a year. Large language models are trained on data that's 6–18 months old. So there's a permanent gap: by the time a model "knows" a Salesforce pattern, the platform has often moved on.
The result is code that looks right and compiles, but uses patterns from two or three releases ago. And the cruel part is that the most recently changed things — security defaults and API versions — are exactly the ones models get wrong, because that's the freshest knowledge and the last to make it into training data.
A few examples I see constantly from Claude, GPT, and Copilot:
-
WITH SECURITY_ENFORCEDon SOQL — superseded by User Mode (WITH USER_MODE). - DML without an access level — instead of
Database.update(records, AccessLevel.USER_MODE). -
System.assertEquals(...)— the legacy assertion API; the modernAssertclass (Assert.areEqual,Assert.isNull) shipped in Winter '23. - Workflow Rules / Process Builder — both retired; everything should be Flow.
- API versions in the v50s on new classes, when current is v67.0.
None of these are exotic. They're the defaults a senior dev would flag in code review. But an autonomous AI pipeline doesn't have that reviewer — it has its own (stale) priors.
The fix: give the agent current ground truth
llms.txt is an emerging convention: a Markdown file at a known location that tells AI agents how to use your content. I used it to build sf-llms-context — a small, opinionated Salesforce knowledge base aimed squarely at coding agents.
Design principles:
- AI-first, not human-first. Every file opens with a one-line instruction for the agent, then dense structured content. No marketing, no navigation chrome.
- Show wrong AND right. Every deprecated pattern sits next to the current one, with the reason (governor limit / security / deprecation).
- Token-efficient. Brevity is a feature. Every pattern is a few hundred tokens, max.
- Verified, not guessed. Every governor-limit number and API version is checked against the official Summer '26 (v67.0) docs. (I even caught a limit I'd carried over that Salesforce removed in API v57.0 — verification matters.)
Does it actually change the output?
I ran a controlled test across three models — Opus 4.8, Sonnet 4.6, and free ChatGPT — each given the same user story, with and without this context file:
"When an Account's Industry changes, copy the new value to a field on every child Contact. Include tests."
I have to be honest about the result, because it surprised me: the models are good. Every no-context run produced one logic-free trigger delegating to a handler, with sharing, and bulkified maps. One even added an async Queueable fallback for accounts with thousands of child Contacts. If I cherry-picked a strawman, the first reader to reproduce it would catch me.
But line them up and a consistent gap appears:
| Model (no context) | SOQL/DML mode | Assertions |
|---|---|---|
| Opus 4.8 | system mode | modern Assert
|
| Sonnet 4.6 | system mode | legacy System.assertEquals
|
| GPT (free) | system mode | legacy System.assertEquals
|
All three defaulted to system-mode SOQL and DML — no FLS, CRUD, or sharing enforcement on the operation. On Summer '26 (API v67.0), the secure default is User Mode:
// default output — system mode
for (Contact c : [SELECT Id, AccountId, Account_Industry__c
FROM Contact WHERE AccountId IN :changedIds]) { ... }
update contactsToUpdate;
// with the context file — user mode
for (Contact c : [SELECT Id, AccountId, Account_Industry__c
FROM Contact WHERE AccountId IN :changedIds
WITH USER_MODE]) { ... }
Database.update(contactsToUpdate, AccessLevel.USER_MODE);
Update — Summer '26 (v67.0) is now GA: Salesforce just made this the platform default. As of API v67.0, database operations run in User Mode by default and Apex classes default to with sharing. So on a v67.0 class a bare query is already User Mode — explicit WITH USER_MODE is now about clarity and back-compat with v66.0 and earlier. These models were tested on the pre-v67.0 platform, where system mode was still the default. The platform moving exactly this way is the strongest possible confirmation that security defaults were the gap worth closing.
Two details made the test more interesting than a simple before/after:
-
The value isn't uniform. Opus already uses the modern
Assertclass unprompted; Sonnet and GPT still emitSystem.assertEquals. The older the model, the more the context earns its keep. (Embarrassingly, my own examples usedSystem.assertEquals— so the content was reinforcing the legacy style. Fixed that.) -
Context isn't magic. With the file loaded, GPT adopted the explicit access-mode syntax but chose
SYSTEM_MODE— the opposite of secure. A model still has to apply what it reads. That fed straight back into the repo: I rewrote the "default to User Mode" guidance to be impossible to misread.
The takeaway isn't "AI can't write Apex." It clearly can. The gap is narrow and sharp: security defaults lag the platform, and that's the worst place for a gap, because system-mode DML compiles, passes its tests, and reviews clean. Nothing flags it until a security review — or an audit — does.
Why this matters more as workflows get autonomous
The interesting frontier in Salesforce dev right now is fully AI-driven workflows: hand an agent a user story, get back a tested, code-reviewed feature. But every stage in that pipeline — architect, implement, test, review — trusts the model's baseline knowledge. If that baseline is stale, the agent can pass its own tests and its own code review and still ship a deprecated pattern. The tests are green; the pattern is just old.
A ground-truth context file is the cheapest possible guardrail for that.
Try it
It's free and open:
- One-fetch context (tools with web access):
https://sf-llms-context.github.io/llms-full.txt - No web access (e.g. free ChatGPT)? Paste the content or upload the file — the URL alone gets silently ignored.
- Browse or contribute: https://github.com/sf-llms-context/sf-llms-context
If your AI tool still generates a wrong Salesforce pattern, there's an issue template for it — that feedback is exactly what keeps this current across releases.
Top comments (0)