Kill the 96 pass 3 survivors and uncovered mutants in os-sdlc cops/structural #1703

Closed
opened 2026-11-11 23:11:28 +00:00 by jared · 2 comments
Owner

Problem

Whole mutation pass 3 (2026-11-11, main 9a1895a1f) left 94 survivors and 2 uncovered mutants in 57 files under cops/structural. None has a ledger row in .sdlc/mutation-rulings.tsv, and none is a known visible mutant (ruling 137). A survivor is a changed behavior that the suite does not see. 55 of these mutants use a tier-2 operator (condition_true, condition_false, negation_removal). 75 also survived pass 2.

Observed

docs/research/mutation-testing/2026-11-11-third-pass/unruled.tsv lists each mutant with its ID, line, operator, and tier. Each line below gives the file, its counts, and the operators.

  • lib/os_sdlc/cops/structural/query_method_reaches_write/write_chain.rb (7 survived): statement_removal 3, condition_true 1, boolean_literal 1, condition_false 1, return_nil 1
  • lib/os_sdlc/cops/structural/edge_scope.rb (5 survived): return_nil 2, condition_false 1, statement_removal 1, boolean_connector 1
  • lib/os_sdlc/cops/structural/precedence_in_edge/candidate.rb (4 survived): condition_false 1, condition_true 1, return_nil 1, boolean_connector 1
  • lib/os_sdlc/cops/structural/layer_ledger/layer_map.rb (3 survived): boolean_connector 2, condition_true 1
  • lib/os_sdlc/cops/structural/feature_envy/site.rb (3 survived): return_nil 2, condition_true 1
  • lib/os_sdlc/cops/structural/effect_reach/walk.rb (3 survived): statement_removal 1, condition_false 1, return_nil 1
  • lib/os_sdlc/cops/structural/effect_in_model.rb (3 survived): condition_false 1, statement_removal 1, condition_true 1
  • lib/os_sdlc/cops/structural/domain_operand_in_edge/second_source.rb (3 survived): condition_true 2, boolean_connector 1
  • lib/os_sdlc/cops/structural/simulated_polymorphism/owned_type.rb (3 survived): condition_true 2, boolean_literal 1
  • lib/os_sdlc/cops/structural/boolean_control_parameter/def_site.rb (3 survived): condition_true 1, boolean_literal 1, return_nil 1
  • lib/os_sdlc/cops/structural/adapter_built_outside_entry.rb (2 survived): condition_false 1, statement_removal 1
  • lib/os_sdlc/cops/structural/own_entry_point_spawned_in_test/script_paths.rb (2 survived): condition_true 2
  • lib/os_sdlc/cops/structural/layer_ledger/ledger.rb (1 survived, 1 uncovered): condition_true 1, statement_removal 1
  • lib/os_sdlc/cops/structural/inward_dependency.rb (2 survived): condition_false 1, statement_removal 1
  • lib/os_sdlc/cops/structural/query_method_reaches_write/write_chain_offense.rb (2 survived): return_nil 1, condition_true 1
  • lib/os_sdlc/cops/structural/format_validation_raising_in_initialize/derived_params.rb (2 survived): condition_true 2
  • lib/os_sdlc/cops/structural/reach_through_chain/holdings.rb (2 survived): condition_true 2
  • lib/os_sdlc/cops/structural/unused_private_method/superclass_calls.rb (2 survived): condition_true 1, condition_false 1
  • lib/os_sdlc/cops/structural/effect_reach.rb (2 survived): boolean_literal 1, condition_true 1
  • lib/os_sdlc/cops/structural/rescue_site/rest_arguments.rb (2 survived): return_nil 1, condition_true 1
  • lib/os_sdlc/cops/structural/reach_through_chain/members.rb (2 survived): condition_true 2
  • lib/os_sdlc/cops/structural/array_literal_of_locals_return.rb (2 survived): condition_false 1, return_nil 1
  • lib/os_sdlc/cops/structural/unreachable_branch_after_guard/statements.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/unreachable_branch_after_guard.rb (1 survived): condition_false 1
  • lib/os_sdlc/cops/structural/unused_private_method/subclass_definition.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/reach_through_chain/chain.rb (1 survived): condition_false 1
  • lib/os_sdlc/cops/structural/raw_file_content_assertion/raw_content_call.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/reach_through_chain/site.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/unused_private_method/superclass_definition.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/same_file_defs.rb (0 survived, 1 uncovered): return_nil 1
  • lib/os_sdlc/cops/structural/resolved_path.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/process_start.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/private_method_defs/visibility_scan/string_value.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/precedence_in_edge/choice.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/simulated_polymorphism/case_dispatch.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/underscored_parameter.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/adapter_built_outside_entry/adapter_constant.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/adapter_scope.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/adapter_scope/method_table.rb (1 survived): condition_false 1
  • lib/os_sdlc/cops/structural/adapter_scope/visibility.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/array_literal_of_locals_return/final_expression.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/boolean_control_parameter/condition_match.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/collaborator_construction_in_initialize.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/discarded_error_code/raise_site.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/domain_effect_in_edge/condition/check.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/domain_effect_in_edge/effect.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/domain_effect_in_edge/facts.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/domain_effect_in_edge/if_site.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/domain_operand_in_edge/if_verdict.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/format_validation_raising_in_initialize.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/format_validation_raising_in_initialize/validation_condition.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/forwarding_class/method_match.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/instance_variable_assumption/ivasgn_conditionality.rb (1 survived): return_nil 1
  • lib/os_sdlc/cops/structural/layer_ledger.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/lifecycle_ivar_behind_attr_reader/attr_declarations.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/lifecycle_ivar_behind_attr_reader/lifecycle_defs/lifecycle_assignments.rb (1 survived): condition_true 1
  • lib/os_sdlc/cops/structural/own_entry_point_spawned_in_test.rb (1 survived): condition_true 1

Reproduce

n/a: the mutants come from a whole pass. Verify with os-sdlc-mutation-pass packet after the packet operator ticket from pass 3 is fixed; before that fix, a packet does not create the tier-2 mutants.

Approach

Run plugins/os-sdlc/references/survivor-loop.md on each file. The --test list of a packet holds every test that .mutineer/pass-coverage.json maps to the source lines, plus every paired test/<lib path>_test.rb. Pass 3 ran with the matrix off, so pass.json has no killed_by field. Kill each survivor with a paired test. Delete dead code (ruling 107). Rule an equivalent mutant with os-sdlc-mutation-rule and a reason that holds for every input. Leave a mutant on a real process call visible (ruling 137). The orchestrator re-runs each packet before it closes the ticket. Do not run a whole pass.

Required work: none beyond the acceptance criteria.

Acceptance criteria

  1. Given a packet over each file listed, with all operators that the whole pass uses, when the packet ends, then it shows 0 unruled survivors and 0 unruled uncovered mutants.
  2. Given a deleted dead-code candidate, when the suite runs, then it is green and no caller of the deleted code remains.

Origin

  • Trigger: whole mutation pass 3, 2026-11-11 (docs/research/mutation-testing/2026-11-11-third-pass/, commit 6f6dfa75b)
  • Improvised this session: none
  • Chain: survivors ← no test kills the mutant ← pass 2 packets did not create tier-2 mutants and left out some files (pass 3 README, "Why 203 pass 2 survivors survive again") ← DESIGN (lib/os_sdlc/mutation_test/pass/packet.rb)
  • Root candidate: none found; searched mutation, survivor, mutant, cops/structural
  • Where: lib/os_sdlc/cops/structural/
  • Session: 2677aa00-1973-4df6-b9c5-e317088f3ea3
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os-plugins-os-sdlc/2677aa00-1973-4df6-b9c5-e317088f3ea3.jsonl

VERDICT: CREATE (ticket-skeptic, 2026-11-11): no open ticket has the same mechanism.

## Problem Whole mutation pass 3 (2026-11-11, main 9a1895a1f) left 94 survivors and 2 uncovered mutants in 57 files under cops/structural. None has a ledger row in `.sdlc/mutation-rulings.tsv`, and none is a known visible mutant (ruling 137). A survivor is a changed behavior that the suite does not see. 55 of these mutants use a tier-2 operator (`condition_true`, `condition_false`, `negation_removal`). 75 also survived pass 2. ## Observed `docs/research/mutation-testing/2026-11-11-third-pass/unruled.tsv` lists each mutant with its ID, line, operator, and tier. Each line below gives the file, its counts, and the operators. - `lib/os_sdlc/cops/structural/query_method_reaches_write/write_chain.rb` (7 survived): statement_removal 3, condition_true 1, boolean_literal 1, condition_false 1, return_nil 1 - `lib/os_sdlc/cops/structural/edge_scope.rb` (5 survived): return_nil 2, condition_false 1, statement_removal 1, boolean_connector 1 - `lib/os_sdlc/cops/structural/precedence_in_edge/candidate.rb` (4 survived): condition_false 1, condition_true 1, return_nil 1, boolean_connector 1 - `lib/os_sdlc/cops/structural/layer_ledger/layer_map.rb` (3 survived): boolean_connector 2, condition_true 1 - `lib/os_sdlc/cops/structural/feature_envy/site.rb` (3 survived): return_nil 2, condition_true 1 - `lib/os_sdlc/cops/structural/effect_reach/walk.rb` (3 survived): statement_removal 1, condition_false 1, return_nil 1 - `lib/os_sdlc/cops/structural/effect_in_model.rb` (3 survived): condition_false 1, statement_removal 1, condition_true 1 - `lib/os_sdlc/cops/structural/domain_operand_in_edge/second_source.rb` (3 survived): condition_true 2, boolean_connector 1 - `lib/os_sdlc/cops/structural/simulated_polymorphism/owned_type.rb` (3 survived): condition_true 2, boolean_literal 1 - `lib/os_sdlc/cops/structural/boolean_control_parameter/def_site.rb` (3 survived): condition_true 1, boolean_literal 1, return_nil 1 - `lib/os_sdlc/cops/structural/adapter_built_outside_entry.rb` (2 survived): condition_false 1, statement_removal 1 - `lib/os_sdlc/cops/structural/own_entry_point_spawned_in_test/script_paths.rb` (2 survived): condition_true 2 - `lib/os_sdlc/cops/structural/layer_ledger/ledger.rb` (1 survived, 1 uncovered): condition_true 1, statement_removal 1 - `lib/os_sdlc/cops/structural/inward_dependency.rb` (2 survived): condition_false 1, statement_removal 1 - `lib/os_sdlc/cops/structural/query_method_reaches_write/write_chain_offense.rb` (2 survived): return_nil 1, condition_true 1 - `lib/os_sdlc/cops/structural/format_validation_raising_in_initialize/derived_params.rb` (2 survived): condition_true 2 - `lib/os_sdlc/cops/structural/reach_through_chain/holdings.rb` (2 survived): condition_true 2 - `lib/os_sdlc/cops/structural/unused_private_method/superclass_calls.rb` (2 survived): condition_true 1, condition_false 1 - `lib/os_sdlc/cops/structural/effect_reach.rb` (2 survived): boolean_literal 1, condition_true 1 - `lib/os_sdlc/cops/structural/rescue_site/rest_arguments.rb` (2 survived): return_nil 1, condition_true 1 - `lib/os_sdlc/cops/structural/reach_through_chain/members.rb` (2 survived): condition_true 2 - `lib/os_sdlc/cops/structural/array_literal_of_locals_return.rb` (2 survived): condition_false 1, return_nil 1 - `lib/os_sdlc/cops/structural/unreachable_branch_after_guard/statements.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/unreachable_branch_after_guard.rb` (1 survived): condition_false 1 - `lib/os_sdlc/cops/structural/unused_private_method/subclass_definition.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/reach_through_chain/chain.rb` (1 survived): condition_false 1 - `lib/os_sdlc/cops/structural/raw_file_content_assertion/raw_content_call.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/reach_through_chain/site.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/unused_private_method/superclass_definition.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/same_file_defs.rb` (0 survived, 1 uncovered): return_nil 1 - `lib/os_sdlc/cops/structural/resolved_path.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/process_start.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/private_method_defs/visibility_scan/string_value.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/precedence_in_edge/choice.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/simulated_polymorphism/case_dispatch.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/underscored_parameter.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/adapter_built_outside_entry/adapter_constant.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/adapter_scope.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/adapter_scope/method_table.rb` (1 survived): condition_false 1 - `lib/os_sdlc/cops/structural/adapter_scope/visibility.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/array_literal_of_locals_return/final_expression.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/boolean_control_parameter/condition_match.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/collaborator_construction_in_initialize.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/discarded_error_code/raise_site.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/domain_effect_in_edge/condition/check.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/domain_effect_in_edge/effect.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/domain_effect_in_edge/facts.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/domain_effect_in_edge/if_site.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/domain_operand_in_edge/if_verdict.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/format_validation_raising_in_initialize.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/format_validation_raising_in_initialize/validation_condition.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/forwarding_class/method_match.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/instance_variable_assumption/ivasgn_conditionality.rb` (1 survived): return_nil 1 - `lib/os_sdlc/cops/structural/layer_ledger.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/lifecycle_ivar_behind_attr_reader/attr_declarations.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/lifecycle_ivar_behind_attr_reader/lifecycle_defs/lifecycle_assignments.rb` (1 survived): condition_true 1 - `lib/os_sdlc/cops/structural/own_entry_point_spawned_in_test.rb` (1 survived): condition_true 1 ## Reproduce n/a: the mutants come from a whole pass. Verify with `os-sdlc-mutation-pass packet` after the packet operator ticket from pass 3 is fixed; before that fix, a packet does not create the tier-2 mutants. ## Approach Run `plugins/os-sdlc/references/survivor-loop.md` on each file. The `--test` list of a packet holds every test that `.mutineer/pass-coverage.json` maps to the source lines, plus every paired `test/<lib path>_test.rb`. Pass 3 ran with the matrix off, so `pass.json` has no `killed_by` field. Kill each survivor with a paired test. Delete dead code (ruling 107). Rule an equivalent mutant with `os-sdlc-mutation-rule` and a reason that holds for every input. Leave a mutant on a real process call visible (ruling 137). The orchestrator re-runs each packet before it closes the ticket. Do not run a whole pass. Required work: none beyond the acceptance criteria. ## Acceptance criteria 1. Given a packet over each file listed, with all operators that the whole pass uses, when the packet ends, then it shows 0 unruled survivors and 0 unruled uncovered mutants. 2. Given a deleted dead-code candidate, when the suite runs, then it is green and no caller of the deleted code remains. ## Origin - Trigger: whole mutation pass 3, 2026-11-11 (`docs/research/mutation-testing/2026-11-11-third-pass/`, commit 6f6dfa75b) - Improvised this session: none - Chain: survivors ← no test kills the mutant ← pass 2 packets did not create tier-2 mutants and left out some files (pass 3 README, "Why 203 pass 2 survivors survive again") ← DESIGN (`lib/os_sdlc/mutation_test/pass/packet.rb`) - Root candidate: none found; searched mutation, survivor, mutant, cops/structural - Where: lib/os_sdlc/cops/structural/ - Session: 2677aa00-1973-4df6-b9c5-e317088f3ea3 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os-plugins-os-sdlc/2677aa00-1973-4df6-b9c5-e317088f3ea3.jsonl VERDICT: CREATE (ticket-skeptic, 2026-11-11): no open ticket has the same mechanism.
Author
Owner

Work started on branch ticket-1703 (survivor loop).

Work started on branch ticket-1703 (survivor loop).
Author
Owner

Resolution

Done: 92 cops/structural survivors and 2 uncovered mutants went to 0: 41 tests in cop test files (ruling 105), dead-code deletions in 11 cop files (ruling 107), 29 equivalent rulings. 8 timeouts are hangs (WriteChain visited-set guard x6, EdgeScope#initialize @root, Choice.in_condition? parent stop).

Evidence: Commit c390a8a5b on ticket-1703. Orchestrator packet re-run: 0 survivors of 1441, unruled 0, 8 timeouts. Full suite 5316 runs, 0 failures. Rubocop clean on 29 changed files. Sonnet review: 2 points; ForwardingClass guard deletion confirmed sound (main code crashes on the same input before the guard, now #1710); a misnamed test renamed. 4 call-counter tests removed by the orchestrator; their memo guards ruled instead.

Follow-ups: #1709 (FormatValidationRaisingInInitialize skips a single-if initialize body), #1710 (ForwardingClass raises on a destructured parameter); both captured with ticket-skeptic VERDICT: CREATE.

## Resolution **Done:** 92 cops/structural survivors and 2 uncovered mutants went to 0: 41 tests in cop test files (ruling 105), dead-code deletions in 11 cop files (ruling 107), 29 equivalent rulings. 8 timeouts are hangs (WriteChain visited-set guard x6, EdgeScope#initialize @root, Choice.in_condition? parent stop). **Evidence:** Commit c390a8a5b on ticket-1703. Orchestrator packet re-run: 0 survivors of 1441, unruled 0, 8 timeouts. Full suite 5316 runs, 0 failures. Rubocop clean on 29 changed files. Sonnet review: 2 points; ForwardingClass guard deletion confirmed sound (main code crashes on the same input before the guard, now #1710); a misnamed test renamed. 4 call-counter tests removed by the orchestrator; their memo guards ruled instead. **Follow-ups:** #1709 (FormatValidationRaisingInInitialize skips a single-if initialize body), #1710 (ForwardingClass raises on a destructured parameter); both captured with ticket-skeptic VERDICT: CREATE. <!-- os-backlog kind: resolution -->
jared closed this issue 2026-11-12 07:56:01 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#1703
No description provided.