@cejel/cejel 0.6.7 → 0.6.10
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 +179 -17
- package/dist/calibration/llm-detector.js +5 -5
- package/dist/{chunk-VGBFZBZQ.js → chunk-2UMHJ23V.js} +81 -19
- package/dist/{chunk-RH6FKREX.js → chunk-6LVNNJTG.js} +1 -1
- package/dist/{chunk-FSMZV3Y6.js → chunk-AMVP7L26.js} +1 -1
- package/dist/{chunk-O3MHSK25.js → chunk-AWLKQUI4.js} +56 -6
- package/dist/{chunk-5PFYOIOS.js → chunk-RRPQHEBU.js} +2 -2
- package/dist/{chunk-TOQPQPDF.js → chunk-U2VDSTIT.js} +3 -3
- package/dist/chunk-YHJ7ICL4.js +23796 -0
- package/dist/index.js +163 -20
- package/dist/mcp/index.js +5 -5
- package/dist/packs/d-series/index.js +4 -4
- package/dist/packs/decision-contracts/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-ZZHQZW26.js +0 -11811
package/dist/index.js
CHANGED
|
@@ -3,18 +3,22 @@ import { createRequire as __cejelCreateRequire } from 'node:module';
|
|
|
3
3
|
const require = __cejelCreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
serveCejelMcpOverStdio
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-U2VDSTIT.js";
|
|
7
7
|
import {
|
|
8
8
|
CALLER_CONTEXT_PRODUCT_IDENTITY_NOTICE,
|
|
9
9
|
CERTIFICATE_GLOSSARY,
|
|
10
|
+
EXTERNAL_FINDINGS_DISPLAY_LIMIT,
|
|
10
11
|
PROSPECTIVE_RUBRIC_NOTICE,
|
|
11
12
|
WITAN_RUBRIC_VERSION_V22,
|
|
12
13
|
WitanReportSchema,
|
|
13
14
|
assertSelectableRubricVersion,
|
|
15
|
+
buildPlainSummary,
|
|
14
16
|
buildRelyingPartySummary,
|
|
15
17
|
buildVerdictExplanation,
|
|
16
18
|
computeApplicableMeasuredCoverage,
|
|
17
19
|
createWitanAttestation,
|
|
20
|
+
describeInputBindingRecord,
|
|
21
|
+
describeScannedSubject,
|
|
18
22
|
formatCertificateMetricAppliedWeightPercent,
|
|
19
23
|
formatCertificateMetricLabel,
|
|
20
24
|
formatCertificateMetricValue,
|
|
@@ -22,21 +26,32 @@ import {
|
|
|
22
26
|
formatDimensionsMeasuredSentence,
|
|
23
27
|
formatExternalSourceLine,
|
|
24
28
|
formatLowConfidenceSentence,
|
|
29
|
+
formatVerdictCapSentence,
|
|
30
|
+
glossaryEntryForRubric,
|
|
31
|
+
importedAdjustmentSentence,
|
|
32
|
+
inheritedFindingNote,
|
|
33
|
+
inputBindingHeadline,
|
|
25
34
|
isProspectiveRubricVersion,
|
|
35
|
+
isWitanAbstentionLabel,
|
|
36
|
+
renderWitanAbstentionHeadline,
|
|
26
37
|
renderWitanBadgeEndpoint,
|
|
27
38
|
renderWitanBadgeSvg,
|
|
28
39
|
renderWitanHtmlReport,
|
|
40
|
+
resolveIngestFilePath,
|
|
29
41
|
runCejelScan,
|
|
30
42
|
serializeWitanReport,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
stripTerminalControls,
|
|
44
|
+
verifyRecordedInputDigests,
|
|
45
|
+
verifyWitanAttestationBinding,
|
|
46
|
+
witanHistoryAbstentionInstruction
|
|
47
|
+
} from "./chunk-YHJ7ICL4.js";
|
|
48
|
+
import "./chunk-2UMHJ23V.js";
|
|
34
49
|
import {
|
|
35
50
|
external_exports
|
|
36
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-AMVP7L26.js";
|
|
37
52
|
import {
|
|
38
53
|
init_esm_shims
|
|
39
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-AWLKQUI4.js";
|
|
40
55
|
|
|
41
56
|
// src/index.ts
|
|
42
57
|
init_esm_shims();
|
|
@@ -643,9 +658,14 @@ function writeOutputFiles(dir, files, what) {
|
|
|
643
658
|
// src/terminal.ts
|
|
644
659
|
init_esm_shims();
|
|
645
660
|
function renderMinScoreAbstentionFailure(summary, minScore) {
|
|
646
|
-
if (summary.verdict
|
|
661
|
+
if (!isWitanAbstentionLabel(summary.verdict)) {
|
|
647
662
|
throw new Error("A minimum-score abstention message requires an abstained Cejel summary.");
|
|
648
663
|
}
|
|
664
|
+
const instruction = witanHistoryAbstentionInstruction(summary.verdict);
|
|
665
|
+
if (instruction !== void 0) {
|
|
666
|
+
return `Cejel: cannot evaluate the required minimum ${minScore.toFixed(1)}/4.0 because the scan is ${summary.verdict.toLowerCase()}, with no composite score and no verdict. ${instruction}
|
|
667
|
+
`;
|
|
668
|
+
}
|
|
649
669
|
return `Cejel: cannot evaluate the required minimum ${minScore.toFixed(1)}/4.0 because this repository has ${summary.verdict.toLowerCase()}.
|
|
650
670
|
`;
|
|
651
671
|
}
|
|
@@ -663,24 +683,22 @@ function renderMinScoreCoverageFailure(coverage, minScore) {
|
|
|
663
683
|
return `Cejel: cannot evaluate the required minimum ${minScore.toFixed(1)}/4.0 because fewer than half of the applicable dimensions were measured in at least one score (${formatCoverageSummary(coverage)}). Resolve the reported evidence gaps and re-scan.
|
|
664
684
|
`;
|
|
665
685
|
}
|
|
666
|
-
function stripTerminalControls(text) {
|
|
667
|
-
return text.replace(/[\t\n]/g, " ").replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
|
|
668
|
-
}
|
|
669
686
|
function renderTerminalCertificate(summary, report) {
|
|
670
|
-
const abstained = summary.verdict
|
|
687
|
+
const abstained = isWitanAbstentionLabel(summary.verdict);
|
|
671
688
|
if (!abstained && (summary.overallScore === null || summary.codeTrustScore === null || summary.processTrustScore === null)) {
|
|
672
689
|
throw new Error("A scored Cejel summary must carry numeric headline scores.");
|
|
673
690
|
}
|
|
674
691
|
const lines = abstained ? [
|
|
675
692
|
`Cejel Trust Certificate \u2014 ${stripTerminalControls(summary.productDisplayName)}`,
|
|
676
693
|
"",
|
|
677
|
-
|
|
694
|
+
renderWitanAbstentionHeadline(summary.verdict),
|
|
678
695
|
` ${summary.insufficientSourceReason === void 0 ? "No ratable source or measurable evidence was found." : stripTerminalControls(summary.insufficientSourceReason)}`,
|
|
679
696
|
""
|
|
680
697
|
] : [
|
|
681
698
|
`Cejel Trust Certificate \u2014 ${stripTerminalControls(summary.productDisplayName)}`,
|
|
682
699
|
"",
|
|
683
700
|
`Overall: ${formatScore(summary.overallScore)}/4.0 (${summary.verdict})`,
|
|
701
|
+
...report && formatVerdictCapSentence(report) ? [` ${formatVerdictCapSentence(report)}`] : [],
|
|
684
702
|
` Code trust: ${formatScore(summary.codeTrustScore)}/4.0`,
|
|
685
703
|
` Process trust: ${formatScore(summary.processTrustScore)}/4.0`,
|
|
686
704
|
...report ? [` ${formatDimensionsMeasuredSentence(report)}`] : [],
|
|
@@ -696,11 +714,12 @@ function renderTerminalCertificate(summary, report) {
|
|
|
696
714
|
`Scope: ${relyingPartySummary.scope}`,
|
|
697
715
|
`What was examined: ${stripTerminalControls(relyingPartySummary.examined)}`,
|
|
698
716
|
`What was established: ${relyingPartySummary.established}`,
|
|
699
|
-
`What was not established: ${relyingPartySummary.notEstablished}`,
|
|
717
|
+
`What was not established: ${stripTerminalControls(relyingPartySummary.notEstablished)}`,
|
|
700
718
|
`What to do next: ${relyingPartySummary.next}`,
|
|
701
719
|
""
|
|
702
720
|
);
|
|
703
721
|
}
|
|
722
|
+
if (report) lines.push(...renderPlainSummaryLines(buildPlainSummary(report), summary, abstained));
|
|
704
723
|
if (summary.scanLimitations.length > 0) {
|
|
705
724
|
lines.push(
|
|
706
725
|
"LIMITED EVIDENCE \u2014 the score and verdict are qualified by scan limitations:",
|
|
@@ -710,7 +729,7 @@ function renderTerminalCertificate(summary, report) {
|
|
|
710
729
|
}
|
|
711
730
|
if (summary.historyLimitations?.length) {
|
|
712
731
|
lines.push(
|
|
713
|
-
"HISTORY LIMITATION \u2014 scored as usual, but some criteria read truncated history:",
|
|
732
|
+
abstained ? "HISTORY LIMITATION \u2014 some criteria read truncated history:" : "HISTORY LIMITATION \u2014 scored as usual, but some criteria read truncated history:",
|
|
714
733
|
...summary.historyLimitations.map((limitation) => ` - ${stripTerminalControls(limitation)}`),
|
|
715
734
|
""
|
|
716
735
|
);
|
|
@@ -719,7 +738,7 @@ function renderTerminalCertificate(summary, report) {
|
|
|
719
738
|
const reads = summary.contentReadSummary;
|
|
720
739
|
const errnoCounts = Object.entries(reads.unreadableByErrno).map(([errno, count]) => `${errno}: ${count}`).join(", ");
|
|
721
740
|
lines.push(
|
|
722
|
-
`Skipped content entries: ${reads.skipped} (unreadable: ${reads.byReason.unreadable}${errnoCounts ? ` [${errnoCounts}]` : ""}; too large: ${reads.byReason.tooLarge}; excluded by extension: ${reads.byReason.excludedByExtension}; denied path: ${reads.byReason.deniedPath}; non-regular file: ${reads.byReason.nonRegularFile}).`
|
|
741
|
+
`Skipped content entries: ${reads.skipped} (unreadable: ${reads.byReason.unreadable}${errnoCounts ? ` [${errnoCounts}]` : ""}; too large: ${reads.byReason.tooLarge}; excluded by extension: ${reads.byReason.excludedByExtension}; denied path: ${reads.byReason.deniedPath}; non-regular file: ${reads.byReason.nonRegularFile}${reads.byReason.lfsPointer ? `; Git LFS pointer: ${reads.byReason.lfsPointer}` : ""}).`
|
|
723
742
|
);
|
|
724
743
|
if (reads.affectedCriteria.length > 0) {
|
|
725
744
|
lines.push(
|
|
@@ -737,6 +756,20 @@ function renderTerminalCertificate(summary, report) {
|
|
|
737
756
|
}
|
|
738
757
|
lines.push("");
|
|
739
758
|
}
|
|
759
|
+
if (report?.inputBinding) {
|
|
760
|
+
lines.push(stripTerminalControls(inputBindingHeadline(report.inputBinding)));
|
|
761
|
+
lines.push(` ${stripTerminalControls(describeScannedSubject(report.inputBinding))}`);
|
|
762
|
+
for (const input of report.inputBinding.inputs.slice(0, EXTERNAL_FINDINGS_DISPLAY_LIMIT)) {
|
|
763
|
+
lines.push(` ${stripTerminalControls(describeInputBindingRecord(input))}`);
|
|
764
|
+
}
|
|
765
|
+
const remaining = report.inputBinding.inputs.length - EXTERNAL_FINDINGS_DISPLAY_LIMIT;
|
|
766
|
+
if (remaining > 0) lines.push(` ...and ${remaining} more \u2014 see report.json inputBinding.`);
|
|
767
|
+
for (const criterion of report.criteria) {
|
|
768
|
+
const sentence = importedAdjustmentSentence(criterion);
|
|
769
|
+
if (sentence) lines.push(` ${criterion.id}: ${sentence}`);
|
|
770
|
+
}
|
|
771
|
+
lines.push("");
|
|
772
|
+
}
|
|
740
773
|
const measurements = report?.criteria.flatMap(
|
|
741
774
|
(criterion) => criterion.metrics.map((metric) => ({
|
|
742
775
|
criterionId: criterion.id,
|
|
@@ -749,7 +782,7 @@ function renderTerminalCertificate(summary, report) {
|
|
|
749
782
|
lines.push("Measurements:");
|
|
750
783
|
for (const measurement of measurements ?? []) {
|
|
751
784
|
lines.push(
|
|
752
|
-
` ${measurement.criterionId} \u2014 ${measurement.label}: ${measurement.value} (weight ${measurement.weightPercent}% of ${measurement.criterionId})`
|
|
785
|
+
` ${measurement.criterionId} \u2014 ${measurement.label}: ${stripTerminalControls(measurement.value)} (weight ${measurement.weightPercent}% of ${measurement.criterionId})`
|
|
753
786
|
);
|
|
754
787
|
}
|
|
755
788
|
lines.push("");
|
|
@@ -783,6 +816,8 @@ function renderTerminalCertificate(summary, report) {
|
|
|
783
816
|
lines.push(
|
|
784
817
|
` [${finding.severity}] ${stripTerminalControls(finding.label)} \u2192 ${finding.dimension}: ${stripTerminalControls(finding.ruleId)} \u2014 ${stripTerminalControls(finding.message)}${finding.location ? ` (${stripTerminalControls(finding.location)})` : ""}`
|
|
785
818
|
);
|
|
819
|
+
const note = inheritedFindingNote(finding.ruleId);
|
|
820
|
+
if (note) lines.push(` Note: ${note}`);
|
|
786
821
|
}
|
|
787
822
|
const remaining = summary.externalFindingCount - summary.topExternalFindings.length;
|
|
788
823
|
if (remaining > 0) {
|
|
@@ -790,7 +825,7 @@ function renderTerminalCertificate(summary, report) {
|
|
|
790
825
|
}
|
|
791
826
|
}
|
|
792
827
|
lines.push("", "Plain-language glossary:");
|
|
793
|
-
for (const entry of CERTIFICATE_GLOSSARY) {
|
|
828
|
+
for (const entry of CERTIFICATE_GLOSSARY.map((curated) => glossaryEntryForRubric(curated, report?.rubricVersion))) {
|
|
794
829
|
lines.push(` ${entry.term} \u2014 ${entry.definition}`);
|
|
795
830
|
}
|
|
796
831
|
if (report && isProspectiveRubricVersion(report.rubricVersion)) {
|
|
@@ -799,6 +834,43 @@ function renderTerminalCertificate(summary, report) {
|
|
|
799
834
|
return `${lines.join("\n")}
|
|
800
835
|
`;
|
|
801
836
|
}
|
|
837
|
+
var PLAIN_TERMINAL_ITEM_LIMIT = 3;
|
|
838
|
+
function renderPlainSummaryLines(plain, summary, abstained) {
|
|
839
|
+
const section = (heading, leads, items, empty) => {
|
|
840
|
+
const shown = items.slice(0, PLAIN_TERMINAL_ITEM_LIMIT);
|
|
841
|
+
const remaining = items.length - shown.length;
|
|
842
|
+
return [
|
|
843
|
+
`${heading} (${items.length}):`,
|
|
844
|
+
...leads.filter((lead) => lead !== void 0).map((lead) => ` ${lead}`),
|
|
845
|
+
...items.length === 0 ? [` ${empty}`] : shown.map((item) => ` - ${stripTerminalControls(item)}`),
|
|
846
|
+
...remaining > 0 ? [` ...and ${remaining} more in certificate.html.`] : []
|
|
847
|
+
];
|
|
848
|
+
};
|
|
849
|
+
const itemLine = (item) => `${item.area} \u2014 ${item.text}${item.location !== void 0 ? ` (${item.location})` : ""}`;
|
|
850
|
+
const wrongFindings = plain.wrong.filter((item) => item.source.kind === "finding").length;
|
|
851
|
+
const otherFindings = summary.findingCount - wrongFindings;
|
|
852
|
+
const topFindingsNote = !abstained && otherFindings > 0 ? `Top findings below counts ${summary.findingCount} finding${summary.findingCount === 1 ? "" : "s"} in all, including ${otherFindings} informational finding${otherFindings === 1 ? "" : "s"} not listed here.` : void 0;
|
|
853
|
+
return [
|
|
854
|
+
"In plain words (the full lists, with links to the evidence, are in certificate.html):",
|
|
855
|
+
...plain.prospectiveNotice !== void 0 ? [` ${plain.prospectiveNotice}`] : [],
|
|
856
|
+
...section("What holds", [plain.areasLine, plain.holdsLead], plain.holds.map(itemLine), plain.holdsNote ?? ""),
|
|
857
|
+
...section(
|
|
858
|
+
"What is wrong",
|
|
859
|
+
[plain.wrongNote, topFindingsNote],
|
|
860
|
+
plain.wrong.map((item) => `${item.level === "critical" ? "Critical" : "Warning"}: ${itemLine(item)}`),
|
|
861
|
+
"Cejel recorded no critical or warning-level problem in what it checked."
|
|
862
|
+
),
|
|
863
|
+
...section("What is not known", [], plain.notKnown.map(itemLine), "Cejel listed no gap here; anything it did not measure is still not established."),
|
|
864
|
+
...section(
|
|
865
|
+
"What to check next",
|
|
866
|
+
[],
|
|
867
|
+
plain.checkNext.map((check) => `${check.area} \u2014 ${check.text}`),
|
|
868
|
+
"Nothing to check from these lists."
|
|
869
|
+
),
|
|
870
|
+
plain.notCovered,
|
|
871
|
+
""
|
|
872
|
+
];
|
|
873
|
+
}
|
|
802
874
|
function formatScore(score) {
|
|
803
875
|
if (score === null) throw new Error("A scored Cejel summary must carry numeric scores.");
|
|
804
876
|
return score.toFixed(1);
|
|
@@ -861,6 +933,17 @@ var CLI_FLAG_SPECS = [
|
|
|
861
933
|
description: "fold in a SARIF/JSON scanner report (repeatable)",
|
|
862
934
|
kind: "ingest"
|
|
863
935
|
},
|
|
936
|
+
{
|
|
937
|
+
tokens: ["--subject-repository"],
|
|
938
|
+
value: "<repo>",
|
|
939
|
+
description: "name this repository (e.g. github.com/owner/repo) so ingested inputs declaring another repository are recorded as mismatched",
|
|
940
|
+
kind: "subjectRepository"
|
|
941
|
+
},
|
|
942
|
+
{
|
|
943
|
+
tokens: ["--strict-ingest"],
|
|
944
|
+
description: "refuse ingested inputs for another repository or commit, observed before this commit, or duplicated (default: record only)",
|
|
945
|
+
kind: "strictIngest"
|
|
946
|
+
},
|
|
864
947
|
{
|
|
865
948
|
tokens: ["--rubric-pin"],
|
|
866
949
|
value: "<version>",
|
|
@@ -953,6 +1036,8 @@ ${usageOptions}
|
|
|
953
1036
|
Verify options:
|
|
954
1037
|
--signers <file> use this allowed-signers file instead of the published one
|
|
955
1038
|
--revocations <file> use this revocations file instead of the published one
|
|
1039
|
+
--input <file> an ingested input (repeatable); fails unless the supplied set of files
|
|
1040
|
+
has exactly the sha256 digests report.json records in inputBinding
|
|
956
1041
|
|
|
957
1042
|
Issue options:
|
|
958
1043
|
--report <file> the report.json being countersigned (required)
|
|
@@ -964,6 +1049,7 @@ Issue options:
|
|
|
964
1049
|
--name <display> pass exactly what the original scan used, or the bytes will not reproduce
|
|
965
1050
|
--rubric-pin <version> pass exactly what the original scan used, or the bytes will not reproduce
|
|
966
1051
|
--ingest <file> pass exactly what the original scan used, or the bytes will not reproduce
|
|
1052
|
+
(--strict-ingest and --subject-repository are read from report.json's inputBinding)
|
|
967
1053
|
|
|
968
1054
|
cejel never signs and never reads private key material.
|
|
969
1055
|
|
|
@@ -1035,6 +1121,8 @@ async function runWitanCli(args, rubricVersion) {
|
|
|
1035
1121
|
...effectiveRubricVersion ? { rubricVersion: effectiveRubricVersion } : {},
|
|
1036
1122
|
ingestPatterns: options.ingestPatterns,
|
|
1037
1123
|
warnOnEmptyIngestMatch: !options.quiet,
|
|
1124
|
+
...options.strictIngest ? { strictIngest: true } : {},
|
|
1125
|
+
...options.subjectRepository ? { subjectRepository: options.subjectRepository } : {},
|
|
1038
1126
|
toolVersion: cliVersion()
|
|
1039
1127
|
});
|
|
1040
1128
|
const attestation = createWitanAttestation(report, {
|
|
@@ -1057,7 +1145,13 @@ async function runWitanCli(args, rubricVersion) {
|
|
|
1057
1145
|
},
|
|
1058
1146
|
{ name: "badge.json", contents: JSON.stringify(renderWitanBadgeEndpoint(report), null, 2) },
|
|
1059
1147
|
{ name: "badge.svg", contents: renderWitanBadgeSvg(report) },
|
|
1060
|
-
|
|
1148
|
+
// plainSummary (goal_cejel_four_question_summary_2026-11-02) is added here, at the one place
|
|
1149
|
+
// summary.json is written, so buildWitanCliSummary's shape (the MCP and HTTP responses) and
|
|
1150
|
+
// every key before it are unchanged.
|
|
1151
|
+
{
|
|
1152
|
+
name: "summary.json",
|
|
1153
|
+
contents: JSON.stringify({ ...summary, plainSummary: buildPlainSummary(report) }, null, 2)
|
|
1154
|
+
}
|
|
1061
1155
|
],
|
|
1062
1156
|
"scan output"
|
|
1063
1157
|
);
|
|
@@ -1198,14 +1292,22 @@ ${members.map((member) => ` - ${member}`).join("\n")}
|
|
|
1198
1292
|
process.stderr.write(renderGitLabCodeQualityFooter(result));
|
|
1199
1293
|
return 0;
|
|
1200
1294
|
}
|
|
1201
|
-
var VERIFY_USAGE = () => `Usage: npx ${NPX_PACKAGE_NAME} verify <report.json> <attestation.json> [issuance.json issuance.json.sig] [--signers <file>] [--revocations <file>]`;
|
|
1295
|
+
var VERIFY_USAGE = () => `Usage: npx ${NPX_PACKAGE_NAME} verify <report.json> <attestation.json> [issuance.json issuance.json.sig] [--signers <file>] [--revocations <file>] [--input <file>...]`;
|
|
1202
1296
|
function parseVerifyArgs(args) {
|
|
1203
1297
|
const positionals = [];
|
|
1204
1298
|
let signersPath;
|
|
1205
1299
|
let revocationsPath;
|
|
1300
|
+
const inputPaths = [];
|
|
1206
1301
|
for (let index = 0; index < args.length; index += 1) {
|
|
1207
1302
|
const arg = args[index];
|
|
1208
1303
|
if (arg === void 0) continue;
|
|
1304
|
+
if (arg === "--input") {
|
|
1305
|
+
const value = args[index + 1];
|
|
1306
|
+
if (!value) throw new Error(`Missing value for ${arg}`);
|
|
1307
|
+
inputPaths.push(resolve3(value));
|
|
1308
|
+
index += 1;
|
|
1309
|
+
continue;
|
|
1310
|
+
}
|
|
1209
1311
|
if (arg === "--signers" || arg === "--revocations") {
|
|
1210
1312
|
const value = args[index + 1];
|
|
1211
1313
|
if (!value) throw new Error(`Missing value for ${arg}`);
|
|
@@ -1227,7 +1329,8 @@ function parseVerifyArgs(args) {
|
|
|
1227
1329
|
...issuancePath ? { issuancePath: resolve3(issuancePath) } : {},
|
|
1228
1330
|
...issuanceSignaturePath ? { issuanceSignaturePath: resolve3(issuanceSignaturePath) } : {},
|
|
1229
1331
|
...signersPath ? { signersPath } : {},
|
|
1230
|
-
...revocationsPath ? { revocationsPath } : {}
|
|
1332
|
+
...revocationsPath ? { revocationsPath } : {},
|
|
1333
|
+
...inputPaths.length > 0 ? { inputPaths } : {}
|
|
1231
1334
|
};
|
|
1232
1335
|
}
|
|
1233
1336
|
function parseIssueArgs(args) {
|
|
@@ -1352,6 +1455,26 @@ ${result.errors.map((error) => ` - ${error}`).join("\n")}
|
|
|
1352
1455
|
return 1;
|
|
1353
1456
|
}
|
|
1354
1457
|
process.stdout.write("Cejel: report/attestation binding verified.\n");
|
|
1458
|
+
if (invocation.inputPaths) {
|
|
1459
|
+
let inputCheck;
|
|
1460
|
+
try {
|
|
1461
|
+
inputCheck = verifyRecordedInputDigests(
|
|
1462
|
+
reportResult.data,
|
|
1463
|
+
invocation.inputPaths,
|
|
1464
|
+
(path) => readFileSync(resolveIngestFilePath(path))
|
|
1465
|
+
);
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1468
|
+
process.stderr.write(
|
|
1469
|
+
`Cejel: input digests not verified \u2014 ${stripTerminalControls(message.replace(/^Cejel: /, ""))}
|
|
1470
|
+
`
|
|
1471
|
+
);
|
|
1472
|
+
return 1;
|
|
1473
|
+
}
|
|
1474
|
+
for (const line of inputCheck.lines) process.stdout.write(`${stripTerminalControls(line)}
|
|
1475
|
+
`);
|
|
1476
|
+
if (!inputCheck.valid) return 1;
|
|
1477
|
+
}
|
|
1355
1478
|
if (!invocation.issuancePath || !invocation.issuanceSignaturePath) {
|
|
1356
1479
|
process.stdout.write("Cejel: signature and signer identity were not verified.\n");
|
|
1357
1480
|
return 0;
|
|
@@ -1490,6 +1613,12 @@ ${attestationBinding.errors.map((error) => ` - ${error}`).join("\n")}
|
|
|
1490
1613
|
...options.rubricPin ? { rubricVersion: options.rubricPin } : {},
|
|
1491
1614
|
ingestPatterns: options.ingestPatterns,
|
|
1492
1615
|
warnOnEmptyIngestMatch: true,
|
|
1616
|
+
// The binding policy and the named subject repository are part of the invocation the report
|
|
1617
|
+
// records, so the reproduction reads them from the report it is reproducing rather than from
|
|
1618
|
+
// flags an issuer could forget. Anything else a report states differently fails the byte
|
|
1619
|
+
// comparison below, as it always has.
|
|
1620
|
+
...suppliedReport.inputBinding?.policy === "strict" ? { strictIngest: true } : {},
|
|
1621
|
+
...suppliedReport.inputBinding?.scannedSubject.repository ? { subjectRepository: suppliedReport.inputBinding.scannedSubject.repository } : {},
|
|
1493
1622
|
toolVersion: cliVersion()
|
|
1494
1623
|
});
|
|
1495
1624
|
const reproducedBytes = serializeWitanReport(reproduction.report);
|
|
@@ -1568,6 +1697,8 @@ function parseArgs(args) {
|
|
|
1568
1697
|
let showVersion = false;
|
|
1569
1698
|
let rubricPin;
|
|
1570
1699
|
let runAttempt;
|
|
1700
|
+
let strictIngest = false;
|
|
1701
|
+
let subjectRepository;
|
|
1571
1702
|
const ingestPatterns = [];
|
|
1572
1703
|
for (let index = 0; index < args.length; index += 1) {
|
|
1573
1704
|
const arg = args[index];
|
|
@@ -1646,6 +1777,16 @@ function parseArgs(args) {
|
|
|
1646
1777
|
index += 1;
|
|
1647
1778
|
break;
|
|
1648
1779
|
}
|
|
1780
|
+
case "strictIngest":
|
|
1781
|
+
strictIngest = true;
|
|
1782
|
+
break;
|
|
1783
|
+
case "subjectRepository": {
|
|
1784
|
+
const value = args[index + 1];
|
|
1785
|
+
if (!value) throw new Error("Missing value for --subject-repository");
|
|
1786
|
+
subjectRepository = value;
|
|
1787
|
+
index += 1;
|
|
1788
|
+
break;
|
|
1789
|
+
}
|
|
1649
1790
|
case "runAttempt": {
|
|
1650
1791
|
const value = args[index + 1];
|
|
1651
1792
|
if (!value) throw new Error("Missing value for --run-attempt");
|
|
@@ -1678,6 +1819,8 @@ function parseArgs(args) {
|
|
|
1678
1819
|
showHelp,
|
|
1679
1820
|
showVersion,
|
|
1680
1821
|
ingestPatterns,
|
|
1822
|
+
...strictIngest ? { strictIngest } : {},
|
|
1823
|
+
...subjectRepository ? { subjectRepository } : {},
|
|
1681
1824
|
...rubricPin ? { rubricPin } : {},
|
|
1682
1825
|
...runAttempt ? { runAttempt } : {}
|
|
1683
1826
|
};
|
package/dist/mcp/index.js
CHANGED
|
@@ -3,13 +3,13 @@ import { createRequire as __cejelCreateRequire } from 'node:module';
|
|
|
3
3
|
const require = __cejelCreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
serveCejelMcpOverStdio
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-U2VDSTIT.js";
|
|
7
|
+
import "../chunk-YHJ7ICL4.js";
|
|
8
|
+
import "../chunk-2UMHJ23V.js";
|
|
9
|
+
import "../chunk-AMVP7L26.js";
|
|
10
10
|
import {
|
|
11
11
|
init_esm_shims
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-AWLKQUI4.js";
|
|
13
13
|
|
|
14
14
|
// src/mcp/index.ts
|
|
15
15
|
init_esm_shims();
|
|
@@ -3,18 +3,18 @@ import { createRequire as __cejelCreateRequire } from 'node:module';
|
|
|
3
3
|
const require = __cejelCreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
listCejelLlmPackFiles
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-RRPQHEBU.js";
|
|
7
7
|
import {
|
|
8
8
|
execGit
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-2UMHJ23V.js";
|
|
10
10
|
import {
|
|
11
11
|
require_typescript
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-6LVNNJTG.js";
|
|
13
13
|
import {
|
|
14
14
|
__toESM,
|
|
15
15
|
init_esm_shims,
|
|
16
16
|
readRepoText
|
|
17
|
-
} from "../../chunk-
|
|
17
|
+
} from "../../chunk-AWLKQUI4.js";
|
|
18
18
|
|
|
19
19
|
// src/packs/d-series/index.ts
|
|
20
20
|
init_esm_shims();
|
|
@@ -3,15 +3,15 @@ import { createRequire as __cejelCreateRequire } from 'node:module';
|
|
|
3
3
|
const require = __cejelCreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
external_exports
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-AMVP7L26.js";
|
|
7
7
|
import {
|
|
8
8
|
require_typescript
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-6LVNNJTG.js";
|
|
10
10
|
import {
|
|
11
11
|
__toESM,
|
|
12
12
|
init_esm_shims,
|
|
13
13
|
readRepoText
|
|
14
|
-
} from "../../chunk-
|
|
14
|
+
} from "../../chunk-AWLKQUI4.js";
|
|
15
15
|
|
|
16
16
|
// src/packs/decision-contracts/index.ts
|
|
17
17
|
init_esm_shims();
|