glamsterdam-compat-lab 0.2.2 → 0.3.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/CONTRIBUTING.md +1 -1
- package/README.md +29 -5
- package/ROADMAP.md +3 -2
- package/dist/cli.js +17 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/reports/compareReports.d.ts +2 -0
- package/dist/reports/compareReports.js +201 -0
- package/dist/reports/compareReports.js.map +1 -0
- package/dist/reports/jsonReporter.d.ts +2 -1
- package/dist/reports/jsonReporter.js +4 -1
- package/dist/reports/jsonReporter.js.map +1 -1
- package/dist/reports/markdownReporter.d.ts +2 -1
- package/dist/reports/markdownReporter.js +74 -0
- package/dist/reports/markdownReporter.js.map +1 -1
- package/dist/reports/reportTypes.d.ts +517 -1
- package/dist/reports/reportTypes.js +86 -1
- package/dist/reports/reportTypes.js.map +1 -1
- package/docs/fixtures.md +2 -0
- package/docs/release.md +26 -20
- package/fixtures/reports/baseline-default-report.json +68 -0
- package/fixtures/reports/candidate-research-report.json +68 -0
- package/package.json +2 -2
package/CONTRIBUTING.md
CHANGED
|
@@ -22,7 +22,7 @@ pnpm test:update
|
|
|
22
22
|
|
|
23
23
|
Releases are published from semver tags. After CI is green on `main`, create the GitHub release tag, then run the manual `Publish npm` workflow from `main` with the release tag as `release_tag`.
|
|
24
24
|
|
|
25
|
-
Start with `dry_run=true
|
|
25
|
+
Start with `dry_run=true` for a new, unpublished release version. Real publishes use npm Trusted Publishing for `glamsterdam-compat-lab` with repository `CruzMolina/glamsterdam-compat-lab`, workflow file `npm-publish.yml`, and environment `npm-publish`. Do not configure `NPM_TOKEN` for the normal release path; use a short-lived token only as an emergency fallback, remove the GitHub secret immediately afterward, and revoke the npm token.
|
|
26
26
|
|
|
27
27
|
The workflow checks out the requested semver tag, verifies that `package.json` matches the tag, installs dependencies, runs tests, builds, and then runs `npm publish --provenance`.
|
|
28
28
|
|
package/README.md
CHANGED
|
@@ -33,13 +33,20 @@ pnpm glamsterdam eips
|
|
|
33
33
|
pnpm glamsterdam scan-bytecode fixtures/bytecode/storage-heavy.hex
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Install the published CLI from npm:
|
|
37
37
|
|
|
38
38
|
```sh
|
|
39
|
-
npm install -g
|
|
39
|
+
npm install -g glamsterdam-compat-lab@0.3.0
|
|
40
|
+
glamsterdam eips
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
The v0.3.0 GitHub release tarball remains available as a reproducible release artifact:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
npm install -g https://github.com/CruzMolina/glamsterdam-compat-lab/releases/download/v0.3.0/glamsterdam-compat-lab-0.3.0.tgz
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
See [docs/release.md](docs/release.md) for maintainer release checks and npm publishing notes.
|
|
43
50
|
|
|
44
51
|
The default output format is Markdown. Use `--format json` for machine-readable reports.
|
|
45
52
|
|
|
@@ -53,6 +60,7 @@ ETH_RPC_URL=https://your-execution-rpc.example pnpm glamsterdam scan-tx --tx 0x0
|
|
|
53
60
|
pnpm glamsterdam scan-indexer fixtures/indexers/subgraph.yaml --format markdown
|
|
54
61
|
pnpm glamsterdam scan-validator --config fixtures/validator/operator-config.yaml --format markdown
|
|
55
62
|
pnpm glamsterdam report report-a.json report-b.json --format markdown
|
|
63
|
+
pnpm glamsterdam compare-reports baseline-report.json candidate-report.json --format markdown
|
|
56
64
|
```
|
|
57
65
|
|
|
58
66
|
Each scanner accepts `--registry <path>` and `--thresholds <path>` so EIP metadata and detector thresholds can be updated without editing detector code.
|
|
@@ -100,13 +108,15 @@ Use `--trace-out <path>` to save the fetched JSON-RPC trace response while also
|
|
|
100
108
|
|
|
101
109
|
`scan-validator` parses JSON and YAML operator configs. It checks for execution, consensus, validator, builder/API, monitoring, and testnet/devnet metadata. It compares client names and versions against `data/client-compat/clients.example.json` or a user-provided matrix, but it does not guess compatibility.
|
|
102
110
|
|
|
111
|
+
`compare-reports` accepts two saved JSON compatibility reports and emits deterministic JSON or Markdown deltas. It compares findings by stable finding ID, reports findings added, removed, changed, and unchanged, and highlights severity and confidence changes. It does not invent exact gas deltas; those must come from explicit input data or future client outputs.
|
|
112
|
+
|
|
103
113
|
## Report model
|
|
104
114
|
|
|
105
115
|
Each scanner returns a `CompatibilityReport`:
|
|
106
116
|
|
|
107
117
|
```json
|
|
108
118
|
{
|
|
109
|
-
"toolVersion": "0.
|
|
119
|
+
"toolVersion": "0.3.0",
|
|
110
120
|
"fork": "glamsterdam",
|
|
111
121
|
"target": {
|
|
112
122
|
"kind": "bytecode",
|
|
@@ -139,6 +149,20 @@ Confidence means:
|
|
|
139
149
|
- `medium`: strong heuristic
|
|
140
150
|
- `low`: weak heuristic or incomplete input
|
|
141
151
|
|
|
152
|
+
Comparison reports include baseline and candidate report references, risk and finding-count deltas, added/removed/changed/unchanged finding lists, and comparison assumptions and limitations. This supports workflows such as comparing default, research, and CI threshold-profile outputs:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
pnpm glamsterdam scan-traces fixtures/traces/storage-heavy-trace.json \
|
|
156
|
+
--thresholds data/detectors/thresholds.json \
|
|
157
|
+
--format json > default-report.json
|
|
158
|
+
|
|
159
|
+
pnpm glamsterdam scan-traces fixtures/traces/storage-heavy-trace.json \
|
|
160
|
+
--thresholds data/detectors/thresholds.research.json \
|
|
161
|
+
--format json > research-report.json
|
|
162
|
+
|
|
163
|
+
pnpm glamsterdam compare-reports default-report.json research-report.json --format markdown
|
|
164
|
+
```
|
|
165
|
+
|
|
142
166
|
## Updating the EIP registry
|
|
143
167
|
|
|
144
168
|
Edit `data/eips/glamsterdam.json`.
|
|
@@ -180,7 +204,7 @@ Release publishing notes live in [docs/release.md](docs/release.md).
|
|
|
180
204
|
|
|
181
205
|
## Roadmap
|
|
182
206
|
|
|
183
|
-
See [ROADMAP.md](ROADMAP.md) for planned phases. Phase 0 is released as `v0.1.0`; `v0.2.0` starts Phase 1 with RPC transaction trace ingestion and broader trace fixture coverage.
|
|
207
|
+
See [ROADMAP.md](ROADMAP.md) for planned phases. Phase 0 is released as `v0.1.0`; `v0.2.0` starts Phase 1 with RPC transaction trace ingestion and broader trace fixture coverage; `v0.3.0` adds baseline comparison reports.
|
|
184
208
|
|
|
185
209
|
## Disclaimer
|
|
186
210
|
|
package/ROADMAP.md
CHANGED
|
@@ -44,9 +44,10 @@ Target release: `v0.3.0`.
|
|
|
44
44
|
|
|
45
45
|
Goal: compare compatibility reports across profiles and, later, across current-client and Glamsterdam-aware traces.
|
|
46
46
|
|
|
47
|
+
- Add `compare-reports` for deterministic JSON and Markdown report comparisons
|
|
47
48
|
- Compare one trace against multiple threshold profiles
|
|
48
|
-
- Emit report deltas for findings added, removed, or changed in severity
|
|
49
|
-
- Keep comparisons deterministic and JSON-friendly
|
|
49
|
+
- Emit report deltas for findings added, removed, or changed in severity or confidence
|
|
50
|
+
- Keep comparisons deterministic and JSON-friendly with golden fixtures and snapshots
|
|
50
51
|
- Defer fork-specific gas deltas until they are present in explicit data files or client configs
|
|
51
52
|
|
|
52
53
|
## Phase 2: Public Dataset
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
-
import { combineReports, defaultClientMatrixPath, defaultThresholdsPath, loadEipRegistry, renderJsonReport, renderMarkdownReport, scanBytecode, scanIndexer, scanTraceFile, scanValidatorConfig, validateCompatibilityReport, fetchAndScanTransactionTrace, writeFetchedTrace } from "./index.js";
|
|
4
|
+
import { combineReports, defaultClientMatrixPath, defaultThresholdsPath, compareCompatibilityReports, loadEipRegistry, renderJsonComparisonReport, renderJsonReport, renderMarkdownComparisonReport, renderMarkdownReport, scanBytecode, scanIndexer, scanTraceFile, scanValidatorConfig, validateCompatibilityReport, fetchAndScanTransactionTrace, writeFetchedTrace } from "./index.js";
|
|
5
5
|
import { TOOL_VERSION } from "./reports/reportTypes.js";
|
|
6
6
|
import { parseDebugTraceMode } from "./scanners/rpcTraceScanner.js";
|
|
7
7
|
const program = new Command();
|
|
@@ -111,6 +111,19 @@ program
|
|
|
111
111
|
const parsedReports = reports.map((path) => validateCompatibilityReport(JSON.parse(readFileSync(path, "utf8"))));
|
|
112
112
|
writeReport(combineReports(parsedReports), parseFormat(options.format));
|
|
113
113
|
});
|
|
114
|
+
program
|
|
115
|
+
.command("compare-reports")
|
|
116
|
+
.alias("compare")
|
|
117
|
+
.argument("<baseline-report>", "Baseline JSON report generated with --format json")
|
|
118
|
+
.argument("<candidate-report>", "Candidate JSON report generated with --format json")
|
|
119
|
+
.option("--format <format>", "Output format: markdown or json", "markdown")
|
|
120
|
+
.description("Compare two saved JSON compatibility reports")
|
|
121
|
+
.action((baselineReport, candidateReport, options) => {
|
|
122
|
+
const baseline = validateCompatibilityReport(JSON.parse(readFileSync(baselineReport, "utf8")));
|
|
123
|
+
const candidate = validateCompatibilityReport(JSON.parse(readFileSync(candidateReport, "utf8")));
|
|
124
|
+
const comparison = compareCompatibilityReports(baseline, candidate);
|
|
125
|
+
writeComparisonReport(comparison, parseFormat(options.format));
|
|
126
|
+
});
|
|
114
127
|
program.parseAsync(process.argv).catch((error) => {
|
|
115
128
|
const message = error instanceof Error ? error.message : String(error);
|
|
116
129
|
process.stderr.write(`Error: ${message}\n`);
|
|
@@ -119,6 +132,9 @@ program.parseAsync(process.argv).catch((error) => {
|
|
|
119
132
|
function writeReport(report, format) {
|
|
120
133
|
process.stdout.write(format === "json" ? renderJsonReport(report) : renderMarkdownReport(report));
|
|
121
134
|
}
|
|
135
|
+
function writeComparisonReport(report, format) {
|
|
136
|
+
process.stdout.write(format === "json" ? renderJsonComparisonReport(report) : renderMarkdownComparisonReport(report));
|
|
137
|
+
}
|
|
122
138
|
function parseFormat(format) {
|
|
123
139
|
if (format === "markdown" || format === "json") {
|
|
124
140
|
return format;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,2BAA2B,EAC3B,4BAA4B,EAC5B,iBAAiB,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,9 @@ export { scanIndexer, summarizeHandlers } from "./scanners/indexerScanner.js";
|
|
|
9
9
|
export { scanValidatorConfig, defaultClientMatrixPath } from "./scanners/validatorScanner.js";
|
|
10
10
|
export { loadDetectorThresholds, defaultThresholdsPath, detectorThresholdsSchema } from "./detectors/thresholds.js";
|
|
11
11
|
export type { DetectorThresholds } from "./detectors/thresholds.js";
|
|
12
|
-
export { compatibilityReportSchema, findingSchema, makeReport, summarizeFindings, validateCompatibilityReport, combineReports } from "./reports/reportTypes.js";
|
|
13
|
-
export type { CompatibilityFinding, CompatibilityReport, Confidence, ReportDomain, Severity, TargetKind } from "./reports/reportTypes.js";
|
|
14
|
-
export {
|
|
15
|
-
export {
|
|
12
|
+
export { compatibilityReportSchema, comparisonReportSchema, comparisonFindingReferenceSchema, changedFindingSchema, findingSchema, makeReport, summarizeFindings, validateCompatibilityReport, validateComparisonReport, combineReports } from "./reports/reportTypes.js";
|
|
13
|
+
export type { ChangedFinding, ComparisonDirection, ComparisonField, ComparisonFindingReference, ComparisonReport, CompatibilityFinding, CompatibilityReport, Confidence, ReportDomain, Severity, TargetKind } from "./reports/reportTypes.js";
|
|
14
|
+
export { compareCompatibilityReports } from "./reports/compareReports.js";
|
|
15
|
+
export { renderJsonComparisonReport, renderJsonReport } from "./reports/jsonReporter.js";
|
|
16
|
+
export { renderMarkdownComparisonReport, renderMarkdownReport } from "./reports/markdownReporter.js";
|
|
16
17
|
export { normalizeBytecode, disassembleBytecode, countOpcodeNames, byteLength, opcodeCount } from "./utils/bytecode.js";
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,9 @@ export { writeFetchedTrace } from "./scanners/rpcTraceScanner.js";
|
|
|
6
6
|
export { scanIndexer, summarizeHandlers } from "./scanners/indexerScanner.js";
|
|
7
7
|
export { scanValidatorConfig, defaultClientMatrixPath } from "./scanners/validatorScanner.js";
|
|
8
8
|
export { loadDetectorThresholds, defaultThresholdsPath, detectorThresholdsSchema } from "./detectors/thresholds.js";
|
|
9
|
-
export { compatibilityReportSchema, findingSchema, makeReport, summarizeFindings, validateCompatibilityReport, combineReports } from "./reports/reportTypes.js";
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
9
|
+
export { compatibilityReportSchema, comparisonReportSchema, comparisonFindingReferenceSchema, changedFindingSchema, findingSchema, makeReport, summarizeFindings, validateCompatibilityReport, validateComparisonReport, combineReports } from "./reports/reportTypes.js";
|
|
10
|
+
export { compareCompatibilityReports } from "./reports/compareReports.js";
|
|
11
|
+
export { renderJsonComparisonReport, renderJsonReport } from "./reports/jsonReporter.js";
|
|
12
|
+
export { renderMarkdownComparisonReport, renderMarkdownReport } from "./reports/markdownReporter.js";
|
|
12
13
|
export { normalizeBytecode, disassembleBytecode, countOpcodeNames, byteLength, opcodeCount } from "./utils/bytecode.js";
|
|
13
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGjF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,oBAAoB,EACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAQlE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAGpH,OAAO,EACL,yBAAyB,EACzB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,cAAc,EACf,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGjF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,oBAAoB,EACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAQlE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAGpH,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,gCAAgC,EAChC,oBAAoB,EACpB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,wBAAwB,EACxB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAelC,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErG,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,WAAW,EACZ,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { TOOL_VERSION, comparisonReportSchema, compatibilityReportSchema } from "./reportTypes.js";
|
|
2
|
+
const severityRank = {
|
|
3
|
+
low: 0,
|
|
4
|
+
medium: 1,
|
|
5
|
+
high: 2
|
|
6
|
+
};
|
|
7
|
+
const confidenceRank = {
|
|
8
|
+
low: 0,
|
|
9
|
+
medium: 1,
|
|
10
|
+
high: 2
|
|
11
|
+
};
|
|
12
|
+
export function compareCompatibilityReports(baselineInput, candidateInput) {
|
|
13
|
+
const baseline = compatibilityReportSchema.parse(baselineInput);
|
|
14
|
+
const candidate = compatibilityReportSchema.parse(candidateInput);
|
|
15
|
+
const baselineMap = keyedFindings(baseline.findings);
|
|
16
|
+
const candidateMap = keyedFindings(candidate.findings);
|
|
17
|
+
const keys = [...new Set([...baselineMap.keys(), ...candidateMap.keys()])].sort();
|
|
18
|
+
const added = [];
|
|
19
|
+
const removed = [];
|
|
20
|
+
const changed = [];
|
|
21
|
+
const unchanged = [];
|
|
22
|
+
for (const key of keys) {
|
|
23
|
+
const baselineFinding = baselineMap.get(key);
|
|
24
|
+
const candidateFinding = candidateMap.get(key);
|
|
25
|
+
if (!baselineFinding && candidateFinding) {
|
|
26
|
+
added.push(toFindingReference(candidateFinding));
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (baselineFinding && !candidateFinding) {
|
|
30
|
+
removed.push(toFindingReference(baselineFinding));
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!baselineFinding || !candidateFinding) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const findingChange = compareFinding(baselineFinding, candidateFinding);
|
|
37
|
+
if (findingChange) {
|
|
38
|
+
changed.push(findingChange);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
unchanged.push(toFindingReference(candidateFinding));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const severityChanges = changed.flatMap((finding) => finding.severityChange ? [finding.severityChange] : []);
|
|
45
|
+
const confidenceChanges = changed.flatMap((finding) => finding.confidenceChange ? [finding.confidenceChange] : []);
|
|
46
|
+
return comparisonReportSchema.parse({
|
|
47
|
+
toolVersion: TOOL_VERSION,
|
|
48
|
+
fork: candidate.fork,
|
|
49
|
+
comparison: {
|
|
50
|
+
baseline: toReportReference(baseline),
|
|
51
|
+
candidate: toReportReference(candidate)
|
|
52
|
+
},
|
|
53
|
+
summary: {
|
|
54
|
+
riskChange: {
|
|
55
|
+
from: baseline.summary.risk,
|
|
56
|
+
to: candidate.summary.risk,
|
|
57
|
+
direction: compareSeverity(baseline.summary.risk, candidate.summary.risk)
|
|
58
|
+
},
|
|
59
|
+
findingCount: {
|
|
60
|
+
baseline: baseline.summary.findingCount,
|
|
61
|
+
candidate: candidate.summary.findingCount,
|
|
62
|
+
delta: candidate.summary.findingCount - baseline.summary.findingCount
|
|
63
|
+
},
|
|
64
|
+
addedCount: added.length,
|
|
65
|
+
removedCount: removed.length,
|
|
66
|
+
changedCount: changed.length,
|
|
67
|
+
unchangedCount: unchanged.length,
|
|
68
|
+
severityIncreasedCount: countDirections(severityChanges, "increased"),
|
|
69
|
+
severityDecreasedCount: countDirections(severityChanges, "decreased"),
|
|
70
|
+
severityChangedCount: countDirections(severityChanges, "changed"),
|
|
71
|
+
confidenceIncreasedCount: countDirections(confidenceChanges, "increased"),
|
|
72
|
+
confidenceDecreasedCount: countDirections(confidenceChanges, "decreased"),
|
|
73
|
+
confidenceChangedCount: countDirections(confidenceChanges, "changed")
|
|
74
|
+
},
|
|
75
|
+
changes: {
|
|
76
|
+
added,
|
|
77
|
+
removed,
|
|
78
|
+
changed,
|
|
79
|
+
unchanged
|
|
80
|
+
},
|
|
81
|
+
assumptions: [
|
|
82
|
+
"Reports were compared by finding id. Repeated finding ids are disambiguated with deterministic occurrence suffixes.",
|
|
83
|
+
"Severity and confidence changes are structural report changes, not protocol gas estimates."
|
|
84
|
+
],
|
|
85
|
+
limitations: [
|
|
86
|
+
"The comparison does not infer exact gas deltas, final Glamsterdam parameters, or current-vs-Glamsterdam client behavior unless those values are already present in the input reports.",
|
|
87
|
+
"Added and removed findings can reflect threshold profile differences, fixture coverage changes, registry updates, or detector changes; review the source reports before treating a diff as a protocol risk change."
|
|
88
|
+
]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function keyedFindings(findings) {
|
|
92
|
+
const seen = new Map();
|
|
93
|
+
const keyed = new Map();
|
|
94
|
+
for (const finding of findings) {
|
|
95
|
+
const occurrence = (seen.get(finding.id) ?? 0) + 1;
|
|
96
|
+
seen.set(finding.id, occurrence);
|
|
97
|
+
const key = occurrence === 1 ? finding.id : `${finding.id}#${occurrence}`;
|
|
98
|
+
keyed.set(key, { key, finding });
|
|
99
|
+
}
|
|
100
|
+
return keyed;
|
|
101
|
+
}
|
|
102
|
+
function compareFinding(baseline, candidate) {
|
|
103
|
+
const changedFields = [];
|
|
104
|
+
const baselineFinding = baseline.finding;
|
|
105
|
+
const candidateFinding = candidate.finding;
|
|
106
|
+
if (baselineFinding.title !== candidateFinding.title) {
|
|
107
|
+
changedFields.push("title");
|
|
108
|
+
}
|
|
109
|
+
if (baselineFinding.severity !== candidateFinding.severity) {
|
|
110
|
+
changedFields.push("severity");
|
|
111
|
+
}
|
|
112
|
+
if (baselineFinding.confidence !== candidateFinding.confidence) {
|
|
113
|
+
changedFields.push("confidence");
|
|
114
|
+
}
|
|
115
|
+
if (!sameStringSet(baselineFinding.domain, candidateFinding.domain)) {
|
|
116
|
+
changedFields.push("domain");
|
|
117
|
+
}
|
|
118
|
+
if (!sameStringSet(baselineFinding.relatedEips, candidateFinding.relatedEips)) {
|
|
119
|
+
changedFields.push("relatedEips");
|
|
120
|
+
}
|
|
121
|
+
if (baselineFinding.description !== candidateFinding.description) {
|
|
122
|
+
changedFields.push("description");
|
|
123
|
+
}
|
|
124
|
+
if (!sameJson(baselineFinding.evidence, candidateFinding.evidence)) {
|
|
125
|
+
changedFields.push("evidence");
|
|
126
|
+
}
|
|
127
|
+
if (baselineFinding.recommendation !== candidateFinding.recommendation) {
|
|
128
|
+
changedFields.push("recommendation");
|
|
129
|
+
}
|
|
130
|
+
if (changedFields.length === 0) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
key: baseline.key,
|
|
135
|
+
id: baselineFinding.id,
|
|
136
|
+
changedFields,
|
|
137
|
+
baseline: toFindingReference(baseline),
|
|
138
|
+
candidate: toFindingReference(candidate),
|
|
139
|
+
severityChange: baselineFinding.severity === candidateFinding.severity
|
|
140
|
+
? undefined
|
|
141
|
+
: {
|
|
142
|
+
from: baselineFinding.severity,
|
|
143
|
+
to: candidateFinding.severity,
|
|
144
|
+
direction: compareSeverity(baselineFinding.severity, candidateFinding.severity)
|
|
145
|
+
},
|
|
146
|
+
confidenceChange: baselineFinding.confidence === candidateFinding.confidence
|
|
147
|
+
? undefined
|
|
148
|
+
: {
|
|
149
|
+
from: baselineFinding.confidence,
|
|
150
|
+
to: candidateFinding.confidence,
|
|
151
|
+
direction: compareConfidence(baselineFinding.confidence, candidateFinding.confidence)
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function toReportReference(report) {
|
|
156
|
+
return {
|
|
157
|
+
toolVersion: report.toolVersion,
|
|
158
|
+
fork: report.fork,
|
|
159
|
+
target: report.target,
|
|
160
|
+
summary: report.summary
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function toFindingReference(keyed) {
|
|
164
|
+
const finding = keyed.finding;
|
|
165
|
+
return {
|
|
166
|
+
key: keyed.key,
|
|
167
|
+
id: finding.id,
|
|
168
|
+
title: finding.title,
|
|
169
|
+
severity: finding.severity,
|
|
170
|
+
confidence: finding.confidence,
|
|
171
|
+
domain: finding.domain,
|
|
172
|
+
relatedEips: finding.relatedEips
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function compareSeverity(from, to) {
|
|
176
|
+
return compareRank(from, to, severityRank);
|
|
177
|
+
}
|
|
178
|
+
function compareConfidence(from, to) {
|
|
179
|
+
return compareRank(from, to, confidenceRank);
|
|
180
|
+
}
|
|
181
|
+
function compareRank(from, to, ranks) {
|
|
182
|
+
if (from === to) {
|
|
183
|
+
return "unchanged";
|
|
184
|
+
}
|
|
185
|
+
const fromRank = ranks[from];
|
|
186
|
+
const toRank = ranks[to];
|
|
187
|
+
if (fromRank === undefined || toRank === undefined) {
|
|
188
|
+
return "changed";
|
|
189
|
+
}
|
|
190
|
+
return toRank > fromRank ? "increased" : "decreased";
|
|
191
|
+
}
|
|
192
|
+
function countDirections(changes, direction) {
|
|
193
|
+
return changes.filter((change) => change.direction === direction).length;
|
|
194
|
+
}
|
|
195
|
+
function sameStringSet(left, right) {
|
|
196
|
+
return JSON.stringify([...left].sort()) === JSON.stringify([...right].sort());
|
|
197
|
+
}
|
|
198
|
+
function sameJson(left, right) {
|
|
199
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=compareReports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compareReports.js","sourceRoot":"","sources":["../../src/reports/compareReports.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { type CompatibilityReport } from "./reportTypes.js";
|
|
1
|
+
import { type ComparisonReport, type CompatibilityReport } from "./reportTypes.js";
|
|
2
2
|
export declare function renderJsonReport(report: CompatibilityReport): string;
|
|
3
|
+
export declare function renderJsonComparisonReport(report: ComparisonReport): string;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { compatibilityReportSchema } from "./reportTypes.js";
|
|
1
|
+
import { compatibilityReportSchema, comparisonReportSchema } from "./reportTypes.js";
|
|
2
2
|
export function renderJsonReport(report) {
|
|
3
3
|
return `${JSON.stringify(compatibilityReportSchema.parse(report), null, 2)}\n`;
|
|
4
4
|
}
|
|
5
|
+
export function renderJsonComparisonReport(report) {
|
|
6
|
+
return `${JSON.stringify(comparisonReportSchema.parse(report), null, 2)}\n`;
|
|
7
|
+
}
|
|
5
8
|
//# sourceMappingURL=jsonReporter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonReporter.js","sourceRoot":"","sources":["../../src/reports/jsonReporter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"jsonReporter.js","sourceRoot":"","sources":["../../src/reports/jsonReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EAGvB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,UAAU,gBAAgB,CAAC,MAA2B;IAC1D,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAwB;IACjE,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAC9E,CAAC"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type { CompatibilityReport } from "./reportTypes.js";
|
|
1
|
+
import type { ComparisonReport, CompatibilityReport } from "./reportTypes.js";
|
|
2
2
|
export declare function renderMarkdownReport(report: CompatibilityReport): string;
|
|
3
|
+
export declare function renderMarkdownComparisonReport(report: ComparisonReport): string;
|
|
@@ -32,6 +32,37 @@ export function renderMarkdownReport(report) {
|
|
|
32
32
|
lines.push("");
|
|
33
33
|
return `${lines.join("\n")}\n`;
|
|
34
34
|
}
|
|
35
|
+
export function renderMarkdownComparisonReport(report) {
|
|
36
|
+
const lines = [];
|
|
37
|
+
lines.push("# Glamsterdam Compatibility Comparison");
|
|
38
|
+
lines.push("");
|
|
39
|
+
lines.push(`Baseline: ${formatReportReference(report.comparison.baseline)}`);
|
|
40
|
+
lines.push(`Candidate: ${formatReportReference(report.comparison.candidate)}`);
|
|
41
|
+
lines.push(`Tool version: ${report.toolVersion}`);
|
|
42
|
+
lines.push(`Fork registry: ${report.fork}`);
|
|
43
|
+
lines.push("");
|
|
44
|
+
lines.push("## Summary");
|
|
45
|
+
lines.push("");
|
|
46
|
+
lines.push(`Overall risk: ${formatInlineSeverity(report.summary.riskChange.from)} -> ${formatInlineSeverity(report.summary.riskChange.to)} (${formatDirection(report.summary.riskChange.direction)})`);
|
|
47
|
+
lines.push(`Findings: ${report.summary.findingCount.baseline} baseline, ${report.summary.findingCount.candidate} candidate, delta ${formatSignedNumber(report.summary.findingCount.delta)}`);
|
|
48
|
+
lines.push(`Changes: ${report.summary.addedCount} added, ${report.summary.removedCount} removed, ${report.summary.changedCount} changed, ${report.summary.unchangedCount} unchanged`);
|
|
49
|
+
lines.push(`Severity changes: ${report.summary.severityIncreasedCount} increased, ${report.summary.severityDecreasedCount} decreased, ${report.summary.severityChangedCount} changed`);
|
|
50
|
+
lines.push(`Confidence changes: ${report.summary.confidenceIncreasedCount} increased, ${report.summary.confidenceDecreasedCount} decreased, ${report.summary.confidenceChangedCount} changed`);
|
|
51
|
+
lines.push("");
|
|
52
|
+
renderFindingReferenceSection(lines, "Added Findings", report.changes.added, "No findings were added.");
|
|
53
|
+
renderFindingReferenceSection(lines, "Removed Findings", report.changes.removed, "No findings were removed.");
|
|
54
|
+
renderChangedFindingSection(lines, report.changes.changed);
|
|
55
|
+
renderFindingReferenceSection(lines, "Unchanged Findings", report.changes.unchanged, "No findings were unchanged.");
|
|
56
|
+
lines.push("## Assumptions");
|
|
57
|
+
lines.push("");
|
|
58
|
+
pushList(lines, report.assumptions, "No explicit assumptions were recorded.");
|
|
59
|
+
lines.push("");
|
|
60
|
+
lines.push("## Limitations");
|
|
61
|
+
lines.push("");
|
|
62
|
+
pushList(lines, report.limitations, "No limitations were recorded.");
|
|
63
|
+
lines.push("");
|
|
64
|
+
return `${lines.join("\n")}\n`;
|
|
65
|
+
}
|
|
35
66
|
function renderFinding(finding, index) {
|
|
36
67
|
const lines = [];
|
|
37
68
|
lines.push(`### ${index}. ${finding.title}`);
|
|
@@ -54,6 +85,40 @@ function renderFinding(finding, index) {
|
|
|
54
85
|
lines.push("");
|
|
55
86
|
return lines.join("\n");
|
|
56
87
|
}
|
|
88
|
+
function renderFindingReferenceSection(lines, title, findings, emptyText) {
|
|
89
|
+
lines.push(`## ${title}`);
|
|
90
|
+
lines.push("");
|
|
91
|
+
if (findings.length === 0) {
|
|
92
|
+
lines.push(emptyText);
|
|
93
|
+
lines.push("");
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
for (const finding of findings) {
|
|
97
|
+
lines.push(`- ${finding.key}: ${finding.title} (${formatInlineSeverity(finding.severity)}, confidence ${finding.confidence})`);
|
|
98
|
+
}
|
|
99
|
+
lines.push("");
|
|
100
|
+
}
|
|
101
|
+
function renderChangedFindingSection(lines, findings) {
|
|
102
|
+
lines.push("## Changed Findings");
|
|
103
|
+
lines.push("");
|
|
104
|
+
if (findings.length === 0) {
|
|
105
|
+
lines.push("No findings changed.");
|
|
106
|
+
lines.push("");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
findings.forEach((finding, index) => {
|
|
110
|
+
lines.push(`### ${index + 1}. ${finding.key}: ${finding.candidate.title}`);
|
|
111
|
+
lines.push("");
|
|
112
|
+
lines.push(`Changed fields: ${finding.changedFields.join(", ")}`);
|
|
113
|
+
if (finding.severityChange) {
|
|
114
|
+
lines.push(`Severity: ${formatInlineSeverity(finding.severityChange.from)} -> ${formatInlineSeverity(finding.severityChange.to)} (${formatDirection(finding.severityChange.direction)})`);
|
|
115
|
+
}
|
|
116
|
+
if (finding.confidenceChange) {
|
|
117
|
+
lines.push(`Confidence: ${finding.confidenceChange.from} -> ${finding.confidenceChange.to} (${formatDirection(finding.confidenceChange.direction)})`);
|
|
118
|
+
}
|
|
119
|
+
lines.push("");
|
|
120
|
+
});
|
|
121
|
+
}
|
|
57
122
|
function pushList(lines, items, emptyText) {
|
|
58
123
|
if (items.length === 0) {
|
|
59
124
|
lines.push(emptyText);
|
|
@@ -72,4 +137,13 @@ function formatEvidence(item) {
|
|
|
72
137
|
function formatInlineSeverity(value) {
|
|
73
138
|
return value.toUpperCase();
|
|
74
139
|
}
|
|
140
|
+
function formatReportReference(report) {
|
|
141
|
+
return `${report.target.kind} ${report.target.name} (${report.summary.risk} risk, ${report.summary.findingCount} findings)`;
|
|
142
|
+
}
|
|
143
|
+
function formatSignedNumber(value) {
|
|
144
|
+
return value > 0 ? `+${value}` : String(value);
|
|
145
|
+
}
|
|
146
|
+
function formatDirection(direction) {
|
|
147
|
+
return direction;
|
|
148
|
+
}
|
|
75
149
|
//# sourceMappingURL=markdownReporter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdownReporter.js","sourceRoot":"","sources":["../../src/reports/markdownReporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"markdownReporter.js","sourceRoot":"","sources":["../../src/reports/markdownReporter.ts"],"names":[],"mappings":"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"}
|