summaryrefslogtreecommitdiff
path: root/constrain
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-02 23:43:08 -0300
committerGabriel Schneider <[email protected]>2026-08-03 09:54:39 -0300
commit5ec72f8723d795d0b02d7e9ebb9f555f0c7e6a2e (patch)
treef12f4b700fff4ff6f7e818d2a542672ba0b8d76e /constrain
parenta9263daee9413c5eff3c1f1bebcd224442fd8685 (diff)
downloadnotevi-5ec72f8723d795d0b02d7e9ebb9f555f0c7e6a2e.tar.gz
notevi-5ec72f8723d795d0b02d7e9ebb9f555f0c7e6a2e.zip
rebrand to notevi: one CLI over the jj sidecar
vr and vrsite become a single binary. vrsite/ folds into a web package in one module (0x4200.cafe/notevi); "notevi web" serves and exports exactly what vrsite did, and "notevi read/grep/note/query" is unchanged. The sidecar is renamed with it: notevi_log, notevi-log.jsonl, and the description "private: notevi log". The pre-rebrand names are still recognized, so an old repository opens and reads; it is renamed in place on the first write, or up front with "notevi migrate DIR...". That rename cannot be a single mv inside jj run. jj only auto-tracks a *new* file in the run working copy below a size limit it does not take from the command line, so writing a whole log under a name the change has never held is silently dropped while jj reports success. ensureLogFile creates the file empty first and lets every later byte be a modification of a tracked file, which snapshots at any size; that also fixes the same latent bug when importing a large legacy vr-log.jsonl. Adds a bem-te-vi mark (favicon and nav brand) and a README. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Diffstat (limited to 'constrain')
-rw-r--r--constrain/AGENTS.md14
-rw-r--r--constrain/README.txt57
-rw-r--r--constrain/claude-headless-settings.json4
-rw-r--r--constrain/claude-settings.json4
-rwxr-xr-xconstrain/notevi-only-guard.sh (renamed from constrain/vr-only-guard.sh)6
-rw-r--r--constrain/notevi-only.rules (renamed from constrain/vr-only.rules)8
6 files changed, 49 insertions, 44 deletions
diff --git a/constrain/AGENTS.md b/constrain/AGENTS.md
index 871fc6c..93df43b 100644
--- a/constrain/AGENTS.md
+++ b/constrain/AGENTS.md
@@ -1,14 +1,14 @@
# Reading code here
-Files are read with the `vr` tool — run `vr -doc` once for full usage.
+Files are read with the `notevi` tool — run `notevi -doc` once for full usage.
-`vr` stores the trace in the repo's private local jj sidecar named `vr_log`.
-Do not set `VR_LOG`, pass `-log`, or create a working-tree `vr-log.jsonl`.
+`notevi` stores the trace in the repo's private local jj sidecar named
+`notevi_log`. Do not create a working-tree log file; there is no path to set.
-- `vr read FILE:START-END` — line-numbered read; prefer ranges over whole files
-- `vr grep PATTERN [PATH]` — regex search; scope with a path
-- `vr read -r REV FILE`, `vr grep -r REV PATTERN PATH` — at another jj change
-- `vr note -f FILE:10-42 -t struct TEXT...` — record observations as you read
+- `notevi read FILE:START-END` — line-numbered read; prefer ranges over whole files
+- `notevi grep PATTERN [PATH]` — regex search; scope with a path
+- `notevi read -r REV FILE`, `notevi grep -r REV PATTERN PATH` — at another jj change
+- `notevi note -f FILE:10-42 -t struct TEXT...` — record observations as you read
Navigate top-down: grep for the symbol, read the enclosing range, note what
you learn. Every entry records the full current jj change and commit IDs; the
diff --git a/constrain/README.txt b/constrain/README.txt
index 4da2733..6d4b882 100644
--- a/constrain/README.txt
+++ b/constrain/README.txt
@@ -1,4 +1,4 @@
-Constrain agents to read files only through vr — enforcement comes from
+Constrain agents to read files only through notevi — enforcement comes from
harness config; AGENTS.md is navigation guidance only, never the constraint.
── files here ──────────────────────────────────────────────────────────────
@@ -6,26 +6,28 @@ 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
+notevi-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
+ the agent at `notevi -doc`, so agents converge
even with zero instructions
-vr-only.rules codex execpolicy rules (allow vr, forbid readers)
-AGENTS.md how-to-navigate-with-vr guidance for the repo
+notevi-only.rules codex execpolicy rules (allow notevi, forbid
+ readers)
+AGENTS.md how-to-navigate-with-notevi 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)
+put it on PATH: go build -o ~/.local/bin/notevi . (repo root)
+
+ one binary now: agents call `notevi read/grep/note`, and you
+ read the trace back with `notevi web`
── running a constrained CLAUDE investigation ──────────────────────────────
From the target jj repo dir:
- claude -p --settings <vr-repo>/constrain/claude-headless-settings.json \
- --allowedTools 'Bash(vr)' 'Bash(vr:*)' \
+ claude -p --settings <notevi-repo>/constrain/claude-headless-settings.json \
+ --allowedTools 'Bash(notevi)' 'Bash(notevi:*)' \
< prompt.txt > report.md
- (<vr-repo> is wherever this repo lives; the settings file's hook path is
+ (<notevi-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
@@ -36,42 +38,45 @@ From the target jj repo dir:
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)
+ cp notevi-only.rules ~/.codex/rules/ # activate (GLOBAL: constrains
+ # every codex session while there)
codex exec -s danger-full-access "$(cat prompt.txt)" > report.md
- rm ~/.codex/rules/vr-only.rules # deactivate when done
+ rm ~/.codex/rules/notevi-only.rules # deactivate when done
- danger-full-access is required: workspace-write blocks jj metadata writes,
- including the sidecar rewrite and `vr read`'s working-copy snapshot.
+ including the sidecar rewrite and `notevi read`'s working-copy snapshot.
- 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
+ codex execpolicy check --rules notevi-only.rules -- cat foo.txt
── shared trace + rendering ────────────────────────────────────────────────
- - vr creates one anonymous sidecar change directly under jj's root() on the
- first append. The repo-local alias vr_log names it; git.private-commits
- protects it from accidental pushes. No path or environment setup exists.
+ - notevi creates one anonymous sidecar change directly under jj's root() on
+ the first append. The repo-local alias notevi_log names it;
+ git.private-commits protects it from accidental pushes. No path or
+ environment setup exists.
+ - A repository last written by the older `vr` tool is renamed in place the
+ first time notevi touches it; `notevi migrate <repo>...` does it up front.
- Multiple agents in the repo share that sidecar. Rewrites are serialized,
note ids are assigned under the same lock, and the project @ is untouched.
- The sidecar has no bookmark and is local-only. It does not survive a fresh
clone; include the jj repository in backups when the trace matters.
- In the prompt, tell the agent to leave pinned notes
- (vr note -f FILE:START-END -t kind "...") — that is the payload.
- - Read traces afterwards from one process. Bare `vrsite` scans below ~ at
+ (notevi note -f FILE:START-END -t kind "...") — that is the payload.
+ - Read traces afterwards from one process. Bare `notevi web` scans below ~ at
startup and when Refresh is pressed, then offers every repo with a sidecar:
- vrsite
+ notevi web
Its explicit buttons can start an empty private sidecar in a discovered jj
repo or initialize colocated jj in a discovered Git repo. The project index
is only in memory; those two requested metadata changes are the only writes.
- To bypass the dashboard and serve one repository directly:
- vrsite -repo <repo> -title "..."
+ notevi web -repo <repo> -title "..."
or take a static copy to hand around (one change, no server features):
- vrsite -repo <repo> -out site -title "..."
- `vrsite -h` explains both, and what a log needs to be worth reading.
+ notevi web -repo <repo> -out site -title "..."
+ `notevi web -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
+rules in notevi-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).
diff --git a/constrain/claude-headless-settings.json b/constrain/claude-headless-settings.json
index 30aff9b..b22704c 100644
--- a/constrain/claude-headless-settings.json
+++ b/constrain/claude-headless-settings.json
@@ -1,7 +1,7 @@
{
"permissions": {
"deny": ["Read", "Grep", "Glob"],
- "allow": ["Bash(vr)", "Bash(vr:*)"]
+ "allow": ["Bash(notevi)", "Bash(notevi:*)"]
},
"hooks": {
"PreToolUse": [
@@ -10,7 +10,7 @@
"hooks": [
{
"type": "command",
- "command": "/home/goblin/00-projects/01-tools/vr-agent-logger/constrain/vr-only-guard.sh"
+ "command": "/home/goblin/00-projects/01-tools/notevi/constrain/notevi-only-guard.sh"
}
]
}
diff --git a/constrain/claude-settings.json b/constrain/claude-settings.json
index 524ccbd..639befb 100644
--- a/constrain/claude-settings.json
+++ b/constrain/claude-settings.json
@@ -1,7 +1,7 @@
{
"permissions": {
"deny": ["Read", "Grep", "Glob"],
- "allow": ["Bash(vr)", "Bash(vr:*)"]
+ "allow": ["Bash(notevi)", "Bash(notevi:*)"]
},
"hooks": {
"PreToolUse": [
@@ -10,7 +10,7 @@
"hooks": [
{
"type": "command",
- "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/vr-only-guard.sh"
+ "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/notevi-only-guard.sh"
}
]
}
diff --git a/constrain/vr-only-guard.sh b/constrain/notevi-only-guard.sh
index 0de698f..729f4d4 100755
--- a/constrain/vr-only-guard.sh
+++ b/constrain/notevi-only-guard.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Claude Code PreToolUse hook (matcher: Bash): deny shell commands that read
-# files without going through vr. A guardrail, not a jail — it catches the
+# files without going through notevi. A guardrail, not a jail — it catches the
# common readers at command position, not every conceivable bypass.
cmd=$(jq -r '.tool_input.command // empty')
@@ -8,12 +8,12 @@ readers='cat|head|tail|less|more|sed|awk|cut|rg|grep|egrep|fgrep|find|fd|strings
pattern='(^|[;&|(`]|\$\()[[:space:]]*('$readers')([[:space:]]|$)'
if printf '%s' "$cmd" | grep -qE "$pattern"; then
- echo "blocked: read/search files only through vr (run 'vr -doc' for usage)" >&2
+ echo "blocked: read/search files only through notevi (run 'notevi -doc' for usage)" >&2
exit 2
fi
vcs='jj[[:space:]]+(file[[:space:]]+show|diff)|git[[:space:]]+(show|diff|grep|cat-file|blame|log)'
if printf '%s' "$cmd" | grep -qE "(^|[;&|(\`])[[:space:]]*($vcs)"; then
- echo "blocked: use 'vr read -r REV FILE' / 'vr grep -r REV' instead of raw jj/git reads" >&2
+ echo "blocked: use 'notevi read -r REV FILE' / 'notevi grep -r REV' instead of raw jj/git reads" >&2
exit 2
fi
exit 0
diff --git a/constrain/vr-only.rules b/constrain/notevi-only.rules
index 54d3392..f618f18 100644
--- a/constrain/vr-only.rules
+++ b/constrain/notevi-only.rules
@@ -1,12 +1,12 @@
-# codex execpolicy: force file reading through vr (which logs every read).
-# Activate: cp vr-only.rules ~/.codex/rules/
-# Deactivate: rm ~/.codex/rules/vr-only.rules
+# codex execpolicy: force file reading through notevi (which logs every read).
+# Activate: cp notevi-only.rules ~/.codex/rules/
+# Deactivate: rm ~/.codex/rules/notevi-only.rules
# The engine parses through `/bin/zsh -lc '...'` wrappers, so these match the
# inner command. Editing tools (apply_patch) are unaffected — this only
# constrains reading. Known hole: scripting runtimes can still open files;
# uncomment the last block to close it at the cost of breaking legit scripts.
-prefix_rule(pattern=["vr"], decision="allow")
+prefix_rule(pattern=["notevi"], decision="allow")
prefix_rule(pattern=["cat"], decision="forbidden")
prefix_rule(pattern=["head"], decision="forbidden")