# trailmark-variant-neighborhood

Expands one confirmed or suspected vulnerability into a Trailmark graph neighborhood of variant candidates by finding sibling functions, shared callers and callees, common sensitive sinks, common entrypoint paths, interface implementations, override relationships, type/reference neighbors, and structurally similar nodes. Use after one issue is found to seed variant-analysis, semgrep-rule-creator, static-analysis, or manual review with graph-derived candidate locations.

- **Kind:** skill
- **Source:** https://github.com/trailofbits/skills
- **Page:** https://forefy.com/skills/e874af87-6e12-4ff7-bea0-3b36d09e3aab
- **API (JSON + files):** https://forefy.com/api/asr/e874af87-6e12-4ff7-bea0-3b36d09e3aab

---

## SKILL.md

---
name: trailmark-variant-neighborhood
description: "Expands one confirmed or suspected vulnerability into a Trailmark graph neighborhood of variant candidates by finding sibling functions, shared callers and callees, common sensitive sinks, common entrypoint paths, interface implementations, override relationships, type/reference neighbors, and structurally similar nodes. Use after one issue is found to seed variant-analysis, semgrep-rule-creator, static-analysis, or manual review with graph-derived candidate locations."
allowed-tools:
  - Bash
  - Read
  - Grep
  - Glob
  - Write
---

# Trailmark Variant Neighborhood

Expand one seed issue into graph-derived variant candidates. This skill
generates review targets, not confirmed findings.

## When to Use

- A finding is confirmed or plausible and variants may exist
- The vulnerable pattern depends on call context
- The issue involves a shared sink, source, validator, interface, override,
  trait, hook, handler, adapter, or critical type
- The next step is to seed `variant-analysis`, `semgrep-rule-creator`,
  `static-analysis`, or manual review

## When NOT to Use

- No seed issue exists. Use discovery or triage first.
- The pattern is purely syntactic and already obvious. Use
  `semgrep-rule-creator` directly.
- The question is exploit-chain composition across multiple findings. Use a
  composition workflow.
- The goal is remediation verification. Use a remediation-review workflow.
- The seed cannot be bound to a graph node.

## Rationalizations to Reject

| Rationalization | Why It Is Wrong | Required Action |
|---|---|---|
| "Nearby code means variant" | Proximity is only a candidate reason | Rank it as a review target |
| "Only exact same names matter" | Variants often share sinks or preconditions, not names | Expand across callers, callees, interfaces, and types |
| "Every candidate is a finding" | This skill outputs candidates for review | Avoid vulnerability claims |
| "Unreachable candidates can be ignored completely" | They may become reachable after refactors | Rank lower or list as deferred |
| "Graph candidates replace semantic pattern work" | Graph structure finds locations, not root-cause semantics | Hand off to variant-analysis, Semgrep, CodeQL, or manual review |

## Workflow

```
Variant Neighborhood Progress:
- [ ] Step 1: Normalize and bind the seed
- [ ] Step 2: Expand graph neighborhoods
- [ ] Step 3: Rank candidates
- [ ] Step 4: Extract variant pattern guidance
- [ ] Step 5: Emit handoff packet
```

### Step 1: Normalize And Bind The Seed

Accept finding text, file/line, function name, or output from
`trailmark-finding-triage`. Bind the seed to a Trailmark node and record the
root cause in plain language.

If the seed has no concrete graph binding, stop before inventing variants.

### Step 2: Expand Neighborhoods

Use the dimensions in
[references/neighborhood-patterns.md](references/neighborhood-patterns.md):

- shared callers
- shared callees and sinks
- entrypoint path neighbors
- interface, override, trait, and implementation siblings
- file or module cluster neighbors
- taint or privilege-boundary peers
- type and state-reference neighbors

Bound expansion to avoid candidate floods.

### Step 3: Rank Candidates

Rank with [references/ranking.md](references/ranking.md). Prioritize
entrypoint-reachable, tainted, boundary-adjacent, high-blast-radius, shared
sink, same-interface, and close-distance candidates. Penalize test, mock,
generated, vendor, unreachable, and trusted-internal-only candidates.

### Step 4: Extract Pattern Guidance

Summarize what should be searched for syntactically and what requires semantic
review. Identify whether follow-up belongs in:

- `variant-analysis`
- `semgrep-rule-creator`
- `static-analysis` with CodeQL or SARIF-producing tools
- manual review

### Step 5: Emit Handoff Packet

Use [references/output-format.md](references/output-format.md). Include
ranked candidates, inclusion reasons, exclusions, limitations, and the
variant-analysis handoff.

## Stop Conditions

- No graph binding exists
- Candidate count is too high and the root cause is underspecified
- Trailmark cannot analyze the target language
- The seed is only in test, generated, or vendor code and the user did not say
  that code is in scope

## agents

```

```

## agents/openai.yaml

```yaml
interface:
  icon_small: "assets/trail-of-bits-mark.svg"
  icon_large: "assets/trail-of-bits-mark.svg"
  brand_color: "#D83A34"
```

## assets

```

```

## assets/trail-of-bits-mark.svg

```

```

## references

```

```

## references/neighborhood-patterns.md

# Neighborhood Patterns

Use multiple bounded graph dimensions. Each dimension creates candidate review
targets, not findings.

| Dimension | Query idea | Variant hypothesis |
|---|---|---|
| Same caller | Other callees of the seed's caller | Caller applies the same bad precondition before several sinks |
| Same callee/sink | Other callers of the vulnerable sink | Missing validation before the same sink elsewhere |
| Same entrypoint path | Nodes on related paths from the same entrypoint | Adjacent unchecked operation in the same user flow |
| Same interface/override | Implementations of the same interface, trait, override, hook, or adapter family | One implementation fixed, sibling remains vulnerable |
| Same file/module cluster | Neighboring functions with similar dependencies | Copy/paste or parallel business logic |
| Same taint/boundary class | Nodes with the same taint and boundary status | Same trust transition, different operation |
| Same type/reference use | Functions touching the same critical type or state object | Missing invariant around the same asset |

## Query Sketches

```python
seed = "{bound_node}"
callers = engine.callers_of(seed)
callees = engine.callees_of(seed)

same_caller_candidates = []
for caller in callers:
    same_caller_candidates.extend(engine.callees_of(caller))

same_sink_candidates = []
for callee in callees:
    if is_sensitive_sink(callee):
        same_sink_candidates.extend(engine.callers_of(callee))

paths = engine.entrypoint_paths_to(seed)

if hasattr(engine, "type_references"):
    type_neighbors = engine.type_references(seed)
```

## Expansion Bounds

Use the smallest useful candidate set:

- cap each dimension at the top 10 candidates unless the user asks for more
- prefer graph distance 1 or 2 before wider expansion
- exclude generated, vendor, test, and mock paths by default
- stop and ask for a narrower root cause when more than 50 candidates survive
  first-pass ranking

## Evidence To Preserve

For each candidate, preserve:

- node ID and source location
- neighborhood dimension
- distance from seed when available
- reachability and trust level
- taint and privilege-boundary status
- shared sink, caller, interface, or type reason
- exclusion or penalty reason

## references/output-format.md

# Output Format

Use Markdown unless the user asks for JSON.

```markdown
# Trailmark Variant Neighborhood

## Seed

- Finding:
- Bound node:
- Root cause:

## Candidate Summary

| Rank | Candidate | Reason | Reachability | Confidence |
|---|---|---|---|---|

## Graph Neighborhoods

### Shared Callers
### Shared Callees / Sinks
### Entrypoint Path Neighbors
### Interface Or Implementation Siblings
### Type / State Neighbors

## Variant-Analysis Handoff

- Root cause:
- Keep specific:
- Abstract:
- Suggested searches:
- Suggested CodeQL/Semgrep direction:

## Exclusions And Limitations
```

## Wording Requirements

- Say "candidate" or "review target", not "variant vulnerability".
- Explain why each candidate was included.
- Separate graph similarity from semantic root-cause similarity.
- Include exclusions so reviewers understand why obvious nearby code was not
  prioritized.

## Handoff Guidance

For `variant-analysis`, provide:

- seed location
- root cause in one sentence
- ranked candidate table
- positive and negative examples
- graph dimensions that produced useful candidates

For `semgrep-rule-creator`, provide:

- the syntax that should stay specific
- the syntax that should be abstracted
- at least one true-positive candidate and one likely negative example

For `static-analysis`, provide:

- candidate files and functions
- suggested source, sink, or path query shape
- SARIF output expectation if the user wants machine-readable results

## references/ranking.md

# Ranking

Rank candidates by review value, not by confirmed severity.

## Positive Signals

| Signal | Effect |
|---|---|
| Entrypoint-reachable | Strong priority increase |
| Untrusted or semi-trusted entrypoint path | Strong priority increase |
| Tainted | Strong priority increase |
| Privilege-boundary adjacent | Strong priority increase |
| High blast radius | Priority increase |
| Shares vulnerable sink | Priority increase |
| Same interface, override, trait, hook, or adapter family | Priority increase |
| Same critical type or state reference | Priority increase |
| Graph distance 1 or 2 from seed | Priority increase |

## Negative Signals

| Signal | Effect |
|---|---|
| Unreachable from modeled entrypoints | Lower priority; keep if root cause is strong |
| Trusted-internal-only | Lower priority |
| Test, mock, generated, or vendor code | Exclude unless in scope |
| Ambiguous binding | Lower confidence |
| Proxy or dynamic edge uncertainty dominates | Lower confidence and add limitation |

## Rank Labels

| Rank | Meaning |
|---|---|
| `High` | Review first; strong structural similarity and reachability |
| `Medium` | Plausible variant; needs semantic review |
| `Low` | Weak or unreachable candidate; keep for completeness or deferred review |
| `Excluded` | Out of scope, generated, vendor, or insufficient binding |

## Confidence Labels

| Confidence | Use when |
|---|---|
| `High` | Exact binding, explicit relationship, clear reachability |
| `Medium` | Clear relationship but some path or root-cause uncertainty |
| `Low` | Ambiguous binding, dynamic dispatch uncertainty, or weak similarity |

