aontu 0.62.0 → 0.64.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/README.md +7 -7
- package/dist/agentsmd.js +0 -27
- package/dist/agentsmd.js.map +1 -1
- package/dist/alias.js.map +1 -1
- package/dist/allow.js +0 -92
- package/dist/allow.js.map +1 -1
- package/dist/aontu.d.ts +3 -3
- package/dist/aontu.js +4 -84
- package/dist/aontu.js.map +1 -1
- package/dist/aontumodel.d.ts +4 -0
- package/dist/aontumodel.js +27 -0
- package/dist/aontumodel.js.map +1 -0
- package/dist/casing.d.ts +5 -0
- package/dist/casing.js +90 -0
- package/dist/casing.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +228 -935
- package/dist/cli.js.map +1 -1
- package/dist/ctx.js +0 -48
- package/dist/ctx.js.map +1 -1
- package/dist/diff.js +0 -32
- package/dist/diff.js.map +1 -1
- package/dist/err.js +0 -40
- package/dist/err.js.map +1 -1
- package/dist/escape.js +0 -45
- package/dist/escape.js.map +1 -1
- package/dist/exactjson.d.ts +0 -35
- package/dist/exactjson.js +0 -131
- package/dist/exactjson.js.map +1 -1
- package/dist/format.js +13 -203
- package/dist/format.js.map +1 -1
- package/dist/grammar.d.ts +9 -0
- package/dist/grammar.js +54 -0
- package/dist/grammar.js.map +1 -0
- package/dist/graph.js +0 -26
- package/dist/graph.js.map +1 -1
- package/dist/hcanon.js +0 -82
- package/dist/hcanon.js.map +1 -1
- package/dist/helpdoc.js +2 -2
- package/dist/helpdoc.js.map +1 -1
- package/dist/hints.d.ts +0 -6
- package/dist/hints.js +57 -55
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.js +0 -114
- package/dist/jsonschema.js.map +1 -1
- package/dist/keyorder.d.ts +0 -7
- package/dist/keyorder.js +0 -41
- package/dist/keyorder.js.map +1 -1
- package/dist/lang.js +17 -915
- package/dist/lang.js.map +1 -1
- package/dist/lsp-server.js +0 -16
- package/dist/lsp-server.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +12 -159
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.js +0 -26
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp.js +0 -149
- package/dist/mcp.js.map +1 -1
- package/dist/mod-tool.js +16 -131
- package/dist/mod-tool.js.map +1 -1
- package/dist/mod.js +0 -162
- package/dist/mod.js.map +1 -1
- package/dist/patch.js +0 -217
- package/dist/patch.js.map +1 -1
- package/dist/profile.d.ts +9 -0
- package/dist/profile.js +28 -0
- package/dist/profile.js.map +1 -0
- package/dist/provenance.js +0 -140
- package/dist/provenance.js.map +1 -1
- package/dist/query.js +0 -75
- package/dist/query.js.map +1 -1
- package/dist/reach.js +0 -43
- package/dist/reach.js.map +1 -1
- package/dist/relation.js +0 -61
- package/dist/relation.js.map +1 -1
- package/dist/report-sarif.d.ts +0 -11
- package/dist/report-sarif.js +0 -28
- package/dist/report-sarif.js.map +1 -1
- package/dist/sig.js +0 -35
- package/dist/sig.js.map +1 -1
- package/dist/sigdecl.js +1 -1
- package/dist/sigdecl.js.map +1 -1
- package/dist/siggate.js +0 -4
- package/dist/siggate.js.map +1 -1
- package/dist/site.js +3 -29
- package/dist/site.js.map +1 -1
- package/dist/subsume.d.ts +0 -10
- package/dist/subsume.js +0 -137
- package/dist/subsume.js.map +1 -1
- package/dist/template.d.ts +2 -1
- package/dist/template.js +58 -138
- package/dist/template.js.map +1 -1
- package/dist/trace.d.ts +21 -0
- package/dist/trace.js +107 -0
- package/dist/trace.js.map +1 -0
- package/dist/trim.js +0 -41
- package/dist/trim.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.js.map +1 -1
- package/dist/unify.js +13 -248
- package/dist/unify.js.map +1 -1
- package/dist/utility.js +0 -22
- package/dist/utility.js.map +1 -1
- package/dist/val/AbnfFuncVal.d.ts +18 -0
- package/dist/val/AbnfFuncVal.js +132 -0
- package/dist/val/AbnfFuncVal.js.map +1 -0
- package/dist/val/AbsentVal.d.ts +11 -0
- package/dist/val/AbsentVal.js +30 -0
- package/dist/val/AbsentVal.js.map +1 -0
- package/dist/val/AggFuncVal.d.ts +10 -1
- package/dist/val/AggFuncVal.js +104 -116
- package/dist/val/AggFuncVal.js.map +1 -1
- package/dist/val/ArithFuncVal.js +0 -12
- package/dist/val/ArithFuncVal.js.map +1 -1
- package/dist/val/BagVal.js +1 -78
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/BigDecimalVal.js +0 -16
- package/dist/val/BigDecimalVal.js.map +1 -1
- package/dist/val/BigIntegerVal.js +0 -16
- package/dist/val/BigIntegerVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +0 -9
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/CmpFuncVal.d.ts +2 -0
- package/dist/val/CmpFuncVal.js +49 -72
- package/dist/val/CmpFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.js +0 -29
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.js +0 -500
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/ContainerKindVal.js +0 -2
- package/dist/val/ContainerKindVal.js.map +1 -1
- package/dist/val/CopyFuncVal.js +0 -3
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.js +0 -179
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DeprecateFuncVal.js.map +1 -1
- package/dist/val/DisjunctVal.js +0 -152
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/EachFuncVal.js +0 -3
- package/dist/val/EachFuncVal.js.map +1 -1
- package/dist/val/EmitFuncVal.d.ts +1 -1
- package/dist/val/EmitFuncVal.js +6 -119
- package/dist/val/EmitFuncVal.js.map +1 -1
- package/dist/val/ExpectVal.js +0 -62
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FilterFuncVal.js +0 -25
- package/dist/val/FilterFuncVal.js.map +1 -1
- package/dist/val/FuncBaseVal.d.ts +1 -0
- package/dist/val/FuncBaseVal.js +7 -127
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/GraphAtomVal.js +0 -15
- package/dist/val/GraphAtomVal.js.map +1 -1
- package/dist/val/HideFuncVal.js +0 -13
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IntegerVal.js +0 -61
- package/dist/val/IntegerVal.js.map +1 -1
- package/dist/val/JunctionVal.js +0 -20
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.js +0 -46
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +0 -57
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js +0 -11
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +0 -151
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MatchFuncVal.js +0 -27
- package/dist/val/MatchFuncVal.js.map +1 -1
- package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
- package/dist/val/MaybeFuncVal.js +50 -0
- package/dist/val/MaybeFuncVal.js.map +1 -0
- package/dist/val/MoveFuncVal.js +0 -18
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.js +0 -60
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NomFuncVal.js +18 -54
- package/dist/val/NomFuncVal.js.map +1 -1
- package/dist/val/NumberVal.js +0 -15
- package/dist/val/NumberVal.js.map +1 -1
- package/dist/val/OpBaseVal.d.ts +1 -0
- package/dist/val/OpBaseVal.js +3 -15
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/PackFuncVal.js +0 -34
- package/dist/val/PackFuncVal.js.map +1 -1
- package/dist/val/PathFuncVal.js +0 -6
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PathVal.js +0 -41
- package/dist/val/PathVal.js.map +1 -1
- package/dist/val/PlaceVal.js +0 -25
- package/dist/val/PlaceVal.js.map +1 -1
- package/dist/val/PlusOpVal.d.ts +1 -7
- package/dist/val/PlusOpVal.js +13 -74
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js +0 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.js +0 -167
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RecurseVal.js +0 -55
- package/dist/val/RecurseVal.js.map +1 -1
- package/dist/val/RefVal.js +0 -282
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.js +3 -232
- package/dist/val/ReferFuncVal.js.map +1 -1
- package/dist/val/ScalarKindVal.js +0 -49
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/ScalarVal.js +0 -11
- package/dist/val/ScalarVal.js.map +1 -1
- package/dist/val/StrFuncVal.js +0 -18
- package/dist/val/StrFuncVal.js.map +1 -1
- package/dist/val/SuperFuncVal.js +0 -32
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.js +0 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TranslateFuncVal.js +1 -3
- package/dist/val/TranslateFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js +0 -11
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +1 -0
- package/dist/val/Val.js +2 -133
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js +0 -12
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/arith.js +0 -37
- package/dist/val/arith.js.map +1 -1
- package/dist/val/caserange.js +0 -61
- package/dist/val/caserange.js.map +1 -1
- package/dist/val/members.js +0 -6
- package/dist/val/members.js.map +1 -1
- package/dist/val/numcmp.js +0 -11
- package/dist/val/numcmp.js.map +1 -1
- package/dist/val/numkind.js +0 -145
- package/dist/val/numkind.js.map +1 -1
- package/dist/val/valutil.js +0 -16
- package/dist/val/valutil.js.map +1 -1
- package/dist/vet.js +0 -461
- package/dist/vet.js.map +1 -1
- package/dist/view.js +0 -414
- package/dist/view.js.map +1 -1
- package/dist/walk.js +0 -41
- package/dist/walk.js.map +1 -1
- package/grammar/aontu.abnf +8 -6
- package/grammar/aontu.gbnf +4 -4
- package/grammar/aontu.lark +4 -4
- package/grammar/aontu.tmLanguage.json +1 -1
- package/package.json +4 -2
- package/skill/tasks.md +9 -7
- package/src/agentsmd.ts +0 -35
- package/src/alias.ts +0 -39
- package/src/allow.ts +1 -96
- package/src/aontu.ts +4 -116
- package/src/aontumodel.ts +26 -0
- package/src/casing.ts +95 -0
- package/src/cli.ts +258 -1024
- package/src/ctx.ts +0 -103
- package/src/diff.ts +0 -40
- package/src/err.ts +0 -40
- package/src/escape.ts +0 -46
- package/src/exactjson.ts +0 -131
- package/src/format.ts +14 -257
- package/src/grammar.ts +72 -0
- package/src/graph.ts +0 -61
- package/src/hcanon.ts +0 -82
- package/src/helpdoc.ts +2 -2
- package/src/hints.ts +69 -57
- package/src/jsonschema.ts +0 -123
- package/src/keyorder.ts +0 -42
- package/src/lang.ts +19 -931
- package/src/lsp-server.ts +0 -16
- package/src/lsp.ts +12 -180
- package/src/mcp-server.ts +0 -31
- package/src/mcp.ts +0 -169
- package/src/mod-tool.ts +18 -159
- package/src/mod.ts +0 -178
- package/src/patch.ts +0 -232
- package/src/profile.ts +42 -0
- package/src/provenance.ts +0 -183
- package/src/query.ts +0 -84
- package/src/reach.ts +0 -53
- package/src/relation.ts +0 -84
- package/src/report-sarif.ts +0 -48
- package/src/sig.ts +0 -35
- package/src/sigdecl.ts +1 -1
- package/src/siggate.ts +0 -30
- package/src/site.ts +3 -29
- package/src/subsume.ts +1 -161
- package/src/template.ts +69 -140
- package/src/trace.ts +157 -0
- package/src/trim.ts +0 -53
- package/src/type.ts +2 -45
- package/src/unify.ts +14 -257
- package/src/utility.ts +0 -31
- package/src/val/AbnfFuncVal.ts +181 -0
- package/src/val/AbsentVal.ts +54 -0
- package/src/val/AggFuncVal.ts +152 -188
- package/src/val/ArithFuncVal.ts +0 -20
- package/src/val/BagVal.ts +1 -78
- package/src/val/BigDecimalVal.ts +0 -16
- package/src/val/BigIntegerVal.ts +0 -16
- package/src/val/CloseFuncVal.ts +0 -9
- package/src/val/CmpFuncVal.ts +68 -184
- package/src/val/ConjunctVal.ts +0 -33
- package/src/val/ConstraintVal.ts +2 -537
- package/src/val/ContainerKindVal.ts +0 -18
- package/src/val/CopyFuncVal.ts +0 -5
- package/src/val/Decimal.ts +1 -185
- package/src/val/DeprecateFuncVal.ts +0 -10
- package/src/val/DisjunctVal.ts +0 -157
- package/src/val/EachFuncVal.ts +0 -40
- package/src/val/EmitFuncVal.ts +8 -208
- package/src/val/ExpectVal.ts +0 -62
- package/src/val/FilterFuncVal.ts +0 -55
- package/src/val/FuncBaseVal.ts +9 -130
- package/src/val/GraphAtomVal.ts +0 -42
- package/src/val/HideFuncVal.ts +0 -15
- package/src/val/IntegerVal.ts +0 -61
- package/src/val/JunctionVal.ts +0 -20
- package/src/val/KeyFuncVal.ts +0 -48
- package/src/val/ListVal.ts +0 -59
- package/src/val/LowerFuncVal.ts +0 -12
- package/src/val/MapVal.ts +0 -151
- package/src/val/MatchFuncVal.ts +0 -59
- package/src/val/MaybeFuncVal.ts +86 -0
- package/src/val/MoveFuncVal.ts +0 -20
- package/src/val/NilVal.ts +0 -60
- package/src/val/NomFuncVal.ts +10 -99
- package/src/val/NumberVal.ts +0 -16
- package/src/val/OpBaseVal.ts +4 -17
- package/src/val/PackFuncVal.ts +0 -63
- package/src/val/PathFuncVal.ts +0 -32
- package/src/val/PathVal.ts +0 -66
- package/src/val/PlaceVal.ts +0 -45
- package/src/val/PlusOpVal.ts +18 -75
- package/src/val/PrefFuncVal.ts +0 -1
- package/src/val/PrefVal.ts +0 -179
- package/src/val/RecurseVal.ts +0 -81
- package/src/val/RefVal.ts +1 -285
- package/src/val/ReferFuncVal.ts +4 -255
- package/src/val/ScalarKindVal.ts +0 -50
- package/src/val/ScalarVal.ts +0 -12
- package/src/val/StrFuncVal.ts +0 -44
- package/src/val/SuperFuncVal.ts +0 -42
- package/src/val/TopVal.ts +0 -1
- package/src/val/TranslateFuncVal.ts +1 -51
- package/src/val/UpperFuncVal.ts +0 -12
- package/src/val/Val.ts +3 -192
- package/src/val/VarVal.ts +0 -15
- package/src/val/arith.ts +0 -92
- package/src/val/caserange.ts +0 -62
- package/src/val/members.ts +0 -23
- package/src/val/numcmp.ts +1 -27
- package/src/val/numkind.ts +0 -149
- package/src/val/valutil.ts +0 -16
- package/src/vet.ts +1 -582
- package/src/view.ts +0 -507
- package/src/walk.ts +0 -41
- package/dist/lower.d.ts +0 -23
- package/dist/lower.js +0 -578
- package/dist/lower.js.map +0 -1
- package/dist/render.d.ts +0 -53
- package/dist/render.js +0 -547
- package/dist/render.js.map +0 -1
- package/dist/std.d.ts +0 -3
- package/dist/std.js +0 -672
- package/dist/std.js.map +0 -1
- package/dist/val/FormFuncVal.js +0 -55
- package/dist/val/FormFuncVal.js.map +0 -1
- package/dist/val/NamerFuncVal.d.ts +0 -12
- package/dist/val/NamerFuncVal.js +0 -176
- package/dist/val/NamerFuncVal.js.map +0 -1
- package/src/lower.ts +0 -636
- package/src/render.ts +0 -732
- package/src/std.ts +0 -683
package/src/graph.ts
CHANGED
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// THE DERIVED STRUCTURE (G4 phase 3,
|
|
4
|
-
// docs/capability-review/g4-identity-relations.md): an evaluated
|
|
5
|
-
// document has, besides its value, a GRAPH — the set of checked links,
|
|
6
|
-
// each from one tree position to another.
|
|
7
|
-
//
|
|
8
|
-
// The graph is PATH-NATIVE (ADR-014). There is no second namespace to
|
|
9
|
-
// index: a node's address is its path, so the entity index the first
|
|
10
|
-
// design carried is exactly the set of paths already in the edges, and
|
|
11
|
-
// the node a link starts at is derived from where the link sits rather
|
|
12
|
-
// than declared by a mark.
|
|
13
|
-
//
|
|
14
|
-
// G4's deliverable is that this exists and is DETERMINISTIC. What is
|
|
15
|
-
// built on it — impact analysis ("what reaches $.services.auth?"),
|
|
16
|
-
// reachability, context-window-sized slices — is a traversal, and its
|
|
17
|
-
// exposure as verbs and projections belongs to G7. Relation properties
|
|
18
|
-
// (acyclicity, inverse consistency) are G4 phase 5's, and consume
|
|
19
|
-
// exactly this edge set.
|
|
20
3
|
|
|
21
4
|
import type { Val } from './type'
|
|
22
5
|
|
|
@@ -24,35 +7,17 @@ import { cmpCodePoint } from './keyorder'
|
|
|
24
7
|
|
|
25
8
|
|
|
26
9
|
export type Edge = {
|
|
27
|
-
// The node the link starts at, as a `$.dotted.path`: the link's own
|
|
28
|
-
// position with the relation key and any list indices stripped. `$`
|
|
29
|
-
// when the link sits at the top of the document.
|
|
30
10
|
from: string
|
|
31
|
-
// The RELATION: the key the link hangs under, so a link inside a
|
|
32
|
-
// list (`dependsOn: [refer() & "$.a"]`) is an edge under `dependsOn`
|
|
33
|
-
// rather than under `0`. A rel()-minted link carries its predicate
|
|
34
|
-
// declared rather than inferred.
|
|
35
11
|
key: string
|
|
36
|
-
// The address, as the link spells it.
|
|
37
12
|
to: string
|
|
38
13
|
// Where the link is, as a `$.dotted.path`, so a report can point at
|
|
39
14
|
// it.
|
|
40
15
|
at: string
|
|
41
|
-
// Set when the link sits inside a `hide()`-marked subtree. The link
|
|
42
|
-
// is still checked and still an edge, but a figure that draws it
|
|
43
|
-
// DISCLOSES what the document hides, so the view extractors skip it
|
|
44
|
-
// and report it as `hidden_contribution`.
|
|
45
16
|
hidden?: true
|
|
46
17
|
}
|
|
47
18
|
|
|
48
19
|
export type Graph = {
|
|
49
20
|
edges: Edge[]
|
|
50
|
-
// The positions of links written under an UNRESOLVED DISJUNCTION.
|
|
51
|
-
// ADR-007: an unresolved disjunction is not a value, so a link
|
|
52
|
-
// beneath one of its arms is not a fact and is not an edge -- but it
|
|
53
|
-
// is not nothing either, and a figure that silently dropped it would
|
|
54
|
-
// be the failure the views exist to avoid. Absent when there are
|
|
55
|
-
// none, so a graph of a decided document is the shape it always was.
|
|
56
21
|
disjunct?: string[]
|
|
57
22
|
}
|
|
58
23
|
|
|
@@ -66,14 +31,6 @@ const formatPath = (path: string[]): string =>
|
|
|
66
31
|
const isIndex = (seg: string): boolean => /^[0-9]+$/.test(seg)
|
|
67
32
|
|
|
68
33
|
|
|
69
|
-
// The node a link starts at and the relation it hangs under, derived
|
|
70
|
-
// from the link's own position.
|
|
71
|
-
//
|
|
72
|
-
// A DECLARED predicate (rel()-minted) is authoritative: the link is cut
|
|
73
|
-
// at the key the rel() sat on, wherever that is on the way down, which
|
|
74
|
-
// is what makes a MAP-valued relation report the relation rather than
|
|
75
|
-
// the inner label. Without one the relation is INFERRED: strip the list
|
|
76
|
-
// indices, and the first real key above the link is it.
|
|
77
34
|
const cut = (
|
|
78
35
|
at: string[], relkey: string | undefined
|
|
79
36
|
): { from: string, key: string } => {
|
|
@@ -92,11 +49,6 @@ const cut = (
|
|
|
92
49
|
}
|
|
93
50
|
|
|
94
51
|
|
|
95
|
-
// The graph of an evaluated tree. Walks POSITIONS, not values: a
|
|
96
|
-
// reference or a spread can put one value object at several positions,
|
|
97
|
-
// and a walk guarded by object identity would find the first and miss
|
|
98
|
-
// every other place it is reached. The guard is therefore the ancestor
|
|
99
|
-
// chain — which is what a cycle actually is.
|
|
100
52
|
export function graphOf(root: Val): Graph {
|
|
101
53
|
const edges: Edge[] = []
|
|
102
54
|
const disjunct: string[] = []
|
|
@@ -136,11 +88,6 @@ export function graphOf(root: Val): Graph {
|
|
|
136
88
|
visit(node.held, path, ancestors, hidden, undecided)
|
|
137
89
|
}
|
|
138
90
|
|
|
139
|
-
// An unresolved conjunction (a link waiting on a peer that never
|
|
140
|
-
// came, a constraint still open) holds its terms at the SAME
|
|
141
|
-
// position; every link among them is written there, and is an
|
|
142
|
-
// edge. This is what a match-selected branch or a deferred refer()
|
|
143
|
-
// looks like after evaluation.
|
|
144
91
|
if (true === node.isConjunct && Array.isArray(node.peg)) {
|
|
145
92
|
ancestors.add(node)
|
|
146
93
|
for (const term of node.peg) {
|
|
@@ -149,10 +96,6 @@ export function graphOf(root: Val): Graph {
|
|
|
149
96
|
ancestors.delete(node)
|
|
150
97
|
}
|
|
151
98
|
|
|
152
|
-
// AN UNRESOLVED DISJUNCTION IS NOT A VALUE (ADR-007), so a link
|
|
153
|
-
// under one of its arms is not an edge. Its POSITION is collected
|
|
154
|
-
// instead, so a figure can report what the document leaves
|
|
155
|
-
// undecided rather than drawing it or dropping it in silence.
|
|
156
99
|
if (true === node.isDisjunct && Array.isArray(node.peg)) {
|
|
157
100
|
ancestors.add(node)
|
|
158
101
|
for (const arm of node.peg) {
|
|
@@ -172,10 +115,6 @@ export function graphOf(root: Val): Graph {
|
|
|
172
115
|
|
|
173
116
|
visit(root, [], new Set(), false, false)
|
|
174
117
|
|
|
175
|
-
// DETERMINISTIC by construction, not by luck: edges by the position
|
|
176
|
-
// they are written at, which is unique — one link, one place. That
|
|
177
|
-
// holds through a conjunction too: its terms share the position, and
|
|
178
|
-
// two links there would have had to unify into one.
|
|
179
118
|
edges.sort((a, b) => cmpCodePoint(a.at, b.at))
|
|
180
119
|
|
|
181
120
|
if (0 < disjunct.length) {
|
package/src/hcanon.ts
CHANGED
|
@@ -1,44 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// The HASH FORM (G6 phase 0, docs/capability-review/g6-distribution.md):
|
|
4
|
-
// exactly the unify-level canon with the additions that close its
|
|
5
|
-
// semantic gaps, so that two documents with the same hash form have the
|
|
6
|
-
// same meaning:
|
|
7
|
-
//
|
|
8
|
-
// - a CLOSED map or list renders wrapped: close({...}), close([...])
|
|
9
|
-
// (canon drops closedness);
|
|
10
|
-
// - the type/hide MARKS render as their builtin wrappers: type(x),
|
|
11
|
-
// hide(x) (canon drops marks).
|
|
12
|
-
//
|
|
13
|
-
// Both additions reuse existing parseable syntax, so the hash form
|
|
14
|
-
// remains valid Aontu source and round-trips:
|
|
15
|
-
// hcanon(unify(parse(hcanon(v)))) == hcanon(v) is a spec-suite property
|
|
16
|
-
// (test/spec/hcanon.tsv). User-facing canon is UNCHANGED — hcanon is a
|
|
17
|
-
// separate rendering.
|
|
18
|
-
//
|
|
19
|
-
// An ALIAS REFERENCE left standing in a spread template renders its
|
|
20
|
-
// EXPANSION through this same walk rather than through the reference's
|
|
21
|
-
// own canon, so a close() or a mark on the aliased value survives into
|
|
22
|
-
// the hash. Without that the wrappers above are absent exactly where
|
|
23
|
-
// the alias filter has already erased the declaration that carried
|
|
24
|
-
// them (BUGS.md §60).
|
|
25
|
-
//
|
|
26
|
-
// The marks PROPAGATE to every descendant at unification (walkMark), so
|
|
27
|
-
// a wrapper is emitted only where a mark STARTS: the walk carries the
|
|
28
|
-
// inherited marks down and a child whose mark the parent already
|
|
29
|
-
// carries renders bare. Without that, hide({a:1}) would render every
|
|
30
|
-
// leaf re-wrapped — still correct, never minimal, and not what the
|
|
31
|
-
// source said.
|
|
32
|
-
//
|
|
33
|
-
// canonHash (G6 phase 1) is the pin built on it:
|
|
34
|
-
// "aon1-" + base64url( SHA-256( UTF-8( hcanon(v) ) ) )
|
|
35
|
-
// (unpadded base64url, RFC 4648 section 5). The "aon1-" scheme id
|
|
36
|
-
// exists so a future semantically-stronger normal form is an upgrade,
|
|
37
|
-
// not a breakage. This is a CANONICAL-TEXT hash, not a semantic
|
|
38
|
-
// equivalence class: the failure direction is the safe one — a false
|
|
39
|
-
// "changed" forces a needless re-review; a false "unchanged" would need
|
|
40
|
-
// two hash forms with the same bytes and different meanings, which is
|
|
41
|
-
// exactly the gap the close/mark wrappers exist to shut.
|
|
42
3
|
|
|
43
4
|
import { createHash } from 'node:crypto'
|
|
44
5
|
|
|
@@ -53,15 +14,6 @@ type HMarks = {
|
|
|
53
14
|
}
|
|
54
15
|
|
|
55
16
|
|
|
56
|
-
// One node's rendering, carrying the marks the ANCESTORS already
|
|
57
|
-
// wrapped. Bags and junctions recurse structurally (their canon getters
|
|
58
|
-
// render children through plain canon, which would drop a nested
|
|
59
|
-
// close), and so does an expanded alias reference, for the reason its
|
|
60
|
-
// own arm gives. Everything else — scalars, kinds, funcs, constraints,
|
|
61
|
-
// and a reference with nothing to expand — delegates to its own canon,
|
|
62
|
-
// whose text is already in cross-port parity. The non-Val arm mirrors
|
|
63
|
-
// MapVal.canon's raw-peg fallback and is unreachable through an
|
|
64
|
-
// evaluated tree (direct-tested, ADR-002).
|
|
65
17
|
function render(v: any, inh: HMarks): string {
|
|
66
18
|
if (true !== v?.isVal) {
|
|
67
19
|
return String(v)
|
|
@@ -76,12 +28,6 @@ function render(v: any, inh: HMarks): string {
|
|
|
76
28
|
|
|
77
29
|
let s: string
|
|
78
30
|
if (true === v.isMap) {
|
|
79
|
-
// Alias declarations are dropped here for the same reason
|
|
80
|
-
// MapVal.canon drops them, and this is the surface where it counts:
|
|
81
|
-
// `aon1-` pins MEANING, so a document written with aliases and the
|
|
82
|
-
// same document written longhand must hash to one string. Two
|
|
83
|
-
// renderers, one rule -- hcanon is not canon and does not inherit
|
|
84
|
-
// the filter (docs/design/ALIASES.0.md §4).
|
|
85
31
|
const keys = Object.keys(v.peg)
|
|
86
32
|
.filter((k) => !v.aliasKeys.includes(k))
|
|
87
33
|
.sort(cmpCodePoint)
|
|
@@ -115,22 +61,6 @@ function render(v: any, inh: HMarks): string {
|
|
|
115
61
|
else if (true === v.isConjunct || true === v.isDisjunct) {
|
|
116
62
|
s = junctionText(v, true === v.isConjunct ? '&' : '|', inner)
|
|
117
63
|
}
|
|
118
|
-
// AN EXPANDED ALIAS REFERENCE IS RENDERED, NOT DELEGATED (BUGS.md
|
|
119
|
-
// §60). A reference standing after unification is one inside a
|
|
120
|
-
// spread template, and `RefVal.canon` answers with the EXPANSION's
|
|
121
|
-
// plain canon -- which drops exactly what this renderer exists to
|
|
122
|
-
// keep. The declaration carrying `close()` or a mark is erased by
|
|
123
|
-
// the alias filter above, so a `close()` lost here is lost from the
|
|
124
|
-
// hash entirely: `%A = close({n:string})` and `%A = {n:string}`,
|
|
125
|
-
// used as `box: [&: %A]`, hashed to ONE STRING while refusing and
|
|
126
|
-
// admitting `{n:"x",z:1}` respectively -- a change of meaning the
|
|
127
|
-
// pin reported as no change, in the unsafe direction. Recursing
|
|
128
|
-
// through `inner` is what makes the alias form and its longhand
|
|
129
|
-
// twin agree again, which is ALIASES.0.md §4's own requirement.
|
|
130
|
-
//
|
|
131
|
-
// A reference with NO expansion still spells its name: a plain
|
|
132
|
-
// `$.A` names a key the hash form still carries in full, and the
|
|
133
|
-
// knot of a recursive alias inside its own template never gets one.
|
|
134
64
|
else if (true === v.isRef && undefined !== v.expansion) {
|
|
135
65
|
s = render(v.expansion, inner)
|
|
136
66
|
}
|
|
@@ -160,14 +90,6 @@ function render(v: any, inh: HMarks): string {
|
|
|
160
90
|
}
|
|
161
91
|
|
|
162
92
|
|
|
163
|
-
// The JunctionVal.canon parenthesisation rule, kept: a member that is
|
|
164
|
-
// itself a junction with more than one term keeps its parens so the
|
|
165
|
-
// text reparses with the same structure (`(1|2)&3`, not the
|
|
166
|
-
// differently-parsing `1|2&3`). Post-unification junctions are
|
|
167
|
-
// flattened by norm, so no SOURCE reaches the wrapping arm -- it is
|
|
168
|
-
// pinned by direct tests over constructed Vals in both ports, because
|
|
169
|
-
// a hash form that could render ambiguously would be a pin that
|
|
170
|
-
// silently agrees with a document it should not.
|
|
171
93
|
function junctionText(v: any, sym: string, inner: HMarks): string {
|
|
172
94
|
return v.peg.map((m: any) =>
|
|
173
95
|
true === m?.isJunction && 1 < m.peg.length
|
|
@@ -185,10 +107,6 @@ export function hcanon(v: Val): string {
|
|
|
185
107
|
}
|
|
186
108
|
|
|
187
109
|
|
|
188
|
-
// The canon-hash pin. Scoped to the module evaluated STANDALONE: its
|
|
189
|
-
// own include closure resolved and unified at its own root, before any
|
|
190
|
-
// consumer context — which is what makes the pin transitive (an edit
|
|
191
|
-
// two includes deep changes the unified root, hence the hash).
|
|
192
110
|
export function canonHash(v: Val): string {
|
|
193
111
|
return 'aon1-' +
|
|
194
112
|
createHash('sha256').update(hcanon(v), 'utf8').digest('base64url')
|
package/src/helpdoc.ts
CHANGED
|
@@ -17,7 +17,7 @@ const HELPDOC: HelpTopic[] = [
|
|
|
17
17
|
"topic": "tasks",
|
|
18
18
|
"summary": "what do you want to do? — the verb for a job",
|
|
19
19
|
"source": "docs/skill/tasks.md",
|
|
20
|
-
"text": "# What do you want to do?\n\nThe verb for a job, found by the word you arrived with. aontu's own\nvocabulary is on the right; yours is probably on the left.\n\n## Start from a document that works\n\nNothing written yet? Do not invent the first document, edit one:\n\n```\naontu init # into the working directory\naontu init model/ # or into a named one\nsh check.sh # the four questions, on what was just written\n```\n\n`init` writes `model.aon` (an entity map constrained with `&:`),\n`data.aon` (an instance of it that holds) and `check.sh` (the four\nchecks to run after every edit). It never overwrites: if any\nof the three already stands there, it refuses and writes none of them.\n\n## Describe a domain\n\nAn **ontology**, a **schema**, a **data model**, a **contract** — in\naontu these are all one thing: a document. Write the entities as a\n**map keyed by name**, and say what every entry must satisfy with the\n`&:` template:\n\n```\nentity: {\n &: {\n table: string\n fields: { &: { type: string, required: *false | boolean } }\n }\n planet: { table: \"planets\", fields: { name: { type: \"string\" } } }\n moon: { table: \"moons\", fields: { name: { type: \"string\" } } }\n}\n```\n\n`&:` is the construct to reach for first, and the one most easily\nmissed. It meets **every** key of the map it sits in. A quoted `\"*\"`\nis not a wildcard — it is a key named `*`, and a schema written that\nway constrains nothing while still reporting `valid`.\n\nPrefer a named map to a list unless the order is a fact (a migration\nsequence, a rule table tried in order). A key is an address, a name\nother parts can refer to, and a diff that shows one insertion instead\nof every following element renumbered.\n\n## Check data against a model\n\n```\naontu vet model.aon data.aon\n```\n\nExit `0` valid, `1` a contradiction, `3` incomplete (nothing\ncontradicts, but the model is not yet satisfied), `4` the model does\nnot stand up on its own. `--format json` for the machine-readable\nreport, `--closed` to refuse keys the model does not declare,\n`--max-errors <n>` to cap the list.\n\n**Make the check prove it checked something.** A check that examined\nnothing answers exactly like one that passed:\n\n```\naontu vet --coverage model.aon data.aon # what did it examine?\naontu vet --strict-coverage model.aon data.aon # exit 1 if nothing\n```\n\n`--coverage` reports how many data leaves a declaration constrained,\nthe data paths none did, and the declarations no data met.\n`--strict-coverage` exits 1 when the answer is nothing. The usual\ncause is the `\"*\"` mistake above: reach for `&:`.\n\n## Check the model is coherent with itself\n\n```\naontu relations model.aon # declared entity edges: targets resolve, no cycles\naontu reaches planet moon model.aon # does one entity reach another, at any remove?\naontu trim --check model.aon # entries whose removal changes nothing\n```\n\n##
|
|
20
|
+
"text": "# What do you want to do?\n\nThe verb for a job, found by the word you arrived with. aontu's own\nvocabulary is on the right; yours is probably on the left.\n\n## Start from a document that works\n\nNothing written yet? Do not invent the first document, edit one:\n\n```\naontu init # into the working directory\naontu init model/ # or into a named one\nsh check.sh # the four questions, on what was just written\n```\n\n`init` writes `model.aon` (an entity map constrained with `&:`),\n`data.aon` (an instance of it that holds) and `check.sh` (the four\nchecks to run after every edit). It never overwrites: if any\nof the three already stands there, it refuses and writes none of them.\n\n## Describe a domain\n\nAn **ontology**, a **schema**, a **data model**, a **contract** — in\naontu these are all one thing: a document. Write the entities as a\n**map keyed by name**, and say what every entry must satisfy with the\n`&:` template:\n\n```\nentity: {\n &: {\n table: string\n fields: { &: { type: string, required: *false | boolean } }\n }\n planet: { table: \"planets\", fields: { name: { type: \"string\" } } }\n moon: { table: \"moons\", fields: { name: { type: \"string\" } } }\n}\n```\n\n`&:` is the construct to reach for first, and the one most easily\nmissed. It meets **every** key of the map it sits in. A quoted `\"*\"`\nis not a wildcard — it is a key named `*`, and a schema written that\nway constrains nothing while still reporting `valid`.\n\nPrefer a named map to a list unless the order is a fact (a migration\nsequence, a rule table tried in order). A key is an address, a name\nother parts can refer to, and a diff that shows one insertion instead\nof every following element renumbered.\n\n## Check data against a model\n\n```\naontu vet model.aon data.aon\n```\n\nExit `0` valid, `1` a contradiction, `3` incomplete (nothing\ncontradicts, but the model is not yet satisfied), `4` the model does\nnot stand up on its own. `--format json` for the machine-readable\nreport, `--closed` to refuse keys the model does not declare,\n`--max-errors <n>` to cap the list.\n\n**Make the check prove it checked something.** A check that examined\nnothing answers exactly like one that passed:\n\n```\naontu vet --coverage model.aon data.aon # what did it examine?\naontu vet --strict-coverage model.aon data.aon # exit 1 if nothing\n```\n\n`--coverage` reports how many data leaves a declaration constrained,\nthe data paths none did, and the declarations no data met.\n`--strict-coverage` exits 1 when the answer is nothing. The usual\ncause is the `\"*\"` mistake above: reach for `&:`.\n\n## Check the model is coherent with itself\n\n```\naontu relations model.aon # declared entity edges: targets resolve, no cycles\naontu reaches planet moon model.aon # does one entity reach another, at any remove?\naontu trim --check model.aon # entries whose removal changes nothing\n```\n\n## Generate code from a model, and hold it\n\n```\naontu get out gen.aon # the component tree: files, and the lines in them\naontu trace gen.aon # what rule wrote each line\n```\n\nA generator answers a **component tree** -- `file(name, [lines])` and\nits neighbours -- which a generator runtime writes to disk. Hand the\ntree to one and compare with what is committed: the model is the truth,\nthe code is the claim, and drift is a finding. `aontu trace` answers\nthe other direction: for a line of the output, the model node and the\nrule behind it.\n\n## Ask what a model says, and why\n\n```\naontu get $.entity.planet.table model.aon\naontu why $.entity.planet.table model.aon\naontu get $.entity --keys model.aon\naontu get $.entity --types model.aon\n```\n\n`why` names **every** contribution to a value, with the file and line\neach was written on. It is the first thing to run when a value is not\nwhat you expected, and the second thing to run when `vet` refuses.\n\n## Change a value without editing the file\n\n```\naontu set '$.entity.planet.table=planet_v2' --entry model.aon --overlay local.aon\n```\n\nThe change is checked before it is written; a change that contradicts\na pinned value is refused, and the file is left alone.\n\n## Gate a change to the model itself\n\n```\naontu subsume old.aon new.aon # does the general admit every specific?\naontu breaking --against git#HEAD~1 model.aon\naontu hash model.aon # a pin that survives reformatting\n```\n\n## Hand a model to another agent\n\n```\naontu agentsmd --write AGENTS.md model.aon\n```\n\nSplices a derived stanza — the pin, the root keys, the shape, and the\ncommands spelled with paths that exist — between two markers, and\nleaves the rest of the file alone. Re-run it in the commit that\nchanges the model.\n\n## When something refuses\n\nRead the code in the brackets, then look it up:\n\n```\naontu explain no_scalar_unify\n```\n\nEvery finding carries a `code`, a `class`, a `path` and the **two\nsites** that disagree — the value and the constraint it failed, each\nwith its file and line. The class says what kind of answer it is:\n`conflict` (two things cannot both hold), `incomplete` (nothing is\nwrong yet, something is missing), `parse`, `reference`, `budget`.\n\nFull index: [`error-codes.md`](error-codes.md). The language on one\npage: [`grammar-card.md`](grammar-card.md). The worked ladder from\nplain JSON upward: [`examples.md`](examples.md).\n"
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"topic": "language",
|
|
@@ -41,7 +41,7 @@ const HELPDOC: HelpTopic[] = [
|
|
|
41
41
|
"topic": "grammar",
|
|
42
42
|
"summary": "the published ABNF, for a parser or a constrained decoder",
|
|
43
43
|
"source": "grammar/aontu.abnf",
|
|
44
|
-
"text": "; Aontu --- published grammar (ABNF, RFC 5234 + RFC 7405).\n;\n; The same language as grammar/aontu.gbnf, rule for rule and name for\n; name, in the notation an RFC reader expects. The GBNF form is for a\n; constrained decoder; THIS form is for a person, and for the railroad\n; diagram in the language reference, which is generated from this file\n; (ts/scripts/figures.cjs).\n;\n; It covers the DOCUMENTED EMISSION SURFACE: what a model should be\n; allowed to write, which is a superset of JSON plus the operators,\n; constraints and marks the language's own canonical form emits. It is\n; CONSERVATIVE BY CONSTRUCTION --- it may accept less than the parser\n; does, never more. The same two deliberate exclusions the GBNF has:\n;\n; - `@\"...\"` includes. A generated document should describe values,\n; not reach for files.\n; - Unquoted keys and the other spellings the parser tolerates.\n; Canon quotes every key, and one spelling is what a grammar is\n; for.\n;\n; TWO NOTATION CHOICES worth stating, because both are load-bearing.\n;\n; EVERY LITERAL IS CASE-SENSITIVE, spelled `%s\"...\"` (RFC 7405). A\n; plain `\"...\"` is case-INSENSITIVE in RFC 5234, and Aontu is not:\n; `TRUE` is a bare word and `true` is a boolean. The reader in\n; ts/scripts/abnf.cjs refuses a bare quoted string rather than guess\n; which was meant.\n;\n; ALTERNATION IS ORDERED. RFC 5234's `/` is formally unordered, and\n; the consumers of this file (a PEG-style matcher here, a railroad\n; renderer) take the first branch that matches. Where one spelling is\n; a prefix of another the longer comes first --- `exact` before\n; `number`, `refer` before `rem` before `re`, `biginteger` before\n; `boolean` --- so the ordered reading and the unordered one accept\n; the same language. ts/test/grammar.test.ts holds this file to the\n; whole canon corpus of test/spec/*.tsv, which is what proves it.\n\nroot = ws value ws\n\n; No pipe. `|>` was parse-time sugar; it was removed, `x |> f(a)`\n; being written `f(x, a)`.\nvalue = disjunct\n\ndisjunct = conjunct *( ws %s\"|\" ws conjunct )\n\nconjunct = prefixed *( ws %s\"&\" ws prefixed )\n\n; A preference marks the alternative a generation picks.\nprefixed = %s\"*\" ws prefixed / sum\n\nsum = atom *( ws %s\"+\" ws atom )\n\natom = map\n / list\n / func\n / ref\n / kind\n / place\n / scalar\n / %s\"(\" ws value ws %s\")\"\n\nmap = %s\"{\" ws [ entry *( ws %s\",\" ws entry ) ws ] %s\"}\"\n\nentry = spread / pair\n\n; The template every key of the bag must also satisfy.\nspread = %s\"&\" ws %s\":\" ws value\n\npair = string ws [ %s\"?\" ] ws %s\":\" ws value\n\n; A list ELEMENT is a value, not a pair --- only the template is keyed.\nlist = %s\"[\" ws [ element *( ws %s\",\" ws element ) ws ] %s\"]\"\n\nelement = spread / value\n\n; The builtins, applied. The name set is closed on purpose: an unknown\n; function is a parse-time error in the engine, so a grammar that\n; allowed any name would over-approximate.\nfunc = name %s\"(\" ws [ value *( ws %s\",\" ws value ) ws ] %s\")\"\n\n; ORDER MATTERS where one name is a prefix of another: `refer` is\n; listed before `re`, and `rem` before `re` as well.\nname = %s\"above\" / %s\"acyclic\" / %s\"add\" / %s\"below\" / %s\"close\"\n / %s\"copy\" / %s\"deprecate\" / %s\"div\"\n / %s\"each\" / %s\"emit\" / %s\"esc\" / %s\"filter\" / %s\"greatest\"\n / %s\"hide\"\n / %s\"inverse\" / %s\"join\" / %s\"key\" / %s\"least\"\n / %s\"length\" / %s\"list\" / %s\"lower\" / %s\"map\" / %s\"match\"\n / %s\"max\" / %s\"min\" / %s\"mod\" / %s\"move\"\n / %s\"mul\" / %s\"must\"\n / %s\"neq\"\n / %s\"open\" / %s\"pack\" / %s\"path\" / %s\"pick\" / %s\"pref\"\n / %s\"refer\" / %s\"rel\" / %s\"rem\" / %s\"rep\" / %s\"re\" / %s\"split\"\n / %s\"super\"\n / %s\"sub\" / %s\"sum\"\n / %s\"type\"\n / %s\"unique\" / %s\"upper\" / %s\"usc\"\n\n; A path reference, absolute from the document root. At least one\n; segment: a bare `$` is an incomplete expression, not a reference.\n; A RELATIVE reference has no `$`: `.n` names a sibling, resolved\n; against the enclosing map rather than the document root. Canon emits\n; one wherever a spread template survives unresolved, so a grammar\n; without it cannot parse this engine's own output. No conflict with\n; `number`: a numeric literal always starts with a digit or `-`.\nref = %s\"$\" 1*( %s\".\" segment ) / 1*( %s\".\" segment )\n\n; No `-`: it is not a bare-text character (test/spec/op-chars.tsv pins\n; `a:6-2` as a parse error), so admitting it would over-approximate.\nsegment = 1*( ALPHA / DIGIT / %s\"_\" )\n\n; The placeholder: a hole a call is filled through. BARE only --- `\"_\"`\n; is an ordinary string, and a longer bare word containing it is\n; ordinary text.\nplace = %s\"_\"\n\n; `biginteger` before `bigdecimal` is not required (they differ at the\n; fourth character), but `biginteger` before `boolean` is: see the\n; ordered-alternation note above.\nkind = %s\"biginteger\" / %s\"bigdecimal\" / %s\"boolean\" / %s\"float\"\n / %s\"integer\" / %s\"number\" / %s\"string\" / %s\"top\" / %s\"nil\"\n\n; `exact` before `number`, or `0d5` would match `number` as the single\n; digit `0` and leave `d5` unconsumed.\nscalar = string / exact / number / %s\"true\" / %s\"false\" / %s\"null\"\n\nstring = DQUOTE *char DQUOTE\n\nchar = unescaped / %x5C escape\n\n; Every code point but the quote and the backslash, which is what the\n; GBNF's `[^\"\\\\]` says. Control characters included: canon writes them\n; escaped, and a grammar that refused them would refuse less than the\n; parser accepts in the one direction this file may not.\nunescaped = %x00-21 / %x23-5B / %x5D-10FFFF\n\nescape = DQUOTE / %x5C / %s\"/\" / %s\"b\" / %s\"f\" / %s\"n\" / %s\"r\"\n / %s\"t\" / %s\"u\" hex hex hex hex\n\nhex = DIGIT / %x41-46 / %x61-66\n\n; The exact leaves: arbitrary precision, spelled with the 0d marker.\nexact = [ %s\"-\" ] %s\"0d\" digits [ %s\".\" digits ] [ exponent ]\n\nnumber = [ %s\"-\" ] digits [ %s\".\" digits ] [ exponent ]\n\nexponent = ( %s\"e\" / %s\"E\" ) [ %s\"-\" / %s\"+\" ] digits\n\ndigits = 1*DIGIT\n\nws = *( %x20 / %x09 / %x0A / %x0D )\n\n; RFC 5234's core rules, written out so this file stands alone.\nALPHA = %x41-5A / %x61-7A\nDIGIT = %x30-39\nDQUOTE = %x22\n"
|
|
44
|
+
"text": "; Aontu --- published grammar (ABNF, RFC 5234 + RFC 7405).\n;\n; The same language as grammar/aontu.gbnf, rule for rule and name for\n; name, in the notation an RFC reader expects. The GBNF form is for a\n; constrained decoder; THIS form is for a person, and for the railroad\n; diagram in the language reference, which is generated from this file\n; (ts/scripts/figures.cjs).\n;\n; It covers the DOCUMENTED EMISSION SURFACE: what a model should be\n; allowed to write, which is a superset of JSON plus the operators,\n; constraints and marks the language's own canonical form emits. It is\n; CONSERVATIVE BY CONSTRUCTION --- it may accept less than the parser\n; does, never more. The same two deliberate exclusions the GBNF has:\n;\n; - `@\"...\"` includes. A generated document should describe values,\n; not reach for files.\n; - Unquoted keys and the other spellings the parser tolerates.\n; Canon quotes every key, and one spelling is what a grammar is\n; for.\n;\n; TWO NOTATION CHOICES worth stating, because both are load-bearing.\n;\n; EVERY LITERAL IS CASE-SENSITIVE, spelled `%s\"...\"` (RFC 7405). A\n; plain `\"...\"` is case-INSENSITIVE in RFC 5234, and Aontu is not:\n; `TRUE` is a bare word and `true` is a boolean. The reader in\n; ts/scripts/abnf.cjs refuses a bare quoted string rather than guess\n; which was meant.\n;\n; ALTERNATION IS ORDERED. RFC 5234's `/` is formally unordered, and\n; the consumers of this file (a PEG-style matcher here, a railroad\n; renderer) take the first branch that matches. Where one spelling is\n; a prefix of another the longer comes first --- `exact` before\n; `number`, `refer` before `rem` before `re`, `biginteger` before\n; `boolean` --- so the ordered reading and the unordered one accept\n; the same language. ts/test/grammar.test.ts holds this file to the\n; whole canon corpus of test/spec/*.tsv, which is what proves it.\n\nroot = ws value ws\n\n; No pipe. `|>` was parse-time sugar; it was removed, `x |> f(a)`\n; being written `f(x, a)`.\nvalue = disjunct\n\ndisjunct = conjunct *( ws %s\"|\" ws conjunct )\n\nconjunct = prefixed *( ws %s\"&\" ws prefixed )\n\n; A preference marks the alternative a generation picks.\nprefixed = %s\"*\" ws prefixed / sum\n\nsum = atom *( ws %s\"+\" ws atom )\n\natom = map\n / list\n / func\n / ref\n / kind\n / place\n / scalar\n / %s\"(\" ws value ws %s\")\"\n\nmap = %s\"{\" ws [ entry *( ws %s\",\" ws entry ) ws ] %s\"}\"\n\nentry = spread / pair\n\n; The template every key of the bag must also satisfy.\nspread = %s\"&\" ws %s\":\" ws value\n\npair = string ws [ %s\"?\" ] ws %s\":\" ws value\n\n; A list ELEMENT is a value, not a pair --- only the template is keyed.\nlist = %s\"[\" ws [ element *( ws %s\",\" ws element ) ws ] %s\"]\"\n\nelement = spread / value\n\n; The builtins, applied. The name set is closed on purpose: an unknown\n; function is a parse-time error in the engine, so a grammar that\n; allowed any name would over-approximate.\nfunc = name %s\"(\" ws [ value *( ws %s\",\" ws value ) ws ] %s\")\"\n\n; ORDER MATTERS where one name is a prefix of another: `refer` is\n; listed before `re`, and `rem` before `re` as well.\nname = %s\"abnf\" / %s\"above\" / %s\"acyclic\" / %s\"add\" / %s\"below\" / %s\"close\"\n / %s\"copyfiles\" / %s\"copy\" / %s\"deprecate\" / %s\"div\"\n / %s\"each\" / %s\"emit\" / %s\"esc\" / %s\"filter\" / %s\"greatest\"\n / %s\"hide\"\n / %s\"inverse\" / %s\"join\" / %s\"key\" / %s\"least\"\n / %s\"length\" / %s\"listitems\" / %s\"list\" / %s\"lower\" / %s\"map\" / %s\"match\"\n / %s\"maybe\" / %s\"max\" / %s\"min\" / %s\"mod\" / %s\"move\"\n / %s\"mul\" / %s\"must\"\n / %s\"neq\"\n / %s\"open\" / %s\"pack\" / %s\"parse\" / %s\"path\" / %s\"pick\" / %s\"pref\"\n / %s\"refer\" / %s\"rel\" / %s\"rem\" / %s\"rep\" / %s\"re\" / %s\"sort\" / %s\"split\"\n / %s\"super\"\n / %s\"content\" / %s\"file\" / %s\"folder\" / %s\"fragment\" / %s\"inject\"\n / %s\"line\" / %s\"nom\" / %s\"project\" / %s\"slot\" / %s\"translate\"\n / %s\"sub\" / %s\"sum\"\n / %s\"type\"\n / %s\"unique\" / %s\"upper\" / %s\"usc\"\n\n; A path reference, absolute from the document root. At least one\n; segment: a bare `$` is an incomplete expression, not a reference.\n; A RELATIVE reference has no `$`: `.n` names a sibling, resolved\n; against the enclosing map rather than the document root. Canon emits\n; one wherever a spread template survives unresolved, so a grammar\n; without it cannot parse this engine's own output. No conflict with\n; `number`: a numeric literal always starts with a digit or `-`.\nref = %s\"$\" 1*( %s\".\" segment ) / 1*( %s\".\" segment )\n\n; No `-`: it is not a bare-text character (test/spec/op-chars.tsv pins\n; `a:6-2` as a parse error), so admitting it would over-approximate.\nsegment = 1*( ALPHA / DIGIT / %s\"_\" )\n\n; The placeholder: a hole a call is filled through. BARE only --- `\"_\"`\n; is an ordinary string, and a longer bare word containing it is\n; ordinary text.\nplace = %s\"_\"\n\n; `biginteger` before `bigdecimal` is not required (they differ at the\n; fourth character), but `biginteger` before `boolean` is: see the\n; ordered-alternation note above.\nkind = %s\"biginteger\" / %s\"bigdecimal\" / %s\"boolean\" / %s\"float\"\n / %s\"integer\" / %s\"number\" / %s\"string\" / %s\"top\" / %s\"nil\"\n\n; `exact` before `number`, or `0d5` would match `number` as the single\n; digit `0` and leave `d5` unconsumed.\nscalar = string / exact / number / %s\"true\" / %s\"false\" / %s\"null\"\n\nstring = DQUOTE *char DQUOTE\n\nchar = unescaped / %x5C escape\n\n; Every code point but the quote and the backslash, which is what the\n; GBNF's `[^\"\\\\]` says. Control characters included: canon writes them\n; escaped, and a grammar that refused them would refuse less than the\n; parser accepts in the one direction this file may not.\nunescaped = %x00-21 / %x23-5B / %x5D-10FFFF\n\nescape = DQUOTE / %x5C / %s\"/\" / %s\"b\" / %s\"f\" / %s\"n\" / %s\"r\"\n / %s\"t\" / %s\"u\" hex hex hex hex\n\nhex = DIGIT / %x41-46 / %x61-66\n\n; The exact leaves: arbitrary precision, spelled with the 0d marker.\nexact = [ %s\"-\" ] %s\"0d\" digits [ %s\".\" digits ] [ exponent ]\n\nnumber = [ %s\"-\" ] digits [ %s\".\" digits ] [ exponent ]\n\nexponent = ( %s\"e\" / %s\"E\" ) [ %s\"-\" / %s\"+\" ] digits\n\ndigits = 1*DIGIT\n\nws = *( %x20 / %x09 / %x0A / %x0D )\n\n; RFC 5234's core rules, written out so this file stands alone.\nALPHA = %x41-5A / %x61-7A\nDIGIT = %x30-39\nDQUOTE = %x22\n"
|
|
45
45
|
}
|
|
46
46
|
]
|
|
47
47
|
|
package/src/hints.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Error code hints for Aontu unification errors.
|
|
5
|
-
*
|
|
6
|
-
* Each key is an error code that can be passed to makeNilErr.
|
|
7
|
-
* Each value is a human-readable explanation of what the error means.
|
|
8
|
-
*/
|
|
9
3
|
|
|
10
4
|
const hints: Record<string, string> = {
|
|
11
5
|
|
|
@@ -40,7 +34,6 @@ const hints: Record<string, string> = {
|
|
|
40
34
|
'when nothing else does.',
|
|
41
35
|
|
|
42
36
|
|
|
43
|
-
// TODO: extend errors to have details so we can name the key
|
|
44
37
|
mapval_required: 'This map value is required.',
|
|
45
38
|
|
|
46
39
|
mapval_no_gen:
|
|
@@ -108,6 +101,31 @@ const hints: Record<string, string> = {
|
|
|
108
101
|
' # with "tier";\n' +
|
|
109
102
|
' min(0) & must(integer,"whole") & 3 -> 3 # Bands compose.',
|
|
110
103
|
|
|
104
|
+
abnf_grammar:
|
|
105
|
+
'This ABNF grammar could not be compiled:\n' +
|
|
106
|
+
'{reason}\n' +
|
|
107
|
+
' \n' +
|
|
108
|
+
'abnf() takes RFC 5234 ABNF -- `=` and `/`, not `::=`. The\n' +
|
|
109
|
+
'compiler reports the first thing it could not read; a rule\n' +
|
|
110
|
+
'referenced but never defined is the usual cause, after a\n' +
|
|
111
|
+
'quantifier written the EBNF way.',
|
|
112
|
+
|
|
113
|
+
parse_arg:
|
|
114
|
+
'parse(grammar, text) takes two strings: a grammar, normally the\n' +
|
|
115
|
+
'answer of an abnf() call, and the text to parse.\n' +
|
|
116
|
+
' \n' +
|
|
117
|
+
'Examples:\n' +
|
|
118
|
+
' G: abnf("v = 1*DIGIT")\n' +
|
|
119
|
+
' a: parse($.G, "12") # the AST\n' +
|
|
120
|
+
' b: parse($.G, 12) # parse_arg: the text is not a string',
|
|
121
|
+
|
|
122
|
+
parse_failed:
|
|
123
|
+
'The text does not parse under this grammar:\n' +
|
|
124
|
+
'{reason}\n' +
|
|
125
|
+
' \n' +
|
|
126
|
+
'A failure to parse is a failure to unify, so the field is\n' +
|
|
127
|
+
'refused rather than set to a value meaning "no".',
|
|
128
|
+
|
|
111
129
|
constraint_pattern:
|
|
112
130
|
'This re() pattern is outside the supported subset. It uses\n' +
|
|
113
131
|
'{reason}.\n' +
|
|
@@ -176,8 +194,6 @@ const hints: Record<string, string> = {
|
|
|
176
194
|
bare_punct: 'A bare string holds letters, digits, `-` and `_`, and nothing else.\nThis one holds `{char}`, in `{text}`. Every other punctuation\ncharacter is either syntax or an error, never silently part of a\nstring: a value that needs one is written quoted, and a `>` or `<`\nthat was meant as a bound is written as min(x), max(x), above(x) or\nbelow(x).\n \nExamples:\n a: team-payments -> "team-payments" # `-` and `_` are text;\n a: 2026-09-05 -> "2026-09-05" # ... digits included;\n a: x=y -> nil # `=` is not;\n a: "x=y" -> "x=y" # ... so quote it;\n a: >10 -> nil # Not an operator: write above(10).',
|
|
177
195
|
|
|
178
196
|
|
|
179
|
-
|
|
180
|
-
|
|
181
197
|
recursion_unexpanded: 'A schema refers to itself here, and no data reached this position\nto expand it against. Guard the recursion -- an optional key\n(next?:) drops when nothing arrives, and a preferred alternative\n(*null | $.Node) generates -- or supply the data.\n \nExamples:\n Node: {v: integer, next?: $.Node}\n t: $.Node & {v: 1} -> {..} # next? drops;\n Node: {v: integer, next: $.Node}\n t: $.Node & {v: 1} -> nil # ... required refuses.',
|
|
182
198
|
recursion_budget: 'A recursive schema expanded past the evaluation depth budget\nwithout meeting concrete data. Expansion is driven by the data --\nfinite data always terminates -- so a chain this deep means two\ndefinitions feeding each other, or data deeper than the budget\n(docs/trust.md raises it deliberately).',
|
|
183
199
|
list_length: 'A literal list alternative in a disjunction admits only a list of\nits own length -- a spread (&:) makes it variadic. Outside a\ndisjunction two statements of one list still merge elementwise.\n \nExamples:\n x: [] | [&: integer]\n x: [1, 2] -> [1,2] # The variadic arm;\n x: [] -> [] # ... or exactly empty;\n y: [a] | [b]\n y: [a, extra] -> nil # ... a literal arm is its length.',
|
|
@@ -195,6 +211,9 @@ const hints: Record<string, string> = {
|
|
|
195
211
|
|
|
196
212
|
view_kind_unknown: 'The figure kind is not one the verb draws. The kinds are tree, matrix,\ngraph, layer, sets, layers, ladder and poset; the note lists them.',
|
|
197
213
|
|
|
214
|
+
// RETIRED with the `render` verb (ADR-038). Registered still,
|
|
215
|
+
// errcodes.tsv being append-only, so a code a released engine raised
|
|
216
|
+
// keeps its meaning.
|
|
198
217
|
render_path: 'A unit path is written below the output directory: relative, with no\n`..` segment, and no two units the same. Rename the unit.',
|
|
199
218
|
render_lang: 'A text escape carries verbatim syntax of ONE language, and it must be\nthe unit\'s: a text of another language in this unit would be written\nas if it were this one. Move it to a unit of its own language.',
|
|
200
219
|
render_profile: 'Only fragments and text escapes render without a lowering, under the\ntext profile. A record, enum, alias, const or func needs a profile\nwhose language has one (typescript, go): set the unit\'s lang, or\nwrite the declaration as a fragment.',
|
|
@@ -204,15 +223,6 @@ const hints: Record<string, string> = {
|
|
|
204
223
|
|
|
205
224
|
format_check: 'The formatted text is not the same document, so nothing was written.\nThis is a formatter defect: please report it, with the source.',
|
|
206
225
|
|
|
207
|
-
// THIS PORT NEVER RAISES decimal_syntax -- Go's construct.go does,
|
|
208
|
-
// and go/hints.go's header records that the CODE is Go-only. The
|
|
209
|
-
// TEXT is here anyway, verbatim, because since G11 phase 3 this
|
|
210
|
-
// table is a LOOKUP surface as well as a message source: the code is
|
|
211
|
-
// in the shared registry (test/spec/errcodes.tsv), so
|
|
212
|
-
// `aontu explain decimal_syntax` must answer the same in both ports
|
|
213
|
-
// or the agent that met the error under one binary learns nothing
|
|
214
|
-
// from the other. An entry for a code this port cannot raise is
|
|
215
|
-
// never read on an error path, only on that lookup.
|
|
216
226
|
decimal_syntax: 'This 0d literal is not a valid exact number.',
|
|
217
227
|
view_style_profile: 'Each profile has ONE way to carry the meaning of a figure\'s marks:\nSGR escapes for text, CSS classes for svg. Asking for the other one is\na usage error rather than a silent no-op. `none` works everywhere.',
|
|
218
228
|
view_style_unknown: 'The styles are none, ansi and css, plus `auto` at the command line,\nwhich the command resolves before the library runs: whether the\ndestination is a terminal is not something a library can see.',
|
|
@@ -345,6 +355,41 @@ const hints: Record<string, string> = {
|
|
|
345
355
|
' pick([{a:1},{b:2}], a) -> nil # ... the second does not;\n' +
|
|
346
356
|
' pick([[9],[8]], 0) -> [9,8] # A list child takes an index.',
|
|
347
357
|
|
|
358
|
+
sort_key:
|
|
359
|
+
'A child of this bag has no key `{key}` to order by. Ordering\n' +
|
|
360
|
+
'refuses rather than skipping, for the reason `pick` does: a\n' +
|
|
361
|
+
'shorter list orders a DIFFERENT set of records than the one the\n' +
|
|
362
|
+
'author named. Give every child the key, or filter the bag first.\n' +
|
|
363
|
+
' \n' +
|
|
364
|
+
'Examples:\n' +
|
|
365
|
+
' sort([{a:2},{a:1}], a) -> [{a:1},{a:2}] # Every child has it;\n' +
|
|
366
|
+
' sort([{a:1},{b:2}], a) -> nil # ... the second does not;\n' +
|
|
367
|
+
' sort([[9],[8]], 0) -> [[8],[9]] # A list child takes an index.',
|
|
368
|
+
|
|
369
|
+
sort_domain:
|
|
370
|
+
'This bag cannot be ordered: `{member}`. There are two orders and no\n' +
|
|
371
|
+
'third -- text by code point, numbers by the exact comparator -- so a\n' +
|
|
372
|
+
'bag that mixes them, or holds a boolean, a null or a container, has\n' +
|
|
373
|
+
'no order to be put in. Project a field that is all one kind, or\n' +
|
|
374
|
+
'filter the bag first.\n' +
|
|
375
|
+
' \n' +
|
|
376
|
+
'Examples:\n' +
|
|
377
|
+
' sort([3,1,2]) -> [1,2,3] # All numbers;\n' +
|
|
378
|
+
' sort([b,a]) -> ["a","b"] # ... or all text;\n' +
|
|
379
|
+
' sort([1,a]) -> nil # ... never both.',
|
|
380
|
+
|
|
381
|
+
sort_dir:
|
|
382
|
+
'A sort direction names no direction: `{dir}`. The third argument is\n' +
|
|
383
|
+
'`asc` or `desc`, and omitting it is `asc`. The second argument is\n' +
|
|
384
|
+
'the field to order by, so a keyless descending sort writes the\n' +
|
|
385
|
+
'empty projector: the member itself.\n' +
|
|
386
|
+
' \n' +
|
|
387
|
+
'Examples:\n' +
|
|
388
|
+
' sort($.rows, n) # Ascending by field `n`;\n' +
|
|
389
|
+
' sort($.rows, n, desc) # ... descending;\n' +
|
|
390
|
+
' sort($.tags) # The members themselves, ascending;\n' +
|
|
391
|
+
' sort($.tags, "", desc) # ... descending.',
|
|
392
|
+
|
|
348
393
|
join_member:
|
|
349
394
|
'A member of this bag is not text and never will be: `{member}`.\n' +
|
|
350
395
|
'`join` folds with `+` seeded with the empty string, and `+` with a\n' +
|
|
@@ -479,8 +524,6 @@ const hints: Record<string, string> = {
|
|
|
479
524
|
'empty': 'Empty disjunction. The disjunction has no valid alternatives.',
|
|
480
525
|
'empty-dist': 'Empty disjunction distribution. All alternatives in the disjunction are invalid.',
|
|
481
526
|
|
|
482
|
-
// ADR-011 R2: two DEFAULTS of equal rank that cannot agree. The
|
|
483
|
-
// fix is a rank, so the hint names it.
|
|
484
527
|
'pref_rank_clash': 'Two defaults of the same rank disagree.' +
|
|
485
528
|
' Rank one of them (`**x`) to say which is the weaker layer,' +
|
|
486
529
|
' or give them the same value.',
|
|
@@ -508,15 +551,6 @@ const hints: Record<string, string> = {
|
|
|
508
551
|
}
|
|
509
552
|
|
|
510
553
|
|
|
511
|
-
// codeClasses assigns every error code a CLASS: conflict | incomplete |
|
|
512
|
-
// reference | parse | budget | internal. The contract lives in
|
|
513
|
-
// test/spec/errcodes.tsv (mode `errcode`): the spec suite executes one
|
|
514
|
-
// row per code against this table and asserts SET EQUALITY between the
|
|
515
|
-
// file and these keys, in both implementations (go/hints.go mirrors
|
|
516
|
-
// this map exactly). Codes are append-only and never renamed; a class
|
|
517
|
-
// change is a breaking change. Class rulings (why decimal_budget and
|
|
518
|
-
// lossy_integer_literal are conflict, not budget; why unknown_function
|
|
519
|
-
// is reference) are documented in the tsv header.
|
|
520
554
|
const codeClasses: Record<string, string> = {
|
|
521
555
|
// parse -- the source text is malformed or unusable
|
|
522
556
|
parse: 'parse',
|
|
@@ -551,10 +585,6 @@ const codeClasses: Record<string, string> = {
|
|
|
551
585
|
patch_ambiguous: 'reference',
|
|
552
586
|
patch_span_mismatch: 'internal',
|
|
553
587
|
|
|
554
|
-
// G4 phase 2 -- the checked link: a string that is not a tree
|
|
555
|
-
// address (class `parse`, the text is wrong), and an address that
|
|
556
|
-
// names nothing in this evaluation (class `reference`, the same
|
|
557
|
-
// class as `no_path`, because it is the same kind of miss).
|
|
558
588
|
refer_address: 'parse',
|
|
559
589
|
rel_address: 'parse',
|
|
560
590
|
refer_unresolved: 'reference',
|
|
@@ -595,10 +625,6 @@ const codeClasses: Record<string, string> = {
|
|
|
595
625
|
// class as refer_address, because it is the same mistake.
|
|
596
626
|
path_address: 'parse',
|
|
597
627
|
|
|
598
|
-
// G8 phase 1 -- the generation combinators. All three are class
|
|
599
|
-
// `parse`: what is wrong is the CALL as written (data that is not a
|
|
600
|
-
// bag, a list element that is not a name), not any pair of values a
|
|
601
|
-
// meet brought together.
|
|
602
628
|
pack_data: 'parse',
|
|
603
629
|
pack_key: 'parse',
|
|
604
630
|
each_data: 'parse',
|
|
@@ -611,24 +637,12 @@ const codeClasses: Record<string, string> = {
|
|
|
611
637
|
filter_data: 'parse',
|
|
612
638
|
match_none: 'conflict',
|
|
613
639
|
|
|
614
|
-
// G9 phase 6 -- the string builtins. All five are class `parse`:
|
|
615
|
-
// what is wrong is the CALL as written -- a variant that names no
|
|
616
|
-
// convention, a pattern outside the subset, a substitution naming a
|
|
617
|
-
// group that does not exist, a separator that is neither string nor
|
|
618
|
-
// pattern. `usc_malformed` is the odd one and still `parse`: the
|
|
619
|
-
// TEXT the call was given has no inverse, which is a fact about the
|
|
620
|
-
// argument rather than about any meet.
|
|
621
640
|
esc_variant: 'parse',
|
|
622
641
|
usc_malformed: 'parse',
|
|
623
642
|
rep_pattern: 'parse',
|
|
624
643
|
rep_sub: 'parse',
|
|
625
644
|
split_sep: 'parse',
|
|
626
645
|
|
|
627
|
-
// G9 phase 6 -- apply-templates. The four shape codes are class
|
|
628
|
-
// `parse`: what is wrong is the CALL as written -- a selection with
|
|
629
|
-
// no children, a table that is not one, a rule missing a half.
|
|
630
|
-
// `emit_none` is class `conflict` for `match_none`'s reason: the
|
|
631
|
-
// node and every pattern written for it disagreed.
|
|
632
646
|
emit_data: 'parse',
|
|
633
647
|
emit_table: 'parse',
|
|
634
648
|
emit_template: 'parse',
|
|
@@ -636,19 +650,11 @@ const codeClasses: Record<string, string> = {
|
|
|
636
650
|
emit_none: 'conflict',
|
|
637
651
|
emit_ref: 'conflict',
|
|
638
652
|
|
|
639
|
-
// RENDER P6 -- `replace` on a template, and `form`. The two
|
|
640
|
-
// template checks are class `parse`: what is wrong is the TEMPLATE
|
|
641
|
-
// as written, before any node. `replace_value` is class `conflict`:
|
|
642
|
-
// the node's value and the body that wanted text disagreed.
|
|
643
|
-
// `form_data` is `each_data`'s retired twin (ADR-027).
|
|
644
653
|
replace_overlap: 'parse',
|
|
645
654
|
replace_unused: 'parse',
|
|
646
655
|
replace_value: 'conflict',
|
|
647
656
|
form_data: 'parse',
|
|
648
657
|
|
|
649
|
-
// G8 phase 3 -- the placeholder. Class `conflict`: two values met
|
|
650
|
-
// and neither could answer for the other, which is what every
|
|
651
|
-
// conflict is.
|
|
652
658
|
place_pair: 'conflict',
|
|
653
659
|
|
|
654
660
|
// G6 phase 2 -- modules. Both are class `parse`: a module import is
|
|
@@ -689,6 +695,9 @@ const codeClasses: Record<string, string> = {
|
|
|
689
695
|
constraint: 'conflict',
|
|
690
696
|
must: 'conflict',
|
|
691
697
|
constraint_pattern: 'conflict',
|
|
698
|
+
abnf_grammar: 'parse',
|
|
699
|
+
parse_arg: 'parse',
|
|
700
|
+
parse_failed: 'conflict',
|
|
692
701
|
scalar_value: 'conflict',
|
|
693
702
|
scalar_kind: 'conflict',
|
|
694
703
|
no_scalar_unify: 'conflict',
|
|
@@ -706,6 +715,9 @@ const codeClasses: Record<string, string> = {
|
|
|
706
715
|
exact_float_mix: 'conflict',
|
|
707
716
|
inexact_integer_sum: 'conflict',
|
|
708
717
|
pick_key: 'conflict',
|
|
718
|
+
sort_key: 'conflict',
|
|
719
|
+
sort_domain: 'conflict',
|
|
720
|
+
sort_dir: 'parse',
|
|
709
721
|
aggregate_data: 'conflict',
|
|
710
722
|
aggregate_empty: 'conflict',
|
|
711
723
|
join_member: 'conflict',
|