Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

## Table of Contents

- [What's new (2026-06-20) — SARIF 2.1.0 Findings Export](#whats-new-2026-06-20--sarif-210-findings-export)
- [What's new (2026-06-20) — Text PII Detection & Redaction](#whats-new-2026-06-20--text-pii-detection--redaction)
- [What's new (2026-06-20) — Self-Healing Locator Write-Back](#whats-new-2026-06-20--self-healing-locator-write-back)
- [What's new (2026-06-20) — DMN-Style Decision Tables](#whats-new-2026-06-20--dmn-style-decision-tables)
Expand Down Expand Up @@ -108,6 +109,12 @@

---

## What's new (2026-06-20) — SARIF 2.1.0 Findings Export

Unify scanner findings for GitHub code scanning. Full reference: [`docs/source/Eng/doc/new_features/v56_features_doc.rst`](docs/source/Eng/doc/new_features/v56_features_doc.rst).

- **`to_sarif` / `write_sarif` / `make_finding` / `from_lint_issues` / `from_audit_findings`** (`AC_export_sarif`, `ac_export_sarif`): the framework's findings producers (action-lint, secrets scan, WCAG audit, guardrail) had no common export. This builds a SARIF 2.1.0 document — with auto rule catalog and stable `partialFingerprints` for cross-run dedupe — that GitHub/Azure DevOps code scanning ingests as line-anchored alerts. Pure-stdlib `json`+`hashlib`; adapters normalize the existing lint/audit shapes.

## What's new (2026-06-20) — Text PII Detection & Redaction

Mask PII in text before it leaks. Full reference: [`docs/source/Eng/doc/new_features/v55_features_doc.rst`](docs/source/Eng/doc/new_features/v55_features_doc.rst).
Expand Down
7 changes: 7 additions & 0 deletions README/README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

## 目录

- [本次更新 (2026-06-20) — SARIF 2.1.0 发现项目导出](#本次更新-2026-06-20--sarif-210-发现项目导出)
- [本次更新 (2026-06-20) — 文本 PII 检测与遮蔽](#本次更新-2026-06-20--文本-pii-检测与遮蔽)
- [本次更新 (2026-06-20) — 自我修复定位器回写](#本次更新-2026-06-20--自我修复定位器回写)
- [本次更新 (2026-06-20) — DMN 式决策表](#本次更新-2026-06-20--dmn-式决策表)
Expand Down Expand Up @@ -107,6 +108,12 @@

---

## 本次更新 (2026-06-20) — SARIF 2.1.0 发现项目导出

统一扫描结果供 GitHub 代码扫描。完整参考:[`docs/source/Zh/doc/new_features/v56_features_doc.rst`](../docs/source/Zh/doc/new_features/v56_features_doc.rst)。

- **`to_sarif` / `write_sarif` / `make_finding` / `from_lint_issues` / `from_audit_findings`**(`AC_export_sarif`、`ac_export_sarif`):框架的发现项目产生器(action-lint、密钥扫描、WCAG 审计、guardrail)缺乏共通导出。本功能建立 SARIF 2.1.0 文件(自动规则目录 + 稳定 `partialFingerprints` 跨运行去重),供 GitHub/Azure DevOps 代码扫描以定位到行的警示导入。纯标准库 `json`+`hashlib`;转接器规范化既有 lint/audit 形状。

## 本次更新 (2026-06-20) — 文本 PII 检测与遮蔽

在文本泄漏前遮蔽 PII。完整参考:[`docs/source/Zh/doc/new_features/v55_features_doc.rst`](../docs/source/Zh/doc/new_features/v55_features_doc.rst)。
Expand Down
7 changes: 7 additions & 0 deletions README/README_zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

## 目錄

- [本次更新 (2026-06-20) — SARIF 2.1.0 發現項目匯出](#本次更新-2026-06-20--sarif-210-發現項目匯出)
- [本次更新 (2026-06-20) — 文字 PII 偵測與遮蔽](#本次更新-2026-06-20--文字-pii-偵測與遮蔽)
- [本次更新 (2026-06-20) — 自我修復定位器回寫](#本次更新-2026-06-20--自我修復定位器回寫)
- [本次更新 (2026-06-20) — DMN 式決策表](#本次更新-2026-06-20--dmn-式決策表)
Expand Down Expand Up @@ -107,6 +108,12 @@

---

## 本次更新 (2026-06-20) — SARIF 2.1.0 發現項目匯出

統一掃描結果供 GitHub 程式碼掃描。完整參考:[`docs/source/Zh/doc/new_features/v56_features_doc.rst`](../docs/source/Zh/doc/new_features/v56_features_doc.rst)。

- **`to_sarif` / `write_sarif` / `make_finding` / `from_lint_issues` / `from_audit_findings`**(`AC_export_sarif`、`ac_export_sarif`):框架的發現項目產生器(action-lint、密鑰掃描、WCAG 稽核、guardrail)缺乏共通匯出。本功能建立 SARIF 2.1.0 文件(自動規則目錄 + 穩定 `partialFingerprints` 跨執行去重),供 GitHub/Azure DevOps 程式碼掃描以定位到行的警示匯入。純標準函式庫 `json`+`hashlib`;轉接器正規化既有 lint/audit 形狀。

## 本次更新 (2026-06-20) — 文字 PII 偵測與遮蔽

在文字洩漏前遮蔽 PII。完整參考:[`docs/source/Zh/doc/new_features/v55_features_doc.rst`](../docs/source/Zh/doc/new_features/v55_features_doc.rst)。
Expand Down
46 changes: 46 additions & 0 deletions docs/source/Eng/doc/new_features/v56_features_doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
SARIF 2.1.0 Findings Export
===========================

The framework has several findings producers — action-lint, the secrets scan,
the WCAG/a11y audit, the guardrail — but no common export, so results couldn't
land in GitHub / Azure DevOps **code scanning** (the durable, deduplicated,
line-anchored alert store). SARIF 2.1.0 (OASIS) is that interchange format.

``to_sarif`` builds a SARIF document from a list of normalized *findings*
(``{rule_id, level, message, file?, line?}``), with adapters for the existing
lint / audit shapes and stable ``partialFingerprints`` so the same issue
deduplicates across runs. Pure standard library (``json`` + ``hashlib``);
imports no ``PySide6``.

Headless API
------------

.. code-block:: python

from je_auto_control import (
make_finding, to_sarif, write_sarif, from_lint_issues,
from_audit_findings)

findings = [
make_finding("AC_SHELL", "shell command not allow-listed",
level="error", file="flow.json", line=12),
*from_lint_issues(lint_issues, file="flow.json"),
*from_audit_findings(wcag_report["findings"]),
]
write_sarif(findings, "results.sarif", tool_name="AutoControl")
# upload results.sarif via the GitHub "upload-sarif" action

``make_finding`` builds one normalized finding; ``from_lint_issues`` (maps
``index/severity/code/message``) and ``from_audit_findings`` (maps
``sc/criterion/kind/severity``) adapt the existing producers; ``to_sarif``
auto-derives the rule catalog and attaches a stable fingerprint per result;
``write_sarif`` serializes to a file. Severity strings map to SARIF
``error`` / ``warning`` / ``note``.

Executor command
----------------

``AC_export_sarif`` takes ``findings`` (a list, or JSON string) plus optional
``path`` and ``tool_name`` and returns ``{sarif, path?}``. The same operation is
exposed as the MCP tool ``ac_export_sarif`` and as a Script Builder command under
**Report**.
1 change: 1 addition & 0 deletions docs/source/Eng/eng_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Comprehensive guides for all AutoControl features.
doc/new_features/v53_features_doc
doc/new_features/v54_features_doc
doc/new_features/v55_features_doc
doc/new_features/v56_features_doc
doc/ocr_backends/ocr_backends_doc
doc/observability/observability_doc
doc/operations_layer/operations_layer_doc
Expand Down
41 changes: 41 additions & 0 deletions docs/source/Zh/doc/new_features/v56_features_doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
SARIF 2.1.0 發現項目匯出
========================

框架有多個發現項目產生器 —— action-lint、密鑰掃描、WCAG/a11y 稽核、guardrail —— 但缺乏
共通匯出,因此結果無法進入 GitHub / Azure DevOps 的**程式碼掃描**(持久、去重、定位到行
的警示儲存)。SARIF 2.1.0(OASIS)正是該交換格式。

``to_sarif`` 由一份正規化*發現項目*清單(``{rule_id, level, message, file?, line?}``)建
立 SARIF 文件,並為既有 lint / audit 形狀提供轉接器,加上穩定的 ``partialFingerprints``
讓同一問題能跨執行去重。純標準函式庫(``json`` + ``hashlib``);不匯入 ``PySide6``。

無頭 API
--------

.. code-block:: python

from je_auto_control import (
make_finding, to_sarif, write_sarif, from_lint_issues,
from_audit_findings)

findings = [
make_finding("AC_SHELL", "shell command not allow-listed",
level="error", file="flow.json", line=12),
*from_lint_issues(lint_issues, file="flow.json"),
*from_audit_findings(wcag_report["findings"]),
]
write_sarif(findings, "results.sarif", tool_name="AutoControl")
# 以 GitHub「upload-sarif」action 上傳 results.sarif

``make_finding`` 建立單一正規化發現項目;``from_lint_issues``(對映
``index/severity/code/message``)與 ``from_audit_findings``(對映
``sc/criterion/kind/severity``)轉接既有產生器;``to_sarif`` 自動衍生規則目錄並為每個結
果附上穩定指紋;``write_sarif`` 序列化成檔案。嚴重度字串對映為 SARIF 的 ``error`` /
``warning`` / ``note``。

執行器指令
----------

``AC_export_sarif`` 接受 ``findings``(清單或 JSON 字串)以及選用的 ``path`` 與
``tool_name``,回傳 ``{sarif, path?}``。相同操作亦提供為 MCP 工具 ``ac_export_sarif``,以
及 Script Builder 中 **Report** 分類下的指令。
1 change: 1 addition & 0 deletions docs/source/Zh/zh_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ AutoControl 所有功能的完整使用指南。
doc/new_features/v53_features_doc
doc/new_features/v54_features_doc
doc/new_features/v55_features_doc
doc/new_features/v56_features_doc
doc/ocr_backends/ocr_backends_doc
doc/observability/observability_doc
doc/operations_layer/operations_layer_doc
Expand Down
6 changes: 6 additions & 0 deletions je_auto_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@
from je_auto_control.utils.pii_text import (
PIIFinding, detect_pii, redact_pii_text,
)
# SARIF 2.1.0 export (unify findings for code-scanning)
from je_auto_control.utils.sarif import (
from_audit_findings, from_lint_issues, make_finding, to_sarif, write_sarif,
)
# Background popup/interrupt watchdog (unattended automation)
from je_auto_control.utils.watchdog import (
PopupWatchdog, WatchdogRule, default_popup_watchdog,
Expand Down Expand Up @@ -761,6 +765,8 @@ def start_autocontrol_gui(*args, **kwargs):
"DecisionTable", "Rule", "evaluate_table",
"RepairStore", "RepairSuggestion", "repair_from_heal",
"PIIFinding", "detect_pii", "redact_pii_text",
"from_audit_findings", "from_lint_issues", "make_finding", "to_sarif",
"write_sarif",
# MCP server
"AuditLogger", "HttpMCPServer", "MCPContent", "MCPPrompt",
"MCPPromptArgument", "MCPResource", "MCPServer", "MCPTool",
Expand Down
13 changes: 13 additions & 0 deletions je_auto_control/gui/script_builder/command_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,19 @@ def _add_misc_specs(specs: List[CommandSpec]) -> None:
),
description="Redact PII in text (label/mask/partial/hash).",
))
specs.append(CommandSpec(
"AC_export_sarif", "Report", "Export SARIF (Code Scanning)",
fields=(
FieldSpec("findings", FieldType.STRING,
placeholder='[{"rule_id": "AC1", "message": "...", '
'"level": "error"}]'),
FieldSpec("path", FieldType.STRING, optional=True,
placeholder="results.sarif"),
FieldSpec("tool_name", FieldType.STRING, optional=True,
default="AutoControl"),
),
description="Unify findings into a SARIF 2.1.0 document.",
))
specs.append(CommandSpec(
"AC_generate_sop", "Report", "Generate SOP Document",
fields=(
Expand Down
15 changes: 15 additions & 0 deletions je_auto_control/utils/executor/action_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3390,6 +3390,20 @@ def _redact_pii(text: str, kinds: Any = None, mode: str = "label",
mask_char=mask_char)}


def _export_sarif(findings: Any, path: Optional[str] = None,
tool_name: str = "AutoControl") -> Dict[str, Any]:
"""Adapter: build (and optionally write) a SARIF 2.1.0 document."""
import json
from je_auto_control.utils.sarif import to_sarif, write_sarif
if isinstance(findings, str):
findings = json.loads(findings)
document = to_sarif(findings, tool_name=tool_name)
result: Dict[str, Any] = {"sarif": document}
if path:
result["path"] = write_sarif(findings, path, tool_name=tool_name)
return result


class Executor:
"""
Executor
Expand Down Expand Up @@ -3680,6 +3694,7 @@ def __init__(self):
"AC_repair_approve": _repair_approve,
"AC_detect_pii": _detect_pii,
"AC_redact_pii": _redact_pii,
"AC_export_sarif": _export_sarif,
"AC_a11y_record_start": _a11y_record_start,
"AC_a11y_record_stop": _a11y_record_stop,
"AC_a11y_record_events": _a11y_record_events,
Expand Down
21 changes: 20 additions & 1 deletion je_auto_control/utils/mcp_server/tools/_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -3338,6 +3338,25 @@ def pii_text_tools() -> List[MCPTool]:
]


def sarif_tools() -> List[MCPTool]:
return [
MCPTool(
name="ac_export_sarif",
description=("Build a SARIF 2.1.0 document from normalized "
"'findings' ([{rule_id, level, message, file?, "
"line?}]) for GitHub/Azure code-scanning. Optional "
"'path' writes it; 'tool_name' labels the driver. "
"Returns {sarif, path?}."),
input_schema=schema(
{"findings": {"type": "array", "items": {"type": "object"}},
"path": {"type": "string"},
"tool_name": {"type": "string"}}, ["findings"]),
handler=h.export_sarif,
annotations=READ_ONLY,
),
]


def unattended_tools() -> List[MCPTool]:
return [
MCPTool(
Expand Down Expand Up @@ -4402,7 +4421,7 @@ def media_assert_tools() -> List[MCPTool]:
locale_tools, voice_tools, coordinate_space_tools, loop_guard_tools,
process_mining_tools, asset_tools, events_tools, notify_channel_tools,
jsonpath_tools, saga_tools, decision_table_tools, locator_repair_tools,
pii_text_tools,
pii_text_tools, sarif_tools,
screen_record_tools,
process_and_shell_tools, remote_desktop_tools, gamepad_tools,
usb_passthrough_tools, assertion_tools, data_source_tools,
Expand Down
8 changes: 8 additions & 0 deletions je_auto_control/utils/mcp_server/tools/_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,14 @@ def redact_pii(text, kinds=None, mode="label", mask_char="*"):
mask_char=mask_char)}


def export_sarif(findings, path=None, tool_name="AutoControl"):
from je_auto_control.utils.sarif import to_sarif, write_sarif
result = {"sarif": to_sarif(findings, tool_name=tool_name)}
if path:
result["path"] = write_sarif(findings, path, tool_name=tool_name)
return result


def vlm_locate(description: str,
screen_region: Optional[List[int]] = None,
model: Optional[str] = None) -> Optional[List[int]]:
Expand Down
10 changes: 10 additions & 0 deletions je_auto_control/utils/sarif/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Export findings as SARIF 2.1.0 for GitHub/Azure code-scanning."""
from je_auto_control.utils.sarif.sarif import (
from_audit_findings, from_lint_issues, make_finding, result_fingerprint,
to_sarif, write_sarif,
)

__all__ = [
"from_audit_findings", "from_lint_issues", "make_finding",
"result_fingerprint", "to_sarif", "write_sarif",
]
Loading
Loading