Skip to content

miner: record feasibility-verdict reasons as rule-fired signals on attempt's infeasible path #8543

Description

@JSONbored

Problem

AMS's calibration capture is one-sided: the four eligibility-exclusion reasons are recorded as rule-fired signals on discovery (recordEligibilityExclusionSignals, packages/loopover-miner/lib/discover-cli.ts), but the feasibility verdict — the other deterministic gate an attempt passes through — records nothing. In packages/loopover-miner/lib/attempt-cli.ts, when buildCodingTaskSpec returns ready: false (the branch that appends an attempt_aborted attempt-log event and an attempt_blocked ledger event with reason `infeasible_${verdict}`), the verdict's reasons (codingTaskSpec.feasibility.avoidReasons / raiseReasons — values like claim_status_solved, issue_quality_do_not_use, duplicate_cluster_high, target_not_found, claim_status_claimed) are printed and dropped. Epic #8107 needs these captured so feasibility rules can be precision-scored the same way eligibility exclusions already can be.

Requirements

⚠️ The capture must go through createSignalTrackingStore (packages/loopover-miner/lib/signal-tracking-store.ts) so events land in the canonical signal_rule_fired shape. This issue is NOT satisfied by: writing custom event types directly via eventLedger.appendEvent, adding capture inside coding-task-spec.ts or packages/loopover-engine/src/feasibility.ts (both are pure modules and must stay side-effect free), or capturing anything on the ready: true path.

  • In attempt-cli.ts, inside the existing if (!codingTaskSpec.ready) branch only: record one RuleFiredEvent per entry of codingTaskSpec.feasibility.avoidReasons and per entry of raiseReasons, with exactly: ruleId = the reason string verbatim; outcome = "avoid" for avoid-reason entries and "raise" for raise-reason entries; targetKey = `${parsed.repoFullName}#issue-${parsed.issueNumber}` (byte-identical to recordEligibilityExclusionSignals' format); occurredAt = ISO timestamp; no metadata (raw-context capture is a separate issue — do not add it here).
  • Store acquisition mirrors discover-cli.ts exactly: an optional initSignalTrackingStore?: () => SignalStore seam on the attempt CLI's options (same name as discover's seam), defaulting to createSignalTrackingStore({ appendEvent, readEvents }) over the shared local event ledger.
  • Best-effort discipline, mirrored verbatim from recordEligibilityExclusionSignals: store-init failure and each individual write failure are swallowed (try/catch around init, .catch(() => undefined) per write) and must not change the CLI's console output, JSON result shape, or exit code (the branch still returns 4).
  • Every ready: false occurrence records — no dedup across repeated attempts at the same issue; each attempt is a distinct decision instance.
  • Tests, all Codecov-visible (follow the test(miner): mirror shouldReenter under root vitest for Codecov (#8347) #8479 root-vitest mirror precedent if the package-native runner's coverage is not what Codecov measures):
    • ready: false with both avoid and raise reasons present → exact ruleId/outcome/targetKey asserted per event, counts match the reason arrays.
    • ready: true → zero fired events recorded.
    • initSignalTrackingStore throwing, and a store whose recordRuleFired rejects → exit code, console output, and JSON result identical to a run without the seam.
    • 100% of changed lines and branches covered — both arms of every conditional introduced.

Deliverables

  • Capture wired in attempt-cli.ts's infeasible branch per the exact event shape above
  • initSignalTrackingStore seam with the discover-identical default
  • Tests covering the four cases above, Codecov-visible

Links & Resources

Boundaries

attempt-cli.ts + tests only. No pure-module changes, no override capture, no metadata, no output-format changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.help wantedExtra attention is needed

    Projects

    Status
    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions