@fitsummehari/mergeguard 0.1.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ This project follows [Semantic Versioning](https://semver.org/). `0.1.0` is the first public beta. There is no prior public npm release of this local-first CLI.
6
+
7
+ ## 0.1.0
8
+
9
+ First public beta of MergeGuard as a local-first semantic pre-push / code-change gate.
10
+
11
+ - Single review engine shared by the CLI, Git pre-push hook, GitHub Actions, GitLab CI, generic CI, and the Node API
12
+ - Working-tree, staged, `--base`/`--head`, and pre-push Git scopes, including first commits and first pushes against Git's empty tree
13
+ - High-signal detectors for security, authorization, tenant isolation, concurrency, database integrity, and related runtime risk
14
+ - Bounded ephemeral repository context (no persisted project database)
15
+ - Published as `@fitsummehari/mergeguard` (CLI binary remains `mergeguard`; unscoped `mergeguard` is a different npm package)
16
+ - Deterministic `offline` verifier by default (reproducible); `auto` and local Laya optional; optional Jev
17
+ - Terminal, JSON, SARIF, and GitLab Code Quality reporters
18
+ - Non-destructive, idempotent hook install/uninstall that respects `core.hooksPath`
19
+ - Zero runtime npm dependencies; Node.js 20+; Laya model weights are not bundled
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MergeGuard contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,290 @@
1
+ # MergeGuard
2
+
3
+ MergeGuard is a local-first semantic code-change gate that catches high-impact bugs before code is pushed or merged.
4
+
5
+ It reviews a Git diff — not an entire repository — for concrete runtime risks such as authorization regressions, tenant-isolation holes, check-then-write races, unsafe SQL or shell construction, and removed transaction boundaries. It is not a SaaS platform and not a style linter.
6
+
7
+ ```text
8
+ Git diff
9
+ ↓
10
+ MergeGuard review engine
11
+ ├── deterministic/static detectors
12
+ ├── repository/context resolver
13
+ └── optional semantic verifier
14
+ ├── local Laya
15
+ └── optional Jev/provider
16
+ ↓
17
+ normalized findings
18
+ ↓
19
+ terminal / JSON / SARIF / GitLab
20
+ ↓
21
+ PASS / BLOCK
22
+ ```
23
+
24
+ The same engine is used by the CLI, a Git pre-push hook, GitHub Actions, GitLab CI, other CI systems, and the programmatic Node API.
25
+
26
+ ```bash
27
+ npm install -D @fitsummehari/mergeguard
28
+ npx mergeguard review
29
+ ```
30
+
31
+ Requires only **Node.js 20+** and **Git** for the default offline experience. The CLI binary is `mergeguard`; the npm package is scoped because the unscoped name is owned by a different project.
32
+
33
+ ## Why it exists
34
+
35
+ Compilers, tests, and formatters do not reliably catch "this change will fail under concurrency" or "this query no longer filters by tenant." MergeGuard sits in front of `git push` and CI so those classes of defect can block the change with a normal process exit code. No MergeGuard server, database, dashboard, GitHub App, or webhook service is required.
36
+
37
+ ## What it catches
38
+
39
+ High-signal, change-scoped risks, including:
40
+
41
+ - authorization / route-protection regressions
42
+ - tenant or ownership filter removal
43
+ - check-then-create and read-check-write races
44
+ - missing uniqueness / idempotency around creates and webhooks
45
+ - removed transaction boundaries and non-atomic related writes
46
+ - unbounded deletes or empty-filter updates
47
+ - SQL injection, command injection, dynamic evaluation
48
+ - unsafe deserialization and path traversal
49
+ - XSS / raw HTML sinks where the sink is visible
50
+ - disabled TLS verification
51
+ - async `forEach`, swallowed errors, N+1 query and unbounded fan-out candidates
52
+ - validation removal and insecure framework markers such as `@Public()` / `[AllowAnonymous]`
53
+
54
+ ## What it deliberately does not catch
55
+
56
+ MergeGuard is not a style linter and will not report:
57
+
58
+ - semicolons, quotes, import order, or naming taste
59
+ - formatting or line length
60
+ - generic "consider refactoring" advice
61
+ - documentation nags
62
+ - arbitrary function-length opinions
63
+ - subjective AI code-review commentary
64
+
65
+ It is also not a CVE database, secret scanner, compiler, or test runner.
66
+
67
+ ## Installation
68
+
69
+ ```bash
70
+ npm install -D @fitsummehari/mergeguard
71
+ npx mergeguard review
72
+ ```
73
+
74
+ Zero runtime npm dependencies. Python is **not** required for default operation.
75
+
76
+ ### One-off invocation without a local install
77
+
78
+ Do **not** run bare `npx mergeguard` before installing — npm may resolve the unrelated unscoped `mergeguard` package.
79
+
80
+ ```bash
81
+ npx --package=@fitsummehari/mergeguard mergeguard review
82
+ ```
83
+
84
+ After a normal local install, `npx mergeguard review` is correct because npm uses the local binary.
85
+
86
+ ### From this source tree
87
+
88
+ ```bash
89
+ node bin/mergeguard.js review
90
+ ```
91
+
92
+ ## 30-second quick start
93
+
94
+ ```bash
95
+ cd your-git-repo
96
+ npm install -D @fitsummehari/mergeguard
97
+ npx mergeguard review
98
+ ```
99
+
100
+ That reviews the working tree (staged, unstaged, and untracked) against `HEAD`. Exit `0` means pass. Exit `1` means a blocking finding. Exit `2` means MergeGuard or the environment failed. The default verifier is **offline** (reproducible across machines).
101
+
102
+ ## Local review
103
+
104
+ ```bash
105
+ npx mergeguard review
106
+ npx mergeguard review --staged
107
+ npx mergeguard review --base origin/main
108
+ npx mergeguard review --base origin/main --head HEAD
109
+ npx mergeguard review --verifier offline
110
+ ```
111
+
112
+ `--no-ai` and `--verifier offline` / `--verifier deterministic` force the built-in verifier.
113
+
114
+ ## Pre-push hook
115
+
116
+ ```bash
117
+ npx mergeguard hook install
118
+ npx mergeguard hook status
119
+ npx mergeguard hook uninstall
120
+ ```
121
+
122
+ Install is idempotent and will not overwrite an existing pre-push hook. It appends a marked MergeGuard block and respects `core.hooksPath` when set. The hook reads Git's pre-push stdin and reviews the outgoing commit range, including first pushes (diffed against Git's empty tree).
123
+
124
+ If MergeGuard blocks a push, it tells you how to bypass **only when relevant**:
125
+
126
+ ```bash
127
+ git push --no-verify
128
+ ```
129
+
130
+ Use CI as the enforcement layer. Local hooks are a convenience, not a security boundary.
131
+
132
+ ## GitHub Actions
133
+
134
+ ```bash
135
+ npx mergeguard ci github --write
136
+ ```
137
+
138
+ Or copy [`examples/github/mergeguard.yml`](examples/github/mergeguard.yml). Default templates install `@fitsummehari/mergeguard`, pin `--verifier offline`, and can upload SARIF. Make the job a required check if you want enforcement. Optional Laya-in-CI recipes are in [docs/LAYA.md](docs/LAYA.md).
139
+
140
+ ## GitLab CI
141
+
142
+ ```bash
143
+ npx mergeguard ci gitlab --write
144
+ ```
145
+
146
+ Or copy [`examples/gitlab/mergeguard.yml`](examples/gitlab/mergeguard.yml). The job writes GitLab Code Quality JSON as an artifact and still uses the CLI exit code to block.
147
+
148
+ ## Other CI
149
+
150
+ Any runner with Git and Node 20+ can run the same engine after installing the scoped package:
151
+
152
+ ```bash
153
+ npm install -D @fitsummehari/mergeguard
154
+ npx mergeguard review --verifier offline --base <base> --head <head>
155
+ ```
156
+
157
+ That works on Jenkins, CircleCI, Azure DevOps, Bitbucket, Buildkite, and custom CI. No provider credentials are required for offline verification.
158
+
159
+ ## Configuration
160
+
161
+ Zero-config defaults to the offline verifier. To pin policy:
162
+
163
+ ```bash
164
+ npx mergeguard init
165
+ ```
166
+
167
+ This writes `.mergeguard.yml` and will not overwrite an existing file unless you pass `--force`.
168
+
169
+ ```yaml
170
+ fail_on: high
171
+
172
+ exclude:
173
+ - dist/**
174
+ - build/**
175
+ - generated/**
176
+ - vendor/**
177
+ - node_modules/**
178
+
179
+ review:
180
+ security: true
181
+ correctness: true
182
+ concurrency: true
183
+ database: true
184
+ performance: true
185
+
186
+ verifier:
187
+ engine: offline
188
+ ```
189
+
190
+ `fail_on` may be `critical`, `high`, `medium`, `low`, `info`, or `none`. Unknown root keys produce a warning. Malformed YAML reports the file path and line. See [docs/CONFIGURATION.md](docs/CONFIGURATION.md).
191
+
192
+ `auto` is available but environment-dependent (uses Laya when installed). Prefer pinning `offline` or `laya` for team/CI reproducibility. `mergeguard doctor` shows configured vs effective verifier.
193
+
194
+ ## Output formats
195
+
196
+ ```bash
197
+ npx mergeguard review --format terminal
198
+ npx mergeguard review --format json
199
+ npx mergeguard review --format sarif --output mergeguard.sarif
200
+ npx mergeguard review --format gitlab --output gl-code-quality-report.json
201
+ ```
202
+
203
+ Machine-readable formats write only the report to stdout (or `--output`). Status goes to stderr so JSON/SARIF/GitLab output stays parseable.
204
+
205
+ ## Exit codes
206
+
207
+ | Code | Meaning |
208
+ | --- | --- |
209
+ | `0` | Review completed; no blocking finding |
210
+ | `1` | Review completed; policy blocked the change |
211
+ | `2` | MergeGuard, config, Git, or runtime failure |
212
+
213
+ ## Optional Laya
214
+
215
+ Laya is **not** bundled with the npm package. MergeGuard works without it. Keeping model weights out of npm keeps the install small (~40 KB) and lets default CI run on Node alone.
216
+
217
+ ```bash
218
+ python -m pip install laya
219
+ npx mergeguard doctor
220
+ npx mergeguard review --verifier laya
221
+ ```
222
+
223
+ `--verifier laya` exits `2` with an install hint if Laya is missing. It does **not** silently fall back. See [docs/LAYA.md](docs/LAYA.md).
224
+
225
+ MergeGuard talks to Laya through a short-lived local Python process over stdin/stdout. It does not start an HTTP server. First model use may download a checkpoint into the Hugging Face cache.
226
+
227
+ ## Optional Jev
228
+
229
+ Jev is opt-in and never required for default operation.
230
+
231
+ ```bash
232
+ export TYPESAFE_API_KEY=... # or JEV_API_KEY
233
+ npx mergeguard review --verifier jev
234
+ ```
235
+
236
+ Jev sends candidate evidence to the configured HTTP API. Secrets are read from the environment and are not printed.
237
+
238
+ ## Programmatic API
239
+
240
+ ```js
241
+ import { review } from "@fitsummehari/mergeguard";
242
+
243
+ const result = await review({
244
+ cwd: process.cwd(),
245
+ base: "origin/main",
246
+ head: "HEAD",
247
+ });
248
+
249
+ // result.passed, result.findings, result.summary, result.metadata
250
+ if (!result.passed) process.exitCode = 1;
251
+ ```
252
+
253
+ Also exported: `reviewChangeSet`, `loadConfig`, `normalizeConfig`, `renderReport`, `toSarif`, `toGitLabCodeQuality`, `detectLaya`, `VERSION`. Everything else is internal.
254
+
255
+ ## Language-support philosophy
256
+
257
+ MergeGuard **runs on any normal Git repository**. That is not the same as equal deep semantics for every language.
258
+
259
+ JavaScript, TypeScript, Python, Java, Kotlin, Go, C#, PHP, Ruby, and SQL have additional syntax-aware rules. Rust, C, C++, shell, YAML, JSON, Terraform, Dockerfiles, and mixed monorepos still get generic analysis and must not crash merely because a deeper adapter is missing.
260
+
261
+ ## Limitations
262
+
263
+ - Findings are candidates plus a verifier, not proofs.
264
+ - Context is bounded — not a persisted project database.
265
+ - Huge diffs are truncated; generated/minified/binary paths are skipped.
266
+ - Local hooks can be bypassed with `--no-verify`.
267
+ - Semantic depth varies by language and framework.
268
+
269
+ See [docs/LIMITATIONS.md](docs/LIMITATIONS.md) and [docs/DETECTORS.md](docs/DETECTORS.md).
270
+
271
+ ## Security and privacy
272
+
273
+ Analyzed repository text is treated as untrusted data, never as instructions or executable code. Offline mode makes no network calls. Laya mode stays on the machine aside from Laya/Hugging Face model-cache behavior. Jev mode is explicit and sends candidate context to the configured API.
274
+
275
+ Do not put credentials in `.mergeguard.yml`. See [SECURITY.md](SECURITY.md).
276
+
277
+ ## Contributing
278
+
279
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
280
+
281
+ ```bash
282
+ git clone https://github.com/FitsumMehari/MergeGuard.git
283
+ cd MergeGuard
284
+ npm test
285
+ npm run check
286
+ ```
287
+
288
+ ## License
289
+
290
+ [MIT](LICENSE)
package/SECURITY.md ADDED
@@ -0,0 +1,26 @@
1
+ # Security
2
+
3
+ MergeGuard reviews untrusted repository text. That text is evidence only. It is never executed, never sourced as configuration code, and never treated as verifier instructions.
4
+
5
+ ## Reporting a vulnerability
6
+
7
+ This project does not publish a dedicated security email. Please use [GitHub private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability) on [FitsumMehari/MergeGuard](https://github.com/FitsumMehari/MergeGuard/security/advisories/new) if the repository has that feature enabled.
8
+
9
+ Maintainers: enable **Settings → Code security → Private vulnerability reporting** so researchers have a private channel.
10
+
11
+ If private reporting is unavailable, open a GitHub issue titled "Security: please contact maintainers" with no exploit details and wait for a maintainer to reply privately.
12
+
13
+ ## Privacy model
14
+
15
+ - **Offline / deterministic:** no network calls.
16
+ - **Laya:** local Python process. Laya/Hugging Face may download a model checkpoint into a local cache on first use.
17
+ - **Jev:** explicit opt-in. Candidate context is sent to the configured HTTP API. Credentials come from `TYPESAFE_API_KEY` or `JEV_API_KEY` and must not be placed in `.mergeguard.yml` or committed.
18
+
19
+ Do not include secrets in reports, fixtures, or configuration examples.
20
+
21
+ ## Trust boundary
22
+
23
+ - Git filenames, diffs, and file contents from the reviewed repository are untrusted.
24
+ - MergeGuard must not run scripts from that repository.
25
+ - Analyzed paths are constrained to the repository root.
26
+ - Binary, oversized, and ignored files are skipped.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "../src/cli.js";
3
+
4
+ main(process.argv.slice(2)).then(
5
+ (code) => process.exit(code ?? 0),
6
+ (error) => {
7
+ console.error(`mergeguard: ${error?.message || error}`);
8
+ if (process.env.MERGEGUARD_DEBUG === "1" && error?.stack) console.error(error.stack);
9
+ process.exit(2);
10
+ },
11
+ );
@@ -0,0 +1,31 @@
1
+ # Architecture
2
+
3
+ MergeGuard is a single-process CLI and Node library. There is no application server, database, queue, dashboard, or webhook listener.
4
+
5
+ ```text
6
+ CLI / hook / CI / JS API
7
+ │
8
+ ├─ Git scope resolver
9
+ │ working | staged | branch range | pre-push
10
+ │
11
+ ├─ detector pipeline
12
+ │ pattern detectors
13
+ │ diff-regression detectors
14
+ │ repository-aware detectors
15
+ │
16
+ ├─ context resolver
17
+ │ changed files + nearby high-signal files
18
+ │ manifests / schemas / auth / migrations
19
+ │
20
+ ├─ verifier
21
+ │ offline (built-in)
22
+ │ Laya (local Python, optional)
23
+ │ Jev (remote, optional)
24
+ │
25
+ └─ reporters
26
+ terminal | JSON | SARIF | GitLab Code Quality
27
+ ```
28
+
29
+ Public library types live in `src/types.js` (`ReviewResult`, `Finding`, `ChangedFile`, severity/category). Additional detectors, language adapters, verifiers, and reporters should plug into this pipeline rather than forking it.
30
+
31
+ Repository context is resolved per review and discarded. Nothing is persisted.
@@ -0,0 +1,59 @@
1
+ # Configuration
2
+
3
+ MergeGuard works with no config file. When present, it reads the first of:
4
+
5
+ - `.mergeguard.yml`
6
+ - `.mergeguard.yaml`
7
+ - `.mergeguard.json`
8
+
9
+ Or `--config PATH`. `mergeguard init` writes a conservative `.mergeguard.yml` and refuses to overwrite unless `--force` is passed.
10
+
11
+ ## Defaults
12
+
13
+ | Field | Default | Notes |
14
+ | --- | --- | --- |
15
+ | `fail_on` | `high` | Also accepts `failOn`. Values: `critical`, `high`, `medium`, `low`, `info`, `none` |
16
+ | `verifier.engine` | `offline` | `offline` (default, reproducible), `deterministic` (alias), `auto` (Laya if installed), `laya`, `jev` |
17
+ | `confidence` | `0.62` | Verifier strength threshold in `0..1` |
18
+ | `exclude` | `node_modules/**`, `vendor/**`, `dist/**`, `build/**`, `coverage/**`, `.next/**`, `.git/**`, `**/*.min.js`, `**/*.map`, `**/generated/**` | Also accepts `ignore` / `ignore.paths` |
19
+ | `review.*` | all categories `true` | Disable a category with `false` |
20
+ | `max_files` | `300` (cap 5000) | Changed files analyzed |
21
+ | `max_candidates` | `120` (cap 1000) | Detector candidates kept |
22
+ | `context_files` | `24` (cap 100) | Nearby files loaded as evidence |
23
+ | `context_chars` | `18000` (cap 200000) | Evidence budget per candidate |
24
+
25
+ Unknown root keys are ignored with a warning that includes the config path.
26
+
27
+ ## Example
28
+
29
+ ```yaml
30
+ fail_on: high
31
+ exclude:
32
+ - dist/**
33
+ - generated/**
34
+ review:
35
+ security: true
36
+ performance: false
37
+ verifier:
38
+ engine: offline
39
+ laya:
40
+ python: python3
41
+ max_len: 4096
42
+ ```
43
+
44
+ ## Environment
45
+
46
+ | Variable | Purpose |
47
+ | --- | --- |
48
+ | `MERGEGUARD_PYTHON` | Python executable for Laya |
49
+ | `MERGEGUARD_LAYA_TIMEOUT_MS` | Laya subprocess timeout (default 180000) |
50
+ | `MERGEGUARD_JEV_TIMEOUT_MS` | Jev HTTP timeout (default 30000) |
51
+ | `TYPESAFE_API_KEY` / `JEV_API_KEY` | Jev only |
52
+ | `MERGEGUARD_BIN` | Pre-push hook executable override |
53
+ | `MERGEGUARD_REMOTE` | Remote name passed into the hook |
54
+ | `MERGEGUARD_DEBUG=1` | Print stack traces on CLI failures |
55
+ | `NO_COLOR` | Disable ANSI color |
56
+
57
+ ## Limits
58
+
59
+ Tracked-file scoring for context is capped at 4000 paths. Individual file reads stop at 2 MiB and skip binary (NUL) content. Symlinks that escape the repository root are not read.
@@ -0,0 +1,29 @@
1
+ # Detector coverage
2
+
3
+ MergeGuard runs only against changed content/diff regressions and then adds bounded repository context.
4
+
5
+ ## High-signal categories
6
+
7
+ | Category | Examples |
8
+ |---|---|
9
+ | Security | dynamic evaluation, SQL injection candidates, shell injection, TLS verification disabled, raw HTML, unsafe deserialization, path traversal, sensitive logging |
10
+ | Authorization | auth guard/policy removal, anonymous/public access introduced, token decode without visible verification |
11
+ | Tenant isolation | tenant/organization/owner predicates removed; repository-aware missing isolation candidates |
12
+ | Concurrency | check-then-create, read-check-write, webhook replay/idempotency candidates |
13
+ | Database | transaction removal, multi-write atomicity, broad delete/update, uniqueness removal, risky migrations |
14
+ | Correctness/reliability | async forEach, swallowed exceptions, unsafe retry behavior, input-validation removal, hard-coded local endpoints |
15
+ | Performance | N+1 query candidates, unbounded async fan-out, potentially blocking index creation |
16
+
17
+ ## Language-aware rules
18
+
19
+ The generic layer runs in any text Git repository. Additional direct rules currently recognize JavaScript/TypeScript, Python, Java/Kotlin, Go, PHP, Ruby, C#, SQL and common configuration forms. C/C++, Rust, shell, Terraform, Dockerfiles and other languages still benefit from generic diff-regression, TLS/SQL/configuration, repository and migration checks, but have fewer syntax-specific rules today. `yaml.load` is ignored when `SafeLoader` is present on the same line.
20
+
21
+ ## Stack/context recognition
22
+
23
+ The context resolver recognizes common signals for NestJS, Next.js, Express, Fastify, Django, FastAPI, Flask, Spring, Laravel, Symfony, Rails, ASP.NET Core, Gin/Fiber, Actix/Axum; Prisma, TypeORM, Sequelize, SQLAlchemy, Entity Framework, GORM, Hibernate, Diesel/SQLx; PostgreSQL, MySQL/MariaDB, MongoDB, SQLite and Redis.
24
+
25
+ Recognition does not imply perfect semantic parsing. It is used to select useful evidence and reduce false positives.
26
+
27
+ ## What is intentionally excluded
28
+
29
+ MergeGuard does not compete with formatters/linters on formatting, naming, import order, line length or generic maintainability opinions. It also does not include a vulnerability-database service, dependency CVE feed, secret-management backend, compiler or test runner.
@@ -0,0 +1,40 @@
1
+ # Integrations
2
+
3
+ All surfaces call the same `review()` engine.
4
+
5
+ Install once:
6
+
7
+ ```bash
8
+ npm install -D @fitsummehari/mergeguard
9
+ ```
10
+
11
+ Do not install the unscoped name `mergeguard` (different package). Do not use bare `npx mergeguard` until the scoped package is installed locally; for a one-off:
12
+
13
+ ```bash
14
+ npx --package=@fitsummehari/mergeguard mergeguard review
15
+ ```
16
+
17
+ ## Local
18
+
19
+ `mergeguard review` compares the working tree (including untracked files) with `HEAD`. `--staged` limits the review to the index. Default verifier is `offline`.
20
+
21
+ ## Pre-push
22
+
23
+ `mergeguard hook install` adds a managed block to the pre-push hook (including `core.hooksPath`). Git supplies local/remote refs on stdin; MergeGuard reviews the outgoing range. Existing hook content is retained.
24
+
25
+ ## GitHub
26
+
27
+ See [`examples/github/mergeguard.yml`](../examples/github/mergeguard.yml). Use `fetch-depth: 0` so merge-base works. Default templates pin `--verifier offline`. Optional Laya CI is in [LAYA.md](LAYA.md).
28
+
29
+ ## GitLab
30
+
31
+ See [`examples/gitlab/mergeguard.yml`](../examples/gitlab/mergeguard.yml). `--format gitlab` writes Code Quality JSON. Use `artifacts: when: always` so findings upload even when the gate exits `1`.
32
+
33
+ ## Jenkins / CircleCI / Azure DevOps / Bitbucket / Buildkite / custom
34
+
35
+ ```bash
36
+ npm install -D @fitsummehari/mergeguard
37
+ npx mergeguard review --verifier offline --base origin/main --head HEAD
38
+ ```
39
+
40
+ The contract is the exit code plus optional JSON/SARIF/GitLab output. No provider API credentials are required for offline verification.
package/docs/LAYA.md ADDED
@@ -0,0 +1,82 @@
1
+ # Optional Laya verification
2
+
3
+ Laya is **not** bundled in the MergeGuard npm package. Detectors run in Node. Laya is an optional verifier that answers narrow questions (plausible, reachable, already protected, impact, worth reporting) about those candidates.
4
+
5
+ MergeGuard works with **Node.js 20+ and Git only**. Python and Laya are extra.
6
+
7
+ ```bash
8
+ python -m pip install laya
9
+ npx mergeguard doctor
10
+ npx mergeguard review --verifier laya
11
+ ```
12
+
13
+ On first model-backed use, Laya may download a checkpoint into its normal local Hugging Face cache. Later runs can reuse that cache. Do not commit model files. Do not put hundreds of millions of parameters into the npm tarball.
14
+
15
+ ## Reproducibility
16
+
17
+ Default for 0.1.0 is `offline` so laptop and CI agree without Python.
18
+
19
+ `auto` uses Laya when it is importable and otherwise falls back to offline. That can make environments disagree. Prefer pinning:
20
+
21
+ ```yaml
22
+ verifier:
23
+ engine: offline
24
+ ```
25
+
26
+ or, if every environment installs Laya:
27
+
28
+ ```yaml
29
+ verifier:
30
+ engine: laya
31
+ ```
32
+
33
+ `mergeguard doctor` shows configured vs effective verifier.
34
+
35
+ ## Optional GitHub Actions (Laya)
36
+
37
+ Do **not** add this to the default lightweight workflow.
38
+
39
+ ```yaml
40
+ - uses: actions/setup-node@v4
41
+ with:
42
+ node-version: 22
43
+ - run: npm install --save-dev @fitsummehari/mergeguard
44
+ - uses: actions/setup-python@v5
45
+ with:
46
+ python-version: "3.11"
47
+ - run: python -m pip install laya
48
+ - uses: actions/cache@v4
49
+ with:
50
+ path: |
51
+ ~/.cache/huggingface
52
+ key: laya-hf-${{ runner.os }}
53
+ - run: npx mergeguard review --verifier laya --base "origin/${{ github.base_ref }}" --head "${{ github.event.pull_request.head.sha }}"
54
+ ```
55
+
56
+ ## Optional GitLab CI (Laya)
57
+
58
+ ```yaml
59
+ mergeguard-laya:
60
+ image: node:22
61
+ before_script:
62
+ - apt-get update && apt-get install -y python3 python3-pip
63
+ - python3 -m pip install laya
64
+ - npm install --save-dev @fitsummehari/mergeguard
65
+ cache:
66
+ paths:
67
+ - .cache/huggingface/
68
+ variables:
69
+ HF_HOME: "$CI_PROJECT_DIR/.cache/huggingface"
70
+ script:
71
+ - npx mergeguard review --verifier laya --base "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" --head "$CI_COMMIT_SHA"
72
+ ```
73
+
74
+ ## Future Node-native path
75
+
76
+ `@receptron/laya` exists on npm (0.1.x) and can load ONNX weights from a local cache. That release is too early to take as a MergeGuard runtime dependency. 0.1.0 keeps the Python subprocess bridge. A later version may optionally call:
77
+
78
+ ```text
79
+ MergeGuard Node → Laya ONNX/TypeScript runtime → model cached locally
80
+ ```
81
+
82
+ without putting hundreds of millions of parameters inside the npm tarball.
@@ -0,0 +1,10 @@
1
+ # Limitations
2
+
3
+ - MergeGuard **runs on arbitrary Git repositories**. It does **not** have equal semantic analysis for every language or framework.
4
+ - Detectors produce candidates. The verifier can suppress weak ones. Neither is a formal proof.
5
+ - Context is ephemeral and bounded. MergeGuard does not build or persist a whole-repository "project brain."
6
+ - Large diffs are truncated (`max_files`). Generated, minified, binary, and excluded paths are skipped.
7
+ - First-push and root-commit reviews use Git's empty tree. Shallow clones still need enough history for `--base` merge-base resolution.
8
+ - Pre-push hooks can be bypassed with `git push --no-verify`.
9
+ - Default verifier is `offline`. `auto` does not fail when Laya is missing and can make laptop vs CI results differ. Only `--verifier laya` (or `verifier.engine: laya`) requires Laya.
10
+ - Jev is optional, network-using, and credential-gated. Default operation never needs it.
@@ -0,0 +1,27 @@
1
+ # Migration from the hosted 1.x shape
2
+
3
+ The previous repository modeled MergeGuard as a hosted review platform. The 2.x local-first shape removes the infrastructure layer and keeps the review capability as a CLI/library.
4
+
5
+ ## Removed
6
+
7
+ - `apps/api`
8
+ - `apps/web`
9
+ - `apps/worker`
10
+ - database/Prisma persistence
11
+ - Redis/BullMQ queues
12
+ - webhook receivers
13
+ - Docker deployment topology
14
+ - dashboard/authentication concerns
15
+ - persisted repository indexing and analysis-run history
16
+
17
+ ## Replaced by
18
+
19
+ - `src/git.js`: Git working/staged/range/pre-push change acquisition
20
+ - `src/detectors/*`: diff and repository-aware candidate detection
21
+ - `src/context.js`: bounded ephemeral repository context
22
+ - `src/verifiers/*`: deterministic, local Laya and optional Jev verifier contract
23
+ - `src/reporters/*`: terminal, JSON, SARIF and GitLab Code Quality
24
+ - `src/hook.js`: composable pre-push installation
25
+ - `src/review.js`: one reusable engine used by CLI and JS API
26
+
27
+ The migration intentionally does not preserve hosted analysis history because persistence is not required by the core product. If a future organization dashboard is needed, it should consume MergeGuard's JSON/SARIF output as a separate optional product rather than being required to run the analyzer.