# Playbook — Find the poisoned pivot without quarantining the legitimate hub

Run three independent integrity checks over a shared indicator graph, correlate them, and contain the one record that fails all three without deleting anything.

## What you need

- Docker 24 or later
- Python 3.9 or later
- About 3 minutes

## 1. Start a disposable Corrobore

```bash
mkdir -p .corrobore-tls .corrobore-secrets
printf '%s\n' 'change-me' > .corrobore-secrets/http-token
openssl req -x509 -newkey rsa:2048 -sha256 -nodes \
  -keyout .corrobore-tls/server.key -out .corrobore-tls/server.crt \
  -days 30 -subj '/CN=localhost' \
  -addext 'basicConstraints=critical,CA:FALSE' \
  -addext 'keyUsage=critical,digitalSignature,keyEncipherment' \
  -addext 'extendedKeyUsage=serverAuth' \
  -addext 'subjectAltName=DNS:localhost,IP:127.0.0.1'

docker run --rm -d --name corrobore-playbook \
  -p 127.0.0.1:8080:8080 \
  -e CORROBORE_STORAGE_MODE=ephemeral \
  -v "$PWD/.corrobore-secrets/http-token:/run/secrets/corrobore-http-token:ro" \
  -v "$PWD/.corrobore-tls/server.crt:/run/secrets/tls.crt:ro" \
  -v "$PWD/.corrobore-tls/server.key:/run/secrets/tls.key:ro" \
  ghcr.io/estance-labs/corrobore:latest

curl --insecure -H 'Authorization: Bearer change-me' https://127.0.0.1:8080/health/ready
```

## 2. Install the notebook dependencies

```bash
pip install requests
```

## 3. Run the notebook

```bash
jupyter lab notebook.ipynb
```

The notebook loads `dataset.json` from the same directory. Keep the three files together.

## 4. What to observe

1. The degree check flags two records, and only one of them is a problem: a rule based on degree alone breaks the registrar.
2. The contradiction is weighted by the reliability of the contradicting source, not merely counted.
3. The behavioural check looks at the feed rather than the assertion, and the retraction rate identifies it.
4. Only the record carrying all three signals is quarantined; the structurally similar hub is left alone.
5. After tombstoning, `recall` stops returning the record while `trace` keeps its version ladder, its author and its contradiction.

## 5. Change one thing and re-run

- Lower `degree_threshold` to 10 and count how many records get a review recommendation.
- Remove the `contradicts` edge and watch the finding drop from quarantine to review.
- Give `feed--drifting` a clean retraction rate and confirm the poisoned pivot is no longer distinguishable from the hub.
- Use `expire` instead of `tombstone` and compare what `trace` retains.

## Boundaries

- The feeds, the indicators and the sinkhole record are synthetic.
- Immune tiers, validators, response planning and verification probes are `graph-core` primitives with no HTTP route in this release; the checks here are client-side and written to the same shape.
- Thresholds in this notebook are illustrative. Real ones belong to a deployment's policy, and an integrity finding is a reason to look rather than an authorisation to act.

## Tear down

```bash
docker rm -f corrobore-playbook
```

---

Documentation: https://docs.corrobore.org — Source: https://github.com/Estance-Labs/corrobore
