決定論的解析器、隔離コンテナ実行、およびライブペネトレーションテスト

pni501 におけるすべての定量的メトリクス、依存関係グラフ、テストカバレッジ率、CVE 件数、およびライブ HTTP エクスプロイト検証は、LLM の推論ステップが実行される前に 6 個の決定論的 Python 解析器によって生成されます。6 言語対応の 1 回パース Tree-sitter CST 解析 (ast-grep-py) と、オフライン単体テスト・ソケットレス Trivy スキャン・ライブループバック侵入テストを実行する隔離 Docker/Podman コンテナサンドボックスを組み合わせることで、pni501 はハルシネーションのない 100% 再現可能なエンジニアリング証跡を保証します。

analyzers_and_pentest_1
1回パース Tree-sitter CST アーキテクチャ: 対応6言語を9個のモジュラーASTチェッカーと言語バージョン互換性ガードレールで評価
Source Code
from drawlib.canvas import save, setup
from drawlib.diagrams.architecture import ArchitectureDiagram, Node, NodeGroup, PhosphorIcon
from drawlib.styles import Styles

setup(width=176, height=98, dpi=150)

diag = ArchitectureDiagram(
    node_style=Styles.PrimaryBold,
    node_text_style=Styles.DarkBold.patch(text_size=10.0),
    edge_style=Styles.DarkBold,
    edge_text_style=Styles.DarkBold.patch(text_size=10.0),
    node_card_style=Styles.WhiteBordered.patch(shape_r=1.5),
)

g_in = diag.add(
    NodeGroup(
        title="1. Parse-Once CST (6 Langs)",
        width=40.0,
        height=90.0,
        style=Styles.Neutral.patch(shape_r=2.0),
        text_style=Styles.PrimaryBold.patch(text_size=10.5, halign="left", valign="top"),
    ),
    xy=(3.0, 4.0),
)

n_langs = g_in.add(
    Node(
        "6 Target Languages\nPy / Java / PHP\nGo / TS / JS",
        width=33.0,
        height=20.0,
        icon=PhosphorIcon.CODE,
        icon_size=5.4,
        card_style=Styles.PrimaryNeutral.patch(shape_r=1.5),
    ),
    xy=(20.0, 67.0),
)

n_cst = g_in.add(
    Node(
        "ast-grep-py SgRoot\nImmutable ParsedUnit\n(Zero Code Execution)",
        width=33.0,
        height=20.0,
        icon=PhosphorIcon.TREE_STRUCTURE,
        icon_size=5.6,
        style=Styles.WhiteBold,
        text_style=Styles.WhiteBold.patch(text_size=10.0),
        card_style=Styles.PrimaryFlat.patch(shape_r=1.5),
    ),
    xy=(20.0, 41.0),
)

n_ver = g_in.add(
    Node(
        "version_compat.py\nSyntax vs Manifest\nRuntime Check",
        width=33.0,
        height=18.0,
        icon=PhosphorIcon.SEAL_CHECK,
        icon_size=5.2,
        card_style=Styles.SecondaryNeutral.patch(shape_r=1.5),
    ),
    xy=(20.0, 15.0),
)

g_chk = diag.add(
    NodeGroup(
        title="2. Nine Modular Tree-sitter AST Checkers (ast_analyze/base/)",
        width=84.0,
        height=90.0,
        style=Styles.Neutral.patch(shape_r=2.0),
        text_style=Styles.DarkBold.patch(text_size=10.5, halign="left", valign="top"),
    ),
    xy=(48.0, 4.0),
)

c1 = g_chk.add(Node("1. Import Hygiene\n(imports.py)", width=24.5, height=17.5, icon=PhosphorIcon.ARROWS_LEFT_RIGHT, icon_size=4.8), xy=(15.5, 67.0))
c2 = g_chk.add(Node("2. Type Safety\n(typing.py)", width=24.5, height=17.5, icon=PhosphorIcon.SHIELD_CHECK, icon_size=4.8), xy=(42.0, 67.0))
c3 = g_chk.add(Node("3. API Docs\n(docs.py)", width=24.5, height=17.5, icon=PhosphorIcon.BOOK_OPEN_TEXT, icon_size=4.8), xy=(68.5, 67.0))

c4 = g_chk.add(Node("4. Code Quality\n(quality.py)", width=24.5, height=17.5, icon=PhosphorIcon.GAUGE, icon_size=4.8), xy=(15.5, 42.0))
c5 = g_chk.add(Node("5. Deps & Cycles\n(dependencies.py)", width=24.5, height=17.5, icon=PhosphorIcon.GRAPH, icon_size=4.8), xy=(42.0, 42.0))
c6 = g_chk.add(Node("6. Test Suite\n(testing.py)", width=24.5, height=17.5, icon=PhosphorIcon.FLASK, icon_size=4.8), xy=(68.5, 42.0))

c7 = g_chk.add(Node("7. Frameworks\n(frameworks.py)", width=24.5, height=17.5, icon=PhosphorIcon.STACK, icon_size=4.8), xy=(15.5, 17.0))
c8 = g_chk.add(Node("8. Operational\n(operational.py)", width=24.5, height=17.5, icon=PhosphorIcon.PULSE, icon_size=4.8), xy=(42.0, 17.0))
c9 = g_chk.add(
    Node(
        "9. Security Sinks\n(security.py)",
        width=24.5,
        height=17.5,
        icon=PhosphorIcon.WARNING_OCTAGON,
        icon_size=4.8,
        style=Styles.DangerBold,
        card_style=Styles.DangerNeutral.patch(shape_r=1.5),
    ),
    xy=(68.5, 17.0),
)

g_out = diag.add(
    NodeGroup(
        title="3. Grounded AstFacts",
        width=36.0,
        height=90.0,
        style=Styles.PrimaryNeutral.patch(shape_r=2.0),
        text_style=Styles.PrimaryBold.patch(text_size=10.5, halign="left", valign="top"),
    ),
    xy=(137.0, 4.0),
)

n_opt = g_out.add(
    Node(
        "pni.toml [[opt_out]]\nWaiver Filter",
        width=29.5,
        height=18.0,
        icon=PhosphorIcon.FUNNEL,
        icon_size=5.0,
    ),
    xy=(18.0, 67.0),
)

n_inv = g_out.add(
    Node(
        "module_inventory &\nimport_graph",
        width=29.5,
        height=19.0,
        icon=PhosphorIcon.BLUEPRINT,
        icon_size=5.2,
    ),
    xy=(18.0, 42.0),
)

n_facts = g_out.add(
    Node(
        "AstFacts JSON\ndangerous_sinks &\napi_endpoints",
        width=29.5,
        height=20.0,
        icon=PhosphorIcon.DATABASE,
        icon_size=5.4,
        style=Styles.SuccessBold,
        card_style=Styles.SuccessNeutral.patch(shape_r=1.5),
    ),
    xy=(18.0, 16.0),
)

diag.connect(n_langs, n_cst, routing="orthogonal")
diag.connect(n_cst, n_ver, routing="orthogonal")
diag.connect(g_in, g_chk, routing="orthogonal", style=Styles.PrimaryBold)
diag.connect(g_chk, g_out, routing="orthogonal", style=Styles.PrimaryBold)
diag.connect(n_opt, n_inv, routing="orthogonal")
diag.connect(n_inv, n_facts, routing="orthogonal", style=Styles.SuccessBold)

diag.draw(xy=(0.0, 0.0))
save()

1. 静的リポジトリ検査と Tree-sitter AST 解析器

1.1 リポジトリ・サプライチェーン・ガバナンス検査器 (project_inspect -> ProjectFacts)

src/pni/_actions/project_inspect.py および src/pni/_actions/_repo_governance.py に実装された run_project_inspect() は、外部パッケージマネージャを実行することなく、リポジトリ構造、依存関係、ドキュメント、および OpenSSF サプライチェーンシグナルを抽出します。

  • 6言語対応マニフェスト & ロックファイル解析: pyproject.toml / setup.py / requirements.txt(Python)、pom.xml / build.gradle* / Gradle バージョンカタログ(Java)、composer.json / WordPress ヘッダ(PHP)、go.mod / go.sum(Go)、および package.json / tsconfig.json(TypeScript & JavaScript)を解析します。lockfiles_found(uv.lock, poetry.lock, gradle.lockfile, composer.lock, go.sum, package-lock.json, pnpm-lock.yaml, yarn.lock)、unpinned_dependencies、detected_frameworks、runtime_types(["library"], ["cli"], ["cli", "library"], ["web_api"], ["worker"])、legacy_language_findings、および tooling_modernization_issues を検出します。
  • OpenSSF サプライチェーン & リポジトリガバナンス (_repo_governance.py): has_license、has_security_policy(SECURITY.md)、has_dependency_automation(Dependabot / Renovate)、GitHub Actions の ci_supply_chain_issues(可変な @main/@master アクション参照、permissions: ブロック欠如、肥大化したインライン bash スクリプト)、committed_secret_files(.env, .pem, .key, サービスアカウント JSON)、Diátaxis readme_headings / docs_inventory、および静的 container_hygiene_issues(:latest ベースタグ、root USER)を監査します。

1.2 1回パース多言語 CST/AST 解析器 (ast_analyze -> AstFacts)

src/pni/_actions/ast_analyze/ に実装された run_ast_analyze() は、信頼できないコードを一切インポート・実行することなく、各対象ファイルを ast-grep-py で 1回だけ不変の ParsedUnit(SgRoot Tree-sitter CST)へパースし、python/, java/, php/, go/, ts_js/(TypeScript + JavaScript)にわたる 9 個のモジュラーチェッカーを実行します。

# チェッカーモジュール 抽出される主な AstFacts 出力とシグナル
1 インポート衛生 (imports.py) import_hygiene_coverage_pct、unsorted_imports、wildcard_imports、関数内 late_imports
2 型安全性 (typing.py) type_safety_coverage_pct、引数/戻り値/フィールド型注釈の欠落(type_safety_issues)、Any/raw-generic/mixed/interface{} の使用(weak_type_usages)、および unscoped_type_ignores(# type: ignore, @SuppressWarnings, @ts-ignore)
3 API ドキュメント (docs.py) PEP 257、Javadoc、PHPDoc、GoDoc、JSDoc/TSDoc にわたる docstring_coverage_pct、missing_docstrings、empty_docstrings、引数/戻り値の doc_signature_mismatches
4 コード品質 & インベントリ (quality.py) 正確な total_files, total_loc, total_classes, total_functions、ファイル別 module_inventory(public_types, public_callables)、complex_functions(> 50 行、> 7 分岐、または認知的複雑度 > 15)、excessive_parameters(> 6)、global_state_usages、bug_risk_idioms
5 依存関係 & レイヤー境界 (dependencies.py) internal_import_graph、Tarjan SCC circular_dependencies、型チェック専用の type_checking_cycles、unused_dependencies、undeclared_dependencies、アーキテクチャ boundary_violations
6 テストスイート健全性 (testing.py) test_functions_count、module_test_coverage_pct、assertion_free_tests、およびフィクスチャ/ハーネス検出(conftest.py, JUnit 5, PHPUnit, testing.T, Vitest/Jest)
7 フレームワーク & イディオム (frameworks.py) FastAPI/Flask/Django、Spring Boot、Laravel/WordPress、Gin/Echo/net/http、Express/NestJS/Next.js のフレームワーク固有アンチパターン(framework_issues)と modernization_hints
8 運用性 & 12-Factor (operational.py) missing_io_timeouts(タイムアウト未指定の HTTP/DB/RPC 呼び出し)、scattered_env_access(設定モジュール外の os.getenv / System.getenv / process.env)、unstructured_logging、AST レベルの hardcoded_secrets
9 セキュリティシンク & ルート (security.py) CWE 分類付き dangerous_sinks(sql_injection, xss, command_injection, unsafe_deserialization, code_execution, path_traversal)および抽出された HTTP ルート(api_endpoints: http_method, path, handler, auth_mechanisms)

1.3 言語バージョン互換性チェックと pni.toml 除外フィルタリング

9 個の AST チェッカーと並行して、run_ast_analyze() は 2 つの横断的な決定論的パスを実行します。

  • マニフェスト対構文の互換性検証 (version_compat.py): パースされた CST 構文をマニフェストで宣言された最小ランタイムバージョン(requires-python、Maven/Gradle Java ターゲット、composer.json PHP 制約、または go.mod の go ディレクティブ)と照合します。下限バージョン未満での Python 3.10+ match/case や 3.12+ type 文、Java 8 ターゲットでの Java 16+ record や Java 11+ String.isBlank() / java.net.http、PHP 7.x 制約での PHP 8.0+ match/?-> や 8.1+ enum/readonly、古い go ディレクティブでの Go 1.18+ ジェネリクスや Go 1.21+/1.23+ 標準パッケージ(log/slog, slices, iter)を language_version_mismatches として検出します。
  • 監査証跡付き [[opt_out]] 除外ルール (pni.toml): pni.toml の明示的な [[opt_out]] ルールに対して CodeLocation および SecuritySinkLocation をフィルタリングしつつ、除外された件数(opt_out_match_counts)を正確に記録して監査の透明性を維持します。

2. 隔離コンテナサンドボックス: ランタイム検証、Trivy、ライブ侵入テスト

ホスト環境を汚染せず外部ネットワークへの誤送信を防ぐため、pni501 は run_check、security_scan、および web_pentest を隔離された Docker または Podman コンテナ内(engine_detect.py が rootless Podman または Docker を自動検出)で実行します。

analyzers_and_pentest_2
隔離コンテナサンドボックスパイプライン: オフライン単体テスト・起動プローブ (run_check)、ソケットレスTrivyスキャン (security_scan)、およびループバックHTTP侵入テスト (web_pentest)
Source Code
from drawlib.canvas import save, setup
from drawlib.diagrams.architecture import ArchitectureDiagram, Node, NodeGroup, PhosphorIcon
from drawlib.styles import Styles

setup(width=176, height=96, dpi=150)

diag = ArchitectureDiagram(
    node_style=Styles.PrimaryBold,
    node_text_style=Styles.DarkBold.patch(text_size=10.0),
    edge_style=Styles.DarkBold,
    edge_text_style=Styles.DarkBold.patch(text_size=10.0),
    node_card_style=Styles.WhiteBordered.patch(shape_r=1.5),
)

g1 = diag.add(
    NodeGroup(
        title="1. run_check (Offline Sandbox)",
        width=53.0,
        height=88.0,
        style=Styles.Neutral.patch(shape_r=2.0),
        text_style=Styles.PrimaryBold.patch(text_size=10.5, halign="left", valign="top"),
    ),
    xy=(3.0, 4.0),
)

r1 = g1.add(
    Node(
        "selector.py\nMaterialize .pni/dockerfiles/\n(6-Lang Build Harness)",
        width=45.0,
        height=18.5,
        icon=PhosphorIcon.PACKAGE,
        icon_size=5.2,
    ),
    xy=(26.5, 65.5),
)

r2 = g1.add(
    Node(
        "Offline Test Runner\n--network=none\nJUnit XML + Line/Branch Cov",
        width=45.0,
        height=19.0,
        icon=PhosphorIcon.TERMINAL_WINDOW,
        icon_size=5.4,
        style=Styles.WhiteBold,
        text_style=Styles.WhiteBold.patch(text_size=10.0),
        card_style=Styles.PrimaryFlat.patch(shape_r=1.5),
    ),
    xy=(26.5, 40.5),
)

r3 = g1.add(
    Node(
        "smoke.py Boot Probe\nlibrary / cli / web_api\n-> RuntimeFacts JSON",
        width=45.0,
        height=18.5,
        icon=PhosphorIcon.PULSE,
        icon_size=5.2,
        card_style=Styles.PrimaryNeutral.patch(shape_r=1.5),
    ),
    xy=(26.5, 15.5),
)

g2 = diag.add(
    NodeGroup(
        title="2. security_scan (Socketless Trivy)",
        width=53.0,
        height=88.0,
        style=Styles.Neutral.patch(shape_r=2.0),
        text_style=Styles.SecondaryBold.patch(text_size=10.5, halign="left", valign="top"),
    ),
    xy=(61.5, 4.0),
)

s1 = g2.add(
    Node(
        "Dual-Surface Target\nRepo Filesystem +\ndocker/podman save Image Tar",
        width=45.0,
        height=18.5,
        icon=PhosphorIcon.HARD_DRIVES,
        icon_size=5.2,
    ),
    xy=(26.5, 65.5),
)

s2 = g2.add(
    Node(
        "Aqua Trivy Container\nNo docker.sock Mount\nShared .pni/cache/trivy-cache",
        width=45.0,
        height=19.0,
        icon=PhosphorIcon.SHIELD_WARNING,
        icon_size=5.4,
        card_style=Styles.SecondaryNeutral.patch(shape_r=1.5),
    ),
    xy=(26.5, 40.5),
)

s3 = g2.add(
    Node(
        "App vs OS CVE Split\nIaC Misconfigs & Redacted\nSecrets -> SecurityFacts",
        width=45.0,
        height=18.5,
        icon=PhosphorIcon.LOCK_KEY,
        icon_size=5.2,
        card_style=Styles.PrimaryNeutral.patch(shape_r=1.5),
    ),
    xy=(26.5, 15.5),
)

g3 = diag.add(
    NodeGroup(
        title="3. web_pentest (Loopback Probe)",
        width=53.0,
        height=88.0,
        style=Styles.Neutral.patch(shape_r=2.0),
        text_style=Styles.DangerBold.patch(text_size=10.5, halign="left", valign="top"),
    ),
    xy=(120.0, 4.0),
)

p1 = g3.add(
    Node(
        "server_plan.py\nBoot Target Web Container\nBound to 127.0.0.1:<port>",
        width=45.0,
        height=18.5,
        icon=PhosphorIcon.GLOBE,
        icon_size=5.2,
    ),
    xy=(26.5, 65.5),
)

p2 = g3.add(
    Node(
        ".pni/pentests/<target>/\npytest + httpx Suite\n(Baseline + AST Route Probes)",
        width=45.0,
        height=19.0,
        icon=PhosphorIcon.BUG,
        icon_size=5.4,
        style=Styles.DangerBold,
        card_style=Styles.DangerNeutral.patch(shape_r=1.5),
    ),
    xy=(26.5, 40.5),
)

p3 = g3.add(
    Node(
        "Clean Teardown & Parse\nCWE-Tagged Findings\n-> PentestFacts JSON",
        width=45.0,
        height=18.5,
        icon=PhosphorIcon.FILE_TEXT,
        icon_size=5.2,
        style=Styles.SuccessBold,
        card_style=Styles.SuccessNeutral.patch(shape_r=1.5),
    ),
    xy=(26.5, 15.5),
)

diag.connect(r1, r2, routing="orthogonal")
diag.connect(r2, r3, routing="orthogonal")
diag.connect(r1, s1, routing="orthogonal", style=Styles.PrimaryBold)
diag.connect(s1, s2, routing="orthogonal")
diag.connect(s2, s3, routing="orthogonal")
diag.connect(s1, p1, routing="orthogonal", style=Styles.PrimaryBold)
diag.connect(p1, p2, routing="orthogonal", style=Styles.DangerBold)
diag.connect(p2, p3, routing="orthogonal", style=Styles.SuccessBold)

diag.draw(xy=(0.0, 0.0))
save()

2.1 隔離コンテナランタイム検証 (run_check -> RuntimeFacts)

src/pni/_actions/runtime_check/ に実装された run_runtime_check() は、隔離コンテナ内でビルド可能性、単体テスト実行、カバレッジ計測、および起動健全性を検証し、.pni/cache/<workflow_id>/runtime/runtime_facts.json に永続化します。

  • ハーネス生成 & イメージビルド (selector.py): プロジェクト構成に応じた .pni/dockerfiles/ テンプレート(uv, poetry, pip, maven, gradle, composer, go, npm, pnpm, yarn, raw)を選択し、プロジェクト Dockerfile の検証とテストハーネスイメージのビルドを行います(go.dockerfile における非 root USER pni と事前ウォームアップ済み /go/cache、および node.dockerfile における @playwright/test / playwright / @vitest/browser 検出時の Playwright Headless Chromium 自動プロビジョニングを含む)。
  • オフライン単体テスト & 実測カバレッジ (--network=none): 外部ネットワーク通信を決定論的に遮断する --network=none でテストスイートを実行し、JUnit XML(TestExecutionResult + FailedTestCase 抜粋)や Node テストランナー出力(@web/test-runner, Mocha, Vitest, Jest)を解析するとともに、pytest-cov JSON、JaCoCo XML、Clover XML、go test -coverprofile、または Vitest/Jest の coverage-summary.json / lcov.info レポートから行/分岐カバレッジ(CoverageResult + lowest_covered_modules)を抽出します。
  • アーキタイプ別スモークプローブ (smoke.py): runtime_types に応じたコンテナ起動プローブを実行し(library: クリーンインポート検証、cli: --help 終了コード 0 検証、cli+library: 両方の複合検証、web_api: 起動 + ループバック HTTP 疎通検証)、失敗要因を BootFailureKind に分類します。

2.2 ソケットレスコンテナ脆弱性 & シークレットスキャン (security_scan -> SecurityFacts)

src/pni/_actions/security_scan/ に実装された run_security_scan() は、共有脆弱性 DB キャッシュ(.pni/cache/trivy-cache/)をマウントしたソケットレスコンテナ内で Aqua Trivy(ghcr.io/aquasecurity/trivy)を実行し、.pni/cache/<workflow_id>/security/security_facts.json に永続化します。

  • docker.sock 不要の二面スキャン: ホストの /var/run/docker.sock を一切マウントせず、リポジトリファイルシステム(scan_filesystem)と docker save / podman save でエクスポートした解決済みコンテナイメージ tar(scan_resolved_image)の両方をスキャンします。
  • 4段階の脆弱性スコープ分類(runtime_core, dev_or_optional, os_package, harness_os)とマスク済みシークレット: 重複排除された CVE を app_vuln_counts と os_vuln_counts に分離し、dep_scopes.py によって pyproject.toml/uv.lock、pom.xml、composer.json、およびモノレポの Node ロックファイル(pnpm-lock.yaml, package-lock.json, yarn.lock)の依存スコープやコンテナ内グローバルツールチェーンパス(/usr/local/lib/node_modules 等)を正確に分類した上で、IaC/Dockerfile の misconfigurations およびマスク済み SecretFindingItem を抽出します。

2.3 ライブループバック Web ペネトレーションテスト (web_pentest -> PentestFacts)

src/pni/_actions/pentest/ に実装された run_web_pentest() は、Web アプリケーションに対する動的なブラックボックス HTTP セキュリティプローブを実行し、.pni/cache/<workflow_id>/pentest/pentest_facts.json に永続化します。

  • フェイルクローズドな明示的プローブスイート (.pni/pentests/<target>/): web_pentest を含むワークフローは、.pni/pentests/<target>/ に conftest.py と test_*.py が存在しない限り pni workflows start 時にフェイルクローズドでブロックします。pni pentests init -w <workflow_id> を実行すると、ベースラインのセキュリティヘッダ・CORS・HTTP メソッド検証に加え、AstFacts.api_endpoints から自動合成された test_target_surface.py ルートプローブが生成されます。
  • ループバックコンテナ実行 (127.0.0.1): server_plan.py がホストのループバック(127.0.0.1:<port>)に厳密にバインドされたコンテナ内で対象 Web サーバーを起動し、ライブエンドポイント(または明示的な --base-url)に対して pytest + httpx を実行した後、コンテナをクリーンに破棄して JUnit XML の失敗を CWE タグ付き PentestFindingItem レコードへ変換します。
# AST 検出ルートから .pni/pentests/<target>/ を生成し、ループバックコンテナに対して実行
pni pentests init -w <workflow_id>
pni pentests run -w <workflow_id>

3. グラフ・契約駆動マイグレーション解析器 (migration_analyze -> MigrationFacts)

src/pni/_actions/migration_analyze/ に実装された run_migration_analyze() は、完了済みの based_on 監査実行に紐づく category: migration ワークフローを支え、.pni/cache/<workflow_id>/migration_facts.json に永続化します。

  • Tarjan SCC 循環切断 & トポロジカル Wave 1..4 (graph_waves.py): internal_import_graph 内の強連結成分(SCC)を検出し、最小限の cycle_cuts(CycleCutSuggestion)を推奨するとともに、末端の DTO/ユーティリティ(Wave 1)からドメイン/サービス層(Waves 2..3)、エントリポイント(Wave 4)までモジュールを段階分けします。
  • 暗黙的契約、境界タッチポイント、および DEC-XX 候補抽出: 型付けされていないリクエスト/レスポンスキー(contracts.py の implicit_contracts)および env_contracts を復元し、in_memory_state, persistence_db, external_http_rpc の結合箇所(touchpoints.py の boundary_touchpoints)を特定します。さらに自動コード変換ツール(codemods.py の ruff, openrewrite, rector, gofmt, jscodeshift)をマッチングし、仕様かバグか曖昧なレガシー挙動を DEC-XX spec_vs_bug_candidates(ambiguities.py)として抽出します。

続いて、これらの決定論的ファクトが 7軸品質スコアリングモデル および Drawlib ビジュアルレポーター にどのように統合されるかを確認するか、対応 6 言語マトリクス で各言語の解析詳細を参照してください。