summaryrefslogtreecommitdiff
path: root/constrain/README.txt
blob: 6d4b882aed5ceb34728cd1e299a04592b76160ed (plain) (blame)
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
74
75
76
77
78
79
80
81
82
Constrain agents to read files only through notevi — 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)
notevi-only-guard.sh           PreToolUse hook: blocks cat/rg/sed/... and
                               jj/git content reads; its error message points
                               the agent at `notevi -doc`, so agents converge
                               even with zero instructions
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 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 <notevi-repo>/constrain/claude-headless-settings.json \
         --allowedTools 'Bash(notevi)' 'Bash(notevi:*)' \
         < prompt.txt > report.md

  (<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
    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 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/notevi-only.rules        # deactivate when done

  - danger-full-access is required: workspace-write blocks jj metadata writes,
    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 notevi-only.rules -- cat foo.txt

── shared trace + rendering ────────────────────────────────────────────────
  - 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
    (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:
      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:
      notevi web -repo <repo> -title "..."
    or take a static copy to hand around (one change, no server features):
      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 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).