#!/bin/sh # .githooks/pre-commit — TVU upstream-gate artifact 确定层机校(零依赖 · 纯文档仓变体) # # 目的:本仓 commit `docs/specs/upstream-gate..md`(支柱④ 上游理解-分析 gate 产出物)时, # 强制它通过 tvu-design-system 的 validator 确定层(schema 必填字段 / sources_read 锚点存在 / # competitive URL 格式与占位域名 / data_feasibility)。人工层(理解 / persona / MVP)留 owner review。 # # 为什么是 git hook 不是 CI(2026-09-09 owner 拍 ai-ds-lab decision-queue Q13): # 本仓是纯文档仓 —— 无 package.json / 无 CI。DS 的 CI 模板 `templates/upstream-gate-workflow.yml` # 要求 `pnpm install --frozen-lockfile` + 把 DS 装成依赖 + GitHub Actions 语法(本仓在 Gitea)。 # 而 DS `templates/consumer-product/.githooks/` 那套范式 README 逐字就是为「变体 B(Design-only), # 连 npm/husky 基建都没有」的仓设计的:git 原生 `core.hooksPath`,**唯一硬依赖是 node**。本文件照它的形态。 # # 启用(每个 clone 各自跑一次,不随 clone 自动带上): # git config core.hooksPath .githooks # # 定位 DS 仓(与 DS `.claude/hooks/detect-figma-task.sh` 同口径): # 环境变量 TVU_DESIGN_SYSTEM_PATH > 兄弟目录 ../tvu-design-system # # 可选环境变量: # TVU_UPSTREAM_GATE_STRICT=1 → node 缺失 / 找不到 DS 时判失败(默认 fail-open:只告警不拦) # # ⚠️ 用 --no-network:pre-commit 不该等 N 个 HTTP 请求。DS validator 2026-09-09 起 --no-network # 仍判 URL 格式 / 占位域名(example.com 会红),只把 HTTP 可达性记 UNVERIFIED 留 owner review。 set -e HOOK_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P) REPO_ROOT=$(CDPATH= cd -- "$HOOK_DIR/.." && pwd -P) # 只看本次 staged 的(新增/复制/修改)artifact;模板 _upstream-gate.template.md 不算 STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^docs/specs/upstream-gate\.[^/_][^/]*\.md$' || true) if [ -z "$STAGED" ]; then exit 0 fi echo "▶ pre-commit: upstream-gate artifact 确定层机校" fail_open() { echo "⚠️ $1" echo " 本次 upstream-gate artifact 【未经机器验证】,只能靠 owner review 人工兜底。" if [ "${TVU_UPSTREAM_GATE_STRICT:-0}" = "1" ]; then echo "❌ TVU_UPSTREAM_GATE_STRICT=1:按失败处理,阻断提交。" exit 1 fi echo " (fail-open:不阻断本次提交。设 TVU_UPSTREAM_GATE_STRICT=1 可改为阻断。)" exit 0 } if ! command -v node >/dev/null 2>&1; then fail_open "未找到 node —— 无法机校。装 node 后本闸自动生效:https://nodejs.org(node 是本闸唯一硬依赖)" fi DS="" if [ -n "${TVU_DESIGN_SYSTEM_PATH:-}" ] && [ -f "$TVU_DESIGN_SYSTEM_PATH/scripts/validate-upstream-gate.mjs" ]; then DS="$TVU_DESIGN_SYSTEM_PATH" elif [ -f "$REPO_ROOT/../tvu-design-system/scripts/validate-upstream-gate.mjs" ]; then DS=$(CDPATH= cd -- "$REPO_ROOT/../tvu-design-system" && pwd -P) fi if [ -z "$DS" ]; then fail_open "未定位 tvu-design-system 仓 —— 设 TVU_DESIGN_SYSTEM_PATH,或把它 clone 到本仓的兄弟目录。" fi for f in $STAGED; do echo " · $f" if ! node "$DS/scripts/validate-upstream-gate.mjs" --repo-root="$REPO_ROOT" --artifact="$REPO_ROOT/$f" --no-network; then echo "❌ $f 确定层 FAIL —— 修复上面点名的 finding 后重新 commit。" echo " (⛔ 别用 --no-verify 绕:这份 artifact 是 mockup/code 动手前的强制前置,见 DS skills/upstream-gate/SKILL.md)" exit 1 fi done echo " ✓ upstream-gate 确定层 OK(--no-network:格式 / 占位域名已判;HTTP 可达性与人工层留 owner review)" exit 0