@intentius/tsad-conformance 1.4.0 → 1.6.0
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/dist/adapter.d.ts +53 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/fixture.d.ts +28 -1
- package/dist/fixture.d.ts.map +1 -1
- package/dist/fixture.js +27 -2
- package/dist/fixture.js.map +1 -1
- package/dist/host.d.ts +13 -0
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +33 -0
- package/dist/host.js.map +1 -1
- package/dist/runner.d.ts +28 -2
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +129 -3
- package/dist/runner.js.map +1 -1
- package/fixtures/F-Call/a-host-factory-is-invoked/expect.json +45 -0
- package/fixtures/F-Call/a-host-factory-is-invoked/project/app.ts +4 -0
- package/fixtures/F-Call/a-host-factory-is-invoked/project/nested.ts +3 -0
- package/fixtures/F-Call/a-host-factory-is-invoked/project/plain.ts +3 -0
- package/fixtures/F-Declarator/a-const-alias-of-a-call-resolves-at-the-declarator/expect.json +50 -0
- package/fixtures/F-Declarator/a-const-alias-of-a-call-resolves-at-the-declarator/project/app.ts +13 -0
- package/fixtures/F-Declarator/a-const-alias-of-a-call-resolves-at-the-declarator/project/nested.ts +5 -0
- package/fixtures/F-Declarator/a-const-alias-of-a-call-resolves-at-the-declarator/project/store.ts +3 -0
- package/fixtures/F-Div-Step/step-reads-the-resolved-composite/expect.json +48 -0
- package/fixtures/F-Div-Step/step-reads-the-resolved-composite/project/app.ts +4 -0
- package/fixtures/F-Div-Step/step-reads-the-resolved-composite/project/pipeline.ts +3 -0
- package/fixtures/F-Host-Closed-vs-Open/package-call-is-closed/expect.json +18 -5
- package/fixtures/F-Host-Composite/a-registered-composite-is-interpreted/expect.json +47 -0
- package/fixtures/F-Host-Composite/a-registered-composite-is-interpreted/project/app.ts +4 -0
- package/fixtures/F-Host-Composite/a-registered-composite-is-interpreted/project/store.ts +6 -0
- package/fixtures/F-IsolatedRefusal/a-project-factory-is-refused-not-invoked/expect.json +18 -0
- package/fixtures/F-IsolatedRefusal/a-project-factory-is-refused-not-invoked/project/app.ts +3 -0
- package/fixtures/F-IsolatedRefusal/a-project-factory-is-refused-not-invoked/project/shapes.ts +5 -0
- package/fixtures/F-Obs-Counters/a-build-reports-its-counts/expect.json +43 -0
- package/fixtures/F-Obs-Counters/a-build-reports-its-counts/project/app.ts +5 -0
- package/fixtures/F-Obs-Counters/a-build-reports-its-counts/project/shapes.ts +3 -0
- package/fixtures/F-Rule-Equivalence/same-source-same-findings/expect.json +21 -0
- package/fixtures/F-Rule-Equivalence/same-source-same-findings/project/buckets.ts +8 -0
- package/fixtures/F-Rule-Equivalence/same-source-same-findings/project/helpers.ts +3 -0
- package/fixtures/F-Rule-Input/a-rule-sees-the-folded-namespace/expect.json +21 -0
- package/fixtures/F-Rule-Input/a-rule-sees-the-folded-namespace/project/buckets.ts +4 -0
- package/fixtures/F-Rule-Phase/a-post-rule-reads-the-artifact/expect.json +21 -0
- package/fixtures/F-Rule-Phase/a-post-rule-reads-the-artifact/project/pairs.ts +3 -0
- package/fixtures/F-Rule-Pure/findings-are-a-function-of-the-input/expect.json +21 -0
- package/fixtures/F-Rule-Pure/findings-are-a-function-of-the-input/project/buckets.ts +4 -0
- package/fixtures/F-Rule-Pure/findings-are-a-function-of-the-input/project/clock.ts +1 -0
- package/fixtures/F-Rule-Supply/the-host-names-the-rule/expect.json +21 -0
- package/fixtures/F-Rule-Supply/the-host-names-the-rule/project/app.ts +4 -0
- package/fixtures/F-Val-Domain/every-case-is-a-value/expect.json +49 -0
- package/fixtures/F-Val-Domain/every-case-is-a-value/project/app.ts +6 -0
- package/fixtures/F-Val-Envelope/envelopes-are-the-output-in-data-host/expect.json +41 -0
- package/fixtures/F-Val-Envelope/envelopes-are-the-output-in-data-host/project/app.ts +5 -0
- package/fixtures/F-Val-Source/a-form-per-case-in-data-host/expect.json +74 -0
- package/fixtures/F-Val-Source/a-form-per-case-in-data-host/project/app.ts +8 -0
- package/fixtures/F-Val-Source/a-form-per-case-in-full/expect.json +35 -0
- package/fixtures/F-Val-Source/a-form-per-case-in-full/project/app.ts +7 -0
- package/fixtures/F-Val-Symbol-Scope/a-symbol-only-inside-an-intrinsic/expect.json +32 -0
- package/fixtures/F-Val-Symbol-Scope/a-symbol-only-inside-an-intrinsic/project/interior.ts +3 -0
- package/fixtures/F-Val-Symbol-Scope/a-symbol-only-inside-an-intrinsic/project/top.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/expect.json +34 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/array.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/class.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/default-function.ts +3 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/let.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/ok.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/rest.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/star.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/uninitialized.ts +1 -0
- package/fixtures/S-Disqualify/each-arm-disqualifies-the-file/project/var.ts +1 -0
- package/fixtures/S-ExportDestructure/plain-elements/expect.json +16 -0
- package/fixtures/S-ExportDestructure/plain-elements/project/app.ts +3 -0
- package/fixtures/S-ExportNamed/local-names-with-an-alias/expect.json +19 -0
- package/fixtures/S-ExportNamed/local-names-with-an-alias/project/app.ts +4 -0
- package/fixtures/S-ExportResource/new-with-props/expect.json +26 -0
- package/fixtures/S-ExportResource/new-with-props/project/app.ts +3 -0
- package/fixtures/S-ExportSingle/an-expression-initializer/expect.json +21 -0
- package/fixtures/S-ExportSingle/an-expression-initializer/input.ts +1 -0
- package/fixtures/S-ExportTypeOnly/type-exports-are-invisible/expect.json +19 -0
- package/fixtures/S-ExportTypeOnly/type-exports-are-invisible/project/app.ts +12 -0
- package/fixtures/S-FactoryBody/consts-then-a-final-return/expect.json +38 -0
- package/fixtures/S-FactoryBody/consts-then-a-final-return/project/bad-shapes.ts +7 -0
- package/fixtures/S-FactoryBody/consts-then-a-final-return/project/empty.ts +3 -0
- package/fixtures/S-FactoryBody/consts-then-a-final-return/project/good-shapes.ts +7 -0
- package/fixtures/S-FactoryBody/consts-then-a-final-return/project/good.ts +3 -0
- package/fixtures/S-FactoryBody/consts-then-a-final-return/project/no-return.ts +3 -0
- package/fixtures/S-FactoryParams/one-plainly-bound-parameter/expect.json +38 -0
- package/fixtures/S-FactoryParams/one-plainly-bound-parameter/project/bad-shapes.ts +4 -0
- package/fixtures/S-FactoryParams/one-plainly-bound-parameter/project/good-shapes.ts +3 -0
- package/fixtures/S-FactoryParams/one-plainly-bound-parameter/project/named.ts +3 -0
- package/fixtures/S-FactoryParams/one-plainly-bound-parameter/project/rest.ts +3 -0
- package/fixtures/S-FactoryParams/one-plainly-bound-parameter/project/two.ts +3 -0
- package/fixtures/S-Module/non-exported-statements-are-invisible/expect.json +17 -0
- package/fixtures/S-Module/non-exported-statements-are-invisible/project/app.ts +13 -0
- package/fixtures/S-Prop/a-computed-key-rejects/expect.json +10 -0
- package/fixtures/S-Prop/a-computed-key-rejects/input.ts +3 -0
- package/fixtures/S-Prop/literal-keys/expect.json +15 -0
- package/fixtures/S-Prop/literal-keys/input.ts +1 -0
- package/fixtures/S-ReExport/named-from-a-sibling/expect.json +18 -0
- package/fixtures/S-ReExport/named-from-a-sibling/project/app.ts +1 -0
- package/fixtures/S-ReExport/named-from-a-sibling/project/config.ts +2 -0
- package/fixtures/S-Shorthand/a-shorthand-property-resolves-as-an-identifier/expect.json +14 -0
- package/fixtures/S-Shorthand/a-shorthand-property-resolves-as-an-identifier/input.ts +4 -0
- package/fixtures/S-TopConst/an-unexported-const-is-a-binding/expect.json +16 -0
- package/fixtures/S-TopConst/an-unexported-const-is-a-binding/project/binding.ts +3 -0
- package/fixtures/S-TopConst/an-unexported-const-is-a-binding/project/invisible.ts +3 -0
- package/fixtures/UNCOVERED.md +1 -28
- package/fixtures/roundtrip/a-resource-and-its-attribute/expect.json +8 -0
- package/fixtures/roundtrip/a-resource-and-its-attribute/value.json +29 -0
- package/fixtures/roundtrip/a-resource-by-args/expect.json +8 -0
- package/fixtures/roundtrip/a-resource-by-args/value.json +14 -0
- package/fixtures/roundtrip/intrinsics-and-a-symbol/expect.json +8 -0
- package/fixtures/roundtrip/intrinsics-and-a-symbol/value.json +36 -0
- package/fixtures/roundtrip/scalars-and-containers/expect.json +8 -0
- package/fixtures/roundtrip/scalars-and-containers/value.json +28 -0
- package/package.json +1 -1
- package/spec/VERSION +1 -1
- package/spec/hosts.md +6 -2
- package/spec/judgments.md +27 -10
- package/spec/rules.md +7 -4
- package/spec/values.md +47 -2
- package/src/adapter.ts +53 -0
- package/src/adapters/chant.ts +361 -10
- package/src/adapters/rust.ts +77 -0
- package/src/chant-agreement.test.ts +68 -23
- package/src/corpus.test.ts +12 -0
- package/src/corpus.ts +76 -34
- package/src/fixture.ts +42 -3
- package/src/host.ts +50 -0
- package/src/runner.test.ts +6 -2
- package/src/runner.ts +107 -5
- package/src/rust-agreement.test.ts +37 -0
package/fixtures/UNCOVERED.md
CHANGED
|
@@ -2,36 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Deliberate, and this list may only shrink (#8). Each entry names the rule and why it is still uncovered. Remove an entry when its fixture lands; the gate fails if an entry is stale.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
135 of 139 rules have fixtures. Every rule below needs something the reference implementation does not have, or something no adapter can observe; the entry says which.
|
|
6
6
|
|
|
7
|
-
- `F-Rule-Input` — the harness has no rule hook and no findings-as-data fixture kind yet (#101)
|
|
8
|
-
- `F-Rule-Phase` — the harness has no rule hook and no findings-as-data fixture kind yet (#101)
|
|
9
|
-
- `F-Rule-Pure` — the harness has no rule hook and no findings-as-data fixture kind yet (#101)
|
|
10
|
-
- `F-Rule-Finding` — the harness has no rule hook and no findings-as-data fixture kind yet (#101)
|
|
11
|
-
- `F-Rule-Equivalence` — the harness has no rule hook and no findings-as-data fixture kind yet (#101)
|
|
12
|
-
- `F-Rule-Supply` — the harness has no rule hook and no findings-as-data fixture kind yet (#101)
|
|
13
|
-
- `F-Div-Step` — needs `{__compositeStep}`, which has no fate in the reference implementation (no composite factory form)
|
|
14
|
-
- `F-Eval-Interior` — an unresolved chain inside an intrinsic call folds to a symbol only with a registry in scope, and an expression fixture names no host
|
|
15
|
-
- `F-Host-Composite` — needs the composite registration form `Composite(fn, "N")`, which the reference implementation does not have
|
|
16
7
|
- `F-Host-Generality` — says what a host may vary and what it may not; no verdict exercises it
|
|
17
|
-
- `F-IsolatedRefusal` — needs isolation mode, which the reference implementation does not have
|
|
18
8
|
- `F-NoOwnExecution` — measured by chant's `test/leftness` profile; an adapter reports verdicts and cannot observe execution
|
|
19
9
|
- `F-NotProject` — a file inside the host's own module tree; the reference's project is a map with no outside
|
|
20
|
-
- `F-Obs-Counters` — the conformance adapter exposes no counters
|
|
21
10
|
- `F-Obs-Provenance` — an optional capability, reported rather than asserted
|
|
22
|
-
- `F-Val-Domain` — no fixture yet; corpus is #24's
|
|
23
|
-
- `F-Val-Envelope` — no fixture yet; corpus is #24's
|
|
24
|
-
- `F-Val-Symbol-Scope` — no fixture yet; corpus is #24's
|
|
25
|
-
- `S-Disqualify` — no fixture yet; corpus is #24's
|
|
26
|
-
- `S-ExportDestructure` — no fixture yet; corpus is #24's
|
|
27
|
-
- `S-ExportNamed` — no fixture yet; corpus is #24's
|
|
28
|
-
- `S-ExportResource` — no fixture yet; corpus is #24's
|
|
29
|
-
- `S-ExportSingle` — no fixture yet; corpus is #24's
|
|
30
|
-
- `S-ExportTypeOnly` — no fixture yet; corpus is #24's
|
|
31
|
-
- `S-FactoryBody` — needs the composite factory form, which the reference implementation does not have
|
|
32
|
-
- `S-FactoryParams` — needs the composite factory form, which the reference implementation does not have
|
|
33
|
-
- `S-Module` — no fixture yet; corpus is #24's
|
|
34
|
-
- `S-Prop` — no fixture yet; corpus is #24's
|
|
35
|
-
- `S-ReExport` — no fixture yet; corpus is #24's
|
|
36
|
-
- `S-Shorthand` — no fixture yet; corpus is #24's
|
|
37
|
-
- `S-TopConst` — no fixture yet; corpus is #24's
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rules": [
|
|
3
|
+
"F-Val-Source"
|
|
4
|
+
],
|
|
5
|
+
"roundtrip": true,
|
|
6
|
+
"host": "shapes",
|
|
7
|
+
"note": "A resource with props and attributes, and attribute references to it at the top and nested. The generator names the same-file binding; F-Eval-Member step 1 folds the read back to the reference."
|
|
8
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"logs": {
|
|
3
|
+
"__resource": "Bucket",
|
|
4
|
+
"props": {
|
|
5
|
+
"name": "logs",
|
|
6
|
+
"tags": [
|
|
7
|
+
"a",
|
|
8
|
+
"b"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"attributes": {
|
|
12
|
+
"region": "eu"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"arn": {
|
|
16
|
+
"__attrRef": {
|
|
17
|
+
"entity": "logs",
|
|
18
|
+
"attribute": "arn"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"site": {
|
|
22
|
+
"origin": {
|
|
23
|
+
"__attrRef": {
|
|
24
|
+
"entity": "logs",
|
|
25
|
+
"attribute": "website"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rules": [
|
|
3
|
+
"F-Val-Source"
|
|
4
|
+
],
|
|
5
|
+
"roundtrip": true,
|
|
6
|
+
"host": "shapes",
|
|
7
|
+
"note": "A resource whose constructor arguments are not (props) or (props, attributes): args is authoritative and the generator spreads it; props is the first object-literal argument, reported for readers and never re-passed (F-Val-Arity)."
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rules": [
|
|
3
|
+
"F-Val-Source"
|
|
4
|
+
],
|
|
5
|
+
"roundtrip": true,
|
|
6
|
+
"host": "shapes",
|
|
7
|
+
"note": "Both intrinsic forms with a symbol, an attribute reference and a span that needs escaping inside them. A symbol has a form only inside an interior, which is where the generator puts it."
|
|
8
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"logs": {
|
|
3
|
+
"__resource": "Bucket",
|
|
4
|
+
"props": {
|
|
5
|
+
"name": "logs"
|
|
6
|
+
}
|
|
7
|
+
},
|
|
8
|
+
"tagged": {
|
|
9
|
+
"__intrinsic": "join",
|
|
10
|
+
"strings": [
|
|
11
|
+
"arn:",
|
|
12
|
+
":",
|
|
13
|
+
"/`${x}`"
|
|
14
|
+
],
|
|
15
|
+
"values": [
|
|
16
|
+
{
|
|
17
|
+
"__symbol": "Region.Name"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"__attrRef": {
|
|
21
|
+
"entity": "logs",
|
|
22
|
+
"attribute": "arn"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"called": {
|
|
28
|
+
"__intrinsic": "ref",
|
|
29
|
+
"args": [
|
|
30
|
+
"logs",
|
|
31
|
+
{
|
|
32
|
+
"__symbol": "Stack.Id"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scalars": {
|
|
3
|
+
"s": "text",
|
|
4
|
+
"n": 1.5,
|
|
5
|
+
"big": 1e+21,
|
|
6
|
+
"b": false,
|
|
7
|
+
"z": null,
|
|
8
|
+
"u": "$undefined"
|
|
9
|
+
},
|
|
10
|
+
"list": [
|
|
11
|
+
1,
|
|
12
|
+
"two",
|
|
13
|
+
[
|
|
14
|
+
3,
|
|
15
|
+
[
|
|
16
|
+
4
|
|
17
|
+
]
|
|
18
|
+
],
|
|
19
|
+
{
|
|
20
|
+
"five": 5
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"keys": {
|
|
24
|
+
"plain": 1,
|
|
25
|
+
"with-dash": 2,
|
|
26
|
+
"3": "three"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/tsad-conformance",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "The conformance suite of the typescript-as-data specification: fixture loader, runner, and the named hosts. An implementation supplies an adapter and gets a report.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
package/spec/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.6
|
package/spec/hosts.md
CHANGED
|
@@ -90,8 +90,12 @@ helpers and `propagate` mutates in place; `createResource()`/
|
|
|
90
90
|
|
|
91
91
|
A call into a **package** folds only through a closed allowlist, a
|
|
92
92
|
registered intrinsic or helper, checked by name *and* by the provenance of
|
|
93
|
-
the binding (R3.3, F-Div-Provenance)
|
|
94
|
-
|
|
93
|
+
the binding (R3.3, F-Div-Provenance), or at a declarator by invocation
|
|
94
|
+
(F-Call), reached directly or through a const alias (F-Declarator), where
|
|
95
|
+
since `1.6` the result is a value whatever it is. A call nested inside an
|
|
96
|
+
expression never folds through a package. A call into a **project file**
|
|
97
|
+
folds whenever the callee's body is itself in the subset (R6.5), with no
|
|
98
|
+
allowlist.
|
|
95
99
|
|
|
96
100
|
The asymmetry is the trust boundary (R2.1, #36). Package code is already
|
|
97
101
|
loaded and executed by the build before discovery begins; admitting a call
|
package/spec/judgments.md
CHANGED
|
@@ -63,6 +63,7 @@ another language embeds, or a JavaScript tool that folds and never runs. It is
|
|
|
63
63
|
| `F-Val-Fate` | altered: revival is serialization. An envelope is the output; `{__resource}`, `{__intrinsic}` and `{__attrRef}` reach the artifact as data for the host's serializer to map. No constructor and no function is invoked |
|
|
64
64
|
| `F-Eval-CallHelper`, `F-Eval-CallEager`, `F-Host-Admission`, `F-Host-NoSubstitution` | absent: there is nothing to invoke. A registered helper or eager name is an ordinary unresolved identifier |
|
|
65
65
|
| `F-Eval-Tagged`, `F-Eval-CallIntrinsic` | apply; the envelope stays an envelope |
|
|
66
|
+
| `F-Val-Source` | applies, and the round trip is `fold(generate(v)) = v` literally: no fate runs, so the fold of a form is the envelope itself. The helper and composite-step cases are absent with their rules |
|
|
66
67
|
| `F-Call`, `F-Host-Composite` | interpretation only (step 4). A factory that is not interpretable is an error, never invoked |
|
|
67
68
|
| `S-LocalFunction`, `S-CallLocal` | apply in full: a same-file or project-imported function is called by interpretation, which needs no runtime |
|
|
68
69
|
| `S-ExportDefault` | applies: a default export is the declarator named `default`. In `full` it is permitted, not required, and chant does not yet admit it |
|
|
@@ -331,11 +332,23 @@ F-IsolatedRefusal like any other.
|
|
|
331
332
|
here; a second construction would put two entities where running puts one
|
|
332
333
|
(F-Count). Under `isolated`, a `T` from a project file is
|
|
333
334
|
F-IsolatedRefusal.
|
|
334
|
-
- *single* `export const x = e`: if `e` is a call,
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
335
|
+
- *single* `export const x = e`: if `e` is a call, its direct arguments are
|
|
336
|
+
resolved first. An argument that is itself a package call resolves by
|
|
337
|
+
F-Call, as does a member read on such a call or a const alias of either;
|
|
338
|
+
every other argument is J1's (`1.6`, #110, `L2.18`). Then the call is
|
|
339
|
+
F-Call for an unregistered callee, or J1's registered form for a helper or
|
|
340
|
+
an intrinsic. If `e` is a member or element access on a
|
|
341
|
+
call's result, F-Call then index (base must be an indexable object); when
|
|
342
|
+
`e` is an identifier bound by a top-level `const`,
|
|
343
|
+
through any chain of such aliases (`L7.7`), to a call or to a member access
|
|
344
|
+
on one, the same again, with the call resolved once per file (F-Count);
|
|
345
|
+
otherwise J1 on `e`, revived. The alias case was added in `1.6` (#110),
|
|
346
|
+
since chant had followed it for a composite and for any package export
|
|
347
|
+
alike (`L2.18`); a call reached any other way, nested inside an expression,
|
|
348
|
+
stays J1's rejection.
|
|
349
|
+
- *destructure* `export const { a, b: c } = e`: `e`, through the same
|
|
350
|
+
aliases, must resolve to a composite instance or an indexable object; each
|
|
351
|
+
element indexes it.
|
|
339
352
|
- *named-export* `export { a, b as c }`: each local name resolves through
|
|
340
353
|
`locals` then `externals`, by F-Eval-Ident and not by re-folding the
|
|
341
354
|
initializer, so a name bound to a same-file `new` reads F-Prebuild's
|
|
@@ -361,10 +374,14 @@ F-IsolatedRefusal like any other.
|
|
|
361
374
|
6. Otherwise the module is imported (once per build) and `c` **invoked** with
|
|
362
375
|
the resolved arguments; `factoryInvocations += 1`, and
|
|
363
376
|
`projectFactoryInvocations += 1` if the specifier is a project file.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
`
|
|
377
|
+
An argument is resolved as F-Declarator says, a direct package call by
|
|
378
|
+
this rule in turn and the rest by J1; a call nested deeper inside an
|
|
379
|
+
argument is J1's rejection. Arguments that are live objects pass
|
|
380
|
+
through unchanged; a `{__attrRef}` among them stays symbolic (R1.2, `L6.9`).
|
|
381
|
+
7. The result is a value, live or plain, and is what the declarator binds
|
|
382
|
+
(`1.6`, #110); a destructured declarator needs an indexable object
|
|
383
|
+
(F-Declarator). Before `1.6` the text required an entity or a composite
|
|
384
|
+
instance here, which chant never implemented (`L8.19`).
|
|
368
385
|
|
|
369
386
|
**F-Count.** Within `f`, a composite call reached by several member accesses
|
|
370
387
|
or destructured names is resolved once (`ResolveCtx.memo`); a same-file
|
|
@@ -879,7 +896,7 @@ position and calls through a bare identifier. A body that references one of
|
|
|
879
896
|
its module's own module-level resources declines (L7.6), that resource is a
|
|
880
897
|
singleton the run path shares, and interpretation would not, and
|
|
881
898
|
`constResolvesToResource` follows alias chains so it cannot be smuggled in
|
|
882
|
-
(L7.7). The defining module is never imported; members are built by the
|
|
899
|
+
(`L7.7`). The defining module is never imported; members are built by the
|
|
883
900
|
lexicon's constructors from the folded props.
|
|
884
901
|
|
|
885
902
|
**F-Eval-CallEager, F-Eval-CallMethod** *(was R7.3. Evaluate eagerly)*
|
package/spec/rules.md
CHANGED
|
@@ -96,7 +96,10 @@ refuses to load one into its own process while the sandbox is armed and
|
|
|
96
96
|
runs it in the child instead (chant#1131), which is the isolation mode's
|
|
97
97
|
boundary drawn once more around rules.
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
The fixtures for this family carry the finding as data and not the rule,
|
|
100
|
+
since a rule is host code (#101): the `shapes` host names two rules by id and
|
|
101
|
+
phase, a fixture's `findings` says what they report, and an implementation
|
|
102
|
+
that carries no rule of that id says so and is skipped visibly. The runner
|
|
103
|
+
asks for each phase twice and holds the two runs to the same answer, which
|
|
104
|
+
is F-Rule-Pure tested before anything else, and `compareAdapters` holds two
|
|
105
|
+
implementations to the same findings, which is F-Rule-Equivalence.
|
package/spec/values.md
CHANGED
|
@@ -132,6 +132,32 @@ arguments (`foldIntrinsicValue`). Anywhere else an unresolved chain is a
|
|
|
132
132
|
located rejection (F-Reference, J2). A `__symbol` therefore never appears at
|
|
133
133
|
the top of a folded tree.
|
|
134
134
|
|
|
135
|
+
## F-Val-Source (every value has a source form)
|
|
136
|
+
|
|
137
|
+
For every value `v` of F-Val-Domain there is source in the subset
|
|
138
|
+
(grammar.md) whose fold, in the profile named, is `v`. The table names one
|
|
139
|
+
such form per case, which is the form a generator should prefer and not the
|
|
140
|
+
only one the subset admits; the rule was added in `1.5` (#80).
|
|
141
|
+
|
|
142
|
+
| Case | A source form that folds to it | In |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| scalar | the literal: `"s"`, `1.5`, `true`, `null`, `undefined` (F-Eval-Literal, F-Eval-Undefined) | both |
|
|
145
|
+
| array, object | the literal, with each member's source form as its element or value; a key that is not an identifier is a string key (S-Prop) | both |
|
|
146
|
+
| attribute reference `{__attrRef: {entity, attribute}}` | `entity.attribute`, where `entity` is a same-file `const` bound to a `new` (F-Eval-Member step 1, F-Prebuild) | both |
|
|
147
|
+
| intrinsic, tag form `{__intrinsic, strings, values}` | the tagged template `name\`s₀${v₀}s₁…\`` for a registered tag (F-Eval-Tagged) | both |
|
|
148
|
+
| intrinsic, call form `{__intrinsic, args}` | `name(args…)` for an intrinsic registered with `foldsAsCall` (F-Eval-CallIntrinsic) | both |
|
|
149
|
+
| helper call `{__helper, args}` | `name(args…)` for a registered helper (F-Eval-CallHelper). J1 yields the envelope and revival invokes the helper, so the envelope is never the output | `full` |
|
|
150
|
+
| resource `{__resource, props, attributes?, args?}` | `new C(props)`, `new C(props, attributes)`, or `new C(…args)` when `args` is present (F-Eval-New, F-Val-Arity) | both |
|
|
151
|
+
| composite step `{__compositeStep, args}` | the interpretable factory form (F-Host-Composite) | `full` |
|
|
152
|
+
| symbol `{__symbol}` | the unresolved chain, written inside an intrinsic's interior (F-Eval-Interior, F-Val-Symbol-Scope) | both |
|
|
153
|
+
|
|
154
|
+
Nothing else is a value, so nothing else needs a form, and the fold of a
|
|
155
|
+
form in `full` is the value after F-Val-Fate, so a resource's form folds to a
|
|
156
|
+
live instance there and to the envelope in `data-host`; the round trip
|
|
157
|
+
(README.md, "the generator obligation") is stated per profile for that
|
|
158
|
+
reason. A live instance has no source form of its own: its form is the
|
|
159
|
+
envelope's.
|
|
160
|
+
|
|
135
161
|
---
|
|
136
162
|
|
|
137
163
|
## Rationale
|
|
@@ -144,8 +170,9 @@ The spec must define what a fold produces. Every other requirement quantifies
|
|
|
144
170
|
over it, and it is currently defined only by a TypeScript union
|
|
145
171
|
(`FoldedValue`, `fold.ts:116`; L4.1).
|
|
146
172
|
|
|
147
|
-
|
|
148
|
-
arrays and plain objects. The rest carry
|
|
173
|
+
There are nine cases, and six of them are ordinary JSON, the scalars with
|
|
174
|
+
`undefined` beside them, plus arrays and plain objects. The rest carry
|
|
175
|
+
envelopes:
|
|
149
176
|
|
|
150
177
|
| Case | Envelope key | Denotes | Fate (R1.2) |
|
|
151
178
|
|---|---|---|---|
|
|
@@ -157,6 +184,24 @@ arrays and plain objects. The rest carry envelopes:
|
|
|
157
184
|
| `FoldedCompositeStepCall` | `__compositeStep` | `<Identifier>(...).step`, member fixed | revived |
|
|
158
185
|
| `SymbolicValue` | `__symbol` | source text preserved inside an intrinsic interior | revived |
|
|
159
186
|
|
|
187
|
+
**F-Val-Source.** The round trip, `fold(generate(v)) = v`, is what makes
|
|
188
|
+
the choice of language a matter of correctness. A generator decides what
|
|
189
|
+
each value is: this string is a literal and that one is a reference to
|
|
190
|
+
another resource's attribute, while a repetition across forty resources is
|
|
191
|
+
one `const`. Each decision needs a form the subset can express and the fold
|
|
192
|
+
reverses, and the rule is the completeness half of that property, written
|
|
193
|
+
as a table rather than a sentence so that a generator author can read off a
|
|
194
|
+
form per case. The two open questions on #80 are settled here as follows.
|
|
195
|
+
The table names one form per case and requires only that one exists, so
|
|
196
|
+
generators stay comparable without being constrained to agree; and the
|
|
197
|
+
property is stated per profile, because in `full` the fold of a resource's
|
|
198
|
+
form is a live instance and not the envelope. chant's three generators, `chant import` from a template,
|
|
199
|
+
`--from` live import and carve-out from Terraform, emit through one
|
|
200
|
+
pipeline (`L12.1`) whose forms are the table's; its Kubernetes round-trip
|
|
201
|
+
suite compares resource count and kinds after re-serialization and not
|
|
202
|
+
bytes (`L12.4`), so the byte-level measurement the paper wants is still to be
|
|
203
|
+
taken.
|
|
204
|
+
|
|
160
205
|
**F-Val-Envelope** *(was R1.1. Symbolic is not unevaluated)*
|
|
161
206
|
|
|
162
207
|
An `__attrRef` is not a thunk. It is the envelope `AttrRef.prototype.toJSON()`
|
package/src/adapter.ts
CHANGED
|
@@ -22,8 +22,42 @@ export interface ProjectResult {
|
|
|
22
22
|
tentative?: Record<string, "fold" | "run">;
|
|
23
23
|
/** For a file J3 tainted, the file whose taint reached it. */
|
|
24
24
|
taintedBy?: Record<string, string>;
|
|
25
|
+
/** F-Obs-Counters, per build. Omitted by an implementation whose public entry exposes none. */
|
|
26
|
+
counters?: ExecutionCounters;
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
/**
|
|
30
|
+
* F-Obs-Counters: in-process factory or constructor invocations while folding;
|
|
31
|
+
* of those, how many resolved to project-owned code; and how many factory
|
|
32
|
+
* bodies were interpreted instead. Three non-negative integers; the names
|
|
33
|
+
* follow the reference and only the shape is normative.
|
|
34
|
+
*/
|
|
35
|
+
export interface ExecutionCounters { factoryInvocations: number; projectFactoryInvocations: number; factoryInterpretations: number }
|
|
36
|
+
|
|
37
|
+
/** F-Rule-Finding's closed severity set. */
|
|
38
|
+
export type Severity = "error" | "warning" | "info";
|
|
39
|
+
/** F-Rule-Phase: named by the input the rule reads, the folded namespace or the artifact. */
|
|
40
|
+
export type RulePhase = "pre" | "post";
|
|
41
|
+
/**
|
|
42
|
+
* A finding, as data (F-Rule-Finding). `rule`, `severity` and `subject` are
|
|
43
|
+
* compared; `message` is not (F-Obs-Messages); `at` only when the fixture
|
|
44
|
+
* gives one and the implementation reports one (F-Obs-Provenance is
|
|
45
|
+
* optional). `file` names the file whose namespace holds the subject for a
|
|
46
|
+
* pre-synthesis finding; a post-synthesis finding concerns the artifact and
|
|
47
|
+
* carries none.
|
|
48
|
+
*/
|
|
49
|
+
export interface Finding {
|
|
50
|
+
rule: string;
|
|
51
|
+
severity: Severity;
|
|
52
|
+
subject: string;
|
|
53
|
+
message: string;
|
|
54
|
+
file?: string;
|
|
55
|
+
at?: { line: number; column: number };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** J2's ι (F-IsolatedRefusal): under `isolated`, no project code is invoked or imported on the fold path. */
|
|
59
|
+
export type IsolationMode = "open" | "isolated";
|
|
60
|
+
|
|
27
61
|
export interface ConformanceAdapter {
|
|
28
62
|
readonly name: string;
|
|
29
63
|
/**
|
|
@@ -48,5 +82,24 @@ export interface ConformanceAdapter {
|
|
|
48
82
|
foldProject?(
|
|
49
83
|
files: Map<string, string>,
|
|
50
84
|
host?: ConformanceHost,
|
|
85
|
+
mode?: IsolationMode,
|
|
51
86
|
): ProjectResult | "unavailable" | Promise<ProjectResult | "unavailable">;
|
|
87
|
+
/**
|
|
88
|
+
* The findings of the host's rules of one phase over the build (#101).
|
|
89
|
+
* A rule is host code, so the harness carries only its identifier and its
|
|
90
|
+
* findings; an implementation that cannot run a rule the host names
|
|
91
|
+
* reports "unavailable" and the fixture is skipped visibly.
|
|
92
|
+
*/
|
|
93
|
+
rules?(
|
|
94
|
+
files: Map<string, string>,
|
|
95
|
+
host: ConformanceHost,
|
|
96
|
+
phase: RulePhase,
|
|
97
|
+
): Finding[] | "unavailable" | Promise<Finding[] | "unavailable">;
|
|
98
|
+
/**
|
|
99
|
+
* The round trip's generator (#80): source in the subset, as one module,
|
|
100
|
+
* whose fold is `namespace` (export name to value, envelopes included).
|
|
101
|
+
* "unavailable" for an implementation with no generator, or for a value it
|
|
102
|
+
* has no form for; F-Val-Source says a form exists for every value.
|
|
103
|
+
*/
|
|
104
|
+
generate?(namespace: Record<string, unknown>, host?: ConformanceHost): string | "unavailable";
|
|
52
105
|
}
|