tools/cube-notes-agent: dedupe findings by ISSUE (not just coord)

_canonical_issue() strips FK/FK#/FA/FB/FLAG/FIX prefixes and normalizes separators so
duplicate representations of one root cause collapse (e.g. FK1-SELINUX_RESTORECON +
SELINUX-RESTORECON -> selinux_restorecon; FK3-WAL_CHECKPOINT +
CONCURRENT-STORE-CHECKPOINT -> checkpoint_before_exit via an alias map). Per issue only
the most-detailed note is reported. mark_covered now covers ALL uncovered finding coords
(including deduped-away duplicates) so nothing re-reports. Corresponding notes re-tagged:
issue logs -> finding, status notes -> impl (no uncategorized notes remain).
This commit is contained in:
CUBELinux-2
2026-09-08 07:46:08 -04:00
parent d84f87e7bb
commit b47a5df1b2
+31 -12
View File
@@ -160,11 +160,26 @@ def uncovered_findings(project=None):
un = "".join(f"{coord} {subj}\n" for coord, cat, subj in _log_findings(project) if coord not in covered)
return un.strip() or "(no new findings)"
# Canonical issue key: collapse duplicate representations of the same root cause
# (e.g. FK1-SELINUX_RESTORECON vs SELINUX-RESTORECON) so the report dedupes by ISSUE,
# not just by coordinate. Prefixes (FK, FK#, FA, FB, FLAG, FIX) are stripped and
# separators normalized; a small alias map unifies differently-worded duplicates.
_ISSUE_PREFIX_RE = _re.compile(r'^(FK\d*|FA|FB|FLAG|FIX)[-_]?', _re.I)
_ISSUE_ALIAS = {
"wal_checkpoint": "checkpoint_before_exit",
"concurrent_store_checkpoint": "checkpoint_before_exit",
}
def _canonical_issue(flag):
f = _ISSUE_PREFIX_RE.sub('', flag)
f = _re.sub(r'[-_/\s]+', '_', f).strip('_').lower()
return _ISSUE_ALIAS.get(f, f)
def _uncovered_meta(project=None):
"""[(coord, flag, desc)] for the currently-UNCOVERED findings (grounded).
desc is the FULL note body (not the truncated list subject)."""
"""[(coord, flag, desc)] for the currently-UNCOVERED findings, DEDUPED BY ISSUE.
desc is the FULL note body; the most-detailed note per canonical issue is kept."""
covered = _covered(project)
out = []
best = {} # issue -> (coord, flag, desc, len)
for coord, cat, subj in _log_findings(project):
if coord in covered:
continue
@@ -175,8 +190,11 @@ def _uncovered_meta(project=None):
flag, sep, rest = body_text.partition(":")
flag = flag.strip()
desc = rest.strip() if sep else body_text
out.append((coord, flag, desc))
return out
issue = _canonical_issue(flag)
cur = best.get(issue)
if cur is None or len(desc) > cur[3]:
best[issue] = (coord, flag, desc, len(desc))
return [(c, f, d) for c, f, d, _ in best.values()]
# Snapshot of the uncovered findings captured when read_findings ran, so the
# report can be composed faithfully even after mark_covered has covered them.
@@ -253,10 +271,11 @@ def compose_report(project=None, model_text=""):
return "\n".join(lines)
def mark_covered(project=None, text=""):
meta = CURRENT_META or _uncovered_meta(project)
if not meta:
covered = _covered(project)
coords = [c for c, cat, subj in _log_findings(project) if c not in covered]
if not coords:
return "nothing to cover"
body = "covered coords:\n" + "\n".join(f"{coord} {flag}" for coord, flag, _ in meta)
body = "covered coords:\n" + "\n".join(coords)
args = [CUBE, "note", "add", "--cat", "checkpoint"]
if project:
args += ["--project", project]
@@ -368,10 +387,10 @@ def main():
if not report_text:
# Run ended without an explicit "done" — still produce a grounded report.
report_text = compose_report(a.project, last_assistant)
if CURRENT_META:
# Deterministic coverage: mark the reported findings covered regardless of
# whether the model did it, so the next run is genuinely incremental.
mark_covered(a.project)
# Deterministic coverage: mark all uncovered findings covered (including any
# deduped-away duplicates) regardless of whether the model did it, so the next
# run is genuinely incremental. No-op when there are no uncovered findings.
mark_covered(a.project)
with open(a.report, "w") as f:
f.write(report_text)
os.makedirs(os.path.dirname(a.report), exist_ok=True) if os.path.dirname(a.report) else None