@anatomytool/validate 1.0.0 → 1.1.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 +13 -12
- package/dist/checks/commands-no-test-warn.d.ts.map +1 -1
- package/dist/checks/commands-no-test-warn.js +18 -1
- package/dist/checks/commands-no-test-warn.js.map +1 -1
- package/dist/checks/verify/ast-grep-verifier.d.ts.map +1 -1
- package/dist/checks/verify/ast-grep-verifier.js +4 -15
- package/dist/checks/verify/ast-grep-verifier.js.map +1 -1
- package/dist/checks/verify/glob-source.d.ts +6 -0
- package/dist/checks/verify/glob-source.d.ts.map +1 -0
- package/dist/checks/verify/glob-source.js +28 -0
- package/dist/checks/verify/glob-source.js.map +1 -0
- package/dist/checks/verify/semgrep-pattern-verifier.d.ts.map +1 -1
- package/dist/checks/verify/semgrep-pattern-verifier.js +3 -13
- package/dist/checks/verify/semgrep-pattern-verifier.js.map +1 -1
- package/dist/checks/verify/semgrep-rule-file-verifier.d.ts.map +1 -1
- package/dist/checks/verify/semgrep-rule-file-verifier.js +3 -12
- package/dist/checks/verify/semgrep-rule-file-verifier.js.map +1 -1
- package/dist/checks/verify-check.d.ts.map +1 -1
- package/dist/checks/verify-check.js +77 -45
- package/dist/checks/verify-check.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/schema-1.1.json +349 -0
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +5 -3
- package/dist/schema.js.map +1 -1
- package/dist/types.generated.d.ts +5 -3
- package/dist/types.generated.d.ts.map +1 -1
- package/dist/types.generated.js +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# `@
|
|
1
|
+
# `@anatomytool/validate`
|
|
2
2
|
|
|
3
|
-
TypeScript validator for `.anatomy` and `.anatomy-memory` files. Routes by declared wire version (v0.1, v0.2, v0.4
|
|
3
|
+
TypeScript validator for `.anatomy` and `.anatomy-memory` files. Routes by declared wire version (v0.1, v0.2, v0.4–v0.15, and v1.0) and supports v0.3 cascading semantics for repos with multiple `.anatomy` files.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @
|
|
8
|
+
npm install @anatomytool/validate
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Requires Node.js ≥ 22.
|
|
@@ -15,7 +15,7 @@ Requires Node.js ≥ 22.
|
|
|
15
15
|
### Single file
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
import { validate } from "@
|
|
18
|
+
import { validate } from "@anatomytool/validate";
|
|
19
19
|
import { readFileSync } from "node:fs";
|
|
20
20
|
|
|
21
21
|
const text = readFileSync(".anatomy", "utf8");
|
|
@@ -32,7 +32,7 @@ if (result.ok) {
|
|
|
32
32
|
### Cascading tree
|
|
33
33
|
|
|
34
34
|
```typescript
|
|
35
|
-
import { validateTree } from "@
|
|
35
|
+
import { validateTree } from "@anatomytool/validate";
|
|
36
36
|
|
|
37
37
|
const tree = validateTree(repoRoot);
|
|
38
38
|
// tree.results: Map<path, ValidateResult>
|
|
@@ -42,7 +42,7 @@ const tree = validateTree(repoRoot);
|
|
|
42
42
|
### Memory file
|
|
43
43
|
|
|
44
44
|
```typescript
|
|
45
|
-
import { validateMemory } from "@
|
|
45
|
+
import { validateMemory } from "@anatomytool/validate";
|
|
46
46
|
|
|
47
47
|
const result = validateMemory(memoryText, {
|
|
48
48
|
anatomyFingerprint: parsedAnatomy.identity.fingerprint,
|
|
@@ -55,12 +55,12 @@ const result = validateMemory(memoryText, {
|
|
|
55
55
|
### `.anatomy` (single file)
|
|
56
56
|
|
|
57
57
|
- **TOML syntax** — parse error → `toml-parse` error.
|
|
58
|
-
- **Schema conformance** — version-routed against `spec/{0.1, 0.2, 0.4
|
|
58
|
+
- **Schema conformance** — version-routed against `spec/{0.1, 0.2, 0.4–0.15, 1.0}/schema.json`. Unknown `anatomy_version` → `unsupported-anatomy-version`.
|
|
59
59
|
- **Identity integrity** — version-aware:
|
|
60
|
-
- **v0.7
|
|
60
|
+
- **v0.7–v1.0:** flat 4-string identity + single fingerprint via `fingerprintFromPillars(stack, form, domain, function)` = `Crockford-base32(SHA-256(stack\0form\0domain\0function))[:20]`.
|
|
61
61
|
- **v0.1–v0.6:** per-pillar `hash = canonicalHash(id)`; `fingerprint = concat(stack.hash, form.hash, domain.hash, function.hash)`.
|
|
62
|
-
- **Path checks** — `structure.entries[].path`, `entry_points[].path
|
|
63
|
-
- **Interface↔form match** — `[interface.exports]` requires a library-shaped form; `[interface.subcommands]` requires a CLI-shaped form; etc.
|
|
62
|
+
- **Path checks** — `structure.entries[].path`, `entry_points[].path` — soft-warn if missing on disk; nested-path-escape error for paths that climb above `repoRoot/anatomyDir`.
|
|
63
|
+
- **Interface↔form match (v0.7–v0.8)** — `[interface.exports]` requires a library-shaped form; `[interface.subcommands]` requires a CLI-shaped form; etc.
|
|
64
64
|
- **Soft warnings** — `description-too-long`, `entry-point-description-deprecated` (v0.2 alias), `commands-no-test` (v0.4+: `[operation.commands]` without a `test` key).
|
|
65
65
|
|
|
66
66
|
### `.anatomy-memory` (paired file)
|
|
@@ -73,11 +73,12 @@ const result = validateMemory(memoryText, {
|
|
|
73
73
|
|
|
74
74
|
### Rule verification (v0.12+)
|
|
75
75
|
|
|
76
|
-
Each `[[rules]]` entry may carry an optional `verify` field that declares how to check the rule against actual source.
|
|
76
|
+
Each `[[rules]]` entry may carry an optional `verify` field that declares how to check the rule against actual source. Four kinds:
|
|
77
77
|
|
|
78
78
|
- `glob_exists` — assert files matching a glob exist (or, with `should_not=true`, don't exist).
|
|
79
79
|
- `glob_only` — assert files matching one glob all live inside another.
|
|
80
80
|
- `ast_pattern` — ast-grep pattern + `expect_in` or `forbid_in` glob. Requires the optional `@ast-grep/napi` dependency.
|
|
81
|
+
- `semgrep` (v0.13+) — Semgrep rule + `expect_in` or `forbid_in` glob, for pattern combinators, taint mode, and non-JS-family languages. Requires the optional `semgrep` CLI on `PATH`.
|
|
81
82
|
|
|
82
83
|
Example:
|
|
83
84
|
|
|
@@ -100,7 +101,7 @@ Verify clauses run during `validate()` when `repoRoot` is provided. Violations s
|
|
|
100
101
|
For repos with multiple `.anatomy` files (one at root, plus per-package overrides):
|
|
101
102
|
|
|
102
103
|
```typescript
|
|
103
|
-
import { findAnatomyForPath, discoverAllAnatomies } from "@
|
|
104
|
+
import { findAnatomyForPath, discoverAllAnatomies } from "@anatomytool/validate";
|
|
104
105
|
|
|
105
106
|
const nearest = findAnatomyForPath(repoRoot, "packages/server/src/index.ts");
|
|
106
107
|
const all = discoverAllAnatomies(repoRoot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-no-test-warn.d.ts","sourceRoot":"","sources":["../../src/checks/commands-no-test-warn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"commands-no-test-warn.d.ts","sourceRoot":"","sources":["../../src/checks/commands-no-test-warn.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAe7D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG;IAChD,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CA4BA"}
|
|
@@ -4,7 +4,24 @@
|
|
|
4
4
|
// running the project's test suite; missing it is a soft signal that the
|
|
5
5
|
// commands table is incomplete. v0.1/v0.2/v0.3 docs are skipped — the
|
|
6
6
|
// recommendation only applies once operation.commands became a v0.4 norm.
|
|
7
|
-
|
|
7
|
+
//
|
|
8
|
+
// Applicability is DERIVED from the canonical supported-version list (filtered
|
|
9
|
+
// to >= 0.4), not a frozen inline set — a hardcoded ["0.4".."0.8"] silently
|
|
10
|
+
// went dead for v0.9–v1.0 once those versions shipped. Gating on
|
|
11
|
+
// supportedVersions also keeps unknown/garbage versions (e.g. "9.9") skipped.
|
|
12
|
+
import { supportedVersions } from "../schema.js";
|
|
13
|
+
// Numeric "major.minor" compare. Lexical compare is wrong here — "0.10" < "0.4"
|
|
14
|
+
// lexically, but 0.10 >= 0.4 numerically.
|
|
15
|
+
function versionAtLeast(version, min) {
|
|
16
|
+
const [vMaj, vMin] = version.split(".").map(Number);
|
|
17
|
+
const [mMaj, mMin] = min.split(".").map(Number);
|
|
18
|
+
if (!Number.isFinite(vMaj) || !Number.isFinite(vMin))
|
|
19
|
+
return false;
|
|
20
|
+
if (vMaj !== mMaj)
|
|
21
|
+
return vMaj > mMaj;
|
|
22
|
+
return vMin >= mMin;
|
|
23
|
+
}
|
|
24
|
+
const APPLICABLE_VERSIONS = new Set(supportedVersions.filter((v) => versionAtLeast(v, "0.4")));
|
|
8
25
|
export function commandsNoTestWarn(doc) {
|
|
9
26
|
const d = doc;
|
|
10
27
|
if (typeof d?.anatomy_version !== "string")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-no-test-warn.js","sourceRoot":"","sources":["../../src/checks/commands-no-test-warn.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,4EAA4E;AAC5E,yEAAyE;AACzE,yEAAyE;AACzE,sEAAsE;AACtE,0EAA0E;
|
|
1
|
+
{"version":3,"file":"commands-no-test-warn.js","sourceRoot":"","sources":["../../src/checks/commands-no-test-warn.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,4EAA4E;AAC5E,yEAAyE;AACzE,yEAAyE;AACzE,sEAAsE;AACtE,0EAA0E;AAC1E,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,iEAAiE;AACjE,8EAA8E;AAG9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,gFAAgF;AAChF,0CAA0C;AAC1C,SAAS,cAAc,CAAC,OAAe,EAAE,GAAW;IAClD,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACtC,OAAO,IAAI,IAAI,IAAI,CAAC;AACtB,CAAC;AAED,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAEvG,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAI7C,MAAM,CAAC,GAAG,GAGT,CAAC;IAEF,IAAI,OAAO,CAAC,EAAE,eAAe,KAAK,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAChF,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAErF,MAAM,QAAQ,GAAG,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC;IACxC,uEAAuE;IACvE,+DAA+D;IAC/D,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE3F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAmC,CAAC,CAAC;IAC9D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE/D,OAAO;QACL,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,+GAA+G;gBACxH,OAAO,EAAE,qBAAqB;aAC/B;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-grep-verifier.d.ts","sourceRoot":"","sources":["../../../src/checks/verify/ast-grep-verifier.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ast-grep-verifier.d.ts","sourceRoot":"","sources":["../../../src/checks/verify/ast-grep-verifier.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAuCnD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,EAAE,CAAC,CA0GpB"}
|
|
@@ -20,9 +20,10 @@
|
|
|
20
20
|
// - Malformed patterns don't throw on findAll — they silently return 0 matches.
|
|
21
21
|
// We detect bad patterns by parsing the pattern string as source and checking
|
|
22
22
|
// for ERROR-kind children in the parse tree.
|
|
23
|
-
import {
|
|
24
|
-
import { join
|
|
23
|
+
import { readFile } from "node:fs/promises";
|
|
24
|
+
import { join } from "node:path";
|
|
25
25
|
import { getAstGrep } from "./detect-ast-grep.js";
|
|
26
|
+
import { collectSourceMatches } from "./glob-source.js";
|
|
26
27
|
const MAX_LISTED_HITS = 5;
|
|
27
28
|
const MAX_FILE_BYTES = 256 * 1024;
|
|
28
29
|
// Map schema lang values to the napi module-level export name.
|
|
@@ -38,18 +39,6 @@ const LANG_EXPORT_MAP = {
|
|
|
38
39
|
go: "go", // Same
|
|
39
40
|
java: "java", // Same
|
|
40
41
|
};
|
|
41
|
-
/** Normalize a platform path to POSIX (forward-slash) for display and glob matching. */
|
|
42
|
-
function toPosix(p) {
|
|
43
|
-
return platformSep === "/" ? p : p.split(platformSep).join("/");
|
|
44
|
-
}
|
|
45
|
-
/** Collect all glob matches under repoRoot, returning POSIX-style relative paths. */
|
|
46
|
-
async function collectMatches(repoRoot, pattern) {
|
|
47
|
-
const out = [];
|
|
48
|
-
for await (const entry of glob(pattern, { cwd: repoRoot })) {
|
|
49
|
-
out.push(toPosix(entry));
|
|
50
|
-
}
|
|
51
|
-
return out;
|
|
52
|
-
}
|
|
53
42
|
/** Detect whether a pattern string is syntactically malformed by parsing it as
|
|
54
43
|
* source code and checking for ERROR-kind nodes in the parse tree. */
|
|
55
44
|
function isPatternMalformed(lang, pattern) {
|
|
@@ -93,7 +82,7 @@ export async function verifyAstPattern(repoRoot, cfg, pointer) {
|
|
|
93
82
|
// Schema enforces oneOf(expect_in, forbid_in); this is a defensive guard.
|
|
94
83
|
return [];
|
|
95
84
|
}
|
|
96
|
-
const files = await
|
|
85
|
+
const files = await collectSourceMatches(repoRoot, targetGlob);
|
|
97
86
|
const hits = [];
|
|
98
87
|
for (const relPath of files) {
|
|
99
88
|
const absPath = join(repoRoot, relPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-grep-verifier.js","sourceRoot":"","sources":["../../../src/checks/verify/ast-grep-verifier.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,yEAAyE;AACzE,6DAA6D;AAC7D,yEAAyE;AACzE,8EAA8E;AAC9E,EAAE;AACF,sCAAsC;AACtC,4EAA4E;AAC5E,8CAA8C;AAC9C,gFAAgF;AAChF,uGAAuG;AACvG,sDAAsD;AACtD,kCAAkC;AAClC,4DAA4D;AAC5D,6EAA6E;AAC7E,iEAAiE;AACjE,kFAAkF;AAClF,kFAAkF;AAClF,iDAAiD;AAEjD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ast-grep-verifier.js","sourceRoot":"","sources":["../../../src/checks/verify/ast-grep-verifier.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,yEAAyE;AACzE,6DAA6D;AAC7D,yEAAyE;AACzE,8EAA8E;AAC9E,EAAE;AACF,sCAAsC;AACtC,4EAA4E;AAC5E,8CAA8C;AAC9C,gFAAgF;AAChF,uGAAuG;AACvG,sDAAsD;AACtD,kCAAkC;AAClC,4DAA4D;AAC5D,6EAA6E;AAC7E,iEAAiE;AACjE,kFAAkF;AAClF,kFAAkF;AAClF,iDAAiD;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC;AAElC,+DAA+D;AAC/D,iFAAiF;AACjF,iFAAiF;AACjF,MAAM,eAAe,GAA6C;IAChE,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,IAAI,EAAM,qEAAqE;IACnF,EAAE,EAAE,IAAI,EAAM,OAAO;IACrB,EAAE,EAAE,IAAI,EAAM,OAAO;IACrB,IAAI,EAAE,MAAM,EAAE,OAAO;CACtB,CAAC;AAaF;uEACuE;AACvE,SAAS,kBAAkB,CAAC,IAAgB,EAAE,OAAe;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,GAAqB,EACrB,OAAe;IAEf,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,CAAC;gBACN,IAAI,EAAE,6BAA6B;gBACnC,OAAO,EACL,0EAA0E;oBAC1E,qEAAqE;oBACrE,yDAAyD;gBAC3D,OAAO;aACR,CAAC,CAAC;IACL,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7C,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,EAAuD,CAAC;IACzE,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAExC,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAC1D,OAAO,CAAC;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,OAAO,EACL,2CAA2C,GAAG,CAAC,IAAI,KAAK;oBACxD,kEAAkE;oBAClE,gEAAgE;gBAClE,OAAO;aACR,CAAC,CAAC;IACL,CAAC;IAED,2EAA2E;IAC3E,IAAI,kBAAkB,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,OAAO,EACL,qBAAqB,GAAG,CAAC,OAAO,4DAA4D,GAAG,CAAC,IAAI,IAAI;gBAC1G,OAAO;aACR,CAAC,CAAC;IACL,CAAC;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC;IAClD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,0EAA0E;QAC1E,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC/D,MAAM,IAAI,GAA0C,EAAE,CAAC;IAEvD,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,GAAG,CAAC,MAAM,GAAG,cAAc;gBAAE,SAAS;YAC1C,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,IAAI,MAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,SAAS;QACX,CAAC;QAED,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;YACpE,SAAS;QACX,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC;gBACN,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EACL,qBAAqB,GAAG,CAAC,OAAO,iCAAiC;oBACjE,OAAO,UAAU,WAAW,GAAG,CAAC,IAAI,IAAI;gBAC1C,OAAO;aACR,CAAC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,IAAI;aACf,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;aAC/B,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,OAAO,CAAC;gBACN,IAAI,EAAE,sCAAsC;gBAC5C,OAAO,EACL,qBAAqB,GAAG,CAAC,OAAO,aAAa,IAAI,CAAC,MAAM,iBAAiB;oBACzE,sBAAsB,UAAU,MAAM,KAAK,GAAG,MAAM,EAAE;gBACxD,OAAO;aACR,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Normalize a platform path to POSIX (forward slash) for stable display + matching. */
|
|
2
|
+
export declare function toPosix(p: string): string;
|
|
3
|
+
/** Collect glob matches under repoRoot as POSIX-relative paths, skipping vendored
|
|
4
|
+
* directories (node_modules, .git) before they reach the parser. */
|
|
5
|
+
export declare function collectSourceMatches(repoRoot: string, pattern: string): Promise<string[]>;
|
|
6
|
+
//# sourceMappingURL=glob-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob-source.d.ts","sourceRoot":"","sources":["../../../src/checks/verify/glob-source.ts"],"names":[],"mappings":"AAeA,wFAAwF;AACxF,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED;qEACqE;AACrE,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO/F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/checks/verify/glob-source.ts
|
|
2
|
+
// Shared source-file collection for the code-SCANNING verifiers (ast_pattern,
|
|
3
|
+
// semgrep pattern, semgrep rule_file). Unlike the existence globs in
|
|
4
|
+
// glob-verifier.ts, these globs feed a parser (ast-grep / semgrep) over every
|
|
5
|
+
// match — so a broad author glob like "**/*.ts" would otherwise walk and PARSE
|
|
6
|
+
// all of node_modules, the dominant verify cost and never the intended target
|
|
7
|
+
// (rules describe the repo's own code, not its dependencies). Vendored dirs are
|
|
8
|
+
// excluded to match the rest of the toolchain (the graph walk already skips them).
|
|
9
|
+
import { glob } from "node:fs/promises";
|
|
10
|
+
import { sep as platformSep } from "node:path";
|
|
11
|
+
// Path segments that are never a legitimate target for a repo's own code rules.
|
|
12
|
+
const VENDORED_SEGMENT = /(?:^|[\\/])(?:node_modules|\.git)(?:[\\/]|$)/;
|
|
13
|
+
/** Normalize a platform path to POSIX (forward slash) for stable display + matching. */
|
|
14
|
+
export function toPosix(p) {
|
|
15
|
+
return platformSep === "/" ? p : p.split(platformSep).join("/");
|
|
16
|
+
}
|
|
17
|
+
/** Collect glob matches under repoRoot as POSIX-relative paths, skipping vendored
|
|
18
|
+
* directories (node_modules, .git) before they reach the parser. */
|
|
19
|
+
export async function collectSourceMatches(repoRoot, pattern) {
|
|
20
|
+
const out = [];
|
|
21
|
+
for await (const entry of glob(pattern, { cwd: repoRoot })) {
|
|
22
|
+
if (VENDORED_SEGMENT.test(entry))
|
|
23
|
+
continue; // raw entry uses platform seps; regex handles both
|
|
24
|
+
out.push(toPosix(entry));
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=glob-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob-source.js","sourceRoot":"","sources":["../../../src/checks/verify/glob-source.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,8EAA8E;AAC9E,qEAAqE;AACrE,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,mFAAmF;AAEnF,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAE/C,gFAAgF;AAChF,MAAM,gBAAgB,GAAG,8CAA8C,CAAC;AAExE,wFAAwF;AACxF,MAAM,UAAU,OAAO,CAAC,CAAS;IAC/B,OAAO,WAAW,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClE,CAAC;AAED;qEACqE;AACrE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAgB,EAAE,OAAe;IAC1E,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QAC3D,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,SAAS,CAAC,mDAAmD;QAC/F,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semgrep-pattern-verifier.d.ts","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-pattern-verifier.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"semgrep-pattern-verifier.d.ts","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-pattern-verifier.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAoBvD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,oBAAoB,EACzB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,EAAE,CAAC,CA0GpB"}
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// JSON, or unrecognized non-zero exit all surface as verify-semgrep-unavailable
|
|
6
6
|
// warnings — never throws.
|
|
7
7
|
import { spawnSync } from "node:child_process";
|
|
8
|
-
import {
|
|
9
|
-
import { join, sep as platformSep } from "node:path";
|
|
8
|
+
import { join } from "node:path";
|
|
10
9
|
import { getSemgrep } from "./detect-semgrep.js";
|
|
10
|
+
import { collectSourceMatches } from "./glob-source.js";
|
|
11
11
|
const MAX_LISTED_HITS = 5;
|
|
12
12
|
const TIMEOUT_MS = 60_000;
|
|
13
13
|
const MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
@@ -16,16 +16,6 @@ const PATTERN_ERROR_SIGNALS = [
|
|
|
16
16
|
"Syntax error",
|
|
17
17
|
"Pattern error",
|
|
18
18
|
];
|
|
19
|
-
function toPosix(p) {
|
|
20
|
-
return platformSep === "/" ? p : p.split(platformSep).join("/");
|
|
21
|
-
}
|
|
22
|
-
async function collectMatches(repoRoot, pattern) {
|
|
23
|
-
const out = [];
|
|
24
|
-
for await (const entry of glob(pattern, { cwd: repoRoot })) {
|
|
25
|
-
out.push(toPosix(entry));
|
|
26
|
-
}
|
|
27
|
-
return out;
|
|
28
|
-
}
|
|
29
19
|
export async function verifySemgrepPattern(repoRoot, cfg, pointer) {
|
|
30
20
|
const detection = getSemgrep();
|
|
31
21
|
if (!detection.available) {
|
|
@@ -39,7 +29,7 @@ export async function verifySemgrepPattern(repoRoot, cfg, pointer) {
|
|
|
39
29
|
const targetGlob = cfg.expect_in ?? cfg.forbid_in;
|
|
40
30
|
if (!targetGlob)
|
|
41
31
|
return []; // Schema enforces oneOf — defensive guard.
|
|
42
|
-
const files = await
|
|
32
|
+
const files = await collectSourceMatches(repoRoot, targetGlob);
|
|
43
33
|
if (files.length === 0) {
|
|
44
34
|
return [{
|
|
45
35
|
code: "verify-no-files-matched",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semgrep-pattern-verifier.js","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-pattern-verifier.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAChF,2BAA2B;AAE3B,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"semgrep-pattern-verifier.js","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-pattern-verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semgrep-rule-file-verifier.d.ts","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-rule-file-verifier.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"semgrep-rule-file-verifier.d.ts","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-rule-file-verifier.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAqBxD,UAAU,YAAY;IACpB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAOD,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,qBAAqB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAmIvB"}
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
// into the dispatcher's errors[] slot. All other verifiers return Warning[]
|
|
9
9
|
// directly because they only ever produce warnings.
|
|
10
10
|
import { spawnSync } from "node:child_process";
|
|
11
|
-
import {
|
|
11
|
+
import { access } from "node:fs/promises";
|
|
12
12
|
import { resolve, join, sep as platformSep } from "node:path";
|
|
13
13
|
import { getSemgrep } from "./detect-semgrep.js";
|
|
14
|
+
import { collectSourceMatches } from "./glob-source.js";
|
|
14
15
|
const MAX_LISTED_HITS = 5;
|
|
15
16
|
const TIMEOUT_MS = 60_000;
|
|
16
17
|
const MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
@@ -20,16 +21,6 @@ const RULE_FILE_ERROR_SIGNALS = [
|
|
|
20
21
|
"Syntax error in rule",
|
|
21
22
|
"missing required field",
|
|
22
23
|
];
|
|
23
|
-
function toPosix(p) {
|
|
24
|
-
return platformSep === "/" ? p : p.split(platformSep).join("/");
|
|
25
|
-
}
|
|
26
|
-
async function collectMatches(repoRoot, pattern) {
|
|
27
|
-
const out = [];
|
|
28
|
-
for await (const entry of glob(pattern, { cwd: repoRoot })) {
|
|
29
|
-
out.push(toPosix(entry));
|
|
30
|
-
}
|
|
31
|
-
return out;
|
|
32
|
-
}
|
|
33
24
|
const warning = (w) => ({ errors: [], warnings: [w] });
|
|
34
25
|
const warnings = (ws) => ({ errors: [], warnings: ws });
|
|
35
26
|
const error = (e) => ({ errors: [e], warnings: [] });
|
|
@@ -69,7 +60,7 @@ export async function verifySemgrepRuleFile(repoRoot, cfg, pointer) {
|
|
|
69
60
|
const targetGlob = cfg.expect_in ?? cfg.forbid_in;
|
|
70
61
|
if (!targetGlob)
|
|
71
62
|
return empty();
|
|
72
|
-
const files = await
|
|
63
|
+
const files = await collectSourceMatches(repoRoot, targetGlob);
|
|
73
64
|
if (files.length === 0) {
|
|
74
65
|
return warning({
|
|
75
66
|
code: "verify-no-files-matched",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semgrep-rule-file-verifier.js","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-rule-file-verifier.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,iFAAiF;AACjF,2EAA2E;AAC3E,gFAAgF;AAChF,wEAAwE;AACxE,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,oDAAoD;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"semgrep-rule-file-verifier.js","sourceRoot":"","sources":["../../../src/checks/verify/semgrep-rule-file-verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-check.d.ts","sourceRoot":"","sources":["../../src/checks/verify-check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verify-check.d.ts","sourceRoot":"","sources":["../../src/checks/verify-check.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAO7D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAoDD,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC;IAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CA8B7D"}
|
|
@@ -1,65 +1,97 @@
|
|
|
1
1
|
// src/checks/verify-check.ts
|
|
2
|
-
// Dispatcher for
|
|
3
|
-
//
|
|
2
|
+
// Dispatcher for `verify` clauses. Walks the three verify-carrying sections —
|
|
3
|
+
// rules (since v0.12), anti_patterns and invariants (v1.1) — and for each entry
|
|
4
|
+
// with a verify field dispatches to the appropriate verifier via runVerify:
|
|
4
5
|
// kind="glob_exists" -> verifyGlobExists
|
|
5
6
|
// kind="glob_only" -> verifyGlobOnly
|
|
6
7
|
// kind="ast_pattern" -> verifyAstPattern (lazy-loads @ast-grep/napi)
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// ANATOMY_VERIFY_SKIP=1 bypasses verify-check entirely (escape hatch for
|
|
12
|
-
// slow CI runs or environments without ast-grep).
|
|
8
|
+
// kind="semgrep" -> verifySemgrepPattern | verifySemgrepRuleFile
|
|
9
|
+
// Returns aggregated { errors, warnings } per the project's never-throw rule.
|
|
10
|
+
// When repoRoot is undefined, skips silently. ANATOMY_VERIFY_SKIP=1 bypasses
|
|
11
|
+
// the check entirely (escape hatch for slow CI or environments without ast-grep).
|
|
13
12
|
import { verifyGlobExists, verifyGlobOnly } from "./verify/glob-verifier.js";
|
|
14
13
|
import { verifyAstPattern } from "./verify/ast-grep-verifier.js";
|
|
15
14
|
import { verifySemgrepPattern } from "./verify/semgrep-pattern-verifier.js";
|
|
16
15
|
import { verifySemgrepRuleFile } from "./verify/semgrep-rule-file-verifier.js";
|
|
16
|
+
// Sections whose entries may carry a `verify` field. `rules` since v0.12;
|
|
17
|
+
// `anti_patterns` and `invariants` added in v1.1.
|
|
18
|
+
const VERIFY_SECTIONS = ["rules", "anti_patterns", "invariants"];
|
|
19
|
+
/** Run a single verify clause and return its diagnostics. The per-entry
|
|
20
|
+
* try/catch keeps a misbehaving verifier (which should never throw — verifiers
|
|
21
|
+
* catch their own errors) from crashing validation: it degrades to a
|
|
22
|
+
* verify-invalid-pattern warning instead. */
|
|
23
|
+
async function runVerify(repoRoot, verify, pointer) {
|
|
24
|
+
const errors = [];
|
|
25
|
+
const warnings = [];
|
|
26
|
+
try {
|
|
27
|
+
if (verify.kind === "glob_exists") {
|
|
28
|
+
warnings.push(...await verifyGlobExists(repoRoot, verify, pointer));
|
|
29
|
+
}
|
|
30
|
+
else if (verify.kind === "glob_only") {
|
|
31
|
+
warnings.push(...await verifyGlobOnly(repoRoot, verify, pointer));
|
|
32
|
+
}
|
|
33
|
+
else if (verify.kind === "ast_pattern") {
|
|
34
|
+
warnings.push(...await verifyAstPattern(repoRoot, verify, pointer));
|
|
35
|
+
}
|
|
36
|
+
else if (verify.kind === "semgrep") {
|
|
37
|
+
if ("pattern" in verify) {
|
|
38
|
+
warnings.push(...await verifySemgrepPattern(repoRoot, verify, pointer));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const r = await verifySemgrepRuleFile(repoRoot, verify, pointer);
|
|
42
|
+
errors.push(...r.errors);
|
|
43
|
+
warnings.push(...r.warnings);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
warnings.push({
|
|
49
|
+
code: "verify-invalid-pattern",
|
|
50
|
+
message: `verify check threw: ${err instanceof Error ? err.message : String(err)}`,
|
|
51
|
+
pointer,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return { errors, warnings };
|
|
55
|
+
}
|
|
56
|
+
/** True when an anti-pattern's verify asserts the bad shape is PRESENT
|
|
57
|
+
* (expect-semantics) — a near-certain authoring error. `glob_only` has no
|
|
58
|
+
* polarity and is exempt; `should_not:true` / `forbid_in` are correct forbid. */
|
|
59
|
+
function isExpectPolarity(verify) {
|
|
60
|
+
if (verify.kind === "glob_exists")
|
|
61
|
+
return verify.should_not !== true;
|
|
62
|
+
if (verify.kind === "ast_pattern" || verify.kind === "semgrep")
|
|
63
|
+
return verify.expect_in !== undefined;
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
17
66
|
export async function verifyCheck(doc, opts) {
|
|
18
67
|
if (process.env.ANATOMY_VERIFY_SKIP === "1")
|
|
19
68
|
return { errors: [], warnings: [] };
|
|
20
69
|
if (!opts.repoRoot)
|
|
21
70
|
return { errors: [], warnings: [] };
|
|
22
|
-
const rules = doc.rules;
|
|
23
|
-
if (!Array.isArray(rules))
|
|
24
|
-
return { errors: [], warnings: [] };
|
|
25
71
|
const errors = [];
|
|
26
72
|
const warnings = [];
|
|
27
|
-
for (
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
if (!verify || typeof verify !== "object")
|
|
73
|
+
for (const section of VERIFY_SECTIONS) {
|
|
74
|
+
const arr = doc[section];
|
|
75
|
+
if (!Array.isArray(arr))
|
|
31
76
|
continue;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
77
|
+
for (let i = 0; i < arr.length; i++) {
|
|
78
|
+
const entry = arr[i];
|
|
79
|
+
const verify = entry?.verify;
|
|
80
|
+
if (!verify || typeof verify !== "object")
|
|
81
|
+
continue;
|
|
82
|
+
const pointer = `/${section}/${i}/verify`;
|
|
83
|
+
if (section === "anti_patterns" && isExpectPolarity(verify)) {
|
|
84
|
+
warnings.push({
|
|
85
|
+
code: "verify-antipattern-expect-polarity",
|
|
86
|
+
message: `anti-pattern verify uses expect-semantics (asserts the bad shape is PRESENT). ` +
|
|
87
|
+
`An anti-pattern should forbid its pattern — use should_not:true or forbid_in. ` +
|
|
88
|
+
`To assert a good shape is present, use an invariant.`,
|
|
89
|
+
pointer,
|
|
90
|
+
});
|
|
36
91
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
else if (verify.kind === "ast_pattern") {
|
|
41
|
-
warnings.push(...await verifyAstPattern(opts.repoRoot, verify, pointer));
|
|
42
|
-
}
|
|
43
|
-
else if (verify.kind === "semgrep") {
|
|
44
|
-
if ("pattern" in verify) {
|
|
45
|
-
warnings.push(...await verifySemgrepPattern(opts.repoRoot, verify, pointer));
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
const r = await verifySemgrepRuleFile(opts.repoRoot, verify, pointer);
|
|
49
|
-
errors.push(...r.errors);
|
|
50
|
-
warnings.push(...r.warnings);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
// Defensive: a verifier exception (should never happen — verifiers
|
|
56
|
-
// catch their own errors) becomes a verify-invalid-pattern warning
|
|
57
|
-
// rather than crashing validation.
|
|
58
|
-
warnings.push({
|
|
59
|
-
code: "verify-invalid-pattern",
|
|
60
|
-
message: `verify check threw: ${err instanceof Error ? err.message : String(err)}`,
|
|
61
|
-
pointer,
|
|
62
|
-
});
|
|
92
|
+
const r = await runVerify(opts.repoRoot, verify, pointer);
|
|
93
|
+
errors.push(...r.errors);
|
|
94
|
+
warnings.push(...r.warnings);
|
|
63
95
|
}
|
|
64
96
|
}
|
|
65
97
|
return { errors, warnings };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-check.js","sourceRoot":"","sources":["../../src/checks/verify-check.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,
|
|
1
|
+
{"version":3,"file":"verify-check.js","sourceRoot":"","sources":["../../src/checks/verify-check.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type ErrorCode = "toml-parse-error" | "schema-violation" | "version-mismatch" | "hash-content-mismatch" | "fingerprint-mismatch" | "unsupported-anatomy-version" | "structure-path-not-found" | "interface-form-mismatch" | "source-path-not-found" | "nested-path-escape" | "anatomy-read-error" | "memory-read-error" | "missing-anatomy-memory-version" | "unsupported-memory-version" | "memory-fingerprint-mismatch" | "memory-supersedes-not-found" | "memory-supersedes-cycle" | "memory-verified-by-malformed" | "verify-rule-file-outside-repo";
|
|
2
|
-
export type WarningCode = "description-too-long" | "entry-point-description-deprecated" | "source-path-soft-not-found" | "duplicate-fingerprint-in-tree" | "memory-dangling-ref" | "commands-no-test" | "memory-verified-by-too-many" | "memory-last-verified-before-at" | "unused-dependency-claim" | "literal-not-in-source" | "source-cross-check-truncated" | "verify-glob-empty" | "verify-glob-unexpected-files" | "verify-glob-outside-container" | "verify-pattern-not-matched" | "verify-pattern-found-where-forbidden" | "verify-ast-grep-unavailable" | "verify-invalid-pattern" | "verify-source-scan-truncated" | "verify-semgrep-unavailable" | "verify-invalid-rule-file" | "verify-rule-file-missing" | "verify-no-files-matched";
|
|
2
|
+
export type WarningCode = "description-too-long" | "entry-point-description-deprecated" | "source-path-soft-not-found" | "duplicate-fingerprint-in-tree" | "memory-dangling-ref" | "commands-no-test" | "memory-verified-by-too-many" | "memory-last-verified-before-at" | "unused-dependency-claim" | "literal-not-in-source" | "source-cross-check-truncated" | "verify-glob-empty" | "verify-glob-unexpected-files" | "verify-glob-outside-container" | "verify-pattern-not-matched" | "verify-pattern-found-where-forbidden" | "verify-ast-grep-unavailable" | "verify-invalid-pattern" | "verify-source-scan-truncated" | "verify-semgrep-unavailable" | "verify-invalid-rule-file" | "verify-rule-file-missing" | "verify-no-files-matched" | "verify-antipattern-expect-polarity";
|
|
3
3
|
export interface ValidationError {
|
|
4
4
|
/** Programmatic categorization. Frozen string-literal union. */
|
|
5
5
|
code: ErrorCode;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,uBAAuB,GACvB,sBAAsB,GACtB,6BAA6B,GAC7B,0BAA0B,GAC1B,yBAAyB,GACzB,uBAAuB,GACvB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,gCAAgC,GAChC,4BAA4B,GAC5B,6BAA6B,GAC7B,6BAA6B,GAC7B,yBAAyB,GACzB,8BAA8B,GAE9B,+BAA+B,CAAC;AAEpC,MAAM,MAAM,WAAW,GACnB,sBAAsB,GACtB,oCAAoC,GACpC,4BAA4B,GAC5B,+BAA+B,GAC/B,qBAAqB,GACrB,kBAAkB,GAClB,6BAA6B,GAC7B,gCAAgC,GAChC,yBAAyB,GACzB,uBAAuB,GACvB,8BAA8B,GAE9B,mBAAmB,GACnB,8BAA8B,GAC9B,+BAA+B,GAC/B,4BAA4B,GAC5B,sCAAsC,GACtC,6BAA6B,GAC7B,wBAAwB,GACxB,8BAA8B,GAE9B,4BAA4B,GAC5B,0BAA0B,GAC1B,0BAA0B,GAC1B,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,uBAAuB,GACvB,sBAAsB,GACtB,6BAA6B,GAC7B,0BAA0B,GAC1B,yBAAyB,GACzB,uBAAuB,GACvB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,gCAAgC,GAChC,4BAA4B,GAC5B,6BAA6B,GAC7B,6BAA6B,GAC7B,yBAAyB,GACzB,8BAA8B,GAE9B,+BAA+B,CAAC;AAEpC,MAAM,MAAM,WAAW,GACnB,sBAAsB,GACtB,oCAAoC,GACpC,4BAA4B,GAC5B,+BAA+B,GAC/B,qBAAqB,GACrB,kBAAkB,GAClB,6BAA6B,GAC7B,gCAAgC,GAChC,yBAAyB,GACzB,uBAAuB,GACvB,8BAA8B,GAE9B,mBAAmB,GACnB,8BAA8B,GAC9B,+BAA+B,GAC/B,4BAA4B,GAC5B,sCAAsC,GACtC,6BAA6B,GAC7B,wBAAwB,GACxB,8BAA8B,GAE9B,4BAA4B,GAC5B,0BAA0B,GAC1B,0BAA0B,GAC1B,yBAAyB,GAGzB,oCAAoC,CAAC;AAEzC,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,EAAE,SAAS,CAAC;IAChB,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C;;;;;+CAK2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB;oDACgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;mDAC+C;IAC/C,WAAW,CAAC,EAAE,WAAW,GAAG,gBAAgB,GAAG,aAAa,CAAC;CAC9D"}
|
package/dist/errors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/errors.ts
|
|
2
2
|
// Public error and warning types. ErrorCode and WarningCode are frozen
|
|
3
|
-
// for v0.1 (adding codes requires a minor bump of @
|
|
3
|
+
// for v0.1 (adding codes requires a minor bump of @anatomytool/validate).
|
|
4
4
|
export {};
|
|
5
5
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,uEAAuE;AACvE,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,uEAAuE;AACvE,0EAA0E"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,9 +17,9 @@ export interface ValidateOptions {
|
|
|
17
17
|
/** Optional: assert the file declares this anatomy_version. Mismatch
|
|
18
18
|
* produces a "version-mismatch" error pointing at /anatomy_version. */
|
|
19
19
|
expectedVersion?: string;
|
|
20
|
-
/** When provided, enables filesystem-aware checks: existence of
|
|
21
|
-
* [structure].entries (
|
|
22
|
-
* (
|
|
20
|
+
/** When provided, enables filesystem-aware checks: existence of
|
|
21
|
+
* [structure].entries paths (structurePathCheck) and source.path references
|
|
22
|
+
* (sourcePathCheck). When absent, those checks are skipped. */
|
|
23
23
|
repoRoot?: string;
|
|
24
24
|
/** v0.3: relative POSIX-style path from repoRoot to the directory containing
|
|
25
25
|
* this .anatomy file. Use "" for a root .anatomy. When set together with
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC3F,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE/E,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B;4EACwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC3F,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE/E,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B;4EACwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;oEAEgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;kDAM8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,GACpD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC;AAElE,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAsD/F"}
|