Skip to content

fix(issueReporter): stabilize auto-issue dedup and cooldown logic#405

Open
shaun0927 wants to merge 1 commit intoEvoMap:mainfrom
shaun0927:fix/issuereporter-dedup-cooldown
Open

fix(issueReporter): stabilize auto-issue dedup and cooldown logic#405
shaun0927 wants to merge 1 commit intoEvoMap:mainfrom
shaun0927:fix/issuereporter-dedup-cooldown

Conversation

@shaun0927
Copy link
Copy Markdown

Problem

Four interacting bugs in src/gep/issueReporter.js combine to defeat the
module's own purpose. The symptoms are already visible on this tracker:
issues #395, #396, #397, and #404 are identical auto-filed duplicates
that the reporter was supposed to suppress.

  1. computeErrorKey hashes the occurrence count. It feeds signals
    like recurring_errsig(3x):timeout in API call and
    recurring_errsig(4x):timeout in API call verbatim into SHA-256, so
    the same underlying error produces a different key every emission.
    recentIssueKeys.includes(errorKey) can never match.

  2. shouldReport bypasses the minStreak gate when the streak
    signal is absent.
    extractStreakCount returns 0 when no
    consecutive_failure_streak_N signal is present, and the
    streakCount > 0 && streakCount < minStreak guard short-circuits.
    Users who raise EVOLVER_ISSUE_MIN_STREAK still get early reports.

  3. maybeReportIssue resets lastReportedAt on the skip branch.
    When findExistingIssue returns an existing open issue, the code
    logs "skipping duplicate" but still writes
    lastReportedAt: new Date().toISOString(). The cooldown check then
    sees a freshly-bumped timestamp, so as long as the existing open
    issue stays open, no re-report is ever possible.

  4. findExistingIssue substring fallback matches unrelated
    titles.
    The fallback it.title.indexOf(titleSig) !== -1 matches
    any title that merely contains the signature as a substring.

computeErrorKey, extractStreakCount, and extractErrorSignature
were not exported, which is how all three bugs in category (1)–(3)
shipped without test coverage.

Fix

  • Normalize the recurring_errsig(Nx): prefix inside computeErrorKey
    (uses the same regex that extractErrorSignature already uses).
  • Drop the > 0 precondition from the minStreak gate.
  • Preserve the prior lastReportedAt on the skip branch; only
    lastSkippedAt and recentIssueKeys are updated.
  • Replace the substring fallback with a prefix check that requires
    both the auto-issue prefix and the same signature.
  • Export the three helpers so the regressions can be covered.

Testing

$ node test/issueReporter.test.js

Against main with the new test cases (added in this PR):

TypeError: computeErrorKey is not a function
    at run (/.../test/issueReporter.test.js:84:14)

With this PR applied:

issueReporter.test.js: OK

The three new test cases cover:

  • computeErrorKey is stable across (3x), (4x), (5x) prefixes.
  • shouldReport(minStreak=5) returns false when the streak signal is
    missing, and true when the streak meets the minimum.
  • findExistingIssue does not match a title that contains the search
    signature as an unrelated substring.

Scope

  • src/gep/issueReporter.js — 4 focused edits, no behaviour change
    outside the bug paths; module exports gain three helpers (additive).
  • test/issueReporter.test.js — three new cases.

No changes to obfuscated modules. No config changes. No new
dependencies.

Follow-ups (not in this PR)

  • DEFAULT_REPO = 'autogame-17/capability-evolver' legacy handle —
    separate issue.
  • sanitize.js pattern gaps (Slack, JWT, Azure, Discord) — separate
    issue.

…cooldown on skip, tighten existing-issue match

Four interacting bugs in the auto-issue reporter combined to defeat its
own purpose. Symptoms are already visible on this tracker: issues EvoMap#395,
EvoMap#396, EvoMap#397, and EvoMap#404 carry identical auto-titles because the reporter
cannot detect that it just filed the same thing.

1. computeErrorKey hashed the occurrence count.
   recurring_errsig(3x):… and recurring_errsig(4x):… produced different
   SHA-256 keys, so recentIssueKeys.includes() never matched and dedup
   was effectively off. The key is now normalized via the same regex
   already used in extractErrorSignature.

2. shouldReport bypassed the minStreak gate when the streak signal was
   absent. extractStreakCount returns 0 when no
   consecutive_failure_streak_N is present, and the old
   'streakCount > 0 && streakCount < minStreak' guard did not fire.
   Callers who raised EVOLVER_ISSUE_MIN_STREAK still got early reports.
   The '> 0' precondition is removed.

3. maybeReportIssue rewrote lastReportedAt on the 'skip duplicate'
   branch even though no new issue was filed. This kept resetting the
   cooldown clock every cycle, so while the existing open issue stayed
   open, no re-report was ever possible. The skip branch now preserves
   the prior lastReportedAt and only updates lastSkippedAt.

4. findExistingIssue matched unrelated titles via a loose substring
   fallback (it.title.indexOf(titleSig) !== -1). It now requires the
   candidate title to begin with the known auto-issue prefix and start
   with the same signature.

computeErrorKey, extractStreakCount, and extractErrorSignature are
exported so the regressions can be covered by unit tests. Three new
cases in test/issueReporter.test.js exercise the three behaviours.

Verification:
  node test/issueReporter.test.js
  # before: TypeError: computeErrorKey is not a function
  # after:  issueReporter.test.js: OK
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