@cejel/cejel 0.2.0 → 0.2.1
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 +6 -2
- package/dist/{chunk-PYI3OIBW.js → chunk-BR2DO4QJ.js} +220 -41
- package/dist/index.js +1 -1
- package/dist/mcp/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,10 @@ certificate + badge over all of them. See "Aggregate your scanners" below.
|
|
|
18
18
|
|
|
19
19
|
> Dogfooded in production. Cejel is run continuously on Barg Labs' own multi-product
|
|
20
20
|
> monorepo — the ten-product studio it was built inside — which it currently scores
|
|
21
|
-
> 3.
|
|
21
|
+
> 3.3/4.0 on its rubric-native certificate. That transparency snapshot opts into prospective
|
|
22
|
+
> v18; the public CLI default remains calibrated v17. On the comparative board, our code sits
|
|
23
|
+
> outside the ranked population and receives no verdict band. We score ourselves before
|
|
24
|
+
> asking you to score yourself.
|
|
22
25
|
|
|
23
26
|
## Install
|
|
24
27
|
|
|
@@ -99,7 +102,8 @@ gh attestation verify ./cejel-Darwin-arm64 -R BargLabs/cejel
|
|
|
99
102
|
This is cryptographically signed provenance. It is distinct from Apple Developer ID or
|
|
100
103
|
Microsoft Authenticode code-signing.
|
|
101
104
|
|
|
102
|
-
**Docker / OCI.** The
|
|
105
|
+
**Docker / OCI.** The current container release is `0.2.0` (container releases are
|
|
106
|
+
versioned independently from npm-only patches):
|
|
103
107
|
|
|
104
108
|
```bash
|
|
105
109
|
docker run --rm -i -v "$PWD:/workspace:ro" ghcr.io/barglabs/cejel:0.2.0
|
|
@@ -4368,7 +4368,7 @@ var WitanAttestationStatementSchema = external_exports.object({
|
|
|
4368
4368
|
var WITAN_NO_MEASUREMENT_REASON = "No free-core rubric criterion produced a measurable signal. Cejel abstains rather than publish a numeric zero for an entirely unmeasured repository.";
|
|
4369
4369
|
var WITAN_AUTHENTICATED_A1_ABSENCE_SUMMARY = "Reviewable source is present, but the complete tracked inventory contains no concrete test file, configured test runner, CI test command, or coverage configuration.";
|
|
4370
4370
|
function isWitanNoMeasurementAbstention(report) {
|
|
4371
|
-
return report.verdict === "insufficient_source" && report.insufficientSourceReason
|
|
4371
|
+
return report.verdict === "insufficient_source" && report.insufficientSourceReason.startsWith(WITAN_NO_MEASUREMENT_REASON) && report.criteria.every(
|
|
4372
4372
|
({ status }) => status === "not_applicable" || status === "insufficient_data"
|
|
4373
4373
|
);
|
|
4374
4374
|
}
|
|
@@ -5086,8 +5086,12 @@ var WITAN_RUBRIC_VERSION_V14 = "witan-rubric-v14-2026-07-23";
|
|
|
5086
5086
|
var WITAN_RUBRIC_VERSION_V15 = "witan-rubric-v15-2026-07-24";
|
|
5087
5087
|
var WITAN_RUBRIC_VERSION_V16 = "witan-rubric-v16-2026-07-24";
|
|
5088
5088
|
var WITAN_RUBRIC_VERSION_V17 = "witan-rubric-v17-2026-07-24";
|
|
5089
|
+
var WITAN_RUBRIC_VERSION_V18 = "witan-rubric-v18-prospective-2026-07-25";
|
|
5089
5090
|
|
|
5090
5091
|
// src/witan/repo-signals.ts
|
|
5092
|
+
function usesV17DetectorClosure(rubricVersion) {
|
|
5093
|
+
return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18;
|
|
5094
|
+
}
|
|
5091
5095
|
function buildWitanInputFromRepo(options) {
|
|
5092
5096
|
assertRepoPathExists(options.repoPath);
|
|
5093
5097
|
const generatedAt = options.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -5096,26 +5100,27 @@ function buildWitanInputFromRepo(options) {
|
|
|
5096
5100
|
const repoFiles = listRepoFiles(options.repoPath);
|
|
5097
5101
|
const inventoryFiles = listRepoInventory(options.repoPath, repoFiles);
|
|
5098
5102
|
const ignoredTargetReason = repoFiles.length === 0 ? explainIgnoredScanTarget(options.repoPath) : void 0;
|
|
5099
|
-
const usesV17Detectors = rubricVersion
|
|
5103
|
+
const usesV17Detectors = usesV17DetectorClosure(rubricVersion);
|
|
5104
|
+
const usesV18NativeRls = rubricVersion === WITAN_RUBRIC_VERSION_V18;
|
|
5100
5105
|
const structuralArchetype = classifyRepoArchetype(inventoryFiles, rubricVersion);
|
|
5101
|
-
const readableArchetype = rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5106
|
+
const readableArchetype = rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion) ? applyReadableSourceRepresentationGate(
|
|
5102
5107
|
options.repoPath,
|
|
5103
5108
|
inventoryFiles,
|
|
5104
5109
|
structuralArchetype,
|
|
5105
5110
|
headSha,
|
|
5106
5111
|
rubricVersion
|
|
5107
5112
|
) : structuralArchetype;
|
|
5108
|
-
const gatedArchetype = rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5113
|
+
const gatedArchetype = rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion) ? applySemanticSourceRepresentationGate(
|
|
5109
5114
|
options.repoPath,
|
|
5110
5115
|
inventoryFiles,
|
|
5111
5116
|
readableArchetype,
|
|
5112
5117
|
rubricVersion
|
|
5113
5118
|
) : readableArchetype;
|
|
5114
|
-
const usesV8Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5115
|
-
const usesV33Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5116
|
-
const usesV36Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5117
|
-
const usesV39Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5118
|
-
const usesV47Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5119
|
+
const usesV8Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion);
|
|
5120
|
+
const usesV33Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion);
|
|
5121
|
+
const usesV36Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion);
|
|
5122
|
+
const usesV39Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion);
|
|
5123
|
+
const usesV47Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion);
|
|
5119
5124
|
const reviewableSourceProof = usesV17Detectors ? buildReviewableSourceProof(options.repoPath, inventoryFiles, headSha, rubricVersion) : void 0;
|
|
5120
5125
|
const coreSignals = collectRepoSignals(
|
|
5121
5126
|
options.repoPath,
|
|
@@ -5126,6 +5131,7 @@ function buildWitanInputFromRepo(options) {
|
|
|
5126
5131
|
usesV36Detectors,
|
|
5127
5132
|
usesV39Detectors,
|
|
5128
5133
|
usesV47Detectors,
|
|
5134
|
+
usesV18NativeRls,
|
|
5129
5135
|
reviewableSourceProof
|
|
5130
5136
|
);
|
|
5131
5137
|
const archetype = usesV17Detectors && reviewableSourceProof?.passes === true && isV17RescuableAbstention(gatedArchetype.abstentionKind) && coreSignals.some(isMeasuredCriterionSignal) ? {
|
|
@@ -5233,7 +5239,7 @@ var SOURCE_EXTENSION_PATTERN_V10 = new RegExp(
|
|
|
5233
5239
|
"i"
|
|
5234
5240
|
);
|
|
5235
5241
|
function isRecognizedSourcePath(path, rubricVersion = WITAN_RUBRIC_VERSION) {
|
|
5236
|
-
return (rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5242
|
+
return (rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion) ? SOURCE_EXTENSION_PATTERN_V10 : SOURCE_EXTENSION_PATTERN).test(path);
|
|
5237
5243
|
}
|
|
5238
5244
|
var BUNDLED_BINARY_EXTENSION_PATTERN = /\.(vsix|zip|tgz|whl|exe|dmg|pkg|msi|jar|war|apk|ipa|dll|dylib|ttf|otf|woff2?|eot|eps)$/i;
|
|
5239
5245
|
var DOCS_OR_MEDIA_EXTENSION_PATTERN = /\.(md|mdx|rst|png|jpe?g|gif|svg|webp|ico|pdf)$/i;
|
|
@@ -5249,6 +5255,7 @@ var SOURCE_DOMINANCE_RATIO_THRESHOLD_V8 = 0.2;
|
|
|
5249
5255
|
var SOURCE_DOMINANCE_RATIO_THRESHOLD_V9 = 0.8;
|
|
5250
5256
|
var SOURCE_DOMINANCE_RATIO_THRESHOLD_V10 = 0.5;
|
|
5251
5257
|
var SOURCE_DOMINANCE_RATIO_THRESHOLD_V11 = 0.2;
|
|
5258
|
+
var V17_REVIEWABLE_SOURCE_RATABLE_SHARE_THRESHOLD = 0.2;
|
|
5252
5259
|
var GENERATED_SOURCE_MINIMUM = 8;
|
|
5253
5260
|
var GENERATED_SOURCE_RATIO_THRESHOLD = 0.8;
|
|
5254
5261
|
var GENERATED_AUTHORED_MAXIMUM = 3;
|
|
@@ -5292,7 +5299,7 @@ function classifyRepoArchetype(repoFiles, rubricVersion = WITAN_RUBRIC_VERSION)
|
|
|
5292
5299
|
insufficientSourceReason: `${catalogSourceFiles.length} of ${sourceFileCount} source-shaped file(s) are under independent solution, exercise, challenge, or algorithm catalog paths; only ${sourceFileCount - catalogSourceFiles.length} source-shaped file(s) remain outside that catalog. Cejel abstains because the repository does not expose one cohesive product implementation to score. ${INGEST_POINTER}`
|
|
5293
5300
|
};
|
|
5294
5301
|
}
|
|
5295
|
-
if (rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5302
|
+
if (rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion)) {
|
|
5296
5303
|
const authoredSourceFiles = sourceFiles.filter(isAuthoredProductionPath);
|
|
5297
5304
|
const documentationFiles = repoFiles.filter(
|
|
5298
5305
|
(file) => DOCS_OR_MEDIA_EXTENSION_PATTERN.test(file)
|
|
@@ -5310,7 +5317,7 @@ function classifyRepoArchetype(repoFiles, rubricVersion = WITAN_RUBRIC_VERSION)
|
|
|
5310
5317
|
(file) => ARTIFACT_DOMINANCE_EXTENSION_PATTERN.test(file)
|
|
5311
5318
|
);
|
|
5312
5319
|
const materialFiles = authoredSourceFiles.length + artifactFiles.length;
|
|
5313
|
-
if (artifactFiles.length >= 10 && (authoredSourceFiles.length <= 10 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5320
|
+
if (artifactFiles.length >= 10 && (authoredSourceFiles.length <= 10 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion)) && materialFiles > 0 && authoredSourceFiles.length / materialFiles <= 0.1) {
|
|
5314
5321
|
return {
|
|
5315
5322
|
archetype: "binary_only",
|
|
5316
5323
|
sourceFileCount,
|
|
@@ -5337,7 +5344,7 @@ function classifyRepoArchetype(repoFiles, rubricVersion = WITAN_RUBRIC_VERSION)
|
|
|
5337
5344
|
const docsDistributionFiles = repoFiles.filter(
|
|
5338
5345
|
(file) => DOCS_OR_MEDIA_EXTENSION_PATTERN.test(file) || DOC_DISTRIBUTION_COMPANION_PATTERN.test(file)
|
|
5339
5346
|
);
|
|
5340
|
-
if (docsFiles.length > 0 && (docsDistributionFiles.length === totalFileCount || (rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5347
|
+
if (docsFiles.length > 0 && (docsDistributionFiles.length === totalFileCount || (rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion)) && unrecognisedSourceFiles.length === 0)) {
|
|
5341
5348
|
return {
|
|
5342
5349
|
archetype: "docs_only",
|
|
5343
5350
|
sourceFileCount,
|
|
@@ -5456,6 +5463,23 @@ function isRepresentativeSourceText(contents) {
|
|
|
5456
5463
|
function representativeSourceRank(rankKey, file) {
|
|
5457
5464
|
return createHash2("sha256").update(`${rankKey}:${file}`).digest("hex");
|
|
5458
5465
|
}
|
|
5466
|
+
function explainNoMeasurementSourceCoverage(repoPath, rubricVersion) {
|
|
5467
|
+
if (!usesV17DetectorClosure(rubricVersion)) return void 0;
|
|
5468
|
+
const repoFiles = listRepoFiles(repoPath);
|
|
5469
|
+
const inventoryFiles = listRepoInventory(repoPath, repoFiles);
|
|
5470
|
+
const proof = buildReviewableSourceProof(
|
|
5471
|
+
repoPath,
|
|
5472
|
+
inventoryFiles,
|
|
5473
|
+
readGitHead(repoPath),
|
|
5474
|
+
rubricVersion
|
|
5475
|
+
);
|
|
5476
|
+
if (proof.sourceShapedFileCount === 0) return void 0;
|
|
5477
|
+
const ratableShare = proof.eligibleSourceFileCount / proof.sourceShapedFileCount;
|
|
5478
|
+
if (ratableShare >= V17_REVIEWABLE_SOURCE_RATABLE_SHARE_THRESHOLD) return void 0;
|
|
5479
|
+
const ratablePct = (ratableShare * 100).toFixed(1);
|
|
5480
|
+
const thresholdPct = (V17_REVIEWABLE_SOURCE_RATABLE_SHARE_THRESHOLD * 100).toFixed(0);
|
|
5481
|
+
return `${WITAN_NO_MEASUREMENT_REASON} Source coverage: ${proof.eligibleSourceFileCount} of ${proof.sourceShapedFileCount} source-shaped files (${ratablePct}%) are criterion-ratable, below the ${thresholdPct}% reviewable-source threshold (${inventoryFiles.length} tracked files in total).`;
|
|
5482
|
+
}
|
|
5459
5483
|
function buildReviewableSourceProof(repoPath, repoFiles, headSha, rubricVersion) {
|
|
5460
5484
|
const sourceShapedFiles = repoFiles.filter(
|
|
5461
5485
|
(path) => isRecognizedSourcePath(path, rubricVersion) || isUnrecognisedSourcePath(path, rubricVersion) || /\.ipynb$/i.test(path)
|
|
@@ -5480,7 +5504,7 @@ function buildReviewableSourceProof(repoPath, repoFiles, headSha, rubricVersion)
|
|
|
5480
5504
|
sampledFileCount: sample.length,
|
|
5481
5505
|
readableSampledFileCount: readablePaths.length,
|
|
5482
5506
|
...readablePaths[0] ? { firstReadablePath: readablePaths[0] } : {},
|
|
5483
|
-
passes: eligibleSourceFiles.length > 0 && ratableShare >=
|
|
5507
|
+
passes: eligibleSourceFiles.length > 0 && ratableShare >= V17_REVIEWABLE_SOURCE_RATABLE_SHARE_THRESHOLD && readablePaths.length > 0 && (readableShare >= 0.75 || readablePaths.length >= 8)
|
|
5484
5508
|
};
|
|
5485
5509
|
}
|
|
5486
5510
|
function applyReadableSourceRepresentationGate(repoPath, repoFiles, classification, headSha, rubricVersion) {
|
|
@@ -5622,7 +5646,7 @@ function readRepresentativeSourceText(repoPath, file) {
|
|
|
5622
5646
|
}
|
|
5623
5647
|
}
|
|
5624
5648
|
function sourceDominanceThreshold(rubricVersion) {
|
|
5625
|
-
if (rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5649
|
+
if (rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion)) {
|
|
5626
5650
|
return SOURCE_DOMINANCE_RATIO_THRESHOLD_V11;
|
|
5627
5651
|
}
|
|
5628
5652
|
if (rubricVersion === WITAN_RUBRIC_VERSION_V10) return SOURCE_DOMINANCE_RATIO_THRESHOLD_V10;
|
|
@@ -5636,7 +5660,7 @@ function isUnrecognisedSourcePath(file, rubricVersion = WITAN_RUBRIC_VERSION) {
|
|
|
5636
5660
|
const base = basename(file);
|
|
5637
5661
|
if (!/\.([a-zA-Z0-9_]+)$/.test(base)) return false;
|
|
5638
5662
|
if (KNOWN_NON_SOURCE_EXTENSION_PATTERN.test(base)) return false;
|
|
5639
|
-
if ((rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
5663
|
+
if ((rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure(rubricVersion)) && V13_NON_SOURCE_EXTENSION_PATTERN.test(base)) {
|
|
5640
5664
|
return false;
|
|
5641
5665
|
}
|
|
5642
5666
|
if (DOCS_OR_MEDIA_EXTENSION_PATTERN.test(base)) return false;
|
|
@@ -5722,7 +5746,7 @@ function buildNotApplicableSignal(criterionId, reason) {
|
|
|
5722
5746
|
notApplicable: true
|
|
5723
5747
|
};
|
|
5724
5748
|
}
|
|
5725
|
-
function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, reviewableSourceProof) {
|
|
5749
|
+
function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, useV18NativeRls, reviewableSourceProof) {
|
|
5726
5750
|
const signals = [];
|
|
5727
5751
|
const mono = resolveMonorepoContext(repoPath);
|
|
5728
5752
|
const a1Signal = collectA1TestIntegrityEvidence(
|
|
@@ -5740,7 +5764,8 @@ function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, u
|
|
|
5740
5764
|
useV33Detectors,
|
|
5741
5765
|
useV36Detectors,
|
|
5742
5766
|
useV39Detectors,
|
|
5743
|
-
useV47Detectors
|
|
5767
|
+
useV47Detectors,
|
|
5768
|
+
useV18NativeRls
|
|
5744
5769
|
);
|
|
5745
5770
|
const a3Signal = collectA3ProdReadinessEvidence(repoPath, repoFiles, useV27Detectors);
|
|
5746
5771
|
const a4Signal = collectA4DependencyEvidence(
|
|
@@ -6032,7 +6057,7 @@ function buildA1AuthenticatedAbsenceSignal(repoPath, proof) {
|
|
|
6032
6057
|
notes: `V17 authenticated absence: ${proof.eligibleSourceFileCount} criterion-ratable of ${proof.sourceShapedFileCount} source-shaped files; sampled ${proof.sampledFileCount}; ${proof.readableSampledFileCount} representative-text files.`
|
|
6033
6058
|
};
|
|
6034
6059
|
}
|
|
6035
|
-
function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors) {
|
|
6060
|
+
function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, useV18NativeRls) {
|
|
6036
6061
|
const evidence = [];
|
|
6037
6062
|
const findings = [];
|
|
6038
6063
|
const gitignore = repoFiles.find((file) => basename(file) === ".gitignore");
|
|
@@ -6128,19 +6153,21 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6128
6153
|
evidence.push(evidenceForRelative(repoPath, dbLayerImportFile, "artifact", "DB client import"));
|
|
6129
6154
|
}
|
|
6130
6155
|
const v47RlsPolicyFiles = useV47Detectors ? findRlsPolicyFiles(repoPath, repoFiles) : [];
|
|
6131
|
-
const
|
|
6156
|
+
const nativeRlsInventory = useV18NativeRls ? deriveRlsPolicyScopeInventory(repoPath, repoFiles) : null;
|
|
6157
|
+
const tenantWithoutRlsPremiseFiles = useV18NativeRls ? findTenantStoragePremiseFiles(repoPath, repoFiles) : [];
|
|
6158
|
+
const v47TenantStorageFiles = useV47Detectors && !useV18NativeRls ? findTenantStoragePremiseFiles(repoPath, repoFiles) : [];
|
|
6132
6159
|
const rlsMigration = useV47Detectors ? v47RlsPolicyFiles[0] : migrationFiles.find((file) => fileContains(repoPath, file, RLS_PATTERN));
|
|
6133
6160
|
const tenantScopePattern = useV39Detectors ? TENANT_SCOPE_PATTERN_V11 : useV36Detectors ? TENANT_SCOPE_PATTERN_V10 : TENANT_SCOPE_PATTERN;
|
|
6134
|
-
const tenantScopedFile = useV47Detectors ? v47TenantStorageFiles[0] : migrationFiles.find((file) => fileContains(repoPath, file, tenantScopePattern));
|
|
6135
|
-
const rlsPolicyCount = useV47Detectors ? v47RlsPolicyFiles.length : countPatternMatches(
|
|
6161
|
+
const tenantScopedFile = useV18NativeRls ? nativeRlsInventory?.storageFiles[0] : useV47Detectors ? v47TenantStorageFiles[0] : migrationFiles.find((file) => fileContains(repoPath, file, tenantScopePattern));
|
|
6162
|
+
const rlsPolicyCount = useV18NativeRls ? nativeRlsInventory?.policyCount ?? 0 : useV47Detectors ? v47RlsPolicyFiles.length : countPatternMatches(
|
|
6136
6163
|
repoPath,
|
|
6137
6164
|
migrationFiles,
|
|
6138
6165
|
/create policy|enable row level security|force row level security/gi
|
|
6139
6166
|
);
|
|
6140
|
-
const tenantScopedMigrationFileCount = useV47Detectors ? v47TenantStorageFiles.length : countFilesContaining(repoPath, migrationFiles, tenantScopePattern);
|
|
6167
|
+
const tenantScopedMigrationFileCount = useV18NativeRls ? nativeRlsInventory?.storageFiles.length ?? 0 : useV47Detectors ? v47TenantStorageFiles.length : countFilesContaining(repoPath, migrationFiles, tenantScopePattern);
|
|
6141
6168
|
const gitignoreEnvFile = gitignore && fileContains(repoPath, gitignore, /^\.env(\*|\b)|\.env\./m) ? gitignore : null;
|
|
6142
6169
|
const envHandlingDepth = (envExamples.length > 0 ? 1 : 0) + (gitignoreEnvFile ? 1 : 0) + (countFilesContaining(repoPath, repoFiles.filter(isImplementationFile), ENV_READ_PATTERN) > 0 ? 1 : 0);
|
|
6143
|
-
const isMultiTenant = tenantScopedMigrationFileCount > 0;
|
|
6170
|
+
const isMultiTenant = useV18NativeRls ? (nativeRlsInventory?.policyCount ?? 0) > 0 && (nativeRlsInventory?.scopeIdentifiers.length ?? 0) > 0 : tenantScopedMigrationFileCount > 0;
|
|
6144
6171
|
if (gitignoreEnvFile) {
|
|
6145
6172
|
evidence.push(
|
|
6146
6173
|
evidenceForRelative(repoPath, gitignoreEnvFile, "secret_scan", ".env files are gitignored")
|
|
@@ -6156,7 +6183,12 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6156
6183
|
}
|
|
6157
6184
|
if (tenantScopedFile) {
|
|
6158
6185
|
evidence.push(
|
|
6159
|
-
evidenceForRelative(
|
|
6186
|
+
evidenceForRelative(
|
|
6187
|
+
repoPath,
|
|
6188
|
+
tenantScopedFile,
|
|
6189
|
+
"artifact",
|
|
6190
|
+
useV18NativeRls ? `Repository-native RLS scope (${nativeRlsInventory?.scopeIdentifiers.join(", ")})` : "Tenant scoping signal"
|
|
6191
|
+
)
|
|
6160
6192
|
);
|
|
6161
6193
|
}
|
|
6162
6194
|
if (committedSecret) {
|
|
@@ -6214,8 +6246,9 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6214
6246
|
evidence: historySecretScan.envPathEvidence
|
|
6215
6247
|
});
|
|
6216
6248
|
}
|
|
6217
|
-
|
|
6218
|
-
|
|
6249
|
+
const hasTenantWithoutRlsGap = rlsPolicyCount === 0 && (useV18NativeRls ? tenantWithoutRlsPremiseFiles.length > 0 : isMultiTenant);
|
|
6250
|
+
if (hasTenantWithoutRlsGap) {
|
|
6251
|
+
const gapEvidence = rlsMigration ?? tenantScopedFile ?? tenantWithoutRlsPremiseFiles[0];
|
|
6219
6252
|
if (gapEvidence) {
|
|
6220
6253
|
findings.push({
|
|
6221
6254
|
severity: "warning",
|
|
@@ -6258,20 +6291,20 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6258
6291
|
"rls_policy_count",
|
|
6259
6292
|
"RLS policy count",
|
|
6260
6293
|
rlsPolicyCount,
|
|
6261
|
-
Math.max(tenantScopedMigrationFileCount * 3, 3),
|
|
6294
|
+
useV18NativeRls ? Math.max(tenantScopedMigrationFileCount, 1) : Math.max(tenantScopedMigrationFileCount * 3, 3),
|
|
6262
6295
|
0.4,
|
|
6263
6296
|
"policies",
|
|
6264
|
-
"Counts static row-level-security enables, forced-RLS statements, and policy definitions.",
|
|
6297
|
+
useV18NativeRls ? "Counts CREATE POLICY definitions with repository-native USING/WITH CHECK clauses against the repository-native scoped data-layer surface." : "Counts static row-level-security enables, forced-RLS statements, and policy definitions.",
|
|
6265
6298
|
"saturating_count"
|
|
6266
6299
|
),
|
|
6267
6300
|
metric(
|
|
6268
6301
|
"tenant_scope_ratio",
|
|
6269
6302
|
"Tenant-scoped schema ratio",
|
|
6270
|
-
countFilesContaining(repoPath, migrationFiles, tenantScopePattern),
|
|
6303
|
+
useV18NativeRls ? tenantScopedMigrationFileCount : countFilesContaining(repoPath, migrationFiles, tenantScopePattern),
|
|
6271
6304
|
Math.max(migrationFiles.length, 1),
|
|
6272
6305
|
0.25,
|
|
6273
6306
|
"ratio",
|
|
6274
|
-
"Measures tenant/studio/workspace scoping evidence across data-layer files."
|
|
6307
|
+
useV18NativeRls ? `Measures repository-native RLS scope identifiers (${nativeRlsInventory?.scopeIdentifiers.join(", ")}) across data-layer files.` : "Measures tenant/studio/workspace scoping evidence across data-layer files."
|
|
6275
6308
|
)
|
|
6276
6309
|
] : [];
|
|
6277
6310
|
const cryptoMetrics = cryptoHygiene.hasSurface ? [
|
|
@@ -6290,7 +6323,7 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6290
6323
|
positiveEvidence: evidence,
|
|
6291
6324
|
findings,
|
|
6292
6325
|
metrics: [...baseMetrics, ...isolationMetrics, ...cryptoMetrics],
|
|
6293
|
-
notes: "History secret scanning covers all reachable git history for credential-pattern paths unless the explicit credential-blob safety valve is reported."
|
|
6326
|
+
notes: useV18NativeRls ? "History secret scanning covers all reachable git history for credential-pattern paths unless the explicit credential-blob safety valve is reported. Positive multi-tenancy credit is derived only from this repository\u2019s own CREATE POLICY USING/WITH CHECK clauses; no fixed tenant-token vocabulary can create isolation credit. A conservative schema premise is retained only to fail closed when a tenant-shaped schema has zero RLS policies." : "History secret scanning covers all reachable git history for credential-pattern paths unless the explicit credential-blob safety valve is reported."
|
|
6294
6327
|
};
|
|
6295
6328
|
}
|
|
6296
6329
|
function collectCryptoHygieneEvidence(repoPath, implFiles, useV39Detectors = false) {
|
|
@@ -7186,7 +7219,7 @@ var TEST_DIRECTORY_SOURCE_PATTERN_V17 = new RegExp(
|
|
|
7186
7219
|
"i"
|
|
7187
7220
|
);
|
|
7188
7221
|
function isTestFile(file, rubricVersion = WITAN_RUBRIC_VERSION) {
|
|
7189
|
-
return rubricVersion
|
|
7222
|
+
return usesV17DetectorClosure(rubricVersion) && (TEST_DIRECTORY_SOURCE_PATTERN_V17.test(file) || /\.tftest\.hcl$/i.test(file) || /\.bats$/i.test(file) || /(^|\/)test[^/]*\.m$/i.test(file) || /_test\.m$/i.test(file)) || TEST_DIRECTORY_SOURCE_PATTERN.test(file) || // AVA's default discovery includes test.js and test-*.js at the scanned package root.
|
|
7190
7223
|
// Keep this root-anchored: nested files need an existing test-directory/suffix convention.
|
|
7191
7224
|
/^test(?:-[^/]+)?\.[cm]?[jt]sx?$/.test(file) || /\.(test|spec)\.[cm]?[jt]sx?$/.test(file) || /(^|\/)test_.*\.py$/.test(file) || /_test\.go$/.test(file) || /(^|\/)test_.*\.(cpp|cc|cxx)$/.test(file) || /_(test|tests)\.(cpp|cc|cxx)$/.test(file) || /Tests?\.(java|kt)$/.test(file) || /(_test|_spec)\.(rs|rb|php|swift|kt)$/.test(file);
|
|
7192
7225
|
}
|
|
@@ -7857,6 +7890,138 @@ function findRlsPolicyFiles(repoPath, repoFiles) {
|
|
|
7857
7890
|
)
|
|
7858
7891
|
);
|
|
7859
7892
|
}
|
|
7893
|
+
var RLS_CLAUSE_SQL_WORDS = /* @__PURE__ */ new Set([
|
|
7894
|
+
"all",
|
|
7895
|
+
"and",
|
|
7896
|
+
"any",
|
|
7897
|
+
"as",
|
|
7898
|
+
"asc",
|
|
7899
|
+
"between",
|
|
7900
|
+
"by",
|
|
7901
|
+
"case",
|
|
7902
|
+
"cast",
|
|
7903
|
+
"current",
|
|
7904
|
+
"desc",
|
|
7905
|
+
"distinct",
|
|
7906
|
+
"else",
|
|
7907
|
+
"end",
|
|
7908
|
+
"exists",
|
|
7909
|
+
"false",
|
|
7910
|
+
"from",
|
|
7911
|
+
"in",
|
|
7912
|
+
"is",
|
|
7913
|
+
"join",
|
|
7914
|
+
"like",
|
|
7915
|
+
"limit",
|
|
7916
|
+
"not",
|
|
7917
|
+
"null",
|
|
7918
|
+
"on",
|
|
7919
|
+
"or",
|
|
7920
|
+
"order",
|
|
7921
|
+
"select",
|
|
7922
|
+
"then",
|
|
7923
|
+
"text",
|
|
7924
|
+
"true",
|
|
7925
|
+
"uuid",
|
|
7926
|
+
"varchar",
|
|
7927
|
+
"when",
|
|
7928
|
+
"where"
|
|
7929
|
+
]);
|
|
7930
|
+
function extractBalancedSqlClause(statement, keyword) {
|
|
7931
|
+
const clauses = [];
|
|
7932
|
+
const keywordPattern = keyword === "using" ? /\busing\s*\(/gi : /\bwith\s+check\s*\(/gi;
|
|
7933
|
+
for (const match of statement.matchAll(keywordPattern)) {
|
|
7934
|
+
const openingParen = (match.index ?? 0) + match[0].lastIndexOf("(");
|
|
7935
|
+
let depth = 0;
|
|
7936
|
+
let quote = null;
|
|
7937
|
+
for (let index = openingParen; index < statement.length; index += 1) {
|
|
7938
|
+
const character = statement[index];
|
|
7939
|
+
if (quote) {
|
|
7940
|
+
if (character === quote && statement[index - 1] !== "\\") quote = null;
|
|
7941
|
+
continue;
|
|
7942
|
+
}
|
|
7943
|
+
if (character === "'" || character === '"') {
|
|
7944
|
+
quote = character;
|
|
7945
|
+
} else if (character === "(") {
|
|
7946
|
+
depth += 1;
|
|
7947
|
+
} else if (character === ")") {
|
|
7948
|
+
depth -= 1;
|
|
7949
|
+
if (depth === 0) {
|
|
7950
|
+
clauses.push(statement.slice(openingParen + 1, index));
|
|
7951
|
+
break;
|
|
7952
|
+
}
|
|
7953
|
+
}
|
|
7954
|
+
}
|
|
7955
|
+
}
|
|
7956
|
+
return clauses;
|
|
7957
|
+
}
|
|
7958
|
+
function extractRlsScopeIdentifiers(clause) {
|
|
7959
|
+
const scrubbed = clause.replace(/'(?:''|[^'])*'/g, " ").replace(/"(?:""|[^"])*"/g, " ");
|
|
7960
|
+
const identifiers = /* @__PURE__ */ new Set();
|
|
7961
|
+
const identifierPattern = /\b[A-Za-z_][A-Za-z0-9_$]*(?:\.[A-Za-z_][A-Za-z0-9_$]*)*\b/g;
|
|
7962
|
+
for (const match of scrubbed.matchAll(identifierPattern)) {
|
|
7963
|
+
const token = match[0];
|
|
7964
|
+
const segments = token.split(".").map((segment) => segment.toLowerCase());
|
|
7965
|
+
const lastSegment = segments.at(-1);
|
|
7966
|
+
if (!lastSegment || lastSegment.length < 2 || RLS_CLAUSE_SQL_WORDS.has(lastSegment)) continue;
|
|
7967
|
+
if (["app", "auth", "jwt", "request", "session"].includes(segments[0] ?? "")) continue;
|
|
7968
|
+
const remainder = scrubbed.slice((match.index ?? 0) + token.length);
|
|
7969
|
+
if (/^\s*\(/.test(remainder)) continue;
|
|
7970
|
+
if (["auth", "current_setting", "jwt", "pg_catalog", "public", "uid"].includes(lastSegment)) {
|
|
7971
|
+
continue;
|
|
7972
|
+
}
|
|
7973
|
+
identifiers.add(lastSegment);
|
|
7974
|
+
}
|
|
7975
|
+
return [...identifiers].sort();
|
|
7976
|
+
}
|
|
7977
|
+
function deriveRlsPolicyScopeInventory(repoPath, repoFiles) {
|
|
7978
|
+
const candidatePolicyFiles = findRlsPolicyFiles(repoPath, repoFiles);
|
|
7979
|
+
const policyFiles = /* @__PURE__ */ new Set();
|
|
7980
|
+
const scopeIdentifiers = /* @__PURE__ */ new Set();
|
|
7981
|
+
let policyCount = 0;
|
|
7982
|
+
for (const file of candidatePolicyFiles) {
|
|
7983
|
+
let content;
|
|
7984
|
+
try {
|
|
7985
|
+
content = readFileSync(join(repoPath, file), "utf8");
|
|
7986
|
+
} catch {
|
|
7987
|
+
continue;
|
|
7988
|
+
}
|
|
7989
|
+
for (const match of content.matchAll(/\bcreate\s+policy\b[\s\S]*?(?:;|$)/gi)) {
|
|
7990
|
+
const statement = match[0];
|
|
7991
|
+
const clauses = [
|
|
7992
|
+
...extractBalancedSqlClause(statement, "using"),
|
|
7993
|
+
...extractBalancedSqlClause(statement, "with check")
|
|
7994
|
+
];
|
|
7995
|
+
if (clauses.length === 0) continue;
|
|
7996
|
+
policyCount += 1;
|
|
7997
|
+
policyFiles.add(file);
|
|
7998
|
+
for (const clause of clauses) {
|
|
7999
|
+
for (const identifier of extractRlsScopeIdentifiers(clause)) {
|
|
8000
|
+
scopeIdentifiers.add(identifier);
|
|
8001
|
+
}
|
|
8002
|
+
}
|
|
8003
|
+
}
|
|
8004
|
+
}
|
|
8005
|
+
const identifiers = [...scopeIdentifiers].sort();
|
|
8006
|
+
const dataLayerFiles = repoFiles.filter(
|
|
8007
|
+
(file) => /(^|\/)(?:migrations?|drizzle|prisma)\/|\.(?:sql|prisma)$/i.test(file)
|
|
8008
|
+
);
|
|
8009
|
+
const storageFiles = identifiers.length === 0 ? [] : dataLayerFiles.filter(
|
|
8010
|
+
(file) => identifiers.some(
|
|
8011
|
+
(identifier) => fileContains(
|
|
8012
|
+
repoPath,
|
|
8013
|
+
file,
|
|
8014
|
+
new RegExp(`\\b${identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "i")
|
|
8015
|
+
)
|
|
8016
|
+
)
|
|
8017
|
+
);
|
|
8018
|
+
return {
|
|
8019
|
+
policyFiles: [...policyFiles].sort(),
|
|
8020
|
+
policyCount,
|
|
8021
|
+
scopeIdentifiers: identifiers,
|
|
8022
|
+
storageFiles
|
|
8023
|
+
};
|
|
8024
|
+
}
|
|
7860
8025
|
function findDeployableServicePremiseFiles(repoPath, repoFiles, strictOperationalBoundary = false) {
|
|
7861
8026
|
const explicitTargets = repoFiles.filter(
|
|
7862
8027
|
(file) => isAuthoredProductionPath(file) && isExplicitDeployTarget(file) && (!strictOperationalBoundary || isV47OperationalApplicationPath(file))
|
|
@@ -9605,6 +9770,9 @@ var WITAN_RUBRIC = [
|
|
|
9605
9770
|
];
|
|
9606
9771
|
|
|
9607
9772
|
// src/witan/scoring.ts
|
|
9773
|
+
function usesV17DetectorClosure2(rubricVersion) {
|
|
9774
|
+
return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18;
|
|
9775
|
+
}
|
|
9608
9776
|
var MAX_SIGNAL_ADJUSTMENT = 0.8;
|
|
9609
9777
|
function createWitanReport(input, inputSignals, rubric = WITAN_RUBRIC) {
|
|
9610
9778
|
const parsedInput = WitanReportInputSchema.parse(input);
|
|
@@ -9688,7 +9856,7 @@ function createWitanReport(input, inputSignals, rubric = WITAN_RUBRIC) {
|
|
|
9688
9856
|
const isFreeCoreRubric = rubric.length === WITAN_RUBRIC.length && rubric.every(
|
|
9689
9857
|
({ id, category }, index) => id === WITAN_RUBRIC[index]?.id && category === WITAN_RUBRIC[index]?.category
|
|
9690
9858
|
);
|
|
9691
|
-
const noMeasurementAbstention = (parsedInput.rubricVersion === WITAN_RUBRIC_VERSION_V16 || parsedInput.rubricVersion
|
|
9859
|
+
const noMeasurementAbstention = (parsedInput.rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure2(parsedInput.rubricVersion)) && isFreeCoreRubric && !hasMeasuredCriterion;
|
|
9692
9860
|
const insufficientSourceReason = parsedInput.insufficientSourceReason ?? (noMeasurementAbstention ? WITAN_NO_MEASUREMENT_REASON : void 0);
|
|
9693
9861
|
const abstained = insufficientSourceReason != null;
|
|
9694
9862
|
return WitanReportSchema.parse({
|
|
@@ -9756,7 +9924,7 @@ function statusForScore(score) {
|
|
|
9756
9924
|
}
|
|
9757
9925
|
function statusAfterInputAdjustment(nativeStatus, nativeScore, adjustment, rubricVersion) {
|
|
9758
9926
|
if (adjustment === 0) return nativeStatus;
|
|
9759
|
-
if (rubricVersion !== WITAN_RUBRIC_VERSION_V8 && rubricVersion !== WITAN_RUBRIC_VERSION_V9 && rubricVersion !== WITAN_RUBRIC_VERSION_V10 && rubricVersion !== WITAN_RUBRIC_VERSION_V11 && rubricVersion !== WITAN_RUBRIC_VERSION_V12 && rubricVersion !== WITAN_RUBRIC_VERSION_V13 && rubricVersion !== WITAN_RUBRIC_VERSION_V14 && rubricVersion !== WITAN_RUBRIC_VERSION_V15 && rubricVersion !== WITAN_RUBRIC_VERSION_V16 && rubricVersion !== WITAN_RUBRIC_VERSION_V17) {
|
|
9927
|
+
if (rubricVersion !== WITAN_RUBRIC_VERSION_V8 && rubricVersion !== WITAN_RUBRIC_VERSION_V9 && rubricVersion !== WITAN_RUBRIC_VERSION_V10 && rubricVersion !== WITAN_RUBRIC_VERSION_V11 && rubricVersion !== WITAN_RUBRIC_VERSION_V12 && rubricVersion !== WITAN_RUBRIC_VERSION_V13 && rubricVersion !== WITAN_RUBRIC_VERSION_V14 && rubricVersion !== WITAN_RUBRIC_VERSION_V15 && rubricVersion !== WITAN_RUBRIC_VERSION_V16 && rubricVersion !== WITAN_RUBRIC_VERSION_V17 && rubricVersion !== WITAN_RUBRIC_VERSION_V18) {
|
|
9760
9928
|
return statusForScore(roundScore(Math.max(0, nativeScore - adjustment)));
|
|
9761
9929
|
}
|
|
9762
9930
|
const statusFloor = {
|
|
@@ -9800,7 +9968,7 @@ function mergeSignalsByCriterion(signals) {
|
|
|
9800
9968
|
return merged;
|
|
9801
9969
|
}
|
|
9802
9970
|
function usesMetricScoring(rubricVersion) {
|
|
9803
|
-
return rubricVersion === WITAN_RUBRIC_VERSION_V1 || rubricVersion === WITAN_RUBRIC_VERSION_V2 || rubricVersion === WITAN_RUBRIC_VERSION_V3 || rubricVersion === WITAN_RUBRIC_VERSION_V4 || rubricVersion === WITAN_RUBRIC_VERSION_V5 || rubricVersion === WITAN_RUBRIC_VERSION_V6 || rubricVersion === WITAN_RUBRIC_VERSION_V7 || rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_TRADING_RUBRIC_VERSION_V0;
|
|
9971
|
+
return rubricVersion === WITAN_RUBRIC_VERSION_V1 || rubricVersion === WITAN_RUBRIC_VERSION_V2 || rubricVersion === WITAN_RUBRIC_VERSION_V3 || rubricVersion === WITAN_RUBRIC_VERSION_V4 || rubricVersion === WITAN_RUBRIC_VERSION_V5 || rubricVersion === WITAN_RUBRIC_VERSION_V6 || rubricVersion === WITAN_RUBRIC_VERSION_V7 || rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18 || rubricVersion === WITAN_TRADING_RUBRIC_VERSION_V0;
|
|
9804
9972
|
}
|
|
9805
9973
|
function unmeasuredStatus(rubricVersion) {
|
|
9806
9974
|
return rubricVersion === WITAN_TRADING_RUBRIC_VERSION_V0 ? "unverified" : "insufficient_data";
|
|
@@ -9931,7 +10099,7 @@ function scoreMetrics(metrics) {
|
|
|
9931
10099
|
function capScoreForFindings(score, findings, rubricVersion, criterionId) {
|
|
9932
10100
|
if (findings.some((finding) => finding.severity === "critical")) {
|
|
9933
10101
|
const criticalFindings = findings.filter(({ severity }) => severity === "critical");
|
|
9934
|
-
const authenticatedA1Absence = rubricVersion
|
|
10102
|
+
const authenticatedA1Absence = usesV17DetectorClosure2(rubricVersion) && criterionId === "A1" && criticalFindings.length === 1 && criticalFindings[0]?.summary === WITAN_AUTHENTICATED_A1_ABSENCE_SUMMARY;
|
|
9935
10103
|
return authenticatedA1Absence ? Math.min(score, 1.4) : 1.4;
|
|
9936
10104
|
}
|
|
9937
10105
|
if (findings.some((finding) => finding.severity === "warning")) return Math.min(score, 2.4);
|
|
@@ -9940,8 +10108,8 @@ function capScoreForFindings(score, findings, rubricVersion, criterionId) {
|
|
|
9940
10108
|
}
|
|
9941
10109
|
function statusForScoreAndFindings(criterionId, score, findings, metrics, rubricVersion) {
|
|
9942
10110
|
if (findings.some((finding) => finding.severity === "critical")) return "critical";
|
|
9943
|
-
if (rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
9944
|
-
const calibrated = rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || rubricVersion
|
|
10111
|
+
if (rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 || rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure2(rubricVersion)) {
|
|
10112
|
+
const calibrated = rubricVersion === WITAN_RUBRIC_VERSION_V11 || rubricVersion === WITAN_RUBRIC_VERSION_V12 || rubricVersion === WITAN_RUBRIC_VERSION_V13 || rubricVersion === WITAN_RUBRIC_VERSION_V14 || rubricVersion === WITAN_RUBRIC_VERSION_V15 || rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure2(rubricVersion) ? calibratedCriterionStateV11(criterionId, metrics) : rubricVersion === WITAN_RUBRIC_VERSION_V9 || rubricVersion === WITAN_RUBRIC_VERSION_V10 ? calibratedCriterionStateV9(criterionId, metrics) : calibratedCriterionStateV8(criterionId, metrics);
|
|
9945
10113
|
if (calibrated && calibrated !== "verified") return calibrated;
|
|
9946
10114
|
if (calibrated === "verified" && !findings.some((finding) => finding.severity === "warning")) {
|
|
9947
10115
|
return "verified";
|
|
@@ -10167,7 +10335,7 @@ function calibratedCriterionStateV11(criterionId, metrics) {
|
|
|
10167
10335
|
return void 0;
|
|
10168
10336
|
}
|
|
10169
10337
|
function ensureFindingsExplainStatus(criterionId, score, status, findings, evidence, rubricVersion) {
|
|
10170
|
-
if (rubricVersion !== WITAN_RUBRIC_VERSION_V8 && rubricVersion !== WITAN_RUBRIC_VERSION_V9 && rubricVersion !== WITAN_RUBRIC_VERSION_V10 && rubricVersion !== WITAN_RUBRIC_VERSION_V11 && rubricVersion !== WITAN_RUBRIC_VERSION_V12 && rubricVersion !== WITAN_RUBRIC_VERSION_V13 && rubricVersion !== WITAN_RUBRIC_VERSION_V14 && rubricVersion !== WITAN_RUBRIC_VERSION_V15 && rubricVersion !== WITAN_RUBRIC_VERSION_V16 && rubricVersion !== WITAN_RUBRIC_VERSION_V17 && findings.length > 0) {
|
|
10338
|
+
if (rubricVersion !== WITAN_RUBRIC_VERSION_V8 && rubricVersion !== WITAN_RUBRIC_VERSION_V9 && rubricVersion !== WITAN_RUBRIC_VERSION_V10 && rubricVersion !== WITAN_RUBRIC_VERSION_V11 && rubricVersion !== WITAN_RUBRIC_VERSION_V12 && rubricVersion !== WITAN_RUBRIC_VERSION_V13 && rubricVersion !== WITAN_RUBRIC_VERSION_V14 && rubricVersion !== WITAN_RUBRIC_VERSION_V15 && rubricVersion !== WITAN_RUBRIC_VERSION_V16 && rubricVersion !== WITAN_RUBRIC_VERSION_V17 && rubricVersion !== WITAN_RUBRIC_VERSION_V18 && findings.length > 0) {
|
|
10171
10339
|
return [...findings];
|
|
10172
10340
|
}
|
|
10173
10341
|
if (status !== "critical" && status !== "warning") return [...findings];
|
|
@@ -10212,7 +10380,18 @@ function scoreRepoWithPublicCejel(options) {
|
|
|
10212
10380
|
...options.rubricVersion ? { rubricVersion: options.rubricVersion } : {}
|
|
10213
10381
|
});
|
|
10214
10382
|
const inputSignals = resolvePublicIngestSignals(options);
|
|
10215
|
-
|
|
10383
|
+
const report = createWitanReport(input, inputSignals.length > 0 ? inputSignals : void 0);
|
|
10384
|
+
if (report.verdict !== "insufficient_source" || !isWitanNoMeasurementAbstention(report)) {
|
|
10385
|
+
return report;
|
|
10386
|
+
}
|
|
10387
|
+
const contextualReason = explainNoMeasurementSourceCoverage(
|
|
10388
|
+
options.repoPath,
|
|
10389
|
+
report.rubricVersion
|
|
10390
|
+
);
|
|
10391
|
+
return contextualReason ? {
|
|
10392
|
+
...report,
|
|
10393
|
+
insufficientSourceReason: contextualReason
|
|
10394
|
+
} : report;
|
|
10216
10395
|
}
|
|
10217
10396
|
function resolvePublicIngestSignals(options) {
|
|
10218
10397
|
const seen = /* @__PURE__ */ new Set();
|
package/dist/index.js
CHANGED
package/dist/mcp/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
renderWitanBadgeSvg,
|
|
11
11
|
renderWitanHtmlReport,
|
|
12
12
|
runCejelScan
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-BR2DO4QJ.js";
|
|
14
14
|
|
|
15
15
|
// node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js
|
|
16
16
|
var require_code = __commonJS({
|