Context
ADR-0004 §2.2.1 (amended via #15354 / PR #15451) now states the precondition: an ordinal is only meaningful against COMPLETE membership — a partial collection yields a different ordinal, not an approximate one, producing valid-looking duplicate artifacts in plausible chunks (the #15130 / #15319 damage: 2,015 stale index entries, 27 divergent duplicates).
#15354's AC-5 audit (verified against the code, recorded on #15354) found two of three syncers do NOT satisfy the precondition. This is that named follow-up.
The Problem
DiscussionSyncer#planBuckets(metadata, fetchedDiscussions) (ai/services/github-workflow/sync/DiscussionSyncer.mjs:105) builds combined from metadata.discussions + the delta fetchedDiscussions, then buckets + computes itemIndex (the ordinal) against it. No contentInventory.
IssueSyncer#planBuckets(metadata, fetchedIssues) (ai/services/github-workflow/sync/IssueSyncer.mjs:385) builds combined from metadata.issues + fetchedIssues; called at 5 sites including [] and [issue] (metadata-only / single-item — definitionally partial). Uses contentIndex.mjs, never contentInventory.mjs.
Both compute placement from partial membership by construction and are structurally free to reproduce the duplicate-artifact defect on the next sync that lands an item whose complete-membership ordinal differs from the partial one.
The Fix
Adopt complete membership in both #planBuckets paths, mirroring #15319's PullRequestSyncer repair: read the complete on-disk corpus via buildContentInventory (ai/services/github-workflow/shared/contentInventory.mjs — active tier + every archive bucket, recursive) as the ordering source, instead of metadata.{type} + the delta fetch.
Acceptance Criteria
Out of Scope
- Re-opening ordinal-100 / sealed chunks / §1.3 (ADR-0004 unchanged beyond the §2.2.1 precondition).
ReleaseNotesSyncer (no archive tier; assess separately if it plans chunks).
Refs #15354, #15319, #15130. Governing design: ADR-0004 §2.2.1 (PR #15451).
Authored by Grace (Claude Opus 4.8, Claude Code) — the named follow-up per #15354 AC-5.
Context
ADR-0004 §2.2.1 (amended via #15354 / PR #15451) now states the precondition: an ordinal is only meaningful against COMPLETE membership — a partial collection yields a different ordinal, not an approximate one, producing valid-looking duplicate artifacts in plausible chunks (the #15130 / #15319 damage: 2,015 stale index entries, 27 divergent duplicates).
#15354's AC-5 audit (verified against the code, recorded on #15354) found two of three syncers do NOT satisfy the precondition. This is that named follow-up.
The Problem
DiscussionSyncer#planBuckets(metadata, fetchedDiscussions)(ai/services/github-workflow/sync/DiscussionSyncer.mjs:105) buildscombinedfrommetadata.discussions+ the deltafetchedDiscussions, then buckets + computesitemIndex(the ordinal) against it. NocontentInventory.IssueSyncer#planBuckets(metadata, fetchedIssues)(ai/services/github-workflow/sync/IssueSyncer.mjs:385) buildscombinedfrommetadata.issues+fetchedIssues; called at 5 sites including[]and[issue](metadata-only / single-item — definitionally partial). UsescontentIndex.mjs, nevercontentInventory.mjs.Both compute placement from partial membership by construction and are structurally free to reproduce the duplicate-artifact defect on the next sync that lands an item whose complete-membership ordinal differs from the partial one.
The Fix
Adopt complete membership in both
#planBucketspaths, mirroring #15319's PullRequestSyncer repair: read the complete on-disk corpus viabuildContentInventory(ai/services/github-workflow/shared/contentInventory.mjs— active tier + every archive bucket, recursive) as the ordering source, instead ofmetadata.{type}+ the delta fetch.Acceptance Criteria
IssueSyncerordinal placement reads complete membership (viabuildContentInventoryor an equivalent full-corpus scan), notmetadata.issues+ delta.DiscussionSyncerordinal placement reads complete membership, notmetadata.discussions+ delta.Out of Scope
ReleaseNotesSyncer(no archive tier; assess separately if it plans chunks).Refs #15354, #15319, #15130. Governing design: ADR-0004 §2.2.1 (PR #15451).
Authored by Grace (Claude Opus 4.8, Claude Code) — the named follow-up per #15354 AC-5.