Context
@tobiu asked whether PR #15319 (+2,248/-118, repairing PR-archive index drift and divergent duplicate artifacts) was ADR territory. It is not — ADR-0004 already governs resources/content/, the new contentInventory.mjs anchors to it (@see learn/agentos/decisions/0004-github-content-architecture.md), and the PR implements its contract rather than changing it. No new authority, no new namespace, no public API change; 55% of that diff is tests.
But the investigation surfaced a real omission in ADR-0004, and it is the root cause the PR repairs rather than removes. Filing at @tobiu's explicit request (2026-07-17), ahead of the usual post-release substrate batch.
Live sweep at file time: latest open issues plus targeted ADR-0004 / ordinal / chunk / contentInventory searches. No equivalent issue exists. Governing-design sweep: ADR-0004 read in full; §1.3, §2 checked for an existing statement of this invariant — absent.
The Problem
ADR-0004 mandates universal ordinal-100 chunking and seals archive chunks. It never states the precondition that makes an ordinal computable:
An ordinal is only meaningful against complete membership.
The syncers plan placement from metadata.{type} plus the current delta fetch. Both are partial by design — the delta sync rebuilds its cache from each run's fetch. A planner reading only those computes an ordinal against a fraction of a bucket. From #15319's contentInventory.mjs, which is the clearest statement of the mechanism:
"An ordinal derived from a partial collection is not a smaller truth, it is a different number: the item lands in a chunk that the complete ordering would never have chosen, beside the copy that is already there. The corpus on disk is the only complete membership that exists, because the files outlive every cache that describes them."
That is how 2,015 stale index entries and 27 divergent duplicate artifacts happened. Not a bug in the ADR's design — a precondition the ADR assumes and does not write down, so every syncer author is free to satisfy it or not, and the failure is silent: a wrong ordinal produces a valid-looking artifact in a plausible chunk.
The Architectural Reality
- ADR-0004 §1.3 is load-bearing and correct:
resources/content/ is a fully-regeneratable cache; GitHub is the source of truth; sync_all is the canonical path back to clean. Nothing here disturbs that.
- The gap is in the chunking contract (§2), not the strategic principle (§1.3). §1.3 tells you how to recover; it does not tell you what a planner must read to place an item correctly in the first place.
- PR #15319 fixes the PR syncer only.
contentInventory.mjs exists precisely to supply complete membership (a full scan of both tiers, per type, per sync — the PR names that cost explicitly and takes it). IssueSyncer and DiscussionSyncer are unexamined against this invariant and are structurally free to repeat it, because nothing in the ADR tells their authors the precondition exists.
The Fix
Amend ADR-0004 with a short subsection under the chunking contract (§2), ~15 lines:
- State the invariant: ordinal placement requires complete membership of the target bucket; a partial collection yields a different ordinal, not an approximate one.
- Name the corpus on disk as the only complete membership that exists, and name
metadata.{type} + delta fetches as partial by design — so a planner reading them is not "optimising", it is computing a different number.
- Name the cost honestly (full scan per type per sync) and why it is the correct price: the alternative is a cache that must never drift, which is the thing that already failed.
- Cross-reference
contentInventory.mjs as the reference implementation and #15130/#15319 as the empirical anchor (2,015 stale → 0; 27 divergent duplicates).
Explicitly NOT in scope: re-opening the ordinal-100 decision, the sealed-chunk rule, or §1.3. This is an amendment recording a precondition of the accepted design, not a new decision — hence an ADR-0004 edit, not a new ADR.
Contract Ledger
| Target surface |
Source of authority |
Proposed behavior |
Fallback |
Docs |
Evidence |
learn/agentos/decisions/0004-github-content-architecture.md §2 |
The accepted ordinal-100 chunking decision |
A subsection stating the complete-membership precondition + its cost |
None |
This ADR is the doc |
#15319's repair census: 2,015 stale index entries → 0; 27 divergent duplicates restored |
Future syncer authors (IssueSyncer, DiscussionSyncer) |
ADR-0004 §2 as amended |
V-B-A against one written precondition instead of re-deriving it from a repair PR's JSDoc |
None |
ADR cross-ref to contentInventory.mjs |
Follow-up audit (below) |
Decision Record impact
This ticket IS the decision-record impact. Amends ADR-0004 (Accepted, 2026-05-14). No supersession — the amendment is additive and does not alter any accepted position.
Acceptance Criteria
Out of Scope
- Re-opening ordinal-100, sealed chunks, or the regeneratable-cache principle.
- Any change to
resources/content/ data.
- Fixing
IssueSyncer / DiscussionSyncer — the audit AC decides whether that work exists; it is not assumed here.
Refs #15130, #15319, #13001, #13200
Retrieval Hint: "ADR-0004 ordinal complete membership partial cache contentInventory chunk placement duplicate artifacts syncer precondition"
Authored by @neo-opus-grace (Grace, Claude Opus 4.8). Requested by @tobiu.
Context
@tobiu asked whether PR #15319 (
+2,248/-118, repairing PR-archive index drift and divergent duplicate artifacts) was ADR territory. It is not — ADR-0004 already governsresources/content/, the newcontentInventory.mjsanchors to it (@see learn/agentos/decisions/0004-github-content-architecture.md), and the PR implements its contract rather than changing it. No new authority, no new namespace, no public API change; 55% of that diff is tests.But the investigation surfaced a real omission in ADR-0004, and it is the root cause the PR repairs rather than removes. Filing at @tobiu's explicit request (2026-07-17), ahead of the usual post-release substrate batch.
Live sweep at file time: latest open issues plus targeted
ADR-0004/ordinal/chunk/contentInventorysearches. No equivalent issue exists. Governing-design sweep: ADR-0004 read in full; §1.3, §2 checked for an existing statement of this invariant — absent.The Problem
ADR-0004 mandates universal ordinal-100 chunking and seals archive chunks. It never states the precondition that makes an ordinal computable:
The syncers plan placement from
metadata.{type}plus the current delta fetch. Both are partial by design — the delta sync rebuilds its cache from each run's fetch. A planner reading only those computes an ordinal against a fraction of a bucket. From #15319'scontentInventory.mjs, which is the clearest statement of the mechanism:That is how 2,015 stale index entries and 27 divergent duplicate artifacts happened. Not a bug in the ADR's design — a precondition the ADR assumes and does not write down, so every syncer author is free to satisfy it or not, and the failure is silent: a wrong ordinal produces a valid-looking artifact in a plausible chunk.
The Architectural Reality
resources/content/is a fully-regeneratable cache; GitHub is the source of truth;sync_allis the canonical path back to clean. Nothing here disturbs that.contentInventory.mjsexists precisely to supply complete membership (a full scan of both tiers, per type, per sync — the PR names that cost explicitly and takes it).IssueSyncerandDiscussionSyncerare unexamined against this invariant and are structurally free to repeat it, because nothing in the ADR tells their authors the precondition exists.The Fix
Amend ADR-0004 with a short subsection under the chunking contract (§2), ~15 lines:
metadata.{type}+ delta fetches as partial by design — so a planner reading them is not "optimising", it is computing a different number.contentInventory.mjsas the reference implementation and #15130/#15319 as the empirical anchor (2,015 stale → 0; 27 divergent duplicates).Explicitly NOT in scope: re-opening the ordinal-100 decision, the sealed-chunk rule, or §1.3. This is an amendment recording a precondition of the accepted design, not a new decision — hence an ADR-0004 edit, not a new ADR.
Contract Ledger
learn/agentos/decisions/0004-github-content-architecture.md§2IssueSyncer,DiscussionSyncer)contentInventory.mjsDecision Record impact
This ticket IS the decision-record impact. Amends ADR-0004 (Accepted, 2026-05-14). No supersession — the amendment is additive and does not alter any accepted position.
Acceptance Criteria
metadata.{type}and delta fetches as partial by design, so the failure reads as structural rather than as a syncer bug.contentInventory.mjs(reference implementation) and #15130/#15319 (empirical anchor).IssueSyncerandDiscussionSyncerare audited against the amended invariant and the result is recorded — either "they already read complete membership" (with the evidence) or a named follow-up ticket per syncer. This AC is the point of the ticket: an amendment nobody checks the other two syncers against is prose, and prose has no tests.Out of Scope
resources/content/data.IssueSyncer/DiscussionSyncer— the audit AC decides whether that work exists; it is not assumed here.Refs #15130, #15319, #13001, #13200
Retrieval Hint: "ADR-0004 ordinal complete membership partial cache contentInventory chunk placement duplicate artifacts syncer precondition"
Authored by @neo-opus-grace (Grace, Claude Opus 4.8). Requested by @tobiu.