@cejel/cejel 0.1.10 → 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 +8 -4
- package/dist/{chunk-EFOUXVJE.js → chunk-BR2DO4QJ.js} +223 -45
- package/dist/index.js +1 -1
- package/dist/mcp/index.js +1 -1
- package/package.json +12 -10
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,16 +102,17 @@ 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
|
-
docker run --rm -i -v "$PWD:/workspace:ro" ghcr.io/barglabs/cejel:0.
|
|
109
|
+
docker run --rm -i -v "$PWD:/workspace:ro" ghcr.io/barglabs/cejel:0.2.0
|
|
106
110
|
```
|
|
107
111
|
|
|
108
112
|
The image defaults to `cejel-mcp` over stdio. To use the CLI instead:
|
|
109
113
|
|
|
110
114
|
```bash
|
|
111
|
-
docker run --rm -v "$PWD:/workspace:ro" --entrypoint cejel ghcr.io/barglabs/cejel:0.
|
|
115
|
+
docker run --rm -v "$PWD:/workspace:ro" --entrypoint cejel ghcr.io/barglabs/cejel:0.2.0 .
|
|
112
116
|
```
|
|
113
117
|
|
|
114
118
|
The OCI image carries an SBOM, maximum-mode build provenance, and a signed registry
|
|
@@ -4079,8 +4079,7 @@ var WITAN_RUBRIC_VERSION_V5 = "witan-rubric-v5-2026-07-18";
|
|
|
4079
4079
|
var WITAN_RUBRIC_VERSION_V6 = "witan-rubric-v6-2026-07-21";
|
|
4080
4080
|
var WITAN_RUBRIC_VERSION_V7 = "witan-rubric-v7-2026-07-21";
|
|
4081
4081
|
var WITAN_RUBRIC_VERSION_V8 = "witan-rubric-v8-2026-07-21";
|
|
4082
|
-
var
|
|
4083
|
-
var WITAN_RUBRIC_VERSION = WITAN_RUBRIC_VERSION_V9;
|
|
4082
|
+
var WITAN_RUBRIC_VERSION = "witan-rubric-v17-2026-07-24";
|
|
4084
4083
|
var WITAN_TRADING_RUBRIC_VERSION_V0 = "witan-trading-rubric-v0-2026-07-01";
|
|
4085
4084
|
var WITAN_CRITERION_IDS = [
|
|
4086
4085
|
"A1",
|
|
@@ -4369,7 +4368,7 @@ var WitanAttestationStatementSchema = external_exports.object({
|
|
|
4369
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.";
|
|
4370
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.";
|
|
4371
4370
|
function isWitanNoMeasurementAbstention(report) {
|
|
4372
|
-
return report.verdict === "insufficient_source" && report.insufficientSourceReason
|
|
4371
|
+
return report.verdict === "insufficient_source" && report.insufficientSourceReason.startsWith(WITAN_NO_MEASUREMENT_REASON) && report.criteria.every(
|
|
4373
4372
|
({ status }) => status === "not_applicable" || status === "insufficient_data"
|
|
4374
4373
|
);
|
|
4375
4374
|
}
|
|
@@ -5078,7 +5077,7 @@ function stripBom(text) {
|
|
|
5078
5077
|
}
|
|
5079
5078
|
|
|
5080
5079
|
// src/witan/rubric-version.ts
|
|
5081
|
-
var
|
|
5080
|
+
var WITAN_RUBRIC_VERSION_V9 = "witan-rubric-v9-2026-07-22";
|
|
5082
5081
|
var WITAN_RUBRIC_VERSION_V10 = "witan-rubric-v10-2026-07-23";
|
|
5083
5082
|
var WITAN_RUBRIC_VERSION_V11 = "witan-rubric-v11-2026-07-23";
|
|
5084
5083
|
var WITAN_RUBRIC_VERSION_V12 = "witan-rubric-v12-2026-07-23";
|
|
@@ -5087,8 +5086,12 @@ var WITAN_RUBRIC_VERSION_V14 = "witan-rubric-v14-2026-07-23";
|
|
|
5087
5086
|
var WITAN_RUBRIC_VERSION_V15 = "witan-rubric-v15-2026-07-24";
|
|
5088
5087
|
var WITAN_RUBRIC_VERSION_V16 = "witan-rubric-v16-2026-07-24";
|
|
5089
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";
|
|
5090
5090
|
|
|
5091
5091
|
// src/witan/repo-signals.ts
|
|
5092
|
+
function usesV17DetectorClosure(rubricVersion) {
|
|
5093
|
+
return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18;
|
|
5094
|
+
}
|
|
5092
5095
|
function buildWitanInputFromRepo(options) {
|
|
5093
5096
|
assertRepoPathExists(options.repoPath);
|
|
5094
5097
|
const generatedAt = options.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -5097,26 +5100,27 @@ function buildWitanInputFromRepo(options) {
|
|
|
5097
5100
|
const repoFiles = listRepoFiles(options.repoPath);
|
|
5098
5101
|
const inventoryFiles = listRepoInventory(options.repoPath, repoFiles);
|
|
5099
5102
|
const ignoredTargetReason = repoFiles.length === 0 ? explainIgnoredScanTarget(options.repoPath) : void 0;
|
|
5100
|
-
const usesV17Detectors = rubricVersion
|
|
5103
|
+
const usesV17Detectors = usesV17DetectorClosure(rubricVersion);
|
|
5104
|
+
const usesV18NativeRls = rubricVersion === WITAN_RUBRIC_VERSION_V18;
|
|
5101
5105
|
const structuralArchetype = classifyRepoArchetype(inventoryFiles, rubricVersion);
|
|
5102
|
-
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(
|
|
5103
5107
|
options.repoPath,
|
|
5104
5108
|
inventoryFiles,
|
|
5105
5109
|
structuralArchetype,
|
|
5106
5110
|
headSha,
|
|
5107
5111
|
rubricVersion
|
|
5108
5112
|
) : structuralArchetype;
|
|
5109
|
-
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(
|
|
5110
5114
|
options.repoPath,
|
|
5111
5115
|
inventoryFiles,
|
|
5112
5116
|
readableArchetype,
|
|
5113
5117
|
rubricVersion
|
|
5114
5118
|
) : readableArchetype;
|
|
5115
|
-
const usesV8Detectors = rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion ===
|
|
5116
|
-
const usesV33Detectors = rubricVersion ===
|
|
5117
|
-
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
|
|
5118
|
-
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
|
|
5119
|
-
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);
|
|
5120
5124
|
const reviewableSourceProof = usesV17Detectors ? buildReviewableSourceProof(options.repoPath, inventoryFiles, headSha, rubricVersion) : void 0;
|
|
5121
5125
|
const coreSignals = collectRepoSignals(
|
|
5122
5126
|
options.repoPath,
|
|
@@ -5127,6 +5131,7 @@ function buildWitanInputFromRepo(options) {
|
|
|
5127
5131
|
usesV36Detectors,
|
|
5128
5132
|
usesV39Detectors,
|
|
5129
5133
|
usesV47Detectors,
|
|
5134
|
+
usesV18NativeRls,
|
|
5130
5135
|
reviewableSourceProof
|
|
5131
5136
|
);
|
|
5132
5137
|
const archetype = usesV17Detectors && reviewableSourceProof?.passes === true && isV17RescuableAbstention(gatedArchetype.abstentionKind) && coreSignals.some(isMeasuredCriterionSignal) ? {
|
|
@@ -5234,7 +5239,7 @@ var SOURCE_EXTENSION_PATTERN_V10 = new RegExp(
|
|
|
5234
5239
|
"i"
|
|
5235
5240
|
);
|
|
5236
5241
|
function isRecognizedSourcePath(path, rubricVersion = WITAN_RUBRIC_VERSION) {
|
|
5237
|
-
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);
|
|
5238
5243
|
}
|
|
5239
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;
|
|
5240
5245
|
var DOCS_OR_MEDIA_EXTENSION_PATTERN = /\.(md|mdx|rst|png|jpe?g|gif|svg|webp|ico|pdf)$/i;
|
|
@@ -5250,6 +5255,7 @@ var SOURCE_DOMINANCE_RATIO_THRESHOLD_V8 = 0.2;
|
|
|
5250
5255
|
var SOURCE_DOMINANCE_RATIO_THRESHOLD_V9 = 0.8;
|
|
5251
5256
|
var SOURCE_DOMINANCE_RATIO_THRESHOLD_V10 = 0.5;
|
|
5252
5257
|
var SOURCE_DOMINANCE_RATIO_THRESHOLD_V11 = 0.2;
|
|
5258
|
+
var V17_REVIEWABLE_SOURCE_RATABLE_SHARE_THRESHOLD = 0.2;
|
|
5253
5259
|
var GENERATED_SOURCE_MINIMUM = 8;
|
|
5254
5260
|
var GENERATED_SOURCE_RATIO_THRESHOLD = 0.8;
|
|
5255
5261
|
var GENERATED_AUTHORED_MAXIMUM = 3;
|
|
@@ -5293,7 +5299,7 @@ function classifyRepoArchetype(repoFiles, rubricVersion = WITAN_RUBRIC_VERSION)
|
|
|
5293
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}`
|
|
5294
5300
|
};
|
|
5295
5301
|
}
|
|
5296
|
-
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)) {
|
|
5297
5303
|
const authoredSourceFiles = sourceFiles.filter(isAuthoredProductionPath);
|
|
5298
5304
|
const documentationFiles = repoFiles.filter(
|
|
5299
5305
|
(file) => DOCS_OR_MEDIA_EXTENSION_PATTERN.test(file)
|
|
@@ -5311,7 +5317,7 @@ function classifyRepoArchetype(repoFiles, rubricVersion = WITAN_RUBRIC_VERSION)
|
|
|
5311
5317
|
(file) => ARTIFACT_DOMINANCE_EXTENSION_PATTERN.test(file)
|
|
5312
5318
|
);
|
|
5313
5319
|
const materialFiles = authoredSourceFiles.length + artifactFiles.length;
|
|
5314
|
-
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) {
|
|
5315
5321
|
return {
|
|
5316
5322
|
archetype: "binary_only",
|
|
5317
5323
|
sourceFileCount,
|
|
@@ -5338,7 +5344,7 @@ function classifyRepoArchetype(repoFiles, rubricVersion = WITAN_RUBRIC_VERSION)
|
|
|
5338
5344
|
const docsDistributionFiles = repoFiles.filter(
|
|
5339
5345
|
(file) => DOCS_OR_MEDIA_EXTENSION_PATTERN.test(file) || DOC_DISTRIBUTION_COMPANION_PATTERN.test(file)
|
|
5340
5346
|
);
|
|
5341
|
-
if (docsFiles.length > 0 && (docsDistributionFiles.length === totalFileCount || (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)) {
|
|
5342
5348
|
return {
|
|
5343
5349
|
archetype: "docs_only",
|
|
5344
5350
|
sourceFileCount,
|
|
@@ -5457,6 +5463,23 @@ function isRepresentativeSourceText(contents) {
|
|
|
5457
5463
|
function representativeSourceRank(rankKey, file) {
|
|
5458
5464
|
return createHash2("sha256").update(`${rankKey}:${file}`).digest("hex");
|
|
5459
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
|
+
}
|
|
5460
5483
|
function buildReviewableSourceProof(repoPath, repoFiles, headSha, rubricVersion) {
|
|
5461
5484
|
const sourceShapedFiles = repoFiles.filter(
|
|
5462
5485
|
(path) => isRecognizedSourcePath(path, rubricVersion) || isUnrecognisedSourcePath(path, rubricVersion) || /\.ipynb$/i.test(path)
|
|
@@ -5481,7 +5504,7 @@ function buildReviewableSourceProof(repoPath, repoFiles, headSha, rubricVersion)
|
|
|
5481
5504
|
sampledFileCount: sample.length,
|
|
5482
5505
|
readableSampledFileCount: readablePaths.length,
|
|
5483
5506
|
...readablePaths[0] ? { firstReadablePath: readablePaths[0] } : {},
|
|
5484
|
-
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)
|
|
5485
5508
|
};
|
|
5486
5509
|
}
|
|
5487
5510
|
function applyReadableSourceRepresentationGate(repoPath, repoFiles, classification, headSha, rubricVersion) {
|
|
@@ -5623,11 +5646,11 @@ function readRepresentativeSourceText(repoPath, file) {
|
|
|
5623
5646
|
}
|
|
5624
5647
|
}
|
|
5625
5648
|
function sourceDominanceThreshold(rubricVersion) {
|
|
5626
|
-
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)) {
|
|
5627
5650
|
return SOURCE_DOMINANCE_RATIO_THRESHOLD_V11;
|
|
5628
5651
|
}
|
|
5629
5652
|
if (rubricVersion === WITAN_RUBRIC_VERSION_V10) return SOURCE_DOMINANCE_RATIO_THRESHOLD_V10;
|
|
5630
|
-
if (rubricVersion ===
|
|
5653
|
+
if (rubricVersion === WITAN_RUBRIC_VERSION_V9) return SOURCE_DOMINANCE_RATIO_THRESHOLD_V9;
|
|
5631
5654
|
return SOURCE_DOMINANCE_RATIO_THRESHOLD_V8;
|
|
5632
5655
|
}
|
|
5633
5656
|
function collectUnrecognisedSourceFiles(repoFiles, rubricVersion) {
|
|
@@ -5637,7 +5660,7 @@ function isUnrecognisedSourcePath(file, rubricVersion = WITAN_RUBRIC_VERSION) {
|
|
|
5637
5660
|
const base = basename(file);
|
|
5638
5661
|
if (!/\.([a-zA-Z0-9_]+)$/.test(base)) return false;
|
|
5639
5662
|
if (KNOWN_NON_SOURCE_EXTENSION_PATTERN.test(base)) return false;
|
|
5640
|
-
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)) {
|
|
5641
5664
|
return false;
|
|
5642
5665
|
}
|
|
5643
5666
|
if (DOCS_OR_MEDIA_EXTENSION_PATTERN.test(base)) return false;
|
|
@@ -5723,7 +5746,7 @@ function buildNotApplicableSignal(criterionId, reason) {
|
|
|
5723
5746
|
notApplicable: true
|
|
5724
5747
|
};
|
|
5725
5748
|
}
|
|
5726
|
-
function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, reviewableSourceProof) {
|
|
5749
|
+
function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, useV18NativeRls, reviewableSourceProof) {
|
|
5727
5750
|
const signals = [];
|
|
5728
5751
|
const mono = resolveMonorepoContext(repoPath);
|
|
5729
5752
|
const a1Signal = collectA1TestIntegrityEvidence(
|
|
@@ -5741,7 +5764,8 @@ function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, u
|
|
|
5741
5764
|
useV33Detectors,
|
|
5742
5765
|
useV36Detectors,
|
|
5743
5766
|
useV39Detectors,
|
|
5744
|
-
useV47Detectors
|
|
5767
|
+
useV47Detectors,
|
|
5768
|
+
useV18NativeRls
|
|
5745
5769
|
);
|
|
5746
5770
|
const a3Signal = collectA3ProdReadinessEvidence(repoPath, repoFiles, useV27Detectors);
|
|
5747
5771
|
const a4Signal = collectA4DependencyEvidence(
|
|
@@ -6033,7 +6057,7 @@ function buildA1AuthenticatedAbsenceSignal(repoPath, proof) {
|
|
|
6033
6057
|
notes: `V17 authenticated absence: ${proof.eligibleSourceFileCount} criterion-ratable of ${proof.sourceShapedFileCount} source-shaped files; sampled ${proof.sampledFileCount}; ${proof.readableSampledFileCount} representative-text files.`
|
|
6034
6058
|
};
|
|
6035
6059
|
}
|
|
6036
|
-
function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors) {
|
|
6060
|
+
function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, useV18NativeRls) {
|
|
6037
6061
|
const evidence = [];
|
|
6038
6062
|
const findings = [];
|
|
6039
6063
|
const gitignore = repoFiles.find((file) => basename(file) === ".gitignore");
|
|
@@ -6129,19 +6153,21 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6129
6153
|
evidence.push(evidenceForRelative(repoPath, dbLayerImportFile, "artifact", "DB client import"));
|
|
6130
6154
|
}
|
|
6131
6155
|
const v47RlsPolicyFiles = useV47Detectors ? findRlsPolicyFiles(repoPath, repoFiles) : [];
|
|
6132
|
-
const
|
|
6156
|
+
const nativeRlsInventory = useV18NativeRls ? deriveRlsPolicyScopeInventory(repoPath, repoFiles) : null;
|
|
6157
|
+
const tenantWithoutRlsPremiseFiles = useV18NativeRls ? findTenantStoragePremiseFiles(repoPath, repoFiles) : [];
|
|
6158
|
+
const v47TenantStorageFiles = useV47Detectors && !useV18NativeRls ? findTenantStoragePremiseFiles(repoPath, repoFiles) : [];
|
|
6133
6159
|
const rlsMigration = useV47Detectors ? v47RlsPolicyFiles[0] : migrationFiles.find((file) => fileContains(repoPath, file, RLS_PATTERN));
|
|
6134
6160
|
const tenantScopePattern = useV39Detectors ? TENANT_SCOPE_PATTERN_V11 : useV36Detectors ? TENANT_SCOPE_PATTERN_V10 : TENANT_SCOPE_PATTERN;
|
|
6135
|
-
const tenantScopedFile = useV47Detectors ? v47TenantStorageFiles[0] : migrationFiles.find((file) => fileContains(repoPath, file, tenantScopePattern));
|
|
6136
|
-
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(
|
|
6137
6163
|
repoPath,
|
|
6138
6164
|
migrationFiles,
|
|
6139
6165
|
/create policy|enable row level security|force row level security/gi
|
|
6140
6166
|
);
|
|
6141
|
-
const tenantScopedMigrationFileCount = useV47Detectors ? v47TenantStorageFiles.length : countFilesContaining(repoPath, migrationFiles, tenantScopePattern);
|
|
6167
|
+
const tenantScopedMigrationFileCount = useV18NativeRls ? nativeRlsInventory?.storageFiles.length ?? 0 : useV47Detectors ? v47TenantStorageFiles.length : countFilesContaining(repoPath, migrationFiles, tenantScopePattern);
|
|
6142
6168
|
const gitignoreEnvFile = gitignore && fileContains(repoPath, gitignore, /^\.env(\*|\b)|\.env\./m) ? gitignore : null;
|
|
6143
6169
|
const envHandlingDepth = (envExamples.length > 0 ? 1 : 0) + (gitignoreEnvFile ? 1 : 0) + (countFilesContaining(repoPath, repoFiles.filter(isImplementationFile), ENV_READ_PATTERN) > 0 ? 1 : 0);
|
|
6144
|
-
const isMultiTenant = tenantScopedMigrationFileCount > 0;
|
|
6170
|
+
const isMultiTenant = useV18NativeRls ? (nativeRlsInventory?.policyCount ?? 0) > 0 && (nativeRlsInventory?.scopeIdentifiers.length ?? 0) > 0 : tenantScopedMigrationFileCount > 0;
|
|
6145
6171
|
if (gitignoreEnvFile) {
|
|
6146
6172
|
evidence.push(
|
|
6147
6173
|
evidenceForRelative(repoPath, gitignoreEnvFile, "secret_scan", ".env files are gitignored")
|
|
@@ -6157,7 +6183,12 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6157
6183
|
}
|
|
6158
6184
|
if (tenantScopedFile) {
|
|
6159
6185
|
evidence.push(
|
|
6160
|
-
evidenceForRelative(
|
|
6186
|
+
evidenceForRelative(
|
|
6187
|
+
repoPath,
|
|
6188
|
+
tenantScopedFile,
|
|
6189
|
+
"artifact",
|
|
6190
|
+
useV18NativeRls ? `Repository-native RLS scope (${nativeRlsInventory?.scopeIdentifiers.join(", ")})` : "Tenant scoping signal"
|
|
6191
|
+
)
|
|
6161
6192
|
);
|
|
6162
6193
|
}
|
|
6163
6194
|
if (committedSecret) {
|
|
@@ -6215,8 +6246,9 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6215
6246
|
evidence: historySecretScan.envPathEvidence
|
|
6216
6247
|
});
|
|
6217
6248
|
}
|
|
6218
|
-
|
|
6219
|
-
|
|
6249
|
+
const hasTenantWithoutRlsGap = rlsPolicyCount === 0 && (useV18NativeRls ? tenantWithoutRlsPremiseFiles.length > 0 : isMultiTenant);
|
|
6250
|
+
if (hasTenantWithoutRlsGap) {
|
|
6251
|
+
const gapEvidence = rlsMigration ?? tenantScopedFile ?? tenantWithoutRlsPremiseFiles[0];
|
|
6220
6252
|
if (gapEvidence) {
|
|
6221
6253
|
findings.push({
|
|
6222
6254
|
severity: "warning",
|
|
@@ -6259,20 +6291,20 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6259
6291
|
"rls_policy_count",
|
|
6260
6292
|
"RLS policy count",
|
|
6261
6293
|
rlsPolicyCount,
|
|
6262
|
-
Math.max(tenantScopedMigrationFileCount * 3, 3),
|
|
6294
|
+
useV18NativeRls ? Math.max(tenantScopedMigrationFileCount, 1) : Math.max(tenantScopedMigrationFileCount * 3, 3),
|
|
6263
6295
|
0.4,
|
|
6264
6296
|
"policies",
|
|
6265
|
-
"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.",
|
|
6266
6298
|
"saturating_count"
|
|
6267
6299
|
),
|
|
6268
6300
|
metric(
|
|
6269
6301
|
"tenant_scope_ratio",
|
|
6270
6302
|
"Tenant-scoped schema ratio",
|
|
6271
|
-
countFilesContaining(repoPath, migrationFiles, tenantScopePattern),
|
|
6303
|
+
useV18NativeRls ? tenantScopedMigrationFileCount : countFilesContaining(repoPath, migrationFiles, tenantScopePattern),
|
|
6272
6304
|
Math.max(migrationFiles.length, 1),
|
|
6273
6305
|
0.25,
|
|
6274
6306
|
"ratio",
|
|
6275
|
-
"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."
|
|
6276
6308
|
)
|
|
6277
6309
|
] : [];
|
|
6278
6310
|
const cryptoMetrics = cryptoHygiene.hasSurface ? [
|
|
@@ -6291,7 +6323,7 @@ function collectA2IsolationEvidence(repoPath, repoFiles, useV27Detectors, useV33
|
|
|
6291
6323
|
positiveEvidence: evidence,
|
|
6292
6324
|
findings,
|
|
6293
6325
|
metrics: [...baseMetrics, ...isolationMetrics, ...cryptoMetrics],
|
|
6294
|
-
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."
|
|
6295
6327
|
};
|
|
6296
6328
|
}
|
|
6297
6329
|
function collectCryptoHygieneEvidence(repoPath, implFiles, useV39Detectors = false) {
|
|
@@ -7187,7 +7219,7 @@ var TEST_DIRECTORY_SOURCE_PATTERN_V17 = new RegExp(
|
|
|
7187
7219
|
"i"
|
|
7188
7220
|
);
|
|
7189
7221
|
function isTestFile(file, rubricVersion = WITAN_RUBRIC_VERSION) {
|
|
7190
|
-
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.
|
|
7191
7223
|
// Keep this root-anchored: nested files need an existing test-directory/suffix convention.
|
|
7192
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);
|
|
7193
7225
|
}
|
|
@@ -7858,6 +7890,138 @@ function findRlsPolicyFiles(repoPath, repoFiles) {
|
|
|
7858
7890
|
)
|
|
7859
7891
|
);
|
|
7860
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
|
+
}
|
|
7861
8025
|
function findDeployableServicePremiseFiles(repoPath, repoFiles, strictOperationalBoundary = false) {
|
|
7862
8026
|
const explicitTargets = repoFiles.filter(
|
|
7863
8027
|
(file) => isAuthoredProductionPath(file) && isExplicitDeployTarget(file) && (!strictOperationalBoundary || isV47OperationalApplicationPath(file))
|
|
@@ -9606,6 +9770,9 @@ var WITAN_RUBRIC = [
|
|
|
9606
9770
|
];
|
|
9607
9771
|
|
|
9608
9772
|
// src/witan/scoring.ts
|
|
9773
|
+
function usesV17DetectorClosure2(rubricVersion) {
|
|
9774
|
+
return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18;
|
|
9775
|
+
}
|
|
9609
9776
|
var MAX_SIGNAL_ADJUSTMENT = 0.8;
|
|
9610
9777
|
function createWitanReport(input, inputSignals, rubric = WITAN_RUBRIC) {
|
|
9611
9778
|
const parsedInput = WitanReportInputSchema.parse(input);
|
|
@@ -9689,7 +9856,7 @@ function createWitanReport(input, inputSignals, rubric = WITAN_RUBRIC) {
|
|
|
9689
9856
|
const isFreeCoreRubric = rubric.length === WITAN_RUBRIC.length && rubric.every(
|
|
9690
9857
|
({ id, category }, index) => id === WITAN_RUBRIC[index]?.id && category === WITAN_RUBRIC[index]?.category
|
|
9691
9858
|
);
|
|
9692
|
-
const noMeasurementAbstention = (parsedInput.rubricVersion === WITAN_RUBRIC_VERSION_V16 || parsedInput.rubricVersion
|
|
9859
|
+
const noMeasurementAbstention = (parsedInput.rubricVersion === WITAN_RUBRIC_VERSION_V16 || usesV17DetectorClosure2(parsedInput.rubricVersion)) && isFreeCoreRubric && !hasMeasuredCriterion;
|
|
9693
9860
|
const insufficientSourceReason = parsedInput.insufficientSourceReason ?? (noMeasurementAbstention ? WITAN_NO_MEASUREMENT_REASON : void 0);
|
|
9694
9861
|
const abstained = insufficientSourceReason != null;
|
|
9695
9862
|
return WitanReportSchema.parse({
|
|
@@ -9757,7 +9924,7 @@ function statusForScore(score) {
|
|
|
9757
9924
|
}
|
|
9758
9925
|
function statusAfterInputAdjustment(nativeStatus, nativeScore, adjustment, rubricVersion) {
|
|
9759
9926
|
if (adjustment === 0) return nativeStatus;
|
|
9760
|
-
if (rubricVersion !== WITAN_RUBRIC_VERSION_V8 && rubricVersion !==
|
|
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) {
|
|
9761
9928
|
return statusForScore(roundScore(Math.max(0, nativeScore - adjustment)));
|
|
9762
9929
|
}
|
|
9763
9930
|
const statusFloor = {
|
|
@@ -9801,7 +9968,7 @@ function mergeSignalsByCriterion(signals) {
|
|
|
9801
9968
|
return merged;
|
|
9802
9969
|
}
|
|
9803
9970
|
function usesMetricScoring(rubricVersion) {
|
|
9804
|
-
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 ===
|
|
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;
|
|
9805
9972
|
}
|
|
9806
9973
|
function unmeasuredStatus(rubricVersion) {
|
|
9807
9974
|
return rubricVersion === WITAN_TRADING_RUBRIC_VERSION_V0 ? "unverified" : "insufficient_data";
|
|
@@ -9932,7 +10099,7 @@ function scoreMetrics(metrics) {
|
|
|
9932
10099
|
function capScoreForFindings(score, findings, rubricVersion, criterionId) {
|
|
9933
10100
|
if (findings.some((finding) => finding.severity === "critical")) {
|
|
9934
10101
|
const criticalFindings = findings.filter(({ severity }) => severity === "critical");
|
|
9935
|
-
const authenticatedA1Absence = rubricVersion
|
|
10102
|
+
const authenticatedA1Absence = usesV17DetectorClosure2(rubricVersion) && criterionId === "A1" && criticalFindings.length === 1 && criticalFindings[0]?.summary === WITAN_AUTHENTICATED_A1_ABSENCE_SUMMARY;
|
|
9936
10103
|
return authenticatedA1Absence ? Math.min(score, 1.4) : 1.4;
|
|
9937
10104
|
}
|
|
9938
10105
|
if (findings.some((finding) => finding.severity === "warning")) return Math.min(score, 2.4);
|
|
@@ -9941,8 +10108,8 @@ function capScoreForFindings(score, findings, rubricVersion, criterionId) {
|
|
|
9941
10108
|
}
|
|
9942
10109
|
function statusForScoreAndFindings(criterionId, score, findings, metrics, rubricVersion) {
|
|
9943
10110
|
if (findings.some((finding) => finding.severity === "critical")) return "critical";
|
|
9944
|
-
if (rubricVersion === WITAN_RUBRIC_VERSION_V8 || rubricVersion ===
|
|
9945
|
-
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);
|
|
9946
10113
|
if (calibrated && calibrated !== "verified") return calibrated;
|
|
9947
10114
|
if (calibrated === "verified" && !findings.some((finding) => finding.severity === "warning")) {
|
|
9948
10115
|
return "verified";
|
|
@@ -10168,7 +10335,7 @@ function calibratedCriterionStateV11(criterionId, metrics) {
|
|
|
10168
10335
|
return void 0;
|
|
10169
10336
|
}
|
|
10170
10337
|
function ensureFindingsExplainStatus(criterionId, score, status, findings, evidence, rubricVersion) {
|
|
10171
|
-
if (rubricVersion !== WITAN_RUBRIC_VERSION_V8 && rubricVersion !==
|
|
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) {
|
|
10172
10339
|
return [...findings];
|
|
10173
10340
|
}
|
|
10174
10341
|
if (status !== "critical" && status !== "warning") return [...findings];
|
|
@@ -10213,7 +10380,18 @@ function scoreRepoWithPublicCejel(options) {
|
|
|
10213
10380
|
...options.rubricVersion ? { rubricVersion: options.rubricVersion } : {}
|
|
10214
10381
|
});
|
|
10215
10382
|
const inputSignals = resolvePublicIngestSignals(options);
|
|
10216
|
-
|
|
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;
|
|
10217
10395
|
}
|
|
10218
10396
|
function resolvePublicIngestSignals(options) {
|
|
10219
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({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cejel/cejel",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"mcpName": "io.github.BargLabs/cejel",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -44,6 +44,16 @@
|
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=18"
|
|
46
46
|
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsup",
|
|
49
|
+
"build:sea-js": "tsup --config tsup.public-sea.config.ts",
|
|
50
|
+
"validate:distribution": "node scripts/validate-distribution-metadata.mjs",
|
|
51
|
+
"prepublishOnly": "pnpm run build",
|
|
52
|
+
"prepack": "pnpm run build",
|
|
53
|
+
"dev": "tsx src/index.ts",
|
|
54
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
55
|
+
"test": "vitest run"
|
|
56
|
+
},
|
|
47
57
|
"devDependencies": {
|
|
48
58
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
49
59
|
"@types/node": "^25.9.1",
|
|
@@ -53,13 +63,5 @@
|
|
|
53
63
|
"typescript": "^5.5.0",
|
|
54
64
|
"vitest": "^2.0.0",
|
|
55
65
|
"zod": "^3.23.0"
|
|
56
|
-
},
|
|
57
|
-
"scripts": {
|
|
58
|
-
"build": "tsup",
|
|
59
|
-
"build:sea-js": "tsup --config tsup.public-sea.config.ts",
|
|
60
|
-
"validate:distribution": "node scripts/validate-distribution-metadata.mjs",
|
|
61
|
-
"dev": "tsx src/index.ts",
|
|
62
|
-
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
63
|
-
"test": "vitest run"
|
|
64
66
|
}
|
|
65
|
-
}
|
|
67
|
+
}
|