You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by ak...@apache.org on 2026/05/19 16:56:36 UTC
(tooling-agents) branch main updated: asvs_relevance_filter: catch bare-filename citations in suggested guidance
This is an automated email from the ASF dual-hosted git repository.
andrewmusselman pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-agents.git
The following commit(s) were added to refs/heads/main by this push:
new ab8c139 asvs_relevance_filter: catch bare-filename citations in suggested guidance
ab8c139 is described below
commit ab8c1396accbf11f87e3c751df9ad73fafc724eb
Author: Andrew Musselman <ak...@apache.org>
AuthorDate: Tue May 19 09:56:21 2026 -0700
asvs_relevance_filter: catch bare-filename citations in suggested guidance
- citation regex was too strict: matched only the full namespace form audit_guidance:{ns}::filename.md, missed paraphrased citations that use just the bare filename
- _build_suggested_guidance_md now accepts known_guidance_filenames from the caller and matches either form, with bare-filename matches restricted to filenames actually present in Phase 1's policy doc set
- caller extracts the basename set from policy_docs labels starting with audit_guidance: and passes it in
- verified against the May 19 provider/google run: all 6 drops citing dag_authors_trusted.md (mix of explicit and bare forms) now correctly classified as cited, vs 4 of 6 with the previous regex
- airflow-core regression run improves 11/3 → 12/2 cited/inferred for the same reason
---
ASVS/agents/asvs_relevance_filter.py | 49 +++++++++++++++++++++++++++++-------
1 file changed, 40 insertions(+), 9 deletions(-)
diff --git a/ASVS/agents/asvs_relevance_filter.py b/ASVS/agents/asvs_relevance_filter.py
index 0cbd2e5..81c9b2c 100644
--- a/ASVS/agents/asvs_relevance_filter.py
+++ b/ASVS/agents/asvs_relevance_filter.py
@@ -325,7 +325,7 @@ async def run(input_dict, tools):
lines.append("")
return "\n".join(lines)
- async def _build_suggested_guidance_md(entries, min_cluster=3):
+ async def _build_suggested_guidance_md(entries, min_cluster=3, known_guidance_filenames=None):
"""Cluster drop reasons by underlying policy via LLM, then
format the recurring patterns into actionable AGENTS.md /
SECURITY.md suggestions.
@@ -362,17 +362,36 @@ async def run(input_dict, tools):
# inferred ones; surface the cited ones in a separate
# diagnostic section so the operator can confirm existing
# guidance is doing work.
- citation_re = re.compile(r"audit_guidance:[^:]+::[\w_.\-]+\.md")
+ #
+ # The triage LLM writes citations in two forms:
+ # (a) full namespace: audit_guidance:airflow::foo.md
+ # (b) bare filename: foo.md
+ # The explicit form is unambiguous. The bare form is
+ # ambiguous (could mention any .md file), so we only treat
+ # it as a citation when the basename is in
+ # known_guidance_filenames — i.e. it's actually one of the
+ # uploaded guidance docs in Phase 1's policy doc set.
+ citation_re = re.compile(r"audit_guidance:[^:]+::([\w_.\-]+\.md)")
+ known_filenames = set(known_guidance_filenames or ())
+ bare_filename_re = None
+ if known_filenames:
+ # word-bounded match on any known filename
+ escaped = "|".join(re.escape(n) for n in known_filenames)
+ bare_filename_re = re.compile(
+ r"(?<![\w./:])(" + escaped + r")(?![\w])"
+ )
cited_entries = []
inferred_entries = []
cited_by_file = {}
for e in entries:
reason = e.get("reason") or ""
- matches = citation_re.findall(reason)
- if matches:
+ matched_files = set(citation_re.findall(reason))
+ if bare_filename_re is not None:
+ matched_files.update(bare_filename_re.findall(reason))
+ if matched_files:
cited_entries.append(e)
- for path in matches:
- cited_by_file.setdefault(path, []).append(e)
+ for fname in matched_files:
+ cited_by_file.setdefault(fname, []).append(e)
else:
inferred_entries.append(e)
@@ -390,10 +409,10 @@ async def run(input_dict, tools):
"applied.*",
"",
]
- for path, drops in sorted(
+ for fname, drops in sorted(
cited_by_file.items(), key=lambda x: -len(x[1])
):
- out.append(f"### {len(drops)}×: cited `{path}`")
+ out.append(f"### {len(drops)}×: cited `{fname}`")
out.append("")
secs = sorted({d.get("section", "?") for d in drops})
if secs:
@@ -1195,7 +1214,19 @@ async def run(input_dict, tools):
print(f"[filter] WARN: failed to write {key}: {e}")
drop_log_md = _build_drop_log_md(all_drop_entries, profile_hash)
- suggested_md = await _build_suggested_guidance_md(all_drop_entries)
+ # Extract bare filenames of uploaded audit_guidance docs so the
+ # suggested-guidance builder can recognize paraphrased citations
+ # that drop the `audit_guidance:{ns}::` prefix (the LLM writes
+ # the citation either form when generating drop reasons).
+ known_guidance_filenames = {
+ label.split("::", 1)[1]
+ for label in policy_docs
+ if label.startswith("audit_guidance:") and "::" in label
+ }
+ suggested_md = await _build_suggested_guidance_md(
+ all_drop_entries,
+ known_guidance_filenames=known_guidance_filenames,
+ )
review_md = _build_review_queue_md(all_drop_entries, profile_hash)
artifacts = {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org