01Safety
0.0 / 30
What changed in the harness
Selection accuracy 96→96, token cost up 6%, unconfirmed writes 0%→0%.
Category breakdown
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
0.0 / 30
24.0 / 30
18.9 / 20
9.9 / 20
Highest-impact fix
Estimated gain +30 pointsExpose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
12 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
read_file |
name_restates_behavior params_unexplained |
DEPRECATED: Use read_text_file instead. Reads the file at 'path' and returns its complete contents as text. If 'head' is provided, returns only the first N lines; if 'tail' is provided, returns only the last N lines. Returns an object with the file content as a string. |
read_text_file |
params_unexplained |
Read the complete contents of the file at 'path' from the file system as text. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Use the 'head' parameter to read only the first N lines of a file, or the 'tail' parameter to read only the last N lines of a file. Operates on the file as text regardless of extension. Only works within allowed directories. |
read_media_file |
params_unexplained |
Read the file at 'path' and return it as a base64-encoded content block with its MIME type. Image and audio files are returned as image/audio content; any other file type is returned as an embedded resource. Only works within allowed directories. |
write_file |
params_unexplained |
Create a new file at 'path' or completely overwrite an existing file with the text in 'content'. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories. |
edit_file |
params_unexplained |
Apply line-based edits to the text file at 'path'. Each item in the 'edits' array replaces exact line sequences ('oldText') with new content ('newText'). Set 'dryRun' to true to preview changes using git-style diff format without applying them. Returns a git-style diff showing the changes made. Only works within allowed directories. |
create_directory |
params_unexplained |
Create a new directory at 'path' or ensure it exists. Can create multiple nested directories in one operation. If the directory already exists, this operation will succeed silently. Perfect for setting up directory structures for projects or ensuring required paths exist. Only works within allowed directories. |
list_directory |
params_unexplained |
Get a detailed listing of all files and directories in the directory at 'path'. Results clearly distinguish between files and directories with [FILE] and [DIR] prefixes. This tool is essential for understanding directory structure and finding specific files within a directory. Only works within allowed directories. |
list_directory_with_sizes |
params_unexplained |
Get a detailed listing of all files and directories in the directory at 'path', including sizes. Results clearly distinguish between files and directories with [FILE] and [DIR] prefixes. 'sortBy' sorts entries by name or size. This tool is useful for understanding directory structure and finding specific files within a directory. Only works within allowed directories. |
directory_tree |
params_unexplained |
Get a recursive tree view of the files and directories under 'path' as a JSON structure. Each entry includes 'name', 'type' (file/directory), and 'children' for directories. Files have no children array, while directories always have a children array (which may be empty). 'excludePatterns' is an array of glob-style patterns used to exclude entries from the tree. The output is formatted with 2-space indentation for readability. Only works within allowed directories. |
move_file |
params_unexplained |
Move or rename the file or directory at 'source' to 'destination'. Can move files between directories and rename them in a single operation. If the destination exists, the operation will fail. Works across different directories and can be used for simple renaming within the same directory. Both source and destination must be within allowed directories. |
search_files |
params_unexplained |
Recursively search within 'path' for files and directories matching 'pattern'. Patterns should be glob-style and match paths relative to the working directory. Use pattern like '*.ext' to match files in the current directory, and '**/*.ext' to match files in all subdirectories. 'excludePatterns' is an array of glob patterns to skip during the search. Returns full paths to all matching items. Great for finding files when you don't know their exact location. Only searches within allowed directories. |
get_file_info |
params_unexplained |
Retrieve detailed metadata about the file or directory at 'path'. Returns comprehensive information including size, creation time, last modified time, permissions, and type. This tool is perfect for understanding file characteristics without reading the actual content. Only works within allowed directories. |
Selection evidence
8 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
read_file |
read_text_file |
high | A task like 'read the file at /tmp/notes.txt' matches both near-identically; read_file is only distinguished by a deprecation note deferring to read_text_file, so name/keyword-based selection can pick the obsolete tool. |
list_directory |
list_directory_with_sizes |
medium | Both descriptions promise 'a detailed listing of all files and directories' for a specified path; a task like 'list the contents of /data' can select either, and picking the plain tool silently drops sizes the user may have wanted. |
read_file |
read_multiple_files |
medium | Tasks like 'read the contents of the project files' are ambiguous about count; the plural tool only works with a paths array while read_file's name matches the singular query, so the wrong tool for the actual list size can be chosen. |
read_file |
read_media_file |
medium | A type-agnostic 'read the file <path>' task is ambiguous; read_file returns text while read_media_file returns base64/MIME content, so selecting the wrong one yields unusable output such as rendering an image as text. |
list_directory |
directory_tree |
medium | 'Show me the directory structure' maps to both; list_directory produces a flat single-level listing while directory_tree produces a recursive JSON tree, so the intended depth is unclear from the task. |
list_directory |
list_allowed_directories |
medium | A request like 'which directories can I access?' or 'list the directories' could mean either listing a path's contents or listing the allowed roots; list_allowed_directories takes no path, so the wrong pick can fail or return irrelevant data. |
read_text_file |
read_media_file |
low | When a file's type is unspecified, 'read the file' could land on the text reader even for images/audio, but the explicit base64/MIME framing of read_media_file usually steers selection correctly. |
write_file |
edit_file |
low | 'Update the file with new content' is ambiguous between a full overwrite (write_file) and targeted line replacements (edit_file), though the descriptions differentiate them strongly enough that confusion is uncommon. |
Compare the field