1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
Constrain agents to read files only through vr — enforcement comes from
harness config; AGENTS.md is navigation guidance only, never the constraint.
── files here ──────────────────────────────────────────────────────────────
claude-settings.json project install: <repo>/.claude/settings.json
(hook path uses $CLAUDE_PROJECT_DIR)
claude-headless-settings.json no-install variant for `claude -p --settings`
(hook path is absolute into this dir)
vr-only-guard.sh PreToolUse hook: blocks cat/rg/sed/... and
jj/git content reads; its error message points
the agent at `vr -doc`, so agents converge
even with zero instructions
vr-only.rules codex execpolicy rules (allow vr, forbid readers)
codex-config.toml optional: centralize VR_LOG for codex
AGENTS.md how-to-navigate-with-vr guidance for the repo
── one-time setup ──────────────────────────────────────────────────────────
put both on PATH: go build -o ~/.local/bin/vr . (repo root)
cd vrsite && go build -o ~/.local/bin/vrsite .
(vr is what agents call; vrsite is how you read the trace)
── running a constrained CLAUDE investigation ──────────────────────────────
No repo mutation needed; from the target repo dir:
VR_LOG=/abs/path/trace.jsonl \
claude -p --settings <vr-repo>/constrain/claude-headless-settings.json \
--allowedTools 'Bash(vr)' 'Bash(vr:*)' \
< prompt.txt > report.md
(<vr-repo> is wherever this repo lives; the settings file's hook path is
absolute into this directory, so it must be spelled out in full)
- --allowedTools on the CLI is required headless: allow rules inside
settings are IGNORED until the workspace is trusted (deny rules and the
hook always apply). Interactive use instead: install claude-settings.json
+ hook into the repo's .claude/, open once, accept the trust dialog.
- put the prompt on stdin; a positional prompt after --allowedTools gets
eaten by the flag's list parsing.
── running a constrained CODEX investigation ───────────────────────────────
cp vr-only.rules ~/.codex/rules/ # activate (GLOBAL: constrains
# every codex session while there)
VR_LOG=/abs/path/trace.jsonl \
codex exec -s danger-full-access "$(cat prompt.txt)" > report.md
rm ~/.codex/rules/vr-only.rules # deactivate when done
- danger-full-access is required: workspace-write blocks .git/ writes,
which kills jj's working-copy snapshot and with it `vr read`.
- enforcement is pre-exec by codex's execpolicy engine, even through
`zsh -lc` wrappers; validate rules with:
codex execpolicy check --rules vr-only.rules -- cat foo.txt
── shared trace + rendering ────────────────────────────────────────────────
- VR_LOG must point at a FILE path whose parent exists. If the path is a
directory (or becomes one), agents improvise their own log files and you
will be merging jsonl afterwards. Ask me how I know.
- Multiple agents may share one log: note ids are per-session, appends are
line-atomic. Same file = one merged timeline for free.
- In the prompt, tell the agent to leave pinned notes
(vr note -f FILE:START-END -t kind "...") — that is the payload.
- Read the trace afterwards — serve it, and write notes of your own back
into the same log:
vrsite -log trace.jsonl -repo <repo> -title "..."
or take a static copy to hand around (one change, no server features):
vrsite -log trace.jsonl -repo <repo> -out site -title "..."
`vrsite -h` explains both, and what a log needs to be worth reading.
── known holes (accepted) ──────────────────────────────────────────────────
Scripting runtimes (python/node/perl) can still open files — uncomment their
rules in vr-only.rules / extend the hook to close, at the cost of breaking
legitimate scripts. Neither harness constrains its own non-shell internals
beyond what the deny rules cover. Codex's rules file is global-only; there is
no per-project rules mechanism (probed, none exists as of codex 0.145).
|