|
| 1 | +# regress-guard |
| 2 | + |
| 3 | +> AI-coding governance gate for ZCode: **don't trust the agent's "done"** — the gate |
| 4 | +> re-runs your tests itself, blocks edits outside the declared change-scope, and |
| 5 | +> keeps human-only-calibrated telemetry on every interception. |
| 6 | +> |
| 7 | +> Design philosophy first: [docs/PHILOSOPHY.md](docs/PHILOSOPHY.md) (sixteen |
| 8 | +> principles and the real incidents behind them). Features age, principles don't. |
| 9 | +> Full workflow: [docs/WORKFLOW.md](docs/WORKFLOW.md) · 中文文档:[README_CN.md](README_CN.md) |
| 10 | +
|
| 11 | +## Why |
| 12 | + |
| 13 | +Agents report "done" confidently and cheaply. This plugin makes "done" a |
| 14 | +machine-verified claim, at the only surface that matters in a direct-to-main |
| 15 | +workflow: **the commit**. |
| 16 | + |
| 17 | +- **Completion re-verification (the core)**: a PreToolUse gate intercepts commit |
| 18 | + commands and runs the project's own test suite itself — agent self-reports are |
| 19 | + never trusted. EARS-style acceptance rows must be checked off with evidence |
| 20 | + before `done` is stamped. Same-tree retries hit a content-keyed result cache |
| 21 | + (0-second gates). |
| 22 | +- **Boundary guard**: edits/writes to files not declared in the active change |
| 23 | + manifest are blocked before they happen — the plan's file list *is* the boundary. |
| 24 | +- **Blast-radius gate**: commits touching configured high-impact paths (contracts, |
| 25 | + shared packages) or spanning ≥2 monorepo units demand an M-tier manifest plus an |
| 26 | + explicit `impact_scope` declaration; unconfigured monorepos get a warn-only hint. |
| 27 | +- **Assumption ledger**: when reality falsifies a plan's assumption, the |
| 28 | + was→reality→evidence record is mandatory. |
| 29 | +- **Six-layer trust surface**: project-level notification channels require a |
| 30 | + human-granted trust table + content pinning; HOME/env-injection redirection is |
| 31 | + neutralized at the launcher allowlist. Cloned-repo injection surfaces are closed. |
| 32 | +- **FP-calibrated telemetry**: every interception is adjudicated later by the |
| 33 | + human (useful / false_positive / ignored) — the agent gets no vote on its own |
| 34 | + accuracy. Public benchmark: 82 cases / 13 families, see [benchmarks/](benchmarks/). |
| 35 | +- **Self-healing**: session start compares the installed copy against the source |
| 36 | + repo; version drift is announced, not silently tolerated. |
| 37 | + |
| 38 | +## Install |
| 39 | + |
| 40 | +**Marketplace (recommended)**: install `regress-guard` from the ZCode plugin |
| 41 | +marketplace — hooks activate via the host runtime, and the plugin can be |
| 42 | +toggled/upgraded natively. |
| 43 | + |
| 44 | +**Personal-source track**: add marketplace source |
| 45 | +`github:1339190177/regress-guard` in ZCode settings, then install. |
| 46 | + |
| 47 | +**Dev track**: clone this repo (`git clone |
| 48 | +https://github.com/1339190177/regress-guard.git`), then `bash install.sh` |
| 49 | +(or tell the AI `/regress:install`). Use one track at a time. |
| 50 | + |
| 51 | +Requirements: ZCode client + Python 3.10+ (the installer checks and refuses |
| 52 | +early with an upgrade path — no obscure heredoc crashes). Runtime has |
| 53 | +**zero third-party Python dependencies** (`filelock` is optional — absent → |
| 54 | +degrades to lock-free atomic write, v1.95.1). To run this repo's own test |
| 55 | +suite: `pip install -r requirements-dev.txt` (pytest / anyio / filelock). |
| 56 | + |
| 57 | +### What your first interception looks like |
| 58 | + |
| 59 | +After install, hooks fail **open** in projects without `.regress/` (nothing |
| 60 | +changes until you `/regress:init`). Once a manifest is active: |
| 61 | + |
| 62 | +- Editing a file outside the manifest boundary → the edit is **blocked |
| 63 | + before it happens**, with three escape routes printed in the message |
| 64 | + (extend via track / finish the current task / disable per project). |
| 65 | +- Committing → the gate re-runs the project's tests; failures, unchecked |
| 66 | + acceptance rows, or leaked secrets block the commit with the reason and |
| 67 | + the bypass path. |
| 68 | +- A crashing guard **blocks** rather than silently passes (fail-closed, |
| 69 | + v1.99) — escape hatches: `/regress:bypass <minutes>` or the per-feature |
| 70 | + config switches in docs/WORKFLOW.md. |
| 71 | + |
| 72 | +Note on `RG_*` env switches: hooks registered via `launcher.js` run in a |
| 73 | +**sanitized environment** (v1.69) — `RG_*`/`WECOM_*`/`GIT_*` variables set |
| 74 | +in your shell do **not** reach those hooks by design. Use config switches |
| 75 | +(`.regress/config.json`) or `/regress:bypass` instead. |
| 76 | + |
| 77 | +Fresh-install smoke test (the machine-runnable stranger funnel): |
| 78 | +`bash scripts/install_dogfood.sh` — installs into a throwaway home, runs |
| 79 | +the four post-install checks, and exercises boundary-block / valve-block / |
| 80 | +gate-pass end to end. |
| 81 | + |
| 82 | +## Five-minute start |
| 83 | + |
| 84 | +1. In any project, tell the AI: `/regress:init` |
| 85 | +2. Daily flow: state a requirement → the AI produces a plan card → you |
| 86 | + **approve / edit / cancel** → it works (with boundary enforcement) → on |
| 87 | + commit, the gate re-runs tests and blocks on failure or unchecked |
| 88 | + acceptance rows |
| 89 | +3. Project state and archaeology live in `.regress/` |
| 90 | + |
| 91 | +## Side-effects declaration (transparency contract) |
| 92 | + |
| 93 | +- **Execution**: all hooks are local Python 3.10+ processes (no prebuilt |
| 94 | + binaries, no obfuscated source) |
| 95 | +- **File writes**: `.regress/` inside projects (manifests/history/ledgers) and |
| 96 | + `~/.zcode/regress-guard-hooks` (installed copy) |
| 97 | +- **Command execution**: exactly two classes — the gate invoking the project's |
| 98 | + own test runner (pytest/jest/maven/gradle/go, auto-detected), and notification |
| 99 | + channel commands (**only for human-granted projects**; untrusted configs fall |
| 100 | + back to machine level, closing the cloned-repo injection surface) |
| 101 | +- **Network**: zero egress by default. Optional interception notifications via |
| 102 | + WeCom self-built apps — credentials require human trust-grant and the API base |
| 103 | + is pinned to the official domain. No MCP, no telemetry upload, no third-party |
| 104 | + analytics |
| 105 | +- **Hook surface**: PreToolUse (commit gate / boundary guard / execution valve), |
| 106 | + PostToolUse (manifest bridge), UserPromptSubmit (governance context), |
| 107 | + SessionStart (self-heal), Stop (end-of-turn notices) |
| 108 | +- **Escapes**: `/regress:bypass N` gives a time-boxed amnesty (audited); each |
| 109 | + feature has an independent env switch |
| 110 | + |
| 111 | +## Health & verification |
| 112 | + |
| 113 | +`bash validate.sh` (expect 5/5) · `python3 -m pytest tests/ -q` (expect green) |
| 114 | +· post-install smoke check runs automatically with `install.sh` |
| 115 | + |
| 116 | +## License |
| 117 | + |
| 118 | +MIT. Third-party: none at runtime (stdlib only). |
| 119 | + |
| 120 | +<!-- generated: reference start · 本区由 scripts/gen_reference.py 生成,勿手改 --> |
| 121 | + |
| 122 | +**实况(由 gen_reference.py 生成,勿手改本区)** |
| 123 | + |
| 124 | +- 命令:16 个 · hook 注册:11 个事件条目 · 测试函数:762 个 |
| 125 | + |
| 126 | +| 命令 | 说明 | |
| 127 | +|---|---| |
| 128 | +| `/regress:bypass` | 紧急绕过回归卡点(限时 + 审计日志),用于 hotfix 等紧急场景 | |
| 129 | +| `/regress:characterize` | 特征测试生成:改无测试老代码前先钉住现状行为(golden master——探针真跑取真值,不猜输出) | |
| 130 | +| `/regress:evolve` | 遇到难点时查社区经验→适配项目→沉淀为知识库(不再重复查) | |
| 131 | +| `/regress:finish` | 收尾流水线:track 回写 → verify 全证据 → 代谢沉淀 → 状态推进 → 汇总报告(一条命令走完收尾,人只出现在决策点) | |
| 132 | +| `/regress:init` | 初始化项目的 .regress/ 数据目录(代码已在全局级安装,这里只建数据) | |
| 133 | +| `/regress:install` | 一键安装 regress-guard 到用户级(零配置,装一次全局生效) | |
| 134 | +| `/regress:learn` | 分析历史+检测框架规则,输出项目洞察,写入 AGENTS.md | |
| 135 | +| `/regress:plan` | 需求→解析→消歧→改动清单。AI 先补全上下文再动手(不问能推断的,只问关键分歧) | |
| 136 | +| `/regress:quick` | 快速模式——机器判据达标的小改动专用(合并 plan+track 一步到位) | |
| 137 | +| `/regress:resume` | 从 .regress/ 产物层单侧重建工作现场(断点续作,不依赖对话历史) | |
| 138 | +| `/regress:stats` | 健康报表:门禁拦截/债务/规律命中/僵尸清单/钩子活性一屏读(观测期仪表盘,只读不改) | |
| 139 | +| `/regress:trace` | 查看交付链:需求→会话→事件→提交 的可追溯视图(文本版 Inspector) | |
| 140 | +| `/regress:track` | 对比 git diff 发现 F3 并直接回写(AI 完成修改后自动执行,不需用户手动触发) | |
| 141 | +| `/regress:uninstall` | 卸载 regress-guard(清理用户级配置 + hook + skill + 命令) | |
| 142 | +| `/regress:update` | 检查并更新 regress-guard 到最新版(手动触发;SessionStart 也会自动检测) | |
| 143 | +| `/regress:verify` | 跑测试预览结果(提交时 hook 也会自动跑;测试失败 AI 应自行修复重跑) | |
| 144 | + |
| 145 | +<!-- generated: reference end --> |
0 commit comments