Policies and digests
Weights and thresholds are not constants in code. They are a versioned artifact per org, and the SHA-256 digest of the active version is written onto every score, every enforcement action and every ledger record it produced. An auditor reading a record a year from now knows exactly which numbers were in force.
One version
{
"version": 2,
"weights": { "score_inflation": 0.30, "config_tamper": 0.30, "alignment_faking": 0.25, "asset_movement": 0.15 },
"thresholds": { "hold": 0.75, "alert": 0.60, "collapse": 0.40 },
"digest": "3f9c...",
"active": true,
"created_by": "console",
"created_at": "2026-09-08T14:02:11Z"
}
Exactly one version per org is active. Version 1 is the seed shown on the BII page, created with the org. Creating a new version deactivates the previous one and invalidates the 60 second policy cache.
The digest
The digest is the SHA-256 of the canonical JSON document {"version": "2026-09-08", "weights": {...}, "thresholds": {...}}. The version key there is the document format tag, not the row version, so two versions with identical numbers share a digest. The digest names the numbers, which is what a record needs.
Where it appears: bii_scores.policy_digest, enforcement_actions.policy_digest, ledger_records.policy_digest. A review record carries the digest active at decision time.
Validation
POST /policies (scope admin) returns 400 unless the weights sum to 1.0 within 1e-6 and collapse < alert < hold, all between 0 and 1. A four-key weights is accepted and stored with blueprint_drift at 0.00. A new version changes the digest on new records only; history keeps the digest it was scored under.
Read the versions
curl -sf -H "Authorization: Bearer $VIGIL_KEY" "$VIGIL_URL/policies"
Newest first. The row with active: true is what the next event will be scored under.
Change the gate
Tighten the hold threshold for an org (admin key):
curl -s -X POST "$VIGIL_URL/policies" \
-H "Authorization: Bearer $VIGIL_ADMIN_KEY" -H "Content-Type: application/json" \
-d '{"weights":{"score_inflation":0.30,"config_tamper":0.30,"alignment_faking":0.25,"asset_movement":0.15},
"thresholds":{"hold":0.80,"alert":0.60,"collapse":0.40}}'
The next event's record carries the new digest. The previous records do not change; they cannot.