pointbreak 0.9.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
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
# Pointbreak maintainer entrypoints. Run `just --list` for grouped discovery and read
# `docs/development.md` for the change-to-gate matrix and failure interpretation.
# `just check` is intentionally Rust-only; Inspector, extension, release, and browser
# surfaces have separate groups and prerequisites.

# Bump to upgrade the agentskills.io validator; review the diff at https://github.com/agentskills/agentskills/compare/<old-sha>...<new-sha> before bumping.
export SKILLS_REF_REV := env_var_or_default("SKILLS_REF_REV", "5d4c1fda3f786fff826c7f56b6cb3341e7f3a911")

# Recipes are written for a POSIX shell. Git for Windows bundles one but does not
# put it on PATH, so name it explicitly (the default install location, which the
# GitHub windows runners share). Without this, every recipe fails from
# PowerShell/cmd with "could not find the shell `sh`".
set windows-shell := ["C:/Program Files/Git/bin/sh.exe", "-cu"]

# Host executable suffix: `.exe` on Windows, empty elsewhere. Mirrors the name the
# extension packager derives from .github/binary-targets.json, so the path handed to
# it in `build-all` actually exists on disk.
bin_ext := if os_family() == "windows" { ".exe" } else { "" }

# List available recipes.
[group('help')]
default:
    @just --list

# Run all tests.
[group('core')]
test *args:
    cargo +stable nextest run --no-tests pass {{ args }}

# Run all tests (CI mode: no fail-fast, verbose).
[group('core')]
test-ci *args:
    cargo +stable nextest run --profile ci --no-tests pass {{ args }}

# Run a specific test file (e.g. just test-file integration).
[group('core')]
test-file name *args:
    cargo +stable nextest run --test {{ name }} {{ args }}

# Run the differential subprocess-vs-gix git-backend parity harness (report-only).
[group('core')]
git-parity *args:
    cargo +stable nextest run --features gix-parity -E 'test(git_backend_parity)' {{ args }}

# Per-op subprocess-vs-gix microbench behind the read-class flips (gix-parity
# feature; separate from the `bench` feature). Prints the measured per-op win.
[group('core')]
git-bench *args:
    cargo +stable nextest run --features gix-parity -E 'test(git_backend_microbench)' --no-capture {{ args }}

# Build (debug).
[group('core')]
build *args:
    cargo +stable build {{ args }}

# Build an optimized binary without publishing it.
[group('core')]
release *args:
    cargo +stable build --release {{ args }}

# Reject a build profile that is not exactly `debug` or `release`, before any
# dependency runs. Kept private so it stays out of `just --list`.
[private]
_require-build-profile profile:
    @[ "{{ profile }}" = "debug" ] || [ "{{ profile }}" = "release" ] || { echo "build-all: profile must be 'debug' or 'release', got '{{ profile }}'" >&2; exit 2; }

# Build every locally shippable surface for dogfood: the Inspector bundle, the CLI
# binary, and a platform-targeted VS Code VSIX (with that freshly built binary
# bundled in) written to target/vsix/<target>/<profile>/. Profile must be `debug`
# or `release` (default `release`).
[group('core')]
build-all profile="release": (_require-build-profile profile) web-install web-build extension-install
    cargo +stable build {{ if profile == "release" { "--release" } else { "" } }}
    POINTBREAK_EXTENSION_PROFILE={{ profile }} POINTBREAK_EXTENSION_BINARY="{{ justfile_directory() }}/target/{{ profile }}/pointbreak{{ bin_ext }}" just extension-package

# Self-test Cargo installation and all release archive layouts without publishing.
[group('release')]
package-archive-selftest:
    ./scripts/package-release-selftest.sh

# Reproduce Cocogitto's native tag lifecycle and the guarded signed-tag finalizer.
[group('release')]
release-bump-selftest:
    ./scripts/finalize-cocogitto-release-tag-selftest.sh

# Exercise the release installer for the current host platform without network access.
[group('release')]
installer-selftest:
    {{ if os() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/install-selftest.ps1" } else { "./scripts/install-selftest.sh" } }}

# Lint GitHub Actions workflows, the packaging script, and the binary target manifest.
[group('release')]
workflow-lint: workflow-actionlint workflow-lint-assertions

# Run actionlint against GitHub Actions workflows.
[group('release')]
workflow-actionlint:
    actionlint

# Run the workflow checks not provided by reviewdog/action-actionlint in CI.
[group('release')]
workflow-lint-assertions:
    #!/usr/bin/env bash
    set -euo pipefail
    shellcheck \
      scripts/package-release-archive.sh \
      scripts/package-release-selftest.sh \
      scripts/verify-release-archives.sh \
      scripts/install.sh \
      scripts/install-selftest.sh \
      scripts/assert-release-identity.sh \
      scripts/assert-release-identity-selftest.sh \
      scripts/finalize-cocogitto-release-tag.sh \
      scripts/finalize-cocogitto-release-tag-selftest.sh \
      scripts/run-release-plan.sh \
      scripts/run-release-verification.sh
    ./scripts/assert-release-identity-selftest.sh
    expected="$(cat <<'EOF'
    [
      {"archive":"tar.gz","builder":"cargo","executable":"pointbreak","os":"macos-latest","rust-target":"x86_64-apple-darwin","target":"darwin-x64"},
      {"archive":"tar.gz","builder":"cargo","executable":"pointbreak","os":"macos-latest","rust-target":"aarch64-apple-darwin","target":"darwin-arm64"},
      {"archive":"tar.gz","builder":"zigbuild","executable":"pointbreak","os":"ubuntu-latest","rust-target":"x86_64-unknown-linux-gnu","target":"linux-x64"},
      {"archive":"tar.gz","builder":"zigbuild","executable":"pointbreak","os":"ubuntu-latest","rust-target":"aarch64-unknown-linux-gnu","target":"linux-arm64"},
      {"archive":"tar.gz","builder":"zigbuild","executable":"pointbreak","os":"ubuntu-latest","rust-target":"x86_64-unknown-linux-musl","target":"alpine-x64"},
      {"archive":"tar.gz","builder":"zigbuild","executable":"pointbreak","os":"ubuntu-latest","rust-target":"aarch64-unknown-linux-musl","target":"alpine-arm64"},
      {"archive":"zip","builder":"cargo","executable":"pointbreak.exe","os":"windows-latest","rust-target":"x86_64-pc-windows-msvc","target":"win32-x64"},
      {"archive":"zip","builder":"cargo","executable":"pointbreak.exe","os":"windows-latest","rust-target":"aarch64-pc-windows-msvc","target":"win32-arm64"}
    ]
    EOF
    )"
    jq -e --argjson expected "$expected" \
      'length == 8
       and (map(.target) | unique | length) == 8
       and (map(."rust-target") | unique | length) == 8
       and map(to_entries | sort_by(.key) | from_entries) == $expected' \
      .github/binary-targets.json > /dev/null
    grep -Fq -- '--bin pointbreak' .github/workflows/release-binaries.yml
    grep -Fq -- 'verify-release-archives.sh' .github/workflows/release-binaries.yml
    grep -Fq -- 'package-archive-selftest' .github/workflows/release-plan.yml
    grep -Fq -- 'package-archive-selftest' .github/workflows/release.yml
    grep -Fq -- 'package-archive-selftest' scripts/run-release-plan.sh
    grep -Fq -- 'expected_source_commit' .github/workflows/release-plan.yml
    grep -Fq -- 'overwrite_files: false' .github/workflows/release-binaries.yml
    grep -Fq -- 'shell: powershell' .github/workflows/verify-release.yml
    grep -Fq -- 'alpine:3.22' .github/workflows/verify-release.yml
    if rg -n 'shore(\.exe)?|--bin shore' \
      .github/binary-targets.json \
      .github/workflows/release-binaries.yml \
      .github/workflows/release-plan.yml \
      .github/workflows/release.yml \
      scripts/package-release-archive.sh \
      scripts/run-release-plan.sh; then
        echo "release surfaces still reference the retired executable" >&2
        exit 1
    fi
    for t in $(jq -r '.[].target' .github/binary-targets.json); do
      grep -q -- "$t" docs/installation.md || { echo "installation docs missing target: $t" >&2; exit 1; }
    done
    echo "workflow-lint assertions ok"

# Run Rust formatting checks and Clippy across all targets and features.
[group('quality')]
lint: fmt-check
    cargo +stable clippy --workspace --all-targets --all-features -- -D warnings

# Type-check all targets without the full clippy/fmt gate. Used by CI's non-Linux
# legs to keep the cfg(windows)/cfg(not(unix))/feature-gated arms compiled while
# paying the workspace+test compile only once. Linux runs the full `lint` gate.
# Type-check all workspace targets and features without the full lint gate.
[group('core')]
check-types:
    cargo +stable check --workspace --all-targets --all-features

# Run clippy with auto-fix.
[group('quality')]
fix *args: fmt
    cargo +stable clippy --fix --workspace --all-targets --all-features --allow-dirty --allow-staged -- -D warnings {{ args }}

# Format code.
[group('quality')]
fmt *args:
    cargo +nightly fmt --all {{ args }}

# Check Rust formatting without writing files.
[group('quality')]
fmt-check:
    cargo +nightly fmt --all -- --check

# Format Nix files with the canonical RFC-166 formatter. Requires Nix.
[group('nix')]
nix-fmt:
    #!/usr/bin/env bash
    set -euo pipefail
    nix run nixpkgs#nixfmt -- $(git ls-files '*.nix')

# Lint and format-check Nix files: nixfmt, statix, deadnix, and `nix flake check`.
# Requires Nix. Deliberately separate from `just lint`/`check`, which stay
# Rust-only so contributors without Nix (mise/manual) can run the core gate.
[group('nix')]
nix-check:
    #!/usr/bin/env bash
    set -euo pipefail
    files=$(git ls-files '*.nix')
    nix run nixpkgs#nixfmt -- --check $files
    nix run nixpkgs#statix -- check .
    nix run nixpkgs#deadnix -- --fail .
    nix flake check

# Install git hooks (commit-msg and pre-push validation via cocogitto).
[group('maintenance')]
setup-hooks:
    cog install-hook --all --overwrite

# Symlink repo Agent Skills into project-local or user-level agent skill directories.
[group('skills')]
skills-link *args:
    ./scripts/link-agent-skills.sh {{ args }}

# Remove local symlinks for repo Agent Skills.
[group('skills')]
skills-unlink *args:
    ./scripts/link-agent-skills.sh unlink {{ args }}

# Validate repo Agent Skills with the pinned agentskills.io validator.
[group('skills')]
skills-validate:
    for skill in skills/*; do \
      [ -d "$skill" ] || continue; \
      [ -f "$skill/SKILL.md" ] || continue; \
      uvx --from "git+https://github.com/agentskills/agentskills@${SKILLS_REF_REV}#subdirectory=skills-ref" \
        skills-ref validate "$skill"; \
    done

# Check conventional commits in the selected range.
[group('quality')]
commit-check range='origin/main..HEAD':
    cog check "{{ range }}"

# Run the CLI.
[group('core')]
run *args:
    cargo +stable run --bin pointbreak -- {{ args }}

# Fold a worktree-local .pointbreak/data store into the Git-common-dir pointbreak store.
# Non-destructive + idempotent; refuses an ephemeral/sensitive worktree unless
# you pass include-ephemeral=true. This IS a shipped subcommand (pointbreak store migrate).
# Migrate a worktree-local store into the Git-common-dir store without deleting the source.
[group('maintenance')]
migrate-store-common-dir repo="." include-ephemeral="false":
    cargo +stable run --bin pointbreak -- store migrate --repo {{ repo }} \
        {{ if include-ephemeral == "true" { "--include-ephemeral" } else { "" } }}

# Run the complete Rust gate: commit check, build, lint, and tests.
[group('quality')]
check: commit-check build lint test

# Run the deterministic cross-candidate fault and native-platform matrix. This
# uses only disposable roots and records raw samples without timing thresholds.
[group('quality')]
store-foundation-qualification-smoke:
    cargo +stable bench --features bench --bench store_foundation -- --qualification-smoke

# Execute the feature-gated derived-access accounting and package regression lane.
[group('quality')]
derived-access-tests:
    cargo +stable nextest run --features longitudinal-counting \
        -E 'test(candidate_open_preserves_admitted_truth_and_accounts_for_governed_namespaces) | test(bound_smoke_fragment_assembles_into_a_verified_incomplete_evidence_package)'

# Run the developer evidence lane with repeated raw performance samples. This
# remains environment evidence rather than a default-test timing gate.
[group('quality')]
store-foundation-qualification:
    cargo +stable bench --features bench --bench store_foundation -- --qualification-evidence

# Print and validate the public longitudinal workload and capacity contracts.
[group('quality')]
longitudinal-contract:
    cargo +stable bench --locked --features bench --bench store_foundation -- --longitudinal-contract

# Print and validate the candidate-independent incremental derived-access falsifier contract.
[group('quality')]
derived-access-contract:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-contract

# Print and validate the dormant product-integration contract.
[group('quality')]
derived-access-product-contract:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-product-contract

# Verify the embedded product-integration fixture against the compiled contract.
[group('quality')]
derived-access-product-contract-verify:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-product-contract-verify

# Exercise the product-integration selector, states, and routes without filesystem action.
[group('quality')]
derived-access-product-contract-smoke:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-product-contract-smoke

# Print and validate the production-readiness contract.
[group('quality')]
derived-access-readiness-contract:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-readiness-contract

# Verify the embedded production-readiness fixture against the compiled contract.
[group('quality')]
derived-access-readiness-contract-verify:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-readiness-contract-verify

# Exercise the production-readiness contract without opening a store or running scale work.
[group('quality')]
derived-access-readiness-contract-smoke:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-readiness-contract-smoke

# Print the current derived-access rollout contract without opening a store.
derived-access-rollout-contract:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-rollout-contract

# Verify the embedded current derived-access rollout fixture without opening a store.
derived-access-rollout-contract-verify:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-rollout-contract-verify

# Run the non-timing current derived-access rollout smoke without opening a store.
derived-access-rollout-contract-smoke:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-rollout-contract-smoke

# List the derived-access qualification modes without creating a store.
[group('quality')]
derived-access-help:
    cargo +stable bench --locked --features bench --bench store_foundation -- --derived-access-help

# Exercise one disposable deterministic D0-128, L1, or L7 correctness tier with counters.
[group('quality')]
derived-access-smoke tier="D0-128":
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-smoke --derived-access-tier="{{ tier }}"

# Measure bounded production bootstrap work and process resources on a disposable public root.
[group('quality')]
derived-access-bootstrap-smoke tier="D0-128":
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-bootstrap-smoke --derived-access-tier="{{ tier }}"

# Attribute revision-page, bootstrap, and governed-write work on one typed root.
[group('quality')]
derived-access-phase request:
    POINTBREAK_DERIVED_ACCESS=sqlite-wal-bodyless-v1 \
        cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-phase-evidence --derived-access-request="{{ request }}"

# Verify a phase bundle against its typed source/tier/root request.
[group('quality')]
derived-access-phase-verify request bundle:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-phase-verify --derived-access-request="{{ request }}" \
        --derived-access-input="{{ bundle }}"

# Run one evidence-bound D0-128, L1, or L7 native smoke request.
[group('quality')]
derived-access-native-smoke request:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-smoke --derived-access-request="{{ request }}"

# Run all native lifecycle vectors from one typed request.
[group('quality')]
derived-access-lifecycle request:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-lifecycle --derived-access-request="{{ request }}"

# Verify a retained L7/L100/C262 input and separately created qualification clone.
[group('quality')]
derived-access-retained-preflight request:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-retained-preflight --derived-access-request="{{ request }}"

# Bootstrap only the derived namespace of a precreated retained-root clone.
[group('quality')]
derived-access-retained-bootstrap request:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-retained-bootstrap --derived-access-request="{{ request }}"

# Collect the frozen L100/C262 operation samples from two admitted roots.
[group('quality')]
derived-access-scale request:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-scale-evidence --derived-access-request="{{ request }}"

# Collect empty-adjusted L7/L100 process-memory evidence.
[group('quality')]
derived-access-resource request:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-resource-evidence --derived-access-request="{{ request }}"

# Convert typed raw receipts into one independently verifiable package fragment.
[group('quality')]
derived-access-fragment request:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-fragment --derived-access-request="{{ request }}"

# Assemble and evaluate derived-access fragments into one completion-last package.
[group('quality')]
derived-access-package root *inputs:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-package --derived-access-package-root="{{ root }}" {{ inputs }}

# Recursively verify one completed derived-access package without editing it.
[group('quality')]
derived-access-verify-package root:
    cargo +stable bench --locked --features "bench longitudinal-counting" --bench store_foundation -- \
        --derived-access-verify-package --derived-access-package-root="{{ root }}"

# Exercise disposable longitudinal construction, pair, preflight, and package mechanics without timing.
[group('quality')]
longitudinal-smoke:
    cargo +stable bench --locked --features bench --bench store_foundation -- --longitudinal-smoke

# Recursively verify one completed longitudinal raw-evidence package without editing it.
[group('quality')]
longitudinal-verify-package root:
    cargo +stable bench --locked --features bench --bench store_foundation -- \
        --longitudinal-verify-package --longitudinal-package-root="{{ root }}"

# Install the Visual Studio Code extension toolchain from its committed lockfile.
[group('extension')]
extension-install:
    cd extensions/vscode && npm ci

# Check the VS Code extension; intentionally separate from the Rust-only `just check`.
[group('extension')]
extension-check:
    cd extensions/vscode && npm run check

# Build a platform-targeted VSIX with its matching pointbreak binary for local
# dogfood, written to target/vsix/<target>/<profile>/. Honors POINTBREAK_EXTENSION_*
# (BINARY, PROFILE, CLEAN_VERSION); `build-all` sets BINARY and PROFILE for you.
[group('extension')]
extension-package:
    node extensions/vscode/scripts/package-local.mjs

# Install the inspector front-end dev toolchain (Node) from the committed lockfile.
[group('web')]
web-install:
    cd src/cli/inspect/web && npm ci

# Node-only; intentionally NOT part of `just check` (the Rust gate stays Node-free). CI runs this
# as its own ubuntu leg.
# Front-end gate: Biome-lint the served app.js (lint-only) + Biome check (lint+format) the ported TS +
# strict tsc --noEmit + the vitest unit tests.
# Run the Inspector front-end lint, format, type, and unit-test gate.
[group('web')]
web-check:
    cd src/cli/inspect/web && npm run check

# Run the inspector front-end JS unit tests (vitest).
[group('web')]
web-test:
    cd src/cli/inspect/web && npm run test

# Build the inspector front-end bundle (esbuild -> the committed assets/app.js). Run after editing
# web/src so the committed bundle stays fresh; the CI freshness gate fails a PR that forgets.
# Rebuild the committed Inspector bundle after changing its web source.
[group('web')]
web-build:
    cd src/cli/inspect/web && npm run build

# Verify the committed inspector bundle is in sync with web/src (the CI freshness gate, run locally).
# Rebuilds the bundle and fails if it differs from the committed artifact.
# Verify that the committed Inspector bundle matches its source without accepting drift.
[group('web')]
web-verify:
    cd src/cli/inspect/web && npm run build && git diff --exit-code ../assets/app.js

# Refresh the dark/light Pointbreak Review screenshots embedded in README.md.
# Requires a running inspector; pass --url/--revision/--track to override the checked-in framing.
# Refresh README Review screenshots from an explicitly selected running Inspector.
[group('review-evidence')]
capture-inspector-screenshots *args:
    ./scripts/capture-inspector-screenshots.sh {{ args }}

# Refresh the product-owned marketing capture from the verified canonical Review example.
# Requires an inspector serving a materialized example repository.
# Refresh the product-owned marketing capture and provenance manifest from the canonical example.
[group('review-evidence')]
capture-marketing-review-screenshots url="http://127.0.0.1:7878":
    ./scripts/capture-inspector-screenshots.sh --url {{ url }} --example-manifest examples/review/checkout-refactor/manifest.json --manifest assets/marketing/review-interface-capture.json --out-dir assets/marketing --hide-observations

# Export the canonical Review example from a source repository through public Pointbreak APIs.
[group('review-evidence')]
review-example-export source output="examples/review/checkout-refactor":
    cargo +stable run --example review_example_pack -- export --repo {{ source }} --output {{ output }}

# Verify the checked canonical Review example pack without depending on store layout.
[group('review-evidence')]
review-example-verify pack="examples/review/checkout-refactor":
    cargo +stable run --example review_example_pack -- verify --pack {{ pack }}

# Materialize the canonical Review example into an empty destination repository.
[group('review-evidence')]
review-example-materialize output pack="examples/review/checkout-refactor":
    cargo +stable run --example review_example_pack -- materialize --pack {{ pack }} --output {{ output }}

# Materialize the Inspector decision-continuity matrix into an empty, isolated repository.
[group('review-evidence')]
review-decision-matrix-materialize output:
    #!/usr/bin/env bash
    set -euo pipefail
    if [ -n "${POINTBREAK_BINARY:-}" ]; then
      ./scripts/materialize-inspector-decision-matrix.sh "{{ output }}"
    else
      cargo +stable build --bin pointbreak
      POINTBREAK_BINARY="$PWD/target/debug/pointbreak" \
        ./scripts/materialize-inspector-decision-matrix.sh "{{ output }}"
    fi

# Materialize both Review evidence stores and verify decision continuity in a real browser.
[group('review-evidence')]
review-decision-browser-verify root:
    #!/usr/bin/env bash
    set -euo pipefail
    if [ -n "${POINTBREAK_BINARY:-}" ]; then
      ./scripts/verify-inspector-decision-continuity.sh --root "{{ root }}"
    else
      cargo +stable build --bin pointbreak
      POINTBREAK_BINARY="$PWD/target/debug/pointbreak" \
        ./scripts/verify-inspector-decision-continuity.sh --root "{{ root }}"
    fi