Skip to content

Track real per-issue attempt-history on the portfolio queue, feed the Governor's convergenceInput #5654

Description

@JSONbored

Context

buildAttemptGovernorContext (packages/gittensory-miner/lib/attempt-input-builder.js) hardcodes convergenceInput: { attempts: 0, consecutiveFailures: 0, reenqueues: 0, reachedDone: false } on every single call — a documented, intentional placeholder (see the file's own "KNOWN, DOCUMENTED GAPS" header) because attempt-log.js's schema has no repo+issue index and the portfolio-queue table tracks no attempt-history columns. packages/gittensory-engine/src/portfolio/non-convergence.ts — the pure detector this data is FOR — already exists, is fully typed and tested, and explicitly says the queue table needs to grow attempt-history columns; it just has no real data flowing into it today. This literal always under-estimates (reads "fresh, no prior failures" even on a real Nth attempt), which fails toward LETTING an attempt through rather than blocking one — not unsafe today, but it means the non-convergence detector has never actually detected anything real.

Dependencies

None — independently shippable. Does not touch non-convergence.ts's own classifier/thresholds or the Governor chokepoint's decision logic (governor-chokepoint.ts/governor-chokepoint-persisted.js, #5134) — this is purely about producing a REAL PortfolioConvergenceInput to feed the ALREADY-EXISTING detector, not changing what the detector does with it.

Requirements

  1. Add attempt-history columns to miner_portfolio_queue (packages/gittensory-miner/lib/portfolio-queue.js): an attempts counter, a consecutive-failures counter, and a reenqueue counter — nullable/defaulted so this is a normal additive schema migration (mirror the file's own established applySchemaMigrations per-column-presence-check idiom already used for leased_at).
  2. Increment the attempts counter on claim (claimNext/claimBatch).
  3. Increment the reenqueue counter on every transition FROM in_progress back TO queued without reaching done (requeueItem, and the stuck-item-reclaim sweep) — exactly the "cycling queued -> in_progress -> queued without ever reaching done" behavior non-convergence.ts's own header names as the reenqueue trigger.
  4. Track consecutive failures: increment on a requeue/reclaim (an attempt that did not reach done), reset to 0 on markDone.
  5. reachedDone is simply status === 'done' — no new column needed for that one.
  6. Add a read function (e.g. getAttemptHistory(repoFullName, identifier, apiBaseUrl)) returning a real PortfolioConvergenceInput-shaped object.
  7. Wire buildAttemptGovernorContext to call it instead of the hardcoded literal — attempt-input-builder.js stays pure itself (per its own header discipline), so the real portfolio-queue read happens in the caller (attempt-cli.js) and gets passed in, matching how every other already-computed dependency reaches this composer today.
  8. Out of scope: changing non-convergence.ts's thresholds, or anything about reputationHistory/selfPlagiarismCandidate (the file's OTHER documented, still-open gap) — that's a separate concern this issue does not touch.

Deliverables / Acceptance Criteria

  • miner_portfolio_queue gains real attempt-history columns via a normal additive migration
  • Attempts/reenqueues/consecutive-failures counters update correctly on claim/requeue/reclaim/done
  • A real read function returns a genuine PortfolioConvergenceInput
  • buildAttemptGovernorContext receives and forwards the real data instead of the hardcoded literal
  • non-convergence.ts's classifier itself is untouched

Test Coverage Requirements

This PR must ship with full test coverage for every changed line and branch — the repo's Codecov patch gate requires 99%+ coverage and the house standard is to aim for 100%, including both sides of every conditional/nullish-coalescing branch introduced. Required: (1) schema-migration tests for a pre-existing on-disk file missing the new columns (mirrors portfolio-queue.js's own leased_at migration test pattern); (2) counter-correctness tests across claim -> requeue -> reclaim -> done sequences, including a REGRESSION test proving a genuinely non-convergent item (repeated requeue without ever reaching done) now produces a PortfolioConvergenceInput that evaluateNonConvergence classifies as non_convergent — the first real exercise of that detector; (3) an invariant test that reachedDone only ever reflects status === 'done', never fabricated.

Expected Outcome

The Governor's non-convergence detector — fully built since Wave 3, never fed real data — starts actually detecting stuck items instead of always reading "fresh." Also closes a real gap Wave 5's multi-tenant scale will need (a customer's stuck/looping task should be caught, not silently retried forever on their compute budget).

Links & Resources

  • packages/gittensory-miner/lib/attempt-input-builder.js (the hardcoded literal + its own gap comment)
  • packages/gittensory-miner/lib/portfolio-queue.js (schema + claim/requeue/reclaim/done functions)
  • packages/gittensory-engine/src/portfolio/non-convergence.ts (the existing pure detector this feeds)
  • Theme: AMS hardening / Wave 5 prerequisite

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.gittensor:priorityMaintainer-selected Gittensor priority — scores a 1.5x multiplier.

    Projects

    Status
    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions