# CLEAN — Apache TinkerPop
Scanned 2026-03-29 for CWE-407.

## Scope

- `gremlin-core/src/main/java` — MatchStep, DisjunctStep, TraversalHelper, PartitionStrategy, FilterRankingStrategy, PathRetractionStrategy
- Graph traversal execution engine

## Findings

| Location | Pattern | Type | Result |
|----------|---------|------|--------|
| `MatchStep.dedups` | `dedups.contains` per traverser | `HashSet<List<Object>>` | CLEAN |
| `MatchStep.traverser.getTags()` | `getTags().contains` per step | `Set<String>` in AbstractTraverser | CLEAN |
| `DisjunctStep.setA / setB` | `setB.contains` / `setA.contains` in loops | Both are `Set<?>` (HashSet impl) | CLEAN |
| `PartitionStrategy.readPartitions` | `readPartitions.contains` per element check | `Set<String>` (unmodifiableSet of HashSet) | CLEAN |
| `CoreImports.unique` (uniqueMethods) | `unique.contains` | `LinkedHashSet<String>` | CLEAN |
| `MatchStep.Helper.computeStartLabel.sort` | `sort.contains` in plan ordering | `ArrayList<String>` — but called once at plan-construction time over label names (N < 20), not per record | LOW — not hot path |
| `TraversalHelper.getSteps().contains` | step membership check | Called once at plan-optimization time | LOW |

All per-record hot-path traversal uses hash-based set types. The `sort` ArrayList in `computeStartLabel` accumulates label strings during query planning (once per query), not during record iteration. With N labels typically in the single digits this is not actionable.

**Result: No actionable CWE-407 defects.**

## Note

Previous scan (project_graphdb_scan.md) also confirmed TinkerPop CLEAN. This scan independently verified the same conclusion with broader coverage of strategy and step classes.
