Skip to content

feat: GHAS급 시크릿 탐지 품질 자율층 M0~M5 (parity SLO, report-only)#58

Merged
pureliture merged 8 commits into
mainfrom
claude/ghas-quality-secrets
Jun 21, 2026
Merged

feat: GHAS급 시크릿 탐지 품질 자율층 M0~M5 (parity SLO, report-only)#58
pureliture merged 8 commits into
mainfrom
claude/ghas-quality-secrets

Conversation

@pureliture

@pureliture pureliture commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

GHAS급 시크릿 탐지 품질 — 자율층 M0~M5 (parity SLO)

시크릿 탐지를 GHAS parity SLO에 맞추는 측정 harness + 티어드 FP-억제 품질 머신 + report-only CI SLO 게이트를 synthetic fixture로만 TDD 완성. 실 GHAS 무접촉. autopilot 단일 goal의 자율 done = M5.

SoT: docs/workbench/specs/ghas-quality-secrets/{requirements,design,review}.md (design v2 리뷰 반영본).

active_goal 슬롯 결정 (사용자 승인)

origin/main이 personal-prod-deploy를 active_goal로 유지 중. 이 PR은 슬롯을 밀어내지 않는다 — governance(autopilot_goal.yml/current.yml/CURRENT.md)는 머지 시 main에 맞춰 personal-prod 유지, ghas는 default-off/report-only 코드만 머지한다. M1M5는 전부 active_goal 슬롯 없이 안전하게 동작(기존 secret default 불변, 신규 동작은 전부 gated/default-off/report-only). autonomous M1M5 done, H1~H3(실 GHAS·baseline·enforce)는 human-gated 후속.

Milestones (각 커밋)

  • M1 0bdf939 — per-repo 1:1 GHAS parity 측정 harness. core/evaluation/metrics.py 재사용(신규 precision/recall·gate 계산 코드 0줄), baseline/ghas_api는 alert→EvaluationKey 어댑터. secret_type↔rule_id 정규화 맵 + type-coverage, state-aware truth(open+resolved-TP만 positive, dismissed 분리), line tolerance(±k), full-history universe. 적대적 fixture(type-mismatch/line-drift/dismissed + tolerance 경계 음성대조)가 정규화/필터/tolerance 누락을 red로.
  • M2 739fac3 — 인라인 싼 FP-억제 티어. scanners/gitleaks/context_filter.py scan-time path-role(docs/example/test)/context-class(manifest-hash) 억제. noise_reason(item:dict) 계약 불변(별도 단계), canary FP-floor(강토큰 위치 무관 보존) → 기존 secret default 불변. partner-pattern default-off gated.
  • M3 b2e90e5 — LLM 티어 disposition 배선(scan_all + scan_worker 2경로). 동기 인라인 자동공유 + 비동기 verify 큐(enqueue-only, 인라인 LLM 호출 0). 멱등 verify-job-id + enqueue CAS로 NEEDS_REVIEW 폭주 차단. 새 테이블/GSI/projection/attribute 없이 기존 job_type="verify"로만. verify job pending-반환 가드. salt provenance.
  • M4 d905e95 — non-GHAS drift monitor. M1 GHAS-derived 분포 기준선 + rule_id TV distance(verifier-직교), parity/SLO 물리 분리 필드, notification_log 노출, default-off·passive(폴링 신설 없음, byte-identical 증명).
  • M5 75df354 — report-only CI SLO 게이트 governance.parity_slo --check. threshold 부재→report-only(영구·자율층), 존재→enforce(H3), 나이>임계→stale-degraded(enforce hard fail). provenance fail-closed.

아키텍처 게이트 (mandatory, 전부 PASS)

pre-implementation / post-M2 / post-M3 / final — 4지점 모두 blocking finding 0.

충돌 해소 (머지 커밋 7d45648)

origin/main이 personal-prod 계열(PR #51~#55, M8 dashboard)로 전진해 충돌 → 사용자 승인대로 해소:

  • governance 3파일 → main(theirs) 채택(personal-prod 유지, origin/main과 byte-identical → autopilot_gate 안 잡음, self-modification/scope-expansion 아님).
  • 코드 2파일(scan_worker/test) → 양쪽 로직 병합(main baseline-job + 우리 M3 verify 가드, 양립).

검증

  • uv run pytest1253 passed, 4 skipped(env-gated)
  • required local checks 전부 green: render --validate/--check, rebuild_ledger_index, render_github_ruleset, public_safety(--diff origin/main...HEAD, --path spec), parity_slo --check(report-only exit 0), autopilot_gate --base origin/main green(governance가 main과 동일하니 base 트릭 불필요)
  • ci/autopilot-gate는 claude/* 면제(ci.yml:109-111, skip+Success)

자율 done = M5 (SLO enforce 미달성 — H-track 대기)

자율층은 영구 report-only(실 baseline 없이 목표 못 만들므로). v1 done(baseline+목표 도달)은 H1~H3 후:

  • H1 실 GHAS snapshot 취득(ghas-live-fetch-or-mutation-required stop → 사람 PR, local 비커밋)
  • H2 baseline + fixture-vs-real divergence 보고 + measure-first 목표 확정
  • H3 threshold(governance/parity_slo_thresholds.yml) 커밋 → report-only→enforce 자동 전환

H-track 메모(final 리뷰 권고): H3 enforce 시 빈/누락 코퍼스 macro=1.0 silent green 방지를 위해 threshold 옆 snapshot_count ≥ N 가드 권고. H1 실 local snapshot 경로를 .gitignore에 명시 추가. M5 parity_slo --check의 ci.yml 한 줄 배선은 .github scope 밖이라 후속(report-only라 미배선이어도 차단 동일).

🤖 Generated with Claude Code

https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh

pureliture and others added 7 commits June 21, 2026 08:59
… 리포인트

- docs/workbench/specs/ghas-quality-secrets/{requirements,design,review}.md (리뷰 반영 v2 승격)
- docs/workbench/agentic-workflows/2026-06-21-ghas-quality-secrets-goal.md (실행 패킷)
- governance/autopilot_goal.yml → goal_id ghas-quality-secrets-parity
  (governance/** 광역 금지·parity_slo.py만, acceptance_checks 정렬, stop_conditions 정본 16)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh
…rity

goal-setup 커밋 07c4e82가 autopilot_goal.yml의 goal_id만 새 goal로
리포인트하고 governance/current.yml의 active_goal 동기화를 빠뜨려
autopilot_gate(render.py active_goal-must-match)가 영구 fail이었음.
직전 goal 전환(5fdc16a)처럼 goal_id·active_goal·CURRENT.md를 함께
맞추는 goal-activation 완성. orchestrator-authorized 정정(범위 한정:
current.yml + render 파생 CURRENT.md만; allowed_writes/gate/public_safety
불변).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh
… 적대적 fixture

자율층 M1. 시크릿 탐지의 per-repo 1:1 GHAS parity 측정 harness를
synthetic fixture로 TDD 완성. 실 GHAS 무접촉.

- baseline/ghas_api/normalize.py: secret_type↔rule_id 정규화 맵(1급 산출물,
  양방향 lookup + 미등록 식별 + type-coverage 메타). 초기 커버리지
  github-pat/discord/aws.
- baseline/ghas_api/parity.py: GHAS alert→EvaluationKey 어댑터.
  - state-aware truth: open + resolved-as-true_positive만 positive,
    dismissed/resolved-FP/revoked는 recall 분모 제외 + GHAS-confirmed-FP 분리집계.
  - line tolerance: ±k(기본 2) 매칭, full-history universe.
  - 정규화 미등록 쌍은 type-unmatched-but-colocated 버킷으로 분리(precision/recall
    미오염).
  - per-repo micro → macro 집계.
  - load_parity_snapshot: source=synthetic provenance fail-closed.
- 신규 precision/recall 공식·gate-threshold 판정 코드 0줄 —
  core/evaluation/metrics.py(EvaluationResult/evaluate_evaluation_gate) 재사용,
  어댑터는 정규화·truth필터·tolerance 매칭만. GhasComparisonResult/
  compare_ghas_alerts_with_findings do-not-modify(제3 엔진 신설 방지).
- eval/ghas-parity-corpus/synthetic-snapshot.json: 적대적 fixture.
  실 GHAS secret_type 토큰 + type-mismatch/line-drift/dismissed + tolerance
  경계 음성대조(±k 안 must-match / 밖 must-NOT-match). 정규화/tolerance/state
  필터를 끄면 특정 지표가 red로 떨어짐을 테스트로 증명(self-fulfilling 차단).
  fake 토큰·repo·path만(public-safe), source=synthetic marker.
- design.md: pre-impl arch gate 반영 — "0 lines" 인변을 공식·gate 코드로 한정,
  어댑터 EvaluationKey 수렴, tolerance 경계 음성대조 요구.

검증: uv run pytest 1058 passed, public_safety green, autopilot_gate green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh
자율층 M2. 11-FP 실관측(docs-example/test-fixture/manifest-hash) 클래스를
scan 시점에 즉시 억제하되 canary TP는 위치 무관 보존. 기존 secret default 불변.

- scanners/gitleaks/context_filter.py(신규): suppression_reason(finding).
  - noise_reason(item:dict) 계약 불변 — path-role은 정규화된
    Finding.location.file_path가 필요해 map 이후·append 이전의 별도 scan-time
    단계로 분리(pre-impl arch gate 권고 준수).
  - default-on 결정적·no-network: context-class manifest-hash(lockfile),
    path-role documentation/example/test 억제.
  - FP-floor: 강토큰(FALSE_NEGATIVE_PATTERN, ghp_/AKIA)은 docs/test/manifest
    어디서도 보존(canary 가드를 첫 분기로 강제) → existing-secret-default
    -behavior-change 안 건드림(억제율 회귀 테스트로 보장).
  - path-role 어휘는 llm/common/prompt._path_role과 동일하게 scanners 레이어에
    재구현(scanners→llm import 없음, 테스트로 등가 강제).
  - partner-pattern은 default-off gated 신규 동작분(이 scan-time 티어에선 KEEP
    신호, 실 boost는 M3 검증 티어 소관 — design Open Questions에 재평가 노트).
- scanners/gitleaks/parser.py: map 이후·append 이전 suppression_reason 배선,
  enable_noise_filter로 게이트. 억제=finding 미생성(scan-time 경계, post-scan
  disposition 아님).
- core/scan/options.py: enable_noise_filter docstring에 path-role 억제도 이
  스위치에 묶임 명시(post-M2 arch gate P1).
- design.md: partner-boost 위치·path-role 공통추출을 Open Questions에 deferred.

post-M2 아키텍처 리뷰 PASS(blocking 0). 검증: uv run pytest 1095 passed,
public_safety green, autopilot_gate --base 81d59d0 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh
자율층 M3. scan_worker 핫패스에 동기 인라인 싼 티어(parser/filter 자동공유) +
비동기 LLM verdict 큐 2경로. 인라인 LLM 호출 0(비용 NFR). 비동기 LLM 티어는
gated default-off.

- runtime/verify_queue.py(신규): 비동기 verify 큐 seam.
  - enqueue: 애매한 finding(terminal disposition 없음)당 멱등 verify 잡.
    verify-job-id를 finding의 content-stable match_key에서 결정적 도출 + 기존
    enqueue_commit_scan_job의 CAS(attribute_not_exists)로 재큐잉 폭주 차단
    (NEEDS_REVIEW backoff 택1). 새 테이블/GSI/projection/attribute 없이 기존
    job_type(free-form 문자열) "verify" 확장으로만 표현.
  - drain: 별도 경로가 verify 잡을 lease→verify→record_verifier_disposition.
    NEEDS_REVIEW는 무기록 consume(record_verifier_disposition 재사용).
  - enqueue_errors를 CAS duplicate와 분리 집계(post-M3 arch gate D1 nit).
- runtime/scan_worker.py: verify_enqueue 훅(default None → pre-M3 byte-identical).
  핫패스 완료 후 애매 건 enqueue-only. **D3 가드(post-M3 arch gate)**: leased
  job_type=="verify"는 코드-스캔 worker가 처리하지 않고 pending 반환 →
  fetch/scan/_advance_repo_health 미도달(freshness 오염 차단).
- scan_all은 기존 verifier/disposition 동기 경로 그대로(주간 배치, 회귀만 확인).
- salt provenance: tests/test_secret_hash_salt_provenance.py — secretHash가 LLM
  티어로 나가는 유일 secret-파생값, per-deployment salt(SECURITY_SCANNER_HASH_SALT)
  주입 시 digest 변화·set-but-empty 폴백 검증(model.py 미수정).
- design.md: NEEDS_REVIEW backoff 택1 확정 + drain 실제 store 구현 후속(D3)
  Open Questions 기록.

post-M3 아키텍처 리뷰 PASS(blocking 0, storage-projection 미트리거). 검증:
uv run pytest 1115 passed, public_safety green, autopilot_gate --base 81d59d0 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh
…ive 노출

자율층 M4. non-GHAS repo는 per-repo truth가 없어 SLO 측정 불가(B-floor+C-monitor,
requirements Q6) — 증류한 품질 머신 전이의 건전성을 분포-shift 조기경보로 감시.

- runtime/drift_monitor.py(신규): DriftBaseline.from_macro_parity가 M1 parity
  집계(aggregate_repo_parity → EvaluationResult.true_positives = GHAS-매칭 TP)의
  canonical-type 분포를 GHAS-calibrated 기준선으로 도출. non-GHAS는 GHAS-매칭 TP가
  0이라 self-baseline 구조적 불가(테스트 증명). evaluate_distribution_drift는
  finding rule_id 분포만으로 total variation distance 산출(stdlib Counter, 신규
  의존성 0) — verifier verdict 절대 미참조(verifier-직교, common-cause bias 완화).
  verifier disposition 비율은 별도 필드로 cross-reference만(distance에 미혼입).
  전이 한계(early-warning 전용, SLO 아님) 모듈 docstring에 명시.
- runtime/notification_log.py: drift_record(type:"drift") 빌더 추가(cadence_overrun
  선례 패턴, append-only JSONL, 기존 consumer 영향 0).
- runtime/scan_all.py: DriftConfig(default-off) + ScanAllRequest.drift_config +
  _maybe_write_drift_record passive 훅. config None/disabled/baseline None이면 즉시
  return → 기존 notification 스트림 byte-identical. drift는 별도 record로만, parity/
  verification summary 슬롯과 분리(SLO 미오염). drift_monitor import는 함수-로컬
  (default-off 경로 미탑재, circular import 회피). 폴링/타이머/스케줄 신설 없음 —
  scan-all 완료 시점에 1회 piggyback(능동 drift 비채택 준수).
- design.md: drift 노출 표면 택1=notification_log 확정(근거 명시).

검증: uv run pytest 1130 passed(+15), default-off byte-identical 증명, parity.py/
metrics.py 무수정, public_safety green, autopilot_gate --base 81d59d0 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh
…lo --check

자율층 M5(자율 goal done). 시크릿 GHAS parity를 frozen synthetic snapshot 대비
재현 측정하는 CI SLO 게이트. threshold 부재 → 영구 report-only(자율층은 실
baseline 없이 목표 못 만들므로). enforce·threshold 커밋은 H3 human-gated.

- governance/parity_slo.py(신규, allowed_writes 유일 governance 파일): three-mode.
  - threshold yml 부재/빈값 → report-only(항상 exit 0, 차단 안 함).
  - threshold 존재 → enforce(macro precision/recall vs precision_min/recall_min).
  - snapshot 나이>임계 또는 fetched_at 부재 → stale-degraded. report-only는
    warn+exit 0, enforce는 hard fail(silent pass 금지, design staleness-passive-only).
  - 측정은 M1(load_parity_snapshot provenance fail-closed → evaluate_repo_parity →
    aggregate_repo_parity, metrics.py 재사용) 소비. 신규 precision/recall 산식 0줄.
  - non-synthetic snapshot은 provenance fail-closed로 게이트 입력 거부(실 GHAS
    export 구동 불가).
- tests/test_governance_parity_slo.py: report-only/enforce(pass·fail)/stale-degraded
  (report-only warn·enforce block)/provenance fail-closed/CLI exit/committed corpus 증명.
- design.md: 현재 상태(SLO enforce 미달성·H-track 대기) + CI 배선 한계(.github
  scope 밖, report-only라 미배선이어도 차단 동일) + Component 표 governance→src
  의존·drift 노출 표면 명문화.

final 아키텍처 리뷰(system + codebase, opus) PASS: blocking 0, 자율 goal done=M5
달성. 검증: uv run pytest 1142 passed, required local checks 8종 전부 green(이제
parity_slo --check 포함), autopilot_gate --base 81d59d0 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the GHAS secret-parity SLO goal, introducing a synthetic adversarial snapshot fixture, an M1 parity harness with bidirectional token normalization, an M2 inline cheap tier for scan-time path-role and context-class suppression, an M3 async LLM verifier queue seam, an M4 non-GHAS drift monitor, and an M5 CI SLO gate. The reviewer feedback highlights a potential busy-loop issue in scan_worker.py when verify jobs are repeatedly leased and returned, and suggests several defensive programming guards to prevent potential AttributeError or TypeError exceptions across verify_queue.py, context_filter.py, and parity.py.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +113 to +117
if job.job_type == JOB_TYPE_VERIFY:
request.store.return_job_to_pending(
job.job_id, "verify job is not handled by the code-scan worker"
)
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

여기에는 잠재적인 효율성 및 안정성 문제가 있습니다. verify 작업이 code-scan 워커에 의해 리스(lease)되면, 대기 상태(pending)로 반환되고 루프가 계속됩니다. 그러나 대기 중인 다른 작업이 없거나 다른 verify 작업만 있는 경우, 동일한 루프 반복 내에서 lease_next_scan_job을 다음으로 호출할 때 방금 반환된 동일한 verify 작업을 즉시 다시 리스할 수 있습니다. 이로 인해 워커가 단일 호출 내에서 동일한 작업을 최대 max_jobs번 반복해서 리스하고 반환하게 되어 데이터베이스 작업과 CPU 사이클이 낭비될 수 있습니다.

이러한 중복 리스 루프를 방지하기 위해, 현재 호출에서 대기 상태로 반환된 작업 ID를 추적하고 중복 리스가 발생할 경우 루프를 중단(break)하거나 건너뛰는 방안을 고려해 주세요.

Comment on lines +130 to +132
secret_hash = finding.evidence.secret_hash
if not secret_hash:
return ""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

안정성을 확보하고 방어적 프로그래밍 관행을 준수하기 위해, finding.evidenceNone이거나 누락된 경우에 대비한 가드가 필요합니다. 만약 finding.evidenceNone인 경우, finding.evidence.secret_hash에 접근하면 AttributeError가 발생합니다.

    evidence = getattr(finding, "evidence", None)
    if not evidence or not evidence.secret_hash:
        return ""
    secret_hash = evidence.secret_hash

Comment on lines +164 to +165
file_path = finding.location.file_path

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

finding.location 또는 finding.location.file_pathNone이거나 누락된 경우 발생할 수 있는 AttributeError 또는 TypeError를 방지하기 위해, 이 속성들을 _is_manifest_hash_location에 전달하기 전에 방어적으로 검증해야 합니다.

Suggested change
file_path = finding.location.file_path
location = getattr(finding, "location", None)
file_path = location.file_path if location else None
if not file_path:
return None

Comment on lines +444 to +445
data = json.loads(Path(path).read_text(encoding="utf-8"))
source = str(data.get("source", "")).strip().lower()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

파싱된 JSON 필드에 대한 방어적 타입 검증을 구현할 때, 키에 접근하거나 .get()을 호출하기 전에 파싱된 JSON이 실제로 딕셔너리 객체인지 확인하여 안정성을 확보해야 합니다. 만약 JSON 파일이 잘못 형성되었거나 객체 대신 리스트/원시 타입을 포함하고 있다면, 처리되지 않은 AttributeError가 발생할 수 있습니다. 또한, 이와 같은 방어적 타입 검증을 구현할 때는 None, 숫자, 불리언, 리스트, 딕셔너리 등 다양한 예기치 않은 타입을 다루는 포괄적인 단위 테스트를 추가하여 견고함을 보장해 주세요.

    data = json.loads(Path(path).read_text(encoding="utf-8"))
    if not isinstance(data, dict):
        raise ValueError("parity snapshot JSON must be a dictionary object")
    source = str(data.get("source", "")).strip().lower()
References
  1. When implementing defensive type validation for parsed JSON fields (e.g., verifying a field is a string), ensure robustness by adding comprehensive unit tests that cover various unexpected types, including None, numbers, booleans, lists, and dictionaries.

Comment on lines +207 to +208
config = config or ParityConfig()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

None 입력에 대한 안정성을 확보하기 위해, alertsfindingsNone으로 전달될 경우 방어적으로 빈 리스트로 초기화해야 합니다.

Suggested change
config = config or ParityConfig()
config = config or ParityConfig()
alerts = alerts or []
findings = findings or []

origin/main이 personal-prod-deploy 계열(PR #51~#55, M8 dashboard)로 전진해 충돌.
사용자 승인 결정대로 해소:

- governance 3파일(autopilot_goal.yml/current.yml/CURRENT.md) → main(theirs) 채택.
  main의 active_goal(personal-prod-deploy)을 그대로 유지 = governance를 main에
  맞춤(우리 goal-activation 폐기). 이 3파일은 origin/main과 byte-identical →
  governance self-modification도 scope-expansion도 아님. ghas는 active_goal 슬롯
  불필요(M1~M5 전부 default-off/report-only라 슬롯 없이 안전 동작).
- 코드 2파일(scan_worker.py/test_scan_worker.py) → 양쪽 로직 병합. main의
  baseline-job full-history(_scan_options_for_job/_is_baseline_job)와 우리 M3
  verify job pending-반환 가드 + enqueue가 양립(auto-merge 성공, 테스트 green).
- 우리 신규 파일(parity/normalize/context_filter/verify_queue/parity_slo,
  eval/ghas-parity-corpus, spec docs)은 충돌 없음.

검증: uv run pytest 1253 passed, 4 skipped(env-gated).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwGs78e6Rb7P5BDe2ezQEh
Comment on lines +41 to +48
from security_scanner.runtime.drift_monitor import (
DRIFT_MONITOR_ENV_VAR,
DriftBaseline,
ScanAllDriftSummary,
drift_config_from_env,
evaluate_distribution_drift,
rule_id_distribution,
)
Comment thread tests/test_ghas_parity.py
Comment on lines +29 to +35
from security_scanner.baseline.ghas_api.parity import (
GHAS_POSITIVE_TRUTH_STATES,
ParityConfig,
aggregate_repo_parity,
evaluate_repo_parity,
load_parity_snapshot,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants