agent-docs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.cursor/plans/OPTIMISE.md +379 -0
  2. package/.cursor/plans/VERSIONING.md +207 -0
  3. package/.cursor/rules/IMPORTANT.mdc +97 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +13 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  6. package/.github/dependabot.yml +38 -0
  7. package/.github/pull_request_template.md +10 -0
  8. package/.github/workflows/format.yml +35 -0
  9. package/CODE_OF_CONDUCT.md +64 -0
  10. package/CONTRIBUTING.md +52 -0
  11. package/LICENSE.md +20 -0
  12. package/PLAN.md +707 -0
  13. package/README.md +133 -0
  14. package/SECURITY.md +21 -0
  15. package/docs/APEXANNOTATIONS.md +472 -0
  16. package/docs/APEXDOC.md +198 -0
  17. package/docs/CML.md +877 -0
  18. package/docs/CODEANALYZER.md +435 -0
  19. package/docs/CONTEXTDEFINITIONS.md +617 -0
  20. package/docs/ESLINT.md +827 -0
  21. package/docs/ESLINTJSDOC.md +520 -0
  22. package/docs/FIELDSERVICE.md +4452 -0
  23. package/docs/GRAPHBINARY.md +208 -0
  24. package/docs/GRAPHENGINE.md +616 -0
  25. package/docs/GRAPHML.md +337 -0
  26. package/docs/GRAPHSON.md +302 -0
  27. package/docs/GREMLIN.md +490 -0
  28. package/docs/GRYO.md +232 -0
  29. package/docs/HUSKY.md +106 -0
  30. package/docs/JEST.md +387 -0
  31. package/docs/JORJE.md +537 -0
  32. package/docs/JSDOC.md +621 -0
  33. package/docs/PMD.md +910 -0
  34. package/docs/PNPM.md +409 -0
  35. package/docs/PRETTIER.md +716 -0
  36. package/docs/PRETTIERAPEX.md +874 -0
  37. package/docs/REVENUETRANSACTIONMANAGEMENT.md +887 -0
  38. package/docs/TINKERPOP.md +252 -0
  39. package/docs/VITEST.md +706 -0
  40. package/docs/VSCODE.md +231 -0
  41. package/docs/XPATH31.md +213 -0
  42. package/package.json +32 -0
  43. package/postinstall.mjs +51 -0
  44. package/prettier.config.js +18 -0
@@ -0,0 +1,616 @@
1
+ # Salesforce Graph Engine (SFGE) Quick Reference
2
+
3
+ > **Version**: 1.0.0
4
+
5
+ Condensed guide for Salesforce Graph Engine (SFGE) data-flow analysis and rules.
6
+
7
+ **Related Docs:** [CODEANALYZER.md](CODEANALYZER.md), [PMD.md](PMD.md),
8
+ [GREMLIN.md](GREMLIN.md), [TINKERPOP.md](TINKERPOP.md),
9
+ [GRAPHML.md](GRAPHML.md), [GRAPHSON.md](GRAPHSON.md), [GRYO.md](GRYO.md),
10
+ [GRAPHBINARY.md](GRAPHBINARY.md)
11
+
12
+ ## Overview
13
+
14
+ Salesforce Graph Engine (SFGE): open-source Salesforce tool performing complex
15
+ analysis on Apex code, identifying security vulnerabilities and code issues.
16
+ Uses data-flow analysis for more complex checks than static-analysis tools.
17
+ **Status:** Developer Preview.
18
+
19
+ **Key Advantage:** SFGE uses data-flow analysis to detect issues requiring
20
+ understanding of how data flows through code paths, not just syntax patterns.
21
+
22
+ **Viewing Available Rules:**
23
+
24
+ ```bash
25
+ scanner run dfa --rule-selector sfge --help
26
+ ```
27
+
28
+ For modifying rule settings (severity, tags), see
29
+ [Customize Your Configuration](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/customize-config.html).
30
+
31
+ ## Data-Flow Analysis Process
32
+
33
+ 1. **Parse Tree Generation:** Apex Jorje compiler analyzes code and returns
34
+ parse tree
35
+ 2. **Graph Construction:** SFGE translates parse tree into vertices and adds
36
+ them to Apache TinkerPop graph database
37
+ 3. **Code Path Construction:** SFGE builds code paths starting from each
38
+ identified entry point
39
+ 4. **Rule Application:** SFGE walks each code path, applying selected rules at
40
+ every vertex with contextual data. Rules evaluate information and create
41
+ violations if applicable
42
+
43
+ After traversal completes, SFGE returns all collected rule violations.
44
+
45
+ ## Key Concepts
46
+
47
+ | Concept | Description |
48
+ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
49
+ | **Entry Point** | Starting code location of execution path from external interaction (e.g., `@AuraEnabled` methods, `public` Visualforce controller methods). Entry points are evaluated in parallel, and timeout is applied to each entry point separately |
50
+ | **Source** | Code location where data originates. When data is passed into an entry point, the entry point is the source for that data. Data can also be produced or read other than getting passed into the entry point, making it possible for the data source to also be in the middle of a code path |
51
+ | **Sink** | Ending code location where data is consumed or modified (e.g., DML operations, SOQL queries) |
52
+ | **Sanitizer** | Check between source and sink that ensures appropriate actions are taken or inappropriate actions are prevented (e.g., null checks, CRUD/FLS checks) |
53
+
54
+ **Rule Logic:** SFGE verifies that each code path containing a source and a sink
55
+ also includes a sanitizer. Missing sanitizers result in violations.
56
+
57
+ **Path Relationships:** A source can lead to multiple sinks. A sink can be
58
+ reached through multiple sources. There can be multiple paths between the same
59
+ source and sink. SFGE analyzes all possible paths from each entry point.
60
+
61
+ ## Configuration
62
+
63
+ Configure SFGE in `code-analyzer.yml`:
64
+
65
+ ```yaml
66
+ engines:
67
+ sfge:
68
+ disable_engine: false
69
+ disable_limit_reached_violations: false
70
+ java_command: null
71
+ java_max_heap_size: null
72
+ java_thread_count: 4
73
+ java_thread_timeout: 900000
74
+ ```
75
+
76
+ ### Configuration Properties
77
+
78
+ | Property | Type | Default | Description |
79
+ | ---------------------------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
80
+ | `disable_engine` | boolean | `false` | Turn off SFGE engine (not included in Code Analyzer commands) |
81
+ | `disable_limit_reached_violations` | boolean | `false` | Prevent LimitReached violations for complex paths. SFGE detects complex paths that might cause OutOfMemory errors and throws LimitReached violations. Disable this check (in addition to increasing `java_max_heap_size`) if needed |
82
+ | `java_command` | string | `null` | Specific `java` command/path for JRE/JDK. Auto-discovered if `null` |
83
+ | `java_max_heap_size` | string | `null` | Maximum Java heap size (bytes). Appended to `-Xmx`. Must be multiple of 1024, >2MB. Use `k`/`K`/`kb`/`KB` (kilobytes), `m`/`M`/`mb`/`MB` (megabytes), `g`/`G`/`gb`/`GB` (gigabytes). Auto: JVM default if `null` |
84
+ | `java_thread_count` | number | `4` | Number of Java threads for parallel execution. Increasing allows more paths evaluated simultaneously |
85
+ | `java_thread_timeout` | number | `900000` | Maximum time (milliseconds) a Java thread may execute before SFGE issues Timeout violation |
86
+
87
+ ## Running SFGE Rules
88
+
89
+ Use `--rule-selector sfge` to run SFGE rules:
90
+
91
+ ```bash
92
+ scanner run dfa --rule-selector sfge
93
+ ```
94
+
95
+ **Note:** `scanner run dfa` invokes data-flow-based rules in SFGE.
96
+
97
+ **Rule Registration:** Rules register interest in specific types of vertices.
98
+ For example: CRUD/FLS rules express interest in DML operation vertices,
99
+ NullPointerException rules express interest in object dereference vertices,
100
+ Performance rules express interest in loop and database operation vertices.
101
+ Rules evaluate vertices along code paths and create violations when conditions
102
+ are met.
103
+
104
+ ## Working with SFGE
105
+
106
+ ### Interpreting Results
107
+
108
+ SFGE results include at least two locations: **Entry Point** (where the code
109
+ path starts, first location) and **Sink** (where the violation occurs, last
110
+ location). Review both to understand potential vulnerabilities.
111
+
112
+ **Note:** SFGE uses the same results output schema that other engines use. See
113
+ [Interpret the Run Results](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/interpret-results.html)
114
+ for information about human-readable output, and the
115
+ [Output Schema Reference](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/output-schema-reference.html)
116
+ for details about machine-readable outputs.
117
+
118
+ **Flow Scanner vs SFGE Differences:** Flow Scanner engine's code paths start
119
+ from the data source. SFGE's code paths always start from the entry point, which
120
+ aren't always the same as the data source.
121
+
122
+ ### Managing False Positives/Negatives
123
+
124
+ SFGE may produce false positives or negatives: **False Negative** (SFGE fails to
125
+ create a violation where the code is insecure), **False Positive** (SFGE creates
126
+ a violation even though the code is secure).
127
+
128
+ If you determine that SFGE created a false positive, add engine directives to
129
+ your code so that SFGE doesn't throw that violation anymore.
130
+
131
+ **Engine Directives (Three Levels):**
132
+
133
+ **1. Disable Next Line:** Disable just the sink from SFGE's analysis. Add
134
+ `disable-next-line` in the line immediately before the sink operation:
135
+
136
+ ```apex
137
+ // sfge-disable-next-line RuleName
138
+ List<Account> accounts = [SELECT Id FROM Account];
139
+ ```
140
+
141
+ **2. Disable Stack (Method):** Disable all analyses of sink operations in paths
142
+ passing through a method. Add `disable-stack` in the line immediately before the
143
+ method declaration:
144
+
145
+ ```apex
146
+ // sfge-disable-stack RuleName
147
+ public void myMethod() {
148
+ List<Account> accounts = [SELECT Id FROM Account];
149
+ }
150
+ ```
151
+
152
+ **3. Disable (Class):** Disable all analyses of sink operations that occur in
153
+ the class. Add `disable` in the line immediately before the class declaration:
154
+
155
+ ```apex
156
+ // sfge-disable RuleName
157
+ public class MyClass {
158
+ public void myMethod() {
159
+ List<Account> accounts = [SELECT Id FROM Account];
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### Understanding Code Paths
165
+
166
+ Recognize how data flows through code: 1. Identify entry points (external
167
+ interaction points), 2. Trace data from sources to sinks, 3. Verify sanitizers
168
+ exist between source and sink, 4. Review violations to understand missing
169
+ sanitizers.
170
+
171
+ ## Writing SFGE-Friendly Code
172
+
173
+ To enhance SFGE performance and reduce analysis time. **Note:** Some suggested
174
+ refactors can conflict with accepted best practices for Apex. Read through the
175
+ options and update your code as appropriate.
176
+
177
+ **Performance Factors:** Two factors directly affect SFGE's performance: 1.
178
+ **Number of entry points analyzed** (entry points are evaluated in parallel, and
179
+ timeout is applied to each entry point separately), 2. **Number of paths each
180
+ entry point constructs** (building paths is the most expensive part of analyzing
181
+ an entry point. Typically, an entry point causes timeouts or memory issues
182
+ because it constructs an inordinate number of paths).
183
+
184
+ **Most Consequential Refactoring:** Decrease the number of paths a single entry
185
+ point constructs or more evenly distribute paths between entry points.
186
+
187
+ ### How Paths Are Built
188
+
189
+ When SFGE encounters conditional statements (if, while, etc.) with unknown
190
+ values, paths fork at each conditional. For example:
191
+
192
+ ```apex
193
+ public void myMethod(boolean b1, boolean b2) {
194
+ if (b1) { /* path 1 */ }
195
+ if (b2) { /* path 2 */ }
196
+ }
197
+ ```
198
+
199
+ If the values of `b1` and `b2` are unknown, SFGE identifies four unique paths
200
+ through the method (2 × 2 = 4). Each conditional causes paths to fork.
201
+
202
+ **Key Principle:** Where possible, SFGE avoids building impossible paths. Paths
203
+ only fork when the outcome is truly indeterminate.
204
+
205
+ ### Reduce Entry Points
206
+
207
+ Minimize number of entry points analyzed (each evaluated separately), break down
208
+ complex entry points into multiple simpler ones, distribute paths evenly among
209
+ entry points.
210
+
211
+ **Refactoring Strategy:** If an entry point's complexity causes timeouts or
212
+ memory problems, refactor that entry point into two separate entry points with
213
+ fewer paths. These entry points are analyzed in parallel and have separate
214
+ timeouts, complete faster, and are less likely to exceed time or memory limits.
215
+
216
+ **Example Path Calculation:** Entry point with 3 unknown parameters and 3
217
+ indeterminate if clauses. If each helper method contains 1 unique path: Total =
218
+ 1 × 2 × 2 × 2 = 8 paths. If each helper method contains 10 unique paths: Total =
219
+ 1 × 20 × 20 × 20 = 8,000 paths.
220
+
221
+ **Refactoring Example:** Split a single entry point into two entry points, each
222
+ passing a literal boolean to avoid forking at one conditional: Original: 8,000
223
+ paths (1 × 20 × 20 × 20), Refactored: 4,000 paths per entry point (1 × 20 × 20 ×
224
+ 10), Total: 8,000 paths across 2 entry points (analyzed in parallel).
225
+
226
+ ### Limit Code Path Complexity
227
+
228
+ Simplify code paths to prevent excessive branching, refactor complex methods
229
+ into smaller manageable ones, reduce conditional branches to decrease number of
230
+ paths SFGE analyzes, prevent timeouts or memory issues from too many paths.
231
+
232
+ ### Best Practices
233
+
234
+ - **Distribute Paths Evenly:** Balance path distribution among entry points
235
+ - **Refactor Complex Methods:** Break down large methods to distribute paths
236
+ - **Simplify Conditionals:** Reduce nested conditionals and branching
237
+ - **Use Literal Values:** Pass literal values to helper methods to avoid path
238
+ forking
239
+ - **Split Entry Points:** Convert single complex entry point into multiple
240
+ simpler entry points
241
+
242
+ ## SFGE Rules Reference
243
+
244
+ ### ApexFlsViolation
245
+
246
+ Detects Create, Read, Update, Delete (CRUD) and Field-Level Security (FLS)
247
+ violations.
248
+
249
+ **Entry Points:** `@AuraEnabled`, `@InvocableMethod`, `@NamespaceAccessible`,
250
+ `@RemoteAction`-annotated methods, methods returning `PageReference` object,
251
+ `public`-scoped methods on Visualforce Controllers, `global`-scoped methods on
252
+ any class, `Messaging.InboundEmailResult handleInboundEmail()` methods on
253
+ `Messaging.InboundEmailHandler` implementations, any method targeted during
254
+ invocation.
255
+
256
+ **Sinks:** DML operations (`delete`, `insert`, `merge`, `undelete`, `update`,
257
+ `upsert`), `Database.method()` counterparts (`Database.delete()`,
258
+ `Database.insert()`, etc.), SOQL queries (`[SELECT ... FROM ...]`),
259
+ `Database.query()` counterpart.
260
+
261
+ **Sanitizers:** CRUD checks (`Schema.DescribeSObjectResult` access checks,
262
+ acceptable for DELETE, UNDELETE, MERGE operations), FLS checks
263
+ (`Schema.DescribeFieldResult` access checks, acceptable for READ, INSERT,
264
+ UPDATE, UPSERT operations on standard/custom objects),
265
+ `Security.stripInaccessible()` filtered lists, SOQL queries using
266
+ `WITH USER_MODE`, SOQL queries using `WITH SECURITY_ENFORCED`.
267
+
268
+ **Violation Messages:**
269
+
270
+ - `{Validation-Type} validation is missing for {Operation-Name} operation on {Object-Type} with fields {Comma-Separated-Fields}`
271
+ - `{Validation-Type} validation is missing for {Operation-Name} operation on {Object-Type} with fields {Comma-Separated-Fields}–Graph Engine couldn't parse all objects and fields correctly. Manually confirm if the objects and fields involved in these segments have FLS checks: {Unknown-Segments}`
272
+
273
+ **Fields:** `Validation-Type` (CRUD or FLS), `Operation-Name` (data operation
274
+ that must be sanitized), `Object-Type` (object name or variable
275
+ name/`SFGE_Unresolved_Argument` if unknown), `Comma-Separated-Fields` (field
276
+ names or `Unknown` if Graph Engine couldn't determine).
277
+
278
+ ### ApexNullPointerException
279
+
280
+ Identifies Apex operations that dereference null objects and throw
281
+ NullPointerExceptions.
282
+
283
+ **Entry Points:** Same as ApexFlsViolation
284
+
285
+ **Sinks:** Any object dereference (e.g., `x.someMethod()`, `x.field`,
286
+ `x[index]`)
287
+
288
+ **Sanitizers:** Non-null initialization (`String s = 'abcde';`), null checks
289
+ before accessing (`if (s != null) { ... }`), checks for specific non-null values
290
+ (`if (x == 7) { ... }`)
291
+
292
+ **Violation Message:**
293
+ `ApexNullPointerException identifies Apex operations with a high likelihood of throwing a NullPointerException`
294
+
295
+ **Fix:** Add null checks before dereferencing, ensure variables are initialized,
296
+ avoid initializing to `null` unless reassigned before use.
297
+
298
+ ### AvoidDatabaseOperationInLoop
299
+
300
+ Detects database operations inside loops that cause performance degradation and
301
+ exceed governor limits.
302
+
303
+ **Entry Points:** Same as ApexFlsViolation
304
+
305
+ **Sinks:** DML operations inside loops, SOQL queries inside loops,
306
+ `Database.method()` calls inside loops
307
+
308
+ **Violation Messages:**
309
+
310
+ - `Database operation {Operation} was called inside a loop. [LoopStatement at {Location}]`
311
+ - `SOQL query was called inside a loop. [LoopStatement at {Location}]`
312
+
313
+ **Fix:** Move database operations outside loops, use bulk operations, collect
314
+ data in collections first.
315
+
316
+ ### AvoidExpensiveSchemaLookups
317
+
318
+ Detects expensive schema lookups (`Schema.getGlobalDescribe()`,
319
+ `Schema.describeSObjects()`) that cause performance issues.
320
+
321
+ **Entry Points:** Same as ApexFlsViolation
322
+
323
+ **Sinks:** `Schema.getGlobalDescribe()`, `Schema.describeSObjects(...)`
324
+
325
+ **Sanitizers:** None (rule detects expensive operations, not security issues)
326
+
327
+ **Violation Messages:**
328
+
329
+ - `Schema.getGlobalDescribe was called inside a loop. [ForEachStatement at {Location}]`
330
+ - `Multiple expensive schema lookups are invoked. [Schema.describeSObjects at {Location}]`
331
+ - `Schema.getGlobalDescribe executed multiple times in the call stack. [getFields at {Location1}, getFields at {Location2}, ...]`
332
+
333
+ **Fix:** Move schema lookups outside loops, cache results, avoid multiple calls
334
+ in same path.
335
+
336
+ ### DatabaseOperationsMustUseWithSharing
337
+
338
+ Identifies database operations in classes annotated as `without sharing` or
339
+ classes that inherit sharing implicitly instead of explicitly using
340
+ `inherited sharing`.
341
+
342
+ **Entry Points:** Same as ApexFlsViolation
343
+
344
+ **Sinks:** Any database operation (DML, SOQL)
345
+
346
+ **Sanitizers:** Class-level `with sharing` annotation, class-level
347
+ `inherited sharing` annotation
348
+
349
+ **Sharing Models:** `with sharing` (database transactions respect sharing rules,
350
+ default recommendation), `without sharing` (database transactions ignore sharing
351
+ rules, use with caution), `inherited sharing` (database transactions inherit
352
+ sharing model of calling class, use for flexibility)
353
+
354
+ **Violation Messages:**
355
+
356
+ - `Database operation must be executed from a class that enforces sharing rules.`
357
+ - `The database operation's class implicitly inherits a sharing model from {Class} {Method}. Explicitly assign a sharing model instead.`
358
+
359
+ **Fix:** Add `with sharing` or `inherited sharing` to class declaration.
360
+
361
+ ### MissingNullCheckOnSoqlVariable
362
+
363
+ Identifies SOQL queries with variables in WHERE clauses that lack null checks.
364
+ When variable is null, O(1) operation becomes O(n) (full table scan).
365
+
366
+ **Entry Points:** Same as ApexFlsViolation
367
+
368
+ **Sinks:** SOQL queries with variables in WHERE clauses
369
+
370
+ **Sanitizers:** Null checks (`if (x != null) { ... }`), explicit non-null
371
+ assignment (`String x = 'asdf';`), checks for specific non-null values
372
+ (`if (x == 7) { ... }`)
373
+
374
+ **Violation Message:**
375
+ `Null check is missing for variable {VariableName} used in SOQL query.`
376
+
377
+ **Fix:** Add null check before SOQL query or assign to specific non-null value.
378
+
379
+ ### UnimplementedType
380
+
381
+ Detects abstract classes and interfaces that are non-global and missing
382
+ implementations or extensions.
383
+
384
+ **Note:** Traditional static analysis rule (not data-flow based). Violation
385
+ occurs at declaration point.
386
+
387
+ **Violation Message:** `Extend, implement, or delete {Type} {Name}`
388
+
389
+ **Fix:** Implement/extend the type or delete if unnecessary. Rule excludes
390
+ `global` scoped classes to prevent false positives.
391
+
392
+ ## Apache TinkerPop Integration
393
+
394
+ SFGE uses Apache TinkerPop graph computing framework to manage and traverse code
395
+ graph representations.
396
+
397
+ **Reference:** See [TINKERPOP.md](TINKERPOP.md) for complete framework
398
+ documentation.
399
+
400
+ ### Graph Database Concepts
401
+
402
+ **Property Graph Model:** See [TINKERPOP.md](TINKERPOP.md#property-graph-model)
403
+ for the general Property Graph Model concept.
404
+
405
+ **SFGE-Specific Graph Structure:**
406
+
407
+ - **Vertices:** Code elements (methods, statements, expressions)
408
+ - **Edges:** Relationships (data flow, control flow)
409
+ - **Properties:** Metadata (line numbers, variable names, operation types)
410
+ - **Labels:** Categories ("Method", "DML", "SOQL", "EntryPoint")
411
+
412
+ **Graph Structure in SFGE:** Code is represented as a directed property graph.
413
+ Entry points are starting vertices. Code paths are sequences of connected
414
+ vertices and edges. Rules traverse paths from entry points to sinks. Graph is
415
+ constructed from Apex parse tree.
416
+
417
+ ### Gremlin Query Language
418
+
419
+ Gremlin is a functional, data-flow language for graph traversal. SFGE uses
420
+ Gremlin internally for path analysis.
421
+
422
+ **Reference:** See [GREMLIN.md](GREMLIN.md) for complete Gremlin language
423
+ documentation.
424
+
425
+ **Note:** Developers don't need to write Gremlin queries. SFGE handles graph
426
+ construction and traversal internally using TinkerPop. The framework
427
+ automatically generates appropriate Gremlin traversals for path analysis.
428
+
429
+ ### Graph Serialization Formats
430
+
431
+ TinkerPop supports multiple formats for graph persistence and exchange. See
432
+ format-specific docs: [GRAPHML.md](GRAPHML.md), [GRAPHSON.md](GRAPHSON.md),
433
+ [GRYO.md](GRYO.md), [GRAPHBINARY.md](GRAPHBINARY.md). For format comparison,
434
+ selection guidance, and general performance/configuration best practices, see
435
+ [TINKERPOP.md](TINKERPOP.md).
436
+
437
+ ### Traversal Patterns
438
+
439
+ Common traversal patterns used in graph analysis: **Path Finding** (Shortest
440
+ Path, All Paths, Reachability, Path Length), **Pattern Matching** (Subgraph
441
+ Matching, Pattern Detection, Motif Finding, `match()` Step - declarative pattern
442
+ matching with multiple patterns, patterns defined using `as()` labels, patterns
443
+ matched independently and combined, useful for complex multi-hop queries),
444
+ **Graph Analysis** (Centrality - degree, betweenness, closeness, Community
445
+ Detection, Graph Metrics), **Data Extraction** (Subgraph Extraction, Property
446
+ Aggregation, Relationship Analysis).
447
+
448
+ SFGE uses these patterns internally to analyze code paths and detect violations.
449
+ The framework automatically applies appropriate traversal patterns based on rule
450
+ requirements.
451
+
452
+ ## Performance Considerations
453
+
454
+ ### Memory Management
455
+
456
+ - Complex paths may cause OutOfMemory errors
457
+ - SFGE dynamically calculates allowed complexity based on `java_max_heap_size`
458
+ - `disable_limit_reached_violations` can disable LimitReached violations if
459
+ needed
460
+
461
+ ### Threading
462
+
463
+ - `java_thread_count` controls parallel execution (default: 4)
464
+ - Increasing thread count allows more paths evaluated simultaneously
465
+ - `java_thread_timeout` prevents threads from running indefinitely (default:
466
+ 900000ms)
467
+
468
+ ### Optimization Tips
469
+
470
+ 1. **Reduce Entry Points:** Fewer entry points = less analysis
471
+ 2. **Simplify Paths:** Fewer branches = faster analysis
472
+ 3. **Increase Heap Size:** For large codebases, increase `java_max_heap_size`
473
+ 4. **Adjust Thread Count:** Balance between speed and resource usage
474
+
475
+ ## Suppression
476
+
477
+ Suppress SFGE violations using engine directives. See
478
+ [Managing False Positives/Negatives](#managing-false-positivesnegatives) for
479
+ details on the three levels of engine directives.
480
+
481
+ **Note:** Suppression syntax may vary. Check Salesforce Code Analyzer
482
+ documentation for current syntax.
483
+
484
+ ## User Action Violations
485
+
486
+ If your SFGE analysis is intentionally blocked, it's because SFGE identified
487
+ something incorrect in your code. You must modify your code to unblock the
488
+ analysis.
489
+
490
+ | Message | Violation | When it Occurs |
491
+ | ------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------- |
492
+ | Remove unreachable code to proceed with the analysis. | User Action | Returned one time on an entire analysis. Analysis of all code is blocked. |
493
+ | Rename or delete this reused variable to proceed with the analysis. | User Action Violation | Returned on a single path. Analysis of only that code path is blocked. |
494
+
495
+ **Unreachable Code Example:**
496
+
497
+ ```apex
498
+ public void myMethod() {
499
+ throw new Exception('Error');
500
+ return; // Unreachable code
501
+ }
502
+ ```
503
+
504
+ SFGE analysis on this code results in the entire analysis being blocked:
505
+ `Remove unreachable code to proceed with the analysis.`
506
+
507
+ **Reused Variable Example:**
508
+
509
+ ```apex
510
+ public void myMethod() {
511
+ String input = 'value1';
512
+ // ... some code ...
513
+ String input = 'value2'; // Reused variable
514
+ }
515
+ ```
516
+
517
+ SFGE analysis on this code path results in a User Action Violation on this path:
518
+ `Rename or delete this reused variable to proceed with the analysis.`
519
+
520
+ ## Limitations
521
+
522
+ 1. **Error Logs:** Error logs shown as
523
+ `Internal error. Work in progress. Please ignore` indicate that the entry
524
+ point's analysis didn't complete successfully. This issue is being worked on.
525
+ In the meantime, you must verify the validity of this error manually.
526
+
527
+ 2. **Duplicate Class Names:** SFGE handles unique class names. If the source
528
+ code has two distinctly different files that have classes with duplicate
529
+ names, SFGE fails with an error message:
530
+ `<example_class> is defined in multiple files`. In cases like these: Provide
531
+ a `--workspace` subpath to the source directory that has only one of the file
532
+ names, set `--target` to the second file name, rerun the `code-analyzer run`
533
+ command.
534
+
535
+ 3. **Anonymous Apex Script:** SFGE doesn't handle anonymous Apex script. Provide
536
+ the class directory path as the `--workspace` that doesn't include any
537
+ anonymous Apex script.
538
+
539
+ 4. **Namespace Placeholders:** SFGE doesn't handle namespace placeholders. Leave
540
+ the namespace placeholder blank.
541
+
542
+ 5. **Property Chain Depth:** SFGE supports Apex property chains with a depth of
543
+ 2 or fewer. For example, SFGE supports `Object.x` but not `Object.x.y`.
544
+
545
+ 6. **Apex Triggers:** SFGE doesn't scan Apex triggers.
546
+
547
+ ## Apex Security Enforcement Methods
548
+
549
+ ### Enforce User Mode for Database Operations
550
+
551
+ Use `WITH USER_MODE` in SOQL queries to enforce field-level security (FLS) and
552
+ sharing rules:
553
+
554
+ ```apex
555
+ // Enforces FLS and sharing rules
556
+ List<Account> accounts = [SELECT Id, Name FROM Account WITH USER_MODE];
557
+ ```
558
+
559
+ **Benefits:** Automatically enforces FLS checks, respects sharing rules,
560
+ prevents access to fields user cannot read, recognized by SFGE as sanitizer for
561
+ FLS violations.
562
+
563
+ **Usage:** Add `WITH USER_MODE` to SOQL queries. Works with `SELECT`, `UPDATE`,
564
+ `DELETE` statements. Alternative to manual FLS checks.
565
+
566
+ ### Security.stripInaccessible Method
567
+
568
+ Use `Security.stripInaccessible()` to remove fields and records the user cannot
569
+ access:
570
+
571
+ ```apex
572
+ List<Account> accounts = [SELECT Id, Name, SecretField FROM Account];
573
+ // Remove inaccessible fields
574
+ SObjectAccessDecision decision = Security.stripInaccessible(
575
+ AccessType.READABLE, accounts
576
+ );
577
+ List<Account> safeAccounts = decision.getRecords();
578
+ ```
579
+
580
+ **Benefits:** Automatically filters inaccessible fields, returns only accessible
581
+ data, recognized by SFGE as sanitizer for FLS violations.
582
+
583
+ **Access Types:** `AccessType.READABLE` (filter fields user cannot read),
584
+ `AccessType.UPDATABLE` (filter fields user cannot update),
585
+ `AccessType.CREATABLE` (filter fields user cannot create).
586
+
587
+ ### Enforcing Object and Field Permissions
588
+
589
+ Use Schema describe methods to check permissions before operations:
590
+
591
+ **Object-Level (CRUD) Checks:**
592
+
593
+ ```apex
594
+ Schema.DescribeSObjectResult objDesc = Account.sObjectType.getDescribe();
595
+ if (objDesc.isDeletable()) {
596
+ delete accounts;
597
+ }
598
+ ```
599
+
600
+ **Field-Level (FLS) Checks:**
601
+
602
+ ```apex
603
+ Schema.DescribeFieldResult fieldDesc = Account.Name.getDescribe();
604
+ if (fieldDesc.isAccessible()) { /* Read field */ }
605
+ if (fieldDesc.isUpdateable()) { /* Update field */ }
606
+ if (fieldDesc.isCreateable()) { /* Create field */ }
607
+ ```
608
+
609
+ **Schema Methods:** `isAccessible()` (check if field can be read),
610
+ `isUpdateable()` (check if field can be updated), `isCreateable()` (check if
611
+ field can be created), `isDeletable()` (check if object can be deleted,
612
+ object-level).
613
+
614
+ **SFGE Recognition:** CRUD checks (recognized for DELETE, UNDELETE, MERGE
615
+ operations), FLS checks (recognized for READ, INSERT, UPDATE, UPSERT
616
+ operations), must be performed before the operation (between source and sink).