Context
#14033's PR vertical (sibling of the tickets vertical, PR #14065). PullRequestSource.extract() writes ONE whole-file chunk per pr-*.md (body + all reviews + comments combined). A multi-round PR (body + N reviews + M comments) trends toward the embedding cap → dropped / blind-byte-split (the #13999 metadata-without-vector class on the no-hard-skip path). Per-element chunks keep every element small.
The Fix
- Pure
splitPullRequestArchiveMarkdown(content) → [{kind:'body'|'review'|'comment', ordinal, content}]. Boundaries (V-B-A'd across 4121 PR files — 494 carry ## Reviews, 243 ## Comments): frontmatter + title + PR body (its OWN ## Deltas/## Test Evidence/## Commits sections stay in the body) until the FIRST of ## Reviews/## Comments; each discussion element is delimited by ### `@<author>` (<STATE>) reviewed on <ISO> (review) or ### `@<author>` commented on <ISO> (comment). No ## Reviews/## Comments → body-only.
- Wire
PullRequestSource.extract() to emit pr-<id>#body + pr-<id>#review-<n> + pr-<id>#comment-<n> (stable names → idempotent re-ingestion), preserving type/kind/source per element + a per-element hash.
Acceptance Criteria
Out of Scope
DiscussionSource (thread format) — the third #14033 slice.
Contract Ledger Matrix
| Consumed surface |
Field |
Change |
Consumer impact |
Fallback / semantics |
PullRequestSource.extract() emitted KB chunks |
name |
per-element pr-<id>#body / #review-<n> / #comment-<n> (was pr-<id>) |
KB re-ingestion: one PR → N element chunks. name is metadata + the embedding-prefix, NOT a lookup/join key (verified for the identical consumers at #14063) → retrieval granularity improves, no name-keyed breakage. |
stable names → idempotent; old whole-file hash drops on re-ingest, per-element hashes added |
| same |
hash |
per-element content hash (was whole-file) |
re-ingestion replaces the one whole-file chunk with N element chunks |
content-fingerprint per element |
Related
- #14033 (parent — PR vertical; Discussion follows); #14063 / PR #14065 (tickets vertical — same pattern, different format); #14039 (v13.1 epic); #14000 (over-cap drop class).
Authored-by: @neo-opus-vega (Vega, Claude Opus 4.8). Session ef66cbd0-3770-466c-9df1-f93c141eb1d3.
Context
#14033's PR vertical (sibling of the tickets vertical, PR #14065).
PullRequestSource.extract()writes ONE whole-file chunk perpr-*.md(body + all reviews + comments combined). A multi-round PR (body + N reviews + M comments) trends toward the embedding cap → dropped / blind-byte-split (the #13999 metadata-without-vector class on the no-hard-skip path). Per-element chunks keep every element small.The Fix
splitPullRequestArchiveMarkdown(content)→[{kind:'body'|'review'|'comment', ordinal, content}]. Boundaries (V-B-A'd across 4121 PR files — 494 carry## Reviews, 243## Comments): frontmatter + title + PR body (its OWN## Deltas/## Test Evidence/## Commitssections stay in the body) until the FIRST of## Reviews/## Comments; each discussion element is delimited by### `@<author>` (<STATE>) reviewed on <ISO>(review) or### `@<author>` commented on <ISO>(comment). No## Reviews/## Comments→ body-only.PullRequestSource.extract()to emitpr-<id>#body+pr-<id>#review-<n>+pr-<id>#comment-<n>(stable names → idempotent re-ingestion), preservingtype/kind/sourceper element + a per-element hash.Acceptance Criteria
extract()emits per-element chunks with stable names;type:'pull'+sourcepreserved per element.extract()per-element emission.Out of Scope
DiscussionSource(thread format) — the third #14033 slice.Contract Ledger Matrix
PullRequestSource.extract()emitted KB chunksnamepr-<id>#body/#review-<n>/#comment-<n>(waspr-<id>)nameis metadata + the embedding-prefix, NOT a lookup/join key (verified for the identical consumers at #14063) → retrieval granularity improves, no name-keyed breakage.hashRelated
Authored-by: @neo-opus-vega (Vega, Claude Opus 4.8). Session ef66cbd0-3770-466c-9df1-f93c141eb1d3.