Pin the three Cut 6c rules Soul's mutations survived
Soul's own suite found three validator rules no test measured: a fix's
commit was unpinned once `by` was `Some`, the validator's own bound on a
supersession was unpinned (only the schema's `maxItems` was), and the
reason on `Recorded` and `Withdrawn` had no bound test. Each is now a
forgery in the test that owns the arm: `Fixed { commit: "dirty-worktree",
by: Some(ruling) }` refused at `resolution.outcome.commit`; nine
supersessors refused as `FieldBound` at `resolution.outcome.by`, eight
accepted; a 1,001-byte reason refused at `resolution.outcome.reason` on
both outcomes.
Soul's S2, S14 and S10 join the Cut 6c suite under their own ids. Rerun:
M0 green (26 passed); M16-M22, S2, S14, S10 killed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
fc7ad7457a
commit
fcfbda3f94
2 changed files with 58 additions and 4 deletions
|
|
@ -1645,6 +1645,30 @@ mod tests {
|
|||
assert_eq!(resolved(finding.clone(), fixed(Some(ruling("R8")))), Ok(()));
|
||||
let forged = PipelineRef { kind: PipelineKind::Finding, id: id("ruling", "R8") };
|
||||
refused("resolution.outcome.by.id", resolved(finding, fixed(Some(forged))));
|
||||
|
||||
// Soul F2: the validator's bound on a supersession is its own, not
|
||||
// only the schema's. Eight referents are the most a subject names;
|
||||
// nine are refused as a count before any item is read.
|
||||
let rulings = |count: usize| (1..=count).map(|n| ruling(&format!("R{n}"))).collect::<Vec<_>>();
|
||||
assert_eq!(resolved(ruling("R8"), ResolutionOutcome::Superseded { by: rulings(8) }), Ok(()));
|
||||
assert_eq!(
|
||||
resolved(ruling("R8"), ResolutionOutcome::Superseded { by: rulings(9) }),
|
||||
Err(PipelineRefusal::FieldBound { field: "resolution.outcome.by".into(), limit: 8, actual: 9 })
|
||||
);
|
||||
|
||||
// Soul F3: the two reason-carrying outcomes are bounded like every
|
||||
// `Line`; the shared arm is pinned on both so neither can drop out.
|
||||
let wide = Line("a".repeat(1001));
|
||||
for outcome in [
|
||||
ResolutionOutcome::Recorded { reason: wide.clone() },
|
||||
ResolutionOutcome::Withdrawn { reason: wide },
|
||||
] {
|
||||
let finding = PipelineRef { kind: PipelineKind::Finding, id: id("finding", "cut-3a.s2.F4") };
|
||||
assert_eq!(
|
||||
resolved(finding, outcome),
|
||||
Err(PipelineRefusal::FieldBound { field: "resolution.outcome.reason".into(), limit: 1000, actual: 1001 })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ruling B: a fix names the tree where the finding stopped being true,
|
||||
|
|
@ -1652,20 +1676,27 @@ mod tests {
|
|||
/// check passes and `hex` refuses.
|
||||
#[test]
|
||||
fn fixed_resolution_requires_a_commit_sha() {
|
||||
let fixed = |commit: &str| {
|
||||
let fixed = |commit: &str, by: Option<PipelineRef>| {
|
||||
let mut resolution = resolution_sample();
|
||||
resolution.subject = PipelineRef { kind: PipelineKind::Finding, id: id("finding", "cut-3a.s2.F4") };
|
||||
resolution.outcome = ResolutionOutcome::Fixed { commit: Sha(commit.into()), by: None };
|
||||
resolution.outcome = ResolutionOutcome::Fixed { commit: Sha(commit.into()), by };
|
||||
PipelineDocument::Resolution(resolution).validate()
|
||||
};
|
||||
assert_eq!(fixed("5f98228d9c"), Ok(()));
|
||||
assert_eq!(fixed("5f98228d9c", None), Ok(()));
|
||||
for forged in ["5F98228D9C", "5f9822", "dirty-worktree", ""] {
|
||||
assert_eq!(
|
||||
fixed(forged),
|
||||
fixed(forged, None),
|
||||
Err(PipelineRefusal::InvalidFormat { field: "resolution.outcome.commit".into(), value: forged.into() }),
|
||||
"{forged:?} is not a commit"
|
||||
);
|
||||
}
|
||||
// Soul F1: naming the record that fixed it does not excuse the commit.
|
||||
let ruling = PipelineRef { kind: PipelineKind::Ruling, id: id("ruling", "R8") };
|
||||
assert_eq!(
|
||||
fixed("dirty-worktree", Some(ruling)),
|
||||
Err(PipelineRefusal::InvalidFormat { field: "resolution.outcome.commit".into(), value: "dirty-worktree".into() }),
|
||||
"a fix with a named record still names a commit"
|
||||
);
|
||||
}
|
||||
|
||||
/// A mutation record has a key-safe identity a verdict claim can name,
|
||||
|
|
|
|||
|
|
@ -84,6 +84,29 @@
|
|||
Test = 'tests::a_verdict_claim_names_the_promise_and_the_mutation_it_measured'
|
||||
Old = 'mutations: Vec<Label>[8]'
|
||||
New = 'mutations: Vec<Label>[16]'
|
||||
},
|
||||
# Soul's Cut 6c pass: three rules that survived, each now pinned by a
|
||||
# forgery the fix batch added. The ids are Soul's.
|
||||
@{
|
||||
Id = 'S2'
|
||||
Rule = 'A fix''s commit is validated whether or not a record is named: Fixed { by: Some(..) } does not excuse the sha.'
|
||||
Test = 'tests::fixed_resolution_requires_a_commit_sha'
|
||||
Old = ' commit.validate(&format!("{field}.commit"))?;'
|
||||
New = ' if by.is_none() { commit.validate(&format!("{field}.commit"))?; }'
|
||||
},
|
||||
@{
|
||||
Id = 'S14'
|
||||
Rule = 'The validator bounds a supersession at eight itself; the schema''s maxItems is not the only bound.'
|
||||
Test = 'tests::resolution_outcome_referents_are_parsed_ids_of_their_kind'
|
||||
Old = ' Self::Superseded { by } => list(&format!("{field}.by"), by, 8),'
|
||||
New = ' Self::Superseded { by } => list(&format!("{field}.by"), by, 9),'
|
||||
},
|
||||
@{
|
||||
Id = 'S10'
|
||||
Rule = 'A Recorded or Withdrawn reason is bounded as a Line.'
|
||||
Test = 'tests::resolution_outcome_referents_are_parsed_ids_of_their_kind'
|
||||
Old = ' Self::Recorded { reason } | Self::Withdrawn { reason } => reason.validate(&format!("{field}.reason")),'
|
||||
New = ' Self::Recorded { reason } | Self::Withdrawn { reason } => { let _ = reason; Ok(()) }'
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue