Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/plawio/veto/llms.txt

Use this file to discover all available pages before exploring further.

The veto scan command discovers tools in your codebase and checks which ones have policy rules defined.

Syntax

veto scan [options]

Description

Scans your codebase to:
  1. Discover tools from source code (TypeScript, Python)
  2. Load policy rules from veto/rules/
  3. Match tools to rules and identify coverage gaps
  4. Suggest policies for uncovered tools (optional)
  5. Report coverage as text or JSON

Options

Fail on Uncovered

--fail-uncovered
Exit with status code 1 if any tools are uncovered (useful for CI). Example:
veto scan --fail-uncovered

Suggest Policies

--suggest
Include AI-generated policy suggestions for uncovered tools. Example:
veto scan --suggest

Include Examples

--include-examples
Include examples/ directory in tool discovery. Example:
veto scan --include-examples

Include Tests

--include-tests
Include test/, tests/, __tests__/ directories in tool discovery. Example:
veto scan --include-tests

Format

--format <text|json>
Output format:
  • text - Human-readable (default)
  • json - Machine-readable JSON
Example:
veto scan --format json

Directory

--directory <path>
Project directory to scan (default: current directory). Example:
veto scan --directory ./packages/backend

Examples

Basic Scan

veto scan
Output:
Veto Scan Coverage Audit
========================

Project directory: /path/to/project
Rules directory: /path/to/project/veto/rules
Rules loaded: 8 (global: 2)
Framework hints: langchain, vercel-ai
Coverage: 8/12 (66.7%)

Discovered tools:
  [COVERED] transfer_funds(amount, recipient, currency)
    locations: src/tools/financial.ts
    sources: source-ts, policy
  [COVERED] approve_invoice(amount, vendor_id)
    locations: src/tools/invoices.ts
    sources: source-ts, policy
  [UNCOVERED] send_email(to, subject, body)
    locations: src/tools/email.ts
    sources: source-ts
  [UNCOVERED] execute_shell_command(command)
    locations: src/tools/shell.ts
    sources: source-ts

Scan with Suggestions

veto scan --suggest
Output:
Veto Scan Coverage Audit
========================

...

Suggested starter rules:

  send_email (@veto/communication)
  Rationale: Tool name matches communication keywords (e.g. email/message/notify).
  Snippet:
    rules:
      - id: guard-send-email
        name: Guard send_email
        description: Restrict sensitive outbound communication
        enabled: true
        severity: high
        action: block
        tools:
          - send_email
        conditions:
          - field: arguments.to
            operator: not_contains
            value: '@company.com'

  execute_shell_command (@veto/coding-agent)
  Rationale: Tool name matches coding-agent keywords (e.g. shell/exec/write_file).
  Snippet:
    rules:
      - id: guard-execute-shell-command
        name: Guard execute_shell_command
        description: Prevent destructive filesystem or shell operations
        enabled: true
        severity: critical
        action: block
        tools:
          - execute_shell_command
        conditions:
          - field: arguments.command
            operator: contains
            value: 'rm -rf'

JSON Output

veto scan --format json
Output:
{
  "timestamp": "2024-03-04T12:00:00.000Z",
  "projectDir": "/path/to/project",
  "policy": {
    "vetoDir": "/path/to/project/veto",
    "rulesDirectory": "/path/to/project/veto/rules",
    "recursiveRules": true,
    "rulesLoaded": 8,
    "globalRules": 2,
    "sourceFiles": [
      "veto/rules/defaults.yaml",
      "veto/rules/financial.yaml"
    ],
    "toolsReferenced": [
      "transfer_funds",
      "approve_invoice"
    ]
  },
  "manifest": {
    "packageJsonFound": true,
    "pyprojectFound": false,
    "jsDependencies": ["@langchain/core", "ai"],
    "pythonDependencies": [],
    "frameworks": ["langchain", "vercel-ai"]
  },
  "discoveredTools": [
    {
      "name": "transfer_funds",
      "parameters": ["amount", "recipient", "currency"],
      "locations": ["src/tools/financial.ts"],
      "sources": ["source-ts", "policy"],
      "covered": true,
      "coverageReason": "tool-rule",
      "matchedRuleIds": ["block-large-transfers"]
    },
    {
      "name": "send_email",
      "parameters": ["to", "subject", "body"],
      "locations": ["src/tools/email.ts"],
      "sources": ["source-ts"],
      "covered": false,
      "coverageReason": "none",
      "matchedRuleIds": []
    }
  ],
  "summary": {
    "total": 12,
    "covered": 8,
    "uncovered": 4,
    "coveragePercent": 66.67
  },
  "suggestions": []
}

CI/CD Gate

veto scan --fail-uncovered
Output (if uncovered tools exist):
Veto Scan Coverage Audit
========================

...

Coverage: 8/12 (66.7%)

Error: 4 uncovered tools found

(exits with code 1)

Scan Specific Directory

veto scan --directory ./packages/backend

How It Works

1. Tool Discovery

Scans source code for tool definitions: TypeScript:
// Detected patterns
tool({ name: "transfer_funds", ... })
const myTool = tool(...)
new DynamicTool({ name: "send_email", ... })
function_tool("execute_code", ...)
Python:
# Detected patterns
@tool
def transfer_funds(amount: int):
    pass

class TransferTool(BaseTool):
    name = "transfer_funds"

2. Policy Loading

Loads rules from veto/rules/:
rules:
  - id: block-large-transfers
    tools:
      - transfer_funds

3. Coverage Matching

Matches tools to rules:
  • COVERED: Tool has specific rule or global rule applies
  • UNCOVERED: Tool has no rules

4. Suggestions (Optional)

Generates policy suggestions based on tool name heuristics:
  • transfer, payment → @veto/financial
  • email, message → @veto/communication
  • navigate, click → @veto/browser-automation
  • query, database → @veto/data-access
  • shell, exec → @veto/coding-agent
  • deploy, release → @veto/deployment

Use Cases

Pre-Commit Hook

#!/bin/bash
# .git/hooks/pre-commit

veto scan --fail-uncovered --format text

if [ $? -ne 0 ]; then
  echo "Error: Uncovered tools found. Add policies before committing."
  exit 1
fi

CI Pipeline

# .github/workflows/veto.yml
name: Veto Policy Check

on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
      - run: npm install -g veto-cli
      - run: veto scan --fail-uncovered --format json > scan-report.json
      - uses: actions/upload-artifact@v3
        with:
          name: veto-scan-report
          path: scan-report.json

Weekly Coverage Report

#!/bin/bash
# cron: 0 9 * * 1 (Every Monday at 9am)

veto scan --suggest --format text > weekly-coverage-report.txt
cat weekly-coverage-report.txt | mail -s "Veto Coverage Report" team@company.com

Find Uncovered Tools

veto scan --format json | jq '.discoveredTools[] | select(.covered == false) | .name'
Output:
"send_email"
"execute_shell_command"
"browse_web"
"query_database"

Coverage Reasons

tool-rule

Tool has a specific rule targeting it:
rules:
  - id: block-transfers
    tools:
      - transfer_funds  # Specific match

global-rule

Tool is covered by a global rule (no tools: field):
rules:
  - id: log-all-tools
    action: log
    # No tools field = applies to all tools

none

Tool has no matching rules:
[UNCOVERED] send_email(to, subject, body)

Troubleshooting

No Tools Discovered

No tools discovered from policy files or source heuristics.
Solution:
  • Check that you’re using supported tool libraries (LangChain, Vercel AI, etc.)
  • Verify tool definitions follow standard patterns
  • Use --include-tests or --include-examples if tools are there

Low Coverage

Coverage: 2/20 (10.0%)
Solution:
# Generate suggestions
veto scan --suggest > suggestions.txt

# Generate policies for uncovered tools
veto policy generate --tool <name> --prompt "..."

# Or add global rule
echo 'rules:\n  - id: require-approval-all\n    action: require_approval' > veto/rules/global.yaml

False Positives

Scan detects non-tool functions: Solution:
  • Exclude directories: Don’t use --include-tests or --include-examples
  • Tools must follow standard naming patterns
  • Report false positives as bugs

Best Practices

1. Scan Regularly

# Add to package.json
{
  "scripts": {
    "veto:scan": "veto scan",
    "veto:check": "veto scan --fail-uncovered"
  }
}

# Run before commits
npm run veto:check

2. Use in CI

# Fail builds if coverage drops
veto scan --fail-uncovered

3. Track Coverage Over Time

# Save scan results
veto scan --format json > coverage-$(date +%Y%m%d).json

# Compare over time
jq '.summary.coveragePercent' coverage-*.json

4. Generate Suggestions

# Get policy suggestions
veto scan --suggest > suggestions.md

# Review and implement
vim suggestions.md

Next Steps

Build docs developers (and LLMs) love