ZIFFER home

The scanner: what it reads

Who this is for: anyone deciding how far to trust a scan, before and after reading its report.

Who this is for: anyone deciding how far to trust a scan, before and after reading its report.

What you end up with: the limits of the scan first, then the frameworks it reads by language, how it finds skills and instruction files, and what it reads on your machine.


1. What the scan does not read, and cannot know

Read these before the rest. The report prints the ones that apply to your code, each with a count and, where it has one, a file and line.

  • It reads files, never a running system. It does not run your application, call a tool, or watch a real call. Everything it says is a reading of source code and configuration.
  • A check it did not find is not proof that nobody is asked. It looks for a confirmation check just before the call that runs your tools, by a short list of names. A check spelled another way, or made somewhere else, is not seen. The reverse holds too: a check it found is a line of code, not proof that the check stops anything.
  • Tools that only exist at run time are not listed. Tools your code fetches from a tool server while it runs are not in the report; it names the place in your code where they are attached. A tool set built at run time is traced back through the code where it can be, and the report counts the ones it could not name. When data decides at run time which tools a user sees, the scan lists every tool that can be offered, not the set any one user gets.
  • Tools a model provider runs on its own servers are listed where the code offers them. No call to them reaches your application, so ZIFFER can only decide whether they are offered at all.
  • It follows types in TypeScript and JavaScript, and only so far. That is how it finds tools your application defines through its own helper functions. It reads each tsconfig.json's files with that file's settings, and every other source file with default settings. A file whose imports cannot be resolved makes the grade provisional, because tools defined through them may be missing: run the scan after installing your dependencies. Code loaded by a computed name, such as a dynamic import or eval, is not followed. Each tool's function is followed a few calls deep into your own code, and the report says how deep.
  • Python is read by its syntax only, with your machine's own Python 3.9 or later. Without that Python, the Python files are counted and not read.
  • Other languages are counted, not read, and so are frameworks the scan does not know. A tool defined in a language or through a framework not listed in section 2 is not in the report.
  • Some folders are skipped when reading code: dependencies, build output, version control, test code, hidden folders, and a second checkout of the project inside it. They are recognised by their name, so your own source kept in a folder called build, dist, out or test is skipped too. The report counts what was skipped and why.
  • Every classification is read from a name or a description. A tool whose words say nothing about undoing it counts against the grade today, until you say whether it can be undone. A flag your code sets on a tool definition, such as one saying it needs approval, is recorded as a claim, and the draft policy does not rely on it.

2. The frameworks it reads, by language

These lists are generated from the scanner's own data file, so they match version 0.3.0 exactly. A framework that is not in these lists is not recognised at all: tools defined through it are not in the report, and the report does not name it as missing. The one exception is tools built with your own helper functions on top of a listed format, which the scan finds by following types (the "app-local tool factory" line). Instructor is read in order to leave it out: structured output runs no tool. Python includes the code cells of Jupyter notebooks.

TypeScript and JavaScript

  • Amazon Bedrock Converse
  • Anthropic Messages API
  • App-local tool factory (found by type)
  • Claude Agent SDK
  • Cohere
  • Genkit
  • Google Gemini (Gen AI SDK)
  • Instructor and structured output (an exclusion: nothing executes)
  • LangChain / LangGraph
  • LlamaIndex
  • Mastra
  • MCP server (Model Context Protocol)
  • Mistral
  • OpenAI Agents SDK
  • OpenAI Chat Completions / Responses (also Azure OpenAI and compatible endpoints)
  • Vercel AI SDK
  • VS Code language model tools

Python

  • AG2 (AutoGen legacy line and AG2 1.x)
  • Amazon Bedrock Converse
  • Anthropic Messages API
  • Claude Agent SDK
  • Cohere
  • CrewAI
  • DSPy
  • Google Agent Development Kit
  • Google Gemini (Gen AI SDK)
  • Haystack
  • Instructor and structured output (an exclusion: nothing executes)
  • LangChain / LangGraph
  • LlamaIndex
  • MCP server (Model Context Protocol)
  • Microsoft Agent Framework (and Microsoft AutoGen AgentChat)
  • Mistral
  • OpenAI Agents SDK
  • OpenAI Chat Completions / Responses (also Azure OpenAI and compatible endpoints)
  • Pydantic AI
  • Semantic Kernel
  • smolagents
  • Strands Agents

Configuration files

  • Coding-assistant hooks (Claude Code, Cursor, Devin Desktop)
  • VS Code language model tools

3. Skills and instruction files

The scan reads skills and instruction files as text. It never runs them, and it reads them only when it reads your code. A file is found in any of three ways, and the report says which:

  • By its name: a file called SKILL.md in any folder, and the instruction files a coding assistant loads by name: CLAUDE.md, AGENTS.md, GEMINI.md, .cursorrules, .windsurfrules and .github/copilot-instructions.md.
  • By its shape: a .md, .mdx, .mdc, .txt or .prompt file whose front matter has both a name and a description. Files under documentation, blog or website content folders are left out, because a web page can carry the same two keys.
  • By your code: a file your application reads, embeds or imports.

For each file the report says who loads it, your coding assistant or your application, what it declares, such as its list of allowed tools, and what it does, such as running a shell command, reaching the network, writing outside its own folder, or reading a credential. Text that reads like an instruction aimed at an AI agent is a finding. A skill that declares no tool list is not a finding, because declaring one is optional. The scan does not follow symbolic links, so a skill linked into two places is read once.


4. The AI tools installed on your machine

In the default run, and with --no-code, the scan reads the tool server configuration of the AI coding tools it knows, in your home folder and in the project. The report names every AI tool it looked for, and every one it cannot read at all.

To learn which tools a server offers, it has to start the server, and it asks first. It asks each server only for its list of tools and never calls one. A remote server, one that is turned off, and one whose command is not installed are not started, and the report says which and why. A tool the scan cannot classify gets no rule in the draft, so the draft refuses it.

Running the scan explains what the scan starts and what it never does.

On this page