redlinegate 0.0.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 +21 -0
- package/README.md +188 -0
- package/commands/redline-init.md +54 -0
- package/commands/redline-verify.md +69 -0
- package/dist/bin/redline.js +605 -0
- package/dist/bin/redline.js.map +1 -0
- package/dist/commands/exempt.js +45 -0
- package/dist/commands/exempt.js.map +1 -0
- package/dist/commands/init.js +615 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/policy.js +25 -0
- package/dist/commands/policy.js.map +1 -0
- package/dist/commands/remove.js +427 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/review.js +72 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/sync.js +42 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/verify.js +478 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/config/redline-json.js +187 -0
- package/dist/config/redline-json.js.map +1 -0
- package/dist/core/errors.js +25 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/git.js +152 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/log.js +22 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/severity.js +16 -0
- package/dist/core/severity.js.map +1 -0
- package/dist/core/version.js +15 -0
- package/dist/core/version.js.map +1 -0
- package/dist/detect/scan.js +79 -0
- package/dist/detect/scan.js.map +1 -0
- package/dist/detect/stack.js +71 -0
- package/dist/detect/stack.js.map +1 -0
- package/dist/enforce/ladder.js +148 -0
- package/dist/enforce/ladder.js.map +1 -0
- package/dist/exempt/parse.js +86 -0
- package/dist/exempt/parse.js.map +1 -0
- package/dist/metrics/options.js +257 -0
- package/dist/metrics/options.js.map +1 -0
- package/dist/metrics/run.js +72 -0
- package/dist/metrics/run.js.map +1 -0
- package/dist/platforms/azure/client.js +53 -0
- package/dist/platforms/azure/client.js.map +1 -0
- package/dist/platforms/azure/index.js +69 -0
- package/dist/platforms/azure/index.js.map +1 -0
- package/dist/platforms/azure/install.js +917 -0
- package/dist/platforms/azure/install.js.map +1 -0
- package/dist/platforms/azure/policy-types.js +70 -0
- package/dist/platforms/azure/policy-types.js.map +1 -0
- package/dist/platforms/azure/verify.js +309 -0
- package/dist/platforms/azure/verify.js.map +1 -0
- package/dist/platforms/detect.js +40 -0
- package/dist/platforms/detect.js.map +1 -0
- package/dist/platforms/github/client.js +49 -0
- package/dist/platforms/github/client.js.map +1 -0
- package/dist/platforms/github/index.js +54 -0
- package/dist/platforms/github/index.js.map +1 -0
- package/dist/platforms/github/install.js +558 -0
- package/dist/platforms/github/install.js.map +1 -0
- package/dist/platforms/github/push.js +102 -0
- package/dist/platforms/github/push.js.map +1 -0
- package/dist/platforms/github/remote.js +36 -0
- package/dist/platforms/github/remote.js.map +1 -0
- package/dist/platforms/github/verify.js +366 -0
- package/dist/platforms/github/verify.js.map +1 -0
- package/dist/platforms/http.js +58 -0
- package/dist/platforms/http.js.map +1 -0
- package/dist/platforms/pull-request-templates.js +157 -0
- package/dist/platforms/pull-request-templates.js.map +1 -0
- package/dist/platforms/remote.js +21 -0
- package/dist/platforms/remote.js.map +1 -0
- package/dist/platforms/resolve.js +69 -0
- package/dist/platforms/resolve.js.map +1 -0
- package/dist/platforms/shape.js +19 -0
- package/dist/platforms/shape.js.map +1 -0
- package/dist/platforms/types.js +24 -0
- package/dist/platforms/types.js.map +1 -0
- package/dist/policy/checks.js +91 -0
- package/dist/policy/checks.js.map +1 -0
- package/dist/policy/diff.js +50 -0
- package/dist/policy/diff.js.map +1 -0
- package/dist/registry/discover.js +74 -0
- package/dist/registry/discover.js.map +1 -0
- package/dist/registry/serialize.js +41 -0
- package/dist/registry/serialize.js.map +1 -0
- package/dist/registry/types.js +2 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/remove/host.js +294 -0
- package/dist/remove/host.js.map +1 -0
- package/dist/render/commands.js +139 -0
- package/dist/render/commands.js.map +1 -0
- package/dist/render/manifest.js +82 -0
- package/dist/render/manifest.js.map +1 -0
- package/dist/render/markers.js +166 -0
- package/dist/render/markers.js.map +1 -0
- package/dist/render/profile.js +23 -0
- package/dist/render/profile.js.map +1 -0
- package/dist/render/standards.js +169 -0
- package/dist/render/standards.js.map +1 -0
- package/dist/render/vendors.js +199 -0
- package/dist/render/vendors.js.map +1 -0
- package/dist/review/engines/api.js +95 -0
- package/dist/review/engines/api.js.map +1 -0
- package/dist/review/engines/embedded.js +20 -0
- package/dist/review/engines/embedded.js.map +1 -0
- package/dist/review/engines/types.js +2 -0
- package/dist/review/engines/types.js.map +1 -0
- package/dist/review/glob.js +29 -0
- package/dist/review/glob.js.map +1 -0
- package/dist/review/prompt.js +45 -0
- package/dist/review/prompt.js.map +1 -0
- package/dist/review/rules.js +25 -0
- package/dist/review/rules.js.map +1 -0
- package/dist/review/schema.js +84 -0
- package/dist/review/schema.js.map +1 -0
- package/dist/review/scope.js +27 -0
- package/dist/review/scope.js.map +1 -0
- package/dist/sarif/map.js +58 -0
- package/dist/sarif/map.js.map +1 -0
- package/dist/sarif/parse.js +88 -0
- package/dist/sarif/parse.js.map +1 -0
- package/dist/sarif/types.js +2 -0
- package/dist/sarif/types.js.map +1 -0
- package/dist/sync/host.js +21 -0
- package/dist/sync/host.js.map +1 -0
- package/dist/sync/plan.js +47 -0
- package/dist/sync/plan.js.map +1 -0
- package/dist/sync/render.js +57 -0
- package/dist/sync/render.js.map +1 -0
- package/dist/sync/run.js +118 -0
- package/dist/sync/run.js.map +1 -0
- package/dist/verify/host.js +52 -0
- package/dist/verify/host.js.map +1 -0
- package/dist/verify/remote.js +146 -0
- package/dist/verify/remote.js.map +1 -0
- package/package.json +52 -0
- package/platforms/azure/gate-template.yml +105 -0
- package/rulesets/redline-org-ruleset.json +46 -0
- package/rulesets/redline-ruleset.json +49 -0
- package/scripts/assign-rule-ids.mjs +129 -0
- package/scripts/build-baseline.mjs +124 -0
- package/scripts/build-correlation.mjs +74 -0
- package/scripts/build-dashboard.mjs +584 -0
- package/scripts/build-digest.mjs +164 -0
- package/scripts/build-inbox.mjs +133 -0
- package/scripts/build-registry.mjs +42 -0
- package/scripts/build-roi.mjs +181 -0
- package/scripts/check-pins.mjs +88 -0
- package/scripts/collect-telemetry.mjs +300 -0
- package/scripts/lib/__tests__/baseline.test.mjs +132 -0
- package/scripts/lib/__tests__/correlate.test.mjs +131 -0
- package/scripts/lib/__tests__/dora.test.mjs +110 -0
- package/scripts/lib/__tests__/exemptions.test.mjs +85 -0
- package/scripts/lib/__tests__/metrics-scanner.test.mjs +65 -0
- package/scripts/lib/__tests__/sarif.test.mjs +125 -0
- package/scripts/lib/__tests__/spend.test.mjs +64 -0
- package/scripts/lib/baseline.mjs +156 -0
- package/scripts/lib/correlate.mjs +125 -0
- package/scripts/lib/dora.mjs +133 -0
- package/scripts/lib/exemptions.mjs +79 -0
- package/scripts/lib/metrics.mjs +172 -0
- package/scripts/lib/rules.mjs +107 -0
- package/scripts/lib/sarif.mjs +108 -0
- package/scripts/lib/spend.mjs +69 -0
- package/scripts/measure-context.mjs +101 -0
- package/scripts/render-self.mjs +18 -0
- package/scripts/score-seeds.mjs +294 -0
- package/scripts/validate.mjs +394 -0
- package/standards/core.md +124 -0
- package/standards/manifest.json +214 -0
- package/standards/stacks/csharp.md +29 -0
- package/standards/stacks/go.md +30 -0
- package/standards/stacks/java.md +30 -0
- package/standards/stacks/javascript.md +42 -0
- package/standards/stacks/kotlin.md +27 -0
- package/standards/stacks/microservices.md +37 -0
- package/standards/stacks/nodejs.md +34 -0
- package/standards/stacks/python.md +29 -0
- package/standards/stacks/react-native.md +29 -0
- package/standards/stacks/react.md +46 -0
- package/standards/stacks/swift.md +26 -0
- package/standards/stacks/terraform.md +27 -0
- package/templates/CODEOWNERS +29 -0
- package/templates/azure/pull_request_template.md +72 -0
- package/templates/github/pull_request_template.md +72 -0
- package/templates/redline.yml +35 -0
- package/templates/repo-context.md +64 -0
- package/workflows/dashboard.yml +119 -0
- package/workflows/inbox.yml +97 -0
- package/workflows/redline-collect.yml +61 -0
- package/workflows/redline-gate.yml +301 -0
- package/workflows/redline-sync.yml +79 -0
- package/workflows/seed-canary.yml +231 -0
- package/workflows/verify-onboarding.yml +115 -0
- package/workflows/weekly-digest.yml +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mohamed Elzanaty
|
|
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,188 @@
|
|
|
1
|
+
# Redline
|
|
2
|
+
|
|
3
|
+
Engineering oversight layer for AI-assisted development at enterprise scale, built on
|
|
4
|
+
GitHub-native primitives: automated code review against versioned standards, branch
|
|
5
|
+
rulesets, reusable Actions workflows, and Pages. No servers, no SaaS, no per-seat fee
|
|
6
|
+
beyond the AI licences already paid for.
|
|
7
|
+
|
|
8
|
+
One system covering the full delivery loop: AI writes code, automated review against
|
|
9
|
+
versioned standards, readiness gates, decision log, org-wide inbox — plus the measurement
|
|
10
|
+
and distribution that let it evolve from data rather than opinion.
|
|
11
|
+
|
|
12
|
+
**Vendor-neutral.** The rules live once in `standards/` and render to GitHub Copilot,
|
|
13
|
+
OpenAI Codex / `AGENTS.md`, and Claude. A Cursor adapter exists but ships disabled
|
|
14
|
+
(`vendors.cursor.enabled: false` in `standards/manifest.json`). See
|
|
15
|
+
[docs/vendors.md](docs/vendors.md).
|
|
16
|
+
|
|
17
|
+
## What's in the box
|
|
18
|
+
|
|
19
|
+
| Path | What | Where it lives in production |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| `standards/core.md` | Core standards: security, type safety, error handling, scope, and the severity output contract | source of truth — **the only file a human edits** |
|
|
22
|
+
| `standards/stacks/*.md` | Per-stack rules: javascript, react, react-native, nodejs, microservices, java, go, python, csharp, kotlin, swift, terraform | source of truth |
|
|
23
|
+
| `standards/manifest.json` | Stack globs, profiles, vendor toggles, standards version | source of truth |
|
|
24
|
+
| `cli/` | The `redline` CLI (`redline init`, `redline verify`) — detects the platform, renders standards, installs the gate | run via `npx redlinegate`, or `redline` once installed with `npm i -g redlinegate` |
|
|
25
|
+
| `.github/pull_request_template.md` | Readiness checklist + ADR link | every onboarded repo |
|
|
26
|
+
| `templates/repo-context.md` | Per-repo context template | reference only — a human copies it above the generated block in `AGENTS.md`; `redline init` never installs it |
|
|
27
|
+
| `templates/CODEOWNERS` | Reference shape of the CODEOWNERS pattern that makes `require_code_owner_review` real and protects the enforcement surface | `redline init` writes `.github/CODEOWNERS` on GitHub repos with equivalent content built in code — it does not read this file |
|
|
28
|
+
| `templates/redline.yml` | Thin caller installed as `.github/workflows/redline.yml` | every onboarded repo |
|
|
29
|
+
| `rulesets/redline-ruleset.json` | Reference shape of the per-repo branch ruleset: 1 human approval, thread resolution, automatic review, required `redline-gate / gate` check | nothing reads this file — `redline init` builds the equivalent ruleset at runtime |
|
|
30
|
+
| `rulesets/redline-org-ruleset.json` | Same rules applied org-wide by custom repository property — no per-repo drift | applied once at org level |
|
|
31
|
+
| `workflows/redline-gate.yml` | Reusable gate: checklist, ADR-for-big-diffs, dependency review, diff secret scan, label-aware aggregation | org `.github` repo |
|
|
32
|
+
| `workflows/redline-sync.yml` | Distributes standards, gate caller and template to onboarded repos as PRs — **disabled in Phase 1**, see [CHANGELOG.md](CHANGELOG.md) | this (source) repo |
|
|
33
|
+
| `workflows/redline-collect.yml` + `scripts/collect-telemetry.mjs` | Nightly central pull of review outcomes across the org | `redline-metrics` repo |
|
|
34
|
+
| `workflows/weekly-digest.yml` + `scripts/build-digest.mjs` | Monday Teams digest as an Adaptive Card | `redline-metrics` repo |
|
|
35
|
+
| `workflows/inbox.yml` + `scripts/build-inbox.mjs` | Org-wide prioritised PR inbox on GitHub Pages | this (source) repo |
|
|
36
|
+
| `workflows/dashboard.yml` + `scripts/build-dashboard.mjs` | Static dashboard on Pages: acted-on rate, trends, seed recall history, the rule tuning queue | `redline-metrics` repo |
|
|
37
|
+
| `workflows/seed-canary.yml` | Weekly regression test of the reviewer itself: opens a seeded PR, scores it, closes it | `redline-metrics` repo |
|
|
38
|
+
| `workflows/verify-onboarding.yml` | Weekly re-verification of every onboarded repo; opens an issue on drift — **disabled in Phase 1**, see [CHANGELOG.md](CHANGELOG.md) | this (source) repo |
|
|
39
|
+
| `scripts/validate.mjs` | Bundle self-check, run by this repo's CI | this repo |
|
|
40
|
+
| `scripts/check-pins.mjs` | Re-resolves SHA-pinned actions against their upstream tag | this repo's CI |
|
|
41
|
+
| `scripts/assign-rule-ids.mjs` | Assigns and verifies the stable `<stack>/<slug>` id on every rule | this repo |
|
|
42
|
+
| `seeded/` | Recall corpus (12 stacks, 82 BLOCKER seeds) + precision corpus, scored by `scripts/score-seeds.mjs` | validation only, never merged |
|
|
43
|
+
|
|
44
|
+
## Language coverage vs org reality
|
|
45
|
+
|
|
46
|
+
Primary-language tally across the org's active repos (2026-09-01):
|
|
47
|
+
Java 187 · TypeScript 86 · Python 47 · JavaScript 32 · HCL 24 · C# 22 ·
|
|
48
|
+
Kotlin 14 · Swift 9 · Go 6. All covered — including plain JavaScript, which the
|
|
49
|
+
TypeScript-only globs previously missed. Shell/Dockerfile/Gherkin intentionally uncovered
|
|
50
|
+
(linters serve better than LLM review there).
|
|
51
|
+
|
|
52
|
+
## Onboard a repository
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
cd your-repo
|
|
56
|
+
npx redlinegate init
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
That is the whole procedure. It detects your stack, renders the standards for it, installs
|
|
60
|
+
the merge-readiness template and the gate (advisory — it reports, it does not block),
|
|
61
|
+
turns on the security floor, and opens a pull request. Anything that needed repository
|
|
62
|
+
admin rights you do not have is listed at the end for an administrator to run.
|
|
63
|
+
|
|
64
|
+
Install it once and the everyday command is shorter:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
npm i -g redlinegate
|
|
68
|
+
redline verify
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The package is named `redlinegate`, not `redline` — that name is already taken on the public
|
|
72
|
+
npm registry by an unrelated package, so `npx redline …` always resolves to the wrong thing.
|
|
73
|
+
The binary it installs is named `redline`, which is why the everyday command reads `redline
|
|
74
|
+
init` / `redline verify` once it is installed rather than `redlinegate init`.
|
|
75
|
+
|
|
76
|
+
`redline verify` checks the repository still matches what it claims. Run it any time —
|
|
77
|
+
scheduled estate-wide re-verification is Phase 3 work, not yet wired up; see
|
|
78
|
+
[CHANGELOG.md](CHANGELOG.md) known limitations.
|
|
79
|
+
|
|
80
|
+
Both GitHub and Azure DevOps are supported. Redline detects which from your git remote.
|
|
81
|
+
|
|
82
|
+
## Verify before you trust
|
|
83
|
+
|
|
84
|
+
The single most common silent failure in a system like this is a required status check
|
|
85
|
+
whose name nothing ever reports: every PR sits on "Expected — waiting for status" forever.
|
|
86
|
+
|
|
87
|
+
Reusable workflows report as `<caller job id> / <called job id>`. Here that is
|
|
88
|
+
**`redline-gate / gate`**, and the name is pinned in two places: the ruleset JSON's
|
|
89
|
+
reference shape, and `scripts/validate.mjs` (CI fails if the job is renamed).
|
|
90
|
+
On GitHub, whether `redline init` makes it a *required* check depends on `--blocking`:
|
|
91
|
+
the default advisory install adds no `required_status_checks` rule at all, but
|
|
92
|
+
`redline init --blocking` writes `redline-gate / gate` into the ruleset
|
|
93
|
+
(`cli/platforms/github/install.ts`'s `REQUIRED_CHECK` constant, not a caller-supplied
|
|
94
|
+
value). `redline verify` reads back whatever the host currently has required and compares
|
|
95
|
+
it to what actually reported on the latest pull request: on a blocking install this is a
|
|
96
|
+
real assertion, failing if the check is required but never reported; on the default
|
|
97
|
+
advisory install nothing is required yet, so `verify` only surfaces the reported name for
|
|
98
|
+
a human to eyeball. See [CHANGELOG.md](CHANGELOG.md) known limitation 5. Run it on every
|
|
99
|
+
onboarded repo either way.
|
|
100
|
+
|
|
101
|
+
## Making a change to the standards
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
$EDITOR standards/stacks/react.md # 1. edit the source, never the output
|
|
105
|
+
node scripts/assign-rule-ids.mjs # 2. give any new rule a permanent id
|
|
106
|
+
$EDITOR standards/manifest.json # 3. bump version
|
|
107
|
+
node scripts/render-self.mjs # 4. re-render this repo's own artifacts
|
|
108
|
+
node scripts/validate.mjs # 5. self-check
|
|
109
|
+
$EDITOR CHANGELOG.md # 6. say what changed and why
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Rule ids are permanent. Reword a rule freely; never edit its id, or every historical
|
|
113
|
+
telemetry record for it orphans and the tuning history resets.
|
|
114
|
+
|
|
115
|
+
Distribution to already-onboarded repos (`redline sync`) is Phase 3 — see
|
|
116
|
+
[CHANGELOG.md](CHANGELOG.md). Until then, an onboarded repo picks up a standards change by
|
|
117
|
+
re-running `redline init`. Redline never pushes to a default branch; every change lands as
|
|
118
|
+
a pull request a team reviews and merges itself.
|
|
119
|
+
|
|
120
|
+
## Two version axes
|
|
121
|
+
|
|
122
|
+
Redline carries two versions that move independently. Do not conflate them.
|
|
123
|
+
|
|
124
|
+
| Axis | Lives in | Bumped by | Example |
|
|
125
|
+
| --- | --- | --- | --- |
|
|
126
|
+
| **CLI version** | `redlinegate` on npm (git `v*` tags) | semantic-release, from conventional commits on `main` | `0.0.1` |
|
|
127
|
+
| **Standards version** | `standards/manifest.json` → `version` | A human, in the same PR as the rule change (see above) | `0.0.1` |
|
|
128
|
+
|
|
129
|
+
The CLI version is the tool's release line: [CHANGELOG.md](CHANGELOG.md) tracks it, and
|
|
130
|
+
semantic-release computes the next one from commit messages — never edit
|
|
131
|
+
`package.json`'s `version` by hand. The standards version is the rules' release line:
|
|
132
|
+
sync PRs and rendered artifacts quote it, so a repo always knows which ruleset it is
|
|
133
|
+
running. A CLI release does not imply a standards change, and vice versa.
|
|
134
|
+
|
|
135
|
+
Each onboarded repo's `.redline.json` records both — `cliVersion` (the tool that
|
|
136
|
+
onboarded it) and `standardsVersion` (the ruleset it was rendered from) — so `redline
|
|
137
|
+
verify` can tell "old tool" apart from "old rules".
|
|
138
|
+
|
|
139
|
+
Releases publish from `.github/workflows/release.yml`: every same-repo PR checks that
|
|
140
|
+
the pinned release toolchain still resolves from the lockfile (`semantic-release
|
|
141
|
+
--dry-run`, which exits early on PR context — no secrets in the job), a manual
|
|
142
|
+
`workflow_dispatch` rehearses the real publish path with a throwaway build on the npm
|
|
143
|
+
`canary` dist-tag without touching `latest`, and the real publish on `main` runs the
|
|
144
|
+
exact semantic-release version pinned in the lockfile.
|
|
145
|
+
|
|
146
|
+
## Why this works at enterprise scale
|
|
147
|
+
|
|
148
|
+
- **Feedback loop that measures the right thing.** Every rule carries a permanent id,
|
|
149
|
+
every finding cites one, and telemetry records not just how often a rule fired but how
|
|
150
|
+
often it was *acted on* — resolved threads versus findings left stale and outdated. The
|
|
151
|
+
dashboard turns that into a tuning queue: the specific rules to cut, named. See
|
|
152
|
+
[docs/measurement.md](docs/measurement.md).
|
|
153
|
+
- **The reviewer itself is regression-tested.** A weekly canary opens a PR of known-bad
|
|
154
|
+
code against a pilot repo, scores what came back against 82 seeded BLOCKER defects and
|
|
155
|
+
a corpus of correct code that must draw zero comments, then closes it. "No findings"
|
|
156
|
+
and "nothing to find" are otherwise indistinguishable.
|
|
157
|
+
- **Distribution.** One source of truth, rendered per profile. `redline sync` — syncing
|
|
158
|
+
standards to already-onboarded repos as reviewable PRs — is Phase 3 (see
|
|
159
|
+
[CHANGELOG.md](CHANGELOG.md)); until then a repo picks up a standards change by
|
|
160
|
+
re-running `redline init`. Never copy-paste per project, never a stale rule file left
|
|
161
|
+
behind when a repo changes stack.
|
|
162
|
+
- **Hard enforcement.** Org-level ruleset plus a required check that is name-verified.
|
|
163
|
+
CODEOWNERS on the enforcement surface, so nobody can weaken their own gate unreviewed.
|
|
164
|
+
- **A real security floor.** Secret scanning with push protection, Dependabot alerts,
|
|
165
|
+
dependency review and a diff secret scan — enabled by `redline init`, not assumed.
|
|
166
|
+
Security checks in the gate can never be label-exempted. On GitHub, that is; see
|
|
167
|
+
[CHANGELOG.md](CHANGELOG.md) for what Azure DevOps does not yet get at the gate.
|
|
168
|
+
- **Least privilege.** Telemetry is pulled centrally with a read-only token. Onboarding a
|
|
169
|
+
repo grants Redline no write access to it.
|
|
170
|
+
- **Enterprise shape.** Per-stack rule composition, human approval always required, full
|
|
171
|
+
audit trail native to GitHub.
|
|
172
|
+
|
|
173
|
+
## Design decisions
|
|
174
|
+
|
|
175
|
+
- Automated review is **advisory input to a human**, never the approver. The ruleset
|
|
176
|
+
requires one human approval regardless, and `validate.mjs` fails if that is ever
|
|
177
|
+
lowered to zero.
|
|
178
|
+
- Standards carry an explicit **output contract** (`Redline/BLOCKER:` …). Without it,
|
|
179
|
+
severity is unparseable and every metric downstream is a guess.
|
|
180
|
+
- Standards carry explicit **What NOT to flag** sections — AI review dies by nitpick
|
|
181
|
+
spam, so noise control is a first-class rule and a measured one.
|
|
182
|
+
- Everything distributes as **PRs, never pushes** — teams see and own changes to their
|
|
183
|
+
gates.
|
|
184
|
+
- The gate separates **process checks from security checks**. `redline-exempt` downgrades
|
|
185
|
+
the checklist and ADR requirements to warnings for a reviewer who accepts the
|
|
186
|
+
trade-off; it does nothing to dependency review or the secret scan.
|
|
187
|
+
- **Profiles, not glob negation.** Rule sets that would contradict each other are never
|
|
188
|
+
installed in the same repo, so no rule depends on unsupported negation syntax.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Onboard this repository to Redline — standards, security floor and merge gate
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run `npx redlinegate init` in the repository root and report what it printed. Do not run
|
|
6
|
+
plain `npx redline` — that resolves to an unrelated package on the public registry; the
|
|
7
|
+
published package is `redlinegate`. If the engineer already has it installed
|
|
8
|
+
(`npm i -g redlinegate`), the everyday command is just `redline init`.
|
|
9
|
+
|
|
10
|
+
The command is not interactive by default. If the engineer asked for something specific,
|
|
11
|
+
pass it through:
|
|
12
|
+
|
|
13
|
+
- a stack override: `--profile <name>`
|
|
14
|
+
- which vendors to render for: `--vendors <list>` (comma-separated: copilot, agents, claude,
|
|
15
|
+
cursor) — overrides both detection and whatever `.redline.json` already recorded, capped by
|
|
16
|
+
whatever the org manifest enables
|
|
17
|
+
- a blocking rather than advisory gate: `--blocking`
|
|
18
|
+
- the plan only, writing nothing and changing no repository setting: `--dry-run`
|
|
19
|
+
- re-apply every capability even on a repository that looks already onboarded: `--repair` —
|
|
20
|
+
the fix once an administrator grants rights that a plain re-run cannot recheck on its own
|
|
21
|
+
(labels, review ownership, the repo property, the gate, the merge policy)
|
|
22
|
+
- capabilities this repository does not want Redline to install because it already has its
|
|
23
|
+
own: `--skip <list>` (comma-separated: gate, merge-policy, labels, review-ownership), and
|
|
24
|
+
`--with <list>` to select one again. A deselected capability is not attempted, not written
|
|
25
|
+
and not reported by `redline verify` as missing — it is reported as off by choice. The
|
|
26
|
+
security floor is the organisation-wide minimum: `--skip security-floor` is refused by name
|
|
27
|
+
rather than quietly ignored
|
|
28
|
+
- `--no-a11y` and `--speckit` are recorded in `.redline.json` for later phases; they change
|
|
29
|
+
nothing in Phase 1, so do not describe them to the engineer as having taken effect
|
|
30
|
+
|
|
31
|
+
Flags you do not pass keep whatever `.redline.json` already recorded — re-running without
|
|
32
|
+
`--blocking` on a repository onboarded with it does not demote the gate.
|
|
33
|
+
|
|
34
|
+
When it finishes, tell them three things and nothing else:
|
|
35
|
+
|
|
36
|
+
1. which profile was detected and what was written
|
|
37
|
+
2. the pull request URL
|
|
38
|
+
3. anything under `partially onboarded` — that list needs a repository administrator, and
|
|
39
|
+
until it is cleared this repository is not fully onboarded
|
|
40
|
+
|
|
41
|
+
A bad flag, an unknown profile, or a host failure all exit non-zero. What exits `0` is a
|
|
42
|
+
**denied** capability — the operator lacks the rights, so it is recorded in `.redline.json`
|
|
43
|
+
under `pendingAdmin` for an administrator to grant later. A capability the host reports as
|
|
44
|
+
**unsupported** — for example Azure DevOps Advanced Security when it isn't licensed on this
|
|
45
|
+
repository — is different again: it is never pending admin work, and never appears in
|
|
46
|
+
`pendingAdmin`, because there is nothing an administrator here could grant. A capability the
|
|
47
|
+
host answers with **unknown** — an indeterminate read the host cannot tell apart from a
|
|
48
|
+
genuine refusal — is treated the same way: never filed as pending admin work either, because
|
|
49
|
+
an indeterminate read has told nobody anything they can act on.
|
|
50
|
+
|
|
51
|
+
Do not edit the files it generated. Content inside `<!-- REDLINE:BEGIN -->` markers is
|
|
52
|
+
owned by Redline and is regenerated on the next `redline init` run; content outside the
|
|
53
|
+
markers in a merged file (`AGENTS.md`, `CLAUDE.md`, `.github/copilot-instructions.md`,
|
|
54
|
+
the pull request template) is the team's own and is never touched.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Check this repository still matches the standards and guardrails it claims
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run `npx redlinegate verify` in the repository root and report the findings table. Do not run
|
|
6
|
+
plain `npx redline` — that resolves to an unrelated package on the public registry; the
|
|
7
|
+
published package is `redlinegate`. If the engineer already has it installed
|
|
8
|
+
(`npm i -g redlinegate`), the everyday command is just `redline verify`. Add `--gate` if the
|
|
9
|
+
engineer wants an explicit pass/fail summary line printed after the table, such as when
|
|
10
|
+
running this by hand to mirror what CI's gate check sees.
|
|
11
|
+
|
|
12
|
+
Each line is a check. For any `FAIL`, explain what it means and what fixes it:
|
|
13
|
+
|
|
14
|
+
- `onboarded` — the repository has no `.redline.json`. Run `redline init`.
|
|
15
|
+
- `capabilities` — never a `FAIL`. It names what this repository deselected at onboarding, so
|
|
16
|
+
the report describes the whole surface. The checks a deselection governs say `off by choice`
|
|
17
|
+
in their own detail rather than reporting the capability as missing: that is the difference
|
|
18
|
+
between "off because we chose to" and "off because it broke".
|
|
19
|
+
- `merge-policy` — no Redline merge policy was found on the host at all, or the live one has
|
|
20
|
+
been loosened, or the ruleset that carries it is no longer in force. The finding names what
|
|
21
|
+
changed: the blocking flag, the approval count, dismissing approvals on push, code-owner
|
|
22
|
+
review, unresolved-thread resolution — or, on Azure, a blocking Status policy with no
|
|
23
|
+
matching Build Validation policy to queue the gate pipeline, so the status is never
|
|
24
|
+
published and every pull request sits blocked; re-run `redline init` with build
|
|
25
|
+
administrator rights. Settings the host cannot attribute to Redline are listed as
|
|
26
|
+
"not compared here" rather than held against the repository. A repository that deselected
|
|
27
|
+
the merge policy is not compared at all — except where Redline itself applied a blocking
|
|
28
|
+
policy before the deselection: that ruleset is still live, still requires the Redline check,
|
|
29
|
+
and fails here while nothing in the repository publishes it.
|
|
30
|
+
- `gate-machinery` — the file that runs the gate is missing from this repository, the job that
|
|
31
|
+
publishes the required check has been renamed, the file is present and correctly named but no
|
|
32
|
+
pull request will ever trigger it, or the job is unchanged but the merge policy now requires a
|
|
33
|
+
different check name. Nothing will ever report the gate, so a blocking policy blocks every pull
|
|
34
|
+
request forever. Re-run `redline init` to restore the file or reapply the policy. Only rename
|
|
35
|
+
the job back if the workflow itself was the thing that changed — if the policy is what moved,
|
|
36
|
+
the job is already correct, and renaming it is the wrong fix. A repository that deselected the
|
|
37
|
+
gate passes here, and is told whether the workflow an earlier run installed is still sitting
|
|
38
|
+
there — a deselection never deletes it.
|
|
39
|
+
- `check-name-reported` — a check ran on the pull request but the required name was never among
|
|
40
|
+
the ones reported. Where the policy blocks, this blocks every pull request in the repository.
|
|
41
|
+
Fix the caller job id, or the policy. "No gate run observed yet" is not a failure: no Redline
|
|
42
|
+
gate run has published anything on that pull request's head commit — other CI may well have —
|
|
43
|
+
and `gate-machinery` above is what says whether one ever could.
|
|
44
|
+
- `security-floor` — secret scanning, push protection or dependency alerts has been turned off.
|
|
45
|
+
A capability nothing could observe is named as unconfirmed, never counted as enabled.
|
|
46
|
+
- `artifacts-current` — the rendered standards are stale against the version this repository
|
|
47
|
+
recorded. A version difference in either direction is reported without failing, because
|
|
48
|
+
neither is drift: a newer version upstream is adopted by `redline init`, and an older one
|
|
49
|
+
means this CLI is behind the repository and wants updating, not re-running.
|
|
50
|
+
- `pull-request-template` — the template the host actually serves is gone, has a broken
|
|
51
|
+
`REDLINE:BEGIN`/`REDLINE:END` pair, or is missing a section the gate checks for, so the gate
|
|
52
|
+
fails pull requests opened from it. Re-run `redline init` — but a mangled marker pair has to
|
|
53
|
+
be repaired by hand first, because `init` refuses to write to it.
|
|
54
|
+
- `pending-admin` — a repository administrator still has work to do. Only capabilities a read
|
|
55
|
+
came back with an answer for are listed as work to chase. Entries the host reported as
|
|
56
|
+
unavailable, and entries no read can answer at all (labels, review ownership, the repo
|
|
57
|
+
property, the gate, the merge policy), are listed separately as recorded-but-unactionable.
|
|
58
|
+
Under `--gate` only the actionable ones fail, so a record only `redline init` can clear does
|
|
59
|
+
not block every pull request in the repository.
|
|
60
|
+
|
|
61
|
+
A capability the host reports as **unsupported** — for example Azure DevOps Advanced Security
|
|
62
|
+
when it isn't licensed on this repository — is not the same as **denied**: it is never listed
|
|
63
|
+
as work an administrator must do, because there is no administrator action that would change
|
|
64
|
+
it. A capability the host answers with **unknown** — a 401/403 this host cannot tell apart
|
|
65
|
+
from a genuine refusal — is treated the same way for the same reason: an indeterminate read
|
|
66
|
+
is not an answer, so it is never counted as work to chase either. Both are still named, so
|
|
67
|
+
nobody mistakes silence for a clean bill.
|
|
68
|
+
|
|
69
|
+
Do not attempt to fix host settings yourself. Report and stop.
|