AGENT FLIGHT CHECK · SAMPLE READOUT

What the readout looks like before you pay for one.

The readout below is the full Flight Check format, produced by the real recorder — Witness v0.3 — against a synthetic estate of four MCP servers and four principals, because one studio does not have four of each to show you. The estate is invented; the records, the report and the verification are not. At the end, the same instrument on our own estate, with the finding it caught here. Download either export and run witness verify on it yourself.

COVER PAGE

Scope and record.

A real readout opens with what was in scope, what was recorded, and whether the record is intact. Numbers here are read from the export at build time, not typed.

IN SCOPE

4 servers · 4 principals

postgres-prod · github · slack · filesystem

  • svc-analytics — declared, not verified
  • svc-release-bot — declared, not verified
  • svc-oncall-agent — declared, not verified
  • m.okafor — declared, not verified

RECORDED

27 tool calls

4 refused by the target system · 1 never answered · 22 completed.

  • 4 / 4 HASH CHAINS VERIFIED · 0 BROKEN LINKS
  • ARGUMENTS AND RESULTS HASHED, NOT STORED
  • SUMMARY FIELDS ALLOW-LISTED PER SERVER: repo, path, channel

FINDINGS

Six findings, ranked, each with its evidence.

A finding is a sentence a CISO can repeat, the records that support it, and the fix. Nothing here is inferred from a screenshot.

F1HIGHfilesystem · m.okafor via cursor

A developer's coding agent read /srv/app/.env, attempted /home/deploy/.ssh/id_ed25519, and was denied on /etc/shadow. The filesystem server is mounted at / for an agent whose job is one application directory.

Fix. Scope the filesystem server to /srv/app; move secrets out of files the agent can reach.

F2HIGHpostgres-prod · svc-analytics via claude-code

Five queries from an analytics principal, one refused by the database as permission-denied. Query text is hashed, not stored; the refused statement is identified from the database's own log in the interview. Either way, an analytics credential is being used beyond a read-only grant.

Fix. Issue a read-only role for svc-analytics; alert on any denied statement from an agent principal.

F3MEDIUMgithub · svc-release-bot via claude-code

The release bot merged a pull request in acme/platform and attempted a merge in acme/infra, which was refused. The token is repo-wide when the approved scope was one repository.

Fix. Fine-grained token limited to acme/platform; merge only via a protected-branch rule that requires a human review.

F4MEDIUMslack · svc-oncall-agent via claude-desktop

The on-call agent posted to #general (approved scope: #incidents), looked up an executive by email, and attempted to read #exec-private, which was refused.

Fix. Restrict the bot's channel allow-list to #incidents; remove users:read.email.

F5LOWfilesystem · list_directory /mnt/nfs/backups

One call never received an answer: the server exited after 370 ms. Witness recorded the call as unknown, not as success. A retry loop on the agent side would have masked this.

Fix. Timeout and retry policy on the harness; alert on unknown outcomes.

F6NOTEAll four principals

Every principal is declared by the harness config (--as) and none is cryptographically verified. The record says so on every line (verified: false). Identity proof is a follow-on build, not part of the two-week check.

Fix. Decide whether declared identity is acceptable for your audit posture before the next review.

REMEDIATION PLAN

What to do Monday.

Ordered by risk removed per day of work. Estimates are what engineering can act on the same week; you can take the plan to your own team or to us.

#ActionOwnerEffortCloses
1Scope filesystem and GitHub tokens to the approved paths and reposPlatform2 daysF1 F3
2Read-only database role for agent principals; deny-alertingData1 dayF2
3Slack app scopes and channel allow-listIThalf a dayF4
4Harness timeout/retry policy; keep the recorder runningPlatform1 dayF5
5Decision: declared vs verified principalsSecurity leadreadoutF6

EVIDENCE EXPORT

The files you keep.

Three files, all yours. The report is generated by witness report; the sessions file is the raw hash-chained record; the checkpoints file is the chain heads, chained again.

DOWNLOAD

Export bundle

Verify: git clone https://github.com/dark-vector-cognition/witness && node witness/bin/witness.mjs verify sessions.jsonl

ONE RECORD, VERBATIM

The read of a private key

Note what is present (tool, path summary, principal, client, hash chain) and what is absent (file contents, the full argument object).

{
  "v": "0.1",
  "seq": 12,
  "ts": "2026-09-12T23:37:44.772Z",
  "session": "s_ac5761f3",
  "event": "tool_call",
  "rpc_id": 15,
  "tool": "read_file",
  "args_sha256": "8cbae1d71d242fe96189b44ab7a97a23a3a94f68dfde52e9625d19d5a904b4ea",
  "args_bytes": 39,
  "args_summary": {
    "path": "/home/deploy/.ssh/id_ed25519"
  },
  "actor": {
    "client": "cursor",
    "version": "1.4.2",
    "protocol": "2025-06-18"
  },
  "principal": {
    "as": "m.okafor",
    "source": "flag",
    "verified": false
  },
  "server": {
    "name": "filesystem",
    "cmd_sha256": "02a751c263674851df7fab225085d4241ce610bc049b22b5ac5809c9deaba85e"
  },
  "prev": "8099faf071d4e216ffd1f182af317b662b21f8930e2d528e5dc4fd6c1160ef57",
  "hash": "fd9086914301b6b3c42363db1a2643a4a6f5f87e03c86930e98e162931c458d5"
}

REPORT.MD, VERBATIM

# Witness report — last 1d

Generated 2026-09-12T23:37:47.076Z · log /sessions/rcw-013spsibfthc6kbi23qcnnp4/wh-sample/log

| Sessions | Servers | Principals | Tool calls | Errors | Unanswered | Broken chains |
|---|---|---|---|---|---|---|
| 4 | 4 | 4 | 27 | 4 (15%) | 1 | 0 |

## Calls by tool

| Tool | Calls | Errors | Open | p50 ms | p95 ms |
|---|---|---|---|---|---|
| read_file | 5 | 1 | 0 | 1 | 15 |
| query | 5 | 1 | 0 | 0 | 13 |
| conversations_history | 3 | 1 | 0 | 0 | 0 |
| merge_pull_request | 2 | 1 | 0 | 1 | 1 |
| write_file | 2 | 0 | 0 | 1 | 1 |
| list_directory | 2 | 0 | 1 | 370 | 370 |
| chat_postMessage | 2 | 0 | 0 | 14 | 14 |
| search_issues | 1 | 0 | 0 | 14 | 14 |
| get_pull_request | 1 | 0 | 0 | 3 | 3 |
| create_pull_request | 1 | 0 | 0 | 0 | 0 |
| list_commits | 1 | 0 | 0 | 0 | 0 |
| create_issue | 1 | 0 | 0 | 1 | 1 |
| users_lookupByEmail | 1 | 0 | 0 | 0 | 0 |

## Calls by server

- **filesystem** — 9
- **github** — 7
- **slack** — 6
- **postgres-prod** — 5

## Calls by declared principal

- m.okafor — 9 _(declared, not verified)_
- svc-release-bot — 7 _(declared, not verified)_
- svc-oncall-agent — 6 _(declared, not verified)_
- svc-analytics — 5 _(declared, not verified)_

## Integrity

- ✓ 4 chain(s) verified, no broken links

Peak hour (UTC): 23:00 with 27 calls.

_Arguments and results are hashed, never stored. See SPEC.md._

FINDING F6, ON OUR OWN ESTATE · NOT A SAMPLE

Config drift, caught on our own estate.

The readout above uses a synthetic estate, because one studio does not have four servers and four principals to show you. This section does not. It is finding F6 — config drift — found on DVC's own machine by DVC's own recorder, with every number read from the export at build time.

RECORDED

25 tool calls

1 session · 1 server (desktop-commander) · 1 declared principal.

  • 54 RECORDS · 1/1 CHAINS VERIFIED · 0 BROKEN LINKS
  • 3 ERRORS (12%) · 0 UNANSWERED
  • ARGUMENTS HASHED, NEVER STORED — NO FILE PATH APPEARS IN ANY RECORD

THE FINDING

The recorder was not recording.

The wrapped config on this machine pointed at a Node binary that a Homebrew upgrade had broken. The server never started, so nothing was recorded — and an empty log looks exactly like a quiet estate. The config on the machine had drifted from the config in the repository, and nothing noticed until someone asked the record a question. It is fixed; the recorder is running.

Read the write-up →

PER TOOL · READ FROM THE EXPORT

The session average hid the only interesting number.

Aggregate error rate was 12% — unremarkable. Every failure was one tool. This is why a Flight Check reports per tool, not per session.

ToolCallsErrorsError ratep50 msp95 ms
read_file12325%62529
list_directory600%22
get_file_info300%22
get_config100%1818
get_usage_stats100%11
list_processes100%169169
list_sessions100%33

Verify it yourself: git clone https://github.com/dark-vector-cognition/witness && node witness/bin/witness.mjs verify sessions.jsonl

TWO WEEKS · $7,500 · NOTHING LEAVES YOUR NETWORK

Your estate, this format.

Thirty minutes to confirm scope and dates. If the Flight Check isn't the right instrument for your estate, we'll say so on the call.

Book the readout call →