@cejel/cejel 0.1.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/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ GNU Affero General Public License v3.0 only
2
+
3
+ Copyright (C) 2026 Barg Labs Studios
4
+
5
+ Alfred is licensed under the GNU Affero General Public License version 3.0 only
6
+ (AGPL-3.0-only), unless a file or package states otherwise.
7
+
8
+ You may copy, distribute, and modify covered files under the terms of the GNU
9
+ Affero General Public License version 3.0 as published by the Free Software
10
+ Foundation.
11
+
12
+ The full license text is published by the Free Software Foundation at:
13
+ https://www.gnu.org/licenses/agpl-3.0.txt
14
+
15
+ SPDX-License-Identifier: AGPL-3.0-only
package/README.md ADDED
@@ -0,0 +1,288 @@
1
+ # cejel
2
+
3
+ [![npm version](https://img.shields.io/npm/v/cejel.svg)](https://www.npmjs.com/package/cejel)
4
+ [![license: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](./LICENSE)
5
+
6
+ Cejel (*"SEH-jel"*) — a trust certificate for your codebase.
7
+
8
+ Free, offline, no-signup CLI that scores the engineering signals that tell you whether to
9
+ trust a repo — tests, secrets, isolation, claim-vs-reality, CI/audit discipline — and prints
10
+ a trust certificate + badge. Especially valuable when AI wrote a lot of the code: that's
11
+ exactly when you can't eyeball trust. Built on a deterministic, no-LLM
12
+ scoring core — the free path makes zero network calls and requires no account.
13
+
14
+ Cejel is not another point scanner competing with the one you already run — it's the open,
15
+ portable, offline trust certificate that aggregates them. Pipe in SARIF-compatible output
16
+ (MunaTrust, Snyk, Semgrep, CodeQL, Codex) plus OpenSSF Scorecard, and get one shareable
17
+ certificate + badge over all of them. See "Aggregate your scanners" below.
18
+
19
+ > Dogfooded in production. Cejel is run continuously on Barg Labs' own multi-product
20
+ > monorepo — the ten-product studio it was built inside — which it currently scores
21
+ > 3.1/4.0 ("Conditional"). We score ourselves before asking you to score yourself.
22
+
23
+ ## Leaderboard
24
+
25
+ This repo ships the [Cejel OSS trust leaderboard](./leaderboard/leaderboard.md): the whole
26
+ corpus scored and published in the open — elite OSS projects, Cejel itself, and the private
27
+ studio monorepo Cejel was built inside — with a per-repository evidence report for every
28
+ row under [`leaderboard/reports/`](./leaderboard/reports/). The board is also hosted at
29
+ [cejel.dev](https://cejel.dev). Same deterministic rubric as `npx cejel .`; nobody is
30
+ exempt, including us.
31
+
32
+ ### Redaction policy
33
+
34
+ A path is published exactly when the reader can check it. Every public repository on the
35
+ board cites full evidence paths and line numbers, everywhere, in every artifact — a
36
+ certificate whose evidence you cannot open is not evidence. The two private-repository
37
+ entries (this monorepo's own transparency entry, and Cejel's own source sub-package inside
38
+ it) never cite a source path, anywhere, in any field or format — but the finding itself, its
39
+ dimension, status, score, and content hash always survive; only the location is withheld,
40
+ marked uniformly as "path withheld — private repository". Redaction removes a location, never
41
+ a fact: a private repository failing its own check still shows up on its certificate, by
42
+ name. The B1 and B5 rubric dimensions are substrate-only (they measure signals specific to
43
+ this monorepo's own internal process, not applicable to any external repository) and are
44
+ excluded from the ranking for every repository, including ours — the same fairness rule
45
+ either way: nobody is scored on a dimension nobody else can have.
46
+
47
+ ### Known false positives (fixed before publishing)
48
+
49
+ Calibrating a rubric against real, elite repositories surfaces mistakes; the record is part
50
+ of the trust claim, not something to bury. Two dimensions produced a punitive score for the
51
+ *absence* of a ratable surface rather than a real weakness, and both are fixed:
52
+ Django was flagged critical on dependency hygiene for using version ranges instead of exact
53
+ pins — normal, deliberate practice for a library, not an app; the rubric now scores
54
+ dependency hygiene against archetype-appropriate norms. OSSF Scorecard — Google's own
55
+ supply-chain security auditing tool — was flagged critical on audit-trail completeness for
56
+ publishing release notes via GitHub Releases instead of a committed `CHANGELOG.md`; a
57
+ repository with no ratable audit surface now returns "insufficient data" (excluded from the
58
+ composite) instead of a punitive score. The board also publishes a measured-coverage
59
+ indicator per row: a score reflects only its *measured* dimensions, and a row scored on fewer
60
+ than half of its applicable dimensions is shown as unranked rather than ordered against
61
+ better-evidenced rows.
62
+
63
+ ## Usage
64
+
65
+ Run it with whichever package manager you already have — no install, no signup. All of
66
+ these pull the same `cejel` package from the npm registry:
67
+
68
+ ```bash
69
+ npx cejel . # npm
70
+ pnpm dlx cejel . # pnpm
71
+ yarn dlx cejel . # yarn
72
+ bunx cejel . # bun
73
+ deno run -A npm:cejel . # deno
74
+ ```
75
+
76
+ Scores the current directory with sensible defaults: no flags, no signup, fully offline.
77
+ Prints a concise terminal certificate and writes to `.cejel/`:
78
+
79
+ - `report.json` — the full structured report
80
+ - `certificate.html` — a self-contained HTML certificate (no external assets)
81
+ - `badge.json` — a [shields.io endpoint](https://shields.io/badges/endpoint-badge) payload
82
+ - `badge.svg` — a static, self-contained trust-score badge
83
+ - `summary.json` — a compact digest (score, verdict, top findings)
84
+
85
+ ### Flags
86
+
87
+ - `<path>` — repo to score (default: current directory)
88
+ - `--out-dir <dir>` — where to write report/certificate/badge files (default: `.cejel`)
89
+ - `--min-score <n>` — exit non-zero if the overall score is below `n` (0–4); used by the
90
+ GitHub Action's optional threshold gate
91
+ - `--ingest <file|glob>` — fold another scanner's output into the score (repeatable). Accepts
92
+ SARIF, OpenSSF Scorecard JSON, or the generic Cejel external-signal shape — format is
93
+ auto-detected. See "Aggregate your scanners" below.
94
+ - `--quiet` — suppress the terminal certificate (files are still written)
95
+
96
+ ## Aggregate your scanners
97
+
98
+ Cejel doesn't compete with your AI-code scanner (MunaTrust, Snyk, Semgrep, CodeQL, Codex,
99
+ whatever runs in CI) — it sits on top of it. Feed a scanner's output in with `--ingest` and
100
+ Cejel folds those findings into the same rubric-scored, offline trust certificate, with the
101
+ contributing tools shown in the certificate and report as provenance:
102
+
103
+ ```bash
104
+ npx cejel . --ingest munatrust.sarif --ingest scorecard.json
105
+ ```
106
+
107
+ Or drop files in `.cejel/inputs/` and they're picked up automatically, no flag needed:
108
+
109
+ ```bash
110
+ mkdir -p .cejel/inputs
111
+ cp munatrust-results.sarif .cejel/inputs/
112
+ npx cejel .
113
+ ```
114
+
115
+ External findings only ever adjust a dimension score *downward*, and by a bounded amount —
116
+ they augment the native repo scan, they never replace it. Every ingested file is attributed
117
+ by name in `certificate.html`, `report.json` (`consumedSignals`), and the terminal output
118
+ ("Incorporates findings from: ..."), so the certificate reads as a visible aggregation, not a
119
+ black box.
120
+
121
+ Three ways a scanner's output gets ingested:
122
+
123
+ 1. **SARIF** — any SARIF 2.1.0-emitting tool (Semgrep, CodeQL, most commercial SAST/AI-code
124
+ scanners) works with zero configuration; `--ingest` auto-detects the `runs` array.
125
+ 2. **OpenSSF Scorecard** — `scorecard --repo=... --format=json > scorecard.json`, then
126
+ `--ingest scorecard.json`; auto-detected by its `checks` array.
127
+ 3. **Generic JSON** — for a tool that emits neither, map its output into the minimal shape
128
+ below (or write a small adapter mirroring
129
+ [`scorecard-adapter.ts`](../witan/src/scorecard-adapter.ts) if the format needs real
130
+ parsing):
131
+
132
+ ```json
133
+ {
134
+ "tool": "my-scanner",
135
+ "signals": [
136
+ {
137
+ "dimension": "A2",
138
+ "weight": 0.7,
139
+ "findings": [
140
+ {
141
+ "ruleId": "hardcoded-secret",
142
+ "severity": "critical",
143
+ "message": "Hardcoded API key detected.",
144
+ "location": "src/config.ts:10"
145
+ }
146
+ ]
147
+ }
148
+ ]
149
+ }
150
+ ```
151
+
152
+ `dimension` is one of the Witan rubric criterion ids (`A1`-`A5`, `B1`-`B6`); `weight`
153
+ (0–1, default `0.5`) bounds how much this signal can move that dimension; `severity` is
154
+ `critical` | `warning` | `info`; `location` is optional.
155
+
156
+ ## Displaying the trust badge
157
+
158
+ Endpoint JSON (host `badge.json` anywhere static — a repo file, a gist, GitHub Pages — and
159
+ point shields.io at it):
160
+
161
+ ```markdown
162
+ ![Cejel trust score](https://img.shields.io/endpoint?url=<url-to-your-hosted-badge.json>)
163
+ ```
164
+
165
+ Or commit/link the static SVG directly:
166
+
167
+ ```markdown
168
+ ![Cejel trust score](./.cejel/badge.svg)
169
+ ```
170
+
171
+ ## GitHub Action
172
+
173
+ See [`action/action.yml`](./action/action.yml) — runs Cejel on `push`/`pull_request`,
174
+ posts the score + top findings to the job summary, and can optionally fail the check below
175
+ a configurable `min-score` threshold. The scoring step makes no network calls and needs no
176
+ secrets.
177
+
178
+ ```yaml
179
+ - uses: BargLabs/cejel/action@main
180
+ with:
181
+ min-score: '2.5' # optional; omit to never fail the check
182
+ ```
183
+
184
+ ## MCP server (for agents)
185
+
186
+ The same package ships a second bin, `cejel-mcp` — a thin MCP (Model Context Protocol)
187
+ server over stdio, so any MCP client (Claude Code, Cowork, Cursor, Codex) can request a
188
+ trust certificate as a tool call. It wraps the exact same scan the CLI runs — same scores,
189
+ same verdict — and is listed on Smithery via the repo's `smithery.yaml`.
190
+
191
+ Add it to an MCP client config:
192
+
193
+ ```json
194
+ {
195
+ "mcpServers": {
196
+ "cejel": {
197
+ "command": "npx",
198
+ "args": ["-y", "--package=cejel", "cejel-mcp"]
199
+ }
200
+ }
201
+ }
202
+ ```
203
+
204
+ The server exposes one tool and two resources:
205
+
206
+ - `scan` — input `{ path, format? }`; scores the repository at `path` and returns the trust
207
+ cert as JSON (`format: "summary"`, the default, is the compact digest; `format: "json"` is
208
+ the full report, identical to the CLI's `report.json`).
209
+ - `cejel://last-scan/certificate.html` and `cejel://last-scan/badge.svg` — the HTML
210
+ certificate and SVG badge for the most recent scan.
211
+
212
+ Like the CLI, scoring over MCP is fully offline: no network calls, no telemetry, no signup,
213
+ and the server writes no files.
214
+
215
+ ## What "offline" means here
216
+
217
+ Scoring a repo — `npx cejel .` itself, and the Action's scoring step — makes zero network
218
+ calls: no telemetry, no signup, no model call. Fetching the `cejel` package the first time
219
+ (like any npm-distributed CLI, including this Action's own dependency install) does need
220
+ network; that's a one-time install cost, not part of the scoring guarantee.
221
+
222
+ ## The public leaderboard: what we redact, what we exclude, and where we were wrong
223
+
224
+ We publish a trust board scoring a corpus of well-known open-source repositories alongside
225
+ our own. Running a leaderboard on other people's code obliges us to be exact about how it
226
+ works, so here is all of it.
227
+
228
+ **What we redact, and on what basis.** One rule: *a path is published exactly when you can
229
+ check it.* For a public repository, every evidence path and line number is cited in full — a
230
+ certificate whose evidence you cannot open is not evidence. For a private repository (ours),
231
+ **no source path is cited anywhere, in any field or format**; an unverifiable path tells you
232
+ nothing you can check while disclosing our file tree for free. Redaction removes a
233
+ **location**, never a **fact**: the finding, its dimension, its status, its score, and its
234
+ content hash all survive. Where a path is withheld you will see it said plainly. This is
235
+ enforced structurally — the public artifacts are built from filtered data rather than
236
+ rendered and then scrubbed — and a build that would emit a private path fails rather than
237
+ publishes.
238
+
239
+ **What we exclude from ranking.** Two of the eleven dimensions — B1 (dispatch trace
240
+ completeness) and B5 (verified learning trace) — measure signals that only exist inside the
241
+ agent substrate Cejel was built in. No external repository can produce them. They are
242
+ therefore **excluded from the ranking for every repository, including ours**: we do not
243
+ score you on something you cannot have, and we do not award ourselves points for something
244
+ you cannot contest. You will still see them defined in the rubric source, because the rubric
245
+ is the published standard and hiding two of its dimensions would make it incomplete. Where a
246
+ dimension does not apply to a repository, the certificate says *not applicable* rather than
247
+ quietly scoring it zero.
248
+
249
+ **Where we were wrong.** Calibrating this rubric against real repositories surfaced four
250
+ errors in our own tool, all found before publication and all fixed. We list them because a
251
+ scoring tool that has never been wrong is a scoring tool that has not been checked:
252
+
253
+ - **Django, scored a false critical on dependency hygiene.** We applied application-shaped
254
+ expectations to a library. Archetype now gates the dimension.
255
+ - **OpenSSF Scorecard, scored a false critical on audit trail.** We flagged Google's own
256
+ auditing tool for insufficient auditing. The dimension lacked a "is there anything here to
257
+ rate?" gate before "how good is it?"; it has one now.
258
+ - **Twelve of seventeen repositories were silently dropped** from an early build of the
259
+ board, which nonetheless reported success. The generator could always lose rows without
260
+ saying so. It now asserts that every repository in the corpus is accounted for — ranked,
261
+ unranked, or errored — and fails loudly otherwise.
262
+ - **Low-coverage repositories were ranked as though fully measured.** A confidence floor now
263
+ publishes them without ranking them, rather than implying a precision we did not have.
264
+ - **A1's scheduled-workflow check hardcoded our own internal QA agent's filename** as its
265
+ definition, instead of the concept it actually measures. It was inert for every external
266
+ repository by construction — a home-field rule dressed up as a general one. It now detects
267
+ the *shape* (a cron-scheduled workflow that runs the verification suite, and whether its
268
+ results are durably published or only handed to an ephemeral CI artifact); our own internal
269
+ nightly QA workflow is one recognized instance of that shape, not its definition.
270
+
271
+ Every one of these was a false alarm produced by *us*, about *other people's code*, and we
272
+ would rather you knew that than discovered it. If you believe the board scores your
273
+ repository wrongly, open an issue — a rubric that cannot be corrected in public has no
274
+ business being published in public.
275
+
276
+ **No rubric change re-scores you silently.** Every change to scoring behavior requires a
277
+ `WITAN_RUBRIC_VERSION` bump and a corpus-wide before/after delta published in
278
+ [`docs/leaderboard/RUBRIC_CHANGELOG.md`](../../docs/leaderboard/RUBRIC_CHANGELOG.md) — score,
279
+ verdict, and rank for every repository, "no repository moved" stated explicitly when that is
280
+ the result. A build that changes scoring without both fails; see that file's `v2` entry for
281
+ the home-field fix above as the first rubric change recorded this way.
282
+
283
+ ## License
284
+
285
+ `cejel` is free and licensed under [AGPL-3.0-only](./LICENSE), copyleft: any modified
286
+ version you distribute or run as a network service must also make its source available
287
+ under the same terms. A commercial license is available for teams that need to use or
288
+ modify `cejel` without those copyleft obligations.