@cejel/cejel 0.3.2 → 0.4.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 CHANGED
@@ -68,7 +68,7 @@ if (-not $expected -or $actual -ne $expected.ToLowerInvariant()) {
68
68
  ```
69
69
 
70
70
  > **Windows signing status:** `cejel-Windows-x86_64.exe` is intentionally unsigned in
71
- > 0.3.2 and may trigger Microsoft SmartScreen. The release build removes Node's inherited
71
+ > 0.4.1 and may trigger Microsoft SmartScreen. The release build removes Node's inherited
72
72
  > signature before SEA injection and fails unless Windows reports the result as `NotSigned`;
73
73
  > it does not ship an invalid signature. Before running it, verify `SHA256SUMS` and the
74
74
  > GitHub build-provenance attestation. Each binary also has an attached SPDX SBOM and an
@@ -91,7 +91,7 @@ docker run --rm --network=none -v "$PWD:/w" -w /w -v "$PWD/cejel:/cejel:ro" debi
91
91
  npx @cejel/cejel@latest .
92
92
  ```
93
93
 
94
- > **Distribution note:** Cejel `0.3.2` is the coordinated release version for npm,
94
+ > **Distribution note:** Cejel `0.4.1` is the coordinated release version for npm,
95
95
  > standalone binaries, Docker/OCI, GitHub Action, Homebrew, and MCP Registry.
96
96
 
97
97
  `npx` can reuse a stale cached package. Force the current npm release with the `@latest`
@@ -140,16 +140,16 @@ gh attestation verify ./cejel-Windows-x86_64.exe -R BargLabs/cejel
140
140
  This is cryptographically signed provenance. It is distinct from Apple Developer ID or
141
141
  Microsoft Authenticode code-signing.
142
142
 
143
- **Docker / OCI.** The current container release is `0.3.2`:
143
+ **Docker / OCI.** The current container release is `0.4.1`:
144
144
 
145
145
  ```bash
146
- docker run --rm -i -v "$PWD:/workspace:ro" ghcr.io/barglabs/cejel:0.3.2
146
+ docker run --rm -i -v "$PWD:/workspace:ro" ghcr.io/barglabs/cejel:0.4.1
147
147
  ```
148
148
 
149
149
  The image defaults to `cejel-mcp` over stdio. To use the CLI instead:
150
150
 
151
151
  ```bash
152
- docker run --rm -v "$PWD:/workspace:ro" --entrypoint cejel ghcr.io/barglabs/cejel:0.3.2 .
152
+ docker run --rm -v "$PWD:/workspace:ro" --entrypoint cejel ghcr.io/barglabs/cejel:0.4.1 .
153
153
  ```
154
154
 
155
155
  The OCI image carries an SBOM, maximum-mode build provenance, and a signed registry
@@ -426,7 +426,7 @@ The OCI image is an alternative when Docker is the preferred execution boundary.
426
426
  the host path with the repository OpenClaw should allow Cejel to read:
427
427
 
428
428
  ```bash
429
- openclaw mcp set cejel-oci '{"command":"docker","args":["run","--rm","-i","-v","/absolute/path/to/repo:/workspace:ro","ghcr.io/barglabs/cejel:0.3.2"]}'
429
+ openclaw mcp set cejel-oci '{"command":"docker","args":["run","--rm","-i","-v","/absolute/path/to/repo:/workspace:ro","ghcr.io/barglabs/cejel:0.4.1"]}'
430
430
  openclaw mcp doctor cejel-oci --probe
431
431
  ```
432
432
 
@@ -4236,12 +4236,12 @@ var WitanContentReadSummarySchema = external_exports.object({
4236
4236
  }
4237
4237
  });
4238
4238
  var WitanRepoRefSchema = external_exports.object({
4239
+ // Retained for backward-compatible verification of reports emitted through v0.4.0.
4240
+ // New reports omit the checkout path so their bytes are independent of run location.
4239
4241
  path: external_exports.string().min(1).max(700).optional(),
4240
4242
  url: external_exports.string().url().optional(),
4241
4243
  headSha: external_exports.string().min(7).max(64).optional()
4242
- }).strict().refine((value) => Boolean(value.path ?? value.url), {
4243
- message: "Witan repo reference must include a path or url."
4244
- });
4244
+ }).strict();
4245
4245
  var WitanReportInputSchema = external_exports.object({
4246
4246
  productSlug: external_exports.string().regex(/^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/),
4247
4247
  productDisplayName: external_exports.string().min(1).max(120),
@@ -4875,7 +4875,7 @@ function renderPathEvidenceTarget(evidence) {
4875
4875
  return [pathTarget, hashTarget].filter(Boolean).join(" \xB7 ");
4876
4876
  }
4877
4877
  function renderRepo(report) {
4878
- const repo = report.repo.path ?? report.repo.url ?? "unknown";
4878
+ const repo = report.repo.path ?? report.repo.url ?? report.productSlug;
4879
4879
  return report.repo.headSha ? `${repo} @ ${report.repo.headSha}` : repo;
4880
4880
  }
4881
4881
  function renderVerdict(score) {
@@ -5269,10 +5269,11 @@ var WITAN_RUBRIC_VERSION_V15 = "witan-rubric-v15-2026-07-24";
5269
5269
  var WITAN_RUBRIC_VERSION_V16 = "witan-rubric-v16-2026-07-24";
5270
5270
  var WITAN_RUBRIC_VERSION_V17 = "witan-rubric-v17-2026-07-24";
5271
5271
  var WITAN_RUBRIC_VERSION_V18 = "witan-rubric-v18-prospective-2026-07-25";
5272
+ var WITAN_RUBRIC_VERSION_V19 = "witan-rubric-v19-prospective-2026-08-09";
5272
5273
 
5273
5274
  // src/witan/repo-signals.ts
5274
5275
  function usesV17DetectorClosure(rubricVersion) {
5275
- return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18;
5276
+ return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18 || rubricVersion === WITAN_RUBRIC_VERSION_V19;
5276
5277
  }
5277
5278
  function buildWitanInputFromRepo(options) {
5278
5279
  const tracked = trackContentReads(options.repoPath, () => buildWitanInputFromRepoUntracked(options));
@@ -5312,7 +5313,8 @@ function buildWitanInputFromRepoUntracked(options) {
5312
5313
  const inventoryFiles = fileInventory.inventoryFiles;
5313
5314
  const ignoredTargetReason = repoFiles.length === 0 ? explainIgnoredScanTarget(options.repoPath) : void 0;
5314
5315
  const usesV17Detectors = usesV17DetectorClosure(rubricVersion);
5315
- const usesV18NativeRls = rubricVersion === WITAN_RUBRIC_VERSION_V18;
5316
+ const usesV18NativeRls = rubricVersion === WITAN_RUBRIC_VERSION_V18 || rubricVersion === WITAN_RUBRIC_VERSION_V19;
5317
+ const usesV19CommitYear = rubricVersion === WITAN_RUBRIC_VERSION_V19;
5316
5318
  const structuralArchetype = classifyRepoArchetype(inventoryFiles, rubricVersion);
5317
5319
  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(
5318
5320
  options.repoPath,
@@ -5344,6 +5346,7 @@ function buildWitanInputFromRepoUntracked(options) {
5344
5346
  usesV39Detectors,
5345
5347
  usesV47Detectors,
5346
5348
  usesV18NativeRls,
5349
+ usesV19CommitYear,
5347
5350
  reviewableSourceProof,
5348
5351
  scanLimitations
5349
5352
  );
@@ -5356,7 +5359,6 @@ function buildWitanInputFromRepoUntracked(options) {
5356
5359
  productSlug: options.productSlug,
5357
5360
  productDisplayName: options.productDisplayName,
5358
5361
  repo: {
5359
- path: options.repoPath,
5360
5362
  ...headSha ? { headSha } : {}
5361
5363
  },
5362
5364
  generatedAt,
@@ -5952,7 +5954,7 @@ function buildNotApplicableSignal(criterionId, reason) {
5952
5954
  notApplicable: true
5953
5955
  };
5954
5956
  }
5955
- function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, useV18NativeRls, reviewableSourceProof, scanLimitations = /* @__PURE__ */ new Set()) {
5957
+ function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, useV33Detectors, useV36Detectors, useV39Detectors, useV47Detectors, useV18NativeRls, useV19CommitYear, reviewableSourceProof, scanLimitations = /* @__PURE__ */ new Set()) {
5956
5958
  const signals = [];
5957
5959
  const mono = resolveMonorepoContext(repoPath, scanLimitations);
5958
5960
  const collectCriterion = (criterionId, collect) => withContentReadCriterion(criterionId, collect);
@@ -6010,7 +6012,13 @@ function collectRepoSignals(repoPath, generatedAt, repoFiles, useV27Detectors, u
6010
6012
  );
6011
6013
  const b4Signal = collectCriterion(
6012
6014
  "B4",
6013
- () => collectB4AuditEvidence(repoPath, repoFiles, generatedAt)
6015
+ () => collectB4AuditEvidence(
6016
+ repoPath,
6017
+ repoFiles,
6018
+ generatedAt,
6019
+ useV19CommitYear,
6020
+ scanLimitations
6021
+ )
6014
6022
  );
6015
6023
  const b5Signal = buildNotApplicableSignal(
6016
6024
  "B5",
@@ -7214,7 +7222,31 @@ function collectB3CiDisciplineEvidence(repoPath, repoFiles, mono) {
7214
7222
  ]
7215
7223
  };
7216
7224
  }
7217
- function collectB4AuditEvidence(repoPath, repoFiles, generatedAt) {
7225
+ function auditFreshnessCommitterYearFromGitResult(result, scanLimitations) {
7226
+ if (!result.ok) {
7227
+ if (!isExpectedGitAbsence(result)) {
7228
+ scanLimitations.add(
7229
+ `${describeGitFailure(result.reason, "HEAD committer-date discovery")} Cejel omitted the numeric B4 freshness year and retained only static freshness markers.`
7230
+ );
7231
+ }
7232
+ return null;
7233
+ }
7234
+ const year = /^([0-9]{4})-/.exec(result.stdout.trim())?.[1];
7235
+ if (!year) {
7236
+ scanLimitations.add(
7237
+ "Cejel: local git HEAD committer-date discovery returned a malformed date. Cejel omitted the numeric B4 freshness year and retained only static freshness markers."
7238
+ );
7239
+ return null;
7240
+ }
7241
+ return year;
7242
+ }
7243
+ function readAuditFreshnessCommitterYear(repoPath, scanLimitations) {
7244
+ return auditFreshnessCommitterYearFromGitResult(
7245
+ execGit(["show", "-s", "--format=%cI", "HEAD"], { cwd: repoPath }),
7246
+ scanLimitations
7247
+ );
7248
+ }
7249
+ function collectB4AuditEvidence(repoPath, repoFiles, generatedAt, useV19CommitYear = false, scanLimitations = /* @__PURE__ */ new Set()) {
7218
7250
  const evidence = [];
7219
7251
  const auditFiles = repoFiles.filter(isAuditFile);
7220
7252
  for (const file of auditFiles.slice(0, 5)) {
@@ -7233,8 +7265,11 @@ function collectB4AuditEvidence(repoPath, repoFiles, generatedAt) {
7233
7265
  "Only a static security-policy artifact (e.g. SECURITY.md) was detected \u2014 no committed CHANGELOG/CHANGES/HISTORY/NEWS/AUDIT/STATUS/release-notes/runbook/provenance file to rate for an audit trail. The project may publish release history outside the repository (e.g. GitHub Releases). B4 has no ratable surface here; it is excluded rather than scored."
7234
7266
  );
7235
7267
  }
7236
- const runYear = new Date(generatedAt).getFullYear();
7237
- const freshnessPattern = new RegExp(`${runYear}|recent|latest|current`, "i");
7268
+ const referenceYear = useV19CommitYear ? readAuditFreshnessCommitterYear(repoPath, scanLimitations) : String(new Date(generatedAt).getFullYear());
7269
+ const freshnessPattern = new RegExp(
7270
+ `${referenceYear ? `${referenceYear}|` : ""}recent|latest|current`,
7271
+ "i"
7272
+ );
7238
7273
  return {
7239
7274
  criterionId: "B4",
7240
7275
  positiveEvidence: evidence,
@@ -7265,7 +7300,7 @@ function collectB4AuditEvidence(repoPath, repoFiles, generatedAt) {
7265
7300
  Math.max(auditFiles.length, 1),
7266
7301
  0.2,
7267
7302
  "ratio",
7268
- "Credits audit artifacts that carry freshness/current-state markers."
7303
+ useV19CommitYear ? "Credits audit artifacts that carry the scanned HEAD committer year or static freshness/current-state markers." : "Credits audit artifacts that carry freshness/current-state markers."
7269
7304
  )
7270
7305
  ]
7271
7306
  };
@@ -10192,7 +10227,7 @@ var WITAN_RUBRIC = [
10192
10227
 
10193
10228
  // src/witan/scoring.ts
10194
10229
  function usesV17DetectorClosure2(rubricVersion) {
10195
- return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18;
10230
+ return rubricVersion === WITAN_RUBRIC_VERSION_V17 || rubricVersion === WITAN_RUBRIC_VERSION_V18 || rubricVersion === WITAN_RUBRIC_VERSION_V19;
10196
10231
  }
10197
10232
  var MAX_SIGNAL_ADJUSTMENT = 0.8;
10198
10233
  function createWitanReport(input, inputSignals, rubric = WITAN_RUBRIC) {
@@ -10351,7 +10386,7 @@ function statusForScore(score) {
10351
10386
  }
10352
10387
  function statusAfterInputAdjustment(nativeStatus, nativeScore, adjustment, rubricVersion) {
10353
10388
  if (adjustment === 0) return nativeStatus;
10354
- 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) {
10389
+ 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 && rubricVersion !== WITAN_RUBRIC_VERSION_V19) {
10355
10390
  return statusForScore(roundScore(Math.max(0, nativeScore - adjustment)));
10356
10391
  }
10357
10392
  const statusFloor = {
@@ -10396,7 +10431,7 @@ function mergeSignalsByCriterion(signals) {
10396
10431
  return merged;
10397
10432
  }
10398
10433
  function usesMetricScoring(rubricVersion) {
10399
- 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;
10434
+ 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_RUBRIC_VERSION_V19 || rubricVersion === WITAN_TRADING_RUBRIC_VERSION_V0;
10400
10435
  }
10401
10436
  function unmeasuredStatus(rubricVersion) {
10402
10437
  return rubricVersion === WITAN_TRADING_RUBRIC_VERSION_V0 ? "unverified" : "insufficient_data";
@@ -10772,7 +10807,7 @@ function calibratedCriterionStateV11(criterionId, metrics) {
10772
10807
  return void 0;
10773
10808
  }
10774
10809
  function ensureFindingsExplainStatus(criterionId, score, status, findings, evidence, rubricVersion) {
10775
- 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) {
10810
+ 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 && rubricVersion !== WITAN_RUBRIC_VERSION_V19 && findings.length > 0) {
10776
10811
  return [...findings];
10777
10812
  }
10778
10813
  if (status !== "critical" && status !== "warning") return [...findings];
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  runCejelScan,
12
12
  serializeWitanReport,
13
13
  verifyWitanAttestationBinding
14
- } from "./chunk-XB65L6WE.js";
14
+ } from "./chunk-HG5NAFH5.js";
15
15
  import {
16
16
  init_esm_shims
17
17
  } from "./chunk-LZVKQV3R.js";
package/dist/mcp/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  renderWitanBadgeSvg,
10
10
  renderWitanHtmlReport,
11
11
  runCejelScan
12
- } from "../chunk-XB65L6WE.js";
12
+ } from "../chunk-HG5NAFH5.js";
13
13
  import {
14
14
  __commonJS,
15
15
  __export,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cejel/cejel",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "mcpName": "io.github.BargLabs/cejel",
5
5
  "private": false,
6
6
  "publishConfig": {