Community

Architecture

Ghost Security Agent's architecture separates deterministic tools from AI judgment. This page covers the technical design and how everything fits together.


Design principles

Tools are standalone. Each tool is a self-contained Go binary that does one job. No tool depends on another tool, the skills layer, or any external service. You can use Poltergeist, Wraith, or Reaper independently without installing Ghost Security Agent.

Skills are composable. Each skill can run independently or as part of a pipeline. Skills read artifacts from previous skills when available (e.g., scan-code reads the repo context from repo-context) but degrade gracefully when they're missing.

Everything is local. No telemetry, no cloud services, no data leaving your machine. Tools download their databases locally (Wraith's OSV database, Poltergeist's embedded rules). Skills cache results to the local filesystem.

Output is auditable. Every finding traces back to specific tool output and specific criteria. You can always inspect the raw Poltergeist matches, the raw Wraith CVE data, or the specific criteria that triggered an Exorcist finding.


Tool architecture

All three Go tools follow similar patterns:

CLI structure

  • Poltergeist -- single command with flags (poltergeist [flags] <path>)
  • Wraith -- subcommands (wraith scan, wraith download-db, wraith version)
  • Reaper -- subcommands via Cobra (reaper start, reaper search, reaper get, reaper stop)

Output formats

All tools support multiple output formats:

FormatUse case
Text (colored)Interactive terminal use
JSONProgrammatic consumption, skill integration
MarkdownReports, documentation, issue tracking

JSON is the primary integration format. Skills parse JSON output from tools.

Binary distribution

Tools are distributed as precompiled binaries via GitHub Releases and installed to ~/.ghost/bin/. The skills layer handles automatic binary download and verification during initialization.


Skill architecture

Skill definition format

Each skill is a SKILL.md file that defines:

  • Tool restrictions -- which Claude Code tools the skill can use (Read, Write, Glob, Grep, Bash, Task)
  • Execution pipeline -- numbered steps the skill follows
  • Input/output contracts -- what the skill reads and what it produces
  • Sub-agent definitions -- for multi-agent skills, references to agent prompt files

Multi-agent patterns

Skills use three architectural patterns:

Orchestrator + sub-agents (scan-deps, scan-secrets) -- a read-only orchestrator spawns sub-agents via the Task tool. Each sub-agent reads its instructions from a prompt file in the skill directory. The orchestrator coordinates but doesn't do the work directly.

Orchestrator (SKILL.md)
├── Task -> Init agent (agents/init/agent.md)
├── Task -> Discover agent (agents/discover/agent.md)
├── Task -> Scan agent (agents/scan/agent.md)
├── Task -> Analyze agent (agents/analyze/agent.md)
└── Task -> Summarize agent (agents/summarize/agent.md)

Loop-based funnel (scan-code) -- a single agent executes all steps directly, using a loop script for resumability. Progress is tracked in checkpoint files (plan.md, nominations.md, analyses.md) so work can resume after timeouts.

Interactive workflow (validate) -- a single agent with step-by-step execution and optional user interaction. Reads findings, traces code, and optionally uses Reaper for live testing.


Data Structure

Cache and Results

~/.ghost/
├── bin/                              # Tool binaries
│   ├── poltergeist
│   ├── wraith
│   └── reaper
└── repos/
    └── <repo_id>/                    # Per-repository
        ├── cache/
        │   └── repo.md              # Repository context (shared)
        └── scans/
            └── <commit_sha>/        # Per-commit
                ├── deps/
                │   ├── lockfiles.json
                │   ├── candidates.json
                │   ├── findings/
                │   └── report.md
                ├── secrets/
                │   ├── candidates.json
                │   ├── findings/
                │   └── report.md
                ├── code/
                │   ├── plan.md
                │   ├── nominations.md
                │   ├── analyses.md
                │   └── findings/
                └── report.md         # Combined report

repo_id is computed from the repository name and remote URL hash, ensuring unique caching per repository.

commit_sha (short) provides per-commit isolation. Scanning the same commit twice returns cached results. A new commit triggers fresh scans.

Data flow between skills

The repo-context output is shared context that informs all scans. It's required for scan-code (to plan which vulnerability vectors to check) and opportunistically loaded when present by the other skills to enrich context (but isn't required for basic operation).


Reaper internals

Reaper has a distinct architecture due to its daemon-based design:

Components

CLI ──── Unix socket (IPC) ──── Daemon
                                  ├── HTTP proxy server
                                  ├── TLS interception (in-memory CA)
                                  ├── Scope filter
                                  └── SQLite storage

IPC protocol

The CLI and daemon communicate via JSON messages over a Unix domain socket at ~/.reaper/reaper.sock:

  • Request: {"command": "search", "params": {"method": "POST", "limit": 50}}
  • Response: {"ok": true, "data": [...]}

Commands: logs, search, get, req, res, shutdown, ping

TLS interception

  1. Client sends CONNECT request to proxy
  2. If in-scope: proxy hijacks TCP connection, responds with 200, starts TLS with generated cert
  3. If out-of-scope: proxy blindly relays bytes between client and server (transparent pass-through)
  4. Per-host certificates are cached in a sync.Map for performance

Design rationale

Go for tools. Single-binary distribution, fast startup, cross-platform compilation. No runtime dependencies.

Markdown for skills. Skills are prompts. Markdown is human-readable, version-controllable, and doesn't require a build step.

YAML for criteria. Structured enough to be machine-parseable, readable enough to be human-reviewed. The AI reads criteria during analysis, and humans review them for correctness.

Local-only. Security tools that send your code to external services create a trust problem. Ghost Security Agent runs entirely on your machine. The only network calls are to the OSV vulnerability database (and even that supports offline mode).

Tool/skill split. Deterministic tools provide a reliable foundation. Pattern matches, CVE lookups, and traffic captures produce the same output every time. The AI layer adds judgment and context, but the underlying data is always verifiable.

Previous
Contributing