feat: vendor permission system source

This commit is contained in:
云服务部-叶林立
2026-08-19 14:35:19 +08:00
parent 198584daf8
commit 410c50a3e5
809 changed files with 157793 additions and 139 deletions
@@ -0,0 +1,114 @@
---
issue: 14
issue_title: "Set up prek for pre-commit linting (Biome + markdownlint)"
---
# Set up prek for pre-commit linting
## Problem Statement
During the #13 retro, a Biome version-skew issue surfaced: running `npm run lint:fix` locally with a different Biome version than the one pinned in `package-lock.json` produced formatting changes that CI rejected.
A pre-commit hook running the project-local linters would catch these mismatches before they reach CI, saving round-trip time on failed builds.
## Goals
- Install and configure [prek](https://prek.j178.dev/) as the git hook manager.
- Run `npx biome check` on staged files in the pre-commit hook so the project-pinned Biome version is always used.
- Run `npx markdownlint-cli2` on staged Markdown files in the pre-commit hook.
- Document the setup so contributors know how to install hooks and what they enforce.
## Non-Goals
- Adding new lint rules or changing existing Biome/markdownlint configuration — out of scope.
- Running the full test suite or type-check in the pre-commit hook — too slow for a pre-commit gate; CI handles these.
- Migrating CI to use prek — CI continues to run `npm run lint` and `npm run lint:md` directly.
## Background
- **Origin:** #13 retro (`docs/retro/0013-consolidate-session-start-handlers.md`) — a `style:` commit with wrong Biome formatting caused a CI failure and 2 extra fixup commits.
- **Existing lint scripts:** `npm run lint` (`biome check .`), `npm run lint:md` (`markdownlint-cli2 '*.md' 'docs/**/*.md' '.pi/prompts/**/*.md'`).
- **CI:** `.github/workflows/ci.yml` runs `npm run lint` and `npm run lint:md` as separate steps.
- **Permission surface:** none — this is a developer-tooling concern with no policy semantics.
- **On-disk identity:** no impact — prek config lives in `.prek.yaml` at the repo root, not in the Pi config directory.
## Design Overview
[prek](https://prek.j178.dev/) is a Rust-based git hook manager (drop-in replacement for `pre-commit`).
It reads `.prek.yaml` at the repo root and installs git hooks that run configured checks on staged files.
### Hook configuration
The `.prek.yaml` file defines two hooks under `pre-commit`:
1. **Biome** — runs `npx biome check` on staged JS/TS/JSON files.
Using `npx biome` ensures the project-local version from `node_modules` is used, preventing version skew.
2. **markdownlint** — runs `npx markdownlint-cli2` on staged `.md` files.
Both hooks should operate only on staged files (prek handles this via `types`/`files` filters and passes matching filenames to the command).
### Developer setup
After cloning, a developer runs `prek install` once to set up the git hooks.
This is a one-time step documented in `README.md` and optionally wired as a `prepare` npm script so `npm install` auto-installs hooks.
## Module-Level Changes
### Added
- **`.prek.yaml`** — prek hook configuration with Biome and markdownlint hooks scoped to relevant file types.
### Changed
- **`package.json`** — add a `prepare` script (`prek install`) so hooks are installed automatically after `npm install`.
This is the standard convention for git hook managers.
- **`README.md`** — document the pre-commit setup: what it runs, how to install hooks manually if needed, how to skip hooks (`git commit --no-verify`) in emergencies.
- **`.gitignore`** — no changes needed; prek does not generate files that need ignoring.
### Not changed
- **`biome.json`** — no changes; the hook invokes the existing config.
- **`.markdownlint-cli2.yaml`** — no changes; the hook invokes the existing config.
- **`.github/workflows/ci.yml`** — no changes; CI continues to run the full lint suite independently.
## TDD Order
This issue is primarily a configuration/tooling change with no application logic, so the "test" cycles are validation-oriented rather than unit-test-oriented.
1. **Verify prek is installable and `.prek.yaml` is valid.**
Create `.prek.yaml` with both hooks.
Run `prek install` and confirm hooks are registered (`.git/hooks/pre-commit` exists and delegates to prek).
Commit: `feat: add prek pre-commit config for Biome and markdownlint (#14)`
2. **Verify Biome hook catches lint violations on staged files.**
Stage a file with a deliberate Biome violation, run `git commit` (or `prek run pre-commit`), confirm it fails.
Stage a clean file, confirm it passes.
Commit: `test: verify Biome pre-commit hook catches violations (#14)` (manual verification, no committed test file)
3. **Verify markdownlint hook catches Markdown violations on staged files.**
Stage a `.md` file with a deliberate violation (e.g., trailing spaces), run the hook, confirm failure.
Stage a clean `.md` file, confirm it passes.
Commit: `test: verify markdownlint pre-commit hook catches violations (#14)` (manual verification)
4. **Add `prepare` script and update README.**
Wire `prek install` into `package.json`'s `prepare` script.
Add a "Pre-commit hooks" section to `README.md`.
Commit: `docs: document prek pre-commit setup (#14)`
## Risks and Mitigations
| Risk | Mitigation |
| -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| prek not installed on contributor's machine → `prepare` script fails | Document prek installation in README. The `prepare` script can use `prek install` with a guard (`command -v prek` or similar) so it warns but does not block `npm install`. |
| Hook runs full-repo lint instead of staged-only → slow commits | Configure prek to pass only staged filenames to each command. Verify with a manual test. |
| Could this silently weaken a permission? | No — this change is purely developer tooling. It adds a pre-commit gate; it does not touch any permission surface, policy file, or runtime code. |
| markdownlint glob mismatch between hook and `npm run lint:md` | Use the same glob patterns in `.prek.yaml` as in `package.json`'s `lint:md` script. |
| `npx biome` falls back to a global install if local is missing | `npx` resolves from `node_modules/.bin` first when run inside a project with a lockfile. Document that `npm install` must be run before committing. |
## Open Questions
1. **Should `prepare` silently skip if prek is not installed?**
A guard like `command -v prek >/dev/null 2>&1 && prek install || true` avoids blocking `npm install` for contributors who haven't installed prek yet, but it also means hooks silently won't exist.
Decide during implementation.
2. **Should we pin a prek version?**
prek is installed globally (via `cargo install` or a binary download), not as an npm dependency.
Pinning is not straightforward — defer unless version-specific breakage appears.