Delete every committed mutation suite

Better to have nothing than a harness that punishes refactoring
(operator ruling, 2026-09-22). Remove all eight tools/*mutations*.psd1
files (921 lines total): cut5, cut6, cut6b, cut6c, cut6d,
cut8-epiphany, cut10-epiphany, readside-leaf. The harness that ran
them, eureka-mutations.ps1, was already deleted from the Eureka skill
(37c80e4).

notes/eureka-body-plane-cut.md, notes/eureka-pipeline-state-cut.md and
notes/eureka-read-side-cut.md still name these suites; they are Self's
campaign records and are left untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-22 18:42:36 +02:00
commit 703fdd0bf7
8 changed files with 0 additions and 1021 deletions

View file

@ -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));'
}
)
}

View file

@ -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)?;
}
'@
}
)
}
)
}

View file

@ -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<CultCache> {
let mut cache = CultCache::new();
'@
New = @'
fn runtime_spine_schema_cache() -> Result<CultCache> {
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::<RegisteredPipelineDocument>()?;
'@
},
# 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 }'
}
)
}

View file

@ -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::<Vec<_>>();'
New = ' let parts = subject_local.split(''.'').chain(std::iter::once(sequence.as_str())).collect::<Vec<_>>();'
},
@{
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(''.''))?;'
}
)
}

View file

@ -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<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(()) }'
}
)
}

View file

@ -1,81 +0,0 @@
# Eureka Cut 6d mutation suite: resolution history and stewardship by
# sequence. Entries only; the harness is tools/eureka-mutations.ps1.
#
# powershell -File tools/eureka-mutations.ps1 `
# -Entries tools/eureka-cut6d-mutations.psd1 `
# -Target epiphany-pipeline/src/lib.rs `
# -Test 'cargo test -p epiphany-pipeline --lib'
#
# Each entry restores the permissiveness the shape it pins removed: M23 and
# M24 restore the one-per-subject and one-per-repo keys this cut retired, M25
# and M26 put the sequence anywhere but last, and M27 drops a nested subject's
# own sequence on the way into the key. S6 and S11 are Soul's, from the pass
# over this suite: S6 copies a nested subject's sequence instead of using the
# document's own, which every all-`1` fixture hides, and S11 is M27 for the
# other sequenced kind, a stewardship subject. Cut 6b's M2 already covers the
# subject's kind on the same line and is re-anchored there, not repeated here.
#
# Stated limits, so a later reader does not mistake silence for coverage. The
# `n` marker itself has no entry: it is pinned only by the sample-key
# equalities in `keys_are_derived_and_mismatch_refuses` and the two prefix
# literals, a fixture pin like 6c's M21, and changing a marker restores no
# permissiveness. The `u32` type has no runtime mutation. Date-invariance has
# none of its own either: putting `assigned_on` into the stewardship key is
# not a permissiveness the old code had, and M24's test asserts the local's
# part count is exactly two, so a mutant that appends the date as a third part
# dies there.
@{
Mutations = @(
@{
Id = 'M23'
Rule = 'A subject''s resolutions are distinct records: the sequence is in the key (Q17 B).'
Test = 'tests::a_subject_keeps_every_resolution_it_had'
Old = ' let parts = std::iter::once(value.subject.kind.name()).chain(subject_local.split(''.'')).chain(std::iter::once(sequence.as_str())).collect::<Vec<_>>();'
New = ' let parts = std::iter::once(value.subject.kind.name()).chain(subject_local.split(''.'')).collect::<Vec<_>>();'
},
@{
Id = 'M24'
Rule = 'A repo''s stewardships on a mind are distinct records: the sequence is in the key (Q18 A, Q20 A).'
Test = 'tests::a_repo_keeps_every_stewardship_it_had'
Old = 'local(&key_field, &[&key_segment(&value.repo.0), &sequence])?)'
New = 'local(&key_field, &[&key_segment(&value.repo.0)])?)'
},
@{
Id = 'M25'
Rule = 'A stewardship''s sequence is the last part, so a repo''s assignments share a prefix (D2).'
Test = 'tests::a_repo_keeps_every_stewardship_it_had'
Old = 'local(&key_field, &[&key_segment(&value.repo.0), &sequence])?)'
New = 'local(&key_field, &[&sequence, &key_segment(&value.repo.0)])?)'
},
@{
Id = 'M26'
Rule = 'A resolution''s sequence is the last part, so a subject''s resolutions share a prefix (D2).'
Test = 'tests::a_subjects_resolutions_share_a_prefix_no_other_key_has'
Old = ' let parts = std::iter::once(value.subject.kind.name()).chain(subject_local.split(''.'')).chain(std::iter::once(sequence.as_str())).collect::<Vec<_>>();'
New = ' let parts = std::iter::once(value.subject.kind.name()).chain(std::iter::once(sequence.as_str())).chain(subject_local.split(''.'')).collect::<Vec<_>>();'
},
@{
Id = 'M27'
Rule = 'A nested subject is recovered whole: a resolution of a resolution keys the inner key, sequence included (defect 3, under the new shape).'
Test = 'tests::a_resolution_of_a_resolution_reads_back'
Old = ' let parts = std::iter::once(value.subject.kind.name()).chain(subject_local.split(''.'')).chain(std::iter::once(sequence.as_str())).collect::<Vec<_>>();'
New = ' let parts = std::iter::once(value.subject.kind.name()).chain(subject_local.rsplit_once(''.'').map_or(subject_local, |(head, _)| head).split(''.'')).chain(std::iter::once(sequence.as_str())).collect::<Vec<_>>();'
},
@{
Id = 'S6'
Rule = 'A nesting''s own sequence is its own field: a resolution of a resolution copies the subject''s sequence instead (Q17 B, defect 3).'
Test = 'tests::every_level_of_a_nesting_keeps_its_own_sequence'
Old = ' let sequence = format!("n{}", value.sequence);
let parts = std::iter::once(value.subject.kind.name())'
New = ' let sequence = if matches!(value.subject.kind, PipelineKind::Resolution) { subject_local.rsplit(''.'').next().unwrap_or("").to_string() } else { format!("n{}", value.sequence) };
let parts = std::iter::once(value.subject.kind.name())'
},
@{
Id = 'S11'
Rule = 'A stewardship subject is recovered whole: its own sequence survives into the resolution key (M27 for the other sequenced kind).'
Test = 'tests::a_resolution_of_a_stewardship_reads_back'
Old = ' let parts = std::iter::once(value.subject.kind.name()).chain(subject_local.split(''.'')).chain(std::iter::once(sequence.as_str())).collect::<Vec<_>>();'
New = ' let parts = std::iter::once(value.subject.kind.name()).chain(if matches!(value.subject.kind, PipelineKind::Stewardship) { subject_local.rsplit_once(''.'').map_or(subject_local, |(head, _)| head) } else { subject_local }.split(''.'')).chain(std::iter::once(sequence.as_str())).collect::<Vec<_>>();'
}
)
}

View file

@ -1,104 +0,0 @@
# Eureka Cut 8 mutation suite, the Epiphany half: the epoch constant and the
# live registrar. Entries only; the harness is tools/eureka-mutations.ps1.
#
# powershell -File tools/eureka-mutations.ps1 `
# -Entries tools/eureka-cut8-epiphany-mutations.psd1 `
# -Target epiphany-pipeline/src/lib.rs `
# -Test 'cargo test -p epiphany-pipeline --lib'
#
# E1-E3 are killed by `every_kind_is_at_the_epochs_version`: it reads the
# version segment off the constant and holds every type id to it, so a wrong
# epoch dies whether it is `.v2` or `.v1x`; and it counts what the live
# registrar registers against `PipelineKind::ALL`, so one type fewer and one
# foreign type more both die on the count.
#
# D1 and D2 are the derives the wire carries a batch through, and both are
# killed by `every_document_and_refusal_serialises_and_reads_back`: the tag a
# reader dispatches on is asserted against `PipelineKind::name()` for every
# kind, and every refusal variant is round-tripped whole, so a field that
# leaves the wire comes back empty and is not the refusal that went out.
#
# R1 and R2 are the public reference door, and both are killed by
# `a_ref_validates_as_an_id_of_the_kind_it_declares`: a kind that is not the
# id's kills the door that answers Ok to everything, and a trailing dot kills
# the door that reads the kind segment and nothing else.
@{
Mutations = @(
@{
Id = 'E1'
Rule = 'The epoch names the version every kind is published at; a bumped epoch fails until the kinds move with it.'
Test = 'tests::every_kind_is_at_the_epochs_version'
Old = 'pub const PIPELINE_SCHEMA_EPOCH: &str = "epiphany.pipeline.epoch.v1";'
New = 'pub const PIPELINE_SCHEMA_EPOCH: &str = "epiphany.pipeline.epoch.v2";'
},
@{
Id = 'E2'
Rule = 'The live registrar registers every kind: one fewer is refused on the count.'
Test = 'tests::every_kind_is_at_the_epochs_version'
Old = ' $(cache.register_entry_type::<$document>()?;)*'
New = ' let mut first = true; $(if !first { cache.register_entry_type::<$document>()?; } first = false;)*'
},
@{
Id = 'E3'
Rule = 'The live registrar registers nothing but the kinds: the foreign stand-in registered again under cfg(test) is refused on the count.'
Test = 'tests::every_kind_is_at_the_epochs_version'
Old = @'
$(cache.register_entry_type::<$document>()?;)*
Ok(())
'@
New = @'
$(cache.register_entry_type::<$document>()?;)*
#[cfg(test)]
cache.register_entry_type::<ForeignDocument>()?;
Ok(())
'@
},
@{
Id = 'D1'
Rule = 'The document tag is the kind name: a wire reader dispatches on the same string the key segment carries, so the variant spelling is renamed to it and not left as Rust case.'
Test = 'tests::every_document_and_refusal_serialises_and_reads_back'
Old = ' #[serde(tag = "kind", content = "value", rename_all = "snake_case")]'
New = ' #[serde(tag = "kind", content = "value")]'
},
@{
Id = 'D2'
Rule = 'A refusal carries its named parts over the wire: the field it refused is on the wire, not dropped and defaulted back on the reader.'
Test = 'tests::every_document_and_refusal_serialises_and_reads_back'
Old = ' FieldBound { field: String, limit: u32, actual: u32 },'
New = ' FieldBound { #[serde(skip)] field: String, limit: u32, actual: u32 },'
},
@{
Id = 'R1'
Rule = 'The public door is the grammar, not a formality: a door that answers Ok to every reference leaves the read side unable to tell a malformed reference from a missing document.'
Test = 'tests::a_ref_validates_as_an_id_of_the_kind_it_declares'
Old = @'
pub fn validate_ref(&self) -> Result<(), PipelineRefusal> {
self.validate("ref")
}
'@
New = @'
pub fn validate_ref(&self) -> Result<(), PipelineRefusal> {
Ok(())
}
'@
},
@{
Id = 'R2'
Rule = 'The door delegates to the one grammar: a door that checks the kind segment alone admits a local no writer composes, and the reference grammar has two owners.'
Test = 'tests::a_ref_validates_as_an_id_of_the_kind_it_declares'
Old = @'
pub fn validate_ref(&self) -> Result<(), PipelineRefusal> {
self.validate("ref")
}
'@
New = @'
pub fn validate_ref(&self) -> Result<(), PipelineRefusal> {
if self.id.0.split(':').nth(1) != Some(self.kind.name()) {
return Err(format_error("ref.id", &self.id.0));
}
Ok(())
}
'@
}
)
}

View file

@ -1,137 +0,0 @@
# Eureka read-side cut, Cut RS-L: the leaf's title, the epoch, and the two new
# grammar doors. Entries only; the harness is tools/eureka-mutations.ps1.
#
# powershell -File tools/eureka-mutations.ps1 `
# -Entries tools/eureka-readside-leaf-mutations.psd1 `
# -Target epiphany-pipeline/src/lib.rs `
# -Test 'cargo test -p epiphany-pipeline --lib'
#
# M0 is the harness's own built-in control and is not an entry here.
#
# L1 and L1L are `OrgRepo::validate_org_repo`, on `Slug::validate_slug`'s
# pattern, and both are killed by `the_org_repo_and_label_doors_are_the_grammar`:
# a door that answers Ok to everything dies on "GameCult" alone, and the
# loosened grammar that accepts any string carrying a slash dies on "a/b/c"
# and on the 201-byte fixture, both of which carry exactly one slash.
#
# L2 and L2L are `Label::validate_label`, on the same pattern, and both are
# killed by the same test: a door that answers Ok to everything dies on the
# empty string, and a door delegating to the slug grammar instead of the
# label grammar dies on "a.b", which `dotted_text` accepts as two labels
# joined by a dot and `label_text` refuses outright because a label carries
# no dot.
#
# L3 and L3L are the `Title` type's non-empty and 200-byte bounds, both
# killed by `question_and_ruling_carry_a_title`: removing the non-empty check
# dies on the empty-title case, and widening the bound to 201 bytes dies on
# the pinned 201-byte refusal.
@{
Mutations = @(
@{
Id = 'L1'
Rule = 'The public door onto the org_repo grammar is the grammar, not a formality: a door that answers Ok to every repo string leaves a caller holding a bare OrgRepo (the read side vocabulary''s repo alias, RS-3) unable to tell a malformed one from a missing document.'
Test = 'tests::the_org_repo_and_label_doors_are_the_grammar'
Old = @'
pub fn validate_org_repo(&self) -> Result<(), PipelineRefusal> {
Bounded::validate(self, "org_repo")
}
'@
New = @'
pub fn validate_org_repo(&self) -> Result<(), PipelineRefusal> {
Ok(())
}
'@
},
@{
Id = 'L1L'
Rule = 'The door delegates to the one grammar, org_repo_text whole: a loosening that accepts any string carrying a slash still depends on the input, but admits a second slash and an over-long value the real grammar refuses.'
Test = 'tests::the_org_repo_and_label_doors_are_the_grammar'
Old = @'
fn org_repo_text(field: &str, value: &str) -> Result<(), PipelineRefusal> {
match value.split_once('/') {
Some((org, repo))
if !org.is_empty() && !repo.is_empty() && !repo.contains('/') && value.len() <= 200 =>
{
Ok(())
}
_ => Err(format_error(field, value)),
}
}
'@
New = @'
fn org_repo_text(field: &str, value: &str) -> Result<(), PipelineRefusal> {
if value.contains('/') { Ok(()) } else { Err(format_error(field, value)) }
}
'@
},
@{
Id = 'L2'
Rule = 'The public door onto the label grammar is the grammar, not a formality: a door that answers Ok to every label string leaves a caller holding a bare Label (the read side vocabulary''s cut alias, RS-3) unable to tell a malformed one from a missing document.'
Test = 'tests::the_org_repo_and_label_doors_are_the_grammar'
Old = @'
pub fn validate_label(&self) -> Result<(), PipelineRefusal> {
Bounded::validate(self, "label")
}
'@
New = @'
pub fn validate_label(&self) -> Result<(), PipelineRefusal> {
Ok(())
}
'@
},
@{
Id = 'L2L'
Rule = 'The door delegates to the label grammar and not to some other one: a door wired to dotted_text instead of label_text admits a dotted name a label never allows, since a label composes no key of its own and carries no dot.'
Test = 'tests::the_org_repo_and_label_doors_are_the_grammar'
Old = @'
pub fn validate_label(&self) -> Result<(), PipelineRefusal> {
Bounded::validate(self, "label")
}
'@
New = @'
pub fn validate_label(&self) -> Result<(), PipelineRefusal> {
dotted_text("label", &self.0)
}
'@
},
@{
Id = 'L3'
Rule = 'Q-RS1 (ruled B): a title is never empty. Removing the non-empty check leaves only the 200-byte bound, so a bare leaf with an empty campaign, cut spec, question or ruling title would validate.'
Test = 'tests::question_and_ruling_carry_a_title'
Old = @'
fn title_text(field: &str, value: &str) -> Result<(), PipelineRefusal> {
if value.is_empty() {
return Err(format_error(field, value));
}
within(200)(field, value)
}
'@
New = @'
fn title_text(field: &str, value: &str) -> Result<(), PipelineRefusal> {
within(200)(field, value)
}
'@
},
@{
Id = 'L3L'
Rule = 'The title bound is exactly 200 bytes, not 201: a loosening that still depends on the input''s length dies on the pinned 201-byte case, which the real bound refuses and the widened one would accept.'
Test = 'tests::question_and_ruling_carry_a_title'
Old = @'
fn title_text(field: &str, value: &str) -> Result<(), PipelineRefusal> {
if value.is_empty() {
return Err(format_error(field, value));
}
within(200)(field, value)
}
'@
New = @'
fn title_text(field: &str, value: &str) -> Result<(), PipelineRefusal> {
if value.is_empty() {
return Err(format_error(field, value));
}
within(201)(field, value)
}
'@
}
)
}