chore: run primary CI before push

This commit is contained in:
Tianyi Cui
2026-07-23 13:09:52 +08:00
parent 3e3ea47296
commit 00d5b69882
18 changed files with 132 additions and 37 deletions
@@ -2,7 +2,7 @@
Status: implemented Status: implemented
The hook/CI symmetry in this record is superseded by [Fast local Git hooks](2026-07-22-fast-local-git-hooks.md); CI remains the exhaustive enforcement path. [Local primary CI before push](2026-07-23-local-primary-ci-before-push.md) restores hook/CI symmetry for the primary Node inventory. [Fast local Git hooks](2026-07-22-fast-local-git-hooks.md) continues to own the pre-commit design.
## Problem ## Problem
@@ -2,7 +2,7 @@
Status: implemented Status: implemented
The local-hook portion of this record is superseded by [Fast local Git hooks](2026-07-22-fast-local-git-hooks.md). The bounded gate scheduler and package-level `publint` parallelism remain in force for CI, `doc-sync`, and explicit local commands. [Local primary CI before push](2026-07-23-local-primary-ci-before-push.md) now owns the local-hook contract: pre-push selects the same primary inventory as CI. The bounded gate scheduler and package-level `publint` parallelism remain in force for CI, `doc-sync`, and explicit local commands.
## Problem ## Problem
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority; # side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with: # after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write # pnpm run verify-translation-pairing --write
2026-07-22-fast-local-git-hooks.md: a07af1cd424c86f7fa80ea946cd5012362cc66eb 2026-07-22-fast-local-git-hooks.md: 4a504c6c4f5816f00be6d86ddfbcb93baf0d7768
2026-07-22-fast-local-git-hooks.zh.md: 78d4ea8980476609a9140737a75152eba123b308 2026-07-22-fast-local-git-hooks.zh.md: 792e035bc5761fc044cf231aff3bb59f31a47659
@@ -4,6 +4,8 @@ Status: implemented
English | [中文](2026-07-22-fast-local-git-hooks.zh.md) English | [中文](2026-07-22-fast-local-git-hooks.zh.md)
> **Superseded for pre-push:** [Local primary CI before push](2026-07-23-local-primary-ci-before-push.md) replaces the typecheck-only publication checkpoint with the exact primary CI inventory. The fast pre-commit decision remains in force; the pre-push design below records the policy this repository no longer uses.
## Problem ## Problem
An agent already runs the tests and checks that exercise its change, while commit, push, and CI can each repeat increasingly broad subsets of the same work. A full pre-push suite therefore delays every publication, amplifies unrelated local flakes, and gives no new signal when CI immediately runs the exhaustive matrix again. An agent already runs the tests and checks that exercise its change, while commit, push, and CI can each repeat increasingly broad subsets of the same work. A full pre-push suite therefore delays every publication, amplifies unrelated local flakes, and gives no new signal when CI immediately runs the exhaustive matrix again.
@@ -4,6 +4,8 @@ Status: implemented
[English](2026-07-22-fast-local-git-hooks.md) | 中文 [English](2026-07-22-fast-local-git-hooks.md) | 中文
> **pre-push 部分已被取代:**[推送前本地运行主 CI](2026-07-23-local-primary-ci-before-push.md)以精确的主 CI 清单取代仅运行类型检查的发布检查点。快速 pre-commit 的决策继续有效;下文的 pre-push 设计记录了本仓库不再采用的策略。
## 问题 ## 问题
agent(智能体)已经会运行能够覆盖自身改动的测试和检查,而提交、推送与 CI 可能分别重复其中范围越来越广的子集。因此,全量 pre-push 套件会拖慢每次推送,放大与当前改动无关的本地偶发失败,而且 CI 紧接着再次运行完整矩阵时不会提供新信号。 agent(智能体)已经会运行能够覆盖自身改动的测试和检查,而提交、推送与 CI 可能分别重复其中范围越来越广的子集。因此,全量 pre-push 套件会拖慢每次推送,放大与当前改动无关的本地偶发失败,而且 CI 紧接着再次运行完整矩阵时不会提供新信号。
@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-23-local-primary-ci-before-push.md: 9d7f4d5a5aae428a003b1cbbb8911e7ad7c50831
2026-07-23-local-primary-ci-before-push.zh.md: 3b58a828bd12d0149d8c4101d8665ee15b9fffc2
@@ -0,0 +1,38 @@
# Agent Note: Local primary CI before push
Status: implemented
English | [中文](2026-07-23-local-primary-ci-before-push.zh.md)
## Problem
Hosted CI can become unavailable before repository code executes because of account, billing, quota, or runner failures. A typecheck-only publication hook then permits a remote branch update without coverage, snapshot, documentation, build, package, or built-entrypoint evidence precisely when the hosted workflow cannot supply that signal.
Focused checks remain the right feedback loop during implementation, but their selection depends on the author correctly predicting every affected contract. Publication needs one complete, mechanically owned local baseline that does not depend on the hosted control plane starting a job.
## Decision
[lefthook.yml](../../../../lefthook.yml) keeps pre-commit focused on staged lint, whitespace, and vendored-source metadata. Pre-push invokes `pnpm run check:pre-push` and blocks publication on any failure.
The `check:pre-push` package script selects the `pre-push` mode in [scripts/run-gates.ts](../../../../scripts/run-gates.ts). Both `pre-push` and `ci-primary` return the same `ciPrimaryGates()` inventory, so the hook and the primary Node CI job cannot drift through separately maintained command lists. Build consumers retain their explicit scheduler dependencies, and `DSH_GATE_CONCURRENCY` remains the resource-control seam for constrained hosts.
Authors still run focused checks while iterating. They do not run the full aggregate immediately before a normal push because the hook owns that one exhaustive local execution. A hook failure is fixed or reported as a blocker; bypass requires explicit approval.
This contract is equivalent to the keyless primary Node CI aggregate on the current host. It does not claim the supported-version or operating-system matrix, Python SDK, real-provider, native, or sandbox workflow signals that require their own environments.
## Supersedes
This decision supersedes the pre-push half of [Fast local Git hooks](2026-07-22-fast-local-git-hooks.md). Its staged pre-commit design remains in force. It also restores the local publication role described by [Parallel pre-push gates](2026-07-06-parallel-pre-push-gates.md) without reviving a second gate inventory.
## Alternatives considered
- **Rely on restoring hosted CI availability** — repairs the immediate administrative failure but leaves publication without a baseline during the next control-plane or runner outage.
- **Wire pre-push to `check:all`** — reuses a broad local command, but that inventory intentionally differs from the primary CI contract and would make “CI equivalent” inaccurate.
- **Copy the CI commands into `lefthook.yml`** — makes the hook visibly comprehensive but creates a second inventory that can drift whenever CI changes.
- **Keep typecheck-only pre-push and require a manual command during outages** — preserves low latency but relies on every author noticing the outage and remembering an exceptional procedure before each update.
## Consequences
Every normal push pays the primary CI aggregate's wall time and may be blocked by a repository-wide local failure unrelated to the outgoing diff. In return, every published revision has observed coverage, snapshots, documentation, build, package, and built-entrypoint evidence from one shared inventory even when hosted jobs never start.
The result is local evidence, not a substitute for unavailable remote environments. Pull requests and handoffs report hosted billing, provider, platform, and pending states separately instead of presenting a successful macOS pre-push run as a green GitHub matrix.
@@ -0,0 +1,38 @@
# Agent Note: 推送前本地运行主 CI
Status: implemented
[English](2026-07-23-local-primary-ci-before-push.md) | 中文
## 问题
托管 CI 可能会因账户、计费、配额或运行器故障,在仓库代码开始执行之前就不可用。此时,仅运行类型检查的发布钩子会允许更新远端分支,却缺少覆盖率、快照、文档、构建、包(package)和构建后入口点的证据;恰恰这时,托管工作流无法提供这些信号。
实现期间,聚焦检查仍是正确的反馈循环,但检查选择取决于作者是否正确预判每项受影响的契约。发布需要一套由机制统一维护的完整本地基线,且不依赖托管控制平面能否启动作业。
## 决策
[lefthook.yml](../../../../lefthook.yml) 让 pre-commit 集中处理暂存文件 lint、空白错误和 vendor 源码元数据。Pre-push 调用 `pnpm run check:pre-push`,任何检查失败都会阻止发布。
`check:pre-push` 包脚本从 [scripts/run-gates.ts](../../../../scripts/run-gates.ts) 中选择 `pre-push` 模式。`pre-push``ci-primary` 都返回同一份 `ciPrimaryGates()` 清单,因此钩子与主 Node CI 作业不会因分别维护命令列表而产生漂移。构建产物消费方仍保留对调度器的显式依赖关系,`DSH_GATE_CONCURRENCY` 仍是资源受限主机的资源控制 seam。
作者在迭代时仍运行聚焦检查。正常推送前不立即运行全量聚合,因为钩子负责这一次全面的本地执行。钩子失败必须修复或报告为阻塞项;绕过钩子需要明确批准。
本契约等同于当前主机上的 keyless 主 Node CI 聚合。它不代表已经取得受支持版本矩阵或操作系统矩阵、Python SDK、真实模型提供方、原生构建或沙箱工作流的信号;这些信号需要各自的环境才能取得。
## 取代关系
本决策取代[快速本地 Git 钩子](2026-07-22-fast-local-git-hooks.md)中有关 pre-push 的部分。其中面向暂存文件的 pre-commit 设计继续有效。它还恢复了[并行 pre-push 门禁](2026-07-06-parallel-pre-push-gates.md)中描述的本地发布职责,但没有重新引入第二份门禁清单。
## 考虑过的替代方案
- **依靠恢复托管 CI 可用性**——可以修复当前的管理性故障,但下一次控制平面或运行器中断时,发布流程仍没有基线。
- **将 pre-push 接入 `check:all`**——能够复用一条广泛的本地命令,但其清单有意不同于主 CI 契约,会使「等同于 CI」的表述不准确。
- **将 CI 命令复制到 `lefthook.yml`**——能够直观展示钩子的全面性,但会创建第二份清单,并在每次 CI 变更时产生漂移。
- **保留仅运行类型检查的 pre-push,并要求中断期间手动运行命令**——能够维持低延迟,但依赖每位作者发现中断,并在每次更新前记得执行特殊流程。
## 结果
每次正常推送都要承担主 CI 聚合的实际耗时,也可能被与待推送 diff 无关的全仓本地失败阻塞。相应地,即使托管作业从未启动,每个已发布版本仍有一套由共享清单实际运行得出的覆盖率、快照、文档、构建、包和构建后入口点证据。
该结果只是本地证据,不能代替不可用的远端环境。PR(Pull Request)和交接会分别报告托管服务计费、提供方、平台与待处理状态,而不会把一次成功的 macOS pre-push 运行表述成 GitHub 矩阵已通过。
+16 -10
View File
@@ -1,11 +1,11 @@
--- ---
name: dsh-pre-push-checks name: dsh-pre-push-checks
description: Use before pushing, force-pushing, marking ready for review, or claiming checks pass on a deepseek-harness branch to select the smallest tests and checks that cover the outgoing diff without reflexively running the full repository suite. description: Use before pushing, force-pushing, marking ready for review, or claiming checks pass on a deepseek-harness branch to select focused implementation evidence and preserve the mandatory primary-CI pre-push gate.
--- ---
# DSH Pre-Push Checks # DSH Pre-Push Checks
Use this skill to run relevant local evidence once before a `deepseek-harness` push. Git hooks are intentionally narrow: pre-commit fixes staged lint, checks staged whitespace, and guards vendored-source metadata; pre-push runs only the incremental repository typecheck. CI owns exhaustive coverage and the platform matrix. Use this skill to run relevant implementation evidence once and the complete local publication baseline once before a `deepseek-harness` push. Pre-commit fixes staged lint, checks staged whitespace, and guards vendored-source metadata; pre-push invokes `pnpm run check:pre-push`, which selects the same primary Node inventory as `pnpm run check:ci`. Hosted CI still owns platform- and provider-specific evidence.
## Inspect the outgoing change ## Inspect the outgoing change
@@ -27,15 +27,15 @@ If the branch has no upstream or that range is not meaningful for the stack, com
## Select relevant evidence ## Select relevant evidence
There is no universal local baseline beyond the hooks. Every behavior change needs the narrowest available test or purpose-built check that would fail for its regression; add broader checks only for surfaces the diff actually reaches. Every behavior change needs the narrowest available test or purpose-built check that would fail for its regression. Run that evidence while iterating; the hook supplies the universal publication baseline.
- **Package or script behavior:** run the owning Vitest file or focused test name. Add adjacent package tests when a shared contract changes; leave repository-wide coverage to CI unless the change is genuinely cross-cutting or the user requests it. - **Package or script behavior:** run the owning Vitest file or focused test name. Add adjacent package tests when a shared contract changes; leave repository-wide coverage to pre-push unless the change is genuinely cross-cutting or the user requests it earlier.
- **Documentation, Agent Notes, catalogs, or doc-linked comments:** run `pnpm run doc-sync`; run full lint when the documentation workflow requires it. - **Documentation, Agent Notes, catalogs, or doc-linked comments:** run `pnpm run doc-sync`; run full lint when the documentation workflow requires it.
- **Model-, editor-, CLI-, or terminal-visible output:** run the focused keyless snapshot or real runnable-example scenario that owns the output. - **Model-, editor-, CLI-, or terminal-visible output:** run the focused keyless snapshot or real runnable-example scenario that owns the output.
- **Package manifests, public exports, build configuration, worker/bin entries, or built runtime paths:** run `pnpm run build`, the relevant hygiene checks, and the owning built-artifact smoke. - **Package manifests, public exports, build configuration, worker/bin entries, or built runtime paths:** run `pnpm run build`, the relevant hygiene checks, and the owning built-artifact smoke.
- **Real provider or agent behavior:** run the relevant `pnpm run test:e2e` target when credentials are available; never print secrets. - **Real provider or agent behavior:** run the relevant `pnpm run test:e2e` target when credentials are available; never print secrets.
Do not manually repeat a passing check merely because commit or push follows. In particular, do not run typecheck immediately before pushing solely to duplicate the pre-push hook. Do not manually repeat a passing check merely because commit or push follows. In particular, do not run `check:pre-push` immediately before a normal push and then repeat the same aggregate in the hook.
### Focus unit coverage on the affected source ### Focus unit coverage on the affected source
@@ -60,13 +60,19 @@ pnpm exec vitest related packages/<group>/<package>/src/<changed>.ts \
`vitest related` cannot discover behavior reached only through configuration, dynamic loading, subprocesses, workers, built artifacts, or external providers; select those owning tests explicitly. Do not use `--passWithNoTests`, lower coverage thresholds, or narrow `--coverage.include` merely to hide an uncovered affected file. If a selected package scope fails because one focused test does not cover it, add its other relevant owning tests or narrow the source scope only when the excluded modules cannot be affected by the change. `vitest related` cannot discover behavior reached only through configuration, dynamic loading, subprocesses, workers, built artifacts, or external providers; select those owning tests explicitly. Do not use `--passWithNoTests`, lower coverage thresholds, or narrow `--coverage.include` merely to hide an uncovered affected file. If a selected package scope fails because one focused test does not cover it, add its other relevant owning tests or narrow the source scope only when the excluded modules cannot be affected by the change.
## Full local rehearsal ## Mandatory publication gate
Run the complete local approximation only when the user explicitly requests it, while diagnosing a CI failure, or when the change spans the repository so broadly that no narrower set is credible. Use the current workflow and package scripts as the inventory; do not recreate the removed `check:pre-push` aggregate. The normal push runs the complete keyless primary Node inventory through Lefthook:
```sh
pnpm run check:pre-push
```
Invoke the command directly only when the user requests a rehearsal independent of publication or when diagnosing the hook itself. Add the relevant `pnpm run test:e2e` target when credentials are available and behavior depends on a real provider; real-API e2e is not part of the keyless primary inventory.
## Handle failures ## Handle failures
If a relevant check fails, stop and fix or explain the blocker. Do not push and hope CI differs. If a relevant check or the publication gate fails, stop and fix or explain the blocker. Do not push and hope CI differs.
If a failure looks environment-specific, prove it: If a failure looks environment-specific, prove it:
@@ -77,9 +83,9 @@ If a failure looks environment-specific, prove it:
## Push procedure ## Push procedure
1. Run the selected relevant checks once. 1. Run the selected focused checks once during implementation.
2. Commit normally and inspect any files changed by the pre-commit fixer before continuing. 2. Commit normally and inspect any files changed by the pre-commit fixer before continuing.
3. Push normally so the incremental typecheck hook runs. 3. Push normally so the complete primary Node hook runs once.
4. Verify the remote ref matches local `HEAD`. 4. Verify the remote ref matches local `HEAD`.
```sh ```sh
@@ -1,4 +1,4 @@
interface: interface:
display_name: "DSH Pre-Push Checks" display_name: "DSH Pre-Push Checks"
short_description: "Run the relevant DeepSeek Harness checks before push" short_description: "Run focused and primary CI checks before push"
default_prompt: "Use $dsh-pre-push-checks before pushing this DeepSeek Harness branch." default_prompt: "Use $dsh-pre-push-checks before pushing this DeepSeek Harness branch."
+2 -2
View File
@@ -73,10 +73,10 @@ When required `gh`, `pnpm`, build, test, or generator commands fail because the
### Run relevant checks locally ### Run relevant checks locally
Agents MUST run relevant tests and checks before pushing; select them with [dsh-pre-push-checks](.agents/skills/dsh-pre-push-checks/SKILL.md) and report only commands run. Agents MUST run focused checks while implementing; normal pre-push runs `check:pre-push`, the same primary Node inventory as `check:ci`. Select focused evidence with [dsh-pre-push-checks](.agents/skills/dsh-pre-push-checks/SKILL.md) and report only commands run.
- Match evidence to the surface: focused tests for behavior, snapshots for model or user output, `doc-sync` for docs, build/hygiene and built smokes for published paths, and real-API e2e for provider behavior. - Match evidence to the surface: focused tests for behavior, snapshots for model or user output, `doc-sync` for docs, build/hygiene and built smokes for published paths, and real-API e2e for provider behavior.
- Never default to the full suite or repeat a passing check for commit or push. CI owns exhaustive coverage and the platform matrix; rehearse all locally only by explicit request, for CI diagnosis, or for an irreducibly repository-wide change. - Let the hook run the full aggregate once; never bypass a failure without explicit approval. Remote CI owns the platform and provider matrix.
- `test:coverage`, not `test`, is the CI coverage gate ([why](docs/testing.md)). - `test:coverage`, not `test`, is the CI coverage gate ([why](docs/testing.md)).
## Secrets / .env ## Secrets / .env
+2 -2
View File
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority; # side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with: # after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write # pnpm run verify-translation-pairing --write
development.md: 4294038e40aa774a006874e6641ca63eea44beeb development.md: 2496afa3a5b27efdade4a7c6e66e54b55a25b075
development.zh.md: 1f07c95dd60d0554b945c29e6e3ba8bc6ca9841a development.zh.md: 9b44eb1c2679be395f7a19882dcdd38261833a06
+7 -6
View File
@@ -75,20 +75,20 @@ DEEPSEEK_BASE_URL=https://... # optional
## Git hooks ## Git hooks
lefthook is configured in `lefthook.yml` as a fast local checkpoint: lefthook is configured in `lefthook.yml` with fast commit-local checks and a comprehensive publication check:
- `pre-commit` runs staged-file ESLint fixes, checks the staged diff for whitespace errors, and runs the vendor manifest guard. - `pre-commit` runs staged-file ESLint fixes, checks the staged diff for whitespace errors, and runs the vendor manifest guard.
- `pre-push` runs only the incremental repository typecheck (`tsc -b` over the root solution, covering both the host and client aggregates). - `pre-push` invokes `pnpm run check:pre-push`, which selects the same primary Node gate inventory as `pnpm run check:ci` from `scripts/run-gates.ts`.
The vendor manifest guard checks that changes under `vendor/*/src` are staged with the matching `vendor/README.md` manifest update. See `vendor/README.md` before editing vendored code. The vendor manifest guard checks that changes under `vendor/*/src` are staged with the matching `vendor/README.md` manifest update. See `vendor/README.md` before editing vendored code.
The hooks intentionally do not run tests, snapshots, documentation checks, builds, or hygiene. Contributors run the [checks relevant to the changed behavior](../AGENTS.md#run-relevant-checks-locally) once; CI owns exhaustive coverage, built-artifact smokes, and the Node 22.19, 24, and 26 compatibility matrix. Contributors run [checks relevant to the changed behavior](../AGENTS.md#run-relevant-checks-locally) while iterating. A normal push runs the complete local primary aggregate once and stops publication on any failure; do not run the same aggregate immediately before pushing.
Contributors can opt into the comprehensive local gate set with `pnpm run check:all`. The command is independent of both Git hooks and is not an agent instruction. The pre-push result covers the keyless primary Node lane on the current host. It does not replace the supported-version and platform matrix, Python SDK tests, real-API e2e, or sandbox workflows. `pnpm run check:all` remains a broad opt-in development inventory; it is independent of both Git hooks and is not the publication contract.
## CI gates ## CI gates
The keyless [CI workflow](../.github/workflows/ci.yml) groups independent gates into broad lanes and runs a smaller compatibility signal across supported Node versions. Artifact consumers wait for one build within their lane. The separate real-API workflow runs `pnpm run test:e2e` with its configured worker bound. See [scripts/run-gates.ts](../scripts/run-gates.ts) and the workflow files for the current gate and job inventory. The keyless [CI workflow](../.github/workflows/ci.yml) groups independent gates into broad lanes and runs a smaller compatibility signal across supported Node versions. Artifact consumers wait for one build within their lane. `check:pre-push` and the primary CI job share one gate inventory; the separate real-API workflow runs `pnpm run test:e2e` with its configured worker bound. See [scripts/run-gates.ts](../scripts/run-gates.ts) and the workflow files for the current gate and job inventory.
## Daily commands ## Daily commands
@@ -98,7 +98,8 @@ Use these from the repo root:
pnpm run test # unit tests pnpm run test # unit tests
pnpm run test:coverage # unit tests with per-file coverage gates pnpm run test:coverage # unit tests with per-file coverage gates
pnpm run test:e2e # real-API tests; self-skips without DEEPSEEK_API_KEY pnpm run test:e2e # real-API tests; self-skips without DEEPSEEK_API_KEY
pnpm run check:all # comprehensive opt-in gate set; not wired to Git hooks pnpm run check:pre-push # primary Node CI inventory; runs automatically before push
pnpm run check:all # broad opt-in development gate set; not wired to Git hooks
pnpm run typecheck # tsc -b over the root solution: emits package/vendor lib/types, checks both aggregates pnpm run typecheck # tsc -b over the root solution: emits package/vendor lib/types, checks both aggregates
pnpm run lint # eslint . pnpm run lint # eslint .
pnpm run lint:fix # eslint . --fix pnpm run lint:fix # eslint . --fix
+7 -6
View File
@@ -75,20 +75,20 @@ DEEPSEEK_BASE_URL=https://... # optional
## Git 钩子 ## Git 钩子
lefthook 在 `lefthook.yml` 中配置,作为快速的本地检查点 lefthook 在 `lefthook.yml` 中配置了快速的提交级检查和全面的发布检查
- `pre-commit` 运行对暂存文件的 ESLint 修复,检查暂存 diff 中的空白错误,并运行 vendor manifest(元数据清单)守卫; - `pre-commit` 运行对暂存文件的 ESLint 修复,检查暂存 diff 中的空白错误,并运行 vendor manifest(元数据清单)守卫;
- `pre-push` 只运行仓库增量类型检查(对根 solution 执行 `tsc -b`,覆盖 host 与 client 两个聚合) - `pre-push` 调用 `pnpm run check:pre-push`;该命令从 `scripts/run-gates.ts` 中选择与 `pnpm run check:ci` 相同的主 Node 门禁清单
vendor manifest 守卫检查 `vendor/*/src` 下的改动是否连同对应的 `vendor/README.md` manifest 更新一起暂存。请在编辑 vendor 代码前先阅读 `vendor/README.md` vendor manifest 守卫检查 `vendor/*/src` 下的改动是否连同对应的 `vendor/README.md` manifest 更新一起暂存。请在编辑 vendor 代码前先阅读 `vendor/README.md`
这些钩子有意不运行测试、快照、文档检查、构建或 `hygiene`。贡献者只运行一次[与改动行为相关的检查](../AGENTS.md#run-relevant-checks-locally);CI 负责全量覆盖率门禁、构建产物冒烟测试,以及 Node 22.19、24 和 26 兼容性矩阵 贡献者在迭代过程中运行[与改动行为相关的检查](../AGENTS.md#run-relevant-checks-locally)。正常推送会在本地完整运行一次主 CI 聚合,并在任何检查失败时阻止发布;不要在推送前立即重复运行同一个聚合
贡献者可以选择运行 `pnpm run check:all`,执行全面的本地门禁集。该命令独立于两个 Git 钩子,也不是对 agent 的指令 pre-push 的结果覆盖当前主机上的 keyless 主 Node lane,但不能代替受支持版本与平台矩阵、Python SDK 测试、真实 API e2e 或沙箱工作流。`pnpm run check:all` 仍是一份广泛的可选开发检查清单;它独立于两个 Git 钩子,也不属于发布契约
## CI 门禁 ## CI 门禁
keyless [CI 工作流](../.github/workflows/ci.yml) 将独立门禁分组到若干宽粒度 lane,并在受支持的 Node 版本上运行一组较小的兼容性检查。产物消费方在各自 lane 内等待一次 build。单独的真实 API 工作流按其配置的 worker 上限运行 `pnpm run test:e2e`。当前门禁和 job 清单以 [scripts/run-gates.ts](../scripts/run-gates.ts) 和工作流文件为准。 keyless [CI 工作流](../.github/workflows/ci.yml) 将独立门禁分组到若干宽粒度 lane,并在受支持的 Node 版本上运行一组较小的兼容性检查。产物消费方在各自 lane 内等待一次 build。`check:pre-push` 与主 CI job 共用一份门禁清单;单独的真实 API 工作流按其配置的 worker 上限运行 `pnpm run test:e2e`。当前门禁和 job 清单以 [scripts/run-gates.ts](../scripts/run-gates.ts) 和工作流文件为准。
## 日常命令 ## 日常命令
@@ -98,7 +98,8 @@ keyless [CI 工作流](../.github/workflows/ci.yml) 将独立门禁分组到若
pnpm run test # unit tests pnpm run test # unit tests
pnpm run test:coverage # unit tests with per-file coverage gates pnpm run test:coverage # unit tests with per-file coverage gates
pnpm run test:e2e # real-API tests; self-skips without DEEPSEEK_API_KEY pnpm run test:e2e # real-API tests; self-skips without DEEPSEEK_API_KEY
pnpm run check:all # comprehensive opt-in gate set; not wired to Git hooks pnpm run check:pre-push # primary Node CI inventory; runs automatically before push
pnpm run check:all # broad opt-in development gate set; not wired to Git hooks
pnpm run typecheck # tsc -b over the root solution: emits package/vendor lib/types, checks both aggregates pnpm run typecheck # tsc -b over the root solution: emits package/vendor lib/types, checks both aggregates
pnpm run lint # eslint . pnpm run lint # eslint .
pnpm run lint:fix # eslint . --fix pnpm run lint:fix # eslint . --fix
+4 -4
View File
@@ -1,5 +1,5 @@
# Git hooks (lefthook). Keep these local checkpoints fast; CI owns the full # Git hooks (lefthook). Pre-commit keeps commit-local checks fast; pre-push
# repository-wide gate matrix. # runs the primary Node CI inventory before publication.
# Install: `pnpm exec lefthook install` (runs automatically via postinstall). # Install: `pnpm exec lefthook install` (runs automatically via postinstall).
pre-commit: pre-commit:
@@ -19,5 +19,5 @@ pre-commit:
pre-push: pre-push:
jobs: jobs:
- name: typecheck - name: primary CI
run: node_modules/.bin/tsc -b --pretty false run: pnpm run check:pre-push
+1
View File
@@ -30,6 +30,7 @@
"test:web": "npm run build:web && vitest run --config vitest.web.config.ts", "test:web": "npm run build:web && vitest run --config vitest.web.config.ts",
"test:gui": "vitest run packages/client packages/host", "test:gui": "vitest run packages/client packages/host",
"check:all": "tsx scripts/run-gates.ts check-all", "check:all": "tsx scripts/run-gates.ts check-all",
"check:pre-push": "tsx scripts/run-gates.ts pre-push",
"check:ci": "tsx scripts/run-gates.ts ci-primary", "check:ci": "tsx scripts/run-gates.ts ci-primary",
"check:ci:static": "tsx scripts/run-gates.ts ci-static", "check:ci:static": "tsx scripts/run-gates.ts ci-static",
"check:ci:lint": "tsx scripts/run-gates.ts ci-lint", "check:ci:lint": "tsx scripts/run-gates.ts ci-lint",
+1 -1
View File
@@ -66,7 +66,7 @@ Run the narrowest rung that covers what you touched; escalate only when the chan
1. **Every GUI code change**`pnpm run test:gui` (seconds; no browser, no server): the client suites plus the host-side GUI packages. This is the inner loop; run it as freely as a typecheck. 1. **Every GUI code change**`pnpm run test:gui` (seconds; no browser, no server): the client suites plus the host-side GUI packages. This is the inner loop; run it as freely as a typecheck.
2. **Changes to the build surface, boot wiring, or static serving** (`apps/web`, vite config, `dsh-host-webserver`) — additionally `pnpm run test:web`: rebuilds the frontend dist, then runs the browser smoke pair (the real-host case self-skips without `DEEPSEEK_API_KEY`). 2. **Changes to the build surface, boot wiring, or static serving** (`apps/web`, vite config, `dsh-host-webserver`) — additionally `pnpm run test:web`: rebuilds the frontend dist, then runs the browser smoke pair (the real-host case self-skips without `DEEPSEEK_API_KEY`).
3. **Before a PR** `pnpm run check:pre-push` (the repo-wide gate ladder). Between PR windows this rung is not expected on every commit. 3. **Before every push** — the normal hook runs `pnpm run check:pre-push` (the repo-wide primary CI inventory). Do not invoke it manually immediately before pushing.
If `test:gui` is red on code you did not touch, neither silently fix nor ignore it: note it in your handoff so it lands in the next PR window's sweep. If `test:gui` is red on code you did not touch, neither silently fix nor ignore it: note it in your handoff so it lands in the next PR window's sweep.
+1 -1
View File
@@ -168,6 +168,7 @@ function nodeOptions(...options: string[]): string {
function gatesForMode(selected: Mode): Gate[] { function gatesForMode(selected: Mode): Gate[] {
switch (selected) { switch (selected) {
case 'ci-primary': case 'ci-primary':
case 'pre-push':
return ciPrimaryGates() return ciPrimaryGates()
case 'ci-static': case 'ci-static':
return ciStaticGates() return ciStaticGates()
@@ -190,7 +191,6 @@ function gatesForMode(selected: Mode): Gate[] {
return ciWindowsObservationalGates() return ciWindowsObservationalGates()
case 'node-compat': case 'node-compat':
return nodeCompatGates() return nodeCompatGates()
case 'pre-push': return []
case 'check-all': case 'check-all':
return [ return [
pnpmScript('runtime-closure', 'verify-runtime-closure', { label: 'runtime closure' }), pnpmScript('runtime-closure', 'verify-runtime-closure', { label: 'runtime closure' }),