@cejel/cejel 0.6.1 → 0.6.2

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
@@ -92,7 +92,7 @@ if (-not $expected -or $actual -ne $expected.ToLowerInvariant()) {
92
92
  ```
93
93
 
94
94
  > **Windows signing status:** `cejel-Windows-x86_64.exe` is intentionally unsigned in
95
- > 0.6.1 and may trigger Microsoft SmartScreen. The release build removes Node's inherited
95
+ > 0.6.2 and may trigger Microsoft SmartScreen. The release build removes Node's inherited
96
96
  > signature before SEA injection and fails unless Windows reports the result as `NotSigned`;
97
97
  > it does not ship an invalid signature. Before running it, verify `SHA256SUMS` and the
98
98
  > GitHub build-provenance attestation. Each binary also has an attached SPDX SBOM (the packages
@@ -116,7 +116,7 @@ docker run --rm --network=none -v "$PWD:/w" -w /w -v "$PWD/cejel:/cejel:ro" debi
116
116
  npx @cejel/cejel@latest .
117
117
  ```
118
118
 
119
- > **Distribution note:** Cejel `0.6.1` is the coordinated release version for npm,
119
+ > **Distribution note:** Cejel `0.6.2` is the coordinated release version for npm,
120
120
  > standalone binaries, Docker/OCI, GitHub Action, Homebrew, and MCP Registry. A GitLab CI
121
121
  > template and Code Quality export live in [`docs/gitlab-ci.md`](./docs/gitlab-ci.md).
122
122
 
@@ -149,11 +149,17 @@ The npm package is scoped as `@cejel/cejel`; its executable remains the short co
149
149
  **GitHub Action** — score every PR and publish the badge:
150
150
 
151
151
  ```yaml
152
+ - uses: actions/checkout@v4
153
+ with:
154
+ fetch-depth: 0 # full history: A2 and B2 read commit history
152
155
  - uses: BargLabs/cejel/action@v1
153
156
  with:
154
157
  min-score: "2.5" # optional: fail the build below this
155
158
  ```
156
159
 
160
+ `actions/checkout` fetches one commit by default. On a shallow clone, A2 and B2 see only that
161
+ commit, and the certificate says so under "History limitations".
162
+
157
163
  For an executed public example that binds a release artifact to the same commit named by its
158
164
  Cejel certificate, see [Certified releases with GitHub build provenance](./docs/certified-release-example.md).
159
165
 
@@ -181,16 +187,16 @@ gh attestation verify ./cejel-Windows-x86_64.exe -R BargLabs/cejel
181
187
  This is cryptographically signed provenance. It is distinct from Apple Developer ID or
182
188
  Microsoft Authenticode code-signing.
183
189
 
184
- **Docker / OCI.** The current container release is `0.6.1`:
190
+ **Docker / OCI.** The current container release is `0.6.2`:
185
191
 
186
192
  ```bash
187
- docker run --rm -i -v "$PWD:/workspace:ro" ghcr.io/barglabs/cejel:0.6.1
193
+ docker run --rm -i -v "$PWD:/workspace:ro" ghcr.io/barglabs/cejel:0.6.2
188
194
  ```
189
195
 
190
196
  The image defaults to `cejel-mcp` over stdio. To use the CLI instead:
191
197
 
192
198
  ```bash
193
- docker run --rm -v "$PWD:/workspace:ro" --entrypoint cejel ghcr.io/barglabs/cejel:0.6.1 .
199
+ docker run --rm -v "$PWD:/workspace:ro" --entrypoint cejel ghcr.io/barglabs/cejel:0.6.2 .
194
200
  ```
195
201
 
196
202
  The OCI image carries an SBOM of its base-image packages, maximum-mode build provenance, and a
@@ -429,11 +435,51 @@ a configurable `min-score` threshold. The scoring step makes no network calls an
429
435
  secrets.
430
436
 
431
437
  ```yaml
438
+ - uses: actions/checkout@v4
439
+ with:
440
+ fetch-depth: 0 # full history: A2 and B2 read commit history
432
441
  - uses: BargLabs/cejel/action@v1
433
442
  with:
434
443
  min-score: '2.5' # optional; omit to never fail the check
435
444
  ```
436
445
 
446
+ Check out with `fetch-depth: 0`: the default depth of 1 truncates the history A2 and B2 read, and
447
+ the certificate then lists a history limitation.
448
+
449
+ ## Use with Claude
450
+
451
+ Cejel ships as a Claude Code plugin in [`plugins/cejel/`](./plugins/cejel/). The plugin gives
452
+ Claude the `scan` tool below, started through `npx` and pinned to this release, plus a
453
+ `cejel-scan` skill. The skill tells Claude when a scan answers the question and how to read the
454
+ certificate. It also tells Claude to present a score as evidence for your own judgment, never as
455
+ an audit or a guarantee.
456
+
457
+ Install it from this repository's marketplace, inside Claude Code:
458
+
459
+ ```text
460
+ /plugin marketplace add BargLabs/cejel
461
+ /plugin install cejel@cejel
462
+ ```
463
+
464
+ From a shell, the same two steps are `claude plugin marketplace add BargLabs/cejel` and
465
+ `claude plugin install cejel@cejel`.
466
+
467
+ Scanning stays offline: the `scan` tool makes no network calls and writes no files. The first
468
+ time the server starts, `npx` fetches the pinned `@cejel/cejel` package from npm. When you name
469
+ a repository that isn't on your machine, Claude asks before cloning it with your `git`. Neither
470
+ fetch is part of the scan.
471
+
472
+ Example prompts that work on a public repository:
473
+
474
+ - "Clone https://github.com/BargLabs/cejel into a temporary folder and give me its Cejel trust
475
+ score."
476
+ - "Scan https://github.com/BargLabs/cejel with Cejel and explain the top findings and the criteria
477
+ they come from."
478
+ - "Run Cejel on https://github.com/BargLabs/cejel and save its trust badge to ./cejel-badge.svg."
479
+
480
+ Support: [GitHub issues](https://github.com/BargLabs/cejel/issues). Privacy policy:
481
+ <https://barglabs.ai/privacy>. Terms: <https://barglabs.ai/terms>.
482
+
437
483
  ## MCP server (for agents)
438
484
 
439
485
  The same package ships a second bin, `cejel-mcp` — a thin MCP (Model Context Protocol)
@@ -521,7 +567,7 @@ The OCI image is an alternative when Docker is the preferred execution boundary.
521
567
  the host path with the repository OpenClaw should allow Cejel to read:
522
568
 
523
569
  ```bash
524
- npx -y openclaw@latest mcp set cejel-oci '{"command":"docker","args":["run","--rm","-i","-v","/absolute/path/to/repo:/workspace:ro","ghcr.io/barglabs/cejel:0.6.1"]}'
570
+ npx -y openclaw@latest mcp set cejel-oci '{"command":"docker","args":["run","--rm","-i","-v","/absolute/path/to/repo:/workspace:ro","ghcr.io/barglabs/cejel:0.6.2"]}'
525
571
  npx -y openclaw@latest mcp doctor cejel-oci --probe
526
572
  ```
527
573
 
@@ -5,7 +5,7 @@ import {
5
5
  deriveProductIdentity,
6
6
  runCejelScan,
7
7
  serializeWitanReport
8
- } from "../chunk-UBU3PP7P.js";
8
+ } from "../chunk-KG62JCJZ.js";
9
9
  import {
10
10
  listCejelLlmPackFiles
11
11
  } from "../chunk-M6YYPJSN.js";
@@ -345,6 +345,10 @@ var WitanReportCommonSchema = external_exports.object({
345
345
  consumedSignals: external_exports.array(WitanConsumedSignalSummarySchema).optional(),
346
346
  archetype: WitanRepoArchetypeSchema.optional(),
347
347
  scanLimitations: external_exports.array(external_exports.string().min(1).max(1e3)).max(16).optional(),
348
+ // Additive-optional (report format 1.5, issue #428): disclosures about the commit history the
349
+ // scan read, such as a shallow clone. Declared, never scored: unlike scanLimitations it gates
350
+ // nothing (no score, abstention, badge or --min-score effect). Absent when history is complete.
351
+ historyLimitations: external_exports.array(external_exports.string().min(1).max(1e3)).max(4).optional(),
348
352
  contentReadSummary: WitanContentReadSummarySchema.optional(),
349
353
  // Additive-optional (report format 1.3): absent means a report produced before this field
350
354
  // existed, never "nothing withheld" — createWitanReport always sets it (possibly to []) on any
@@ -397,7 +401,7 @@ var WitanReportSchema = external_exports.preprocess((value) => {
397
401
  }, StrictWitanReportSchema);
398
402
  var WITAN_ATTESTATION_STATEMENT_TYPE = "https://in-toto.io/Statement/v1";
399
403
  var WITAN_ATTESTATION_PREDICATE_TYPE = "https://cejel.dev/attestations/scan/v1";
400
- var WITAN_REPORT_FORMAT_VERSION = "1.4";
404
+ var WITAN_REPORT_FORMAT_VERSION = "1.5";
401
405
  var WitanAttestationOutcomeSchema = external_exports.discriminatedUnion("status", [
402
406
  external_exports.object({
403
407
  status: external_exports.literal("scored"),
@@ -2179,6 +2183,13 @@ function renderWitanHtmlReport(report, options = {}) {
2179
2183
  ).join("")}</ul>
2180
2184
  </section>` : ""}
2181
2185
 
2186
+ ${(report.historyLimitations?.length ?? 0) > 0 ? `<section class="scan-limitations-section evidence-section" aria-label="History limitations">
2187
+ <h2>History limitations</h2>
2188
+ <ul>${(report.historyLimitations ?? []).map(
2189
+ (limitation) => `<li class="scan-warning"><strong>History limitation</strong><span>${escapeHtml(limitation)}</span></li>`
2190
+ ).join("")}</ul>
2191
+ </section>` : ""}
2192
+
2182
2193
  ${renderContentReadSummary(report)}
2183
2194
 
2184
2195
  <section class="trust-grid" aria-label="Rubric criteria">
@@ -9218,6 +9229,15 @@ function hasEnvPathInGitHistory(repoPath, scanLimitations) {
9218
9229
  // src/witan/public-scan.ts
9219
9230
  init_esm_shims();
9220
9231
 
9232
+ // src/witan/history-depth.ts
9233
+ init_esm_shims();
9234
+ var SHALLOW_HISTORY_LIMITATION = "This repository is a shallow clone (git rev-parse --is-shallow-repository reports true), so its commit history is truncated. A2 (credentials and .env files in earlier commits) and B2 (pull-request merge ratio over recent commits) read history and saw only the commits present; on a full clone their results may differ. Scores are computed exactly as for any other scan. Re-scan a full clone (for actions/checkout, set fetch-depth: 0).";
9235
+ function detectHistoryLimitations(repoPath) {
9236
+ const result = execGit(["rev-parse", "--is-shallow-repository"], { cwd: repoPath });
9237
+ if (!result.ok || result.stdout.trim() !== "true") return void 0;
9238
+ return [SHALLOW_HISTORY_LIMITATION];
9239
+ }
9240
+
9221
9241
  // src/witan/ingest.ts
9222
9242
  init_esm_shims();
9223
9243
  import { lstatSync as lstatSync3, opendirSync, readFileSync as readFileSync4, realpathSync as realpathSync3 } from "fs";
@@ -9755,12 +9775,14 @@ function scoreRepoWithPublicCejel(options) {
9755
9775
  ...options.rubricVersion ? { rubricVersion: options.rubricVersion } : {}
9756
9776
  });
9757
9777
  const inputSignals = resolvePublicIngestSignals(options);
9758
- const report = createWitanReport(
9778
+ const scored = createWitanReport(
9759
9779
  input,
9760
9780
  inputSignals.length > 0 ? inputSignals : void 0,
9761
9781
  void 0,
9762
9782
  options.toolVersion
9763
9783
  );
9784
+ const historyLimitations = detectHistoryLimitations(options.repoPath);
9785
+ const report = historyLimitations ? { ...scored, historyLimitations } : scored;
9764
9786
  if (report.verdict !== "insufficient_source" || !isWitanNoMeasurementAbstention(report)) {
9765
9787
  return report;
9766
9788
  }
@@ -9982,6 +10004,7 @@ function buildWitanCliSummary(report) {
9982
10004
  externalFindingCount: allExternalFindings.length,
9983
10005
  topExternalFindings: allExternalFindings.slice(0, EXTERNAL_FINDINGS_DISPLAY_LIMIT),
9984
10006
  scanLimitations: [...report.scanLimitations ?? []],
10007
+ ...report.historyLimitations?.length ? { historyLimitations: [...report.historyLimitations] } : {},
9985
10008
  ...report.contentReadSummary ? { contentReadSummary: report.contentReadSummary } : {}
9986
10009
  };
9987
10010
  if (report.verdict === "insufficient_source") {