bfev cheatsheet

One-page reference. For deep dives see explanation/architecture.md, reference/contracts.md, reference/testing.md.

Install

# from source
git clone https://github.com/DeeRocking/bfev.git
cd bfev
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"          # core + tests
uv pip install -e ".[dev,live]"     # + claude-agent-sdk for `bfev test --live`

# from ghcr (private — needs Collaborator on github.com/DeeRocking/bfev)
gh auth token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/deerocking/bfev:0.1.0

Configure

export BFEV_HOME=$HOME/bfev          # default ~/bfev; never in the bfev repo
mkdir -p "$BFEV_HOME/.bfev"
echo "PORTEO" >> "$BFEV_HOME/.bfev/isolation-blacklist.txt"   # one client token per line

Pipeline lifecycle

bfev init <slug>                     # bootstrap $BFEV_HOME/clients/<slug>/
$EDITOR  $BFEV_HOME/clients/<slug>/client.yaml   # fill name, country, sector, period, actors[]

# (4 stages run via Claude Code plugin: /plugin install bfev@bfev)
# Then verify:
bfev status <slug>                   # dashboard: artefact presence + runs + audit
bfev audit  <slug>                   # cross-stage check (anti-leak + reconciliation + entities)
bfev log    <slug> -n 20             # tail runs.jsonl

Plugin install (one-time per machine)

/plugin marketplace add /path/to/bfev   # the repo root (NOT plugin/)
/plugin install bfev@bfev
/reload-plugins

Verify with /agents — you should see bfev-orchestrator, bfev-collection, bfev-simulate, bfev-calculate, bfev-report.

Test harness

pytest -q                                                   # unit tests, <5s
bfev test calculate                                         # replay (no Claude), 3 cases
bfev test calculate --case diesel-only                      # single case
bfev test calculate --case diesel-only --accept             # regenerate golden after intentional change

bfev ping --verbose                                         # ~$0.05, 5s — SDK + plugin sanity
bfev test --live calculate --case diesel-only --verbose     # ~$0.25, 30s — true E2E
bfev test --live calculate --case <c> --verbose --keep-tmp  # keep the tmpdir for inspection

Audit checks (what bfev audit enforces)

Check What it does Fails when
anti_leak greps deliverable PDFs for v1/v2/recalibrage/audit interne/en attente de/à confirmer par/mis à jour quand any forbidden phrase appears in a rendered PDF
crosscheck_reconciliation recomputes Σ AD·EF·GWP from crosscheck.xlsx, compares to aggregates.json drift > tolerance_pct (default 0.5%) on any scope
entity_allowlist report self-audit's entities_referencedclient.yaml.actors the report cites an actor not in client.yaml

Exit code: 0 if all pass, 1 otherwise. Output written to $BFEV_HOME/clients/<slug>/deliverables-<scenario>/consistency-audit.json.

Crosscheck XLSX — the human-audit story

from bfev.crosscheck import build
from pathlib import Path
build(Path("calculations-v0/results.json"), Path("calculations-v0/crosscheck.xlsx"))

Vendor skill re-sync (when upstream ~/.claude/skills/ changes)

./scripts/apply-vendor-patches.sh                       # default: $HOME/.claude/skills
SKILLS=ghg-reporting ./scripts/apply-vendor-patches.sh  # narrow to one
./scripts/apply-vendor-patches.sh /alt/skills/source    # custom upstream

Fails loud on patch conflict — that's the signal that upstream has drifted into a patched zone. To regenerate a patch:

diff -u $HOME/.claude/skills/<skill>/<path> plugin/skills/<skill>/<path> \
  | sed -E "1s|^--- .*|--- a/<path>|; 2s|^\+\+\+ .*|+++ b/<path>|" \
  > plugin/skills/.patches/<skill>/<NN>-<name>.patch

Docker

# build (~10 min cold, ~1.5 GB)
docker build -t bfev:latest .
docker build --build-arg LIVE=1 -t bfev:live .

# run
docker run --rm -v "$HOME/bfev:/work/bfev-home" \
  -e BFEV_HOME=/work/bfev-home \
  ghcr.io/deerocking/bfev:0.1.0 bfev init demo

# publish
docker tag bfev:latest ghcr.io/deerocking/bfev:0.1.0
docker push ghcr.io/deerocking/bfev:0.1.0

Never re-push under the same tag if content changed — bump version (0.1.1, etc.). lockfile.yaml relies on stable digests.

Common gotchas

File layout reference

$BFEV_HOME/
├── .bfev/
   ├── isolation-blacklist.txt           # client tokens to refuse in deliverables
   └── isolation-allowlist/<slug>.txt    # per-client exemptions (optional)
├── resources/
   ├── categories.json                   # master taxonomy
   └── ipcc-volume-{1..5}/...            # IPCC AR2006 PDFs
└── clients/<slug>/
    ├── client.yaml                       # name, country, sector, period, actors[]
    ├── lockfile.yaml                     # bfev version + EF/IPCC/skill hashes
    ├── runs.jsonl                        # append-only audit trail
    ├── collection/{schema.xlsx,request.pdf}
    ├── activity-data-<sc>/{filled.xlsx,provenance.yaml}
    ├── calculations-<sc>/{aggregates.json,results.json,crosscheck.xlsx,meta.yaml,audit.log,figures/}
    └── deliverables-<sc>/{executive.pdf,scientific.pdf,official.pdf,consistency-audit.json,self-audit.json}

Memory hygiene