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-21) — JSON Schema Validation](#whats-new-2026-06-21--json-schema-validation)
- [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)
Expand Down Expand Up @@ -109,6 +110,12 @@

---

## What's new (2026-06-21) — JSON Schema Validation

Validate nested JSON against a real schema. Full reference: [`docs/source/Eng/doc/new_features/v57_features_doc.rst`](docs/source/Eng/doc/new_features/v57_features_doc.rst).

- **`validate_json` / `is_valid` / `assert_schema`** (`AC_validate_json`, `ac_validate_json`): the framework only *generated* JSON Schema and `data_quality` is a flat per-column checker — neither could validate a nested API request/response body. This adds the consumer: a JSON Schema (Draft 2020-12 subset) validator that reports **every** violation as `{path, keyword, message}` (e.g. `$.age maximum`). Covers `type` (incl. integral-float `integer`), `enum`/`const`, numeric/string bounds, array & object keywords, `allOf`/`anyOf`/`oneOf`/`not`, boolean schemas and local `$ref`. Pure-stdlib `re`; pairs with `json_query` and the `http_request` helper.

## 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).
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-21) — JSON Schema 验证](#本次更新-2026-06-21--json-schema-验证)
- [本次更新 (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--自我修复定位器回写)
Expand Down Expand Up @@ -108,6 +109,12 @@

---

## 本次更新 (2026-06-21) — JSON Schema 验证

以真正的 schema 验证嵌套 JSON。完整参考:[`docs/source/Zh/doc/new_features/v57_features_doc.rst`](../docs/source/Zh/doc/new_features/v57_features_doc.rst)。

- **`validate_json` / `is_valid` / `assert_schema`**(`AC_validate_json`、`ac_validate_json`):框架过去只会*产生* JSON Schema,而 `data_quality` 是扁平的逐列检查器 —— 两者都无法验证嵌套的 API 请求/响应内容。本功能补上消费端:一个 JSON Schema(Draft 2020-12 子集)验证器,将**每一个**违规以 `{path, keyword, message}` 报告(例如 `$.age maximum`)。涵盖 `type`(含整数值浮点数的 `integer`)、`enum`/`const`、数字/字符串界限、数组与对象关键字、`allOf`/`anyOf`/`oneOf`/`not`、布尔 schema 与本地 `$ref`。纯标准库 `re`;与 `json_query` 及 `http_request` 辅助函数搭配。

## 本次更新 (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)。
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-21) — JSON Schema 驗證](#本次更新-2026-06-21--json-schema-驗證)
- [本次更新 (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--自我修復定位器回寫)
Expand Down Expand Up @@ -108,6 +109,12 @@

---

## 本次更新 (2026-06-21) — JSON Schema 驗證

以真正的 schema 驗證巢狀 JSON。完整參考:[`docs/source/Zh/doc/new_features/v57_features_doc.rst`](../docs/source/Zh/doc/new_features/v57_features_doc.rst)。

- **`validate_json` / `is_valid` / `assert_schema`**(`AC_validate_json`、`ac_validate_json`):框架過去只會*產生* JSON Schema,而 `data_quality` 是扁平的逐欄檢查器 —— 兩者都無法驗證巢狀的 API 請求/回應內容。本功能補上消費端:一個 JSON Schema(Draft 2020-12 子集)驗證器,將**每一個**違規以 `{path, keyword, message}` 回報(例如 `$.age maximum`)。涵蓋 `type`(含整數值浮點數的 `integer`)、`enum`/`const`、數字/字串界限、陣列與物件關鍵字、`allOf`/`anyOf`/`oneOf`/`not`、布林 schema 與本地 `$ref`。純標準函式庫 `re`;與 `json_query` 及 `http_request` 輔助函式搭配。

## 本次更新 (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)。
Expand Down
73 changes: 73 additions & 0 deletions docs/source/Eng/doc/new_features/v57_features_doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
JSON Schema Validation
======================

The framework only ever *generated* JSON Schema (action-lint, the tool-use
schema), and ``data_quality.validate_rows`` is a flat, per-column table checker —
neither can validate a nested API request/response body against a real schema.
This adds the missing consumer: validate an in-memory value against a JSON
Schema (Draft 2020-12 subset) and report **every** violation with a readable
path.

``validate_json`` returns a ``SchemaValidationResult`` (``ok`` plus an
``errors`` list of ``{path, keyword, message}``); ``is_valid`` is the boolean
shortcut; ``assert_schema`` raises ``AutoControlAssertionException`` with a
joined summary. Pure standard library (``re``); imports no ``PySide6``.

Supported keywords
------------------

* ``type`` — including ``integer`` matching integral floats (``5.0``) but never
booleans; ``enum`` / ``const`` (keeping ``True`` and ``1`` distinct).
* numbers — ``minimum`` / ``maximum`` / ``exclusiveMinimum`` /
``exclusiveMaximum`` / ``multipleOf``.
* strings — ``minLength`` / ``maxLength`` / ``pattern``.
* arrays — ``minItems`` / ``maxItems`` / ``uniqueItems`` / ``items`` /
``prefixItems`` / ``contains``.
* objects — ``required`` / ``minProperties`` / ``maxProperties`` /
``properties`` / ``patternProperties`` / ``additionalProperties``.
* combinators — ``allOf`` / ``anyOf`` / ``oneOf`` / ``not``; boolean schemas
(``True`` / ``False``); local ``$ref`` (``#/$defs/...`` JSON Pointer).

Remote ``$ref`` and ``format`` assertions are intentionally out of scope.

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

.. code-block:: python

from je_auto_control import validate_json, is_valid, assert_schema

schema = {
"type": "object",
"required": ["name", "age"],
"additionalProperties": False,
"properties": {
"name": {"type": "string", "minLength": 1},
"age": {"type": "integer", "minimum": 0, "maximum": 130},
"roles": {"type": "array", "items": {"enum": ["admin", "user"]},
"uniqueItems": True},
},
}

result = validate_json({"name": "", "age": 200, "extra": 1}, schema)
# result.ok is False
for error in result.errors:
print(error["path"], error["keyword"], "-", error["message"])
# $.name minLength - shorter than 1
# $.age maximum - greater than maximum 130
# $.extra additionalProperties - additional property not allowed

if is_valid(payload, schema):
... # boolean shortcut

assert_schema(payload, schema) # raises on the first invalid value

This pairs naturally with the existing ``json_query`` (extract a value) and the
``http_request`` helper (validate an API response body before acting on it).

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

``AC_validate_json`` takes ``data`` and ``schema`` (each a list/object, or a
JSON string) and returns ``{ok, errors}``. The same operation is exposed as the
MCP tool ``ac_validate_json`` and as a Script Builder command under **Data**.
1 change: 1 addition & 0 deletions docs/source/Eng/eng_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Comprehensive guides for all AutoControl features.
doc/new_features/v54_features_doc
doc/new_features/v55_features_doc
doc/new_features/v56_features_doc
doc/new_features/v57_features_doc
doc/ocr_backends/ocr_backends_doc
doc/observability/observability_doc
doc/operations_layer/operations_layer_doc
Expand Down
71 changes: 71 additions & 0 deletions docs/source/Zh/doc/new_features/v57_features_doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
JSON Schema 驗證
================

框架過去只會*產生* JSON Schema(action-lint、tool-use schema),而
``data_quality.validate_rows`` 是扁平、逐欄的表格檢查器 —— 兩者都無法以真正的 schema 驗證
巢狀的 API 請求/回應內容。這補上了缺少的消費端:以 JSON Schema(Draft 2020-12 子集)驗證
一個記憶體中的值,並以可讀的路徑回報**每一個**違規。

``validate_json`` 回傳 ``SchemaValidationResult``(``ok`` 加上一個由
``{path, keyword, message}`` 組成的 ``errors`` 清單);``is_valid`` 是布林捷徑;
``assert_schema`` 會以彙整後的摘要拋出 ``AutoControlAssertionException``。純標準函式庫
(``re``);不匯入 ``PySide6``。

支援的關鍵字
------------

* ``type`` —— 包含 ``integer`` 會匹配整數值的浮點數(``5.0``)但永不匹配布林值;
``enum`` / ``const``(讓 ``True`` 與 ``1`` 保持相異)。
* 數字 —— ``minimum`` / ``maximum`` / ``exclusiveMinimum`` / ``exclusiveMaximum`` /
``multipleOf``。
* 字串 —— ``minLength`` / ``maxLength`` / ``pattern``。
* 陣列 —— ``minItems`` / ``maxItems`` / ``uniqueItems`` / ``items`` /
``prefixItems`` / ``contains``。
* 物件 —— ``required`` / ``minProperties`` / ``maxProperties`` / ``properties`` /
``patternProperties`` / ``additionalProperties``。
* 組合器 —— ``allOf`` / ``anyOf`` / ``oneOf`` / ``not``;布林 schema(``True`` /
``False``);本地 ``$ref``(``#/$defs/...`` JSON Pointer)。

遠端 ``$ref`` 與 ``format`` 斷言刻意排除在範圍之外。

無頭 API
--------

.. code-block:: python

from je_auto_control import validate_json, is_valid, assert_schema

schema = {
"type": "object",
"required": ["name", "age"],
"additionalProperties": False,
"properties": {
"name": {"type": "string", "minLength": 1},
"age": {"type": "integer", "minimum": 0, "maximum": 130},
"roles": {"type": "array", "items": {"enum": ["admin", "user"]},
"uniqueItems": True},
},
}

result = validate_json({"name": "", "age": 200, "extra": 1}, schema)
# result.ok 為 False
for error in result.errors:
print(error["path"], error["keyword"], "-", error["message"])
# $.name minLength - shorter than 1
# $.age maximum - greater than maximum 130
# $.extra additionalProperties - additional property not allowed

if is_valid(payload, schema):
... # 布林捷徑

assert_schema(payload, schema) # 遇到第一個無效值即拋出

這與既有的 ``json_query``(擷取一個值)以及 ``http_request`` 輔助函式(在處理前先驗證 API
回應內容)自然搭配。

執行器命令
----------

``AC_validate_json`` 接受 ``data`` 與 ``schema``(各為 list/object 或 JSON 字串),回傳
``{ok, errors}``。同一操作亦以 MCP 工具 ``ac_validate_json`` 以及 Script Builder 中
**Data** 分類下的命令提供。
1 change: 1 addition & 0 deletions docs/source/Zh/zh_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ AutoControl 所有功能的完整使用指南。
doc/new_features/v54_features_doc
doc/new_features/v55_features_doc
doc/new_features/v56_features_doc
doc/new_features/v57_features_doc
doc/ocr_backends/ocr_backends_doc
doc/observability/observability_doc
doc/operations_layer/operations_layer_doc
Expand Down
5 changes: 5 additions & 0 deletions je_auto_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@
from je_auto_control.utils.sarif import (
from_audit_findings, from_lint_issues, make_finding, to_sarif, write_sarif,
)
# JSON Schema (Draft 2020-12 subset) validation of parsed JSON
from je_auto_control.utils.json_schema import (
SchemaValidationResult, assert_schema, is_valid, validate_json,
)
# Background popup/interrupt watchdog (unattended automation)
from je_auto_control.utils.watchdog import (
PopupWatchdog, WatchdogRule, default_popup_watchdog,
Expand Down Expand Up @@ -767,6 +771,7 @@ def start_autocontrol_gui(*args, **kwargs):
"PIIFinding", "detect_pii", "redact_pii_text",
"from_audit_findings", "from_lint_issues", "make_finding", "to_sarif",
"write_sarif",
"SchemaValidationResult", "assert_schema", "is_valid", "validate_json",
# MCP server
"AuditLogger", "HttpMCPServer", "MCPContent", "MCPPrompt",
"MCPPromptArgument", "MCPResource", "MCPServer", "MCPTool",
Expand Down
10 changes: 10 additions & 0 deletions je_auto_control/gui/script_builder/command_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,16 @@ def _add_misc_specs(specs: List[CommandSpec]) -> None:
),
description="Extract a {key: jsonpath} mapping into a flat object.",
))
specs.append(CommandSpec(
"AC_validate_json", "Data", "JSON Schema: Validate",
fields=(
FieldSpec("data", FieldType.STRING,
placeholder='{"name": "Jo", "age": 30}'),
FieldSpec("schema", FieldType.STRING,
placeholder='{"type": "object", "required": ["name"]}'),
),
description="Validate JSON against a JSON Schema; returns {ok, errors}.",
))
specs.append(CommandSpec(
"AC_run_saga", "Flow", "Run Saga (Compensating Rollback)",
fields=(
Expand Down
12 changes: 12 additions & 0 deletions je_auto_control/utils/executor/action_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3316,6 +3316,17 @@ def _json_extract(data: Any, mapping: Any) -> Dict[str, Any]:
return {"result": json_extract(data, mapping)}


def _validate_json(data: Any, schema: Any) -> Dict[str, Any]:
"""Adapter: validate data against a JSON Schema (each JSON string or object)."""
import json
from je_auto_control.utils.json_schema import validate_json
if isinstance(data, str):
data = json.loads(data)
if isinstance(schema, str):
schema = json.loads(schema)
return validate_json(data, schema).to_dict()


def _run_saga(steps: Any) -> Dict[str, Any]:
"""Adapter: run a saga (steps with compensating rollback) from a spec."""
import json
Expand Down Expand Up @@ -3686,6 +3697,7 @@ def __init__(self):
"AC_notify_webhook": _notify_webhook,
"AC_json_query": _json_query,
"AC_json_extract": _json_extract,
"AC_validate_json": _validate_json,
"AC_run_saga": _run_saga,
"AC_decision_table": _decision_table,
"AC_repair_record": _repair_record,
Expand Down
8 changes: 8 additions & 0 deletions je_auto_control/utils/json_schema/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""JSON Schema (Draft 2020-12 subset) validation over parsed JSON."""
from je_auto_control.utils.json_schema.json_schema import (
SchemaValidationResult, assert_schema, is_valid, validate_json,
)

__all__ = [
"SchemaValidationResult", "assert_schema", "is_valid", "validate_json",
]
Loading
Loading