diff --git a/tools/eureka-cut10-epiphany-mutations.psd1 b/tools/eureka-cut10-epiphany-mutations.psd1 deleted file mode 100644 index 6cbef6b6..00000000 --- a/tools/eureka-cut10-epiphany-mutations.psd1 +++ /dev/null @@ -1,69 +0,0 @@ -# Eureka Cut 10 mutation suite, the Epiphany half: the public slug door, -# `Slug::validate_slug`, filled into its owner by Self's ruling on the F6 -# fork. Entries only; the harness moved out of this repo, 2026-09-17, to -# `C:\Users\Meta\.claude\skills\eureka\tools\eureka-mutations.ps1` -# (`GameCult/Eureka`), so one copy serves every campaign. It takes `-Repo` -# when run from outside that checkout. -# -# powershell -File C:\Users\Meta\.claude\skills\eureka\tools\eureka-mutations.ps1 ` -# -Repo F:\Projects\Epiphany ` -# -Entries tools/eureka-cut10-epiphany-mutations.psd1 ` -# -Target epiphany-pipeline/src/lib.rs ` -# -Test 'cargo test -p epiphany-pipeline --lib' -# -# G1 is the revert: the door answers `Ok` to everything, which is exactly the -# gap Huginn's throwaway `PipelineInstance` wrapper used to paper over. G1L is -# a loosening reachable through the same door as the leaf's other text -# fields: admitting a lone backslash inside one label. The fixture -# `outer\inner` has no empty label for the loosening to hide behind, so it -# dies only on the backslash byte itself. -@{ - Mutations = @( - @{ - Id = 'G1' - Rule = 'The public slug door applies the crate''s own grammar: a declared name outside the crate is held to the same check every Slug field is (Self''s ruling on the F6 fork).' - Test = 'tests::slug_validate_applies_the_dotted_grammar' - Old = ' pub fn validate_slug(&self) -> Result<(), PipelineRefusal> { - Bounded::validate(self, "slug") - }' - New = ' pub fn validate_slug(&self) -> Result<(), PipelineRefusal> { - let _ = self; - Ok(()) - }' - }, - @{ - Id = 'G1L' - Rule = 'A label byte is exactly `[A-Za-z0-9_-]`: a lone backslash inside one label is refused, not just a backslash beside an empty label.' - Test = 'tests::slug_validate_applies_the_dotted_grammar' - Old = ' .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b''_'' | b''-''));' - New = ' .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b''_'' | b''-'' | b''\\''));' - }, - @{ - Id = 'S5whole' - Rule = 'The whole-name bound is 64 bytes: `dotted_text` refuses a value one byte past it, even when every individual label sits far under 64.' - Test = 'tests::slug_validate_applies_the_dotted_grammar' - Old = 'fn dotted_text(field: &str, value: &str) -> Result<(), PipelineRefusal> { - if value.is_empty() || value.len() > 64 { - return Err(format_error(field, value)); - }' - New = 'fn dotted_text(field: &str, value: &str) -> Result<(), PipelineRefusal> { - if value.is_empty() { - return Err(format_error(field, value)); - }' - }, - @{ - Id = 'S5label' - Rule = 'The per-label bound is 64 bytes too, the same check `Label` is held to on its own: a lone label carrying no dot is refused one byte past it.' - Test = 'tests::slug_validate_applies_the_dotted_grammar' - Old = ' if !valid || value.is_empty() || value.len() > 64 {' - New = ' if !valid || value.is_empty() {' - }, - @{ - Id = 'S5nul' - Rule = 'NUL is refused as a label byte, not merely as one more character `is_ascii_alphanumeric` happens to reject.' - Test = 'tests::slug_validate_applies_the_dotted_grammar' - Old = ' .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b''_'' | b''-''));' - New = ' .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b''_'' | b''-'' | 0u8));' - } - ) -} diff --git a/tools/eureka-cut5-mutations.psd1 b/tools/eureka-cut5-mutations.psd1 deleted file mode 100644 index 40ab37b9..00000000 --- a/tools/eureka-cut5-mutations.psd1 +++ /dev/null @@ -1,174 +0,0 @@ -# Eureka Cut 5 mutation suite. Entries only; the harness is -# tools/eureka-mutations.ps1. -# -# powershell -File tools/eureka-mutations.ps1 ` -# -Entries tools/eureka-cut5-mutations.psd1 ` -# -Target epiphany-core/src/reasoning_context.rs,epiphany-core/src/runtime_spine.rs ` -# -Test 'cargo test -p epiphany-core --lib' -# -# Cut 5 collapsed `TypedCommitStore` into `commit_authorized_mind_mutation`. -# The collapse is only safe if the rules the profile's tests used to pin are -# still pinned against the concrete owner. M1-M5 are the collapse's own rules. -# MS1 and MS2 close Soul's findings S7 and S8: each is a mutation the suite -# used to survive, kept here so the gap cannot reopen. -# -# Two of the rules are about the *order* of two statements, and removing a -# statement and reinserting it elsewhere is two edits, so those entries carry -# an `Edits` list. The validation loop they move is -# -# for write in &writes { -# crate::mind_documents::validate_mind_write_envelope(write)?; -# } -# -# written out in each entry, since a data file cannot share it. -@{ - Mutations = @( - @{ - Id = 'M1' - Rule = 'The store opener refuses a store at a foreign schema epoch, before the commit can write to it.' - Test = 'reasoning_context::tests::mind_commit_refuses_a_foreign_epoch_store' - Edits = @( - @{ - File = 'epiphany-core/src/runtime_spine.rs' - Old = ' validate_runtime_store_epoch(&backing_store.pull_all()?)?;' - New = ' let _ = &backing_store;' - } - ) - }, - @{ - Id = 'M2' - Rule = 'The batch is validated against the Mind document rules at all. MS2 pins that every write is.' - Test = 'reasoning_context::tests::mind_commit_keeps_validation_receipts_replay_and_conflicts' - Edits = @( - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = @' - for write in &writes { - crate::mind_documents::validate_mind_write_envelope(write)?; - } -'@ - New = @' - for write in &writes { - let _ = write; - } -'@ - } - ) - }, - @{ - Id = 'M3' - Rule = 'The owner resolves one backing store and both reads and writes that one.' - Test = 'reasoning_context::tests::mind_commit_reads_and_writes_one_store' - Edits = @( - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = ' if backing_store.compare_and_swap_batch(&expected, replacements)? {' - New = ' if runtime_spine_backing_store(&store_path.with_file_name("other.cc"))?.compare_and_swap_batch(&expected, replacements)? {' - } - ) - }, - # Ruling 12 order, first half. Hoisting validation above the uniqueness - # checks changes which refusal a caller is told about for a batch that - # is both duplicated and invalid. - @{ - Id = 'M4' - Rule = 'Identity uniqueness is checked before the writes are validated.' - Test = 'reasoning_context::tests::mind_commit_refuses_repeated_write_identities_before_validating' - Edits = @( - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = @' - for write in &writes { - crate::mind_documents::validate_mind_write_envelope(write)?; - } -'@ - New = '' - }, - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = ' validate_unique_envelope_identities(&strong_reads, "strong read")?;' - New = @' - for write in &writes { - crate::mind_documents::validate_mind_write_envelope(write)?; - } - validate_unique_envelope_identities(&strong_reads, "strong read")?; -'@ - } - ) - }, - # Ruling 12 order, second half, and Soul's finding S6. Moving validation - # below the replay answer lets a stored receipt answer a batch the - # current validator would refuse. - @{ - Id = 'M5' - Rule = 'Writes are validated before a stored receipt may answer a replay.' - Test = 'reasoning_context::tests::mind_commit_validates_before_answering_a_replay' - Edits = @( - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = @' - for write in &writes { - crate::mind_documents::validate_mind_write_envelope(write)?; - } -'@ - New = '' - }, - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = @' - return Ok(EpiphanyMindCommitOutcome::Committed(existing)); - } -'@ - New = @' - return Ok(EpiphanyMindCommitOutcome::Committed(existing)); - } - for write in &writes { - crate::mind_documents::validate_mind_write_envelope(write)?; - } -'@ - } - ) - }, - # Soul's finding S7. M3 sends the CAS to a *different* path, which - # leaves a second file the one-store test can see. This sends it to the - # same path, which leaves no trace in the directory at all and survived - # M3's test. It is still a second handle, and the map's redb plan makes - # that fatal: redb permits one writable handle per path. - @{ - Id = 'MS1' - Rule = 'The owner resolves the backing store once and reuses that handle, rather than re-deriving it.' - Test = 'reasoning_context::tests::mind_commit_reads_and_writes_one_store' - Edits = @( - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = ' if backing_store.compare_and_swap_batch(&expected, replacements)? {' - New = ' if runtime_spine_backing_store(store_path)?.compare_and_swap_batch(&expected, replacements)? {' - } - ) - }, - # Soul's finding S8. M2 neuters validation for every write, which any - # single-write batch catches. This keeps validation and narrows it to - # the first write, which nothing caught until a batch of two carried an - # invalid second write. - @{ - Id = 'MS2' - Rule = 'Every write in the batch is validated, not just the first.' - Test = 'reasoning_context::tests::mind_commit_validates_every_write_in_the_batch' - Edits = @( - @{ - File = 'epiphany-core/src/reasoning_context.rs' - Old = @' - for write in &writes { - crate::mind_documents::validate_mind_write_envelope(write)?; - } -'@ - New = @' - for write in writes.iter().take(1) { - crate::mind_documents::validate_mind_write_envelope(write)?; - } -'@ - } - ) - } - ) -} diff --git a/tools/eureka-cut6-mutations.psd1 b/tools/eureka-cut6-mutations.psd1 deleted file mode 100644 index bc5251e4..00000000 --- a/tools/eureka-cut6-mutations.psd1 +++ /dev/null @@ -1,149 +0,0 @@ -# Eureka Cut 6 mutation suite. Entries only; the harness is -# tools/eureka-mutations.ps1. -# -# powershell -File tools/eureka-mutations.ps1 ` -# -Entries tools/eureka-cut6-mutations.psd1 ` -# -Target epiphany-pipeline/src/lib.rs,epiphany-core/src/runtime_spine.rs ` -# -Test 'cargo test -p epiphany-pipeline --lib' -# -# M1-M9 are Cut 4's suite re-anchored: the code they mutate moved from -# `epiphany-core/src/pipeline_documents.rs` to `epiphany-pipeline/src/lib.rs`. -# M10 still mutates the spine in epiphany-core, so it carries its own command. -# M11 is the first of the two the cut named for the kinds it added. -# -# Five entries Cut 6b's grammar made stale are gone rather than re-anchored; -# each note below names where the rule is pinned now. -# -# - M5, "a finding label carries no dot": the finding arm no longer validates -# the label itself; the label goes through `local` as its last part, which -# refuses a dotted part as `finding.key`. Cut 6b's F5 accepted that -# refusal; the rule is pinned on the composer by Cut 6b's N3 (the last part -# skips the label check) and M6 (the head does), and through the documents -# by `composed_keys_cannot_collide`. -# - M12, "a repo inside a key is escaped", and M13, "the repo escape is -# injective": `key_segment` replaced `repo_segment`; each is re-anchored on -# it as Cut 6b's N7 (the escape is the identity) and N8 (`/` to a bare `_`, -# `_` unescaped), both killed by `stewardship_key_escapes_the_repo_slash`. -# - M14, "an instance's slug is validated where its key is composed": the -# instance arm composes through the shared root check; pinned by Cut 6b's -# M5 and M1. -# - M15, "the id reader knows the same roots the key writer does": every kind -# reads back with no root excused; pinned by Cut 6b's N6 (the reader's kind -# check excuses the Instance kind), killed by -# `keys_read_back_as_ids_of_their_kind` reading a campaign key as an -# instance, and by Cut 6b's M1. -@{ - Mutations = @( - @{ - Id = 'M1' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'A document decodes back only from an envelope of its own type id.' - Test = 'tests::every_pipeline_kind_round_trips_through_named_slot_zero' - Old = '$(if envelope.r#type == <$document as DatabaseEntry>::TYPE {' - New = '$(if envelope.r#type != <$document as DatabaseEntry>::TYPE {' - }, - @{ - Id = 'M2' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'Text bounds are measured in UTF-8 bytes, not characters.' - Test = 'tests::bounds_refuse_in_utf8_bytes' - Old = ' move |field: &str, value: &str| bound(field, limit, value.len())' - New = ' move |field: &str, value: &str| bound(field, limit, value.chars().count())' - }, - @{ - Id = 'M3' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'An OrgRepo carries exactly one slash.' - Test = 'tests::repo_fields_must_be_org_slash_repo' - Old = " if !org.is_empty() && !repo.is_empty() && !repo.contains('/') && value.len() <= 200 =>" - New = ' if !org.is_empty() && !repo.is_empty() && value.len() <= 200 =>' - }, - @{ - Id = 'M4' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'A write envelope''s key is recomputed from the value and a mismatch refuses.' - Test = 'tests::keys_are_derived_and_mismatch_refuses' - Old = ' if envelope.key != expected {' - New = ' if false {' - }, - @{ - Id = 'M6' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'A parent local must carry its own kind''s marker character.' - Test = 'tests::parent_ids_are_parsed_strictly' - Old = ' let digits = suffix.strip_prefix(marker).ok_or_else(invalid)?;' - New = ' let digits = suffix.strip_prefix(marker).unwrap_or(suffix);' - }, - @{ - Id = 'M7' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'A PipelineRef''s id is parsed as a full id of its declared kind.' - Test = 'tests::resolution_subject_is_a_full_id_of_its_kind' - Old = ' pipeline_id(&format!("{at}.id"), &self.id.0, self.kind).map(|_| ())' - New = ' Ok(())' - }, - @{ - Id = 'M8' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'Published schemas are the Rust derivation, byte for byte.' - Test = 'tests::pipeline_published_schemas_match_derivation' - Old = ' Short = 200, |field, value| within(200)(field, value);' - New = ' Short = 201, |field, value| within(200)(field, value);' - }, - # Soul F2. M1 removes the positive match; this removes the refusal that - # catches everything the positive match misses, leaving a decode that - # says "malformed payload" about an envelope that was never a document. - @{ - Id = 'M9' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'An envelope whose type id belongs to another kind is refused as ForeignStore.' - Test = 'tests::decode_refuses_an_envelope_of_a_foreign_type' - Old = 'Err(PipelineRefusal::ForeignStore { r#type: envelope.r#type.clone() })' - New = 'Err(format_error("payload", &envelope.r#type))' - }, - # Soul F4. The spine cache refuses a pipeline store by registering its - # own types and nothing else, so the mutation that removes the rule is - # the one that registers a pipeline type into it. epiphany-core no - # longer has the documents, so the mutation declares its own type - # carrying the same type id, exactly as the test does. - @{ - Id = 'M10' - File = 'epiphany-core/src/runtime_spine.rs' - Command = 'cargo test -p epiphany-core --lib' - Rule = 'The runtime spine cache refuses an epiphany.pipeline.* envelope.' - Test = 'runtime_spine::tests::runtime_spine_cache_refuses_a_pipeline_store' - Old = @' -fn runtime_spine_schema_cache() -> Result { - let mut cache = CultCache::new(); -'@ - New = @' -fn runtime_spine_schema_cache() -> Result { - let mut cache = CultCache::new(); - #[derive(Clone, Debug, PartialEq, Eq, DatabaseEntry)] - #[cultcache( - type = "epiphany.pipeline.campaign.v1", - schema = "EpiphanyPipelineCampaignDocument" - )] - struct RegisteredPipelineDocument { - #[cultcache(key = 0)] - slug: String, - } - cache.register_entry_type::()?; -'@ - }, - # The cut's first named mutation: change a value type's shape and leave - # the published schema alone. A field cannot be added without breaking - # every struct literal that builds the value, which would fail the whole - # target and prove nothing about this test in particular, so the shape - # change is a new enum variant: it compiles, and it changes exactly one - # derived schema. - @{ - Id = 'M11' - File = 'epiphany-pipeline/src/lib.rs' - Rule = 'A change to a value type''s shape is caught unless its schema is regenerated.' - Test = 'tests::pipeline_published_schemas_match_derivation' - Old = ' FindingSeverity { Blocker, High, Medium, Low }' - New = ' FindingSeverity { Blocker, High, Medium, Low, Cosmetic }' - } - ) -} diff --git a/tools/eureka-cut6b-mutations.psd1 b/tools/eureka-cut6b-mutations.psd1 deleted file mode 100644 index c80bbf0e..00000000 --- a/tools/eureka-cut6b-mutations.psd1 +++ /dev/null @@ -1,195 +0,0 @@ -# Eureka Cut 6b mutation suite: the key grammar. Entries only; the harness is -# tools/eureka-mutations.ps1. -# -# powershell -File tools/eureka-mutations.ps1 ` -# -Entries tools/eureka-cut6b-mutations.psd1 ` -# -Target epiphany-pipeline/src/lib.rs ` -# -Test 'cargo test -p epiphany-pipeline --lib' -# -# M1-M6 are the cut's own rules. S2, S4 and S5 are the mutations Soul's pass -# found surviving; each is kept exactly as Soul wrote it, against the test the -# fix batch extended to kill it. N3, N6, N7, N8, N9 and N10 are Soul's second -# pass: N7 and N8 re-anchor Cut 6's M12 and M13 on `key_segment`, N3 is the -# analogue of Cut 6's M5 on `local`, N6 of Cut 6's M15 on the reader, and N9 -# and N10 are the dotted-root mutations that survived until -# `dotted_roots_key_and_read_back`. X1 and X11 are Soul's third pass, the -# reader trimming a trailing dot from the root or the local, killed by the -# malformed fixtures in `keys_read_back_as_ids_of_their_kind`. The file holds -# an `é` literal in `bounds_refuse_in_utf8_bytes`, which is why the harness -# I/O is byte-exact. -# -# Soul's N4 moved the bound in `local` and both 64s in the depth test to 60 -# together and survived: the test restated the literal. `LOCAL_MAX` now names -# the bound, `local` and the depth test both read it, and the mutation is no -# longer expressible as a single-site edit, so it has no entry here. -@{ - Mutations = @( - @{ - Id = 'M1' - Rule = 'Campaign and instance roots do not share one namespace (defect 1).' - Test = 'tests::roots_of_different_kinds_do_not_share_a_key' - Old = ' D::Campaign(value) => ("campaign.slug", value.slug.0.as_str(), local(&key_field, &[ROOT_LOCAL])?),' - New = ' D::Campaign(value) => return Ok(value.slug.0.clone()),' - }, - @{ - Id = 'M2' - Rule = 'A resolution''s key carries its subject''s kind (defect 2).' - Test = 'tests::a_resolution_names_its_subjects_kind' - Old = ' let parts = std::iter::once(value.subject.kind.name()).chain(subject_local.split(''.'')).chain(std::iter::once(sequence.as_str())).collect::>();' - New = ' let parts = subject_local.split(''.'').chain(std::iter::once(sequence.as_str())).collect::>();' - }, - @{ - Id = 'M3' - Rule = 'A resolution of a resolution composes a key the reader accepts (defect 3).' - Test = 'tests::a_resolution_of_a_resolution_reads_back' - Old = ' (field, subject_root, local(&key_field, &parts)?)' - New = ' return Ok(format!("resolution:{}", value.subject.id.0))' - }, - @{ - Id = 'M4' - Rule = 'A composed local is bounded whole, not only per part.' - Test = 'tests::a_composed_local_is_bounded_whole' - Old = @' - if joined.len() > LOCAL_MAX { - return Err(format_error(field, &joined)); - } -'@ - New = '' - }, - @{ - Id = 'M5' - Rule = 'The root segment is validated where the key is composed.' - Test = 'tests::every_key_has_exactly_three_segments' - Old = ' dotted_text(root_field, root)?;' - New = ' let _ = root_field;' - }, - @{ - Id = 'M6' - Rule = 'No local part carries the separator, the head included (R2).' - Test = 'tests::no_local_part_carries_the_separator' - Old = @' - for part in parts { - label_text(field, part)?; - } -'@ - New = @' - for (index, part) in parts.iter().enumerate() { - if index == 0 { dotted_text(field, part)?; } else { label_text(field, part)?; } - } -'@ - }, - # Soul S2. The escape's `_` half was pinned only through an OrgRepo, so - # an escape that skipped it for a value with no slash survived: `a_db` - # and `a.b` both keyed to `a_db`. The receiver pair kills it. - @{ - Id = 'S2' - Rule = 'key_segment escapes `_` for a slug as well as a repo, so `a_db` and `a.b` are two receivers.' - Test = 'tests::hand_off_names_both_instances' - Old = ' value.replace(''_'', "__").replace(''/'', "_-").replace(''.'', "_d")' - New = @' - if !value.contains('/') { - return value.replace('.', "_d"); - } - value.replace('_', "__").replace('/', "_-").replace('.', "_d") -'@ - }, - # Soul S4. The composer's root check was pinned by `a:b` alone, so a - # check that trimmed a trailing dot first survived. The root fixtures - # kill it. - @{ - Id = 'S4' - Rule = 'The composer''s root check refuses a trailing dot, not only a colon.' - Test = 'tests::every_key_has_exactly_three_segments' - Old = ' dotted_text(root_field, root)?;' - New = ' dotted_text(root_field, root.trim_end_matches(''.''))?;' - }, - # Soul S5. The whole-local bound was unpinned on both sides, so an - # off-by-one survived. The 64- and 65-byte fixtures kill it. - @{ - Id = 'S5' - Rule = 'The whole-local bound is 64 exactly: 65 refuses.' - Test = 'tests::a_composed_local_is_bounded_whole' - Old = ' if joined.len() > LOCAL_MAX {' - New = ' if joined.len() > LOCAL_MAX + 1 {' - }, - # Soul N3, the analogue of Cut 6's M5 ("a finding label carries no - # dot") on the composer: the join bound stays and the last part skips - # `label_text`. A finding's label is the last part of its local. - @{ - Id = 'N3' - Rule = 'Every local part is a label, the last included (Cut 6 M5 on the composer).' - Test = 'tests::no_local_part_carries_the_separator' - Old = @' - for part in parts { - label_text(field, part)?; - } -'@ - New = @' - for part in &parts[..parts.len() - 1] { - label_text(field, part)?; - } -'@ - }, - # Soul N6, the analogue of Cut 6's M15 on the reader: the kind check - # excuses the Instance kind. A campaign key read as an instance kills it. - @{ - Id = 'N6' - Rule = 'The reader checks the kind segment for a root kind as for every other (Cut 6 M15).' - Test = 'tests::keys_read_back_as_ids_of_their_kind' - Old = ' if name != kind.name() {' - New = ' if name != kind.name() && kind != PipelineKind::Instance {' - }, - # Soul N7, Cut 6's M12 re-anchored on `key_segment`: the escape is - # the identity, so a repo's slash reaches the local and is refused. - @{ - Id = 'N7' - Rule = 'A repo inside a key is escaped (Cut 6 M12).' - Test = 'tests::stewardship_key_escapes_the_repo_slash' - Old = ' value.replace(''_'', "__").replace(''/'', "_-").replace(''.'', "_d")' - New = ' value.to_string()' - }, - # Soul N8, Cut 6's M13 re-anchored on `key_segment`: `/` becomes a - # bare `_` and `_` is not escaped, so two repos claim one key. - @{ - Id = 'N8' - Rule = 'The repo escape is injective (Cut 6 M13).' - Test = 'tests::stewardship_key_escapes_the_repo_slash' - Old = ' value.replace(''_'', "__").replace(''/'', "_-").replace(''.'', "_d")' - New = ' value.replace(''/'', "_").replace(''.'', "_d")' - }, - # Soul N9 and N10: the root is a `Slug`, on the writer and the reader. - # Both survived while no test keyed or read back a dotted root. - @{ - Id = 'N9' - Rule = 'The composer''s root check is a slug check: a dotted root keys.' - Test = 'tests::dotted_roots_key_and_read_back' - Old = ' dotted_text(root_field, root)?;' - New = ' label_text(root_field, root)?;' - }, - @{ - Id = 'N10' - Rule = 'The reader''s root check is a slug check: a dotted root reads back.' - Test = 'tests::dotted_roots_key_and_read_back' - Old = ' dotted_text(field, root)?;' - New = ' label_text(field, root)?;' - }, - # Soul X1 and X11, the reader's halves of S4: a trailing dot on the - # root or on the local was refused only by the writer, which never - # composes one, so a reader that trimmed it survived. The malformed - # fixtures read through `pipeline_id` kill both. - @{ - Id = 'X1' - Rule = 'The reader''s root check refuses a trailing dot; it does not trim one.' - Test = 'tests::keys_read_back_as_ids_of_their_kind' - Old = ' dotted_text(field, root)?;' - New = ' dotted_text(field, root.trim_end_matches(''.''))?;' - }, - @{ - Id = 'X11' - Rule = 'The reader''s local check refuses a trailing dot; it does not trim one.' - Test = 'tests::keys_read_back_as_ids_of_their_kind' - Old = ' dotted_text(field, local)?;' - New = ' dotted_text(field, local.trim_end_matches(''.''))?;' - } - ) -} diff --git a/tools/eureka-cut6c-mutations.psd1 b/tools/eureka-cut6c-mutations.psd1 deleted file mode 100644 index 98485c6c..00000000 --- a/tools/eureka-cut6c-mutations.psd1 +++ /dev/null @@ -1,112 +0,0 @@ -# Eureka Cut 6c mutation suite: the Ghostlight shapes. Entries only; the -# harness is tools/eureka-mutations.ps1. -# -# powershell -File tools/eureka-mutations.ps1 ` -# -Entries tools/eureka-cut6c-mutations.psd1 ` -# -Target epiphany-pipeline/src/lib.rs ` -# -Test 'cargo test -p epiphany-pipeline --lib' -# -# A retyping is the mutation-hostile case: the compiler catches the type -# change, so the tempting test constructs a valid value and asserts `Ok(())`, -# which stays green under every mutation below. Where the cut's content is a -# type, the mutation is a type-level mutation (M19, M20, M22) and its killer -# is a forgery the wider type admits. The key suite is blind to all of these -# because a resolution's key is outcome-invariant. -@{ - Mutations = @( - @{ - Id = 'M16' - Rule = 'A Superseded list is validated item by item, not only bounded: a wrong-kind referent inside it is refused.' - 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 } => bound(&format!("{field}.by"), 8, by.len()),' - }, - @{ - Id = 'M17' - Rule = 'Every resolution referent is validated as a full id of the kind it declares.' - Test = 'tests::resolution_outcome_referents_are_parsed_ids_of_their_kind' - Old = @' - match self { - Self::Superseded { by } => list(&format!("{field}.by"), by, 8), - Self::Answered { by } => by.validate(&format!("{field}.by")), - Self::Fixed { commit, by } => { - commit.validate(&format!("{field}.commit"))?; - by.validate(&format!("{field}.by")) - } - Self::Deferred { to } => to.validate(&format!("{field}.to")), - Self::Recorded { reason } | Self::Withdrawn { reason } => reason.validate(&format!("{field}.reason")), - } -'@ - New = @' - let _ = field; - Ok(()) -'@ - }, - @{ - Id = 'M18' - Rule = 'A fix''s commit is validated as a sha (ruling B): uppercase hex of legal length is refused.' - Test = 'tests::fixed_resolution_requires_a_commit_sha' - Old = ' commit.validate(&format!("{field}.commit"))?;' - New = ' let _ = commit;' - }, - @{ - Id = 'M19' - Rule = 'A mutation record''s label is a Label, so it is key-safe: a dotted label is refused.' - Test = 'tests::mutation_records_carry_a_dot_free_label_and_a_commit' - Old = 'pub struct MutationRecord { label: Label,' - New = 'pub struct MutationRecord { label: Short,' - }, - @{ - Id = 'M20' - Rule = 'A mutation record is pinned to a tree: its commit is a Sha, not free text.' - Test = 'tests::mutation_records_carry_a_dot_free_label_and_a_commit' - Old = 'commit: Sha, failed_as_expected: bool }' - New = 'commit: Short, failed_as_expected: bool }' - }, - # The two-line anchor carries the opener: the numbers alone also match - # the report sample's StructuralDelta. - @{ - Id = 'M21' - Rule = 'The estimate''s two u32 fields are not interchangeable: the sample spec estimates a net addition.' - Test = 'tests::the_sample_cut_spec_estimates_a_net_addition' - Old = @' - estimate: StructuralDelta { - lines_added: 900, lines_removed: 0, -'@ - New = @' - estimate: StructuralDelta { - lines_added: 0, lines_removed: 900, -'@ - }, - @{ - Id = 'M22' - Rule = 'A verdict claim names at most eight mutations.' - Test = 'tests::a_verdict_claim_names_the_promise_and_the_mutation_it_measured' - Old = 'mutations: Vec