feat(signals): wire burden forecast through intelligence + MCP with freshness - #61
Merged
Merged
Conversation
added 4 commits
May 29, 2026 11:06
New getBurdenForecast reader on the existing burden_forecasts table plus a services/burden-forecast loader that returns an envelope with generatedAt, ageSeconds, and a freshness marker (fresh | stale, 6h window). Falls back to a computed forecast for known repos that have no cached snapshot yet, so callers see actionable data on first hit without waiting for the scheduled job.
…onse buildRepoIntelligenceResponse now attaches the cached burden forecast plus a burdenForecastFreshness slice (source, generatedAt, ageSeconds, freshness) to both the snapshot and computed branches. Reads from the dedicated burden_forecasts table, so request-time scans are limited to the indexed PK lookup.
Returns the cached or freshly-computed burden forecast for a repo along with its freshness marker so MCP consumers can decide whether to retry once the next scheduled rebuild lands. Falls back to a not_found payload when the repo is unknown.
- Builder fixtures: small clean queue, ragflow/sure-scale critical queue, duplicate-cluster trend, stale PR trend. - Service fixtures: snapshot freshness fresh/stale, computed fallback for known but uncached repos, broad-lister spy regression so the cached path never triggers request-time scans. - Queue.test.ts now asserts a burden forecast row was persisted after the build-burden-forecasts job. - api.test.ts asserts the intelligence response includes the cached forecast plus its freshness slice, and that the MCP tool round-trips through cache + missing-repo branches.
Contributor
Author
|
@JSONbored please review the PR when you have a chance and let me know your feedback. |
Contributor
Author
|
thank you for your review! |
jony376
pushed a commit
to jony376/gittensory
that referenced
this pull request
May 31, 2026
…reshness (JSONbored#61) * feat(signals): add burden forecast reader and cache-or-compute helper New getBurdenForecast reader on the existing burden_forecasts table plus a services/burden-forecast loader that returns an envelope with generatedAt, ageSeconds, and a freshness marker (fresh | stale, 6h window). Falls back to a computed forecast for known repos that have no cached snapshot yet, so callers see actionable data on first hit without waiting for the scheduled job. * feat(intelligence): include burden forecast in repo intelligence response buildRepoIntelligenceResponse now attaches the cached burden forecast plus a burdenForecastFreshness slice (source, generatedAt, ageSeconds, freshness) to both the snapshot and computed branches. Reads from the dedicated burden_forecasts table, so request-time scans are limited to the indexed PK lookup. * feat(mcp): add gittensory_get_burden_forecast tool Returns the cached or freshly-computed burden forecast for a repo along with its freshness marker so MCP consumers can decide whether to retry once the next scheduled rebuild lands. Falls back to a not_found payload when the repo is unknown. * test(signals): cover burden forecast fixtures and wiring - Builder fixtures: small clean queue, ragflow/sure-scale critical queue, duplicate-cluster trend, stale PR trend. - Service fixtures: snapshot freshness fresh/stale, computed fallback for known but uncached repos, broad-lister spy regression so the cached path never triggers request-time scans. - Queue.test.ts now asserts a burden forecast row was persisted after the build-burden-forecasts job. - api.test.ts asserts the intelligence response includes the cached forecast plus its freshness slice, and that the MCP tool round-trips through cache + missing-repo branches. * fix(signals): tighten burden forecast contract --------- Co-authored-by: mkdev11 <MkDev11@users.noreply.github.com>
24 tasks
This was referenced Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #22.
Summary
getBurdenForecastreader on the existingburden_forecaststable (src/db/repositories.ts).loadOrComputeBurdenForecastResponse(src/services/burden-forecast.ts) returns an envelope withgeneratedAt,ageSeconds, and afreshness: \"fresh\" | \"stale\"marker (6 h window matchingDECISION_PACK_MAX_AGE_MS). Falls back to a computed forecast for known repos that have no cached snapshot yet, so callers see actionable data on first hit.buildRepoIntelligenceResponse(src/api/routes.ts) attachesburdenForecast+ aburdenForecastFreshnessslice (source, generatedAt, ageSeconds, freshness) to both snapshot and computed branches. Reads from the dedicated PK-indexed table, so request-time scans stay bounded.gittensory_get_burden_forecast(src/mcp/server.ts) for parity with the private intelligence surface; returnsnot_foundfor unknown repos.Acceptance criteria → coverage
level: \"critical\"and runs in unit-test time.forecast.duplicateTrendandfindings[*].codeforqueue_growth_risk+stale_review_load; the existing builder also emitsfinding.actionfor cleanup hints.burdenForecast+burdenForecastFreshness: { source: \"snapshot\", freshness: \"stale\", ageSeconds: > 0 }when the cached row is older than 6 h.listIssueSignalSample,listOpenPullRequests, andlistRecentMergedPullRequestsare NOT called when a cached forecast exists.Validation
npm run typechecknpx vitest run test/unit test/integration— 352 tests passnpx vitest run --coverage— branches at 95.07% (over the 95% gate)Safety
burden_forecaststable; no migrationOpen questions for review
GET /v1/repos/:owner/:repo/burden-forecasthandler —test/unit/openapi.test.tskeeps the path on the "removed" list, matching the project pattern of exposing repo signals via the/intelligenceaggregator + MCP tools rather than dedicated GET endpoints. Happy to add it if you'd rather expose it separately.DECISION_PACK_MAX_AGE_MS. Open to a different value.burden_forecaststable (one row per repo, primary-key access). Could move tosignal_snapshotsfor consistency with other signals, but that's a refactor beyond this PR's scope.Relationship to other in-flight work