Skip to content

Commit 7ae25de

Browse files
authored
Merge pull request #33 from A3S-Lab/chore/sync-acl-schema-admission-20260720
docs: sync ACL schema admission
2 parents e60e6a0 + 07b7442 commit 7ae25de

8 files changed

Lines changed: 186 additions & 17 deletions

File tree

apps/docs/content/docs/cn/acl/index.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Rust crate 与 Node.js/TypeScript SDK,可以把 ACL 文本解析成 AST,也
1919
| --- | --- |
2020
| 语法 | ACL attributes、带 label 的 blocks、nested blocks、lists、objects、strings、numbers、booleans、null、function calls、comments,以及 `=` / `:` assignments。 |
2121
| Lexer/parser | Bounded parsing 和 multi-diagnostic collection、stable diagnostic codes、UTF-8 byte spans、comment skipping、string escapes、negative numbers 和 scientific notation。 |
22+
| Admission | Closed-by-default declarative schemas、recursive value rules、stable logical paths、redacted diagnostics,以及 bounded Rust/Node validation reports。 |
2223
| 函数 | 支持把 `env(...)``concat(...)` 和自定义函数名表示为 first-class call values。 |
2324
| AST | `Document``Block`、typed values、builders、value constructors 和 `Value` accessors。 |
2425
| 生成 | Native ACL output、block-header labels、sorted attributes 和 objects、type-stable strings,以及 map generation。 |
@@ -29,10 +30,11 @@ Rust crate 与 Node.js/TypeScript SDK,可以把 ACL 文本解析成 AST,也
2930

3031
- [Syntax](/cn/docs/acl/syntax) 说明 blocks、attributes、values、calls、
3132
comments 和 parser boundaries。
32-
- [Rust API](/cn/docs/acl/rust-api) 覆盖 bounded parsing、multi-diagnostic
33-
collection、canonical digests、generation、builders 和 AST value helpers。
33+
- [Rust API](/cn/docs/acl/rust-api) 覆盖 bounded parsing、schema admission、
34+
multi-diagnostic collection、canonical digests、generation、builders 和 AST
35+
value helpers。
3436
- [Node SDK](/cn/docs/acl/node-sdk) 覆盖 JavaScript/TypeScript parser、
35-
native ACL generator、canonical APIs 和 builders。
37+
schema validator、native ACL generator、canonical APIs 和 builders。
3638
- [Generation And Boundaries](/cn/docs/acl/generation-boundaries) 说明 stable
3739
output、canonical bytes、secret handling 和 host-component ownership。
3840

apps/docs/content/docs/cn/acl/node-sdk.mdx

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Node SDK
3-
description: "@a3s-lab/acl 的 JavaScript/TypeScript bounded parsing、multi-diagnostics、native ACL generation、canonical digests 和 builders。"
3+
description: "@a3s-lab/acl 的 JavaScript/TypeScript bounded parsing、schema admission、multi-diagnostics、native ACL generation、canonical digests 和 builders。"
44
---
55

66
# Node SDK
@@ -47,6 +47,9 @@ const generated = generate(new DocumentBuilder().block(provider).build());
4747
| `collectDiagnostics(input, limits?)` | 在不构造 partial AST 的前提下收集 bounded diagnostics。 |
4848
| `DEFAULT_PARSE_LIMITS` | Document bytes、nesting、collection items、token bytes 和 diagnostic count 的 shared immutable defaults。 |
4949
| `ParseError``DIAGNOSTIC_CODES``DiagnosticReport` | Stable codes、complete spans、UTF-8 byte offsets、redacted messages 和明确的 truncation state。 |
50+
| `validateDocument(document, schema, limits?)` | 使用 declarative schema 验证 parsed `Document`,并返回 bounded report。 |
51+
| `SCHEMA_DIAGNOSTIC_CODES``SchemaDiagnostic``SchemaReport` | Stable schema codes、logical paths、redacted messages 和明确的 truncation state。 |
52+
| `Schema``AttributeSchema``BlockSchema``ValueSchema` | Closed-by-default document、block 和 recursive value rules 的 TypeScript definitions。 |
5053
| `generate(doc)` | 生成 labels 位于 block headers 的 native ACL text。 |
5154
| `canonicalBytes(doc)``canonicalDigest(doc)` | 生成 stable cross-SDK bytes 和带 algorithm prefix 的 SHA-256 digest。 |
5255
| `CanonicalError` | 对 non-finite numbers、non-scalar strings 和 non-portable identifiers 返回不回显值的错误。 |
@@ -99,6 +102,41 @@ Resource-limit diagnostics 仍然是 fatal。Report 最多保存
99102
`maxDiagnostics` 个 errors,只有在继续观察到超出 budget 的 error 后才会把
100103
`truncated` 设为 true。
101104

105+
## Schema Admission
106+
107+
使用显式 limits 解析 untrusted text,然后在 activation 前验证得到的
108+
document:
109+
110+
```typescript
111+
import {parse, validateDocument, type Schema} from '@a3s-lab/acl';
112+
113+
const limits = {maxDiagnostics: 20};
114+
const document = parse('version = 1', limits);
115+
const schema: Schema = {
116+
attributes: {
117+
version: {required: true, value: {kind: 'Number'}},
118+
},
119+
};
120+
const report = validateDocument(document, schema, limits);
121+
```
122+
123+
Schemas 默认拒绝 undeclared attributes、blocks 和 object fields。它们可以声明
124+
required/optional attributes、block occurrence 和 label cardinalities,以及
125+
recursive `Any``String``Number``Bool``Null``List``Object`
126+
`Call``OneOf` rules。Extension points 必须使用相应的显式 allow flag。
127+
128+
Schema reports 使用 stable `acl.schema.*` codes 和
129+
`$.blocks.provider[0].attributes.api_key` 这样的 logical paths。Messages 和
130+
paths 不包含 attribute values、call arguments 或 block labels。Reports 使用
131+
`maxDiagnostics`,只有在继续观察到超出 budget 的 schema error 后才会把
132+
`truncated` 设为 true。
133+
134+
Malformed 或 cyclic programmatic documents、invalid cardinality ranges、empty
135+
unions、unknown schema fields 和 schema cycles 会在 validation 前以
136+
`TypeError` 失败。Schema admission 只验证 document shape;numeric ranges、
137+
secret resolution、provider credentials 和其它 product semantics 仍由 host
138+
component 负责。
139+
102140
## Native And Canonical Output
103141

104142
`generate` 只有一个 native ACL output contract。Labels 保留在 block headers;
@@ -110,5 +148,6 @@ semantically unordered attribute 和 object keys 排序。
110148

111149
## 边界
112150

113-
SDK 是 parser/generator 和 AST builder。它不会加载环境变量、拉取远程配置、验证 provider
114-
credentials,也不会执行 `env(...)` 等函数。
151+
SDK 负责解析、生成、构造和验证 declarative ACL document shapes。它不会加载
152+
环境变量、拉取远程配置、验证 provider credentials,也不会执行 `env(...)`
153+
等函数。

apps/docs/content/docs/cn/acl/rust-api.mdx

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Rust API
3-
description: a3s-acl 的 Rust bounded parsing、multi-diagnostics、canonical digests、native ACL generation、AST 和 builders。
3+
description: a3s-acl 的 Rust bounded parsing、schema admission、multi-diagnostics、canonical digests、native ACL generation、AST 和 builders。
44
---
55

66
# Rust API
@@ -37,6 +37,9 @@ Public crate exports:
3737
| `parse_with_limits``ParseLimits` | 使用显式 document、nesting、collection、token 和 diagnostic limits 解析 untrusted input。 |
3838
| `collect_diagnostics``collect_diagnostics_with_limits` | 在不构造 partial AST 的前提下收集 bounded diagnostics。 |
3939
| `DiagnosticCode``ParseError``DiagnosticReport` | 返回 stable codes、UTF-8 byte spans、redacted messages 和明确的 truncation state。 |
40+
| `validate_document``validate_document_with_limits` | 使用 declarative schema 验证 parsed `Document`,并返回 bounded report。 |
41+
| `Schema``AttributeSchema``BlockSchema``ValueSchema` | 定义 closed-by-default document、block 和 recursive value rules。 |
42+
| `SchemaDiagnosticCode``SchemaDiagnostic``SchemaReport` | 返回 stable schema codes、logical paths、redacted messages 和明确的 truncation state。 |
4043
| `generate` / `generate_acl` |`Document` 生成 ACL text。 |
4144
| `generate_from_map` |`HashMap<String, Value>` 生成 ACL text。 |
4245
| `canonical_bytes``canonical_digest` | 生成 stable cross-SDK bytes 和带 algorithm prefix 的 SHA-256 digest。 |
@@ -86,6 +89,46 @@ Resource-limit diagnostics 仍然是 fatal。Report 最多保存
8689
`max_diagnostics` 个 errors,只有在继续观察到超出 budget 的 error 后才会把
8790
`truncated` 设为 true。
8891

92+
## Schema Admission
93+
94+
使用显式 limits 解析 untrusted text,然后在 activation 前验证得到的
95+
document:
96+
97+
```rust
98+
use a3s_acl::{
99+
parse_with_limits, validate_document_with_limits, AttributeSchema,
100+
ParseLimits, Schema, ValueSchema,
101+
};
102+
103+
let limits = ParseLimits {
104+
max_diagnostics: 20,
105+
..ParseLimits::default()
106+
};
107+
let document = parse_with_limits("version = 1", limits)?;
108+
let schema = Schema::new().attribute(
109+
"version",
110+
AttributeSchema::required(ValueSchema::number()),
111+
);
112+
let report = validate_document_with_limits(&document, &schema, limits);
113+
assert!(report.is_empty());
114+
```
115+
116+
Schemas 默认拒绝 undeclared attributes、blocks 和 object fields。它们可以声明
117+
required/optional attributes、block occurrence 和 label cardinalities,以及
118+
recursive `Any``String``Number``Bool``Null``List``Object`
119+
`Call``OneOf` rules。Extension points 必须使用相应的显式 allow flag。
120+
121+
Schema reports 使用 stable `acl.schema.*` codes 和
122+
`$.blocks.provider[0].attributes.api_key` 这样的 logical paths。Messages 和
123+
paths 不包含 attribute values、call arguments 或 block labels。Report 使用
124+
`ParseLimits::max_diagnostics`,只有在继续观察到超出 budget 的 schema error
125+
后才会把 `truncated` 设为 true。
126+
127+
构造 trusted schema 时,invalid cardinality ranges 和 empty unions 会返回
128+
`SchemaDefinitionError`。Schema admission 只验证 document shape;numeric
129+
ranges、secret resolution、provider credentials 和其它 product semantics 仍由
130+
host component 负责。
131+
89132
## AST
90133

91134
| Type | Fields |

apps/docs/content/docs/en/acl/index.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ is `@a3s-lab/acl` `0.2.2`. The crate repository metadata points to
1919
| --- | --- |
2020
| Syntax | ACL attributes, labeled blocks, nested blocks, lists, objects, strings, numbers, booleans, null, function calls, comments, and `=` / `:` assignments. |
2121
| Lexer/parser | Bounded parsing and multi-diagnostic collection, stable diagnostic codes, UTF-8 byte spans, comment skipping, string escapes, negative numbers, and scientific notation. |
22+
| Admission | Closed-by-default declarative schemas, recursive value rules, stable logical paths, redacted diagnostics, and bounded Rust/Node validation reports. |
2223
| Functions | First-class call values such as `env(...)`, `concat(...)`, and custom function names. |
2324
| AST | `Document`, `Block`, typed values, builders, value constructors, and `Value` accessors. |
2425
| Generation | Native ACL output, block-header labels, sorted attributes and objects, type-stable strings, and map generation. |
@@ -29,10 +30,11 @@ is `@a3s-lab/acl` `0.2.2`. The crate repository metadata points to
2930

3031
- [Syntax](/docs/acl/syntax) documents blocks, attributes, values, calls,
3132
comments, and parser boundaries.
32-
- [Rust API](/docs/acl/rust-api) covers bounded parsing, multi-diagnostic
33-
collection, canonical digests, generation, builders, and AST value helpers.
33+
- [Rust API](/docs/acl/rust-api) covers bounded parsing, schema admission,
34+
multi-diagnostic collection, canonical digests, generation, builders, and
35+
AST value helpers.
3436
- [Node SDK](/docs/acl/node-sdk) covers the JavaScript/TypeScript parser,
35-
native ACL generator, canonical APIs, and builders.
37+
schema validator, native ACL generator, canonical APIs, and builders.
3638
- [Generation And Boundaries](/docs/acl/generation-boundaries) explains stable
3739
output, canonical bytes, secret handling, and host-component ownership.
3840

apps/docs/content/docs/en/acl/node-sdk.mdx

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Node SDK
3-
description: JavaScript and TypeScript bounded parsing, multi-diagnostics, native ACL generation, canonical digests, and builders in @a3s-lab/acl.
3+
description: JavaScript and TypeScript bounded parsing, schema admission, multi-diagnostics, native ACL generation, canonical digests, and builders in @a3s-lab/acl.
44
---
55

66
# Node SDK
@@ -47,6 +47,9 @@ const generated = generate(new DocumentBuilder().block(provider).build());
4747
| `collectDiagnostics(input, limits?)` | Collect bounded diagnostics without constructing a partial AST. |
4848
| `DEFAULT_PARSE_LIMITS` | Shared immutable defaults for document bytes, nesting, collection items, token bytes, and diagnostic count. |
4949
| `ParseError`, `DIAGNOSTIC_CODES`, `DiagnosticReport` | Stable codes, complete spans, UTF-8 byte offsets, redacted messages, and explicit truncation state. |
50+
| `validateDocument(document, schema, limits?)` | Validate a parsed `Document` against a declarative schema with a bounded report. |
51+
| `SCHEMA_DIAGNOSTIC_CODES`, `SchemaDiagnostic`, `SchemaReport` | Stable schema codes, logical paths, redacted messages, and explicit truncation state. |
52+
| `Schema`, `AttributeSchema`, `BlockSchema`, `ValueSchema` | TypeScript definitions for closed-by-default document, block, and recursive value rules. |
5053
| `generate(doc)` | Generate native ACL text with labels in block headers. |
5154
| `canonicalBytes(doc)`, `canonicalDigest(doc)` | Produce stable cross-SDK bytes and an algorithm-prefixed SHA-256 digest. |
5255
| `CanonicalError` | Report non-finite numbers, non-scalar strings, and non-portable identifiers without echoing values. |
@@ -99,6 +102,42 @@ Resource-limit diagnostics remain fatal. A report stores at most
99102
`maxDiagnostics` errors and sets `truncated` only after observing another error
100103
beyond that budget.
101104

105+
## Schema Admission
106+
107+
Parse untrusted text with explicit limits, then validate the resulting
108+
document before activating it:
109+
110+
```typescript
111+
import {parse, validateDocument, type Schema} from '@a3s-lab/acl';
112+
113+
const limits = {maxDiagnostics: 20};
114+
const document = parse('version = 1', limits);
115+
const schema: Schema = {
116+
attributes: {
117+
version: {required: true, value: {kind: 'Number'}},
118+
},
119+
};
120+
const report = validateDocument(document, schema, limits);
121+
```
122+
123+
Schemas reject undeclared attributes, blocks, and object fields by default.
124+
They can declare required or optional attributes, block occurrence and label
125+
cardinalities, and recursive `Any`, `String`, `Number`, `Bool`, `Null`, `List`,
126+
`Object`, `Call`, and `OneOf` rules. Extension points require the corresponding
127+
explicit allow flag.
128+
129+
Schema reports use stable `acl.schema.*` codes and logical paths such as
130+
`$.blocks.provider[0].attributes.api_key`. Messages and paths never include
131+
attribute values, call arguments, or block labels. Reports use
132+
`maxDiagnostics` and set `truncated` only after observing an additional schema
133+
error beyond that budget.
134+
135+
Malformed or cyclic programmatic documents, invalid cardinality ranges, empty
136+
unions, unknown schema fields, and schema cycles fail with `TypeError` before
137+
validation. Schema admission validates document shape; host components still
138+
own numeric ranges, secret resolution, provider credentials, and other product
139+
semantics.
140+
102141
## Native And Canonical Output
103142

104143
`generate` has one native ACL output contract. Labels remain in block headers;
@@ -110,6 +149,6 @@ sorting semantically unordered attribute and object keys.
110149

111150
## Boundary
112151

113-
The SDK is a parser/generator and AST builder. It does not load environment
114-
variables, fetch remote configuration, validate provider credentials, or execute
115-
functions such as `env(...)`.
152+
The SDK parses, generates, builds, and validates declarative ACL document
153+
shapes. It does not load environment variables, fetch remote configuration,
154+
validate provider credentials, or execute functions such as `env(...)`.

apps/docs/content/docs/en/acl/rust-api.mdx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Rust API
3-
description: Rust bounded parsing, multi-diagnostics, canonical digests, native ACL generation, AST, and builders for a3s-acl.
3+
description: Rust bounded parsing, schema admission, multi-diagnostics, canonical digests, native ACL generation, AST, and builders for a3s-acl.
44
---
55

66
# Rust API
@@ -37,6 +37,9 @@ The public crate exports:
3737
| `parse_with_limits`, `ParseLimits` | Parse untrusted input with explicit document, nesting, collection, token, and diagnostic limits. |
3838
| `collect_diagnostics`, `collect_diagnostics_with_limits` | Collect bounded diagnostics without constructing a partial AST. |
3939
| `DiagnosticCode`, `ParseError`, `DiagnosticReport` | Return stable codes, UTF-8 byte spans, redacted messages, and explicit truncation state. |
40+
| `validate_document`, `validate_document_with_limits` | Validate a parsed `Document` against a declarative schema with a bounded report. |
41+
| `Schema`, `AttributeSchema`, `BlockSchema`, `ValueSchema` | Define closed-by-default document, block, and recursive value rules. |
42+
| `SchemaDiagnosticCode`, `SchemaDiagnostic`, `SchemaReport` | Return stable schema codes, logical paths, redacted messages, and explicit truncation state. |
4043
| `generate` / `generate_acl` | Generate ACL text from a `Document`. |
4144
| `generate_from_map` | Build ACL text from a `HashMap<String, Value>`. |
4245
| `canonical_bytes`, `canonical_digest` | Produce stable cross-SDK bytes and an algorithm-prefixed SHA-256 digest. |
@@ -86,6 +89,47 @@ Resource-limit diagnostics remain fatal. A report stores at most
8689
`max_diagnostics` errors and sets `truncated` only after observing another
8790
error beyond that budget.
8891

92+
## Schema Admission
93+
94+
Parse untrusted text with explicit limits, then validate the resulting
95+
document before activating it:
96+
97+
```rust
98+
use a3s_acl::{
99+
parse_with_limits, validate_document_with_limits, AttributeSchema,
100+
ParseLimits, Schema, ValueSchema,
101+
};
102+
103+
let limits = ParseLimits {
104+
max_diagnostics: 20,
105+
..ParseLimits::default()
106+
};
107+
let document = parse_with_limits("version = 1", limits)?;
108+
let schema = Schema::new().attribute(
109+
"version",
110+
AttributeSchema::required(ValueSchema::number()),
111+
);
112+
let report = validate_document_with_limits(&document, &schema, limits);
113+
assert!(report.is_empty());
114+
```
115+
116+
Schemas reject undeclared attributes, blocks, and object fields by default.
117+
They can declare required or optional attributes, block occurrence and label
118+
cardinalities, and recursive `Any`, `String`, `Number`, `Bool`, `Null`, `List`,
119+
`Object`, `Call`, and `OneOf` rules. Extension points require the corresponding
120+
explicit allow flag.
121+
122+
Schema reports use stable `acl.schema.*` codes and logical paths such as
123+
`$.blocks.provider[0].attributes.api_key`. Messages and paths never include
124+
attribute values, call arguments, or block labels. The report uses
125+
`ParseLimits::max_diagnostics` and sets `truncated` only after observing an
126+
additional schema error beyond that budget.
127+
128+
Invalid cardinality ranges and empty unions return `SchemaDefinitionError`
129+
while constructing the trusted schema. Schema admission validates document
130+
shape; host components still own numeric ranges, secret resolution, provider
131+
credentials, and other product semantics.
132+
89133
## AST
90134

91135
| Type | Fields |

compat/cloud-stack.acl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ component "acl" {
99
package = "a3s-acl"
1010
path = "crates/acl"
1111
repository = "git@github.com:A3S-Lab/ACL.git"
12-
revision = "cef613ef945cff9ebbc5a36b983d1daaa1067fdb"
12+
revision = "63f3cd73eac4bad84e5bddb0c6c3cc026b19c66e"
1313
source = "git"
1414
version = "0.2.2"
1515
}

0 commit comments

Comments
 (0)