From d7c5e9f77558422ee0ecbb9fe3a602afb2a97046 Mon Sep 17 00:00:00 2001 From: Samuel Johnson Date: Wed, 10 Jun 2026 12:07:32 -0400 Subject: [PATCH 1/3] merge main --- Published/CORE-000084/negative/02/results/results.csv | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Published/CORE-000084/negative/02/results/results.csv b/Published/CORE-000084/negative/02/results/results.csv index ac0a344f7..daf1aa5b6 100644 --- a/Published/CORE-000084/negative/02/results/results.csv +++ b/Published/CORE-000084/negative/02/results/results.csv @@ -1,14 +1,6 @@ Dataset,Record,Variable,Value -<<<<<<< HEAD -AE,0,AEENTPT,2013-05-20 -AE,1,AEENTPT,2013-05-20 -AE,2,AEENTPT,2013-01-14 -AE,3,AEENTPT,2013-01-14 -AE,4,AEENTPT, -======= AE.csv,1,AEENTPT,2013-05-20 AE.csv,2,AEENTPT,2013-05-20 AE.csv,3,AEENTPT,2013-01-14 AE.csv,4,AEENTPT,2013-01-14 AE.csv,5,AEENTPT, ->>>>>>> main From ab8dd73f596204549e7af91067845f02ccb27711 Mon Sep 17 00:00:00 2001 From: Gerry Campion Date: Thu, 16 Jul 2026 11:33:30 -0400 Subject: [PATCH 2/3] update published rules action only focuses on filtered standards --- .../scripts/filter_core_ids_by_standard.py | 101 ++++++++++++++++++ .../workflows/update-published-results.yml | 31 +++++- 2 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 .github/scripts/filter_core_ids_by_standard.py diff --git a/.github/scripts/filter_core_ids_by_standard.py b/.github/scripts/filter_core_ids_by_standard.py new file mode 100644 index 000000000..8d2a961f5 --- /dev/null +++ b/.github/scripts/filter_core_ids_by_standard.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +"""Filter Published CORE rule IDs by Authorities.Standards.Name.""" + +from __future__ import annotations + +import argparse +import sys +from pathlib import Path + +import yaml + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Return space-separated CORE IDs for Published rules matching standards." + ) + parser.add_argument( + "--rules-root", + required=True, + help="Repository root containing Published/", + ) + parser.add_argument( + "--standards", + nargs="+", + required=True, + help="Standards to match from Authorities[].Standards[].Name", + ) + parser.add_argument( + "--core-ids", + default="", + help="Optional space-separated CORE IDs to intersect with the standard filter.", + ) + return parser.parse_args() + + +def iter_published_rule_files(rules_root: Path) -> list[Path]: + published_dir = rules_root / "Published" + files: list[Path] = [] + for pattern in ("**/rule.yml", "**/rule.yaml"): + files.extend(published_dir.glob(pattern)) + return sorted(set(files)) + + +def rule_matches_standard(rule: dict, target_standards: set[str]) -> bool: + for authority in rule.get("Authorities") or []: + if not isinstance(authority, dict): + continue + for standard in authority.get("Standards") or []: + if not isinstance(standard, dict): + continue + standard_name = str(standard.get("Name") or "").strip().upper() + if standard_name in target_standards: + return True + return False + + +def collect_filtered_core_ids(rules_root: Path, standards: list[str]) -> list[str]: + target_standards = {name.strip().upper() for name in standards if name.strip()} + core_ids: list[str] = [] + + for rule_file in iter_published_rule_files(rules_root): + with rule_file.open("r", encoding="utf-8") as handle: + rule = yaml.safe_load(handle) or {} + if not isinstance(rule, dict): + continue + if not rule_matches_standard(rule, target_standards): + continue + + core = rule.get("Core") or {} + if not isinstance(core, dict): + continue + core_id = str(core.get("Id") or "").strip() + if core_id: + core_ids.append(core_id) + return core_ids + + +def intersect_with_requested(core_ids: list[str], requested_core_ids: str) -> list[str]: + requested = requested_core_ids.split() + if not requested: + return core_ids + + allowed = set(core_ids) + return [core_id for core_id in requested if core_id in allowed] + + +def main() -> int: + args = parse_args() + rules_root = Path(args.rules_root) + if not rules_root.is_dir(): + print(f"rules-root does not exist: {rules_root}", file=sys.stderr) + return 1 + + filtered_core_ids = collect_filtered_core_ids(rules_root, args.standards) + output_core_ids = intersect_with_requested(filtered_core_ids, args.core_ids) + print(" ".join(output_core_ids)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/workflows/update-published-results.yml b/.github/workflows/update-published-results.yml index ba0c5e14b..8417e12c8 100644 --- a/.github/workflows/update-published-results.yml +++ b/.github/workflows/update-published-results.yml @@ -79,8 +79,9 @@ jobs: run: venv/bin/pip install tabulate jmespath pyyaml ruamel.yaml # ----------------------------------------------------------------------- - # 4. Run the engine for every Published rule, writing actual results.csv - # directly into each case's results/ directory (overwriting the old baseline) + # 4. Run the engine for Published rules filtered by Authorities.Standards.Name, + # writing actual results.csv directly into each case's results/ directory + # (overwriting the old baseline) # ----------------------------------------------------------------------- - name: Run engine and write results id: run_engine @@ -88,11 +89,31 @@ jobs: run: | chmod +x .github/scripts/run_validation.sh - CORE_IDS_ARG="" - if [ -n "${{ inputs.core_ids }}" ]; then - CORE_IDS_ARG="--core-ids ${{ inputs.core_ids }}" + FILTER_STANDARDS=("USDM" "TIG") + FILTERED_CORE_IDS="$(venv/bin/python .github/scripts/filter_core_ids_by_standard.py \ + --rules-root "$(pwd)" \ + --standards "${FILTER_STANDARDS[@]}")" + + if [ -z "$FILTERED_CORE_IDS" ]; then + echo "No Published rules found for standards: ${FILTER_STANDARDS[*]}" + exit 0 + fi + + CORE_IDS_TO_RUN="$(venv/bin/python .github/scripts/filter_core_ids_by_standard.py \ + --rules-root "$(pwd)" \ + --standards "${FILTER_STANDARDS[@]}" \ + --core-ids "${{ inputs.core_ids }}")" + + if [ -z "$CORE_IDS_TO_RUN" ]; then + echo "No rules match the standards filter and requested CORE IDs." + exit 0 fi + echo "Running validation for standards: ${FILTER_STANDARDS[*]}" + echo "Rule count: $(echo "$CORE_IDS_TO_RUN" | wc -w | tr -d ' ')" + + CORE_IDS_ARG="--core-ids $CORE_IDS_TO_RUN" + ENGINE_DIR_OVERRIDE="$(pwd)/engine" \ venv/bin/python engine/scripts/validate_published_rules.py \ --rules-root "$(pwd)" \ From cc6cd60f6a51840e0438d84eaf4aec678090d53b Mon Sep 17 00:00:00 2001 From: Samuel Johnson Date: Fri, 24 Jul 2026 10:59:13 -0400 Subject: [PATCH 3/3] remove double call --- .github/workflows/update-published-results.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/update-published-results.yml b/.github/workflows/update-published-results.yml index 8417e12c8..fc229a858 100644 --- a/.github/workflows/update-published-results.yml +++ b/.github/workflows/update-published-results.yml @@ -88,24 +88,21 @@ jobs: continue-on-error: true run: | chmod +x .github/scripts/run_validation.sh - FILTER_STANDARDS=("USDM" "TIG") - FILTERED_CORE_IDS="$(venv/bin/python .github/scripts/filter_core_ids_by_standard.py \ + mapfile -t FILTER_RESULT < <(venv/bin/python .github/scripts/filter_core_ids_by_standard.py \ --rules-root "$(pwd)" \ - --standards "${FILTER_STANDARDS[@]}")" + --standards "${FILTER_STANDARDS[@]}" \ + --core-ids "${{ inputs.core_ids }}") + FILTERED_CORE_IDS="${FILTER_RESULT[0]}" + CORE_IDS_TO_RUN="${FILTER_RESULT[1]}" if [ -z "$FILTERED_CORE_IDS" ]; then echo "No Published rules found for standards: ${FILTER_STANDARDS[*]}" exit 0 fi - CORE_IDS_TO_RUN="$(venv/bin/python .github/scripts/filter_core_ids_by_standard.py \ - --rules-root "$(pwd)" \ - --standards "${FILTER_STANDARDS[@]}" \ - --core-ids "${{ inputs.core_ids }}")" - if [ -z "$CORE_IDS_TO_RUN" ]; then - echo "No rules match the standards filter and requested CORE IDs." + echo "No requested core_ids matched Published rules for standards: ${FILTER_STANDARDS[*]}" exit 0 fi