semantic-gap-investigator

semantic-gap-investigator is a skill for Claude Code, Codex from PlamenTSV/plamen. It costs 55 tokens per session (2,493 once invoked), scanned A, original, MIT.

A code-audit agent that traces missing updates and inconsistent state changes across smart-contract code.

In plain words
What is it for?
It is for investigating synchronization gaps, conditional writes, and related state-tracking problems in protocols.
Why use it?
It helps reveal bugs caused when one execution path updates shared state but another path skips the update.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one.

Good fit It is for investigating synchronization gaps, conditional writes, and related state-tracking problems in protocols.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/plamentsv/plamen/semantic-gap-investigator
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add PlamenTSV/plamen --skill semantic-gap-investigator
Clone the repo
git clone --depth 1 https://github.com/PlamenTSV/plamen

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for semantic-gap-investigator

README.md
[![agentmods](https://agentmods.dev/badge/skills/plamentsv/plamen/semantic-gap-investigator/github.svg)](https://agentmods.dev/skills/plamentsv/plamen/semantic-gap-investigator)
Your own site
<a href="https://agentmods.dev/skills/plamentsv/plamen/semantic-gap-investigator"><img src="https://agentmods.dev/badge/skills/plamentsv/plamen/semantic-gap-investigator/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for semantic-gap-investigator

Your own site · 80×15
<a href="https://agentmods.dev/skills/plamentsv/plamen/semantic-gap-investigator"><img src="https://agentmods.dev/badge/skills/plamentsv/plamen/semantic-gap-investigator.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 55 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,493 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe. Third-party audits
  • NVIDIA SkillSpector pass 7 Sept 2026
How audits are shown
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00055 $0.02493
Opus 5 $0.00028 $0.01247
Sonnet 5 $0.00011 $0.00499
Haiku 4.5 $0.00006 $0.00249

Measured 9d ago against content hash 415092d85949, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-12, from the pricing page.

Security

Grade A, and why

semantic-gap-investigator scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

agents/skills/niche/semantic-gap-investigator/SKILL.md · 135 lines

How it starts

The opening of the file, as written. The whole thing — 135 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Niche Agent: Semantic Gap Investigator

Trigger: Semantic Invariant Agent (Phase 4a.5) reports sync_gaps >= 1 OR accumulation_exposures >= 1 OR conditional_writes >= 1 OR cluster_gaps >= 1 in its return message Agent Type: general-purpose (standalone niche agent, NOT injected into another agent) Budget: 1 depth budget slot in Phase 4b iteration 1 Finding prefix: [SGI-N]

When This Agent Spawns

The Semantic Invariant Agent (Phase 4a.5) Pass 2 returns a summary: 'DONE: {G} cluster_gaps, {T} consequence traces ({D} deep_propagation), {W} missed_write_sites, {B} branch_asymmetries'. Pass 1 returns: 'DONE: {N} variables, {M} gaps, {C} conditional, {S} sync_gaps, {A} accumulation, {K} clusters'. If S >= 1 OR A >= 1 OR C >= 1 OR G >= 1, the orchestrator spawns this agent.

CONDITIONAL writes on accumulator/snapshot/tracking variables are now in-scope. The semantic invariant agent pre-filters - it only annotates CONDITIONALs on state-tracking variables (not every if in the codebase), so the investigation set is bounded. Depth agents do not systematically trace conditional skip-path consequences through consumer functions; this agent does.

Agent Prompt Template

Task(subagent_type="general-purpose", prompt="
You are the Semantic Gap Investigator. You take pre-flagged SYNC_GAP, ACCUMULATION_EXPOSURE, and CONDITIONAL annotations from the Semantic Invariant Agent and investigate each one to a definitive conclusion (exploitable or benign).

## Your Inputs
Read:
- {SCRATCHPAD}/semantic_invariants.md (the Main Table CONDITIONAL annotations, Mirror Variable Pairs, and Time-Weighted Accumulators tables, plus any Potential Gaps column entries tagged SYNC_GAP, ACCUMULATION_EXPOSURE, or CONDITIONAL)
- {SCRATCHPAD}/state_variables.md (variable definitions)
- {SCRATCHPAD}/function_list.md (all functions)
- Source files referenced in the gap annotations

## Processing Protocol (MANDATORY)

For each analysis step below, execute in order:
1. **ENUMERATE targets**: List every entity the step applies to (gaps, variables, functions) as a numbered list before analysis begins.
2. **PROCESS exhaustively**: Analyze each numbered entity. Mark each "DONE" or "N/A (reason)" before moving to the next.
3. **COVERAGE GATE**: Count enumerated vs processed. If any entity lacks a marker, process it before proceeding to the next step.

## Your Task

### STEP 1: Extract Investigation Targets

From semantic_invariants.md, collect every entry tagged:
- **SYNC_GAP(other_var, function)**: A function writes one mirror variable but not the other
- **ACCUMULATION_EXPOSURE(input, time_source)**: A time-weighted calculation with externally controllable input and unbounded time delta
- **CONDITIONAL(condition_expression)**: A write to an accumulator/snapshot/tracking variable that only executes when a condition is true - callers that trigger the enclosing function when the condition is false leave this variable stale

### STEP 2: Investigate Each SYNC_GAP

For each SYNC_GAP:
1. Read the function that creates the gap (writes variable A but not variable B)
2. Identify ALL consumers that read the stale variable B after the gap-creating function executes
3. For each consumer: trace the execution with concrete values showing the stale read produces a wrong result
4. Check: is the gap self-correcting? If yes, how long can the window last? What functions trigger correction?
5. Check: can any action during the gap window cause permanent damage (e.g., setting a checkpoint to a stale value)?

Verdict per gap:
- **EXPLOITABLE**: Consumer produces materially wrong result during window, AND window can last > 1 block, AND either (a) window is unbounded or (b) permanent damage is possible during window. **After EXPLOITABLE verdict**: The confirmed mechanism requires precondition P. Using the Main Table write sites (including constructor), verify no other code path also establishes P. If found: investigate and create a separate finding.
- **BENIGN**: Gap exists but all consumers are overridden/unused, OR gap self-corrects within same transaction, OR stale value direction is always conservative (undercharges, not overcharges)

### STEP 3: Investigate Each ACCUMULATION_EXPOSURE

For each ACCUMULATION_EXPOSURE:
1. Read the accumulation formula and identify the controllable input and time source
2. Model the attack: Can an actor (permissionless OR semi-trusted) manipulate the controllable input, wait for time to pass, then trigger the accumulation to snapshot the manipulated state?
3. Quantify: What is the maximum excess accumulation from a single manipulation? Use concrete values (e.g., 1000 ETH deposit, 7-day stale period, 10% annual fee rate)
4. Check mitigations: Does the protocol snapshot BEFORE or AFTER the manipulation? Does it use min(old, new) or time-weighted averages? Are there caps?
5. Check composition: Can multiple exposures be combined (e.g., inflate supply AND extend time delta in the same attack)?

Verdict per exposure:
- **EXPLOITABLE**: Manipulation produces > 1% excess accumulation with realistic parameters, AND no mitigation fully prevents it, AND attacker can profit (or protocol loses funds). **After EXPLOITABLE verdict**: The confirmed mechanism requires precondition P. Using the Main Table write sites (including constructor), verify no other code path also establishes P. If found: investigate and create a separate finding.
- **BENIGN**: Mitigations prevent meaningful manipulation, OR the exposure is bounded below materiality, OR the controllable input requires fully-trusted actor access

### STEP 4: Investigate Each CONDITIONAL Write

For each CONDITIONAL annotation on an accumulator/snapshot/tracking variable:
1. Identify the function containing the conditional write and the condition expression
2. Identify ALL callers of that function (direct and indirect via call chain)
3. For each caller: determine if the caller can trigger the function when the condition is FALSE (the skip path). What concrete state causes the skip? (e.g., `vestingGains == 0` after full vest (vesting vaults), `pendingRewards == 0` after claim (staking), `timeElapsed == 0` in same block, `totalSupply == 0` after last exit (share-based pools))
4. When the write is skipped, identify ALL consumer functions that READ the stale variable afterward - within the same caller's execution AND in subsequent external calls
5. For each consumer: trace execution with the stale value using concrete numbers. Does the stale read produce a materially wrong result?
6. Check temporal scope: how long can the stale value persist? Until the next call that satisfies the condition? Unbounded?

Verdict per conditional:
- **EXPLOITABLE**: Consumer produces materially wrong result with stale value, AND the skip path is reachable under normal operation (not just error/revert paths), AND the staleness window can last > 1 block. **After EXPLOITABLE verdict**: The confirmed mechanism requires precondition P. Using the Main Table write sites (including constructor), verify no other code path also establishes P. If found: investigate and create a separate finding.
- **BENIGN**: Skip path is unreachable under normal operation, OR all consumers handle the stale value correctly, OR staleness self-corrects within the same transaction

### STEP 5: Trace Conditional Skip Paths for SYNC_GAP functions

For each function identified in STEP 2 as creating a sync gap:
- Does ANY caller of this function assume the gap does NOT exist?
- Specifically: if function F creates a sync gap when condition C is false, does any caller of F (e.g., `distributeYield`/`recordLoss` (vesting vaults), `reportProfit`/`reportLoss` (Yearn-style), `notifyRewardAmount`/`getReward` (staking)) rely on the variable being updated regardless of C?
- If yes: trace the caller's subsequent logic with the stale value to find the impact

**Coverage assertion**: Before returning, verify every entity enumerated under each step has been processed. Report enumerated vs analyzed counts in your return message.

## Output Format

### Flag Disposition Table (MANDATORY - write FIRST, update per flag)

Write this skeleton table to {SCRATCHPAD}/niche_semantic_gap_findings.md BEFORE starting investigation.
Update each row's Disposition as you investigate. PENDING rows at completion = workflow violation.

| # | Flag Type | Variable | Location | Disposition | If BENIGN: Defense (file:line) | If EXPLOITABLE: Finding ID |
|---|-----------|----------|----------|-------------|-------------------------------|---------------------------|

Every SYNC_GAP, ACCUMULATION_EXPOSURE, CONDITIONAL, and CLUSTER_GAP flag from semantic_invariants.md
MUST appear as a row. The orchestrator verifies: count(rows) == count(flags).

### Findings

Use standard finding format with [SGI-N] IDs.

For each finding, include:
- **Gap Type**: SYNC_GAP, ACCUMULATION_EXPOSURE, CONDITIONAL_SKIP, or CLUSTER_GAP
- **Source Annotation**: Quote the exact annotation from semantic_invariants.md
- **Investigation Result**: EXPLOITABLE or BENIGN with full reasoning
- **Concrete Values**: Numeric trace showing the wrong result (for EXPLOITABLE)

## Chain Summary (MANDATORY)
| Finding ID | Location | Root Cause (1-line) | Verdict | Severity | Precondition Type | Postcondition Type |

Write to {SCRATCHPAD}/niche_semantic_gap_findings.md

Return: 'DONE: {S} sync gaps, {A} accumulation exposures, {C} conditional writes, {G} cluster gaps - {T} total flags dispositioned, {E} exploitable'
")

Read the full file on GitHub · 135 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 9d ago First seen · 135 lines · 55 tokens per session scan A 415092d85949

Subscribe to this mod's changes

semantic-gap-investigator is a skill published in the GitHub repository PlamenTSV/plamen (295 stars, last pushed 4d ago), licensed MIT. It adds 55 tokens to every session and 2,493 once invoked, about $0.0003 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-03.