Skip to content

fix(#136): memory pipeline hardening + issue relinking (#135)#138

Open
alexosugo wants to merge 17 commits into
mainfrom
feat/136-memory-pipeline-feedback
Open

fix(#136): memory pipeline hardening + issue relinking (#135)#138
alexosugo wants to merge 17 commits into
mainfrom
feat/136-memory-pipeline-feedback

Conversation

@alexosugo

@alexosugo alexosugo commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Description

Two related pieces of work on the memory distillation pipeline:

#135 — Issue resolution and relinking: replaces the buggy pr.prNumber-as-issue-number aliasing with proper GitHub issue resolution via closingIssuesReferences + title scope + body keywords, plus a one-off relink-issues tool to repair previously mislinked drafts.

#136 — Memory pipeline hardening (first-run post-mortem follow-through):

  • CI guard rejecting mislinked/slug-contradicting drafts
  • Cross-domain dedup (dedupeByIssueId) collapsing backport/multi-PR duplicates into a single canonical draft
  • Prompt hardening (CONSTRAINTS block) and HTML boilerplate stripping
  • Adaptive issue-body budget for near-empty PRs
  • Confidence gradient replacing hardcoded 'medium'
  • Per-run reconciliation report
  • Unambiguous slug separator between conventional-commit type and issue number
  • Fix for dedupeByIssueId's sort comparator: returned NaN (non-deterministic ordering) when two drafts for the same issue both lacked source_pr — flagged by roborev review #223, fixed with a stable path tiebreaker, regression tests added

#135
#136

Code review checklist

  • Readable: Concise, well named, follows the style guide.
  • Tested: Unit tests added/updated (dedup, distiller, gh-classify, issue-linkage, reconcile, relink-issues, run-pipeline, scraper)
  • Backwards compatible: Works with existing data; includes a one-off relink-issues repair tool for previously mislinked drafts.

License

The software is provided under AGPL-3.0. Contributions to this project are accepted under the same license.

Hareet and others added 15 commits July 1, 2026 21:12
…ref filter, Sonar fixes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…SonarCloud S6594)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… — addresses #129 review

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
R2: open-review-pr rejects a draft whose issueNumber aliases its own
source PR number, or whose filename slug contradicts its frontmatter
issueNumber (src/scripts/dedup.ts ciGuardReason).

R3: a cross-domain dedupeByIssueId pass collapses backport cherry-picks
and multi-PR epics that resolve to the same issue id into one canonical
draft (lowest source PR number), tagging it with source_prs[]. Adds the
source_prs field to agent-memory/schema.json.

Builds on the R1 issue-resolution fix already on this branch (cherry-picked
from PR #129's gh-classify.ts/issue-linkage.ts), which makes issueNumber a
stable, non-aliased key these checks can trust.
…dence gradient

R5: CONSTRAINTS block in distiller buildPrompt grounds relatedFiles/entities in
the PR's file list, bans ungrounded channels/reviewers/process trivia, and
tightens domainReasoning/rootCause field descriptions to stop leaked
classifier language and vague root causes. Adds an onboarding/navigation
DOMAIN_PITFALLS entry so route-guard/modal/i18n-only PRs aren't forced into
forms-and-reports.

R6: scraper.ts strips HTML-comment template boilerplate (e.g. CHT's PHI
warning block) from PR and issue bodies before any truncation happens.
distiller.ts grants an expanded ISSUE_BODY_LIMIT when the PR body is
near-empty, so a bare "Fixes #N" PR doesn't lose the issue's root-cause
mechanism to truncation (cht-core #10912 / memory 10914).

R7: confidence is now computeConfidence(draft, pr) instead of a hardcoded
'medium' — 'low' when relatedFiles aren't grounded in the PR's file list or
the PR looks like a backport cherry-pick. related_issues is now populated
from the PR's own secondary linked issues (candidate cht-core-<n> memory
ids) instead of always being an empty array awaiting a pass that never ran.
…ry-run

collectValidPlans previously rewrote a canonical draft's frontmatter
(source_prs) unconditionally, and never deleted a collapsed duplicate from
_pending. Two bugs followed: dry-run silently mutated draft files on disk,
and an apply run's collapsed duplicate stayed in _pending — on the next run
it was the only member of its group, so it got promoted as a fresh memory
for an issue already in the corpus, defeating R3's one-memory-per-issue
invariant.

collectValidPlans is now pure planning (returns kept/dropped alongside
plans/skipped); the frontmatter rewrite and duplicate deletion happen in a
new applyDedupMutations, called only when --apply is passed.

Adds an integration test through openReviewPR covering both the dry-run
no-mutation case and the apply collapse-and-delete case, verified against
the real schema validator.
…run-hygiene

Adds a small reconcile.ts module: reconcile() buckets a batch's skip-log
entries into CI-guard rejections, dedup collapses, and other human-review
flags (matching on .includes since open-review-pr.ts's writeSkipEntry always
prefixes reasons with "open-review-pr: ", never a bare prefix match), and
hallucinationRate() is a ground-truth check comparing a distilled draft's
relatedFiles/entities against the PR's real fileList. distillPR now returns
hallucinationRate on written drafts; run-pipeline's reportOutcome prints both
the reconciliation summary and a count of drafts with unverified file refs
(a >0 reporting threshold, not a gate — entities may legitimately name a
module/concept rather than a literal path).

Root-caused the real _skipped.ndjson pollution: filter.spec.ts's
"touchesMultipleServices: single service..." test called
filterPR(pr, { skipLlm: true }) without a logPath override, so the skipLlm
branch's flag-for-human write landed in the real DEFAULT_PIPELINE_LOG_PATH
on every `npm test` run. Fixed by passing a tmpLogPath() like every other
test in the file. Cleaned the 7 already-committed prNumber:1 rows (all
"LLM triage skipped", 2026-06-16 — leftover fixture noise); verified no
further pollution by emptying the file and running the full suite to
confirm it stays empty.
…e and issue number

slugify() deleted punctuation instead of replacing it with a boundary, so
"fix(#11218):" collapsed to "fix11218" with no separator between the commit
type and the issue number. Replace stripped characters with a space so they
become a hyphen after collapsing, e.g. "fix-11218-...".

The filename-token regexes in dedup.ts and relink-issues.ts that cross-check
a draft's slug against its frontmatter issueNumber assumed the no-separator
shape; made the separator optional there so both old (already-promoted,
never-rewritten) and new drafts keep resolving correctly.
…is missing

roborev review #223: comparator returned NaN when two drafts for the same
issue both lacked source_pr, making canonical draft selection non-deterministic.
alexosugo added 2 commits July 2, 2026 16:01
- dedup.ts: extract groupByIssueId/collapseGroup/draftId to bring
  dedupeByIssueId's cognitive complexity under threshold; avoid
  [object Object] stringification of a non-primitive frontmatter id
- distiller.ts: group BACKPORT_MARKER regex alternation to make
  operator precedence explicit
- open-review-pr.ts: extract validateDraft, buildPlansByDomain,
  buildSkippedDomains, rewriteCanonicalFrontmatter, and
  removeDroppedDrafts to bring three functions' cognitive complexity
  under threshold
- dedup.spec.ts: use to.be.null/to.be.undefined instead of
  to.equal(null/undefined) for more specific assertions
…instead

The helper splits in bd954fa existed only to dodge the cognitive-complexity
linter on straight-line, single-caller code. Inlined back and suppressed
the specific Sonar rule at each site instead of forking functions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants