Yog965/grc-ai-command-deck
0
1"""Phase 2: Map logs to top-3 NIST controls using SBERT."""2 3from __future__ import annotations4 5import argparse6import json7from pathlib import Path8 9import pandas as pd10 11from grc_ai_pipeline import DEFAULT_NIST_JSON_URL, NISTControlMapper, fetch_nist_controls12 13 14def parse_args() -> argparse.Namespace:15 parser = argparse.ArgumentParser(description="Phase 2 - SBERT mapping")16 parser.add_argument("--log-text", required=True, help="Raw system log string")17 parser.add_argument("--nist-source-url", default=DEFAULT_NIST_JSON_URL)18 parser.add_argument("--output-json", type=Path, default=Path("outputs_phase2/top3_controls.json"))19 return parser.parse_args()20 21 22def main() -> None:23 args = parse_args()24 controls_df = fetch_nist_controls(args.nist_source_url)25 mapper = NISTControlMapper(controls_df)26 top3 = mapper.top_k_controls(args.log_text, k=3)27 28 result = [29 {30 "control_id": m.control_id,31 "title": m.title,32 "description": m.description,33 "similarity": m.similarity,34 }35 for m in top336 ]37 38 args.output_json.parent.mkdir(parents=True, exist_ok=True)39 args.output_json.write_text(json.dumps(result, indent=2), encoding="utf-8")40 41 print("Phase 2 complete. Top-3 controls:")42 print(pd.DataFrame(result).to_string(index=False))43 print(f"\nSaved JSON: {args.output_json}")44 45 46if __name__ == "__main__":47 main()48 