@hypequery/protocol-conformance 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -27
- package/fixtures/deployment-bundles-v1/README.md +5 -57
- package/fixtures/deployment-releases-v1/README.md +6 -33
- package/fixtures/deployments-v1/README.md +5 -73
- package/fixtures/expressions-v1/README.md +4 -22
- package/fixtures/fuzz-seeds-v1/README.md +6 -26
- package/fixtures/identifiers-v1/README.md +4 -12
- package/fixtures/query-diagnostics-v1/README.md +4 -45
- package/fixtures/query-events-v1/README.md +4 -56
- package/fixtures/query-implementations-v1/README.md +4 -30
- package/fixtures/query-schemas-v1/README.md +4 -22
- package/fixtures/sql-portability-v1/README.md +3 -12
- package/fixtures/tagged-values-v1/README.md +5 -41
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -1,40 +1,56 @@
|
|
|
1
1
|
# @hypequery/protocol-conformance
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Hypequery security protocol. It drives any implementation of the protocol
|
|
5
|
-
against the language-neutral fixtures in `specs/security-protocol/fixtures/`
|
|
6
|
-
and checks the results against the pinned expectations.
|
|
3
|
+
`@hypequery/protocol-conformance` checks TypeScript, Python, or any other implementation of the Hypequery security protocol against the same language-neutral fixtures. It includes a command-line runner and the TypeScript reference adapter.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
for the manifest schema, the adapter wire protocol, and the pass criteria.
|
|
5
|
+
The manifest, adapter wire format, and pass rules are defined in [RFC 0012](../../specs/security-protocol/rfc/0012-cross-language-conformance.md).
|
|
10
6
|
|
|
11
|
-
##
|
|
7
|
+
## Run the reference adapter
|
|
12
8
|
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
hypequery-protocol-
|
|
9
|
+
```bash
|
|
10
|
+
hypequery-protocol-conformance run -- \
|
|
11
|
+
hypequery-protocol-reference-adapter
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Test another language
|
|
15
|
+
|
|
16
|
+
Everything after `--` is the adapter command. The runner starts it directly, without a shell:
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
```bash
|
|
19
|
+
hypequery-protocol-conformance run \
|
|
20
|
+
--fixtures ./specs/security-protocol/fixtures \
|
|
21
|
+
-- python -m my_implementation.adapter
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Useful options include:
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
```bash
|
|
27
|
+
# Run selected fixture families and emit JSON.
|
|
28
|
+
hypequery-protocol-conformance run \
|
|
29
|
+
--families sql-portability-v1 \
|
|
30
|
+
--skip-fuzz \
|
|
31
|
+
--report json \
|
|
32
|
+
-- node ./adapter.mjs
|
|
24
33
|
|
|
25
|
-
#
|
|
34
|
+
# Show case counts by family.
|
|
26
35
|
hypequery-protocol-conformance list
|
|
27
36
|
```
|
|
28
37
|
|
|
29
|
-
Exit
|
|
30
|
-
|
|
38
|
+
Exit code `0` means every case passed, `1` means conformance failures, and `2` means the runner or adapter protocol could not be set up correctly.
|
|
39
|
+
|
|
40
|
+
## Adapter shape
|
|
41
|
+
|
|
42
|
+
An adapter reads newline-delimited JSON from stdin and writes newline-delimited JSON to stdout. It answers the initial `hello` with supported fixture families, then returns one `result` for every `case`.
|
|
43
|
+
|
|
44
|
+
The exported `createStdioAdapter` helper handles the loop. Your handler maps `(family, role, case)` to one of:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
{ ok: true, output? }
|
|
48
|
+
{ ok: false, code }
|
|
49
|
+
{ skipped: true, reason }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The package includes a pinned fixture snapshot, so a pinned package version is also a pinned conformance target. Pass `--fixtures` to test local or newer specifications.
|
|
31
53
|
|
|
32
|
-
##
|
|
54
|
+
## License
|
|
33
55
|
|
|
34
|
-
|
|
35
|
-
answers a `hello` with the families it supports, then one `result` per `case`.
|
|
36
|
-
The `createStdioAdapter` helper implements the loop; a handler maps
|
|
37
|
-
`(family, role, case)` to `{ ok: true, output? }`, `{ ok: false, code }`, or
|
|
38
|
-
`{ skipped: true, reason }`. The bundled fixture snapshot means a pinned
|
|
39
|
-
package version is a pinned conformance target; pass `--fixtures` to test
|
|
40
|
-
against newer or local specs.
|
|
56
|
+
Apache-2.0.
|
|
@@ -1,61 +1,9 @@
|
|
|
1
1
|
# Deployment bundle manifest v1 fixtures
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- `rejections.json` maps generated invalid inputs to stable failure codes.
|
|
5
|
-
- `identity.json` fixes the RFC 8785 canonical bytes and domain-separated
|
|
6
|
-
SHA-256 identity for matching success fixture ids.
|
|
3
|
+
These fixtures pin the closed bundle rules in RFC 0007.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
- `success.json` contains accepted manifests.
|
|
6
|
+
- `rejections.json` describes invalid manifests and required failure codes.
|
|
7
|
+
- `identity.json` pins canonical bytes and domain-separated SHA-256 identities.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Every rejection is a deterministic transform of this pinned base manifest
|
|
15
|
-
(RFC 0012), where `artifact(index)` denotes (with `<sha256>` the 64-digit
|
|
16
|
-
lowercase hexadecimal form of `index`, zero-padded):
|
|
17
|
-
|
|
18
|
-
```json
|
|
19
|
-
{
|
|
20
|
-
"runtime": "node",
|
|
21
|
-
"path": "artifacts/<sha256>.mjs",
|
|
22
|
-
"sha256": "<sha256>",
|
|
23
|
-
"byteLength": 1
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
and the base is:
|
|
28
|
-
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"kind": "hypequery-deployment-bundle",
|
|
32
|
-
"version": 1,
|
|
33
|
-
"deployment": {
|
|
34
|
-
"path": "deployment.json",
|
|
35
|
-
"identity": "1111111111111111111111111111111111111111111111111111111111111111",
|
|
36
|
-
"sha256": "2222222222222222222222222222222222222222222222222222222222222222",
|
|
37
|
-
"byteLength": 1
|
|
38
|
-
},
|
|
39
|
-
"artifacts": [artifact(0)]
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Generator types expand as follows:
|
|
44
|
-
|
|
45
|
-
- `wrong-root-type`: an empty array instead of an object;
|
|
46
|
-
- `unknown-root-field`: the base plus `"extra": true`;
|
|
47
|
-
- `unsupported-version`: the base with `"version": 2`;
|
|
48
|
-
- `malformed-digest`: the base with `deployment.identity` replaced by
|
|
49
|
-
`"bad"`;
|
|
50
|
-
- `traversal-path`: the base with `deployment.path` replaced by
|
|
51
|
-
`"../deployment.json"`;
|
|
52
|
-
- `duplicate-path`: the base with its only artifact's `path` replaced by
|
|
53
|
-
`"deployment.json"`, colliding with the deployment path;
|
|
54
|
-
- `too-many-artifacts`: the base with 101 artifacts `artifact(0)` through
|
|
55
|
-
`artifact(100)`;
|
|
56
|
-
- `deployment-too-large`: the base with `deployment.byteLength` replaced by
|
|
57
|
-
16777217 (16 MiB plus one byte);
|
|
58
|
-
- `unsafe-accessor`: the base with `kind` served by an enumerable computed
|
|
59
|
-
accessor returning `"hypequery-deployment-bundle"` instead of a plain
|
|
60
|
-
data property. Host-model conditional (RFC 0012): implementations whose
|
|
61
|
-
input model cannot express computed accessors skip this case.
|
|
9
|
+
Rejections cover root shape, unknown fields, versions, digests, traversal, duplicate paths, artifact and byte limits, and unsafe host-language accessors. Filesystem byte verification is tested by the deployment verifier because this family describes manifests, not directories.
|
|
@@ -1,36 +1,9 @@
|
|
|
1
|
-
# Deployment release
|
|
1
|
+
# Deployment release v1 fixtures
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- `rejections.json` maps generated invalid inputs to stable failure codes.
|
|
5
|
-
- `identity.json` fixes the RFC 8785 canonical bytes and domain-separated
|
|
6
|
-
SHA-256 identity for matching success fixture ids.
|
|
3
|
+
These fixtures pin RFC 0008 release envelopes, which bind one verified bundle identity to an explicit project and environment.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
- `success.json` contains accepted envelopes.
|
|
6
|
+
- `rejections.json` maps invalid or generated inputs to stable error codes.
|
|
7
|
+
- `identity.json` pins canonical bytes and release identities.
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Every rejection is a deterministic transform of this pinned base envelope
|
|
14
|
-
(RFC 0012):
|
|
15
|
-
|
|
16
|
-
```json
|
|
17
|
-
{
|
|
18
|
-
"kind": "hypequery-deployment-release",
|
|
19
|
-
"version": 1,
|
|
20
|
-
"bundleIdentity": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
21
|
-
"target": { "project": "project_1", "environment": "production" }
|
|
22
|
-
}
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Generator types expand as follows:
|
|
26
|
-
|
|
27
|
-
- `wrong-root-type`: an empty array instead of an object;
|
|
28
|
-
- `unknown-root-field`: the base plus `"extra": true`;
|
|
29
|
-
- `unsupported-version`: the base with `"version": 2`;
|
|
30
|
-
- `malformed-bundle-identity`: the base with `"bundleIdentity": "bad"`;
|
|
31
|
-
- `target-too-large`: the base with `target.project` replaced by `p`
|
|
32
|
-
followed by 128 repetitions of `a` (129 bytes);
|
|
33
|
-
- `unsafe-accessor`: the base with `kind` served by an enumerable computed
|
|
34
|
-
accessor returning `"hypequery-deployment-release"` instead of a plain
|
|
35
|
-
data property. Host-model conditional (RFC 0012): implementations whose
|
|
36
|
-
input model cannot express computed accessors skip this case.
|
|
9
|
+
The family covers closed fields, version handling, bundle digests, target limits, and unsafe accessors. Bundle filesystem verification remains in the bundle contract.
|
|
@@ -1,77 +1,9 @@
|
|
|
1
1
|
# Deployment contract v1 fixtures
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- `rejections.json` maps generated invalid inputs to stable failure codes.
|
|
5
|
-
- `identity.json` fixes the RFC 8785 canonical bytes and domain-separated
|
|
6
|
-
SHA-256 identity for matching success fixture ids.
|
|
3
|
+
These fixtures exercise RFC 0006 deployment envelopes containing datasets, named queries, endpoint policy, and runtime artifact references.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
implementation must return.
|
|
5
|
+
- `success.json` contains accepted language-neutral deployments.
|
|
6
|
+
- `rejections.json` pins generated invalid inputs and stable error codes.
|
|
7
|
+
- `identity.json` pins canonical bytes and deployment identities.
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Every rejection is a deterministic transform of this pinned base deployment
|
|
16
|
-
(RFC 0012), where `dataset(name)` denotes:
|
|
17
|
-
|
|
18
|
-
```json
|
|
19
|
-
{
|
|
20
|
-
"name": "<name>",
|
|
21
|
-
"source": "orders",
|
|
22
|
-
"tenant": { "kind": "not-required" },
|
|
23
|
-
"dimensions": [],
|
|
24
|
-
"measures": [],
|
|
25
|
-
"filters": [],
|
|
26
|
-
"metrics": [],
|
|
27
|
-
"relationships": []
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
and the base is:
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"kind": "hypequery-deployment",
|
|
36
|
-
"version": 1,
|
|
37
|
-
"datasets": [dataset("orders")],
|
|
38
|
-
"queries": [],
|
|
39
|
-
"artifacts": []
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Generator types expand as follows:
|
|
44
|
-
|
|
45
|
-
- `wrong-root-type`: an empty array instead of an object;
|
|
46
|
-
- `unknown-root-field`: the base plus `"extra": true`;
|
|
47
|
-
- `unsupported-version`: the base with `"version": 2`;
|
|
48
|
-
- `invalid-dataset-identifier`: the base with its only dataset replaced by
|
|
49
|
-
`dataset("bad-name")` (hyphens are not valid identifier characters);
|
|
50
|
-
- `invalid-relationship-queryability`: the base with its only dataset given
|
|
51
|
-
one relationship
|
|
52
|
-
`{ "name": "items", "kind": "hasMany", "target": "orders", "from": "id",
|
|
53
|
-
"to": "order_id", "queryable": true }` (a `hasMany` relationship must not
|
|
54
|
-
be queryable);
|
|
55
|
-
- `missing-runtime-artifact`: the base plus one named query `health` with
|
|
56
|
-
input `{ "kind": "any" }`, output `{ "kind": "any" }`, implementation
|
|
57
|
-
`{ "kind": "runtime-reference", "runtime": "node", "artifactSha256":
|
|
58
|
-
<64 zeros>, "entrypoint": "queries.health" }`, endpoint
|
|
59
|
-
`{ "access": { "kind": "public" }, "tenant": { "kind": "not-required" },
|
|
60
|
-
"method": "GET", "path": "/health" }`, and `"tags": []` — while
|
|
61
|
-
`artifacts` stays empty, so the referenced artifact does not exist;
|
|
62
|
-
- `ambiguous-query-route`: the base plus two named queries `first` and
|
|
63
|
-
`second`, each with input `{ "kind": "void" }`, output
|
|
64
|
-
`{ "kind": "void" }`, implementation `{ "kind": "semantic-plan",
|
|
65
|
-
"query": { "kind": "dataset", "dataset": "orders", "dimensions": [],
|
|
66
|
-
"measures": [], "filters": [], "orderBy": [] } }`, endpoint
|
|
67
|
-
`{ "access": { "kind": "public" }, "tenant": { "kind": "not-required" },
|
|
68
|
-
"method": "GET", "path": "/same" }`, and `"tags": []` — both share one
|
|
69
|
-
method and path;
|
|
70
|
-
- `too-many-datasets`: the base with 101 datasets `dataset("dataset_0")`
|
|
71
|
-
through `dataset("dataset_100")`;
|
|
72
|
-
- `source-too-large`: the base with its only dataset's `source` replaced by
|
|
73
|
-
1025 repetitions of `a`;
|
|
74
|
-
- `unsafe-accessor`: the base with `kind` served by an enumerable computed
|
|
75
|
-
accessor returning `"hypequery-deployment"` instead of a plain data
|
|
76
|
-
property. Host-model conditional (RFC 0012): implementations whose input
|
|
77
|
-
model cannot express computed accessors skip this case.
|
|
9
|
+
Coverage includes closed fields, versions, identifiers, relationship queryability, missing runtime artifacts, ambiguous routes, collection limits, source limits, and unsafe accessors.
|
|
@@ -1,25 +1,7 @@
|
|
|
1
|
-
# Portable expression fixtures
|
|
1
|
+
# Portable expression v1 fixtures
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
operator registry and both semantic query envelopes. `rejections.json` covers
|
|
5
|
-
every stable failure code; generator entries describe inputs that are awkward
|
|
6
|
-
or unsafe to encode directly as JSON.
|
|
3
|
+
This family accompanies RFC 0003 and covers the closed semantic expression registry plus metric and dataset query envelopes.
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
`success.json` exercises accepted expressions and queries. `rejections.json` pins every stable failure code, including generated depth, width, node-count, and unsafe-accessor cases.
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
(`expression` or `query`) selecting the validated surface, and the required
|
|
12
|
-
stable `error` code. Generator types expand as follows (RFC 0012), where
|
|
13
|
-
`literal` denotes `{ "kind": "literal", "value": false }`:
|
|
14
|
-
|
|
15
|
-
- `nested-not`: wraps `literal` in
|
|
16
|
-
`{ "kind": "logical", "operator": "not", "operand": ... }` `depth` times;
|
|
17
|
-
- `logical-operands`: one
|
|
18
|
-
`{ "kind": "logical", "operator": "and", "operands": [...] }` node whose
|
|
19
|
-
operands are `count` copies of `literal`;
|
|
20
|
-
- `logical-tree`: one `and` node whose operands are 10 `and` nodes, each
|
|
21
|
-
with 100 copies of `literal` as operands (1011 nodes total);
|
|
22
|
-
- `unsafe-accessor`: `{ "kind": "reference" }` with `name` served by an
|
|
23
|
-
enumerable computed accessor returning `"orders"` instead of a plain data
|
|
24
|
-
property. Host-model conditional (RFC 0012): implementations whose input
|
|
25
|
-
model cannot express computed accessors skip this case.
|
|
7
|
+
Each rejection selects the `expression` or `query` validation surface and contains exactly one literal value or deterministic generator.
|
|
@@ -1,29 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Deterministic fuzz seed corpus v1
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
(RFC 0012). A mutating fuzzer is out of scope; this corpus is the foundation
|
|
5
|
-
it would grow. Any input that later crashes an implementation must be
|
|
6
|
-
minimized and added here as a seed.
|
|
3
|
+
These adversarial inputs replay on every conformance run under RFC 0012. An implementation may accept a seed within documented limits or reject it with a stable `HQ_*` code; it must never crash, hang, partially execute input, or allocate without bounds.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
input, and must enforce documented limits before unbounded allocation.
|
|
5
|
+
- `value-sources.json` targets duplicate-aware JSON decoding and tagged values.
|
|
6
|
+
- `structured-values.json` targets selected structural validator families.
|
|
7
|
+
- `sql-expressions.json` targets the SQL portability compiler.
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- `value-sources.json` targets the tagged-values-v1 decode and validation
|
|
16
|
-
path. Entries carry an `id` and exactly one of `sourceUtf8` (exact JSON
|
|
17
|
-
source for a duplicate-aware parser) or `generator` (expanded per the
|
|
18
|
-
tagged-values-v1 README).
|
|
19
|
-
- `structured-values.json` targets structural validators. Entries carry an
|
|
20
|
-
`id`, a `value`, and a `targets` array of family names; the seed is
|
|
21
|
-
replayed once per target family through that family's validate operation.
|
|
22
|
-
- `sql-expressions.json` targets the sql-portability-v1 compiler. Entries
|
|
23
|
-
carry an `id` and either `sql` (the exact source) or `sqlRepeat`
|
|
24
|
-
(`{ "value": ..., "count": ... }`, expanded by concatenating `count`
|
|
25
|
-
copies of `value`, optionally between `prefix` and `suffix`).
|
|
26
|
-
|
|
27
|
-
Seed ids are unique within one file. Seeds carry no expected code: any
|
|
28
|
-
stable rejection is conforming, and an implementation that accepts a seed
|
|
29
|
-
within its limits also conforms.
|
|
9
|
+
Minimize any newly discovered crashing input and add it here with a unique ID.
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
# Portable identifier
|
|
1
|
+
# Portable identifier v1 fixtures
|
|
2
2
|
|
|
3
|
-
These draft
|
|
3
|
+
These draft fixtures accompany RFC 0002.
|
|
4
4
|
|
|
5
|
-
Success
|
|
6
|
-
`value`, and the expected `segments`. Rejection entries contain exactly one of
|
|
7
|
-
`value` or `generator` and the required stable `error` code.
|
|
5
|
+
Success cases pin simple or qualified identifiers and their exact segments. Rejection cases contain a literal value or deterministic repeat/segment generator plus the required error code.
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- `repeat-string`: concatenates `count` copies of `value`;
|
|
12
|
-
- `qualified-segments`: joins `count` copies of `segment` with `.`.
|
|
13
|
-
|
|
14
|
-
Fixture consumers must preserve accepted strings exactly. They must not trim,
|
|
15
|
-
case-fold, normalize, or reinterpret qualified identifiers as SQL names.
|
|
7
|
+
Conforming implementations preserve accepted strings exactly: no trimming, case folding, Unicode normalization, or reinterpretation as SQL identifiers.
|
|
@@ -1,49 +1,8 @@
|
|
|
1
1
|
# Query diagnostics v1 fixtures
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
validator.
|
|
5
|
-
- `rejections.json` maps generated invalid inputs to stable failure codes.
|
|
3
|
+
These fixtures exercise the privileged diagnostics projection in RFC 0011.
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
(`debugQuery`), terminal reason, attempt count, runtime identity, and a safe
|
|
10
|
-
message. Rejections prove result rows (`unknown-result-field`) and
|
|
11
|
-
credentials (`unknown-credentials-field`) have no representable field, and
|
|
12
|
-
that `newer-version` fails closed for older consumers. Note that
|
|
13
|
-
`full-diagnostics.debugQuery` uses the deliberately non-executable
|
|
14
|
-
placeholder syntax of RFC 0010 and carries no parameter values.
|
|
5
|
+
- `success.json` contains accepted diagnostic records.
|
|
6
|
+
- `rejections.json` maps invalid or generated records to stable failure codes.
|
|
15
7
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Every rejection is a deterministic transform of this pinned base projection
|
|
19
|
-
(RFC 0012):
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"kind": "hypequery-query-diagnostics",
|
|
24
|
-
"version": 1,
|
|
25
|
-
"eventId": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
26
|
-
"queryId": "1111111111111111111111111111111111111111111111111111111111111111",
|
|
27
|
-
"terminalReason": "completed",
|
|
28
|
-
"attempts": 1
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Generator types expand as follows:
|
|
33
|
-
|
|
34
|
-
- `wrong-root-type`: an empty array instead of an object;
|
|
35
|
-
- `missing-required-field`: the base without `attempts`;
|
|
36
|
-
- `unknown-result-field`: the base plus `"rows": [[1, 2]]`;
|
|
37
|
-
- `unknown-credentials-field`: the base plus `"password": "hunter2"`;
|
|
38
|
-
- `newer-version`: the base with `"version": 2`;
|
|
39
|
-
- `malformed-query-id`: the base with `"queryId": "bad"`;
|
|
40
|
-
- `unknown-terminal-reason`: the base with `"terminalReason": "exploded"`;
|
|
41
|
-
- `zero-attempts`: the base with `"attempts": 0`;
|
|
42
|
-
- `control-character-message`: the base plus a `safeMessage` of `bad`,
|
|
43
|
-
U+0007 (BEL), then `message`;
|
|
44
|
-
- `oversized-debug-query`: the base plus a `debugQuery` of 4097 repetitions
|
|
45
|
-
of `x`;
|
|
46
|
-
- `unsafe-accessor`: the base with `kind` served by an enumerable computed
|
|
47
|
-
accessor returning `"hypequery-query-diagnostics"` instead of a plain
|
|
48
|
-
data property. Host-model conditional (RFC 0012): implementations whose
|
|
49
|
-
input model cannot express computed accessors skip this case.
|
|
8
|
+
Coverage includes required fields, versions, IDs, terminal reasons, attempt counts, safe-message controls, debug-query limits, unknown result or credential fields, and unsafe accessors. Debug queries are deliberately non-executable and contain no parameter values.
|
|
@@ -1,60 +1,8 @@
|
|
|
1
1
|
# Query event v1 fixtures
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- `rejections.json` maps generated invalid inputs to stable failure codes.
|
|
3
|
+
This RFC 0011 family pins bounded, non-sensitive analytics query events.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
(`unknown-parameters-field`), and a raw tenant identifier
|
|
9
|
-
(`unknown-raw-tenant-field`): the default event has no field that can accept
|
|
10
|
-
them, so each fails closed as an unknown field. `newer-version` proves an
|
|
11
|
-
older consumer rejects an unknown version cleanly; consumers may skip such
|
|
12
|
-
records without failing an event stream.
|
|
5
|
+
- `success.json` contains accepted events.
|
|
6
|
+
- `rejections.json` maps invalid or generated events to stable codes.
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Every rejection is a deterministic transform of this pinned base event
|
|
17
|
-
(RFC 0012):
|
|
18
|
-
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"kind": "hypequery-query-event",
|
|
22
|
-
"version": 1,
|
|
23
|
-
"eventId": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
24
|
-
"occurredAt": "2026-07-20T12:34:56.789Z",
|
|
25
|
-
"target": { "project": "project_1", "environment": "production" },
|
|
26
|
-
"queryName": "daily_revenue",
|
|
27
|
-
"operation": "query",
|
|
28
|
-
"outcome": "success",
|
|
29
|
-
"durationMs": 182
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Generator types expand as follows:
|
|
34
|
-
|
|
35
|
-
- `wrong-root-type`: an empty array instead of an object;
|
|
36
|
-
- `missing-required-field`: the base without `durationMs`;
|
|
37
|
-
- `unknown-sql-field`: the base plus `"sql": "SELECT 1"`;
|
|
38
|
-
- `unknown-parameters-field`: the base plus
|
|
39
|
-
`"parameters": { "start": "2026-01-01" }`;
|
|
40
|
-
- `unknown-raw-tenant-field`: the base plus `"tenantId": "acme"`;
|
|
41
|
-
- `newer-version`: the base with `"version": 2`;
|
|
42
|
-
- `malformed-event-id`: the base with `"eventId": "bad"`;
|
|
43
|
-
- `invalid-occurred-at`: the base with
|
|
44
|
-
`"occurredAt": "2026-13-40T99:99:99Z"`;
|
|
45
|
-
- `failure-without-category`: the base with `"outcome": "failure"` and no
|
|
46
|
-
`errorCategory`;
|
|
47
|
-
- `success-with-category`: the base plus `"errorCategory": "internal"`
|
|
48
|
-
while `outcome` stays `"success"`;
|
|
49
|
-
- `unknown-error-category`: the base with `"outcome": "failure"` plus
|
|
50
|
-
`"errorCategory": "exploded"`;
|
|
51
|
-
- `negative-duration`: the base with `"durationMs": -1`;
|
|
52
|
-
- `invalid-target`: the base with
|
|
53
|
-
`"target": { "project": "has space", "environment": "production" }`;
|
|
54
|
-
- `invalid-query-name`: the base with `"queryName": "not an identifier"`;
|
|
55
|
-
- `oversized-correlation-id`: the base plus a `correlationId` of 2049
|
|
56
|
-
repetitions of `x`;
|
|
57
|
-
- `unsafe-accessor`: the base with `kind` served by an enumerable computed
|
|
58
|
-
accessor returning `"hypequery-query-event"` instead of a plain data
|
|
59
|
-
property. Host-model conditional (RFC 0012): implementations whose input
|
|
60
|
-
model cannot express computed accessors skip this case.
|
|
8
|
+
The default event cannot represent SQL, parameter values, or raw tenant IDs. Coverage also includes versions, event IDs, timestamps, outcomes, error categories, durations, targets, query names, correlation limits, and unsafe accessors.
|
|
@@ -1,33 +1,7 @@
|
|
|
1
|
-
# Query implementation
|
|
1
|
+
# Query implementation v1 fixtures
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
implementation kinds. `rejections.json` maps invalid artifacts to stable RFC
|
|
5
|
-
0005 failure codes. Generator entries create values that JSON cannot represent
|
|
6
|
-
concisely or safely.
|
|
3
|
+
This family covers RFC 0005 trusted SQL expressions and the closed named-query implementation kinds.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
valid ClickHouse SQL or authorize it for execution; the trusted ClickHouse
|
|
10
|
-
adapter performs those checks.
|
|
5
|
+
`success.json` contains accepted structures. `rejections.json` selects either the SQL-expression or implementation surface and pins invalid values, bounded generators, and stable error codes.
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Rejection entries carry a `surface` (`sql-expression` or `implementation`)
|
|
15
|
-
selecting the validated artifact kind, exactly one of `value` or
|
|
16
|
-
`generator`, and the required stable `error` code. Generator types expand as
|
|
17
|
-
follows (RFC 0012):
|
|
18
|
-
|
|
19
|
-
- `parameters`: a compiled SQL implementation
|
|
20
|
-
`{ "kind": "compiled-sql", "dialect": "clickhouse", "operation":
|
|
21
|
-
"select", "statement": "SELECT 1", "parameters": [...], "readSources":
|
|
22
|
-
[], "tenant": { "kind": "not-required" } }` whose parameters are `count`
|
|
23
|
-
entries `{ "name": "param<i>", "source": { "kind": "input", "path":
|
|
24
|
-
"param<i>" }, "clickHouseType": "String" }` for `i` from 0 to
|
|
25
|
-
`count - 1`;
|
|
26
|
-
- `sql-expression`: `{ "kind": "sql-expression", "dialect": "clickhouse",
|
|
27
|
-
"sql": ..., "output": { "kind": "string" }, "dependencies": [] }` with a
|
|
28
|
-
`sql` of `bytes` repetitions of `a`;
|
|
29
|
-
- `unsafe-accessor`: an object with `kind` served by an enumerable computed
|
|
30
|
-
accessor returning `"semantic-plan"` instead of a plain data property,
|
|
31
|
-
and no other properties. Host-model conditional (RFC 0012):
|
|
32
|
-
implementations whose input model cannot express computed accessors skip
|
|
33
|
-
this case.
|
|
7
|
+
Structural validation does not prove SQL is valid or authorize execution. The trusted database adapter owns those checks.
|
|
@@ -1,25 +1,7 @@
|
|
|
1
|
-
# Portable query schema fixtures
|
|
1
|
+
# Portable query schema v1 fixtures
|
|
2
2
|
|
|
3
|
-
These
|
|
4
|
-
and every currently portable Serve/Zod feature. Rejection fixtures cover every
|
|
5
|
-
stable failure code; generators describe oversized or unsafe inputs that
|
|
6
|
-
cannot be represented directly in JSON.
|
|
3
|
+
These RFC 0004 fixtures cover the declarative Serve/Zod schema features that can travel between runtimes without executable transforms.
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
`success.json` exercises every portable schema kind. `rejections.json` pins stable errors for invalid values plus generated depth, width, description-size, and unsafe-accessor boundaries.
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
required stable `error` code. Generator types expand as follows (RFC 0012):
|
|
12
|
-
|
|
13
|
-
- `nested-array`: wraps `{ "kind": "any" }` in
|
|
14
|
-
`{ "kind": "array", "items": ... }` `depth` times;
|
|
15
|
-
- `union-tree`: one `{ "kind": "union", "variants": [...] }` node whose
|
|
16
|
-
variants are 10 union nodes, each with 100 `{ "kind": "any" }` variants
|
|
17
|
-
(1011 nodes total);
|
|
18
|
-
- `enum-values`: `{ "kind": "enum", "values": [...] }` with `count` values
|
|
19
|
-
`v0` through `v<count - 1>`;
|
|
20
|
-
- `description`: `{ "kind": "string", "description": ... }` with a
|
|
21
|
-
description of `bytes` repetitions of `a`;
|
|
22
|
-
- `unsafe-accessor`: an object with `kind` served by an enumerable computed
|
|
23
|
-
accessor returning `"string"` instead of a plain data property, and no
|
|
24
|
-
other properties. Host-model conditional (RFC 0012): implementations
|
|
25
|
-
whose input model cannot express computed accessors skip this case.
|
|
7
|
+
Every rejection contains exactly one literal value or deterministic generator.
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
# SQL portability v1 fixtures
|
|
2
2
|
|
|
3
|
-
- `portable.json` maps SQL expression fragments
|
|
4
|
-
|
|
5
|
-
- `non-portable.json` maps inputs outside the subset to the first
|
|
6
|
-
incompatibility issue code and its start offset.
|
|
3
|
+
- `portable.json` maps accepted SQL expression fragments to RFC 0003 expression trees and sorted dependencies.
|
|
4
|
+
- `non-portable.json` maps unsupported input to the first issue code and source offset.
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
subset is deliberately small: qualified and backtick-quoted identifiers,
|
|
10
|
-
numeric/string/boolean/null literals, `+ - * /`, the comparison operators,
|
|
11
|
-
literal `IN`/`NOT IN` lists, `BETWEEN` with literal bounds, `LIKE`,
|
|
12
|
-
`AND`/`OR`/`NOT`, parentheses, and the RFC 0003 function allowlist
|
|
13
|
-
(`nullIfZero`, `coalesce`, `round`, `floor`, `ceil`). Statements, casts,
|
|
14
|
-
subqueries, lambdas, comments, unlisted functions, backslash escapes, and
|
|
15
|
-
non-literal `IN`/`BETWEEN` operands are non-portable by construction.
|
|
6
|
+
The portable subset covers identifiers, literals, arithmetic, comparisons, literal `IN` lists, literal `BETWEEN`, `LIKE`, boolean logic, parentheses, and the approved formula functions. Statements, subqueries, casts, lambdas, comments, unapproved functions, and dynamic list/range operands remain non-portable by construction.
|
|
@@ -1,44 +1,8 @@
|
|
|
1
|
-
# Tagged value
|
|
1
|
+
# Tagged value v1 fixtures
|
|
2
2
|
|
|
3
|
-
These draft
|
|
4
|
-
normative when the RFC is accepted.
|
|
3
|
+
These draft fixtures accompany RFC 0001 and pin canonical values before they become a stable wire contract.
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
- `success.json` contains parsed values, exact RFC 8785 UTF-8 bytes as hex, and SHA-256 integrity hashes.
|
|
6
|
+
- `rejections.json` contains exact JSON source, parsed values, or deterministic boundary generators with required error codes.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- `id`: stable fixture identifier;
|
|
11
|
-
- `value`: the parsed canonical value before JCS;
|
|
12
|
-
- `canonicalHex`: exact RFC 8785 canonical UTF-8 bytes as lowercase hex;
|
|
13
|
-
- `sha256`: lowercase SHA-256 of those exact bytes.
|
|
14
|
-
|
|
15
|
-
The hash is a fixture integrity check, not a deployment digest or cache key.
|
|
16
|
-
|
|
17
|
-
## Rejection manifest
|
|
18
|
-
|
|
19
|
-
Entries in `rejections.json` use one of:
|
|
20
|
-
|
|
21
|
-
- `sourceUtf8`: exact JSON source presented to a duplicate-aware parser;
|
|
22
|
-
- `value`: an already parsed value presented to model validation;
|
|
23
|
-
- `generator`: a deterministic boundary case that would be wasteful to store
|
|
24
|
-
expanded.
|
|
25
|
-
|
|
26
|
-
`declaredClickHouseType`, when present, supplies the containing schema type
|
|
27
|
-
needed to validate integer-tag requirements and exact tag/type compatibility.
|
|
28
|
-
|
|
29
|
-
Generators expand as follows:
|
|
30
|
-
|
|
31
|
-
- `non-finite-float`: creates the host-language non-finite number named by
|
|
32
|
-
`value` (`NaN`, `Infinity`, or `-Infinity`) after JSON parsing;
|
|
33
|
-
- `nested-array`: wraps `leaf` in the tagged array form `depth` times;
|
|
34
|
-
- `array`: creates one tagged array containing `items` copies of `value`;
|
|
35
|
-
- `array-tree`: creates one tagged array containing `branches` tagged arrays,
|
|
36
|
-
each containing `itemsPerBranch` copies of `value`;
|
|
37
|
-
- `repeat-string`: concatenates `count` copies of the UTF-8 string `utf8`.
|
|
38
|
-
|
|
39
|
-
`error` is the required stable failure code. `phase` identifies the earliest
|
|
40
|
-
stage that must reject the input. A consumer may reject earlier only when it
|
|
41
|
-
returns the same code and does not partially execute or hash the value.
|
|
42
|
-
|
|
43
|
-
Fixture runners must not pass `sourceUtf8` through an ordinary JSON dictionary
|
|
44
|
-
parser before duplicate-key detection.
|
|
8
|
+
The hash here verifies fixture bytes; it is not a deployment or cache identity. Duplicate-key cases must reach a duplicate-aware parser before ordinary object decoding. Generated cases cover non-finite numbers, nested and wide arrays, repeated strings, and integer tag/type compatibility.
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/protocol-conformance",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "Cross-language conformance runner
|
|
3
|
+
"version": "0.9.2",
|
|
4
|
+
"description": "Cross-language conformance runner for the Hypequery analytics security protocol",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"hypequery",
|
|
7
|
+
"protocol",
|
|
8
|
+
"conformance",
|
|
9
|
+
"analytics",
|
|
10
|
+
"typescript",
|
|
11
|
+
"testing"
|
|
12
|
+
],
|
|
5
13
|
"license": "Apache-2.0",
|
|
6
14
|
"type": "module",
|
|
7
15
|
"main": "dist/index.js",
|
|
@@ -23,7 +31,7 @@
|
|
|
23
31
|
"README.md"
|
|
24
32
|
],
|
|
25
33
|
"dependencies": {
|
|
26
|
-
"@hypequery/protocol": "^0.10.
|
|
34
|
+
"@hypequery/protocol": "^0.10.2"
|
|
27
35
|
},
|
|
28
36
|
"devDependencies": {
|
|
29
37
|
"@types/node": "^22.5.0",
|
|
@@ -32,10 +40,10 @@
|
|
|
32
40
|
},
|
|
33
41
|
"repository": {
|
|
34
42
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/hypequery/hypequery.git",
|
|
43
|
+
"url": "git+https://github.com/hypequery/hypequery.git",
|
|
36
44
|
"directory": "packages/protocol-conformance"
|
|
37
45
|
},
|
|
38
|
-
"homepage": "https://
|
|
46
|
+
"homepage": "https://hypequery.com",
|
|
39
47
|
"bugs": {
|
|
40
48
|
"url": "https://github.com/hypequery/hypequery/issues"
|
|
41
49
|
},
|