Answers Salesforce developer code-quality questions: "audit my Apex for quality issues", "find governor-limit risks", "where do we have hardcoded IDs / emails / usernames", "check CRUD / FLS enforcement", "what tests are missing / fake-covered", "find dead code", "review this Apex class", "what methods does this class have". Drives the v2.1 quality-recognizer cascade (`code_quality_audit`, `governor_limit_risks`, `find_hardcoded_values`, `crud_fls_audit`, `test_coverage_gaps`), the v2.4 hygie...
Scanned 9/3/2026
Install to Claude Code
npx -y skills add PranavNagrecha/Salesforce-Intelligence --skill developer-code-quality --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Developer Code Quality?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/pranavnagrecha-developer-code-quality)More formats (shields.io, HTML) on the badges page.
---
name: developer-code-quality
description: |
Answers Salesforce developer code-quality questions: "audit my Apex
for quality issues", "find governor-limit risks", "where do we have
hardcoded IDs / emails / usernames", "check CRUD / FLS enforcement",
"what tests are missing / fake-covered", "find dead code", "review
this Apex class", "what methods does this class have". Drives
the v2.1 quality-recognizer cascade (`code_quality_audit`,
`governor_limit_risks`, `find_hardcoded_values`, `crud_fls_audit`,
`test_coverage_gaps`), the v2.4 hygiene tool `find_dead_code`, and
`apex_structure` for a question about ONE named class or trigger
(parsed on demand; adds AST-only checks at `confidence: 'parsed'`).
Every recognizer finding is `confidence: 'heuristic'` — pattern
recognition is recognition, not declaration; only `apex_structure`'s
eight AST-only checks rise above that. Discloses the v2.1 boundary verbatim:
the recognizer pattern-matches on tokenized Apex source (not a compiler AST),
so cross-class blindness, custom security utility helpers invisible, dynamic
SOQL invisible, reflective field access invisible, custom test-assertion
frameworks invisible. (Note: Apex extraction itself uses a parser-grade AST by
default for confidence: parsed edges; the recognizer's scope is narrower.)
---
# Developer code quality
## Overview
This skill is the developer persona's companion to the v2.1 quality
recognizer family and the v2.4 hygiene tools. The developer's
first-line question is one of six shapes — "what's broken in this
Apex", "where will I hit governor limits", "where are my hardcoded
values", "what's missing a CRUD/FLS check", "what tests are fake or
missing", "what code is dead" — and the honest answer is a **cascade**
of pattern-recognized findings, each tagged with `severity` and
`confidence: 'heuristic'`. The skill teaches Claude how to drive the
cascade, present severity-bucketed findings clearly, and surface the
recognizer's blind spots verbatim so the developer doesn't act on a
finding that's a false positive without verifying.
The recognizer catalog is declared in one place — the product's
`code-quality-patterns` module — and nowhere else. Every recognizer's
output rides in `properties.qualityIssues[]` on the parent ApexClass /
ApexTrigger node: the MCP tools READ this mirror, they do not re-run the
recognizer at request time.
Two absences, and they are NOT the same answer:
- **Flow is not Apex.** The recognizers read Apex syntax, so no Flow ever
carries a `qualityIssues` finding, on any vault, after any refresh.
`sfi.code_quality_audit` names this in `notCheckedTypes` and points at
the Flow-side tools (`sfi.flow_bulkification_audit`,
`sfi.flow_fault_audit`). Never report a Flow as clean on this basis.
- **A vault built before a type was scanned.** Its nodes carry no
`qualityIssues` property at all. Every tool that composes over the
mirror says so by name in `boundaries[]` and in `qualityScanCoverage` —
`sfi.code_quality_audit`, `sfi.crud_fls_audit`,
`sfi.governor_limit_risks`, `sfi.find_hardcoded_values`,
`sfi.find_hardcoded_values_anywhere`, `sfi.tech_debt_score` and
`sfi.test_coverage_gaps` (whose zero-gap answer is exactly what an
unscanned test-class set produces). `sfi.explain_apex_method` carries
the same distinction in its `disclosure` instead. The fix is
`sfi refresh`. An empty `issues` list on such a vault is "not checked",
NOT "nothing to report" — surface the boundary rather than the zero.
The boundary that matters for developers: **the quality recognizer
is a pattern matcher, not a compiler AST.** It tokenizes Apex source
(string-stripped) and pattern-matches on the output. Dataflow analysis,
control-flow analysis, type-inference, cross-class transitive analysis,
custom security utility helpers, and dynamic SOQL all return as false
positives or false negatives. (Note: Apex extraction uses a parser-grade
AST for graph edges; this recognizer's constraint is its own scope.)
The skill surfaces the boundary disclosure verbatim on every finding.
`sfi.find_dead_code` and `sfi.governor_limit_risks` carry a `soundness`
envelope (`complete` / `blindSpots[]` / `staticCoverage`): when a candidate
or scanned class uses dynamic Apex they return `complete: false` with a
`dynamic-apex` blind spot naming those classes. A `dead` verdict (or a clean
governor scan) on a flagged class needs a human read of the source — a
reflectively-invoked method looks dead, and a SOQL BUILT from string
concatenation (`Database.query('SELECT ' + f + ...)`) is invisible to
the recognizer. (Field references in inline static SOQL and
constant-string `Database.query` literals ARE resolved into
parsed-confidence edges by the default-on Apex AST pass, so a field
used only inside such a query does not look dead.)
## Baseline suppression (v4.0)
When the user says a CRUD/FLS or governor-limit finding is a known false
positive, call **`sfi.baseline_acknowledge`** with the exact `tool`, `rule`,
`componentId`, and `location` from the finding. Re-running
`sfi.crud_fls_audit` or `sfi.governor_limit_risks` then excludes it and
reports `suppressedFindingCount` / `suppressedRiskCount`. Use
**`sfi.baseline_status`** to list what is muted.
## When to fire
Fire this skill on quality / hygiene phrasing. Concrete triggers:
- **"Audit / check Apex quality."** — "audit my Apex for quality
issues", "code quality check on `OpportunityService`", "what
quality issues does this org have".
- **"Find governor-limit risks."** — "find governor-limit risks",
"where do we have SOQL in loops", "DML in loops", "show me
bulkification risks", "what runs SOQL inside a `for` loop".
- **"Find hardcoded values."** — "where do we have hardcoded IDs",
"find hardcoded emails", "show me hardcoded usernames", "find
sandbox-specific test data".
- **"CRUD / FLS check."** — "audit CRUD / FLS enforcement", "what
DML is missing a `Schema.sObjectType` check", "find SOQL without
`WITH SECURITY_ENFORCED`".
- **"Test quality."** — "where are tests missing", "what tests have
no real assertions", "find fake-coverage", "what tests don't
assert anything", "show me low-quality test coverage".
- **"Find dead code."** — "what code in this org is dead", "find
classes nobody calls", "what fields have no readers/writers",
"what's safe to delete".
- **"Tech debt."** — "give me a tech-debt score", "where's the
worst code in this org". Defer this to `sfi.tech_debt_score`
but use this skill's cascade as the deeper drill-in.
## When NOT to fire
Defer to another skill when:
- **The user asks "what breaks if I change X?"** That's
cross-component impact analysis. Defer to
`architect-impact-analysis` → `sfi.get_impact`.
- **The user asks "where is `X` used in Apex?"** That's a code
reference question. Defer to `developer-apex-refactor` →
`sfi.find_code_usages`.
- **The user asks "what tests cover this method?"** That's a
reachability question. Defer to
`developer-impact-and-reachability` →
`sfi.test_coverage_for_method`.
- **The user wants live data** ("how many SOQL queries did
`OpportunityService` make today?"). v2.1 is offline.
- **The user wants the recognizer to FIX the issue.** v2.1 is
read-only; it surfaces findings but never writes a rewrite.
- **The user wants frontend (LWC / Aura / VF) quality checks.**
v2.1 scopes to Apex + Flow. Frontend quality is deferred.
## The cascade
The six org-wide tools run in this order from broad to narrow. Each
one narrows the same `qualityIssues[]` mirror to a different lens.
Pick the right entry point by user intent.
**When the question is about ONE class or trigger, start at
`sfi.apex_structure` instead** (§7). The six below all read the
extraction-time recognizer mirror, which is a tokenizer, not a
compiler AST. `sfi.apex_structure` parses the `.cls` / `.trigger` on
demand and adds checks the recognizer catalog cannot express — at
`confidence: 'parsed'` rather than `'heuristic'`.
### 1. `sfi.code_quality_audit` — broad sweep
The general-purpose entry point. Composes `listNodesByType` over
every ApexClass / ApexTrigger node, reads each node's
`qualityIssues[]` property, applies optional severity / rule /
per-class filters, sorts by severity DESC then id ASC, and returns
the limited list + per-severity and per-rule summary counts.
Default invocation (top-priority sweep):
```json
{ "severityFilter": "all", "limit": 50 }
```
Severity narrowing:
```json
{ "severityFilter": "critical", "limit": 50 }
{ "severityFilter": "high", "limit": 100 }
```
Per-class narrowing — the canonical key is `componentId` (an
`ApexClass:` / `ApexTrigger:` id; `classApiName` / `apiName` take a
bare class name, and `componentFilter` is accepted as an alias for the
same scope):
```json
{ "componentId": "ApexClass:OpportunityService" }
```
A scoped response echoes `appliedScope: { component, mode: "component" }`.
**A response with NO `appliedScope` key is the ORG-WIDE audit** — if you
asked for one class and got no `appliedScope`, do not present the
findings as that class's. The schema is `.strict()`, so a mis-spelled
scope key returns `invalid-query` rather than silently widening the
audit; report the error, don't retry with a guess.
Rule narrowing (useful when the user wants ONE specific pattern
across the org) — `ruleFilter` is an ARRAY of rule ids, never a bare
string:
```json
{ "ruleFilter": ["soql-in-loop"], "limit": 100 }
```
Fire this tool when the user asks the broad question ("audit my
Apex", "what quality issues does this org have"). Use the
per-severity summary to lead the response — `critical` and `high`
findings get foreground attention; `medium` and `low` get sectioned
below; `info` is suppressed by default unless explicitly requested.
### 2. `sfi.governor_limit_risks` — performance / scale narrowing
Narrows the catalog to the three governor-limit-relevant rules:
`soql-in-loop`, `dml-in-loop`, `database-upsert-no-options`. Groups
findings by class. When the parent class is the target of an
incoming `callsApex` edge from an ApexTrigger, surfaces the
trigger as `triggerContext` — a class flagged with SOQL-in-loop
that's called from a trigger multiplies the limit risk per
trigger invocation.
Default invocation:
```json
{ "limit": 50 }
```
Fire this tool when the user asks the performance question — "find
governor-limit risks", "what won't bulkify", "show me SOQL in
loops". Use the `triggerContext` array to prioritize: triggers
fire on every DML batch, so a SOQL-in-loop inside a trigger's
handler class is more urgent than the same pattern in a batch job.
### 3. `sfi.find_hardcoded_values` — literal-search narrowing
Narrows the catalog to the four hardcoded-literal rules:
`hardcoded-id`, `hardcoded-email`, `hardcoded-username`,
`hardcoded-sandbox-test-data`. Returns each match's location and
the literal value the recognizer saw.
Category narrowing:
```json
{ "category": "id", "limit": 100 }
{ "category": "email" }
{ "category": "username" }
{ "category": "sandbox-data" }
```
Fire this tool when the user asks about hardcoded values directly
("where are hardcoded IDs / emails", "find sandbox-specific
literals"). When a finding's parent ApexClass has `isTest: true`,
ALWAYS surface the refusal-pattern disclosure: "this is a test
class — hardcoded IDs / emails / sandbox URLs may be intentional
test fixtures; verify before treating as a bug." The recognizer's
own `boundaries[]` carries this disclosure verbatim; echo it.
For `id` matches outside the allowlist of ~40 known Salesforce key
prefixes (001, 003, 005, 006, 00Q, 00e, 0PS, etc.), the recognizer
suppresses the finding entirely — so a finding you see IS shaped
like a Salesforce ID. Strings shaped like an ID that aren't actually
IDs (session keys, hashes) may still slip through if they happen
to start with a known prefix; the heuristic confidence covers this.
For broader literal search across all metadata corpora (Apex + Flow
XML + metadata XML + formula expressions), defer to
`sfi.find_hardcoded_values_anywhere` (v2.2's universal-search tool
documented in `developer-find-anywhere`).
### 4. `sfi.crud_fls_audit` — security narrowing
Narrows the catalog to the two security-enforcement rules:
`missing-crud-check`, `missing-fls-check`. Groups findings by
class. Test classes (`properties.isTest: true`) are excluded.
Default invocation:
```json
{ "limit": 50 }
```
Fire this tool when the user asks about access enforcement ("audit
CRUD / FLS", "where is DML missing a security check"). ALWAYS
surface the Q80 verbatim disclosure on responses with findings —
custom security utility helpers (`SecurityUtils.canCreate(account)`)
are invisible to the recognizer, so the finding may be a false
positive if your org uses a helper. Cross-method dataflow is also
invisible — a method that delegates to a helper class is analyzed
in isolation.
### 5. `sfi.test_coverage_gaps` — test-quality narrowing
The three-signal composition: test-class identity
(`properties.isTest === true`), reachability via incoming **USAGE**
edges (BFS capped at depth 3 — every edge type except `parentOf` and
`grantedBy`, the same deny-list `method_reachability` and
`find_dead_code` use; a `callsApex`-only walk called live classes
uncovered), and assertion meaningfulness (via the `fake-assertion`
rule in the recognizer catalog). Classifies each non-test ApexClass
into one of three verdicts:
- **`uncovered`** — no test class reaches it within the depth cap.
- **`fake-coverage`** — every covering test class is flagged with
`fake-assertion`; the class IS reached but the coverage is
meaningless.
- **`low-quality-coverage`** — some covering test classes have
fake-assertion findings; at least one doesn't.
Default invocation (uncovered first):
```json
{ "limit": 50 }
```
Fire this tool when the user asks the test-quality question ("where
are tests missing", "what classes lack real coverage"). For a deeper
audit of WHICH test classes have fake assertions, follow up with
`sfi.meaningful_test_audit` (a sibling tool in the
`developer-impact-and-reachability` cascade).
### 6. `sfi.find_dead_code` — hygiene narrowing
The v2.4 cross-cutting dead-code surface. Cascades over v2.7's
`method_reachability` verdict, the entry-point taxonomy (REST /
Aura / Invocable / Queueable / Batchable / Schedulable / triggers),
and zero-usage detection. Returns one of three verdicts per
candidate:
- **`definitely_dead`** — zero incoming USAGE edges: every edge type
except `parentOf` (structural containment) and `grantedBy` (a
Profile / PermissionSet access grant — access is not usage). No
callers, no triggers, no listeners. For CustomField, no incoming
references at all (no formula refs, no Apex reads/writes, no Flow
record-ops, no layout placements) — AND, for an Activity/Task/Event-
family CustomField specifically (the same physical field can be
materialized as up to three graph nodes,
`CustomField:Activity/Task/Event.<field>`), no OTHER EXISTING
representation of that field has a real incoming usage edge either.
A sibling with usage this candidate does not have downgrades the
verdict to `uncertain` instead — see cause (d) below; the import-
time polymorphic mirror can under-mint or be absent, so it is not
trusted alone.
- **`likely_dead`** — reached only by test classes
(`isTest === true`) or via heuristic-only edges that may be
stripped by dynamic SOQL / reflective access.
- **`uncertain`** — four different causes, all suppressed by default
and surfaced with `includeUncertain: true`: (a) reached by at least
one EXTERNAL entry point; (b) an unproven dynamic registration — a
dotted `superclass` (another namespace's framework instantiates its
own subclasses) or a declared `Callable` interface, which have zero
incoming edges BY CONSTRUCTION and so must never be called dead;
(c) a whole-word source re-check found the class named in
production Apex through a static-field or type-name usage the
parser models as no edge; (d) an Activity/Task/Event-family
CustomField (e.g. `CustomField:Task.X` vs `CustomField:Event.X`)
whose OTHER EXISTING representation has a real incoming usage edge
this one does not — it would otherwise have read `definitely_dead`.
An Active / Draft / unknown-status Flow is also `uncertain`, never
`definitely_dead`.
Default invocation:
```json
{ "types": ["ApexClass", "ApexTrigger", "Flow", "CustomField"], "limit": 100 }
```
Type narrowing:
```json
{ "types": ["ApexClass"], "limit": 200 }
{ "types": ["CustomField"], "limit": 500 }
```
Fire this tool when the user asks the hygiene question ("what's
dead", "what can I delete"). ALWAYS pair `definitely_dead` and
`likely_dead` findings with the verbatim invisible-callers
disclosure: dynamic dispatch, reflective invocation, framework
wiring (TriggerHandler / fflib), and managed-package callers are
invisible to the graph edges this tool walks.
### 7. `sfi.apex_structure` — ONE class or trigger, parsed on demand
The per-component entry point, and the right one whenever the user
names a class or a trigger ("review this class", "what does this class
do", "list its methods", "does it enforce sharing"). It parses the
source with the ANTLR Apex grammar at request time — nothing
persisted, no refresh needed — and returns the declared methods with
rendered signatures, fields and inner types, the sharing keyword and
what it means for enforcement, every SOQL / SOSL / DML / callout /
async-dispatch site with its line, its enclosing method and whether it
sits inside a loop BODY, the declared entry-point surface, what the
component reads and writes, its covering tests, and a `review` block.
```json
{ "classRef": "AccountService" }
{ "classRef": "ApexClass:AccountService", "method": "recalculate" }
```
Two things to read before the findings:
- **`review.rulesEvaluatedHere`** names every rule that ran, so an
empty `findings` list reads as CHECKED rather than as unscanned.
- **`confidence` is per finding.** Eight AST-only checks
(`callout-in-loop`, `async-dispatch-in-loop`, `dml-before-callout`,
`database-partial-result-discarded`,
`soql-assigned-to-single-sobject`,
`no-sharing-declared-on-entry-point`,
`without-sharing-external-entry-point`,
`trigger-logic-in-trigger-body`) carry `parsed` or `declared`. The
19-rule recognizer catalog is mirrored alongside them verbatim at
`heuristic` — the same findings the six tools above return, not a
second opinion.
A parse failure returns `structure: null` and says so; it never
returns an empty structure that reads as "this class has nothing in
it". `entryPoints.checked` is the AND of "the source parsed", "the
inbound-edge query succeeded" and "the reachability walk succeeded",
so a zero there is only a real zero when `checked` is `true`.
## Honesty axes
Verbatim disclosures the skill MUST surface from each tool's
`boundaries[]` array. These ARE the recognizer's blind spots; the
developer needs them to interpret findings honestly.
### Universal (every tool's `boundaries[]`)
- **Pattern recognition is heuristic.** Every finding carries
`confidence: 'heuristic'`. The recognizer pattern-matches on the
v0.3 tokenization output (string-stripped Apex source). False
positives are expected; verify before refactoring.
- **Severity is industry-consensus, not user-tuned.** The catalog
severity (`critical`, `high`, `medium`, `low`, `info`) is fixed
in v2.1. A team that disagrees with the assignment cannot
override; per-org severity overrides are deferred to a future
milestone.
### Code-quality + governor-limit specific
- **No dataflow / control-flow / type-inference.** These recognizers
run on token patterns, not on the parser-grade Apex AST that backs
dependency-edge extraction — that AST resolves receivers and calls,
but is not a dataflow engine. So dataflow analyses ("this user input
reaches this SOQL string"), control-flow analyses ("this code is
unreachable"), and type-inference analyses ("this variable's type
doesn't match the SObject field") are NOT supported. SOQL inside a
method called FROM a loop is invisible — the recognizer scopes
to within-method-body patterns only.
- **Cross-class blindness.** A class that delegates the dangerous
operation to a helper class is analyzed in isolation. The
helper's behavior is invisible to the caller's recognizer.
- **Dynamic SOQL invisible.** `Database.query('SELECT...')` strings
are stripped before regex passes; the embedded SQL is invisible.
- **Reflective field access invisible.** `obj.get('FieldName')` and
`Schema.fieldSetMember.getFieldPath()` are not recognized.
- **Trigger framework recognition partial.** The
`trigger-without-recursion-guard` recognizer matches the
static-Boolean and static-`Set<Id>` patterns. Framework-provided
guards (fflib's TriggerHandler, custom team handlers) are
invisible — the trigger may be flagged as unguarded when it's
actually guarded by a framework base class.
### Hardcoded-value specific
- **Test-class context (refusal pattern).** Matches inside
`@isTest`-annotated classes may be intentional test fixtures.
Surface the refusal-pattern disclosure verbatim; do NOT treat
a test-class hardcoded ID as automatically a bug.
- **ID-shape allowlist.** The recognizer filters to ~40 known
Salesforce key prefixes (001, 003, 005, 006, 00Q, 00e, 0PS, etc.).
Arbitrary 15-character alphanumeric strings outside the allowlist
are suppressed. Strings shaped like an ID that aren't IDs (session
keys, hashes) may still match if they start with a known prefix.
- **Numeric category not provided.** v2.1's hardcoded-value catalog
covers IDs, emails, usernames, and sandbox-test data; generic
numeric / magic-number detection is NOT shipped (the FP rate is
too high without dataflow). Use `sfi.find_hardcoded_values_anywhere`
for cross-corpus literal search.
### CRUD / FLS specific (Q80 verbatim)
> Custom security utility methods are invisible to the recognizer;
> this finding may be a false positive if your org uses a helper
> like `SecurityUtils.canCreate(account)`. Cross-method dataflow
> is invisible — a method that delegates the dangerous operation
> to a helper class is analyzed in isolation. Dynamic SOQL
> (`Database.query(...)`) strings are stripped before pattern
> passes; the embedded SQL is invisible to the FLS recognizer.
### Test-quality specific
- **Custom assertion helpers invisible.** Assertions via helper
methods (`MyTestHelper.assertField(record, ...)`) or framework
wrappers are NOT recognized as real assertions. A class flagged
`fake-coverage` may actually have meaningful tests via a custom
assertion helper.
- **Reachability does NOT cover dynamic dispatch.**
`Type.forName('...').newInstance().method(...)` and reflective
invocation are invisible. A class genuinely tested via dynamic
dispatch will surface as `uncovered` by this heuristic.
- **Depth cap is 3.** Long-chain coverage (Test → A → B → C → D)
beyond 3 hops is invisible.
### Dead-code specific
- **Entry-point taxonomy is closed.** The taxonomy covers REST
resources, `@AuraEnabled` methods, `@InvocableMethod`,
Queueable / Batchable / Schedulable, and ApexTriggers. A class
invoked only via `EventBus.subscribe(...)`, virtual sObject
callouts, or managed-package framework wiring will surface as
`likely_dead` even when it's reachable at runtime.
- **CustomField dead-code includes layouts.** A field that's on a
layout but never read by Apex / Flow is NOT `definitely_dead` —
the layout placement counts as a reference. To find fields that
are "only on layouts but never used in business logic," use
`sfi.unused_fields_deep` as the deeper drill-in.
## Severity-aware delivery
The catalog's five-tier severity scale (`critical`, `high`, `medium`,
`low`, `info`) drives response shape. Do not flatten the cascade
into a single bullet list.
| Severity | Default delivery |
|---|---|
| `critical` | Foreground. Lead the response with these. State the rule, the location, the explanation, and the recommended fix in plain language. |
| `high` | Secondary section. Group by rule (e.g., "Missing CRUD checks (5)") and list per-class findings. |
| `medium` | Compact section. List per-class summary; offer to drill in if the user wants details. |
| `low` | Suppress by default. Surface count only ("3 `low` findings — say 'show low' to expand"). |
| `info` | Suppress by default. Mention count only when summary requested. |
When the user explicitly asks for the full list ("show me all
findings"), surface every severity. When the user is scanning ("any
quality issues?"), lead with `critical` + `high` only.
## Worked example
User: *"Audit `OpportunityService` for code quality issues."*
Claude's flow:
1. **Classify** → broad-sweep narrowed to one class. Use
`sfi.code_quality_audit` with the `componentId` class scope.
2. **Fire** `sfi.run_analysis` with `{ "name": "sfi.code_quality_audit", "args": { … } }` with
`{ "componentId": "ApexClass:OpportunityService" }`, then CHECK the
response carries `appliedScope.component ===
"ApexClass:OpportunityService"` before reporting the findings as that
class's.
3. **Receive** (illustrative):
```json
{
"data": {
"issues": [
{ "rule": "soql-in-loop", "severity": "critical", "componentId": "ApexClass:OpportunityService", "location": "method:processOpps@line47", "explanation": "SOQL query inside `for (Id oppId : oppIds)` loop", "confidence": "heuristic" },
{ "rule": "missing-crud-check", "severity": "high", "componentId": "ApexClass:OpportunityService", "location": "line89", "explanation": "DML `update opps;` without preceding `Schema.sObjectType.Opportunity.isUpdateable()` check or `WITH SECURITY_ENFORCED`", "confidence": "heuristic" },
{ "rule": "hardcoded-id", "severity": "medium", "componentId": "ApexClass:OpportunityService", "location": "line12", "explanation": "Hardcoded Salesforce ID literal `'00e000000000001'` — IDs differ between sandbox/production", "confidence": "heuristic" }
],
"summary": { "critical": 1, "high": 1, "medium": 1, "low": 0, "info": 0 },
"boundaries": ["Pattern recognition is heuristic — every finding carries confidence: 'heuristic'. False positives are expected.", "Custom security utility helpers (e.g. SecurityUtils.canCreate) are invisible to the recognizer — missing-crud-check findings may be false positives if your org uses a custom helper."]
}
}
```
4. **Respond:**
> Quality audit for `ApexClass:OpportunityService` (3 findings).
>
> **Critical (1)**
> - `soql-in-loop` at `method:processOpps@line47` — SOQL inside
> `for (Id oppId : oppIds)`. This will hit the 100-SOQL governor
> limit when called with >100 records. **Fix:** query the full
> set in one bulk SOQL outside the loop (`[SELECT Id FROM
> Opportunity WHERE Id IN :oppIds]`) and iterate the result.
>
> **High (1)**
> - `missing-crud-check` at `line89` — `update opps;` without a
> preceding `Schema.sObjectType.Opportunity.isUpdateable()` check
> or `WITH SECURITY_ENFORCED` on the source SOQL. **Fix:** add a
> CRUD check before the DML, OR add `WITH SECURITY_ENFORCED` to
> the query that produced `opps`.
>
> **Medium (1)**
> - `hardcoded-id` at `line12` — literal `'00e000000000001'`. Profile
> IDs differ between sandbox and production. **Fix:** replace
> with a `[SELECT Id FROM Profile WHERE Name = 'Admin']` lookup
> or a Custom Metadata record.
>
> All three findings are `confidence: heuristic`. The recognizer
> pattern-matches on Apex tokenization, not on an AST. Specifically:
>
> - The `missing-crud-check` finding may be a false positive if your
> org uses a custom security helper like
> `SecurityUtils.canUpdate(opportunity)` — the recognizer recognizes
> only the standard `Schema.sObjectType...` patterns.
> - Cross-method dataflow is invisible — if `processOpps` delegates
> to a helper that runs the SOQL/DML, the recognizer would miss
> it (and the finding here might double-count if the helper is
> inlined).
> - Dynamic SOQL (`Database.query('SELECT...')`) is stripped before
> the pattern pass — anything inside the query string is invisible.
>
> Verify each finding's context before refactoring. For governor-
> limit-specific narrowing across the whole org, run
> `sfi.governor_limit_risks`. For dead-code scan, run
> `sfi.find_dead_code`.
The response leads with `critical`, groups by severity, cites
canonical IDs, names the rule, gives the recommended fix, and
appends the verbatim boundary disclosures.
## Anti-patterns
| Mistake | Why it's wrong |
|---|---|
| Presenting a `heuristic` finding as ground truth. | Every v2.1 finding is `confidence: heuristic`. State it explicitly; the developer needs to know to verify before refactoring. |
| Flattening severity into one bullet list. | The catalog's severity is the primary delivery axis. A `critical` SOQL-in-loop next to a `low` hardcoded-email reads as equal urgency; surface them separately. |
| Silently dropping low / info findings. | Tell the user the count even if you suppress the details. The boundary disclosure is "v2.1 found N low / info findings; ask 'show low' to expand", not "no low findings." |
| Treating a `hardcoded-id` in a test class as a bug. | The refusal-pattern disclosure exists for this reason: test classes legitimately hardcode IDs, emails, and sandbox URLs as fixtures. Surface the finding with the refusal-pattern note, not as an actionable bug. |
| Treating a `missing-crud-check` finding as ground truth in an org with a custom security helper. | The Q80 disclosure says it: custom helpers are invisible. If the org uses `SecurityUtils.canCreate(...)`, every DML will flag. Tell the user the FP risk before acting. |
| Claiming an `uncovered` class has no real test coverage. | The reachability walk caps at depth 3 and is invisible to dynamic dispatch. A class genuinely covered by `Type.forName(...).newInstance().testMe()` will surface as `uncovered`. Cite the boundary, then suggest verifying the test runner. |
| Treating a `definitely_dead` ApexClass as safe to delete without verification. | The dead-code scan can't see managed-package callers, framework wiring, or runtime registrations. A class flagged `definitely_dead` may be wired in by a TriggerHandler base class or invoked via `EventBus.subscribe(...)`. Verify with `sfi.find_code_usages` before deletion. |
| Skipping the boundary disclosure on a clean (zero-finding) response. | A clean response is also load-bearing: "the recognizer found no quality issues for ApexClass:X" should still cite that the recognizer is heuristic and the AST + cross-class blind spots remain. |
| Conflating `fake-coverage` with `uncovered`. | They're distinct verdicts. `fake-coverage` means the class IS reached by test classes but every covering test class has `fake-assertion` findings. `uncovered` means nothing reaches it. Present them as separate buckets, not "tests are bad either way." |
## See also
- `developer-apex-refactor` — for code-reference questions ("where
is `OpportunityService` used", "is it safe to rename"). Apex tier is
parser-grade AST by default (`parsed`) with a heuristic scanner
backfill; the LWC/Aura/VF frontend tier stays `heuristic`.
- `developer-impact-and-reachability` — for what-if questions and
dead-code drill-in via `method_reachability`. v2.3 + v2.7.
- `architect-impact-analysis` — for cross-component impact ("what
breaks if I delete this field"). v0.2 `sfi.get_impact`.
- `developer-find-anywhere` — for cross-corpus literal search
(`sfi.find_hardcoded_values_anywhere`) and semantic field
discovery. v2.2.
## Verification
Before sending a response, confirm:
- [ ] I classified the question into one of the six shapes (broad
sweep / governor-limit / hardcoded value / CRUD-FLS / test
quality / dead code) and fired the right tool.
- [ ] I cited each finding's `severity` and `rule` by name; I led
the response with `critical` and `high` findings, not buried
them.
- [ ] I stated `confidence: heuristic` explicitly for every finding
and named the specific blind spot relevant to each rule
(AST, cross-class, custom helper, dynamic SOQL, dynamic
dispatch, test-class refusal pattern).
- [ ] For hardcoded-value findings in test classes, I surfaced the
refusal-pattern disclosure verbatim.
- [ ] For CRUD/FLS findings, I surfaced the Q80 verbatim
disclosure (custom security utility helpers invisible,
cross-method dataflow invisible, dynamic SOQL stripped).
- [ ] For dead-code findings, I surfaced the invisible-callers
disclosure (dynamic dispatch, reflective invocation,
framework wiring, managed-package callers).
- [ ] I did NOT present a finding as ground truth or recommend an
irreversible refactor without naming the verification step.
- [ ] When the response was clean (zero findings), I still cited the
recognizer is heuristic and named the blind spots.
---
**Grounding & routing (shared contract).** For a vague or broad ask, call `sfi.route_question` first — in the default hybrid mode it returns a meaning-ranked `toolCandidates` shortlist (which YOU pick from) plus a suggested plane and a `route` hint (and whether to `sfi.resolve` a name first). **Default tool profile is `core`:** only the core spine (including `sfi.live_consent`) is directly invokable. For every other `sfi.*` analysis, call `sfi.run_analysis` with `{ "name": "sfi.<tool>", "args": { … } }` (or follow `route_question.invoke`, which already wraps non-core steps). Optional: `sfi.describe_analysis` first when args are unclear. Every org fact must come from an `sfi.*` tool call, cited by its canonical id — never from memory. Build the answer only from what the tools returned, then pass it through `sfi.synthesize_answer`, which flags any `hallucinatedIds` (canonical ids no tool produced). Full cascade: `using-sf-intelligence`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!