Onboard a repository
One command per repo. redline detects GitHub or Azure DevOps from your git remote, installs the floor, and opens a pull request — never a direct push.
$ npx redlinegate init ok profile web-react write AGENTS.md write CLAUDE.md write .github/copilot-instructions.md applied secret-scanning applied push-protection denied dependency-alerts needs admin ⚠ partially onboarded — an administrator must still enable: dependency-alerts pull request: https://github.com/acme/checkout-service/pull/42
Before you start
redlinegate@0.1.3 is the version on npm's latest tag. Every command on this page installs it.
- Node.js 22 or newer on the machine running the CLI.
- A git repository whose remote points at GitHub — including GitHub Enterprise Server, if the hostname contains
github— or Azure DevOps. A self-hosted host on a hostname that carries neither is not auto-detected. - Nothing to install:
npx redlinegatefetches the CLI on demand. The npm package isredlinegate; the command it installs isredline.
Two version lines run separately and neither is derived from the other. The package version is the CLI on npm, computed by semantic-release at publish time. The standards version is standards/manifest.json → version, currently 0.1.0; every rendered artifact and every sync pull request names it, so a repository can always say which standard its files came from.
The whole sequence
redline init is one command, but onboarding is not one step. Steps 4 and 5 are the ones most often skipped, and skipping them leaves a repository that reports as onboarded and enforces nothing.
| # | Step | Who |
|---|---|---|
| 1 | npx redlinegate init --dry-run — read the plan. Writes nothing, needs no credential, contacts no host. | anyone |
| 2 | npx redlinegate init — files, whatever repository settings your token allows, and a pull request. Never a direct push. | anyone with push |
| 3 | Review and merge that pull request. Until it merges, the gate exists only on its own branch. | a reviewer |
| 4 | npx redlinegate init --repair with an admin token — applies everything the first run recorded in pendingAdmin, including the branch ruleset that makes the check required. | repo admin |
| 5 | Run the nine verification scenarios — watch the gate pass, block, and refuse to be waived. | anyone with push |
| 6 | Soak at observe, then promote: redline init --rung warn, later block-blocker. A promotion the recorded evidence does not support is refused. | the team |
Step 4 is not optional cleanup. A non-admin run installs the workflow and opens the pull request, so the gate runs — but nothing marks its check required, and no ruleset requires an approval. Every check can be clicked past. The repository looks onboarded on the dashboard and a merge is still one button.
What it installs — the floor, no opt-out
- Rendered standards for the detected profile, plus the review output contract — Copilot, AGENTS.md, CLAUDE.md, Cursor, whichever vendors the manifest enables.
- Context sections, where selected — background about how this repository works, rendered into the same artifacts as the rules and carrying no rule ids, because they are chosen per repository rather than by stack. Spec-first is on by default; TM Forum is opt-in.
- Security floor — secret scanning with push protection and dependency alerts; anything it couldn't enable is reported, not silently skipped.
- Merge-readiness gate, advisory — one human approval always, plus the required check name. It reports; it does not block, until promoted deliberately.
.redline.json— profile, vendors, menu choices, pending-admin list, and the standards/CLI versions that produced it. This is what makes the repo visible to central telemetry — read-only, no secret is ever written to the repo.
Menu — offered, defaulted, skippable
| Flag | Default | Effect in Phase 1 |
|---|---|---|
--blocking | off | Promotes the gate from advisory to blocking. |
--profile <name> | detected | Overrides stack detection. |
--vendors <list> | detected | Comma-separated vendor ids (copilot,agents,codex,claude,cursor) to render for — overrides detection and any recorded selection; a vendor the org has not enabled never renders regardless. |
--dry-run | off | Prints the plan — files, repository settings, resolved menu — and exits; writes nothing, needs no credential. |
--no-commit | off | Writes the files into your working tree and stops — no setting changed, no branch, no pull request. Offline, so an org-sourced caller is written without confirming the organisation publishes the gate it references. |
--gate-source org|local | org | Where the gate machinery lives — see below. Omitting it keeps whatever the repository already recorded. |
--repair | off | Re-applies capabilities a plain re-run treats as already settled — the fix once an administrator grants rights a read can never confirm on its own. |
--no-a11y | on | Recorded in .redline.json; doesn't change what's rendered yet. |
--speckit / --no-speckit | on | Renders the spec-first context section into the standards artifacts. Dropped automatically, with a note in the report, where the repository already runs Spec Kit — that is a separate tool with its own installer, and Redline neither creates nor edits its files. --no-speckit on a later run removes a section already rendered. |
--tmf / --no-tmf | off | Renders the TM Forum context section — resource naming, @type/@baseType, offset/limit paging, the TMF error body. Ask for it only in a repository that actually implements TMF interfaces. |
--with review-ownership | off | Seeds .github/CODEOWNERS and lets the ruleset require code-owner review. Off by default — see Name an owner that exists. |
--review-owners <list> | @<org>/platform-engineering | Who owns the paths seeded into CODEOWNERS — a team, a user or an email, comma-separated. Set this: the default is a guess, and a wrong owner fails silently. |
--rung <name> | observe | observe, warn, block-blocker, block-high — the enforcement ladder. |
--skip <list> / --with <list> | — | Capabilities this repository does not want Redline to install, because it has its own. A deselected capability is not attempted, not written and not reported as missing. The security floor is refused by name rather than deselected. |
--integrations <list> | detected | Controls you already run (sonarqube,snyk,mend,dependabot,renovate,gitleaks,trufflehog,codeql). This is what writes stand-down: into the caller — from what you declared, never from detection alone, because detection reads a checkout and cannot see a scanner wired through a shared pipeline template. |
--setup <list> | off | Controls to install alongside Redline: dependabot, renovate, codeql. Only what works with no account and no token. An existing file is never overwritten. |
--pipeline <name> | detected | github-actions or azure-pipelines — what actually runs this repository's pull request checks. Asked separately from the host, because the two come apart: a repository on GitHub can be built entirely by Azure Pipelines, and installing an Actions workflow there gates nothing. |
--branches <patterns> | default branch | Which branches the merge policy governs, in the host's own syntax. Widening this widens an enforcement boundary, so it is never detected for you. |
--adopt-caller | off | Lets Redline take over gate machinery already at its path when what is there carries nothing attributing it to Redline — a 2.1 caller, in practice. Without it the run refuses rather than clobbering somebody's workflow. |
Name an owner that exists
--with review-ownership is the mitigation for a vendored gate, and the single most common way to install it wrong is to accept the default owner.
GitHub ignores a CODEOWNERS owner it cannot resolve, and it does so without erroring: no failed push, no warning in the UI. The file installs, the ruleset requires code-owner review, and the review is required of nobody. That is worse than not installing it, because the dashboard now says the control is on.
- A team must be written
@org/teamand must actually exist. A bare@platform-engineeringis read as a user, and a user that does not exist makes GitHub mark the whole file erroneous — at which pointrequire_code_owner_reviewdegrades to the silent no-op above. - A repository under a personal account has no teams at all.
@you/platform-engineeringcannot exist there, so pass your own handle:--review-owners @you. redline verifyreportsreview-ownership, which resolves every owner in the file against the host. It is the check that tells an enforcingCODEOWNERSfrom a decorative one.
Where the gate lives
By default the caller workflow Redline writes references a reusable workflow published once at <org>/.github. One merge there reaches every onboarded repository, and the gate sits outside the blast radius of the pull requests it judges — nobody raising a pull request can change the thing reviewing it.
On GitHub, publish it once before the first repository onboards. Copy workflows/redline-gate.yml into your organisation's .github repository as .github/workflows/redline-gate.yml, so uses: <org>/.github/.github/workflows/redline-gate.yml@main resolves for every repo that follows. The secret-scan action ships pinned to a full commit SHA, and scripts/check-pins.mjs keeps it honest. Azure DevOps needs no equivalent step: redline init writes the whole pipeline template into the repository as .azuredevops/redline-gate.yml.
Most organisations do not have that repository on day one, and “go and get a shared .github repo created” is a long way to travel before finding out whether any of this is worth having. So --gate-source local vendors the gate into the repository itself at .github/workflows/redline-gate.yml and points the caller at it. It is the same file the organisation copy is published from. The required check name does not change — a local reusable workflow still reports as redline-gate / gate — so rulesets, branch policy and redline verify are identical either way, and moving between the two is a re-run with a different flag.
A vendored gate is the weaker control, not an equal one. A workflow triggered by pull_request runs from the pull request's own head commit, so a pull request that edits .github/workflows/redline-gate.yml changes the gate judging it — including standing down the dependency and secret jobs, which are the two checks no label can waive. Protect .github/workflows/ with --with review-ownership --review-owners <team> so that edit needs an owner's approval, and move to --gate-source org once the organisation publishes a gate.
A vendored gate is a copy, so it does not update itself the way the organisation one does. redline verify reports a gate-vendored check comparing the version stamped in the file against the CLI running the check; redline init --repair brings it level.
A repo installs exactly one profile — see Profiles & stacks for the full table.
Permission degradation is the normal path
The engineer running redline init usually doesn't have repo admin. The command never aborts part-way: file-level work always lands, and the pull request always opens. Refused settings are recorded under pendingAdmin in .redline.json, and the command still exits 0.
pendingAdmin, unsupported and unknown are three different things. A denied capability goes in pendingAdmin — an admin can grant it later. Azure DevOps Advanced Security is separately licensed; an unlicensed repository reports it as unsupported, not pendingAdmin — no admin action clears it, so it doesn't sit on the dashboard forever demanding one. A read the host answered with neither a yes nor a definite no — a 401/403 it cannot tell apart from a genuine refusal — reports unknown instead, and is treated the same way: an indeterminate read is never filed as admin work either.
Verify
$ npx redlinegate verify ok onboarded profile web-react, standards v0.1.0 ok capabilities every capability selected ok merge-policy policy is advisory, config says advisory ok gate-machinery .github/workflows/redline.yml publishes redline-gate / gate ok check-name-reported no required check configured yet (advisory gate) — PR #42 reported: redline-gate / gate ok security-floor security floor enabled ok artifacts-current rendered artifacts match standards v0.1.0 ok review-ownership no CODEOWNERS on this host ok commands-current slash commands match what this CLI renders ok pull-request-template .github/pull_request_template.md — maintained inside REDLINE markers FAIL pending-admin partially onboarded — an administrator must still enable: dependency-alerts
Eleven checks, each named after what it reads. Three are worth knowing before you see them: check-name-reported is skipped rather than failed on a repository with no pull request yet — a fresh repo is not drifted, it is new; review-ownership resolves every owner in CODEOWNERS against the host, which is what tells an enforcing file from a decorative one; and pending-admin is the one that stays red until a person acts. Run it on demand, or wire redline verify --gate into CI — the same checks, exiting non-zero on failure. Troubleshooting has what ok, FAIL and ?? each oblige you to do.
The sample above is the default advisory install, where nothing is marked required yet, so check-name-reported only confirms the check is being reported at all. Onboard with --blocking and GitHub gets a real required check named redline-gate / gate — from then on this line reads required checks reported on PR #42: redline-gate / gate on success, and fails outright if that check is required but never reported.
After the pull request merges
Merging installs the files. It does not grant the permissions the first run was refused, and a plain re-run will not retry them — a capability already recorded as pending is treated as settled, which is exactly what --repair exists to override.
$ npx redlinegate init --repair applied secret-scanning applied push-protection applied dependency-alerts applied merge-policy branch ruleset — redline-gate / gate required applied repo-property redline=onboarded
Run it with a token that has repository admin. Everything under pendingAdmin in .redline.json is retried, and the file is rewritten with what actually stuck.
The approval trap. The ruleset requires one approving review, and GitHub does not let you approve your own pull request. On a repository with one active maintainer, the ruleset you just applied will block your next pull request with no way forward from inside the repository.
That is the policy working as designed — one human approval, always — but decide it deliberately rather than discovering it. If you work solo, add yourself as a bypass actor on the Redline ruleset. It is a real weakening and it is visible in the ruleset, which is the right place for it to be visible.
Then run the verification scenarios. Everything up to this point proves the gate is installed; only a pull request that the gate actually stopped proves it is a gate.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success. |
| 1 | The thing being checked is wrong — verification failed, drift found. |
| 2 | Usage error — bad flag, unknown profile, not a git repository. |
| 3 | Permission denied outright — nothing could be done at all. |
| 4 | Host or network error. |
3 is for total failure only. A partial permission failure is the normal path above: exit 0, with the refusals reported.
Known limitations
- The gate installs advisory-only on both hosts. Promoting it is a deliberate second step on the enforcement ladder, after a soak period.
redline syncruns from a checkout of the Redline source repository, not from a product repo, and only reaches repositories in the register — see Distribution & drift. One that is not in it picks up a standards change by re-runningredline init.- No offline single-file executable yet, which matters for air-gapped Azure agents without npm registry access.