mirror of
https://github.com/instructkr/claw-code.git
synced 2026-05-18 13:31:28 +08:00
require provenance for green contracts
Promote merge-ready green contracts from a level-only check to explicit provenance requirements for test commands, base freshness, recovery-attempt context, and known blocking flakes. This preserves simple level contracts while giving policy code a single satisfied-contract signal to require before merge decisions.\n\nConstraint: Task scope was limited to green_contract.rs, policy_engine.rs if needed, and narrow tests; stale_* and recovery_recipes.rs were not edited.\nRejected: Adding more boolean fields to GreenContract | clippy flagged the shape and a requirement list is more explicit.\nConfidence: high\nScope-risk: narrow\nDirective: Treat raw test level as insufficient for merge readiness unless green contract evidence is satisfied.\nTested: cargo check --manifest-path rust/Cargo.toml -p runtime; cargo test --manifest-path rust/Cargo.toml -p runtime; cargo clippy --manifest-path rust/Cargo.toml -p runtime -- -D warnings; focused green_contract, policy_engine, and integration tests.\nNot-tested: full workspace cargo test due pre-existing rusty-claude-cli session_lifecycle_prefers_running_process_over_idle_shell failure observed before this slice.
This commit is contained in:
@@ -27,12 +27,10 @@ impl std::fmt::Display for GreenLevel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct GreenContract {
|
pub struct GreenContract {
|
||||||
pub required_level: GreenLevel,
|
pub required_level: GreenLevel,
|
||||||
pub require_test_command_provenance: bool,
|
pub requirements: Vec<GreenContractRequirement>,
|
||||||
pub require_base_branch_freshness: bool,
|
|
||||||
pub require_recovery_attempt_context: bool,
|
|
||||||
pub block_known_flakes: bool,
|
pub block_known_flakes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,9 +39,7 @@ impl GreenContract {
|
|||||||
pub fn new(required_level: GreenLevel) -> Self {
|
pub fn new(required_level: GreenLevel) -> Self {
|
||||||
Self {
|
Self {
|
||||||
required_level,
|
required_level,
|
||||||
require_test_command_provenance: false,
|
requirements: Vec::new(),
|
||||||
require_base_branch_freshness: false,
|
|
||||||
require_recovery_attempt_context: false,
|
|
||||||
block_known_flakes: false,
|
block_known_flakes: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,15 +48,17 @@ impl GreenContract {
|
|||||||
pub fn merge_ready(required_level: GreenLevel) -> Self {
|
pub fn merge_ready(required_level: GreenLevel) -> Self {
|
||||||
Self {
|
Self {
|
||||||
required_level,
|
required_level,
|
||||||
require_test_command_provenance: true,
|
requirements: vec![
|
||||||
require_base_branch_freshness: true,
|
GreenContractRequirement::TestCommandProvenance,
|
||||||
require_recovery_attempt_context: true,
|
GreenContractRequirement::BaseBranchFreshness,
|
||||||
|
GreenContractRequirement::RecoveryAttemptContext,
|
||||||
|
],
|
||||||
block_known_flakes: true,
|
block_known_flakes: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn evaluate(self, observed_level: Option<GreenLevel>) -> GreenContractOutcome {
|
pub fn evaluate(&self, observed_level: Option<GreenLevel>) -> GreenContractOutcome {
|
||||||
match observed_level {
|
match observed_level {
|
||||||
Some(level) if level >= self.required_level => GreenContractOutcome::Satisfied {
|
Some(level) if level >= self.required_level => GreenContractOutcome::Satisfied {
|
||||||
required_level: self.required_level,
|
required_level: self.required_level,
|
||||||
@@ -82,16 +80,23 @@ impl GreenContract {
|
|||||||
missing.push(GreenContractRequirement::RequiredLevel);
|
missing.push(GreenContractRequirement::RequiredLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.require_test_command_provenance && !evidence.has_passing_test_command() {
|
for requirement in &self.requirements {
|
||||||
missing.push(GreenContractRequirement::TestCommandProvenance);
|
match requirement {
|
||||||
}
|
GreenContractRequirement::TestCommandProvenance
|
||||||
|
if !evidence.has_passing_test_command() =>
|
||||||
if self.require_base_branch_freshness && !evidence.base_branch_fresh {
|
{
|
||||||
missing.push(GreenContractRequirement::BaseBranchFreshness);
|
missing.push(*requirement);
|
||||||
}
|
}
|
||||||
|
GreenContractRequirement::BaseBranchFreshness if !evidence.base_branch_fresh => {
|
||||||
if self.require_recovery_attempt_context && !evidence.recovery_attempt_context_recorded {
|
missing.push(*requirement);
|
||||||
missing.push(GreenContractRequirement::RecoveryAttemptContext);
|
}
|
||||||
|
GreenContractRequirement::RecoveryAttemptContext
|
||||||
|
if !evidence.recovery_attempt_context_recorded =>
|
||||||
|
{
|
||||||
|
missing.push(*requirement);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.block_known_flakes {
|
if self.block_known_flakes {
|
||||||
@@ -119,7 +124,7 @@ impl GreenContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_satisfied_by(self, observed_level: GreenLevel) -> bool {
|
pub fn is_satisfied_by(&self, observed_level: GreenLevel) -> bool {
|
||||||
observed_level >= self.required_level
|
observed_level >= self.required_level
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user