LearnNewsExamplesServices
Frontmatter
id12188
titlegh-workflow syncer: fetch full release history so closed-issue bucketing isn''t floored into v8.1.0
stateClosed
labels
bugaiarchitecture
assigneesneo-opus-ada
createdAtMay 30, 2026, 2:51 AM
updatedAtMay 30, 2026, 7:46 AM
githubUrlhttps://github.com/neomjs/neo/issues/12188
authorneo-opus-ada
commentsCount0
parentIssue12186
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 30, 2026, 7:46 AM

gh-workflow syncer: fetch full release history so closed-issue bucketing isn't floored into v8.1.0

Closed v13.0.0/archive-v13-0-0-chunk-14 bugaiarchitecture
neo-opus-ada
neo-opus-ada commented on May 30, 2026, 2:51 AM

Context

Sub of #12186 (full root-cause analysis + investigation provenance there). The portal tickets view buckets 4,133 of 7,263 archived issues (56.9%) into v8.1.0 — a catch-all dump, not a real per-release distribution.

Root cause (grounded against IssueSyncer.mjs:367-369 + ReleaseNotesSyncer.mjs:117-157)

Closed issues with no milestone and no valid oldVersion are bucketed via:

const release = (ReleaseNotesSyncer.sortedReleases || []).find(r => new Date(r.publishedAt) > closed);

sortedReleases is filtered to publishedAt >= syncStartDate (= 2025-01-01) and sorted ascending. For any pre-2025 closed issue, the oldest in-window release (v8.1.0) is the first to satisfy publishedAt > closedAt, so .find() returns it. The true bucket — a pre-floor release — was never a candidate. (No hidden default is involved; :378 correctly routes genuine no-matches to active/Backlog.)

The Fix

Make the bucketing reference list (ReleaseNotesSyncer.sortedReleases, as consumed by issue/PR/Discussion bucketing) contain the full release history rather than only >= syncStartDate. Precedent: IssueSyncer.mjs:528-532 already overrides syncStartDate with a 2017-01-01 clean-slate floor for issue fetching — releases need the symmetric treatment. Cost is trivial (~24 GraphQL pages @ ~1pt for ~1,194 releases). One-time re-sort of release-notes chunks is a regeneratable-cache rebuild (ADR-0004 §1.3/§3.6); release-notes have no archive tier (§2.1), so this is not a sealed-chunk violation.

Lands with #12184 (milestone semver-guard) — see #12184 for the necessary-but-insufficient coupling.

Acceptance Criteria

  • The release list consumed by closed-item bucketing contains the full history, not just >= syncStartDate.
  • After re-sync, archive/issues/ has no v8.1.0 catch-all; pre-2025 closed issues distribute to the release that shipped after they closed.
  • Confirm the syncStartDate floor's other consumers before widening it globally — if the floor also bounds what release-notes content is written to disk (vs. only the in-memory bucketing reference), scope the change to the bucketing consumer or consciously accept the wider fetch. (shared-default cross-consumer caution.)
  • Re-sync regenerates clean buckets (ADR-0004 regeneratable-cache); no garbage/non-semver folders alongside #12184.

Out of Scope

  • The milestone→version semver guard itself (#12184 — lands together).
  • PR/Discussion delta-fetch + query-cost (rate-limit hardening) — #12186 P1.

Related

  • #12186 (epic), #12184 (milestone guard — lands together).
  • Authority: learn/agentos/decisions/0004-github-content-architecture.md.

Retrieval Hint: grep sortedReleases + syncStartDate in ai/services/github-workflow/sync/.

tobiu referenced in commit bb95a80 - "fix(github-workflow): full release history for bucketing + milestone semver guard (#12188) (#12192) on May 30, 2026, 7:46 AM
tobiu closed this issue on May 30, 2026, 7:46 AM
tobiu referenced in commit b9e2d48 - "feat(github-workflow): one-time non-destructive archive re-bucket migration (#12194) (#12196) on May 30, 2026, 3:06 PM