test(buzz-db): add absent-policy FK rejection to provenance regression

Extends identity_binding_provenance_is_independent_of_enrollment_mode with
the negative half required for two-sided mutation sensitivity.

A second deferred transaction inserts an otherwise-valid identity_bindings
row referencing policy_revision 999 (nonexistent in
identity_enrollment_policies) and asserts the INSERT fails with SQLSTATE
23503 from the narrowed FK identity_bindings(community_id, policy_revision)
→ identity_enrollment_policies(community_id, policy_revision).

Non-vacuity verified: removing the FK from the migration causes the
absent-policy INSERT to succeed (rows_affected: 1) and the expect_err
assertion to fire, confirming the negative half detects a dropped or
neutered FK. The existing positive half catches the old composite FK;
together they give full two-sided coverage.

Zero production changes: migrations 0040/0041 and schema.sql are
byte-untouched.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Hayt <9e1c23a3fd83f61da34420e4e88ff1b16e45cafcc0cd9019eb07d4ecfa8ca9b0@buzz.block.builderlab.xyz>
This commit is contained in:
Hayt
2026-08-28 17:56:39 -04:00
parent 315740d672
commit a83d29e2c5

View File

@@ -3129,5 +3129,102 @@ mod tests {
stored_provenance, stored_mode,
"provenance and mode are independent: they must differ here"
);
// --- Negative half: absent policy revision ---
//
// Two-sided mutation sensitivity requires that a FK dropped or neutered
// entirely is also detected. A second otherwise-valid deferred
// transaction uses a nonexistent policy_revision (999) and must fail
// with SQLSTATE 23503 — the narrowed FK
// identity_bindings(community_id, policy_revision)
// → identity_enrollment_policies(community_id, policy_revision)
// rejects the row. This FK is not deferred, so it fires at INSERT
// time; a `COMMIT` is unnecessary and not reached. If the FK were
// absent the INSERT would succeed and this assertion would catch the
// regression.
let absent_binding_id = uuid::Uuid::new_v4();
let absent_history_id = uuid::Uuid::new_v4();
let absent_operation_id = uuid::Uuid::new_v4();
let absent_fp = vec![0xC0_u8; 32];
let nonexistent_policy_revision: i64 = 999;
let mut conn2 = pool.acquire().await.expect("acquire second connection");
sqlx::query("BEGIN")
.execute(&mut *conn2)
.await
.expect("begin absent-policy transaction");
// History first (receipt_history_cardinality guard fires on receipt
// insert and requires the history row to already exist).
sqlx::query(
"INSERT INTO identity_lifecycle_history \
(community_id, history_id, transition_kind, outcome_code, \
successor_binding_id, successor_binding_version, \
successor_lifecycle_revision, successor_state, \
operation_id, request_fingerprint, transition_digest) \
VALUES ($1, $2, 1, 1, $3, 2, 1, 1, $4, $5, $6)",
)
.bind(community_id)
.bind(absent_history_id)
.bind(absent_binding_id)
.bind(absent_operation_id)
.bind(&absent_fp)
.bind(vec![0xC1_u8; 32])
.execute(&mut *conn2)
.await
.expect("insert absent-policy lifecycle history");
sqlx::query(
"INSERT INTO authorization_operation_receipts \
(community_id, operation_id, request_fingerprint, operation_kind, \
actor_fingerprint, outcome_code, result_digest) \
VALUES ($1, $2, $3, 1, $4, 1, $5)",
)
.bind(community_id)
.bind(absent_operation_id)
.bind(&absent_fp)
.bind(vec![0xC2_u8; 32])
.bind(vec![0xC3_u8; 32])
.execute(&mut *conn2)
.await
.expect("insert absent-policy operation receipt");
// The policy FK is not deferred; it fires at INSERT, not COMMIT.
let absent_policy_err = sqlx::query(
"INSERT INTO identity_bindings \
(community_id, binding_id, issuer, subject, \
principal_fingerprint, event_author_pubkey, \
binding_state, lifecycle_revision, binding_provenance, \
policy_revision, enrollment_evidence_digest, \
birth_history_id, creation_operation_id, \
creation_request_fingerprint) \
VALUES ($1, $2, 'https://issuer.example', 'sub-02', \
$3, $4, 1, 1, 1, $5, $6, $7, $8, $9)",
)
.bind(community_id)
.bind(absent_binding_id)
.bind(vec![0xC4_u8; 32]) // principal_fingerprint (unique, different from first binding)
.bind(vec![0xC5_u8; 32]) // event_author_pubkey (unique, different from first binding)
.bind(nonexistent_policy_revision)
.bind(vec![0xC6_u8; 32]) // enrollment_evidence_digest
.bind(absent_history_id)
.bind(absent_operation_id)
.bind(&absent_fp)
.execute(&mut *conn2)
.await
.expect_err("binding with nonexistent policy_revision must be rejected by the FK");
assert!(
absent_policy_err
.as_database_error()
.map(|e| e.code().as_deref() == Some("23503"))
.unwrap_or(false),
"expected FK violation (23503) for absent policy_revision, got: {absent_policy_err}"
);
sqlx::query("ROLLBACK")
.execute(&mut *conn2)
.await
.expect("rollback absent-policy transaction");
}
}