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
EVD-02 · WITNESS READING · SAMPLE READOUT
The readout below is the full Witness Reading 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
A readout states the scope, the recorded calls and the hash-chain check. That check establishes internal consistency, not identity, origin, completeness or an independent timestamp. Call counts here come from the export.
IN SCOPE
postgres-prod · github · slack · filesystem
RECORDED
4 server-reported errors · 1 unresolved · 22 reported successes.
FINDINGS
These synthetic findings combine tool records with the scenario's permissions and supporting context. Server responses alone do not independently prove what changed in a target system.
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.
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.
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.
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.
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.
Every principal is declared by the harness config (--as) and none is cryptographically verified. Each principal field states verified: false. Identity proof is outside this record and the reading.
Fix. Decide whether declared identity is acceptable for your audit posture before the next review.
REMEDIATION PLAN
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.
| # | Action | Owner | Effort | Closes |
|---|---|---|---|---|
| 1 | Scope filesystem and GitHub tokens to the approved paths and repos | Platform | 2 days | F1 F3 |
| 2 | Read-only database role for agent principals; deny-alerting | Data | 1 day | F2 |
| 3 | Slack app scopes and channel allow-list | IT | half a day | F4 |
| 4 | Harness timeout/retry policy; keep the recorder running | Platform | 1 day | F5 |
| 5 | Decision: declared vs verified principals | Security lead | readout | F6 |
EVIDENCE EXPORT
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
Check chain consistency: git clone https://github.com/dark-vector-cognition/witness && node witness/bin/witness.mjs verify sessions.jsonl
ONE RECORD, VERBATIM
This tool-call record contains the request, path summary, declared principal, client and hash chain. It does not prove the file was read or contain its contents.
{
"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
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
1 session · 1 server (desktop-commander) · 1 declared principal.
THE FINDING
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
Aggregate error rate was 12% - unremarkable. Every failure was one tool. This is why a Witness Reading reports per tool, not per session.
| Tool | Calls | Errors | Error rate | p50 ms | p95 ms |
|---|---|---|---|---|---|
| read_file | 12 | 3 | 25% | 62 | 529 |
| list_directory | 6 | 0 | 0% | 2 | 2 |
| get_file_info | 3 | 0 | 0% | 2 | 2 |
| get_config | 1 | 0 | 0% | 18 | 18 |
| get_usage_stats | 1 | 0 | 0% | 1 | 1 |
| list_processes | 1 | 0 | 0% | 169 | 169 |
| list_sessions | 1 | 0 | 0% | 3 | 3 |
Check the redacted export's chain consistency: git clone https://github.com/dark-vector-cognition/witness && node witness/bin/witness.mjs verify sessions.jsonl
WITNESS READING · SCOPED · LOCAL RECORDS, REVIEWED EXPORTS
Thirty minutes to confirm scope and dates, then a fixed price in writing. If a Witness Reading is not the right instrument for your estate, we will say so on the call. A recorder that stopped recording, like ours did, is what Witness Rollout fixes.