aontu 0.52.0 → 0.53.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 +88 -0
- package/bin/aontu-mcp.js +4 -0
- package/dist/agentsmd.d.ts +16 -0
- package/dist/agentsmd.js +107 -0
- package/dist/agentsmd.js.map +1 -0
- package/dist/aontu.d.ts +14 -3
- package/dist/aontu.js +145 -4
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +44 -1
- package/dist/cli.js +2401 -44
- package/dist/cli.js.map +1 -1
- package/dist/ctx.d.ts +16 -0
- package/dist/ctx.js +44 -0
- package/dist/ctx.js.map +1 -1
- package/dist/diff.d.ts +22 -0
- package/dist/diff.js +141 -0
- package/dist/diff.js.map +1 -0
- package/dist/err.d.ts +3 -1
- package/dist/err.js +48 -8
- package/dist/err.js.map +1 -1
- package/dist/graph.d.ts +16 -0
- package/dist/graph.js +73 -0
- package/dist/graph.js.map +1 -0
- package/dist/hcanon.d.ts +3 -0
- package/dist/hcanon.js +146 -0
- package/dist/hcanon.js.map +1 -0
- package/dist/hints.js +223 -5
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.d.ts +20 -0
- package/dist/jsonschema.js +391 -0
- package/dist/jsonschema.js.map +1 -0
- package/dist/lang.js +698 -35
- package/dist/lang.js.map +1 -1
- package/dist/lsp.d.ts +9 -2
- package/dist/lsp.js +262 -46
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.d.ts +20 -0
- package/dist/mcp-server.js +147 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp.d.ts +42 -0
- package/dist/mcp.js +814 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mod-tool.d.ts +58 -0
- package/dist/mod-tool.js +498 -0
- package/dist/mod-tool.js.map +1 -0
- package/dist/mod.d.ts +31 -0
- package/dist/mod.js +250 -0
- package/dist/mod.js.map +1 -0
- package/dist/patch.d.ts +44 -0
- package/dist/patch.js +506 -0
- package/dist/patch.js.map +1 -0
- package/dist/provenance.d.ts +40 -0
- package/dist/provenance.js +335 -0
- package/dist/provenance.js.map +1 -0
- package/dist/query.d.ts +27 -0
- package/dist/query.js +294 -0
- package/dist/query.js.map +1 -0
- package/dist/reach.d.ts +14 -0
- package/dist/reach.js +140 -0
- package/dist/reach.js.map +1 -0
- package/dist/relation.d.ts +19 -0
- package/dist/relation.js +305 -0
- package/dist/relation.js.map +1 -0
- package/dist/report-sarif.d.ts +14 -0
- package/dist/report-sarif.js +102 -0
- package/dist/report-sarif.js.map +1 -0
- package/dist/site.d.ts +4 -0
- package/dist/site.js +31 -0
- package/dist/site.js.map +1 -1
- package/dist/std.d.ts +1 -0
- package/dist/std.js +73 -0
- package/dist/std.js.map +1 -0
- package/dist/subsume.d.ts +39 -0
- package/dist/subsume.js +526 -0
- package/dist/subsume.js.map +1 -0
- package/dist/trim.d.ts +19 -0
- package/dist/trim.js +155 -0
- package/dist/trim.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.d.ts +17 -1
- package/dist/type.js.map +1 -1
- package/dist/unify.d.ts +3 -1
- package/dist/unify.js +287 -18
- package/dist/unify.js.map +1 -1
- package/dist/utility.d.ts +9 -1
- package/dist/utility.js +122 -1
- package/dist/utility.js.map +1 -1
- package/dist/val/AggFuncVal.d.ts +33 -0
- package/dist/val/AggFuncVal.js +202 -0
- package/dist/val/AggFuncVal.js.map +1 -0
- package/dist/val/ArithFuncVal.d.ts +31 -0
- package/dist/val/ArithFuncVal.js +62 -0
- package/dist/val/ArithFuncVal.js.map +1 -0
- package/dist/val/BagVal.d.ts +5 -0
- package/dist/val/BagVal.js +96 -5
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +9 -1
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.d.ts +1 -1
- package/dist/val/ConjunctVal.js +19 -0
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.d.ts +48 -1
- package/dist/val/ConstraintVal.js +1501 -110
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/CopyFuncVal.d.ts +1 -2
- package/dist/val/CopyFuncVal.js +7 -0
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.d.ts +1 -0
- package/dist/val/Decimal.js +13 -0
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DeprecateFuncVal.d.ts +11 -0
- package/dist/val/DeprecateFuncVal.js +47 -0
- package/dist/val/DeprecateFuncVal.js.map +1 -0
- package/dist/val/DisjunctVal.js +130 -21
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/EachFuncVal.d.ts +15 -0
- package/dist/val/EachFuncVal.js +75 -0
- package/dist/val/EachFuncVal.js.map +1 -0
- package/dist/val/ExpectVal.d.ts +1 -0
- package/dist/val/ExpectVal.js +41 -4
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FeatureVal.js +1 -1
- package/dist/val/FeatureVal.js.map +1 -1
- package/dist/val/FilterFuncVal.d.ts +15 -0
- package/dist/val/FilterFuncVal.js +91 -0
- package/dist/val/FilterFuncVal.js.map +1 -0
- package/dist/val/FuncBaseVal.d.ts +6 -1
- package/dist/val/FuncBaseVal.js +178 -2
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IdFuncVal.d.ts +13 -0
- package/dist/val/IdFuncVal.js +54 -0
- package/dist/val/IdFuncVal.js.map +1 -0
- package/dist/val/JunctionVal.js +7 -1
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.d.ts +1 -1
- package/dist/val/KeyFuncVal.js +38 -30
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +117 -17
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +102 -8
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MatchFuncVal.d.ts +15 -0
- package/dist/val/MatchFuncVal.js +107 -0
- package/dist/val/MatchFuncVal.js.map +1 -0
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.js +24 -0
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/OpBaseVal.d.ts +1 -1
- package/dist/val/OpBaseVal.js +24 -2
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/OpenFuncVal.js +4 -1
- package/dist/val/OpenFuncVal.js.map +1 -1
- package/dist/val/PackFuncVal.d.ts +15 -0
- package/dist/val/PackFuncVal.js +108 -0
- package/dist/val/PackFuncVal.js.map +1 -0
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PlaceVal.d.ts +13 -0
- package/dist/val/PlaceVal.js +131 -0
- package/dist/val/PlaceVal.js.map +1 -0
- package/dist/val/PlusOpVal.js +11 -2
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.d.ts +2 -2
- package/dist/val/PrefVal.js +78 -23
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RefVal.d.ts +1 -1
- package/dist/val/RefVal.js +158 -30
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.d.ts +36 -0
- package/dist/val/ReferFuncVal.js +303 -0
- package/dist/val/ReferFuncVal.js.map +1 -0
- package/dist/val/ScalarKindVal.d.ts +1 -2
- package/dist/val/ScalarKindVal.js +0 -11
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TypeFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +9 -2
- package/dist/val/Val.js +150 -4
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/arith.d.ts +6 -0
- package/dist/val/arith.js +170 -0
- package/dist/val/arith.js.map +1 -0
- package/dist/vet.d.ts +45 -0
- package/dist/vet.js +776 -0
- package/dist/vet.js.map +1 -0
- package/dist/walk.d.ts +2 -0
- package/dist/walk.js +91 -0
- package/dist/walk.js.map +1 -0
- package/grammar/aontu.gbnf +130 -0
- package/grammar/aontu.lark +113 -0
- package/package.json +30 -15
- package/skill/SKILL.md +37 -0
- package/skill/error-codes.md +62 -0
- package/skill/examples.md +99 -0
- package/skill/grammar-card.md +57 -0
- package/src/agentsmd.ts +135 -0
- package/src/aontu.ts +192 -4
- package/src/cli.ts +2858 -71
- package/src/ctx.ts +81 -0
- package/src/diff.ts +196 -0
- package/src/err.ts +52 -8
- package/src/graph.ts +135 -0
- package/src/hcanon.ts +169 -0
- package/src/hints.ts +271 -5
- package/src/jsonschema.ts +511 -0
- package/src/lang.ts +779 -37
- package/src/lsp.ts +281 -47
- package/src/mcp-server.ts +187 -0
- package/src/mcp.ts +993 -0
- package/src/mod-tool.ts +679 -0
- package/src/mod.ts +344 -0
- package/src/patch.ts +624 -0
- package/src/provenance.ts +430 -0
- package/src/query.ts +379 -0
- package/src/reach.ts +184 -0
- package/src/relation.ts +395 -0
- package/src/report-sarif.ts +137 -0
- package/src/site.ts +36 -1
- package/src/std.ts +73 -0
- package/src/subsume.ts +690 -0
- package/src/trim.ts +195 -0
- package/src/tsconfig.json +10 -4
- package/src/type.ts +51 -2
- package/src/unify.ts +311 -16
- package/src/utility.ts +139 -1
- package/src/val/AggFuncVal.ts +319 -0
- package/src/val/ArithFuncVal.ts +108 -0
- package/src/val/BagVal.ts +101 -4
- package/src/val/CloseFuncVal.ts +9 -1
- package/src/val/ConjunctVal.ts +20 -0
- package/src/val/ConstraintVal.ts +1699 -116
- package/src/val/CopyFuncVal.ts +7 -1
- package/src/val/Decimal.ts +15 -0
- package/src/val/DeprecateFuncVal.ts +84 -0
- package/src/val/DisjunctVal.ts +139 -28
- package/src/val/EachFuncVal.ts +133 -0
- package/src/val/ExpectVal.ts +43 -6
- package/src/val/FeatureVal.ts +1 -1
- package/src/val/FilterFuncVal.ts +154 -0
- package/src/val/FuncBaseVal.ts +200 -3
- package/src/val/HideFuncVal.ts +0 -2
- package/src/val/IdFuncVal.ts +91 -0
- package/src/val/JunctionVal.ts +7 -1
- package/src/val/KeyFuncVal.ts +39 -35
- package/src/val/ListVal.ts +125 -18
- package/src/val/LowerFuncVal.ts +0 -1
- package/src/val/MapVal.ts +110 -8
- package/src/val/MatchFuncVal.ts +176 -0
- package/src/val/MoveFuncVal.ts +0 -2
- package/src/val/NilVal.ts +25 -0
- package/src/val/OpBaseVal.ts +26 -3
- package/src/val/OpenFuncVal.ts +4 -2
- package/src/val/PackFuncVal.ts +175 -0
- package/src/val/PathFuncVal.ts +0 -1
- package/src/val/PlaceVal.ts +193 -0
- package/src/val/PlusOpVal.ts +11 -2
- package/src/val/PrefFuncVal.ts +0 -1
- package/src/val/PrefVal.ts +79 -36
- package/src/val/RefVal.ts +163 -30
- package/src/val/ReferFuncVal.ts +387 -0
- package/src/val/ScalarKindVal.ts +0 -13
- package/src/val/TopVal.ts +0 -1
- package/src/val/TypeFuncVal.ts +0 -2
- package/src/val/UpperFuncVal.ts +0 -1
- package/src/val/Val.ts +213 -3
- package/src/val/VarVal.ts +0 -1
- package/src/val/arith.ts +316 -0
- package/src/vet.ts +992 -0
- package/src/walk.ts +99 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/dist/reach.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { VetFinding } from './vet';
|
|
2
|
+
import type { TrustOptions } from './type';
|
|
3
|
+
export type ReachVerdict = 'reaches' | 'unreachable' | 'error';
|
|
4
|
+
export type ReachReport = {
|
|
5
|
+
verdict: ReachVerdict;
|
|
6
|
+
path?: string[];
|
|
7
|
+
errors?: VetFinding[];
|
|
8
|
+
};
|
|
9
|
+
export type ReachOptions = {
|
|
10
|
+
path?: string;
|
|
11
|
+
trust?: TrustOptions;
|
|
12
|
+
relation?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function reachCheck(src: string, from: string, to: string, opts?: ReachOptions): ReachReport;
|
package/dist/reach.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.reachCheck = reachCheck;
|
|
5
|
+
// REACHABILITY OVER THE ENTITY GRAPH (the review's finding J,
|
|
6
|
+
// use-cases/REVIEW.md): "ship a transitive `reaches(a, b)` check verb".
|
|
7
|
+
//
|
|
8
|
+
// `relations` answers questions about the edge set as a whole --- is it
|
|
9
|
+
// acyclic, does every edge have its inverse, is every far end what the
|
|
10
|
+
// relation says it is. This answers the question that needs the CLOSURE
|
|
11
|
+
// rather than the edges: does anything `a` depends on, at any remove,
|
|
12
|
+
// end up at `b`? That is the shape of every blast-radius question an
|
|
13
|
+
// operator asks ("if the billing database goes, what falls over?") and
|
|
14
|
+
// every containment question a policy asks ("nothing in the public tier
|
|
15
|
+
// may reach the ledger"), and neither can be expressed by looking one
|
|
16
|
+
// edge at a time.
|
|
17
|
+
//
|
|
18
|
+
// It is a VERB and not a constraint, for the same reason acyclicity is
|
|
19
|
+
// (docs/reference-language.md, "Declared relations"): reachability is
|
|
20
|
+
// global and non-monotone. One more edge can make an unreachable pair
|
|
21
|
+
// reachable, so a lattice citizen asserting non-reachability could be
|
|
22
|
+
// true and then false, and the lattice guarantee is that more
|
|
23
|
+
// information never falsifies what has already been observed.
|
|
24
|
+
//
|
|
25
|
+
// TRANSITIVE, NOT REFLEXIVE-TRANSITIVE: `reaches(a, a)` is true only
|
|
26
|
+
// when a path of one or more edges returns to `a`, which is the useful
|
|
27
|
+
// answer (it says the graph has a cycle through `a`) rather than the
|
|
28
|
+
// vacuous one.
|
|
29
|
+
//
|
|
30
|
+
// The Go twin is go/reach.go; what the two ports must agree on --- the
|
|
31
|
+
// verdict and the path --- is test/spec/reach.tsv.
|
|
32
|
+
const aontu_1 = require("./aontu");
|
|
33
|
+
const vet_1 = require("./vet");
|
|
34
|
+
const graph_1 = require("./graph");
|
|
35
|
+
const keyorder_1 = require("./keyorder");
|
|
36
|
+
// The entity an address names --- everything before the first dot. A
|
|
37
|
+
// link into `svc/auth.ports.http` reaches `svc/auth`: reachability is
|
|
38
|
+
// between ENTITIES, and the path inside one says which part of it the
|
|
39
|
+
// link arrives at. Same rule as relation.ts's entityOf, and it has to
|
|
40
|
+
// be, or the two verbs would disagree about what an edge connects.
|
|
41
|
+
function entityOf(addr) {
|
|
42
|
+
const dot = addr.indexOf('.');
|
|
43
|
+
return dot < 0 ? addr : addr.slice(0, dot);
|
|
44
|
+
}
|
|
45
|
+
function endpointFinding(name, known) {
|
|
46
|
+
return {
|
|
47
|
+
code: 'refer_unresolved',
|
|
48
|
+
class: 'reference',
|
|
49
|
+
severity: 'error',
|
|
50
|
+
path: '$',
|
|
51
|
+
// NOT "unreachable". An endpoint that names no entity is a
|
|
52
|
+
// question the document cannot answer, and answering it `no` would
|
|
53
|
+
// report a typo as a fact about the model --- the fail-open shape
|
|
54
|
+
// this review exists to retire.
|
|
55
|
+
message: `${name} names no entity in this document.`,
|
|
56
|
+
sites: [],
|
|
57
|
+
...(0 === known.length ? {} : {
|
|
58
|
+
note: 'known entities: ' + known.join(', '),
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// The reachability check for one document.
|
|
63
|
+
function reachCheck(src, from, to, opts) {
|
|
64
|
+
const options = opts ?? {};
|
|
65
|
+
const aontu = new aontu_1.Aontu(null == options.trust ? undefined : { trust: options.trust });
|
|
66
|
+
const ctx = aontu.ctx({ collect: true });
|
|
67
|
+
const parseOpts = null == options.path ? undefined : { path: options.path };
|
|
68
|
+
const root = aontu.unify(src, parseOpts, ctx);
|
|
69
|
+
// A document that does not stand up is not a document with an
|
|
70
|
+
// unreachable pair: the errors it already has are the answer.
|
|
71
|
+
if (0 < ctx.err.length || true === root?.isNil) {
|
|
72
|
+
return {
|
|
73
|
+
verdict: 'error',
|
|
74
|
+
errors: [(0, vet_1.failureFinding)(ctx, options.path, root)],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const graph = (0, graph_1.graphOf)(root);
|
|
78
|
+
const known = graph.entities.map((e) => e.id).sort(keyorder_1.cmpCodePoint);
|
|
79
|
+
const missing = [from, to].filter((n) => !known.includes(n));
|
|
80
|
+
if (0 < missing.length) {
|
|
81
|
+
return {
|
|
82
|
+
verdict: 'error',
|
|
83
|
+
errors: missing.map((n) => endpointFinding(n, known)),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// The successor map, restricted to one relation when the caller asked
|
|
87
|
+
// for one. Sorted, so the path the search finds is the same one in
|
|
88
|
+
// both ports.
|
|
89
|
+
const succ = new Map();
|
|
90
|
+
for (const e of graph.edges) {
|
|
91
|
+
if ('' === e.from ||
|
|
92
|
+
(null != options.relation && options.relation !== e.key)) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const list = succ.get(e.from);
|
|
96
|
+
const dest = entityOf(e.to);
|
|
97
|
+
if (undefined === list) {
|
|
98
|
+
succ.set(e.from, [dest]);
|
|
99
|
+
}
|
|
100
|
+
else if (!list.includes(dest)) {
|
|
101
|
+
list.push(dest);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
for (const list of succ.values()) {
|
|
105
|
+
list.sort(keyorder_1.cmpCodePoint);
|
|
106
|
+
}
|
|
107
|
+
// BREADTH-FIRST, so the path reported is a SHORTEST one --- the
|
|
108
|
+
// evidence an operator wants is the tightest chain, not whichever the
|
|
109
|
+
// walk happened to find first --- and, with the successors sorted, a
|
|
110
|
+
// determined one: among shortest paths, the first in code-point order
|
|
111
|
+
// at the first step that distinguishes them.
|
|
112
|
+
const prev = new Map();
|
|
113
|
+
const seen = new Set();
|
|
114
|
+
let front = [from];
|
|
115
|
+
while (0 < front.length) {
|
|
116
|
+
const next = [];
|
|
117
|
+
for (const node of front) {
|
|
118
|
+
for (const dest of succ.get(node) ?? []) {
|
|
119
|
+
if (dest === to) {
|
|
120
|
+
const path = [dest];
|
|
121
|
+
let step = node;
|
|
122
|
+
while (step !== from) {
|
|
123
|
+
path.unshift(step);
|
|
124
|
+
step = prev.get(step);
|
|
125
|
+
}
|
|
126
|
+
path.unshift(from);
|
|
127
|
+
return { verdict: 'reaches', path };
|
|
128
|
+
}
|
|
129
|
+
if (!seen.has(dest)) {
|
|
130
|
+
seen.add(dest);
|
|
131
|
+
prev.set(dest, node);
|
|
132
|
+
next.push(dest);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
front = next;
|
|
137
|
+
}
|
|
138
|
+
return { verdict: 'unreachable' };
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=reach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reach.js","sourceRoot":"","sources":["../src/reach.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { VetFinding } from './vet';
|
|
2
|
+
import type { TrustOptions } from './type';
|
|
3
|
+
export type RelationVerdict = 'pass' | 'fail' | 'error';
|
|
4
|
+
export type RelationFinding = {
|
|
5
|
+
code: string;
|
|
6
|
+
relation: string;
|
|
7
|
+
at: string;
|
|
8
|
+
detail: string[];
|
|
9
|
+
};
|
|
10
|
+
export type RelationReport = {
|
|
11
|
+
verdict: RelationVerdict;
|
|
12
|
+
findings: RelationFinding[];
|
|
13
|
+
errors?: VetFinding[];
|
|
14
|
+
};
|
|
15
|
+
export type RelationOptions = {
|
|
16
|
+
path?: string;
|
|
17
|
+
trust?: TrustOptions;
|
|
18
|
+
};
|
|
19
|
+
export declare function relationCheck(src: string, opts?: RelationOptions): RelationReport;
|
package/dist/relation.js
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.relationCheck = relationCheck;
|
|
5
|
+
// RELATION GRAPH CHECKS (G4 phase 5,
|
|
6
|
+
// docs/capability-review/g4-identity-relations.md): acyclicity and
|
|
7
|
+
// inverse consistency over the edge set, checked AFTER unification and
|
|
8
|
+
// never by it.
|
|
9
|
+
//
|
|
10
|
+
// Why not in the lattice. Both properties are GLOBAL and NON-MONOTONE:
|
|
11
|
+
// an acyclic graph becomes cyclic when one more edge unifies in, and an
|
|
12
|
+
// inverse that is present becomes absent when the far side is narrowed.
|
|
13
|
+
// The lattice guarantee is that more information never falsifies what
|
|
14
|
+
// has been observed, so a constraint that could be true and then false
|
|
15
|
+
// is not a constraint the lattice may hold. These are facts about the
|
|
16
|
+
// finished model, and the verb that reports facts about a finished
|
|
17
|
+
// model is where they belong.
|
|
18
|
+
//
|
|
19
|
+
// A relation is DECLARED as data, under the `relations` key of the
|
|
20
|
+
// document root, which is the `std/system` vocabulary's convention:
|
|
21
|
+
//
|
|
22
|
+
// relations: dependsOn: $.std.Relation & {
|
|
23
|
+
// target: $.std.Service, inverse: dependedOnBy, acyclic: true
|
|
24
|
+
// }
|
|
25
|
+
//
|
|
26
|
+
// Nothing in the engine knows the name `relations`; this pass does,
|
|
27
|
+
// and says so.
|
|
28
|
+
const aontu_1 = require("./aontu");
|
|
29
|
+
const vet_1 = require("./vet");
|
|
30
|
+
const graph_1 = require("./graph");
|
|
31
|
+
const keyorder_1 = require("./keyorder");
|
|
32
|
+
const unify_1 = require("./unify");
|
|
33
|
+
// The entity an address names — everything before the first dot. An
|
|
34
|
+
// edge into `svc/auth.ports.http` is an edge to `svc/auth`: a relation
|
|
35
|
+
// holds between ENTITIES, and the path inside one says which part of it
|
|
36
|
+
// the link reaches.
|
|
37
|
+
function entityOf(addr) {
|
|
38
|
+
const dot = addr.indexOf('.');
|
|
39
|
+
return dot < 0 ? addr : addr.slice(0, dot);
|
|
40
|
+
}
|
|
41
|
+
// The node an address names, or undefined. The entity's own position
|
|
42
|
+
// comes from the graph (a merged entity sits at every position that
|
|
43
|
+
// declared it, and they hold the same value, so the FIRST in the
|
|
44
|
+
// graph's sorted list is as good as any and is the same one in both
|
|
45
|
+
// ports); the rest of the address walks into it, exactly as the
|
|
46
|
+
// address's own grammar says.
|
|
47
|
+
// NO GUARD ON THE LOOKUP OR THE WALK. An edge exists only because
|
|
48
|
+
// `refer()` RESOLVED its full address, so `find` cannot miss and no
|
|
49
|
+
// segment can fall off: an address that does not walk is
|
|
50
|
+
// `refer_unresolved` at unification and the document never reaches the
|
|
51
|
+
// graph (probed for a missing key, a scalar mid-path and an
|
|
52
|
+
// out-of-range index, in both ports). An unreachable `if` is a branch
|
|
53
|
+
// arm the ADR-002 gate counts and no marker suppresses, so the Go twin
|
|
54
|
+
// keeps its guards — where a nil would PANIC rather than propagate,
|
|
55
|
+
// and where the marker mechanism can carry them — and this one relies
|
|
56
|
+
// on optional chaining instead.
|
|
57
|
+
function addressed(root, graph, addr) {
|
|
58
|
+
const dot = addr.indexOf('.');
|
|
59
|
+
const name = dot < 0 ? addr : addr.slice(0, dot);
|
|
60
|
+
const entry = graph.entities.find((e) => e.id === name);
|
|
61
|
+
const segs = entry.paths[0].slice(2).split('.')
|
|
62
|
+
.concat(dot < 0 ? [] : addr.slice(dot + 1).split('.'));
|
|
63
|
+
let node = root;
|
|
64
|
+
for (const seg of segs) {
|
|
65
|
+
node = node?.peg?.[seg];
|
|
66
|
+
}
|
|
67
|
+
return node;
|
|
68
|
+
}
|
|
69
|
+
// Does the far end satisfy the declared target? A TEST, never a flow:
|
|
70
|
+
// the check reports on a finished model and writing into it would be
|
|
71
|
+
// generation, which `relations` does not do (the same rule that keeps
|
|
72
|
+
// it from writing an author's inverse for them). So both sides are
|
|
73
|
+
// CLONED into a throwaway context and the meet is taken there; what
|
|
74
|
+
// the document holds is untouched either way.
|
|
75
|
+
//
|
|
76
|
+
// `refer(t)` is the other half of this and does flow, at the site. The
|
|
77
|
+
// two agree on what "satisfies" means -- a meet that is not a nil --
|
|
78
|
+
// which is what lets a relation declare once what every site would
|
|
79
|
+
// otherwise repeat.
|
|
80
|
+
// `root` is the DOCUMENT, not the node: a target lifted out of the
|
|
81
|
+
// model (`target: $.std.Service`) can still hold a reference that
|
|
82
|
+
// resolves against the document, and a probe rooted at the far end
|
|
83
|
+
// answers `no_path` for it -- which the worked example in
|
|
84
|
+
// test/spec/relation.tsv caught the moment this check existed.
|
|
85
|
+
function meets(aontu, root, node, target) {
|
|
86
|
+
const ctx = aontu.ctx({ collect: true });
|
|
87
|
+
ctx.root = root;
|
|
88
|
+
const out = (0, unify_1.unite)(ctx, node.clone(ctx), target.clone(ctx), 'relation-target');
|
|
89
|
+
if (true === out?.isNil) {
|
|
90
|
+
return out.why;
|
|
91
|
+
}
|
|
92
|
+
if (0 < ctx.err.length) {
|
|
93
|
+
return ctx.err[0].why;
|
|
94
|
+
}
|
|
95
|
+
// A MEET THAT LEAVES A HOLE IS NOT SATISFACTION. `target:
|
|
96
|
+
// {kind: service, port: integer}` against a far end with no `port`
|
|
97
|
+
// does not CONFLICT -- the meet simply carries `integer` into a key
|
|
98
|
+
// that had none -- and a check that stopped at "no conflict" would
|
|
99
|
+
// pass a far end that is missing half of what the relation demands.
|
|
100
|
+
//
|
|
101
|
+
// What `refer(t)` does at the site is the yardstick: it flows `t` in,
|
|
102
|
+
// and the document then fails to generate, because `integer` is not a
|
|
103
|
+
// value. So the same question is asked here -- can the far end still
|
|
104
|
+
// generate once the target is met? -- and the answer is compared with
|
|
105
|
+
// the far end ALONE, so a node that was already incomplete for its
|
|
106
|
+
// own reasons is not blamed on the relation that points at it.
|
|
107
|
+
// The REASON reported is the engine's own -- the code `refer(t)` at
|
|
108
|
+
// the site would have raised -- rather than a name invented here.
|
|
109
|
+
const probe = (v) => {
|
|
110
|
+
const gctx = aontu.ctx({ collect: true });
|
|
111
|
+
gctx.root = root;
|
|
112
|
+
v.gen(gctx);
|
|
113
|
+
return 0 === gctx.err.length ? undefined : gctx.err[0].why;
|
|
114
|
+
};
|
|
115
|
+
const alone = probe(node.clone(aontu.ctx({ collect: true })));
|
|
116
|
+
const met = probe(out);
|
|
117
|
+
return undefined === alone && undefined !== met ? met : undefined;
|
|
118
|
+
}
|
|
119
|
+
function declaredRelations(root) {
|
|
120
|
+
const rels = root?.peg?.relations;
|
|
121
|
+
if (true !== rels?.isMap) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
const out = [];
|
|
125
|
+
for (const name of Object.keys(rels.peg).sort(keyorder_1.cmpCodePoint)) {
|
|
126
|
+
const r = rels.peg[name];
|
|
127
|
+
if (true !== r?.isMap) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const inv = r.peg.inverse;
|
|
131
|
+
const acy = r.peg.acyclic;
|
|
132
|
+
const tgt = r.peg.target;
|
|
133
|
+
out.push({
|
|
134
|
+
name,
|
|
135
|
+
inverse: true === inv?.isScalar && 'string' === typeof inv.peg
|
|
136
|
+
? inv.peg : undefined,
|
|
137
|
+
acyclic: true === acy?.isScalar && true === acy.peg,
|
|
138
|
+
target: true === tgt?.isVal && true !== tgt.isTop ? tgt : undefined,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
// The first cycle reachable from `start`, as the entities it runs
|
|
144
|
+
// through, or undefined. Depth-first with the path as the stack, and
|
|
145
|
+
// the successors visited in sorted order, so the cycle a report names
|
|
146
|
+
// is the same one in both ports.
|
|
147
|
+
function findCycle(start, succ, done) {
|
|
148
|
+
const stack = [];
|
|
149
|
+
const onStack = new Set();
|
|
150
|
+
const walk = (node) => {
|
|
151
|
+
if (onStack.has(node)) {
|
|
152
|
+
return [...stack.slice(stack.indexOf(node)), node];
|
|
153
|
+
}
|
|
154
|
+
if (done.has(node)) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
done.add(node);
|
|
158
|
+
stack.push(node);
|
|
159
|
+
onStack.add(node);
|
|
160
|
+
for (const next of succ.get(node) ?? []) {
|
|
161
|
+
const found = walk(next);
|
|
162
|
+
if (undefined !== found) {
|
|
163
|
+
return found;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
stack.pop();
|
|
167
|
+
onStack.delete(node);
|
|
168
|
+
return undefined;
|
|
169
|
+
};
|
|
170
|
+
return walk(start);
|
|
171
|
+
}
|
|
172
|
+
// The relation checks for one document.
|
|
173
|
+
function relationCheck(src, opts) {
|
|
174
|
+
const options = opts ?? {};
|
|
175
|
+
const aontu = new aontu_1.Aontu(null == options.trust ? undefined : { trust: options.trust });
|
|
176
|
+
const ctx = aontu.ctx({ collect: true });
|
|
177
|
+
const parseOpts = null == options.path ? undefined : { path: options.path };
|
|
178
|
+
const root = aontu.unify(src, parseOpts, ctx);
|
|
179
|
+
// A document that does not stand up is not a document with a bad
|
|
180
|
+
// graph: the errors it already has are the answer, and blaming its
|
|
181
|
+
// relations on top would be noise.
|
|
182
|
+
if (0 < ctx.err.length || true === root?.isNil) {
|
|
183
|
+
return {
|
|
184
|
+
verdict: 'error',
|
|
185
|
+
findings: [],
|
|
186
|
+
errors: [(0, vet_1.failureFinding)(ctx, options.path, root)],
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const declared = declaredRelations(root);
|
|
190
|
+
if (0 === declared.length) {
|
|
191
|
+
return { verdict: 'pass', findings: [] };
|
|
192
|
+
}
|
|
193
|
+
const graph = (0, graph_1.graphOf)(root);
|
|
194
|
+
const edges = graph.edges;
|
|
195
|
+
const findings = [];
|
|
196
|
+
// The edge set, indexed the two ways the checks read it.
|
|
197
|
+
const byRelation = new Map();
|
|
198
|
+
const pairs = new Set();
|
|
199
|
+
for (const e of edges) {
|
|
200
|
+
if ('' === e.from) {
|
|
201
|
+
// An edge outside every entity has no source to be a relation OF.
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const list = byRelation.get(e.key);
|
|
205
|
+
if (undefined === list) {
|
|
206
|
+
byRelation.set(e.key, [e]);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
list.push(e);
|
|
210
|
+
}
|
|
211
|
+
pairs.add(e.key + ' ' + e.from + ' ' + entityOf(e.to));
|
|
212
|
+
}
|
|
213
|
+
for (const rel of declared) {
|
|
214
|
+
const mine = byRelation.get(rel.name) ?? [];
|
|
215
|
+
if (rel.acyclic) {
|
|
216
|
+
const succ = new Map();
|
|
217
|
+
for (const e of mine) {
|
|
218
|
+
const list = succ.get(e.from);
|
|
219
|
+
const to = entityOf(e.to);
|
|
220
|
+
if (undefined === list) {
|
|
221
|
+
succ.set(e.from, [to]);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
list.push(to);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
for (const list of succ.values()) {
|
|
228
|
+
list.sort(keyorder_1.cmpCodePoint);
|
|
229
|
+
}
|
|
230
|
+
// The roots are visited in sorted order, and a node already
|
|
231
|
+
// settled is not revisited, so one cycle is reported once and the
|
|
232
|
+
// SAME one in both ports.
|
|
233
|
+
const done = new Set();
|
|
234
|
+
const roots = [...succ.keys()].sort(keyorder_1.cmpCodePoint);
|
|
235
|
+
for (const from of roots) {
|
|
236
|
+
const cycle = findCycle(from, succ, done);
|
|
237
|
+
if (undefined !== cycle) {
|
|
238
|
+
// The cycle's first node is a key of `succ`, and every key of
|
|
239
|
+
// `succ` came from an edge's `from`, so the edge is there.
|
|
240
|
+
const at = mine.find((e) => e.from === cycle[0]);
|
|
241
|
+
findings.push({
|
|
242
|
+
code: 'relation_cycle',
|
|
243
|
+
relation: rel.name,
|
|
244
|
+
at: at.at,
|
|
245
|
+
detail: cycle,
|
|
246
|
+
});
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// TARGET: the far end IS what the relation says it is (the review's
|
|
252
|
+
// finding J). The declaration used to be inert -- `target` was read
|
|
253
|
+
// by nothing, on the reasoning that `refer(t)` already flows the
|
|
254
|
+
// type in at the site. It does, and that is exactly why the
|
|
255
|
+
// declaration was worth nothing: the site has to REPEAT it, and the
|
|
256
|
+
// idiom that avoids repeating it (`refer($.std.Service)`) tripped
|
|
257
|
+
// the fixpoint until §19 was fixed, so every real model wrote bare
|
|
258
|
+
// `refer()` and a typed-endpoint declaration checked nothing.
|
|
259
|
+
//
|
|
260
|
+
// Reported per EDGE, not per entity: an entity reached by two
|
|
261
|
+
// relations must satisfy both, and the report points at the link
|
|
262
|
+
// that made the demand.
|
|
263
|
+
if (undefined !== rel.target) {
|
|
264
|
+
for (const e of mine) {
|
|
265
|
+
// No guard on the node either, and for the same reason
|
|
266
|
+
// `addressed` needs none: an unresolved link is a nil in the
|
|
267
|
+
// tree, so this document would not have reached the graph.
|
|
268
|
+
const why = meets(aontu, root, addressed(root, graph, e.to), rel.target);
|
|
269
|
+
if (undefined !== why) {
|
|
270
|
+
findings.push({
|
|
271
|
+
code: 'relation_target_unmet',
|
|
272
|
+
relation: rel.name,
|
|
273
|
+
at: e.at,
|
|
274
|
+
detail: [e.from, e.to, why],
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (undefined !== rel.inverse) {
|
|
280
|
+
for (const e of mine) {
|
|
281
|
+
const to = entityOf(e.to);
|
|
282
|
+
if (!pairs.has(rel.inverse + ' ' + to + ' ' + e.from)) {
|
|
283
|
+
findings.push({
|
|
284
|
+
code: 'relation_inverse_missing',
|
|
285
|
+
relation: rel.name,
|
|
286
|
+
at: e.at,
|
|
287
|
+
detail: [e.from, to, rel.inverse],
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// SORTED, because a report is read by a machine that diffs it: by the
|
|
294
|
+
// position the offending edge is written at, then by code. No third
|
|
295
|
+
// key: one edge sits under one key and one key is one relation, so
|
|
296
|
+
// two findings can share (at, code) only by being the same finding.
|
|
297
|
+
// The sort is STABLE, and the relations were iterated in sorted
|
|
298
|
+
// order, so what order remains is fixed anyway.
|
|
299
|
+
findings.sort((a, b) => (0, keyorder_1.cmpCodePoint)(a.at, b.at) || (0, keyorder_1.cmpCodePoint)(a.code, b.code));
|
|
300
|
+
return {
|
|
301
|
+
verdict: 0 === findings.length ? 'pass' : 'fail',
|
|
302
|
+
findings,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=relation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation.js","sourceRoot":"","sources":["../src/relation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { VetReport } from './vet';
|
|
2
|
+
/**
|
|
3
|
+
* Render a vet report as SARIF 2.1.0 text (a minimal profile: one run,
|
|
4
|
+
* one result per finding, the finding embedded in `properties`).
|
|
5
|
+
*
|
|
6
|
+
* @param report A report from `vet()`.
|
|
7
|
+
* @param version The producer version for `tool.driver.version` —
|
|
8
|
+
* the CLI passes its package version; the two ports'
|
|
9
|
+
* version series are independent by design.
|
|
10
|
+
* @returns The SARIF JSON text, indented two spaces, keys in
|
|
11
|
+
* the canonical emitter's sorted order.
|
|
12
|
+
*/
|
|
13
|
+
declare function sarifReport(report: VetReport, version: string): string;
|
|
14
|
+
export { sarifReport, };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.sarifReport = sarifReport;
|
|
5
|
+
const exactjson_1 = require("./exactjson");
|
|
6
|
+
// SARIF levels are error/warning/note; the report's severities are
|
|
7
|
+
// error/warning/info. Only `info` needs translating, but the map spells
|
|
8
|
+
// out all three so a new severity fails loudly here rather than
|
|
9
|
+
// silently emitting itself.
|
|
10
|
+
const SARIF_LEVEL = {
|
|
11
|
+
error: 'error',
|
|
12
|
+
warning: 'warning',
|
|
13
|
+
info: 'note',
|
|
14
|
+
};
|
|
15
|
+
// A site's file is a filesystem path, and a SARIF artifactLocation.uri
|
|
16
|
+
// is a URI reference: `#`, `%`, spaces and every other URI-significant
|
|
17
|
+
// character must be percent-encoded or a consumer parses the path as
|
|
18
|
+
// something else (text after `#` becomes a fragment). Encoded BY BYTE
|
|
19
|
+
// over UTF-8, with RFC 3986's unreserved and path characters kept
|
|
20
|
+
// literal, so the Go twin produces identical bytes from an identical
|
|
21
|
+
// loop (go/report_sarif.go sarifURI).
|
|
22
|
+
function sarifUri(path) {
|
|
23
|
+
const bytes = Buffer.from(path, 'utf8');
|
|
24
|
+
let out = '';
|
|
25
|
+
for (const b of bytes) {
|
|
26
|
+
const c = String.fromCharCode(b);
|
|
27
|
+
if (b < 128 && /[A-Za-z0-9\-._~/!$&'()*+,;=:@]/.test(c)) {
|
|
28
|
+
out += c;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
out += '%' + b.toString(16).toUpperCase().padStart(2, '0');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function sarifLocation(site) {
|
|
37
|
+
const physical = {
|
|
38
|
+
artifactLocation: { uri: sarifUri(site.file) },
|
|
39
|
+
};
|
|
40
|
+
// SARIF regions are 1-based. A finding with no position — a parse
|
|
41
|
+
// failure reports at -1:-1 — gets a location with no region rather
|
|
42
|
+
// than an invented one.
|
|
43
|
+
if (1 <= site.row) {
|
|
44
|
+
physical.region = { startColumn: site.col, startLine: site.row };
|
|
45
|
+
}
|
|
46
|
+
return { physicalLocation: physical };
|
|
47
|
+
}
|
|
48
|
+
function sarifResult(finding) {
|
|
49
|
+
// The engine orders sites data-first (the thing to fix), so the first
|
|
50
|
+
// site is the primary location and the rest are related — which for a
|
|
51
|
+
// two-site conflict puts the schema's declaration under
|
|
52
|
+
// `relatedLocations`, exactly where a code-scanning UI shows "the
|
|
53
|
+
// other side".
|
|
54
|
+
const result = {
|
|
55
|
+
level: SARIF_LEVEL[finding.severity],
|
|
56
|
+
locations: [sarifLocation(finding.sites[0])],
|
|
57
|
+
message: { text: finding.message },
|
|
58
|
+
properties: finding,
|
|
59
|
+
ruleId: 'aontu/' + finding.code,
|
|
60
|
+
};
|
|
61
|
+
const related = finding.sites.slice(1);
|
|
62
|
+
if (0 < related.length) {
|
|
63
|
+
result.relatedLocations = related.map(sarifLocation);
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Render a vet report as SARIF 2.1.0 text (a minimal profile: one run,
|
|
69
|
+
* one result per finding, the finding embedded in `properties`).
|
|
70
|
+
*
|
|
71
|
+
* @param report A report from `vet()`.
|
|
72
|
+
* @param version The producer version for `tool.driver.version` —
|
|
73
|
+
* the CLI passes its package version; the two ports'
|
|
74
|
+
* version series are independent by design.
|
|
75
|
+
* @returns The SARIF JSON text, indented two spaces, keys in
|
|
76
|
+
* the canonical emitter's sorted order.
|
|
77
|
+
*/
|
|
78
|
+
function sarifReport(report, version) {
|
|
79
|
+
return (0, exactjson_1.exactJSON)({
|
|
80
|
+
$schema: 'https://json.schemastore.org/sarif-2.1.0.json',
|
|
81
|
+
runs: [{
|
|
82
|
+
// An `error` verdict means the run could not be set up (an
|
|
83
|
+
// unusable schema): zero findings from a FAILED run must not
|
|
84
|
+
// read like zero findings from a clean one, so the failure is
|
|
85
|
+
// carried in SARIF's own invocation metadata rather than by an
|
|
86
|
+
// indistinguishable empty result list.
|
|
87
|
+
invocations: [{
|
|
88
|
+
executionSuccessful: 'error' !== report.verdict,
|
|
89
|
+
}],
|
|
90
|
+
results: report.findings.map(sarifResult),
|
|
91
|
+
tool: {
|
|
92
|
+
driver: {
|
|
93
|
+
informationUri: 'https://github.com/rjrodger/aontu',
|
|
94
|
+
name: 'aontu',
|
|
95
|
+
version,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}],
|
|
99
|
+
version: '2.1.0',
|
|
100
|
+
}, 2);
|
|
101
|
+
} /* node:coverage ignore next 6 */
|
|
102
|
+
//# sourceMappingURL=report-sarif.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-sarif.js","sourceRoot":"","sources":["../src/report-sarif.ts"],"names":[],"mappings":"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"}
|