agent-spec-conformance
Behavioral Specification 21 tests
Test Details
all_checks_pass Property
let b = bundle(
spec(
vec!["src/*"],
vec![".env"],
vec!["cargo"],
Some(100),
Some(2000),
),
exec(vec!["src/main.rs"], vec!["cargo"], 50, 1000),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/agent_spec_conformance.rs
forbidden_path_exact Property
let b = bundle(
spec(vec![], vec![".env"], vec![], None, None),
exec(vec![".env"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects.iter().any(|s| s.contains(".env")));
crates/core/src/controls/agent_spec_conformance.rs
file_not_in_allowed_paths Property
let b = bundle(
spec(vec!["src/*"], vec![], vec![], None, None),
exec(vec!["config/settings.toml"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(
findings[0]
.subjects
.iter()
.any(|s| s.contains("config/settings.toml"))
);
crates/core/src/controls/agent_spec_conformance.rs
unauthorized_tool Property
let b = bundle(
spec(vec![], vec![], vec!["cargo"], None, None),
exec(vec![], vec!["curl"], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects.iter().any(|s| s.contains("curl")));
crates/core/src/controls/agent_spec_conformance.rs
exceed_step_limit Property
let b = bundle(
spec(vec![], vec![], vec![], Some(100), None),
exec(vec![], vec![], 150, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects.iter().any(|s| s.contains("150/100")));
crates/core/src/controls/agent_spec_conformance.rs
exceed_budget Property
let b = bundle(
spec(vec![], vec![], vec![], None, Some(2000)),
exec(vec![], vec![], 0, 5000),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects.iter().any(|s| s.contains("5000/2000")));
crates/core/src/controls/agent_spec_conformance.rs
multiple_violations Property
let b = bundle(
spec(
vec!["src/*"],
vec![".env"],
vec!["cargo"],
Some(100),
Some(2000),
),
exec(vec![".env", "docs/readme.md"], vec!["curl"], 150, 5000),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
let subjects = &findings[0].subjects;
assert!(subjects.iter().any(|s| s.contains(".env")));
assert!(subjects.iter().any(|s| s.contains("docs/readme.md")));
assert!(subjects.iter().any(|s| s.contains("curl")));
assert!(subjects.iter().any(|s| s.contains("150/100")));
assert!(subjects.iter().any(|s| s.contains("5000/2000")));
crates/core/src/controls/agent_spec_conformance.rs
empty_allowed_paths_no_restriction Property
let b = bundle(
spec(vec![], vec![], vec![], None, None),
exec(vec!["anywhere/file.txt"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/agent_spec_conformance.rs
empty_allowed_tools_no_restriction Property
let b = bundle(
spec(vec![], vec![], vec![], None, None),
exec(vec![], vec!["anything"], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/agent_spec_conformance.rs
forbidden_prefix_match_with_slash Property
let b = bundle(
spec(vec![], vec!["secrets/"], vec![], None, None),
exec(vec!["secrets/api.key"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(
findings[0]
.subjects
.iter()
.any(|s| s.contains("secrets/api.key"))
);
crates/core/src/controls/agent_spec_conformance.rs
allowed_wildcard_match Property
let b = bundle(
spec(vec!["src/*"], vec![], vec![], None, None),
exec(vec!["src/main.rs"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/agent_spec_conformance.rs
missing_spec_indeterminate Property
let b = EvidenceBundle {
agent_spec: EvidenceState::missing(vec![]),
agent_execution: EvidenceState::complete(exec(vec![], vec![], 0, 0)),
..Default::default()
};
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/agent_spec_conformance.rs
not_applicable_execution Property
let b = EvidenceBundle {
agent_spec: EvidenceState::complete(spec(vec![], vec![], vec![], None, None)),
agent_execution: EvidenceState::not_applicable(),
..Default::default()
};
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/agent_spec_conformance.rs
path_traversal_blocked Property
let b = bundle(
spec(vec!["src/*"], vec![], vec![], None, None),
exec(vec!["src/../secrets/key.pem"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(
findings[0]
.subjects
.iter()
.any(|s| s.contains("secrets/key.pem"))
);
crates/core/src/controls/agent_spec_conformance.rs
path_traversal_forbidden_detected Property
let b = bundle(
spec(vec![], vec![".env"], vec![], None, None),
exec(vec!["src/../.env"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/agent_spec_conformance.rs
dot_prefix_normalized Property
let b = bundle(
spec(vec!["src/*"], vec![], vec![], None, None),
exec(vec!["./src/main.rs"], vec![], 0, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/agent_spec_conformance.rs
normalize_path_resolves_traversal Property
assert_eq!(normalize_path("src/../secrets/key.pem"), "secrets/key.pem");
assert_eq!(normalize_path("./src/main.rs"), "src/main.rs");
assert_eq!(normalize_path("src/./deep/../main.rs"), "src/main.rs");
assert_eq!(normalize_path("a/b/c/../../d"), "a/d");
crates/core/src/controls/agent_spec_conformance.rs
steps_at_limit_satisfied Property
let b = bundle(
spec(vec![], vec![], vec![], Some(100), None),
exec(vec![], vec![], 100, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/agent_spec_conformance.rs
budget_at_limit_satisfied Property
let b = bundle(
spec(vec![], vec![], vec![], None, Some(2000)),
exec(vec![], vec![], 0, 2000),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/agent_spec_conformance.rs
steps_one_over_limit_violated Property
let b = bundle(
spec(vec![], vec![], vec![], Some(100), None),
exec(vec![], vec![], 101, 0),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/agent_spec_conformance.rs
budget_one_over_limit_violated Property
let b = bundle(
spec(vec![], vec![], vec![], None, Some(2000)),
exec(vec![], vec![], 0, 2001),
);
let findings = AgentSpecConformanceControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/agent_spec_conformance.rs
branch-history-integrity
Source L2: Verifies that branch history is continuous and linear by checking actual commit history for merge commits (evidence of non-linear history). Instead of checking branch protection API settings (which require admin permissions), this control examines the factual commit history collected from the change request. See ADR-0002 for rationale.
Formal Specification Creusot + SMT
fn branch_history_severity(unprotected_count: usize) -> Severity
Branch history integrity severity (Source L2). Pass iff zero merge commits found in the change request (linear history).
#[ensures(unprotected_count == 0usize ==> result == Severity::Pass)]
#[ensures(unprotected_count >= 1usize ==> result == Severity::Error)]
Implementation
if unprotected_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 7 tests
Test Details
not_applicable_when_no_changes Property
let evidence = EvidenceBundle::default();
let findings = BranchHistoryIntegrityControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert_eq!(
findings[0].control_id,
builtin::id(builtin::BRANCH_HISTORY_INTEGRITY)
);
crates/core/src/controls/branch_history_integrity.rs
not_applicable_when_revisions_not_applicable Property
let bundle = make_bundle(make_change(EvidenceState::not_applicable()));
let findings = BranchHistoryIntegrityControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/branch_history_integrity.rs
indeterminate_when_revisions_missing Property
let bundle = make_bundle(make_change(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "commits".to_string(),
detail: "API returned 403".to_string(),
},
])));
let findings = BranchHistoryIntegrityControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/branch_history_integrity.rs
indeterminate_when_revisions_empty Property
let bundle = make_bundle(make_change(EvidenceState::complete(vec![])));
let findings = BranchHistoryIntegrityControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/branch_history_integrity.rs
satisfied_when_all_commits_linear Property
let bundle = make_bundle(make_change(EvidenceState::complete(vec![
make_revision("abc123", false),
make_revision("def456", false),
])));
let findings = BranchHistoryIntegrityControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("linear history"));
crates/core/src/controls/branch_history_integrity.rs
violated_when_merge_commits_present Property
let bundle = make_bundle(make_change(EvidenceState::complete(vec![
make_revision("abc123", false),
make_revision("merge1", true),
])));
let findings = BranchHistoryIntegrityControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("merge commit"));
assert!(findings[0].rationale.contains("merge1"));
crates/core/src/controls/branch_history_integrity.rs
correct_control_id Property
assert_eq!(
BranchHistoryIntegrityControl.id(),
builtin::id(builtin::BRANCH_HISTORY_INTEGRITY)
);
crates/core/src/controls/branch_history_integrity.rs
branch-protection-enforcement
Source L3: Verifies that continuous technical controls were actually enforced by checking factual evidence: all CI checks passed AND an independent review approved the change. Instead of checking branch protection API settings (which require admin permissions), this control examines whether the enforcement actually happened. See ADR-0002 for rationale.
Formal Specification Creusot + SMT
fn branch_protection_enforcement_severity(non_enforced_count: usize) -> Severity
Technical enforcement severity (Source L3). Pass iff zero change requests lack factual enforcement (CI checks passed + independent review).
#[ensures(non_enforced_count == 0usize ==> result == Severity::Pass)]
#[ensures(non_enforced_count >= 1usize ==> result == Severity::Error)]
Implementation
if non_enforced_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 9 tests
Test Details
not_applicable_when_no_changes Property
let evidence = EvidenceBundle {
check_runs: passing_checks(),
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/branch_protection_enforcement.rs
satisfied_when_checks_pass_and_independent_review Property
let evidence = EvidenceBundle {
change_requests: vec![make_approved_change()],
check_runs: passing_checks(),
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(
findings[0]
.rationale
.contains("Technical controls were enforced")
);
crates/core/src/controls/branch_protection_enforcement.rs
violated_when_checks_fail Property
let evidence = EvidenceBundle {
change_requests: vec![make_approved_change()],
check_runs: failing_checks(),
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("CI check(s) failed"));
crates/core/src/controls/branch_protection_enforcement.rs
violated_when_no_independent_review Property
let change = make_change(
EvidenceState::complete(vec![ApprovalDecision {
actor: "author".to_string(), // self-approval
disposition: ApprovalDisposition::Approved,
submitted_at: None,
}]),
EvidenceState::complete(vec![SourceRevision {
id: "abc123".to_string(),
authored_by: Some("author".to_string()),
committed_at: None,
merge: false,
authenticity: EvidenceState::not_applicable(),
}]),
);
let evidence = EvidenceBundle {
change_requests: vec![change],
check_runs: passing_checks(),
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no independent review"));
crates/core/src/controls/branch_protection_enforcement.rs
violated_when_no_checks_executed Property
let evidence = EvidenceBundle {
change_requests: vec![make_approved_change()],
check_runs: EvidenceState::complete(vec![]),
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no CI checks were executed"));
crates/core/src/controls/branch_protection_enforcement.rs
violated_reports_both_gaps Property
let change = make_change(
EvidenceState::complete(vec![]), // no approvals
EvidenceState::complete(vec![]),
);
let evidence = EvidenceBundle {
change_requests: vec![change],
check_runs: EvidenceState::complete(vec![]), // no checks
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no CI checks"));
assert!(findings[0].rationale.contains("no independent review"));
crates/core/src/controls/branch_protection_enforcement.rs
indeterminate_when_check_runs_missing Property
let evidence = EvidenceBundle {
change_requests: vec![make_approved_change()],
check_runs: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "check-runs".to_string(),
detail: "API returned 403".to_string(),
}]),
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/branch_protection_enforcement.rs
indeterminate_when_approvals_missing Property
let change = make_change(
EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "reviews".to_string(),
detail: "API returned 403".to_string(),
}]),
EvidenceState::complete(vec![]),
);
let evidence = EvidenceBundle {
change_requests: vec![change],
check_runs: passing_checks(),
..Default::default()
};
let findings = BranchProtectionEnforcementControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/branch_protection_enforcement.rs
correct_control_id Property
assert_eq!(
BranchProtectionEnforcementControl.id(),
builtin::id(builtin::BRANCH_PROTECTION_ENFORCEMENT)
);
crates/core/src/controls/branch_protection_enforcement.rs
build-isolation
Verifies that builds run in isolated, ephemeral environments with signing key isolation.
Formal Specification Creusot + SMT
fn build_isolation_severity(non_isolated_count: usize) -> Severity
Build isolation severity (Build L3). Pass iff zero builds lack isolation, ephemerality, or signing key isolation.
#[ensures(non_isolated_count == 0usize ==> result == Severity::Pass)]
#[ensures(non_isolated_count >= 1usize ==> result == Severity::Error)]
Implementation
if non_isolated_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 13 tests
Test Details
not_applicable_when_evidence_state_is_not_applicable Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::not_applicable(),
..Default::default()
};
let findings = BuildIsolationControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert_eq!(
findings[0].control_id,
builtin::id(builtin::BUILD_ISOLATION)
);
crates/core/src/controls/build_isolation.rs
not_applicable_when_platform_list_empty Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/build_isolation.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "build-platform".to_string(),
detail: "API returned 403".to_string(),
}]),
..Default::default()
};
let findings = BuildIsolationControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/build_isolation.rs
satisfied_when_all_conditions_met Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![
make_platform("github-actions", true, true, true),
make_platform("cloud-build", true, true, true),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects.len(), 2);
assert!(findings[0].rationale.contains("2 build platform(s)"));
crates/core/src/controls/build_isolation.rs
satisfied_single_fully_isolated_platform Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![make_platform(
"github-actions",
true,
true,
true,
)]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects, vec!["github-actions"]);
crates/core/src/controls/build_isolation.rs
violated_when_not_isolated Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![make_platform(
"shared-runner",
false,
true,
true,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("shared-runner"));
assert!(findings[0].rationale.contains("not isolated"));
crates/core/src/controls/build_isolation.rs
violated_when_not_ephemeral Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![make_platform(
"persistent-runner",
true,
false,
true,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("persistent-runner"));
assert!(findings[0].rationale.contains("not ephemeral"));
crates/core/src/controls/build_isolation.rs
violated_when_signing_key_not_isolated Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![make_platform(
"leaky-runner",
true,
true,
false,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("leaky-runner"));
assert!(findings[0].rationale.contains("signing key not isolated"));
crates/core/src/controls/build_isolation.rs
violated_reports_multiple_failures Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![make_platform(
"bad-runner",
false,
false,
false,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("not isolated"));
assert!(findings[0].rationale.contains("not ephemeral"));
assert!(findings[0].rationale.contains("signing key not isolated"));
crates/core/src/controls/build_isolation.rs
violated_when_any_platform_fails Property
let findings = BuildIsolationControl.evaluate(&make_bundle(vec![
make_platform("github-actions", true, true, true),
make_platform("self-hosted", false, false, false),
]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("self-hosted"));
assert_eq!(findings[0].subjects.len(), 2);
crates/core/src/controls/build_isolation.rs
partial_evidence_with_isolated_platforms_satisfied Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::partial(
vec![make_platform("github-actions", true, true, true)],
vec![EvidenceGap::Truncated {
source: "github".to_string(),
subject: "build-platforms".to_string(),
}],
),
..Default::default()
};
let findings = BuildIsolationControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/build_isolation.rs
partial_evidence_with_non_isolated_platform_violated Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::partial(
vec![make_platform("shared-runner", false, true, true)],
vec![EvidenceGap::Truncated {
source: "github".to_string(),
subject: "build-platforms".to_string(),
}],
),
..Default::default()
};
let findings = BuildIsolationControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/build_isolation.rs
correct_control_id Property
assert_eq!(
BuildIsolationControl.id(),
builtin::id(builtin::BUILD_ISOLATION)
);
crates/core/src/controls/build_isolation.rs
build-provenance
Verifies that all artifact attestations carry valid cryptographic provenance.
Formal Specification Creusot + SMT
fn build_provenance_severity(unverified_count: usize) -> Severity
Build provenance severity. Pass iff zero unverified attestations; Error otherwise. Empty attestation lists are handled at control level (NotApplicable).
#[ensures(unverified_count == 0usize ==> result == Severity::Pass)]
#[ensures(unverified_count >= 1usize ==> result == Severity::Error)]
Implementation
if unverified_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 11 tests
Test Details
not_applicable_when_evidence_state_is_not_applicable Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::not_applicable(),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert_eq!(
findings[0].control_id,
builtin::id(builtin::BUILD_PROVENANCE)
);
crates/core/src/controls/build_provenance.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "gh-attestation".to_string(),
subject: "binary".to_string(),
detail: "API returned 403".to_string(),
}]),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/build_provenance.rs
not_applicable_when_attestation_list_empty Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::complete(vec![]),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/build_provenance.rs
satisfied_when_all_verified Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::complete(vec![
make_attestation("ghcr.io/owner/app:v1.0.0", true),
make_attestation("gh-verify-linux-amd64", true),
]),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects.len(), 2);
crates/core/src/controls/build_provenance.rs
violated_when_any_unverified Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::complete(vec![
make_attestation("ghcr.io/owner/app:v1.0.0", true),
make_attestation("gh-verify-linux-amd64", false),
]),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("gh-verify-linux-amd64"));
// subjects should list all artifacts, not just unverified ones
assert_eq!(findings[0].subjects.len(), 2);
crates/core/src/controls/build_provenance.rs
violated_when_all_unverified Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::complete(vec![
make_attestation("artifact-a", false),
make_attestation("artifact-b", false),
]),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("artifact-a"));
assert!(findings[0].rationale.contains("artifact-b"));
crates/core/src/controls/build_provenance.rs
single_verified_attestation_satisfied Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::complete(vec![make_attestation(
"single-binary",
true,
)]),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects, vec!["single-binary"]);
crates/core/src/controls/build_provenance.rs
partial_evidence_with_verified_attestations_satisfied Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::partial(
vec![make_attestation("partial-binary", true)],
vec![EvidenceGap::Truncated {
source: "gh-attestation".to_string(),
subject: "attestation-list".to_string(),
}],
),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/build_provenance.rs
partial_evidence_with_unverified_attestation_violated Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::partial(
vec![make_attestation("partial-binary", false)],
vec![EvidenceGap::Truncated {
source: "gh-attestation".to_string(),
subject: "attestation-list".to_string(),
}],
),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/build_provenance.rs
partial_evidence_with_empty_list_not_applicable Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::partial(
vec![],
vec![EvidenceGap::Truncated {
source: "gh-attestation".to_string(),
subject: "attestation-list".to_string(),
}],
),
..Default::default()
};
let findings = BuildProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/build_provenance.rs
correct_control_id Property
assert_eq!(
BuildProvenanceControl.id(),
builtin::id(builtin::BUILD_PROVENANCE)
);
crates/core/src/controls/build_provenance.rs
change-request-size
Verifies that change request size is within acceptable limits.
Behavioral Specification 17 tests
| Scenario | Verdict | Key Assertion |
|---|---|---|
| small pr passes | Pass | assert_eq!( |
| many lines warns | Warning | assert_eq!( |
| many files warns | Warning | assert_eq!( |
| huge pr errors | Error | assert_eq!( |
Test Details
not_applicable_when_no_changes Property
let findings = ChangeRequestSizeControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/change_request_size.rs
satisfied_for_small_pr Property
let bundle = bundle_with(EvidenceState::complete(vec![
asset("src/foo.rs", 50, 10),
asset("src/bar.rs", 30, 5),
]));
let findings = ChangeRequestSizeControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/change_request_size.rs
violated_for_large_pr Property
let bundle = bundle_with(EvidenceState::complete(vec![asset(
"src/huge.rs",
800,
300,
)]));
let findings = ChangeRequestSizeControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/change_request_size.rs
generated_files_excluded Property
let bundle = bundle_with(EvidenceState::complete(vec![
asset("package-lock.json", 5000, 2000),
asset("src/main.rs", 10, 5),
]));
let findings = ChangeRequestSizeControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(
!findings[0]
.subjects
.contains(&"package-lock.json".to_string())
);
crates/core/src/controls/change_request_size.rs
indeterminate_when_evidence_missing Property
let bundle = bundle_with(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "files".to_string(),
detail: "API error".to_string(),
},
]));
let findings = ChangeRequestSizeControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/change_request_size.rs
lock_file Property
assert!(is_generated_file("Cargo.lock"));
assert!(is_generated_file("yarn.lock"));
assert!(is_generated_file("deep/path/Gemfile.lock"));
crates/core/src/size.rs
lock_json Property
assert!(is_generated_file("package-lock.json"));
assert!(is_generated_file("node_modules/foo/package-lock.json"));
crates/core/src/size.rs
lock_yaml Property
assert!(is_generated_file("pnpm-lock.yaml"));
assert!(is_generated_file("some/path/pnpm-lock.yaml"));
assert!(is_generated_file("pnpm-lock.yml"));
crates/core/src/size.rs
yarn_lock Property
assert!(is_generated_file("yarn.lock"));
assert!(is_generated_file("packages/app/yarn.lock"));
crates/core/src/size.rs
snap_file Property
assert!(is_generated_file("tests/__snapshots__/foo.snap"));
crates/core/src/size.rs
generated_file Property
assert!(is_generated_file("src/schema.generated.ts"));
assert!(is_generated_file("proto/api.generated.go"));
crates/core/src/size.rs
normal_file Property
assert!(!is_generated_file("src/main.rs"));
assert!(!is_generated_file("README.md"));
assert!(!is_generated_file("lib/lock_manager.rs"));
crates/core/src/size.rs
small_pr_passes Pass
assert_eq!(
classify_pr_size(10, 2, WARN_LINES, WARN_FILES, ERROR_LINES, ERROR_FILES),
Severity::Pass,
);
crates/core/src/size.rs
many_lines_warns Warning
assert_eq!(
classify_pr_size(600, 5, WARN_LINES, WARN_FILES, ERROR_LINES, ERROR_FILES),
Severity::Warning,
);
crates/core/src/size.rs
many_files_warns Warning
assert_eq!(
classify_pr_size(100, 20, WARN_LINES, WARN_FILES, ERROR_LINES, ERROR_FILES),
Severity::Warning,
);
crates/core/src/size.rs
huge_pr_errors Error
assert_eq!(
classify_pr_size(1500, 40, WARN_LINES, WARN_FILES, ERROR_LINES, ERROR_FILES),
Severity::Error,
);
crates/core/src/size.rs
boundary_at_threshold_passes Property
// Exactly at the threshold is not "exceeds", so it should pass/warn respectively.
assert_eq!(
classify_pr_size(500, 15, WARN_LINES, WARN_FILES, ERROR_LINES, ERROR_FILES),
Severity::Pass,
);
assert_eq!(
classify_pr_size(1000, 30, WARN_LINES, WARN_FILES, ERROR_LINES, ERROR_FILES),
Severity::Warning,
);
crates/core/src/size.rs
code-scanning-alerts-resolved
Validates that no high-or-above severity code scanning alerts are open. Maps to SOC2 CC7.1: detect and remediate vulnerabilities in source code. Open high/critical code scanning alerts indicate known security weaknesses that could be exploited in production. Evaluation: - NotApplicable: code scanning is not enabled - Satisfied: zero open high-or-above severity alerts - Violated: one or more open high-or-above severity alerts
Behavioral Specification 5 tests
Test Details
not_applicable_when_posture_not_applicable Property
let findings =
CodeScanningAlertsResolvedControl.evaluate(&bundle(EvidenceState::not_applicable()));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/code_scanning_alerts_resolved.rs
indeterminate_when_posture_missing Property
let findings =
CodeScanningAlertsResolvedControl.evaluate(&bundle(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "posture".to_string(),
detail: "API error".to_string(),
},
])));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/code_scanning_alerts_resolved.rs
not_applicable_when_code_scanning_disabled Property
let findings = CodeScanningAlertsResolvedControl
.evaluate(&bundle(EvidenceState::complete(posture(false, 0))));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert!(findings[0].rationale.contains("not enabled"));
crates/core/src/controls/code_scanning_alerts_resolved.rs
satisfied_when_no_open_alerts Property
let findings = CodeScanningAlertsResolvedControl
.evaluate(&bundle(EvidenceState::complete(posture(true, 0))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("No open"));
crates/core/src/controls/code_scanning_alerts_resolved.rs
violated_when_open_alerts_exist Property
let findings = CodeScanningAlertsResolvedControl
.evaluate(&bundle(EvidenceState::complete(posture(true, 3))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("3 open"));
assert!(findings[0].subjects[0].contains("open:3"));
crates/core/src/controls/code_scanning_alerts_resolved.rs
codeowners-coverage
Validates that a CODEOWNERS file exists and provides meaningful coverage. Maps to SOC2 CC6.1: logical access controls ensure that code changes to sensitive areas are routed to designated owners for review. Also an ASPM signal — code ownership coverage reduces unreviewed blast radius. Evaluation tiers: - Satisfied: catch-all pattern exists, OR 3+ targeted entries (intentional ownership) - Violated: no entries, or fewer than 3 entries without catch-all
Behavioral Specification 8 tests
Test Details
not_applicable_when_posture_not_applicable Property
let findings = CodeownersCoverageControl.evaluate(&bundle(EvidenceState::not_applicable()));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/codeowners_coverage.rs
indeterminate_when_posture_missing Property
let findings = CodeownersCoverageControl.evaluate(&bundle(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "posture".to_string(),
detail: "API error".to_string(),
},
])));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/codeowners_coverage.rs
violated_when_no_entries Property
let findings =
CodeownersCoverageControl.evaluate(&bundle(EvidenceState::complete(posture(vec![]))));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/codeowners_coverage.rs
violated_when_too_few_entries_without_catch_all Property
let findings =
CodeownersCoverageControl.evaluate(&bundle(EvidenceState::complete(posture(vec![
entry("/src/", &["@org/core-team"]),
]))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("only 1 entries"));
crates/core/src/controls/codeowners_coverage.rs
satisfied_with_catch_all Property
let findings =
CodeownersCoverageControl.evaluate(&bundle(EvidenceState::complete(posture(vec![
entry("/src/auth/", &["@org/security-team"]),
entry("*", &["@org/default-reviewers"]),
]))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/codeowners_coverage.rs
satisfied_with_glob_catch_all Property
let findings =
CodeownersCoverageControl.evaluate(&bundle(EvidenceState::complete(posture(vec![
entry("/**", &["@org/default-reviewers"]),
]))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/codeowners_coverage.rs
satisfied_with_targeted_entries_no_catch_all Property
let findings =
CodeownersCoverageControl.evaluate(&bundle(EvidenceState::complete(posture(vec![
entry("/src/auth/", &["@org/security-team"]),
entry("/infra/", &["@org/platform-team"]),
entry("/.github/", &["@org/devops"]),
]))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("targeted entries"));
crates/core/src/controls/codeowners_coverage.rs
violated_with_two_entries_no_catch_all Property
let findings =
CodeownersCoverageControl.evaluate(&bundle(EvidenceState::complete(posture(vec![
entry("/src/auth/", &["@org/security-team"]),
entry("/infra/", &["@org/platform-team"]),
]))));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/codeowners_coverage.rs
conventional-title
Verifies that change request titles follow the Conventional Commits format. Maps to SOC2 CC8.1: structured change documentation. Conventional commit titles (e.g. feat: add X, fix!: resolve Y) enable automated changelog generation and ensure changes are categorized consistently.
Behavioral Specification 11 tests
Test Details
not_applicable_when_no_changes Property
let findings = ConventionalTitleControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/conventional_title.rs
satisfied_for_feat Property
let cr = make_change("feat: add new compliance control");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/conventional_title.rs
satisfied_for_fix_with_scope Property
let cr = make_change("fix(core): resolve null pointer");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/conventional_title.rs
satisfied_for_breaking_change Property
let cr = make_change("refactor!: rename API endpoint");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/conventional_title.rs
satisfied_for_breaking_with_scope Property
let cr = make_change("feat(api)!: redesign auth flow");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/conventional_title.rs
violated_for_untyped_title Property
let cr = make_change("Add new feature");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/conventional_title.rs
violated_for_unknown_type Property
let cr = make_change("wip: work in progress");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/conventional_title.rs
violated_for_missing_space_after_colon Property
let cr = make_change("feat:no space");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/conventional_title.rs
violated_for_empty_description Property
let cr = make_change("feat: ");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/conventional_title.rs
violated_for_empty_title Property
let cr = make_change("");
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/conventional_title.rs
all_conventional_types_accepted Property
for ty in CONVENTIONAL_TYPES {
let cr = make_change(&format!("{ty}: test description"));
let findings = ConventionalTitleControl.evaluate(&bundle(vec![cr]));
assert_eq!(
findings[0].status,
ControlStatus::Satisfied,
"type '{ty}' should be accepted"
);
}
crates/core/src/controls/conventional_title.rs
dependency-completeness
Verifies that ALL dependencies (direct AND transitive) meet L3 verification (Dependencies L4). Requires: - Every dependency (regardless of is_direct) has Verified + signer_identity + transparency_log_uri - At least one transitive dependency exists (otherwise the check is trivially satisfied and the control returns NotApplicable — a project with only direct deps should use L3) This is the strictest dependency verification level. It ensures the entire dependency tree — not just direct dependencies — is fully provenance-verified. Registry scoping: Only evaluates dependencies from registries that support the full trust chain (L3). Dependencies from non-L3 registries are excluded.
Behavioral Specification 8 tests
Test Details
satisfied_when_all_npm_deps_fully_verified Property
let evidence = bundle(vec![
npm_dep_l3("react", true),
npm_dep_l3("react-dom", false),
npm_dep_l3("express", true),
npm_dep_l3("body-parser", false),
]);
let findings = DependencyCompletenessControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("2 direct"));
assert!(findings[0].rationale.contains("2 transitive"));
crates/core/src/controls/dependency_completeness.rs
violated_when_npm_transitive_dep_lacks_provenance Property
let evidence = bundle(vec![
npm_dep_l3("react", true),
npm_dep_checksum("scheduler", false),
]);
let findings = DependencyCompletenessControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(
findings[0]
.rationale
.contains("scheduler@1.0.0 [transitive]")
);
crates/core/src/controls/dependency_completeness.rs
violated_when_npm_direct_dep_lacks_provenance Property
let evidence = bundle(vec![
npm_dep_checksum("lodash", true),
npm_dep_l3("express", false),
]);
let findings = DependencyCompletenessControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("lodash@1.0.0 [direct]"));
crates/core/src/controls/dependency_completeness.rs
not_applicable_when_only_cargo_deps Property
let findings = DependencyCompletenessControl.evaluate(&bundle(vec![cargo_dep("serde")]));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/dependency_completeness.rs
mixed_registries_only_evaluates_npm Property
let evidence = bundle(vec![cargo_dep("serde"), npm_dep_l3("react", true)]);
let findings = DependencyCompletenessControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("skipped"));
crates/core/src/controls/dependency_completeness.rs
violated_when_partial_evidence_has_gaps Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::partial(
vec![npm_dep_l3("react", true)],
vec![EvidenceGap::Truncated {
source: "github-tree-api".to_string(),
subject: "repository-tree".to_string(),
}],
),
..Default::default()
};
let findings = DependencyCompletenessControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(
findings[0]
.rationale
.contains("Cannot guarantee completeness")
);
crates/core/src/controls/dependency_completeness.rs
not_applicable_when_empty Property
let findings = DependencyCompletenessControl.evaluate(&bundle(vec![]));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/dependency_completeness.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "registry".to_string(),
subject: "deps".to_string(),
detail: "timeout".to_string(),
}]),
..Default::default()
};
let findings = DependencyCompletenessControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/dependency_completeness.rs
dependency-provenance-check
Verifies that all dependencies have cryptographic provenance (Dependencies L2). Requires every dependency to have: - VerificationOutcome::Verified (not just ChecksumMatch) - source_repo present (provenance links to source) This is stricter than L1 (dependency-signature) which accepts checksum-only verification. Registry scoping: Only evaluates dependencies from registries that support cryptographic provenance (L2+). Dependencies from checksum-only registries (e.g. crates.io) are excluded to avoid false positives. If all dependencies are from checksum-only registries, the control returns NotApplicable.
Behavioral Specification 8 tests
Test Details
satisfied_when_all_npm_signed_with_source_repo Property
let evidence = bundle(vec![
npm_dep_signed("react", Some("facebook/react")),
npm_dep_signed("express", Some("expressjs/express")),
]);
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/dependency_provenance.rs
violated_when_npm_checksum_only Property
let evidence = bundle(vec![npm_dep_no_provenance("lodash")]);
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no cryptographic signature"));
crates/core/src/controls/dependency_provenance.rs
violated_when_npm_signed_but_no_source_repo Property
let evidence = bundle(vec![npm_dep_signed("react", None)]);
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no source_repo"));
crates/core/src/controls/dependency_provenance.rs
not_applicable_when_only_cargo_deps Property
let evidence = bundle(vec![cargo_dep("serde"), cargo_dep("tokio")]);
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert!(findings[0].rationale.contains("checksum-only registries"));
crates/core/src/controls/dependency_provenance.rs
mixed_registries_only_evaluates_npm Property
let evidence = bundle(vec![
cargo_dep("serde"),
npm_dep_signed("react", Some("facebook/react")),
]);
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("1 dependenc(ies)"));
assert!(findings[0].rationale.contains("skipped"));
crates/core/src/controls/dependency_provenance.rs
not_applicable_when_empty Property
let evidence = bundle(vec![]);
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/dependency_provenance.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::missing(vec![
crate::evidence::EvidenceGap::CollectionFailed {
source: "registry".to_string(),
subject: "deps".to_string(),
detail: "timeout".to_string(),
},
]),
..Default::default()
};
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/dependency_provenance.rs
partial_evidence_propagates_gaps_in_rationale Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::partial(
vec![npm_dep_signed("react", Some("facebook/react"))],
vec![crate::evidence::EvidenceGap::Truncated {
source: "tree-api".to_string(),
subject: "repo-tree".to_string(),
}],
),
..Default::default()
};
let findings = DependencyProvenanceControl.evaluate(&evidence);
assert!(
findings[0].rationale.contains("evidence gap"),
"rationale should warn about gaps: {}",
findings[0].rationale
);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/dependency_provenance.rs
dependency-signature
Verifies that all dependencies have been checked for integrity or provenance. Distinguishes two levels of verification: - Verified: Cryptographic signature confirmed (Sigstore, PGP, cosign) - ChecksumMatch: Integrity hash matched (Cargo.lock checksum, npm SRI hash) — confirms download integrity but NOT authenticity Both levels pass this control, but the rationale clearly reports the breakdown (e.g. "140 checksum, 2 sigstore") so consumers can distinguish trust levels. When evidence is Partial (some dependencies could not be checked), the control propagates the evidence gaps into the finding and appends a warning to the rationale.
Formal Specification Creusot + SMT
fn dependency_signature_severity(unsigned_count: usize) -> Severity
Dependency signature verification severity. Pass iff zero dependencies lack verified signatures; Error otherwise.
#[ensures(unsigned_count == 0usize ==> result == Severity::Pass)]
#[ensures(unsigned_count >= 1usize ==> result == Severity::Error)]
Implementation
if unsigned_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 18 tests
Test Details
not_applicable_when_evidence_state_is_not_applicable Property
let evidence = EvidenceBundle::default();
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert_eq!(
findings[0].control_id,
builtin::id(builtin::DEPENDENCY_SIGNATURE)
);
crates/core/src/controls/dependency_signature.rs
not_applicable_when_dependency_list_empty Property
let findings = DependencySignatureControl.evaluate(&make_bundle(vec![]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/dependency_signature.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "package-registry".to_string(),
subject: "dependencies".to_string(),
detail: "registry unreachable".to_string(),
}]),
..Default::default()
};
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/dependency_signature.rs
satisfied_when_all_signed Property
let findings = DependencySignatureControl.evaluate(&make_bundle(vec![
make_dep("serde", "1.0.204", true),
make_dep("tokio", "1.38.0", true),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects.len(), 2);
assert!(findings[0].rationale.contains("2 dependenc(ies) verified"));
crates/core/src/controls/dependency_signature.rs
satisfied_single_dependency Property
let findings = DependencySignatureControl
.evaluate(&make_bundle(vec![make_dep("serde", "1.0.204", true)]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects, vec!["serde@1.0.204"]);
crates/core/src/controls/dependency_signature.rs
violated_when_dependency_unsigned Property
let findings = DependencySignatureControl.evaluate(&make_bundle(vec![
make_dep("serde", "1.0.204", true),
make_dep("sketchy-lib", "0.1.0", false),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("sketchy-lib@0.1.0"));
assert!(findings[0].rationale.contains("attestation_absent"));
crates/core/src/controls/dependency_signature.rs
violated_when_all_unsigned Property
let findings = DependencySignatureControl.evaluate(&make_bundle(vec![
make_dep("foo", "1.0.0", false),
make_dep("bar", "2.0.0", false),
]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("foo@1.0.0"));
assert!(findings[0].rationale.contains("bar@2.0.0"));
crates/core/src/controls/dependency_signature.rs
violated_with_signature_invalid_reason Property
let evidence = make_bundle(vec![DependencySignatureEvidence {
name: "tampered-pkg".to_string(),
version: "1.0.0".to_string(),
registry: Some("registry.npmjs.org".to_string()),
verification: VerificationOutcome::SignatureInvalid {
detail: "ECDSA signature mismatch".to_string(),
},
signature_mechanism: Some("sigstore".to_string()),
signer_identity: None,
source_repo: None,
source_commit: None,
pinned_digest: None,
actual_digest: None,
is_direct: true,
transparency_log_uri: None,
}]);
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("signature_invalid"));
crates/core/src/controls/dependency_signature.rs
partial_evidence_with_signed_deps_includes_gap_warning Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::partial(
vec![make_dep("serde", "1.0.204", true)],
vec![EvidenceGap::Truncated {
source: "package-registry".to_string(),
subject: "dependency-list".to_string(),
}],
),
..Default::default()
};
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(
findings[0].rationale.contains("evidence gap"),
"Partial evidence must warn about gaps in rationale: {}",
findings[0].rationale
);
assert_eq!(
findings[0].evidence_gaps.len(),
1,
"Partial evidence gaps must propagate to finding"
);
crates/core/src/controls/dependency_signature.rs
partial_evidence_with_unsigned_dep_violated Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::partial(
vec![make_dep("sketchy", "0.1.0", false)],
vec![EvidenceGap::Truncated {
source: "package-registry".to_string(),
subject: "dependency-list".to_string(),
}],
),
..Default::default()
};
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("evidence gap"));
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/dependency_signature.rs
partial_evidence_empty_deps_is_indeterminate Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::partial(
vec![],
vec![EvidenceGap::CollectionFailed {
source: "npm-registry".to_string(),
subject: "audit-signatures".to_string(),
detail: "timeout".to_string(),
}],
),
..Default::default()
};
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/dependency_signature.rs
npm_provenance_satisfied_with_source_repo Property
let findings = DependencySignatureControl.evaluate(&make_bundle(vec![
make_npm_dep("react", "18.3.1", true, Some("facebook/react")),
make_npm_dep("express", "4.18.2", true, Some("expressjs/express")),
]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/dependency_signature.rs
npm_provenance_mixed_legacy_violated Property
let findings = DependencySignatureControl.evaluate(&make_bundle(vec![
make_npm_dep("react", "18.3.1", true, Some("facebook/react")),
make_npm_dep("lodash", "4.17.21", false, None),
]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("lodash@4.17.21"));
crates/core/src/controls/dependency_signature.rs
violated_with_digest_mismatch Property
let evidence = make_bundle(vec![DependencySignatureEvidence {
name: "replaced-pkg".to_string(),
version: "1.0.0".to_string(),
registry: Some("registry.npmjs.org".to_string()),
verification: VerificationOutcome::DigestMismatch {
detail: "sha512 mismatch: expected abc..., got def...".to_string(),
},
signature_mechanism: None,
signer_identity: None,
source_repo: None,
source_commit: None,
pinned_digest: Some("sha512:abc123".to_string()),
actual_digest: Some("sha512:def456".to_string()),
transparency_log_uri: None,
is_direct: false,
}]);
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("digest_mismatch"));
crates/core/src/controls/dependency_signature.rs
violated_with_signer_mismatch Property
let evidence = make_bundle(vec![DependencySignatureEvidence {
name: "hijacked-pkg".to_string(),
version: "2.0.0".to_string(),
registry: Some("registry.npmjs.org".to_string()),
verification: VerificationOutcome::SignerMismatch {
detail: "expected signer: alice@example.com, got: eve@attacker.com".to_string(),
},
signature_mechanism: Some("sigstore".to_string()),
signer_identity: Some("eve@attacker.com".to_string()),
source_repo: None,
source_commit: None,
pinned_digest: None,
actual_digest: None,
transparency_log_uri: None,
is_direct: true,
}]);
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("signer_mismatch"));
crates/core/src/controls/dependency_signature.rs
violated_when_verified_but_digest_differs Property
// Critical: artifact replacement attack where signature is valid
// but the actual artifact was swapped after signing.
let evidence = make_bundle(vec![DependencySignatureEvidence {
name: "swapped-pkg".to_string(),
version: "1.0.0".to_string(),
registry: Some("crates.io".to_string()),
verification: VerificationOutcome::Verified,
signature_mechanism: Some("sigstore".to_string()),
signer_identity: Some("legit@example.com".to_string()),
source_repo: Some("owner/repo".to_string()),
source_commit: None,
pinned_digest: Some("sha512:expected".to_string()),
actual_digest: Some("sha512:tampered".to_string()),
transparency_log_uri: None,
is_direct: true,
}]);
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(
findings[0].status,
ControlStatus::Violated,
"Verified signature with mismatched digest must be Violated"
);
assert!(findings[0].rationale.contains("digest_mismatch"));
crates/core/src/controls/dependency_signature.rs
satisfied_when_verified_and_digests_match Property
let evidence = make_bundle(vec![DependencySignatureEvidence {
name: "good-pkg".to_string(),
version: "1.0.0".to_string(),
registry: Some("crates.io".to_string()),
verification: VerificationOutcome::Verified,
signature_mechanism: Some("sigstore".to_string()),
signer_identity: None,
source_repo: None,
source_commit: None,
pinned_digest: Some("sha512:abc".to_string()),
actual_digest: Some("sha512:abc".to_string()),
transparency_log_uri: None,
is_direct: true,
}]);
let findings = DependencySignatureControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/dependency_signature.rs
correct_control_id Property
assert_eq!(
DependencySignatureControl.id(),
builtin::id(builtin::DEPENDENCY_SIGNATURE)
);
crates/core/src/controls/dependency_signature.rs
dependency-signer-verified
Verifies that all dependencies have bound signer identity and transparency log (Dependencies L3). Requires every dependency to have: - VerificationOutcome::Verified (cryptographic signature) - signer_identity present (who signed it) - transparency_log_uri present (publicly auditable) This extends L2 (dependency-provenance) by requiring the full trust chain to be inspectable: not just "signed by someone" but "signed by whom, verifiable where". Registry scoping: Only evaluates dependencies from registries that support the full trust chain (L3: signature + signer identity + transparency log). Currently only npm (Sigstore + Rekor) qualifies. Dependencies from L2-only or checksum-only registries are excluded.
Behavioral Specification 8 tests
Test Details
satisfied_with_full_trust_chain Property
let findings = DependencySignerVerifiedControl.evaluate(&bundle(vec![
npm_dep_full("react"),
npm_dep_full("express"),
]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/dependency_signer_verified.rs
violated_when_signer_identity_missing Property
let findings =
DependencySignerVerifiedControl.evaluate(&bundle(vec![npm_dep_no_signer("lodash")]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no signer_identity"));
crates/core/src/controls/dependency_signer_verified.rs
violated_when_transparency_log_missing Property
let findings =
DependencySignerVerifiedControl.evaluate(&bundle(vec![npm_dep_no_tlog("lodash")]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no transparency_log"));
crates/core/src/controls/dependency_signer_verified.rs
not_applicable_when_only_cargo_deps Property
let findings = DependencySignerVerifiedControl.evaluate(&bundle(vec![cargo_dep("serde")]));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert!(findings[0].rationale.contains("skipped"));
crates/core/src/controls/dependency_signer_verified.rs
mixed_registries_only_evaluates_npm Property
let evidence = bundle(vec![cargo_dep("serde"), npm_dep_full("react")]);
let findings = DependencySignerVerifiedControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("1 dependenc(ies)"));
crates/core/src/controls/dependency_signer_verified.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::missing(vec![
crate::evidence::EvidenceGap::CollectionFailed {
source: "registry".to_string(),
subject: "deps".to_string(),
detail: "timeout".to_string(),
},
]),
..Default::default()
};
let findings = DependencySignerVerifiedControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/dependency_signer_verified.rs
partial_evidence_propagates_gaps_in_rationale Property
let evidence = EvidenceBundle {
dependency_signatures: EvidenceState::partial(
vec![npm_dep_full("react")],
vec![crate::evidence::EvidenceGap::Truncated {
source: "tree-api".to_string(),
subject: "repo-tree".to_string(),
}],
),
..Default::default()
};
let findings = DependencySignerVerifiedControl.evaluate(&evidence);
assert!(
findings[0].rationale.contains("evidence gap"),
"rationale should warn about gaps: {}",
findings[0].rationale
);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/dependency_signer_verified.rs
violated_when_both_signer_and_tlog_missing Property
let mut d = npm_dep_full("pkg");
d.signer_identity = None;
d.transparency_log_uri = None;
let findings = DependencySignerVerifiedControl.evaluate(&bundle(vec![d]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no signer_identity"));
assert!(findings[0].rationale.contains("no transparency_log"));
crates/core/src/controls/dependency_signer_verified.rs
description-quality
Verifies that change requests include a meaningful description. Maps to SOC2 CC8.1: change management documentation. A well-documented change request ensures reviewers understand intent, scope, and rationale before approving.
Behavioral Specification 6 tests
Test Details
not_applicable_when_no_changes Property
let findings = DescriptionQualityControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/description_quality.rs
satisfied_when_body_present Property
let cr = make_change(Some(
"This PR adds a new compliance control for description quality.",
));
let findings = DescriptionQualityControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/description_quality.rs
violated_when_body_none Property
let cr = make_change(None);
let findings = DescriptionQualityControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no description"));
crates/core/src/controls/description_quality.rs
violated_when_body_empty Property
let cr = make_change(Some(""));
let findings = DescriptionQualityControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/description_quality.rs
violated_when_body_too_short Property
let cr = make_change(Some("fix"));
let findings = DescriptionQualityControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("too short"));
crates/core/src/controls/description_quality.rs
violated_when_body_only_whitespace Property
let cr = make_change(Some(" \n\t "));
let findings = DescriptionQualityControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no description"));
crates/core/src/controls/description_quality.rs
hosted-build-platform
Verifies that all builds run on hosted infrastructure, not developer workstations.
Formal Specification Creusot + SMT
fn hosted_build_severity(non_hosted_count: usize) -> Severity
Hosted build platform severity (Build L2). Pass iff zero build runs are on non-hosted platforms.
#[ensures(non_hosted_count == 0usize ==> result == Severity::Pass)]
#[ensures(non_hosted_count >= 1usize ==> result == Severity::Error)]
Implementation
if non_hosted_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 10 tests
Test Details
not_applicable_when_evidence_state_is_not_applicable Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::not_applicable(),
..Default::default()
};
let findings = HostedBuildPlatformControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert_eq!(
findings[0].control_id,
builtin::id(builtin::HOSTED_BUILD_PLATFORM)
);
crates/core/src/controls/hosted_build_platform.rs
not_applicable_when_platform_list_empty Property
let findings = HostedBuildPlatformControl.evaluate(&make_bundle(vec![]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/hosted_build_platform.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "build-platform".to_string(),
detail: "API returned 403".to_string(),
}]),
..Default::default()
};
let findings = HostedBuildPlatformControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/hosted_build_platform.rs
satisfied_when_all_platforms_hosted Property
let findings = HostedBuildPlatformControl.evaluate(&make_bundle(vec![
make_platform("github-actions", true),
make_platform("cloud-build", true),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects.len(), 2);
assert!(
findings[0]
.rationale
.contains("2 build platform(s) are hosted")
);
crates/core/src/controls/hosted_build_platform.rs
satisfied_single_hosted_platform Property
let findings = HostedBuildPlatformControl
.evaluate(&make_bundle(vec![make_platform("github-actions", true)]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects, vec!["github-actions"]);
crates/core/src/controls/hosted_build_platform.rs
violated_when_any_platform_not_hosted Property
let findings = HostedBuildPlatformControl.evaluate(&make_bundle(vec![
make_platform("github-actions", true),
make_platform("developer-laptop", false),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("developer-laptop"));
assert_eq!(findings[0].subjects.len(), 2);
crates/core/src/controls/hosted_build_platform.rs
violated_when_all_platforms_not_hosted Property
let findings = HostedBuildPlatformControl.evaluate(&make_bundle(vec![
make_platform("local-runner-a", false),
make_platform("local-runner-b", false),
]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("local-runner-a"));
assert!(findings[0].rationale.contains("local-runner-b"));
crates/core/src/controls/hosted_build_platform.rs
partial_evidence_with_hosted_platforms_satisfied Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::partial(
vec![make_platform("github-actions", true)],
vec![EvidenceGap::Truncated {
source: "github".to_string(),
subject: "build-platforms".to_string(),
}],
),
..Default::default()
};
let findings = HostedBuildPlatformControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/hosted_build_platform.rs
partial_evidence_with_non_hosted_platform_violated Property
let evidence = EvidenceBundle {
build_platform: EvidenceState::partial(
vec![make_platform("self-hosted-runner", false)],
vec![EvidenceGap::Truncated {
source: "github".to_string(),
subject: "build-platforms".to_string(),
}],
),
..Default::default()
};
let findings = HostedBuildPlatformControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/hosted_build_platform.rs
correct_control_id Property
assert_eq!(
HostedBuildPlatformControl.id(),
builtin::id(builtin::HOSTED_BUILD_PLATFORM)
);
crates/core/src/controls/hosted_build_platform.rs
issue-linkage
Verifies that change requests reference at least one issue or ticket.
Behavioral Specification 4 tests
Test Details
not_applicable_when_no_changes Property
let findings = IssueLinkageControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/issue_linkage.rs
satisfied_when_refs_present Property
let cr = make_change(EvidenceState::complete(vec![WorkItemRef {
system: "github_issue".to_string(),
value: "#42".to_string(),
}]));
let findings = IssueLinkageControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].subjects.iter().any(|s| s.contains("#42")));
crates/core/src/controls/issue_linkage.rs
violated_when_no_refs Property
let cr = make_change(EvidenceState::complete(vec![]));
let findings = IssueLinkageControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/issue_linkage.rs
indeterminate_when_missing Property
let cr = make_change(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "body".to_string(),
detail: "parse error".to_string(),
},
]));
let findings = IssueLinkageControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/issue_linkage.rs
merge-commit-policy
Verifies that source revisions follow a linear history policy (no merge commits). Maps to SOC2 CC8.1: change management process integrity. Merge commits in a change request indicate non-linear history (e.g. merging the base branch into the feature branch), which can obscure the audit trail and make it harder to review individual changes.
Behavioral Specification 5 tests
Test Details
not_applicable_when_no_changes Property
let findings = MergeCommitPolicyControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/merge_commit_policy.rs
satisfied_when_all_linear Property
let cr = make_change(EvidenceState::complete(vec![
revision("abc", false),
revision("def", false),
]));
let findings = MergeCommitPolicyControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/merge_commit_policy.rs
violated_when_merge_commit_present Property
let cr = make_change(EvidenceState::complete(vec![
revision("abc", false),
revision("merge123", true),
]));
let findings = MergeCommitPolicyControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("merge123"));
crates/core/src/controls/merge_commit_policy.rs
not_applicable_when_no_revisions Property
let cr = make_change(EvidenceState::complete(vec![]));
let findings = MergeCommitPolicyControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/merge_commit_policy.rs
indeterminate_when_revisions_missing Property
let cr = make_change(EvidenceState::missing(vec![
crate::evidence::EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "commits".to_string(),
detail: "API error".to_string(),
},
]));
let findings = MergeCommitPolicyControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/merge_commit_policy.rs
privileged-operation-audit
Surfaces privileged operations from two evidence sources: 1. Structured git events (force push, admin bypass, tag/branch deletion) 2. Agent action log commands matched against notable patterns This control does not enforce policy — it makes operations visible. The OPA profile decides whether each finding is pass/review/fail.
Behavioral Specification 14 tests
Test Details
no_events_no_actions_satisfied Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::complete(vec![]),
agent_action_log: EvidenceState::complete(log_with(vec![])),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/privileged_operation_audit.rs
force_push_from_git_events Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::complete(vec![git_event(
"bot",
PrivilegedAction::ForcePush,
Some("main"),
None,
)]),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects[0].contains("force-push"));
crates/core/src/controls/privileged_operation_audit.rs
admin_bypass_from_git_events Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::complete(vec![git_event(
"admin",
PrivilegedAction::AdminBypassProtection,
Some("main"),
None,
)]),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/privileged_operation_audit.rs
tag_deletion_from_git_events Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::complete(vec![git_event(
"bot",
PrivilegedAction::TagDeletion,
None,
Some("v1.0.0"),
)]),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects[0].contains("v1.0.0"));
crates/core/src/controls/privileged_operation_audit.rs
rm_rf_from_action_log Property
let b = EvidenceBundle {
agent_action_log: EvidenceState::complete(log_with(vec![action("rm -rf /tmp")])),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects[0].contains("rm -rf /tmp"));
crates/core/src/controls/privileged_operation_audit.rs
terraform_destroy_from_action_log Property
let b = EvidenceBundle {
agent_action_log: EvidenceState::complete(log_with(vec![action(
"terraform destroy -auto-approve",
)])),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/privileged_operation_audit.rs
safe_commands_satisfied Property
let b = EvidenceBundle {
agent_action_log: EvidenceState::complete(log_with(vec![
action("cargo build"),
action("git commit -m 'fix'"),
])),
privileged_git_events: EvidenceState::complete(vec![]),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/privileged_operation_audit.rs
custom_patterns_from_spec Property
let b = EvidenceBundle {
agent_action_log: EvidenceState::complete(log_with(vec![action(
"vault delete secret/prod",
)])),
agent_spec: EvidenceState::complete(AgentSpec {
custom_destructive_patterns: vec!["vault delete".to_string()],
..Default::default()
}),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/privileged_operation_audit.rs
git_events_and_action_log_combined Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::complete(vec![git_event(
"bot",
PrivilegedAction::ForcePush,
Some("main"),
None,
)]),
agent_action_log: EvidenceState::complete(log_with(vec![action("DROP TABLE users")])),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert_eq!(findings[0].subjects.len(), 2);
crates/core/src/controls/privileged_operation_audit.rs
both_missing_indeterminate Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "webhook".into(),
subject: "events".into(),
detail: "down".into(),
}]),
agent_action_log: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "monitor".into(),
subject: "log".into(),
detail: "down".into(),
}]),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 2);
crates/core/src/controls/privileged_operation_audit.rs
both_not_applicable Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::not_applicable(),
agent_action_log: EvidenceState::not_applicable(),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/privileged_operation_audit.rs
one_missing_one_present_still_evaluates Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::missing(vec![]),
agent_action_log: EvidenceState::complete(log_with(vec![action("rm -rf /")])),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/privileged_operation_audit.rs
case_insensitive_matching Property
let b = EvidenceBundle {
agent_action_log: EvidenceState::complete(log_with(vec![action("DROP TABLE users")])),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/privileged_operation_audit.rs
partial_evidence_notes_gaps Property
let b = EvidenceBundle {
privileged_git_events: EvidenceState::partial(
vec![],
vec![EvidenceGap::Truncated {
source: "webhook".into(),
subject: "events".into(),
}],
),
agent_action_log: EvidenceState::complete(log_with(vec![])),
..Default::default()
};
let findings = PrivilegedOperationAuditControl.evaluate(&b);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("partial evidence"));
crates/core/src/controls/privileged_operation_audit.rs
privileged-workflow-detection
Detects workflows using pull_request_target with elevated permissions, which is a known attack vector for CI/CD pipeline exploitation. Maps to SOC2 CC6.1 / CC7.1: access control and threat detection. A pull_request_target workflow runs in the context of the *base* branch with write access to secrets. If combined with actions/checkout of the PR head, an external contributor can exfiltrate secrets or inject code. Evaluation tiers: - Satisfied: no privileged workflow patterns detected - Violated: one or more workflows use dangerous pull_request_target patterns
Behavioral Specification 4 tests
Test Details
not_applicable_when_posture_not_applicable Property
let findings =
PrivilegedWorkflowDetectionControl.evaluate(&bundle(EvidenceState::not_applicable()));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/privileged_workflow_detection.rs
indeterminate_when_posture_missing Property
let findings =
PrivilegedWorkflowDetectionControl.evaluate(&bundle(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "posture".to_string(),
detail: "API error".to_string(),
},
])));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/privileged_workflow_detection.rs
satisfied_when_no_privileged_workflows Property
let findings = PrivilegedWorkflowDetectionControl
.evaluate(&bundle(EvidenceState::complete(posture(vec![]))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/privileged_workflow_detection.rs
violated_when_privileged_workflows_detected Property
let workflows = vec![
PrivilegedWorkflow {
file: ".github/workflows/ci.yml".to_string(),
trigger: "pull_request_target".to_string(),
risk: "checks out PR head with write access".to_string(),
},
PrivilegedWorkflow {
file: ".github/workflows/label.yml".to_string(),
trigger: "pull_request_target".to_string(),
risk: "runs untrusted code with secrets".to_string(),
},
];
let findings = PrivilegedWorkflowDetectionControl
.evaluate(&bundle(EvidenceState::complete(posture(workflows))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("2 workflow(s)"));
assert_eq!(findings[0].subjects.len(), 2);
assert!(findings[0].subjects[0].contains("ci.yml"));
assert!(findings[0].subjects[1].contains("label.yml"));
crates/core/src/controls/privileged_workflow_detection.rs
provenance-authenticity
Verifies that provenance attestations are cryptographically signed and authenticated with traceable signer information.
Formal Specification Creusot + SMT
fn provenance_authenticity_severity(unauthenticated_count: usize) -> Severity
Provenance authenticity severity (Build L2). Pass iff zero attestations lack cryptographic authentication.
#[ensures(unauthenticated_count == 0usize ==> result == Severity::Pass)]
#[ensures(unauthenticated_count >= 1usize ==> result == Severity::Error)]
Implementation
if unauthenticated_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 11 tests
Test Details
not_applicable_when_evidence_state_is_not_applicable Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::not_applicable(),
..Default::default()
};
let findings = ProvenanceAuthenticityControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
assert_eq!(
findings[0].control_id,
builtin::id(builtin::PROVENANCE_AUTHENTICITY)
);
crates/core/src/controls/provenance_authenticity.rs
not_applicable_when_attestation_list_empty Property
let findings = ProvenanceAuthenticityControl.evaluate(&make_bundle(vec![]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/provenance_authenticity.rs
indeterminate_when_evidence_missing Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "gh-attestation".to_string(),
subject: "binary".to_string(),
detail: "API returned 403".to_string(),
}]),
..Default::default()
};
let findings = ProvenanceAuthenticityControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/provenance_authenticity.rs
satisfied_when_all_verified_with_signer Property
let findings = ProvenanceAuthenticityControl.evaluate(&make_bundle(vec![
make_attestation("app:v1.0", true, Some(".github/workflows/release.yml")),
make_attestation("app:v1.1", true, Some(".github/workflows/ci.yml")),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects.len(), 2);
assert!(
findings[0]
.rationale
.contains("2 attestation(s) are verified")
);
crates/core/src/controls/provenance_authenticity.rs
satisfied_single_attestation Property
let findings =
ProvenanceAuthenticityControl.evaluate(&make_bundle(vec![make_attestation(
"binary",
true,
Some(".github/workflows/release.yml"),
)]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects, vec!["binary"]);
crates/core/src/controls/provenance_authenticity.rs
violated_when_attestation_not_verified Property
let findings = ProvenanceAuthenticityControl.evaluate(&make_bundle(vec![
make_attestation("app:v1.0", true, Some(".github/workflows/release.yml")),
make_attestation("app:v1.1", false, Some(".github/workflows/ci.yml")),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("app:v1.1"));
assert!(findings[0].rationale.contains("signature_invalid"));
crates/core/src/controls/provenance_authenticity.rs
violated_when_signer_workflow_missing Property
let findings = ProvenanceAuthenticityControl
.evaluate(&make_bundle(vec![make_attestation("app:v1.0", true, None)]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("app:v1.0"));
assert!(findings[0].rationale.contains("no signer info"));
crates/core/src/controls/provenance_authenticity.rs
violated_when_both_unverified_and_no_signer Property
let findings =
ProvenanceAuthenticityControl.evaluate(&make_bundle(vec![make_attestation(
"app:v1.0", false, None,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("signature_invalid"));
assert!(findings[0].rationale.contains("no signer info"));
crates/core/src/controls/provenance_authenticity.rs
partial_evidence_with_authenticated_attestations_satisfied Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::partial(
vec![make_attestation(
"partial-binary",
true,
Some(".github/workflows/release.yml"),
)],
vec![EvidenceGap::Truncated {
source: "gh-attestation".to_string(),
subject: "attestation-list".to_string(),
}],
),
..Default::default()
};
let findings = ProvenanceAuthenticityControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/provenance_authenticity.rs
partial_evidence_with_unauthenticated_attestation_violated Property
let evidence = EvidenceBundle {
artifact_attestations: EvidenceState::partial(
vec![make_attestation("partial-binary", false, None)],
vec![EvidenceGap::Truncated {
source: "gh-attestation".to_string(),
subject: "attestation-list".to_string(),
}],
),
..Default::default()
};
let findings = ProvenanceAuthenticityControl.evaluate(&evidence);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/provenance_authenticity.rs
correct_control_id Property
assert_eq!(
ProvenanceAuthenticityControl.id(),
builtin::id(builtin::PROVENANCE_AUTHENTICITY)
);
crates/core/src/controls/provenance_authenticity.rs
release-asset-attestation
Validates that the latest release assets have build provenance attestations (GitHub Attestations / Sigstore). Maps to SOC2 PI1.4: processing integrity through artifact provenance. Build provenance attestations bind release binaries to the source commit and CI workflow that produced them, enabling consumers to verify that artifacts were not tampered with after build. Evaluation tiers: - Satisfied: release assets have attestations - Violated: release assets exist but lack attestations - NotApplicable: no release exists
Behavioral Specification 4 tests
Test Details
not_applicable_when_posture_not_applicable Property
let findings =
ReleaseAssetAttestationControl.evaluate(&bundle(EvidenceState::not_applicable()));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/release_asset_attestation.rs
indeterminate_when_posture_missing Property
let findings =
ReleaseAssetAttestationControl.evaluate(&bundle(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "posture".to_string(),
detail: "API error".to_string(),
},
])));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/release_asset_attestation.rs
satisfied_when_attested Property
let findings = ReleaseAssetAttestationControl
.evaluate(&bundle(EvidenceState::complete(posture(true))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("attestations"));
crates/core/src/controls/release_asset_attestation.rs
violated_when_not_attested Property
let findings = ReleaseAssetAttestationControl
.evaluate(&bundle(EvidenceState::complete(posture(false))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("lack"));
crates/core/src/controls/release_asset_attestation.rs
release-traceability
Verifies that release promotion batches have linked change requests. Maps to SOC2 CC7.1: change traceability through the release pipeline. Every release should trace back to governed change requests (PRs) to maintain a complete audit trail from code change to production deployment.
Behavioral Specification 5 tests
Test Details
not_applicable_when_no_batches Property
let findings = ReleaseTraceabilityControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/release_traceability.rs
satisfied_when_crs_linked Property
let batch = make_batch(EvidenceState::complete(vec![
ChangeRequestId::new("test", "owner/repo#1"),
ChangeRequestId::new("test", "owner/repo#2"),
]));
let findings = ReleaseTraceabilityControl.evaluate(&bundle(vec![batch]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("2 change request(s)"));
crates/core/src/controls/release_traceability.rs
violated_when_no_crs_linked Property
let batch = make_batch(EvidenceState::complete(vec![]));
let findings = ReleaseTraceabilityControl.evaluate(&bundle(vec![batch]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("no linked change requests"));
crates/core/src/controls/release_traceability.rs
indeterminate_when_evidence_missing Property
let batch = make_batch(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "commits".to_string(),
detail: "API error".to_string(),
},
]));
let findings = ReleaseTraceabilityControl.evaluate(&bundle(vec![batch]));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/release_traceability.rs
not_applicable_when_crs_not_applicable Property
let batch = make_batch(EvidenceState::not_applicable());
let findings = ReleaseTraceabilityControl.evaluate(&bundle(vec![batch]));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/release_traceability.rs
required-status-checks
Verifies that CI check runs on the change request HEAD commit all passed.
Behavioral Specification 12 tests
Test Details
all_checks_success_is_satisfied Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![run(
"ci/build",
CheckConclusion::Success,
)]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert_eq!(findings[0].subjects, vec!["commit"]);
assert!(findings[0].rationale.contains("1 check run(s) passed"));
crates/core/src/controls/required_status_checks.rs
multiple_checks_all_pass_is_satisfied Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![
run("ci/build", CheckConclusion::Success),
run("ci/test", CheckConclusion::Success),
run("ci/lint", CheckConclusion::Neutral),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("3 check run(s) passed"));
crates/core/src/controls/required_status_checks.rs
skipped_check_is_satisfied Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![
run("ci/build", CheckConclusion::Success),
run("ci/optional", CheckConclusion::Skipped),
]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/required_status_checks.rs
one_check_failed_is_violated Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![
run("ci/build", CheckConclusion::Success),
run("ci/test", CheckConclusion::Failure),
]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("ci/test"));
crates/core/src/controls/required_status_checks.rs
cancelled_check_is_violated Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![run(
"ci/build",
CheckConclusion::Cancelled,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/required_status_checks.rs
timed_out_check_is_violated Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![run(
"ci/build",
CheckConclusion::TimedOut,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/required_status_checks.rs
pending_check_is_violated Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![run(
"ci/deploy",
CheckConclusion::Pending,
)]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/required_status_checks.rs
no_check_runs_is_indeterminate Property
let findings = RequiredStatusChecksControl.evaluate(&make_bundle(vec![]));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert!(findings[0].rationale.contains("No check runs found"));
crates/core/src/controls/required_status_checks.rs
indeterminate_when_evidence_missing Property
let bundle = EvidenceBundle {
check_runs: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "commit".to_string(),
detail: "403 Forbidden".to_string(),
}]),
..Default::default()
};
let findings = RequiredStatusChecksControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert_eq!(findings[0].evidence_gaps.len(), 1);
crates/core/src/controls/required_status_checks.rs
not_applicable_when_evidence_not_applicable Property
let bundle = EvidenceBundle {
check_runs: EvidenceState::not_applicable(),
..Default::default()
};
let findings = RequiredStatusChecksControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/required_status_checks.rs
partial_evidence_still_evaluates Property
let bundle = EvidenceBundle {
check_runs: EvidenceState::partial(
vec![run("ci/test", CheckConclusion::Success)],
vec![EvidenceGap::Truncated {
source: "github".to_string(),
subject: "check_runs".to_string(),
}],
),
..Default::default()
};
let findings = RequiredStatusChecksControl.evaluate(&bundle);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/required_status_checks.rs
control_id_is_required_status_checks Property
assert_eq!(
RequiredStatusChecksControl.id(),
builtin::id(builtin::REQUIRED_STATUS_CHECKS)
);
crates/core/src/controls/required_status_checks.rs
review-independence
Verifies that at least one approver is independent from the change author and requester.
Formal Specification Creusot + SMT
fn is_approver_independent(is_commit_author: bool, is_pr_author: bool) -> bool
Core predicate for the four-eyes principle (SLSA mutual approval). An approver is independent iff they are neither a commit author nor the PR author. Both conditions must hold (AND).
#[ensures(result == (!is_commit_author && !is_pr_author))]
Implementation
!is_commit_author && !is_pr_authorBehavioral Specification 3 tests
Test Details
independent_approval_is_satisfied Property
let finding = evaluate_change(&make_change());
assert_eq!(finding.status, crate::control::ControlStatus::Satisfied);
crates/core/src/controls/review_independence.rs
self_approval_is_violated Property
let mut change = make_change();
change.approval_decisions = EvidenceState::complete(vec![ApprovalDecision {
actor: "author".to_string(),
disposition: ApprovalDisposition::Approved,
submitted_at: None,
}]);
let finding = evaluate_change(&change);
assert_eq!(finding.status, crate::control::ControlStatus::Violated);
crates/core/src/controls/review_independence.rs
missing_authorship_is_indeterminate Property
let mut change = make_change();
change.source_revisions = EvidenceState::partial(
vec![SourceRevision {
id: "abc123".to_string(),
authored_by: None,
committed_at: Some("2026-03-14T00:00:00Z".to_string()),
merge: false,
authenticity: EvidenceState::not_applicable(),
}],
vec![EvidenceGap::Unsupported {
source: "github".to_string(),
capability: "author login unavailable for change request commit evidence"
.to_string(),
}],
);
let findings = ReviewIndependenceControl.evaluate(&EvidenceBundle {
change_requests: vec![change],
promotion_batches: vec![],
..Default::default()
});
assert_eq!(
findings[0].status,
crate::control::ControlStatus::Indeterminate
);
crates/core/src/controls/review_independence.rs
scoped-change
Verifies that change request changes are well-scoped (single logical unit).
Formal Specification Creusot + SMT
fn classify_scope(code_files_count: usize, components: usize) -> Severity
Scope classification. Exhaustive postconditions covering all input combinations. Precondition: union-find produces at most as many connected components as there are code files (each file starts as its own component).
#[ensures(code_files_count <= 1usize ==> result == Severity::Pass)]
#[ensures(code_files_count > 1usize && components <= 1usize ==> result == Severity::Pass)]
#[ensures(code_files_count > 1usize && components == 2usize ==> result == Severity::Warning)]
#[ensures(code_files_count > 1usize && components >= 3usize ==> result == Severity::Error)]
Implementation
if code_files_count <= 1 {
return Severity::Pass;
}
match components {
0 | 1 => Severity::Pass,
2 => Severity::Warning,
_ => Severity::Error,
}fn merge_commit_policy_severity(merge_count: usize) -> Severity
Merge commit policy severity (CC8.1). Pass iff zero merge commits are present in the change request.
#[ensures(merge_count == 0usize ==> result == Severity::Pass)]
#[ensures(merge_count >= 1usize ==> result == Severity::Error)]
Implementation
if merge_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 16 tests
| Scenario | Verdict | Key Assertion |
|---|---|---|
| empty graph | Pass | assert_eq!(uf.component_count(), 0); |
Test Details
empty_graph Pass
let mut uf = UnionFind::new();
assert_eq!(uf.component_count(), 0);
assert!(uf.is_empty());
crates/core/src/union_find.rs
single_node Property
let mut uf = UnionFind::new();
let a = uf.add_node(0, "main.rs", NodeKind::File);
assert_eq!(uf.find(a), a);
assert_eq!(uf.component_count(), 1);
crates/core/src/union_find.rs
deduplication Property
let mut uf = UnionFind::new();
let a = uf.add_node(0, "main.rs", NodeKind::File);
let b = uf.add_node(0, "main.rs", NodeKind::File);
assert_eq!(a, b);
assert_eq!(uf.len(), 1);
crates/core/src/union_find.rs
merge_reduces_components Property
let mut uf = UnionFind::new();
let a = uf.add_node(0, "a.rs", NodeKind::File);
let b = uf.add_node(1, "b.rs", NodeKind::File);
assert_eq!(uf.component_count(), 2);
uf.merge(a, b);
assert_eq!(uf.component_count(), 1);
assert_eq!(uf.find(a), uf.find(b));
crates/core/src/union_find.rs
find_is_idempotent Property
let mut uf = UnionFind::new();
let a = uf.add_node(0, "a.rs", NodeKind::File);
let b = uf.add_node(1, "b.rs", NodeKind::File);
uf.merge(a, b);
let root1 = uf.find(a);
let root2 = uf.find(root1);
assert_eq!(root1, root2);
crates/core/src/union_find.rs
merge_is_symmetric Property
let mut uf1 = UnionFind::new();
let a1 = uf1.add_node(0, "a.rs", NodeKind::File);
let b1 = uf1.add_node(1, "b.rs", NodeKind::File);
uf1.merge(a1, b1);
let mut uf2 = UnionFind::new();
let a2 = uf2.add_node(0, "a.rs", NodeKind::File);
let b2 = uf2.add_node(1, "b.rs", NodeKind::File);
uf2.merge(b2, a2);
// Both should have same component count
assert_eq!(uf1.component_count(), uf2.component_count());
assert_eq!(uf1.find(a1), uf1.find(b1));
assert_eq!(uf2.find(a2), uf2.find(b2));
crates/core/src/union_find.rs
merge_is_transitive Property
let mut uf = UnionFind::new();
let a = uf.add_node(0, "a.rs", NodeKind::File);
let b = uf.add_node(1, "b.rs", NodeKind::File);
let c_node = uf.add_node(2, "c.rs", NodeKind::File);
uf.merge(a, b);
uf.merge(b, c_node);
assert_eq!(uf.find(a), uf.find(c_node));
assert_eq!(uf.component_count(), 1);
crates/core/src/union_find.rs
function_nodes_dont_count_as_components Property
let mut uf = UnionFind::new();
let file_a = uf.add_node(0, "a.rs", NodeKind::File);
let _fn_a = uf.add_node(0, "foo", NodeKind::Function);
let file_b = uf.add_node(1, "b.rs", NodeKind::File);
// 2 file components (function node doesn't count)
assert_eq!(uf.component_count(), 2);
// Merging function with its file doesn't change file component count
uf.merge(file_a, _fn_a);
assert_eq!(uf.component_count(), 2);
// But merging files does
uf.merge(file_a, file_b);
assert_eq!(uf.component_count(), 1);
crates/core/src/union_find.rs
get_components_returns_grouped_indices Property
let mut uf = UnionFind::new();
let _a = uf.add_node(0, "a.rs", NodeKind::File);
let _b = uf.add_node(1, "b.rs", NodeKind::File);
let _c = uf.add_node(2, "c.rs", NodeKind::File);
uf.merge(_a, _b);
let mut components = uf.get_components();
components.sort_by_key(|c| c[0]);
assert_eq!(components.len(), 2);
// One group has {0, 1}, the other has {2}
let group_with_a = components.iter().find(|g| g.contains(&0)).unwrap();
assert!(group_with_a.contains(&1));
let group_with_c = components.iter().find(|g| g.contains(&2)).unwrap();
assert_eq!(group_with_c.len(), 1);
crates/core/src/union_find.rs
structural_invariant_maintained Property — Invariant: parent.len() == rank.len() == nodes.len()
let mut uf = UnionFind::new();
for i in 0..100 {
uf.add_node(i, &format!("file_{i}"), NodeKind::File);
assert_eq!(uf.nodes.len(), uf.parent.len());
assert_eq!(uf.nodes.len(), uf.rank.len());
}
// After merges, invariant still holds
for i in 0..99 {
uf.merge(i, i + 1);
assert_eq!(uf.nodes.len(), uf.parent.len());
assert_eq!(uf.nodes.len(), uf.rank.len());
}
crates/core/src/union_find.rs
parent_bounds_invariant Property — Invariant: parent[i] < parent.len() for all i
let mut uf = UnionFind::new();
for i in 0..50u16 {
uf.add_node(i, &format!("f{i}"), NodeKind::File);
}
// Random-ish merges
for i in (0..49).step_by(2) {
uf.merge(i, i + 1);
}
for i in (0..48).step_by(4) {
uf.merge(i, i + 2);
}
for (i, &p) in uf.parent.iter().enumerate() {
assert!(
(p as usize) < uf.parent.len(),
"parent[{i}] = {p} >= len {}",
uf.parent.len()
);
}
crates/core/src/union_find.rs
not_applicable_when_no_changes Property
let findings = ScopedChangeControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/scoped_change.rs
satisfied_for_single_file Property
let bundle = bundle_with(vec![asset("src/foo.rs")]);
let findings = ScopedChangeControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/scoped_change.rs
satisfied_for_connected_source_and_test Property
let bundle = bundle_with(vec![asset("src/foo.rs"), asset("tests/foo_test.rs")]);
let findings = ScopedChangeControl.evaluate(&bundle);
assert_eq!(
findings[0].status,
ControlStatus::Satisfied,
"source + test should be connected: {}",
findings[0].rationale
);
crates/core/src/controls/scoped_change.rs
violated_for_disconnected_files Property
let bundle = bundle_with(vec![
asset("src/auth/login.rs"),
asset("src/payment/checkout.rs"),
]);
let findings = ScopedChangeControl.evaluate(&bundle);
assert_eq!(
findings[0].status,
ControlStatus::Violated,
"disconnected domains should be violated: {}",
findings[0].rationale
);
crates/core/src/controls/scoped_change.rs
non_code_files_excluded Property
let bundle = bundle_with(vec![asset("src/auth/login.rs"), asset("README.md")]);
let findings = ScopedChangeControl.evaluate(&bundle);
// Only one code file after filtering → satisfied
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/scoped_change.rs
secret-scanning
Validates that secret scanning is enabled on the repository. Maps to SOC2 CC6.1 / CC6.6: protect credentials and prevent leakage. ASPM signal — secret scanning prevents accidental exposure of API keys, tokens, and other credentials in source code. Evaluation tiers: - Satisfied: scanning enabled AND push protection enabled (prevention) - Satisfied (with caveat): scanning enabled but push protection off (detection only) - Violated: scanning not enabled
Behavioral Specification 7 tests
Test Details
indeterminate_when_security_analysis_unavailable Property
let findings =
SecretScanningControl.evaluate(&bundle(EvidenceState::complete(RepositoryPosture {
security_analysis_available: false,
..Default::default()
})));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert!(findings[0].rationale.contains("permissions"));
crates/core/src/controls/secret_scanning.rs
not_applicable_when_posture_not_applicable Property
let findings = SecretScanningControl.evaluate(&bundle(EvidenceState::not_applicable()));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/secret_scanning.rs
indeterminate_when_posture_missing Property
let findings = SecretScanningControl.evaluate(&bundle(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "posture".to_string(),
detail: "API error".to_string(),
},
])));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/secret_scanning.rs
satisfied_when_enabled Property
let findings =
SecretScanningControl.evaluate(&bundle(EvidenceState::complete(posture(true))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/secret_scanning.rs
violated_when_disabled Property
let findings =
SecretScanningControl.evaluate(&bundle(EvidenceState::complete(posture(false))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("not enabled"));
crates/core/src/controls/secret_scanning.rs
satisfied_with_push_protection_has_prevention_tier Property
let mut p = posture(true);
p.secret_push_protection_enabled = true;
let findings = SecretScanningControl.evaluate(&bundle(EvidenceState::complete(p)));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("push protection"));
assert!(findings[0].subjects[0].contains("prevention"));
crates/core/src/controls/secret_scanning.rs
satisfied_detection_only_has_detection_tier Property
let findings =
SecretScanningControl.evaluate(&bundle(EvidenceState::complete(posture(true))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("detection only"));
assert!(findings[0].subjects[0].contains("detection"));
crates/core/src/controls/secret_scanning.rs
security-file-change
Detects changes to security-sensitive files that require heightened review. Maps to SOC2 CC7.2: monitoring for anomalies in change governance. Changes to CI configs, access control, lock files, and infrastructure definitions have outsized blast radius and should be flagged for scrutiny.
Behavioral Specification 8 tests
Test Details
not_applicable_when_no_changes Property
let findings = SecurityFileChangeControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/security_file_change.rs
satisfied_when_no_sensitive_files Property
let cr = make_change(EvidenceState::complete(vec![
asset("src/main.rs"),
asset("src/lib.rs"),
]));
let findings = SecurityFileChangeControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/security_file_change.rs
violated_when_workflow_changed Property
let cr = make_change(EvidenceState::complete(vec![
asset("src/main.rs"),
asset(".github/workflows/ci.yml"),
]));
let findings = SecurityFileChangeControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("ci.yml"));
crates/core/src/controls/security_file_change.rs
violated_when_codeowners_changed Property
let cr = make_change(EvidenceState::complete(vec![asset("CODEOWNERS")]));
let findings = SecurityFileChangeControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/security_file_change.rs
violated_when_lockfile_changed Property
let cr = make_change(EvidenceState::complete(vec![asset("Cargo.lock")]));
let findings = SecurityFileChangeControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/security_file_change.rs
violated_when_dockerfile_changed Property
let cr = make_change(EvidenceState::complete(vec![asset("Dockerfile")]));
let findings = SecurityFileChangeControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/security_file_change.rs
indeterminate_when_assets_missing Property
let cr = make_change(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "files".to_string(),
detail: "API error".to_string(),
},
]));
let findings = SecurityFileChangeControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/security_file_change.rs
multiple_sensitive_files_all_reported Property
let cr = make_change(EvidenceState::complete(vec![
asset(".github/workflows/release.yml"),
asset("CODEOWNERS"),
asset("Cargo.lock"),
]));
let findings = SecurityFileChangeControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert_eq!(findings[0].subjects.len(), 3);
crates/core/src/controls/security_file_change.rs
security-policy
Validates that a security policy (SECURITY.md) exists with a responsible disclosure process. Maps to SOC2 CC7.3 / CC7.4: incident response communication. ASPM signal — a published security policy enables external reporters to disclose vulnerabilities responsibly, reducing exposure window. Note: In enterprise settings (SOC2 preset), this control's violations are treated as "review" rather than "fail" because enterprises typically maintain disclosure processes in internal portals, not repo-level files. In OSS (OSS preset), this is strict — SECURITY.md is the primary channel.
Behavioral Specification 5 tests
Test Details
not_applicable_when_posture_not_applicable Property
let findings = SecurityPolicyControl.evaluate(&bundle(EvidenceState::not_applicable()));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/security_policy.rs
indeterminate_when_posture_missing Property
let findings = SecurityPolicyControl.evaluate(&bundle(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "posture".to_string(),
detail: "API error".to_string(),
},
])));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/security_policy.rs
violated_when_no_policy Property
let findings =
SecurityPolicyControl.evaluate(&bundle(EvidenceState::complete(posture(false, false))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("No SECURITY.md"));
crates/core/src/controls/security_policy.rs
violated_when_policy_without_disclosure Property
let findings =
SecurityPolicyControl.evaluate(&bundle(EvidenceState::complete(posture(true, false))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(
findings[0]
.rationale
.contains("lacks a responsible disclosure")
);
crates/core/src/controls/security_policy.rs
satisfied_when_policy_with_disclosure Property
let findings =
SecurityPolicyControl.evaluate(&bundle(EvidenceState::complete(posture(true, true))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/security_policy.rs
security-test-in-ci
Validates that security testing (SAST/DAST) is integrated into CI. Maps to UN-R155 Clause 7.2.2.2 (Security testing throughout lifecycle), NIST 800-53 SA-11 (Developer Testing and Evaluation). Uses code_scanning_enabled as evidence — this is true when CodeQL or other SAST tools have produced at least one analysis result, indicating active security testing in the CI pipeline.
Behavioral Specification 4 tests
Test Details
satisfied_when_code_scanning_enabled Property
let findings = SecurityTestInCiControl.evaluate(&bundle_with(true, true));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/security_test_in_ci.rs
violated_when_no_code_scanning Property
let findings = SecurityTestInCiControl.evaluate(&bundle_with(true, false));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("No security testing"));
crates/core/src/controls/security_test_in_ci.rs
indeterminate_when_api_unavailable Property
let findings = SecurityTestInCiControl.evaluate(&bundle_with(false, false));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/security_test_in_ci.rs
indeterminate_when_posture_missing Property
let findings = SecurityTestInCiControl.evaluate(&EvidenceBundle {
repository_posture: EvidenceState::missing(vec![]),
..Default::default()
});
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/security_test_in_ci.rs
source-authenticity
Verifies that all source revisions carry valid cryptographic signatures.
Formal Specification Creusot + SMT
fn signature_severity(unsigned_count: usize) -> Severity
Signature check severity. Pass iff zero unsigned commits; Error otherwise.
#[ensures(unsigned_count == 0usize ==> result == Severity::Pass)]
#[ensures(unsigned_count > 0usize ==> result == Severity::Error)]
Implementation
if unsigned_count == 0 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 3 tests
Test Details
verified_revisions_are_satisfied Property
let findings = SourceAuthenticityControl.evaluate(&EvidenceBundle {
change_requests: vec![make_change(true)],
promotion_batches: vec![],
..Default::default()
});
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/source_authenticity.rs
unsigned_revisions_are_violated Property
let findings = SourceAuthenticityControl.evaluate(&EvidenceBundle {
change_requests: vec![make_change(false)],
promotion_batches: vec![],
..Default::default()
});
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/source_authenticity.rs
missing_authenticity_is_indeterminate Property
let mut change = make_change(true);
change.source_revisions = EvidenceState::complete(vec![SourceRevision {
id: "deadbeef".to_string(),
authored_by: Some("author".to_string()),
committed_at: Some("2026-03-15T00:00:00Z".to_string()),
merge: false,
authenticity: EvidenceState::not_applicable(),
}]);
let findings = SourceAuthenticityControl.evaluate(&EvidenceBundle {
change_requests: vec![change],
promotion_batches: vec![],
..Default::default()
});
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/source_authenticity.rs
stale-review
Detects approval decisions that predate the latest non-merge source revision. Maps to SOC2 CC7.2: monitoring for anomalies in change governance. A review approved before subsequent code changes is stale and may not reflect the final state of the change request.
Behavioral Specification 13 tests
Test Details
not_applicable_when_no_changes Property
let findings = StaleReviewControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/stale_review.rs
satisfied_when_approval_postdates_latest_commit Property
let cr = make_change(
EvidenceState::complete(vec![approval("reviewer", "2026-03-15T12:00:00Z")]),
EvidenceState::complete(vec![revision("abc", "2026-03-15T10:00:00Z", false)]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/stale_review.rs
violated_when_approval_predates_latest_commit Property
let cr = make_change(
EvidenceState::complete(vec![approval("reviewer", "2026-03-15T10:00:00Z")]),
EvidenceState::complete(vec![revision("abc", "2026-03-15T12:00:00Z", false)]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("reviewer"));
crates/core/src/controls/stale_review.rs
ignores_merge_commits_for_latest_timestamp Property
let cr = make_change(
EvidenceState::complete(vec![approval("reviewer", "2026-03-15T11:00:00Z")]),
EvidenceState::complete(vec![
revision("abc", "2026-03-15T10:00:00Z", false),
revision("merge", "2026-03-15T14:00:00Z", true),
]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/stale_review.rs
indeterminate_when_approvals_missing Property
let cr = make_change(
EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "reviews".to_string(),
detail: "API error".to_string(),
}]),
EvidenceState::complete(vec![revision("abc", "2026-03-15T10:00:00Z", false)]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/stale_review.rs
not_applicable_when_no_approvals Property
let cr = make_change(
EvidenceState::complete(vec![]),
EvidenceState::complete(vec![revision("abc", "2026-03-15T10:00:00Z", false)]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/stale_review.rs
ignores_bot_commits_for_latest_timestamp Property
// bors rebases after approval — the bot commit should not invalidate the review
let mut bot_rev = revision("bot-abc", "2026-03-15T14:00:00Z", false);
bot_rev.authored_by = Some("bors".to_string());
let cr = make_change(
EvidenceState::complete(vec![approval("reviewer", "2026-03-15T11:00:00Z")]),
EvidenceState::complete(vec![
revision("abc", "2026-03-15T10:00:00Z", false),
bot_rev,
]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/stale_review.rs
ignores_github_app_bot_commits Property
let mut bot_rev = revision("bot-abc", "2026-03-15T14:00:00Z", false);
bot_rev.authored_by = Some("dependabot[bot]".to_string());
let cr = make_change(
EvidenceState::complete(vec![approval("reviewer", "2026-03-15T11:00:00Z")]),
EvidenceState::complete(vec![
revision("abc", "2026-03-15T10:00:00Z", false),
bot_rev,
]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/stale_review.rs
bot_author_detection Property
assert!(is_bot_author(Some("bors")));
assert!(is_bot_author(Some("Bors")));
assert!(is_bot_author(Some("k8s-ci-robot")));
assert!(is_bot_author(Some("dependabot[bot]")));
assert!(is_bot_author(Some("custom-app[bot]")));
assert!(!is_bot_author(Some("developer")));
assert!(!is_bot_author(None));
crates/core/src/controls/stale_review.rs
timezone_aware_comparison_utc_vs_offset Property
// Approval at 02:54 UTC, commit at 10:34+08:00 = 02:34 UTC
// Approval is AFTER commit → not stale
assert!(!ts_is_before(
"2026-03-24T02:54:37Z",
"2026-03-24T10:34:00+08:00"
));
// Reverse: commit at 02:34 UTC is before approval at 02:54 UTC
assert!(ts_is_before(
"2026-03-24T10:34:00+08:00",
"2026-03-24T02:54:37Z"
));
crates/core/src/controls/stale_review.rs
timezone_aware_same_tz Property
assert!(ts_is_before("2026-03-15T10:00:00Z", "2026-03-15T12:00:00Z"));
assert!(!ts_is_before(
"2026-03-15T12:00:00Z",
"2026-03-15T10:00:00Z"
));
crates/core/src/controls/stale_review.rs
timezone_aware_negative_offset Property
// 10:00-05:00 = 15:00 UTC, which is after 14:00 UTC
assert!(!ts_is_before(
"2026-03-15T10:00:00-05:00",
"2026-03-15T14:00:00Z"
));
assert!(ts_is_before(
"2026-03-15T14:00:00Z",
"2026-03-15T10:00:00-05:00"
));
crates/core/src/controls/stale_review.rs
satisfied_when_approval_after_offset_commit Property
// Real k8s scenario: approval at 02:54 UTC, commit at 10:34+08:00 (=02:34 UTC)
let cr = make_change(
EvidenceState::complete(vec![approval("reviewer", "2026-03-24T02:54:37Z")]),
EvidenceState::complete(vec![revision("abc", "2026-03-24T10:34:00+08:00", false)]),
);
let findings = StaleReviewControl.evaluate(&bundle(vec![cr]));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/stale_review.rs
test-coverage
Verifies that source file changes include corresponding test updates.
Behavioral Specification 12 tests
| Scenario | Verdict | Key Assertion |
|---|---|---|
| has test coverage passes when pair exists | Pass | assert!(uncovered.is_empty()); |
| semantic fallback matches named test | Pass | assert!(uncovered.is_empty()); |
Test Details
find_test_pair_for_src_file Property
let pairs = find_test_pair("src/foo.rs");
assert!(pairs.contains(&"tests/foo_test.rs".to_string()));
assert!(pairs.contains(&"src/foo_test.rs".to_string()));
assert!(pairs.contains(&"tests/test_foo.rs".to_string()));
assert!(pairs.contains(&"src/tests/foo.rs".to_string()));
crates/core/src/test_coverage.rs
find_test_pair_for_nested_workspace_source Property
let pairs = find_test_pair("crates/core/src/scope.rs");
assert!(pairs.contains(&"crates/core/tests/scope_test.rs".to_string()));
assert!(pairs.contains(&"crates/core/src/scope_test.rs".to_string()));
assert!(pairs.contains(&"crates/core/tests/test_scope.rs".to_string()));
assert!(pairs.contains(&"crates/core/src/tests/scope.rs".to_string()));
crates/core/src/test_coverage.rs
has_test_coverage_passes_when_pair_exists Pass
let sources = vec!["src/foo.rs"];
let tests = vec!["tests/foo_test.rs"];
let uncovered = has_test_coverage(&sources, &tests);
assert!(uncovered.is_empty());
crates/core/src/test_coverage.rs
has_test_coverage_warns_missing_source_pair Property
let sources = vec!["src/foo.rs", "src/bar.rs"];
let tests = vec!["tests/foo_test.rs"];
let uncovered = has_test_coverage(&sources, &tests);
assert_eq!(uncovered.len(), 1);
assert_eq!(uncovered[0].source_path, "src/bar.rs");
crates/core/src/test_coverage.rs
semantic_fallback_matches_named_test Pass
let sources = vec!["packages/runtime-core/src/apiDefineComponent.ts"];
let tests = vec!["packages/runtime-core/__tests__/apiDefineComponent.spec.ts"];
let uncovered = has_test_coverage(&sources, &tests);
assert!(uncovered.is_empty());
crates/core/src/test_coverage.rs
semantic_fallback_rejects_generic_test_name Property
let sources = vec!["src/auth.rs"];
let tests = vec!["tests/index_test.rs"];
let uncovered = has_test_coverage(&sources, &tests);
assert_eq!(uncovered.len(), 1);
crates/core/src/test_coverage.rs
not_applicable_when_no_changes Property
let findings = TestCoverageControl.evaluate(&EvidenceBundle::default());
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/test_coverage.rs
satisfied_when_test_pair_exists Property
let bundle = bundle_with(vec![asset("src/foo.rs"), asset("tests/foo_test.rs")]);
let findings = TestCoverageControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/test_coverage.rs
violated_when_source_has_no_test Property
let bundle = bundle_with(vec![asset("src/bar.rs")]);
let findings = TestCoverageControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].subjects.contains(&"src/bar.rs".to_string()));
crates/core/src/controls/test_coverage.rs
satisfied_for_test_only_pr Property
let bundle = bundle_with(vec![asset("tests/foo_test.rs")]);
let findings = TestCoverageControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/test_coverage.rs
satisfied_for_non_code_only_pr Property
let bundle = bundle_with(vec![asset("README.md"), asset("docs/guide.md")]);
let findings = TestCoverageControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/test_coverage.rs
indeterminate_when_evidence_missing Property
let bundle = EvidenceBundle {
change_requests: vec![GovernedChange {
id: ChangeRequestId::new("test", "owner/repo#1"),
title: "test".to_string(),
summary: None,
submitted_by: None,
changed_assets: EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "files".to_string(),
detail: "API error".to_string(),
}]),
approval_decisions: EvidenceState::not_applicable(),
source_revisions: EvidenceState::not_applicable(),
work_item_refs: EvidenceState::not_applicable(),
}],
..Default::default()
};
let findings = TestCoverageControl.evaluate(&bundle);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/test_coverage.rs
two-party-review
Source L4: Verifies that at least two independent reviewers approved each change.
Formal Specification Creusot + SMT
fn two_party_review_severity(independent_count: usize) -> Severity
Two-party review severity (Source L4). Pass iff at least 2 independent reviewers approved.
#[ensures(independent_count >= 2usize ==> result == Severity::Pass)]
#[ensures(independent_count < 2usize ==> result == Severity::Error)]
Implementation
if independent_count >= 2 {
Severity::Pass
} else {
Severity::Error
}Behavioral Specification 10 tests
Test Details
satisfied_with_two_independent_approvers Property
let change = make_change(vec!["reviewer-a", "reviewer-b"]);
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("2"));
crates/core/src/controls/two_party_review.rs
violated_with_only_one_independent_approver Property
let change = make_change(vec!["reviewer-a"]);
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("1"));
crates/core/src/controls/two_party_review.rs
violated_when_self_approval_reduces_count Property
// author + one independent = only 1 independent
let change = make_change(vec!["author", "reviewer-a"]);
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
crates/core/src/controls/two_party_review.rs
not_applicable_when_no_changes Property
let evidence = EvidenceBundle::default();
let findings = TwoPartyReviewControl.evaluate(&evidence);
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/two_party_review.rs
indeterminate_when_approvals_missing Property
let mut change = make_change(vec![]);
change.approval_decisions = EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "reviews".to_string(),
detail: "API error".to_string(),
}]);
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/two_party_review.rs
indeterminate_when_revisions_missing Property
let mut change = make_change(vec!["reviewer-a", "reviewer-b"]);
change.source_revisions = EvidenceState::missing(vec![EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "commits".to_string(),
detail: "API error".to_string(),
}]);
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/two_party_review.rs
satisfied_with_three_independent_approvers Property
let change = make_change(vec!["reviewer-a", "reviewer-b", "reviewer-c"]);
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("3"));
crates/core/src/controls/two_party_review.rs
violated_when_zero_approvals Property
let change = make_change(vec![]);
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("0"));
crates/core/src/controls/two_party_review.rs
indeterminate_when_submitted_by_missing Property
let mut change = make_change(vec!["reviewer-a", "reviewer-b"]);
change.submitted_by = None;
let findings = TwoPartyReviewControl.evaluate(&bundle(change));
assert_eq!(findings.len(), 1);
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/two_party_review.rs
correct_control_id Property
assert_eq!(
TwoPartyReviewControl.id(),
builtin::id(builtin::TWO_PARTY_REVIEW)
);
crates/core/src/controls/two_party_review.rs
vulnerability-scanning
Validates that dependency vulnerability scanning is enabled on the repository. Maps to SOC2 CC7.1: detect vulnerabilities in third-party components. ASPM signal — continuous vulnerability scanning ensures known CVEs in dependencies are flagged before they reach production. Evaluates both dependency scanning (SCA) and code scanning (SAST) when available.
Behavioral Specification 7 tests
Test Details
indeterminate_when_security_analysis_unavailable Property
let findings = VulnerabilityScanningControl.evaluate(&bundle(EvidenceState::complete(
RepositoryPosture {
security_analysis_available: false,
..Default::default()
},
)));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
assert!(findings[0].rationale.contains("permissions"));
crates/core/src/controls/vulnerability_scanning.rs
not_applicable_when_posture_not_applicable Property
let findings =
VulnerabilityScanningControl.evaluate(&bundle(EvidenceState::not_applicable()));
assert_eq!(findings[0].status, ControlStatus::NotApplicable);
crates/core/src/controls/vulnerability_scanning.rs
indeterminate_when_posture_missing Property
let findings =
VulnerabilityScanningControl.evaluate(&bundle(EvidenceState::missing(vec![
EvidenceGap::CollectionFailed {
source: "github".to_string(),
subject: "posture".to_string(),
detail: "API error".to_string(),
},
])));
assert_eq!(findings[0].status, ControlStatus::Indeterminate);
crates/core/src/controls/vulnerability_scanning.rs
satisfied_when_enabled Property
let findings =
VulnerabilityScanningControl.evaluate(&bundle(EvidenceState::complete(posture(true))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
crates/core/src/controls/vulnerability_scanning.rs
violated_when_disabled Property
let findings =
VulnerabilityScanningControl.evaluate(&bundle(EvidenceState::complete(posture(false))));
assert_eq!(findings[0].status, ControlStatus::Violated);
assert!(findings[0].rationale.contains("not enabled"));
crates/core/src/controls/vulnerability_scanning.rs
satisfied_with_code_scanning_has_sast_tier Property
let mut p = posture(true);
p.code_scanning_enabled = true;
let findings = VulnerabilityScanningControl.evaluate(&bundle(EvidenceState::complete(p)));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(findings[0].rationale.contains("code scanning"));
assert!(findings[0].subjects[0].contains("sca+sast"));
crates/core/src/controls/vulnerability_scanning.rs
satisfied_sca_only_has_sca_tier Property
let findings =
VulnerabilityScanningControl.evaluate(&bundle(EvidenceState::complete(posture(true))));
assert_eq!(findings[0].status, ControlStatus::Satisfied);
assert!(
findings[0]
.rationale
.contains("consider enabling code scanning")
);
assert!(findings[0].subjects[0].contains("sca-only"));
crates/core/src/controls/vulnerability_scanning.rs