@eviano/tribunal 0.1.2 → 0.2.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 +177 -11
- package/dist/analyzers/claimReconciliation.js +43 -22
- package/dist/analyzers/claimReconciliation.js.map +1 -1
- package/dist/analyzers/commentCodeDrift.d.ts +37 -0
- package/dist/analyzers/commentCodeDrift.js +241 -0
- package/dist/analyzers/commentCodeDrift.js.map +1 -0
- package/dist/analyzers/hallucinatedSymbol.js +22 -0
- package/dist/analyzers/hallucinatedSymbol.js.map +1 -1
- package/dist/analyzers/index.d.ts +5 -1
- package/dist/analyzers/index.js +12 -2
- package/dist/analyzers/index.js.map +1 -1
- package/dist/analyzers/riskyDiffNoTest.d.ts +36 -0
- package/dist/analyzers/riskyDiffNoTest.js +221 -0
- package/dist/analyzers/riskyDiffNoTest.js.map +1 -0
- package/dist/cli.js +167 -24
- package/dist/cli.js.map +1 -1
- package/dist/config/loadConfig.d.ts +19 -0
- package/dist/config/loadConfig.js +89 -0
- package/dist/config/loadConfig.js.map +1 -0
- package/dist/config/parseYaml.d.ts +17 -0
- package/dist/config/parseYaml.js +131 -0
- package/dist/config/parseYaml.js.map +1 -0
- package/dist/config/types.d.ts +17 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/diff/parseUnifiedDiff.d.ts +4 -0
- package/dist/diff/parseUnifiedDiff.js +45 -18
- package/dist/diff/parseUnifiedDiff.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/paths.d.ts +27 -0
- package/dist/paths.js +112 -0
- package/dist/paths.js.map +1 -0
- package/dist/propose.d.ts +103 -0
- package/dist/propose.js +175 -0
- package/dist/propose.js.map +1 -0
- package/dist/report/render.d.ts +5 -0
- package/dist/report/render.js +78 -0
- package/dist/report/render.js.map +1 -1
- package/package.json +1 -1
package/dist/report/render.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
const VERDICT_EMOJI = {
|
|
2
3
|
CONTRADICTED: '🔴',
|
|
3
4
|
UNVERIFIED: '🟡',
|
|
@@ -67,4 +68,81 @@ function renderFinding(f) {
|
|
|
67
68
|
const head = `- ${VERDICT_EMOJI[f.verdict]} **${f.title}** — ${where} _(${f.analyzer})_`;
|
|
68
69
|
return `${head}\n ${f.detail}`;
|
|
69
70
|
}
|
|
71
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
72
|
+
// SARIF (Static Analysis Results Interchange Format) v2.1.0 output.
|
|
73
|
+
//
|
|
74
|
+
// Designed so Tribunal findings can be posted as GitHub code-scanning alerts via
|
|
75
|
+
// github/codeql-action/upload-sarif, with proper tracking/dismissal across runs.
|
|
76
|
+
//
|
|
77
|
+
// Verdict → SARIF level mapping (deliberate, matches the Trust Contract's "gate only on
|
|
78
|
+
// CONTRADICTED"): CONTRADICTED → error, UNVERIFIED → note, PASS → omitted. Only the blocking verdict
|
|
79
|
+
// becomes an alert entry; UNVERIFIED is visible but non-noisy. SARIF is DATA, never a gate — the gate
|
|
80
|
+
// stays in exitCode().
|
|
81
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
82
|
+
const SARIF_LEVEL = {
|
|
83
|
+
CONTRADICTED: 'error',
|
|
84
|
+
UNVERIFIED: 'note',
|
|
85
|
+
PASS: null,
|
|
86
|
+
};
|
|
87
|
+
const SARIF_SCHEMA = 'https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/schemas/sarif-schema-2.1.0.json';
|
|
88
|
+
/**
|
|
89
|
+
* A stable, content-addressed fingerprint for a finding so GitHub can track the same alert across runs
|
|
90
|
+
* (reopen/dismiss/stable identity). Derived from the analyzer + file + line + claim — deliberately NOT
|
|
91
|
+
* from the prose (title/detail), which we may reword without wanting to fork a new alert.
|
|
92
|
+
*/
|
|
93
|
+
function sarifFingerprint(f) {
|
|
94
|
+
const material = [f.analyzer, f.file, String(f.line), f.claim ?? ''].join('|');
|
|
95
|
+
return createHash('sha256').update(material).digest('hex').slice(0, 16);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Render the report as a SARIF Log v2.1.0 JSON string. Each analyzer becomes a `rule`; each
|
|
99
|
+
* CONTRADICTED/UNVERIFIED finding becomes a `result` (PASS findings are omitted).
|
|
100
|
+
*/
|
|
101
|
+
export function renderSarif(report) {
|
|
102
|
+
// One rule per analyzer that produced a non-PASS finding, so GitHub groups alerts by analyzer.
|
|
103
|
+
const ruleAnalyzers = Array.from(new Set(report.findings.filter((f) => SARIF_LEVEL[f.verdict] !== null).map((f) => f.analyzer)));
|
|
104
|
+
const rules = ruleAnalyzers.map((id) => ({
|
|
105
|
+
id,
|
|
106
|
+
name: id,
|
|
107
|
+
shortDescription: { text: `Tribunal analyzer: ${id}` },
|
|
108
|
+
}));
|
|
109
|
+
const results = report.findings
|
|
110
|
+
.filter((f) => SARIF_LEVEL[f.verdict] !== null)
|
|
111
|
+
.map((f) => {
|
|
112
|
+
const region = { startLine: f.line };
|
|
113
|
+
if (f.endLine && f.endLine !== f.line)
|
|
114
|
+
region.endLine = f.endLine;
|
|
115
|
+
return {
|
|
116
|
+
ruleId: f.analyzer,
|
|
117
|
+
level: SARIF_LEVEL[f.verdict],
|
|
118
|
+
message: { text: `${f.title} — ${f.detail}` },
|
|
119
|
+
locations: [
|
|
120
|
+
{
|
|
121
|
+
physicalLocation: {
|
|
122
|
+
artifactLocation: { uri: f.file },
|
|
123
|
+
region,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
partialFingerprints: { tribunal: sarifFingerprint(f) },
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
const log = {
|
|
131
|
+
$schema: SARIF_SCHEMA,
|
|
132
|
+
version: '2.1.0',
|
|
133
|
+
runs: [
|
|
134
|
+
{
|
|
135
|
+
tool: {
|
|
136
|
+
driver: {
|
|
137
|
+
name: 'tribunal',
|
|
138
|
+
informationUri: 'https://github.com/eviano/tribunal',
|
|
139
|
+
rules,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
results,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
return JSON.stringify(log, null, 2);
|
|
147
|
+
}
|
|
70
148
|
//# sourceMappingURL=render.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/report/render.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/report/render.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eviano/tribunal",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A deterministic, no-LLM-in-the-loop CI gate that catches agent-PR defects: assertion-free tests, hallucinated symbols, and PR claims that contradict the diff.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|