pointbreak 0.5.0

Durable terminal code review for changes humans and coding agents collaborate on together
Documentation
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
# Review Workflow

This document describes the intended end-to-end workflow for reviewing a
tool-assisted change with Pointbreak today. Command reference details live in the
`README.md`; this is the narrative version that explains *when* to run each
command and *why*. If the change was authored by a coding agent, start with
[Agent authoring handoffs](agent-authoring.md) for the capture-at-end-of-work loop.

## What Pointbreak reviews

Pointbreak reviews a **revision**: the base endpoint, the target endpoint, and a
captured diff snapshot taken at a single moment. Capturing a revision is the one **generative move**
in the workflow — proposing a captured work object for others to assert facts about — while "review"
stays the surface verb. V1 captures one of two shapes:
the local Git worktree from `HEAD` to the working tree, including untracked files
(the default); or, with `shore capture --base <rev>`, the committed range
between two resolved commits (`<rev>..--target`, target defaulting to `HEAD`),
read as a tree diff with no working-tree involvement.

Each revision binds an immutable **object artifact** by content hash. The artifact body is
content-only, so two revisions capturing the same change in different worktrees share one
byte-identical artifact — they converge on a single **object** — rather than each owning a distinct
copy. The revision is the captured unit's identity; the object is a hash of its content alone.
Anything you record afterwards — observations, input requests, assessments — attaches to that
revision and lives in the durable `events/` log.

A later capture can record that it **supersedes** one or more earlier revisions, forming a
fork-tolerant succession graph. A reviewer is free to counter-propose by capturing their own revision
that supersedes yours. Successive rounds never mutate the captured snapshots; the thread's current
**head** is derived from the supersession graph, and when two captures supersede the same predecessor
the **competing heads** are surfaced rather than one silently winning.

## The workflow at a glance

1. Start from a Git worktree containing the change you want to review.
2. Capture a revision with `shore capture`.
3. Inspect what was captured with `shore revision show` and
   `shore history`.
4. Record review facts as you read the diff:
   - **Observations** are notes you want preserved.
   - **Input requests** are durable pause/decision requests for someone else.
   - **Assessments** are the current review call for the revision (or for a
     file, range, or specific fact within it).

The rest of this document walks through each step.

## 1. Start in a worktree with the change

Pointbreak runs inside a Git worktree. For the default capture the working tree
must differ from `HEAD`; the change can come from anywhere — a coding agent, a
teammate's WIP branch, your own edits — but it must be present in the working
tree before capture. Pointbreak reads the diff from `git`; it does not summarize
prior commits on its own. If the change is already committed, capture the
committed range directly with `shore capture --base <rev>` (see
[section 2](#2-capture-a-revision)) instead of recreating it in the working
tree.

```bash
cd path/to/worktree
git status        # confirm the changes you expect are present
```

By default the store is the shared common-dir store at `.git/shore`, under the clone's Git common
directory — every worktree of the clone resolves the same store, and because it lives inside `.git`
it never appears in `git status`, so ordinary captures never touch the working tree at all. Opting
into an ephemeral worktree (`shore store mode ephemeral`) or writing a `--local` identity override
generates a committed `.shore/.gitignore` (two lines: `data/` + `*.local.json`) that keeps the
worktree-local store and the private overrides out of `git status`; the file is visible, meant to
be committed, and survives clone. If the paths are already ignored — for example by a project
`.gitignore` entry — Pointbreak generates nothing and leaves your ignore files untouched. Nothing
writes the hidden `.git/info/exclude` anymore.

## 2. Capture a revision

```bash
shore capture
```

`shore capture` records a `work_object_proposed` event and writes the
captured snapshot as an immutable Pointbreak-owned object artifact. The output document is
`shore.review-capture` JSON and includes:

- the revision ID
- the object ID (the content-only identity)
- the object artifact's canonical content hash

You can pin later commands to the captured revision with `--revision
<id>`. When only one revision exists in the store, commands that need a
current revision pick it automatically. When multiple exist, list them with
`shore revision list` and pass either the exact revision ID or seed a
supersession thread with `--revision <id>`.

The snapshot is now frozen. Re-running `shore capture` later creates a
new revision; it does not mutate the previous one.

### Capturing a committed range

When the change is already committed and the working tree is clean, capture the
landed range instead of recreating a working-tree diff:

```bash
shore capture --base <commit-before-the-change>   # target defaults to HEAD
shore capture --base <rev> --target <rev>         # explicit range
```

`--base`/`--target` resolve any rev (a branch, tag, `HEAD~N`, or commit OID) to a
commit; annotated tags peel, and a non-commit or unknown rev is rejected with an
honest error. The capture is the `base..target` tree diff — both endpoints are
`git_commit`, no working-tree or untracked state is read, and no worktree path
appears in the output. This is the supported way to review after landing: never
rewrite history (for example `git reset --soft`) to manufacture a worktree diff.

A post-landing range capture is a second current revision alongside any
worktree capture, so disambiguate later reads and writes with `--revision
<id>`, exactly as for any multi-capture store. Recording the
landed commit, choosing a canonical capture, and revision lifecycle remain open
follow-ups.

### Scoping a capture to a subtree

In a monorepo a review is usually about one subtree, but the worktree and the
commits interleave changes across many. Scope the capture with `--path` so
unrelated changes stay out of the reviewer's diff and out of the revision's
identity:

```bash
# review only what changed under packages/foo, in the current worktree
shore capture --path packages/foo

# same, over an explicit range
shore capture --base v1.2.0 --target HEAD --path docs/spec
```

`--path` takes a native git pathspec, is repeatable, and scopes tracked and
untracked files alike; a scope that matches no changed files is an error. See
[`shore capture`](./cli-reference.md#shore-capture) for the full
semantics.

Record a succession round by naming the revisions a new capture supersedes:

```bash
shore capture --supersedes <revision-id>
shore capture --supersedes <revision-id> --supersedes <other-revision-id>
```

The `supersedes` set is order-independent and may name more than one predecessor. There is no
separate lineage command or declared lineage id — the thread is the connected component of the
`supersedes` graph, and its current **head** is derived from that graph. When two captures supersede
the same predecessor, the resulting **competing heads** are surfaced as competing, never collapsed to
a single winner.

Write commands such as `shore observation add`,
`shore input-request open`, and `shore assessment add` accept
`--revision <id>`. When more than one captured revision is current, pass
the ID from capture output or `shore revision list`; otherwise writes fail
with an ambiguity error.

Supersession makes that ambiguity contextual. A revision-scoped read seeds on `--revision <id>` and
resolves that revision's thread head; unscoped current selection remains ambiguous when multiple
unrelated captures exist. Routine list, history, and exact-revision reads have no always-on
ambiguous-current warning. A thread-level read may report `stale_by_superseding_revision` when a fact
targets a revision that a newer revision supersedes, but exact-revision reads remain valid for
superseded revisions.

## 3. Inspect what was captured

Three read surfaces describe revisions, and they answer different questions:

```bash
shore revision list     # what revisions exist in the store
shore revision show          # composite revision view (narrative + snapshot)
shore history       # chronological raw event listing
```

For a visual, cross-linked view of the whole store — an event timeline, composite per-revision
pages, supersession-thread pages, and captured diffs annotated with their review facts — run
`shore inspect` to open a local web UI (see the [CLI reference](cli-reference.md)). The commands
below remain the scriptable surface.

### `shore revision list`

`shore revision list` projects every `work_object_proposed` event into a
flat directory of revisions. It is the discovery surface — start here when
`shore revision show` errors with `multiple captured revisions; pass
--revision`, or whenever you need to pick an ID for `--revision <id>`.

It returns `shore.review-revision-list` JSON with `eventSetHash`, `eventCount`,
`revisionCount`, and an `entries` array whose elements include
`revisionId`, `capturedAt`, `objectId`, `source`, `base`,
`target`, and `objectArtifactContentHash`. Entries are sorted by capture
time so the newest revision appears last. Pass `--object <object-id>` to list only the revisions
that share one content object — a listing lens that may span threads, never a head selector.

```bash
shore revision list --pretty
```

When a revision supersedes another, the list/read projections build the supersession DAG and surface
each thread's competing heads. That view is a thread over immutable captures, not an interdiff
renderer; this release has no interdiff or stack DAG. Capture facts remain signable through the
generic `EventToBeSigned` producer-fact view and ADR-0004's Dead Simple Signing Envelope (DSSE)
pre-authentication encoding.

### `shore revision show`

`shore revision show` is the composite view of one revision. It returns
`shore.review-revision` JSON containing:

- revision identity and event-set freshness metadata
- summary counts and current assessment status
- native observations, input requests, and assessments
- projection rows (narrative-first, then snapshot-complete)
- diagnostics

Narrative rows (native facts) appear before the snapshot
remainder, but the snapshot remainder still includes every captured file,
metadata row, hunk header, and diff row. Track filters narrow narrative facts
without changing snapshot completeness.

```bash
shore revision show --pretty
shore revision show <revision-id>
shore revision show --track agent:codex
shore revision show --include-body
```

Passing a revision id seeds head selection on that revision and resolves its thread's current
head; an intra-thread fork is reported as competing revisions.

### `shore history`

`shore history` is the chronological raw-event listing across the
entire `events/` log — across revisions if there is more than one.
It is the place to answer "what happened, in what order?" rather than
"what does this revision look like right now?".

```bash
shore history --pretty
shore history --event-type review-observation-recorded
shore history --revision <id> --include-body
```

`eventSetHash` and `eventCount` describe the full validated event set used to
build the document, even when filters return only a subset of entries.
History preserves duplicate semantic events as separate entries; it does not
collapse them or pick "winners".

## 4. Record review facts

The three event families below are append-only. Each writes one durable event
per call. Read surfaces collapse same-semantic-ID writes to one logical row
and surface a duplicate diagnostic.

### Observations

An observation is a durable note for a revision, a file, or a line range.
Observations are append-only; corrections are new observations that name the
older observation through `--supersedes`.

```bash
# Review-wide observation
shore observation add \
  --track agent:codex \
  --title "Check error handling near IO boundary"

# File-targeted observation
shore observation add \
  --track agent:codex \
  --title "Untrusted input flows here" \
  --file src/lib.rs

# Range-targeted observation, with a body from a file
shore observation add \
  --track human:kevin \
  --title "Worth a unit test" \
  --file src/lib.rs --start-line 42 --end-line 58 \
  --body-file notes/lib-42.md

# Replay observations for one track
shore observation list --track agent:codex --pretty

# Include bodies on read
shore observation list --include-body
```

Bodies may come from `--body`, `--body-file`, or `--body-stdin`. Large bodies
are stored as Pointbreak-owned content-addressed artifacts; command output never
exposes those paths.

### Input requests

An input request is a durable pause/decision request. Use it when a reviewer
or tool needs an explicit answer before proceeding. `--mode` defaults to
`operative`; `advisory` requests are still durable and visible but do not
imply that a cooperative client must pause.

```bash
shore input-request open \
  --track human:kevin \
  --title "Need approval to land schema change" \
  --reason manual-decision-required

shore input-request list                 # defaults to open
shore input-request list --status all
shore input-request show <input-request-id> --include-body

shore input-request respond <input-request-id> \
  --outcome approved \
  --reason "discussed in chat, ok to land"
```

`--reason` on the request is the classification axis (`manual-decision-required`,
`ambiguous-state`, `unsafe-action`, etc.). `--outcome` on the response is a
separate axis (`approved`, `rejected`, `dismissed`, `superseded`, `abandoned`).

Multiple different response events are preserved as append-only facts and
make the input request `ambiguous` rather than picking a timestamp winner.

### Assessments

An assessment is the current review call for a revision, a file, a range,
or a specific native observation/input request/assessment in the same
revision. CLI input and human-facing display use `accepted`,
`accepted-with-follow-up`, `needs-changes`, and `needs-clarification`; command
JSON output uses the matching `snake_case` values.

```bash
shore assessment add \
  --track human:kevin \
  --assessment accepted \
  --summary "looks good, ship it"

# Assessment that replaces an older one
shore assessment add \
  --track human:kevin \
  --assessment accepted-with-follow-up \
  --summary "supersedes earlier needs-changes after offline discussion" \
  --replaces <older-assessment-id>

shore assessment show --pretty
shore assessment show --all --include-summary
```

`--replaces` is the only V1 relationship that removes an older assessment
from the current set.
`--related-observation` and `--related-input-request` record evidence links;
they do not mutate observations or close input requests (use
`shore input-request respond` for the input-request lifecycle).

State-change outcomes such as deferred, split-out, overridden, and superseded
are recorded as observations tagged with `state-change:*`. Use
`shore assessment` for review calls and `shore observation add`
with a concrete tag such as `--tag state-change:deferred` for state-change
evidence.

## 5. Concepts you need to know

### Durable event facts vs. rebuildable projections

Pointbreak separates **authoritative facts** from **derived views**. The paths below are relative to
the resolved store directory — `.git/shore` by default, or a worktree-local `.shore/data/` when the
worktree is ephemeral:

- `events/` is the authoritative append-only log. Each file is one
  immutable durable fact. Events are never moved, retried in place, or
  rewritten on read.
- `artifacts/` holds the immutable support records that events bind to:
  captured revision object artifacts, and the optional content-addressed bodies
  for large observation, input request, and assessment payloads.
- `state.json` is a **rebuildable projection**, not the authority. It
  may be deleted and regenerated; freshness against the current event set is
  verified through `eventSetHash`.

If `state.json` looks stale or inconsistent, Pointbreak rebuilds it from
the event log. Do not write to `state.json` yourself, and do not depend on
its internal shape.

### Command-output JSON is the integration surface

The stable surface for automation is **command-output JSON documents**:
`shore.review-capture`, `shore.review-history`, `shore.review-revision`,
`shore.review-observation-add` / `-list`,
`shore.review-input-request-open` / `-list` / `-fetch` / `-respond`,
and `shore.review-assessment-add` / `-show`.

These documents expose semantic IDs, content hashes, and freshness metadata.
Raw event files, event filenames, artifact paths, and `state.json` are
Pointbreak-owned storage details. They can change without a deprecation cycle.

### Tracks

Every observation, input request, and assessment belongs to a required
`--track`. Tracks are **review lanes**, such as `agent:codex` or
`human:kevin`. They are not actor identity. Writer provenance — who actually
ran the command — is recorded separately in the event envelope: the writer
`actorId` (from local Git config, or an explicit `actor:agent:<name>` set via
`SHORE_ACTOR_ID`) and the `producer` that wrote the event. The human a resolved
agent acts on behalf of comes from the checked-in `.shore/delegates.json` map at
read time. Pick track names that group facts the way you want to read them back,
then let provenance take care of itself.

### Bodies

Observation bodies, input request bodies, input request response
reasons, and assessment summaries all share the same input mechanics:
`--body` / `--body-file` / `--body-stdin` (or `--summary*` /
`--reason*`). Read commands omit body-like text by default and hydrate it
only when `--include-body` is passed. Small bodies stay inline in the event
payload; larger bodies move to content-addressed artifacts. From a user
perspective, the difference is invisible — read commands return the same
shape either way.

### IDs are opaque

Pointbreak exposes several kinds of IDs in its output: revision IDs, object
IDs, observation IDs, input request IDs, input request response
IDs, assessment IDs, event IDs, and review-stream row IDs. **Treat them all
as opaque strings.** They are stable and safe to use as keys or to pass back
into other commands, but their internal format is an implementation detail.
This opacity is load-bearing: a content id is derived from content, so two clones
capturing identical content converge on the same revision and object IDs without
coordinating, and a store migration may rename the on-disk files that hold them
while the IDs themselves stay valid and unchanged. Read the IDs; never parse them.
In particular:

- Do not parse review-stream `row.id` values, derive ordering from them
  lexically, or assume any particular width or prefix. Use the sibling
  `ordinal` field if you need a numeric position.
- Do not parse storage filenames. Event filenames, object artifact
  filenames, and note-body artifact filenames are derived from internal
  hashes and may change without a deprecation cycle.
- Do not depend on artifact paths or the internal shape of
  `state.json`.

## 6. A small realistic walkthrough

The block below captures the typical sequence: confirm the change, capture
the revision, inspect it, record a couple of observations, open an
input request, respond to it, and land an assessment.

```bash
# 0. Confirm the worktree has the changes you want to review.
cd ~/src/myproject
git status

# 1. Capture a revision. This freezes the current diff as a snapshot.
#    `shore capture` emits compact JSON only; pipe through jq if you
#    want to read it.
shore capture | jq .

# 2. Read the captured revision (composite view, narrative + snapshot).
shore revision show --pretty | less

# 3. Record observations as you read the diff.
shore observation add \
  --track agent:codex \
  --title "Check error handling near IO boundary" \
  --file src/io.rs --start-line 88 --end-line 104 \
  --body "The new branch swallows io::ErrorKind::Interrupted silently."

shore observation add \
  --track human:kevin \
  --title "Unit test for the new retry path" \
  --file src/io.rs --start-line 120 --end-line 135

shore observation list --pretty

# 4. Open an input request when you need a decision from someone else.
shore input-request open \
  --track human:kevin \
  --title "Approve schema migration before landing" \
  --reason manual-decision-required \
  --file db/migrations/0042_users.sql

# Someone reads the open queue and responds to it.
shore input-request list --status open
shore input-request respond <input-request-id> \
  --outcome approved \
  --reason "verified backfill plan with on-call DBA"

# 5. Record the final assessment for the revision.
shore assessment add \
  --track human:kevin \
  --assessment accepted-with-follow-up \
  --summary "ship it; follow up on the retry-path unit test"

# 6. Verify the durable record.
shore assessment show --pretty
shore history --pretty | less
```

That is the full V1 workflow. Anything beyond it — notifications, daemons,
multi-writer coordination, automatic delivery — is intentionally out of
scope and will be addressed by future, separately-designed subsystems.