Skip to content

Rectify: Merge Gate Diagnosis Context Loss#3893

Merged
Trecek merged 6 commits into
developfrom
diagnose-merge-gate-returns-misleading-failure-subtype-unkno/3890
Jun 8, 2026
Merged

Rectify: Merge Gate Diagnosis Context Loss#3893
Trecek merged 6 commits into
developfrom
diagnose-merge-gate-returns-misleading-failure-subtype-unkno/3890

Conversation

@Trecek

@Trecek Trecek commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

diagnose_merge_gate classifies failure subtype from test output strings alone, with no knowledge of which merge_worktree failure step triggered the diagnosis. When called after a dirty_tree failure (where no tests ran), it receives empty strings, falls through to failure_subtype = unknown, and hardcodes failure_type = test. This misleads resolve-failures into treating a worktree-hygiene problem as a flaky test, creating an unwinnable loop.

The architectural weakness: the recipe routing layer consumes failed_step for branching but never captures it into context, so downstream classification functions must re-derive failure category from output content — an inherently lossy operation when some failure modes produce no output.

The immunity approach: make diagnose_merge_gate accept the failure step as a typed parameter, capture it in recipe context, add a semantic rule to enforce capture, and use exhaustive dispatch so that pre-test failures are correctly classified without consulting empty test output.

Implementation Plan

Plan file: /home/talon/projects/autoskillit-runs/remediation-20260607-163912-937216/.autoskillit/temp/rectify/rectify_merge_gate_diagnosis_context_loss_2026-06-07_164500.md

Closes #3890

🤖 Generated with Claude Code via AutoSkillit

Token Usage Summary

Step Model count uncached output cache_read peak_ctx turns cache_write time
rectify* opus[1m] 1 63 19.4k 1.3M 105.0k 41 82.8k 18m 55s
review_approach* sonnet 1 62 9.7k 258.1k 59.5k 19 43.5k 9m 38s
dry_walkthrough* opus 1 40 11.9k 1.1M 140.1k 48 187.3k 7m 10s
audit_impl* sonnet 1 68 18.3k 297.2k 49.3k 25 47.2k 5m 58s
prepare_pr* MiniMax-M3 1 43.2k 3.6k 209.5k 47.3k 15 0 1m 16s
compose_pr* MiniMax-M3 1 41.4k 1.6k 233.5k 43.5k 17 0 51s
review_pr* sonnet 1 156 32.3k 1.1M 92.0k 47 71.2k 7m 57s
resolve_review* opus[1m] 1 37 5.2k 1.0M 59.3k 32 37.3k 5m 43s
Total 85.0k 101.9k 5.6M 140.1k 469.3k 57m 29s

* Step used a non-Anthropic provider; caching behavior may differ.

Token Efficiency

Step LoC Changed cache_read/LoC cache_write/LoC output/LoC
rectify 0
review_approach 0
dry_walkthrough 0
audit_impl 0
prepare_pr 0
compose_pr 0
review_pr 0
resolve_review 4 255834.5 9323.5 1304.8
Total 4 1393641.0 117330.2 25478.2

Model Usage Breakdown

Model steps uncached output cache_read cache_write time
opus[1m] 2 100 24.6k 2.4M 120.1k 24m 38s
sonnet 3 286 60.3k 1.7M 161.9k 23m 34s
opus 1 40 11.9k 1.1M 187.3k 7m 10s
MiniMax-M3 2 84.5k 5.2k 443.0k 0 2m 6s

Trecek and others added 6 commits June 7, 2026 17:25
Previously diagnose_merge_gate fell through to failure_subtype=unknown and
hardcoded failure_type=test when called with empty test output, which
misclassified pre-test failures (dirty_tree, rebase, etc.) as test
failures and created an unwinnable flake-suspected retry loop.

- Add failed_step parameter to diagnose_merge_gate signature.
- Add exhaustive dispatch on _PRE_TEST_STEPS / _TEST_STEPS / backward
  compat branches.
- Rename _classify_subtype to _classify_test_subtype with early-return
  for empty input.
- Change hardcoded "failure_type = test" literal to f-string
  interpolation; emit failure_type in Structured Output section.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Update the three pipeline recipes (remediation, implementation,
implementation-groups) to capture result.failed_step on the merge
step and pass it through to diagnose_merge_gate. The diagnose_merge_gate
run_python call now receives failed_step from context, and the field is
added to optional_context_refs so it is not required at the iteration
boundary.

Also add failed_step to the diagnose_merge_gate callable contract in
skill_contracts.yaml so the rules_callable_inputs validation accepts
recipe with: blocks that pass it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a new semantic rule that fires when a merge_worktree step routes on
result.failed_step to a chain reaching diagnose_merge_gate, but the
merge_worktree capture block does not include result.failed_step. Without
this capture, diagnose_merge_gate receives no failed_step argument and
falls back to failure_type=test, misclassifying pre-test failures
(dirty_tree, rebase, etc.) as test failures and creating an unwinnable
retry loop.

The rule uses BFS from each route target to find the diagnose_merge_gate
step (parallel to the existing _find_resolve_failures_step helper), then
checks the merge_worktree capture block for any field whose from_
references failed_step.

Add tests covering: rule fires when capture is missing, rule does not
fire when capture is present, and rule does not fire on the three
fixed pipeline recipes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Update pre-compiled JSON for remediation, implementation, and
implementation-groups recipes to match the YAML source after adding
merge_failed_step capture and failed_step input to diagnose_merge_gate.

Generated by `task regen-contracts && task compile-recipes`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ed_step capture

The merge-failed-step-not-captured rule's BFS traversed through
intermediate merge_worktree steps that already capture result.failed_step,
causing false positives on pre_remediation_merge which routes through
the main merge step (that independently provides context).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When failed_step is non-empty but not in _PRE_TEST_STEPS or _TEST_STEPS,
emit subtype="unrecognized_step" instead of silently falling through to
content-based test classification. This prevents upstream coding errors
or newly added steps from being mislabeled as test failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Trecek Trecek added this pull request to the merge queue Jun 8, 2026
Merged via the queue into develop with commit 660e1c5 Jun 8, 2026
3 checks passed
@Trecek Trecek deleted the diagnose-merge-gate-returns-misleading-failure-subtype-unkno/3890 branch June 8, 2026 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant