Skip to content

feat(darwin/repro): non-gating symptom-binding signal for conformant repros (ADR-175 §63, #47)#122

Merged
ruvnet merged 1 commit into
mainfrom
feat/repro-symptom-binding
Jul 7, 2026
Merged

feat(darwin/repro): non-gating symptom-binding signal for conformant repros (ADR-175 §63, #47)#122
ruvnet merged 1 commit into
mainfrom
feat/repro-symptom-binding

Conversation

@ruvnet

@ruvnet ruvnet commented Jul 7, 2026

Copy link
Copy Markdown
Owner

What / why

Addresses the concrete, unbuilt technical follow-up named in ADR-175 §63 and raised by downstream feedback in #47 (from ruvnet/ruflo): Conformant repair's Goodhart trap. In oracle-OFF mode the agent's self-written reproduce_bug.py is the contract, so it can fail for a narrower/friendlier/unrelated reason than the ticket demands — a "fix-shaped artifact" that passes a fake test.

test-critic already closes the coarse slice (an Import/Syntax/collection error is classified error, not a valid repro — only a real raised assertion/exception counts). The remaining §63 ask — "assert the issue's specific symptom" — lands here as a measurement, not a gate.

Change

  • New pure export symptomBindingScore(problemStatement, repro, logTail):
    • +0.5 when the failure trace raises an exception type the issue names (boundExceptionType)
    • +0.5 × the fraction of (≤3) salient issue identifiers the repro references
    • assessable:false / score:null when the issue names neither — no fabricated confidence
    • stopword-filtered identifiers; conservative by design (noise only weakens a non-gating score)
  • Plumbed through buildReproTestreproGateSolverow.symptomBinding in the run report — all one-line, non-behavioral passthroughs. valid/invalid, reproPassed, and the resolve path are unchanged.

Why non-gating (deliberate)

Hard-rejecting low-binding repros would risk lowering the load-bearing conformant resolve (55.6% Verified, 51.3% Lite). The responsible order is: ship the measurement a live A/B on the frozen holdout can act on, then decide whether a gate is safe — not a blind gate. meetsPromotionRule and all scoring are untouched.

Tests

  • 7 tests (test-critic.test.mjs, node-script style — $0, no Docker/LLM): exception-type binding, non-binding when the trace's exception differs, not-assessable, stopword filtering, the ≤3 identifier cap + fraction scoring, and the non-gating passthrough through reproGateSolve (incl. the undefined-when-no-signal case).
  • Wired into the CI node-test list (ci.yml); existing repro-gate.test.mjs still green.
  • ADR-175 §63 updated to record the signal + the deferred-gating rationale.

🤖 Generated with claude-flow

…repros (ADR-175 §63, #47)

Downstream feedback (#47, from ruflo) flags Conformant repair's Goodhart trap: the agent's
self-written reproduce_bug.py IS the contract, so it can fail for a friendlier/unrelated reason than
the ticket demands. test-critic already rejects error-phase failures (Import/Syntax/collection) — only
a real raised assertion/exception counts as valid. The remaining ADR-175 §63 follow-up ("assert the
issue's SPECIFIC symptom") is implemented here as a MEASUREMENT, not a gate:

  symptomBindingScore(problemStatement, repro, logTail) → { assessable, score∈[0,1],
    boundExceptionType, matchedExceptions, matchedIdentifiers, ... }

  +0.5 when the failure trace raises an exception TYPE the issue names; +0.5 × the fraction of (≤3)
  salient issue identifiers the repro references; assessable=false (score null) when the issue names
  neither — no fabricated confidence.

Deliberately NON-GATING: hard-rejecting low-binding repros would risk lowering the load-bearing
conformant resolve (55.6% Verified), so we ship the signal a live A/B can act on, not a blind gate.
Plumbed through buildReproTest → reproGateSolve → row.symptomBinding in the run report (all one-line,
non-behavioral passthroughs; valid/invalid and the resolve path are unchanged).

7 tests (node-script style; $0, no Docker/LLM) wired into the CI node-test list. ADR-175 §63 updated
to record the signal + the deferred-gating rationale.

Co-Authored-By: claude-flow <ruv@ruv.net>
@ruvnet ruvnet merged commit cb3f4c7 into main Jul 7, 2026
25 checks passed
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