护栏
铁路冷冻执行和压制-标记门(ADLC C5).
屏蔽建造器编辑 P4 期间被宣布为被冻结的铁路路径,并添加了greps diff线用于逃避测试/林特覆盖的压制标记. 在干净的 通过它可以记录 铁轨- diff- 空取证明 在城门上.
ADLC 阶段
C5——P3/P4执行. 位于P3(包机)之间的CI门内 (规划)和P4(建设者执行)。 守卫两个互不相干的人:
- 铁路冻结: 已申报的铁路路径(测试文件、合同类型、CI配置) 在P4期间,建设者不得触碰.
- 禁止标记门: 新添加
.skip(, (中文(简体) ),.only(, (中文(简体) ),xfail, (中文(简体) ),@ts-ignore, (中文(简体) ),@ts-expect-error, (中文(简体) ),eslint-disable, (中文(简体) ),# noqa, (中文(简体) ),#[ignore]线路被屏蔽,除非有效票body包含一个明确的allow-suppression: <marker>声明. 复制文档文件 (单位:千美元).md, (中文(简体) ),.markdown)被豁免于此扫描——道具中的标记从不是一种 已执行的压制,并且文件(包括本README)合法命名 在描述规则时标记..mdx实值 没有 免责: 它编译为 JSX/TS 并可以携带操作压制,所以扫描像代码一样.
使用量
rails-guard [--base <ref>] [--ticket <id>] [--tickets <path>] \
[--rails <glob>...] [--record] [--json]
旗帜
| 旗帜 | 默认 | 说明 |
|---|---|---|
--base <ref> | HEAD | 驳回 diff 对 |
--ticket <id> | —— 说 | 装入铁路和 allow-suppression 本票的申报 |
--tickets <path> | .adlc/tickets.json | 门票文件路径 |
--rails <glob> | —— 说 | 一个或多个被冻结的路径( 可重复; 覆盖) ticket.rails(中文(简体) ) |
--record | 关 | 在一张干净的通行证上,附上一个明确条目 .adlc/manifest.jsonl |
--json | 关 | Emit机器可读JSON结果 |
--help | —— 说 | 打印此帮助并退出 0 |
铁路源分辨率
- 若为
--rails提供软膜直接使用. - 否则
--ticket必须提供; 铁路来自ticket.rails。 。 。 . - 如果两者都不可用,则工具退出 1(操作错误).
允许压制声明
为了允许特定的压制标记,在售票机体上添加这个确切的文字:
allow-suppression: @ts-ignore
allow-suppression: .skip(
每行一个声明; 大小写敏感; 标记文本必须精确匹配 .
实例
# Check that no frozen test files were touched, fail on any suppression
rails-guard --rails "test/**" --rails "schema/**"
# Use rails declared in ticket T42; allow .skip( for known broken test
rails-guard --ticket T42 --tickets .adlc/tickets.json
# Diff against a feature branch base commit
rails-guard --rails "test/**" --base origin/main
# CI gate with machine-readable output + manifest record on clean pass
rails-guard --rails "test/**" --json --record
产出
可读( 默认)
干净 :
rails-guard: all checks passed
违反情况:
rails-guard: 2 violation(s) found
[rail-edit] test/auth.test.ts (matched globs: test/**)
[suppression] src/foo.ts:12 marker: @ts-ignore
// @ts-ignore
贾森(JSON)--json(中文(简体) )
{
"tool": "rails-guard",
"base": "HEAD",
"ticket": "T42",
"railGlobs": ["test/**"],
"railGlobError": null,
"railsDiffEmpty": true,
"suppressionsClean": false,
"sanctionedAdditions": [],
"passed": false,
"violations": [
{
"file": "src/foo.ts",
"type": "suppression",
"marker": "@ts-ignore",
"lineNo": 12,
"line": "// @ts-ignore"
}
]
}
明显记录--record只有干净的传球)
附录 .adlc/manifest.jsonl数字 :
{
"ts": "2026-06-10T12:00:00.000Z",
"type": "rails-check",
"ticket": "T42",
"base": "HEAD",
"railsDiffEmpty": true,
"suppressionsClean": true,
"sanctionedAdditions": ["test/frozen/new.test.mjs"],
"railFiles": {
"test/auth.test.ts": "abc123...",
"schema/types.ts": "def456..."
}
}
sanctionedAdditions (单位:千美元)--json 财务报告和审定财务报表 --record命名每一个铁路比对路径
通过 CI- 发出豁免 --sanctioned-add 此运行的旗帜—— 当没有使用时为空 .
railsDiffEmpty'它本身的意义不变:它仍然 true 当有零时
违反铁路管理、制裁或 #228 包括仅限版本的豁免。 一条路径
sanctionedAdditions 是纯粹的附加,从不编辑——豁免从来不沉默.
`railFiles` contains the SHA-256 of every repo file that matches a rail glob at
the time of the clean pass — a content-addressed snapshot usable for auditing.
## Exit codes
| Code | Meaning |
|------|---------|
| `0` | Gate passes — no violations |
| `1` | Operational error — not a git repo, bad input, no rails resolvable |
| `2` | Gate fails — violations found (list printed to stderr / JSON) |
## Violation types
| `type` | Meaning |
|--------|---------|
| `rail-edit` | A changed file matches a frozen rail glob |
| `suppression` | An added line contains a suppression marker not declared in the ticket |
## Immutable trust roots (CI gate)
The CI backstop `adlc rails-guard-ci` freezes a second set of paths on top of the
active ticket's rails: the **immutable trust roots** (#140). A trust root is a file
whose contents decide what the gate *enforces* — the config, the ticket-store
manifest, CODEOWNERS, the deployed workflow, and the gate's own sources. They are
frozen unconditionally, because a PR that can edit the enforcer can edit away its
own enforcement.
The default set lives in `DEFAULT_IMMUTABLE_TRUST_ROOTS`
(`lib/ci/trust-roots.mjs`) and applies to every repo with no configuration:
.adlc/config.json.adlc/admin.pub 页面存档备份,存于互联网档案馆 .adlc/tickets/.store.json.github/工作流程/adlc-rails-guard.yml • .github/ 守则 • 文献/守则管理员 文档/ci/rails-guard.yml脚本/rails-guard-ci.mjs 包/铁路护卫/lib/ci/** 包/铁路护卫/宾/铁路护卫-ci.mjs 包/铁道护卫/站/铁道护卫.mjs 包/铁路护卫/lib/信托-根-授权. mjs
**`package.json` and `.npmrc` are NOT in the default set.** They were briefly added
during the 1.11.0 development window and removed again before release: every Node
repo has them and edits them constantly, so freezing them by default turns an
ordinary dependency bump into a denied PR that the consuming repo cannot opt out of.
A repo that *does* want them frozen — the ADLC repo itself does, because its
documented entry points resolve through `scripts` and npm execution flags — declares
them with `--trust-root`.
### Extending the set
`--trust-root <path>` (repeatable) adds a repo-specific trust root. It only ever
**extends** the defaults; nothing on the command line can shrink them. Supplying
them this way is safe because the caller that passes them is itself a default trust
root, so a PR cannot drop the arguments without editing a frozen file.
```bash
adlc rails-guard-ci --base origin/main \
--trust-root .github/workflows/ci.yml \
--trust-root package.json
更改信任根
修改、删除或重命名信任根的 diff 退出 2, 除非 # 141
仪式授权: trust-root-change 标签 财务报告和审定财务报表 获取
批准非作者CODEOWNER对已改变路径的审查。 另一种办法是
保护基础管理路径。 授权只取消特定的信任根
在批准仪式的道路上——从不申报铁路票.
仅限版本豁免. 更改为一揽子清单package.json, (中文(简体) ),
plugin.json, (中文(简体) ), marketplace.json唯一的区别是版本字段和
锁定步骤 @adlc/* 依赖式爬行是机械释放起伏,不是信任根
并不经仪式而通过(ADR 0012)。 任何其他编辑——a scripts
变化,即第三方依赖性暴跌,是信任根基的变化. .npmrc 不是一个
明目张胆,没有任何例外.
兄弟姐妹工具
- 闪光探测器(C6): 使用
--record显示要验证否的条目 建筑师会话滑过大门. - 协商一致(C7): 运行每个候选人
rails-guard在此之前 接受为幸存者. - 合并预测: 读取
manifest.jsonl连接到地表大门历史 合并风险.
核心差距
无。 所有需要的API(globMatch, (中文(简体) ), hashFiles, (中文(简体) ), appendEntry, (中文(简体) ), changedFiles, (中文(简体) ),
gitDiff, (中文(简体) ), loadTickets) 存在于 @adlc/core。 。 。 .