lili 1981a6be01
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
feat(storage): 闭合 Agent 到 Runtime 的 OSS 游戏链路
增加不可变源码检出、两阶段 finalize/activate、Runtime 同源对象读取与 iframe 安全边界,并用 fail-closed CI 门固定契约。Git 仅提交平台实现、契约、迁移和 SoT,不包含具体游戏源码、素材、bundle 或验收证据。
2026-07-30 05:21:44 -07:00

75 lines
4.8 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# 治理机器门 pre-commit(激活一次:git config core.hooksPath .githooks)
# 各门按暂存文件路径条件触发(判据没动的提交不跑对应门,省时间);
# 紧急绕过:git commit --no-verify(服务端 Gitea Actions 门仍会兜住)。
set -uo pipefail
STAGED="$(git diff --cached --name-only)"
ROOT="$(git rev-parse --show-toplevel)"
fail=0
# ── 门 1:文档治理七检 —— 触发 = 任一 .md 变更 ──
if printf '%s\n' "$STAGED" | grep -qE '\.md$'; then
bash "$ROOT/.agents/tools/docs-gate.sh" || { echo '✘ docs-gate 七检未过'; fail=1; }
fi
# ── 门 2:门金标判例库全量回归 —— 触发 = 触及任一验收门判据或判例库自身 ──
# 判据文件改动前必须先让本回归全绿(误杀/漏放判例不得回退),口径见 contracts/gate-fixtures/README.md。
if printf '%s\n' "$STAGED" | grep -qE '(play\.cdp\.cjs|amodel-gen/tools\.mjs|check-undef\.mjs|gate_judge\.py|cheap_gates\.py|^contracts/gate-fixtures/)'; then
node "$ROOT/contracts/gate-fixtures/run.mjs" || { echo '✘ 门金标判例库回归未过'; fail=1; }
fi
# ── 门 3:play-loop 契约校验(PlaySpec C5 / VerdictFeedback C6)—— 触发 = 触及 play-loop 契约 ──
if printf '%s\n' "$STAGED" | grep -qE '^contracts/play-loop/'; then
python3 "$ROOT/contracts/play-loop/validate.py" --suite || { echo '✘ play-loop 契约正负样本套件未过'; fail=1; }
fi
# ── 门 3b:游戏内容对象存储契约正负样本 —— 触发 = 三份清单/状态迁移/实现或判例变更 ──
if printf '%s\n' "$STAGED" | grep -qE '(contracts/(game-(package|artifact-manifest|source-archive)\.schema\.json|db-schemas/V3[45].*artifact)|game-cloud/huijing-server/src/main/resources/db/migration/V3[45].*artifact|tier2/gen-worker/(worker/game_(artifact|source_archive|artifact_storage)_store\.py|worker/game_content_repository\.py|scripts/game_content_repository\.py|tests/test_game_(artifact|source_archive|artifact_storage|content_repository)))'; then
# mise 的默认 Python 可能未装 pytest仓内测试 venv 可用时复用,否则明确判红,绝不静默跳过。
PYTEST_PYTHON=python3
if ! "$PYTEST_PYTHON" -c 'import pytest' >/dev/null 2>&1; then
if [ -x "$ROOT/cheap-worker/.venv/bin/python" ] \
&& "$ROOT/cheap-worker/.venv/bin/python" -c 'import pytest' >/dev/null 2>&1; then
PYTEST_PYTHON="$ROOT/cheap-worker/.venv/bin/python"
else
echo '✘ 游戏内容对象存储门缺少 pytest默认 Python 与 cheap-worker/.venv 均不可用)'
PYTEST_PYTHON=''
fail=1
fi
fi
if [ -n "$PYTEST_PYTHON" ]; then
PYTHONPATH="$ROOT/tier2/gen-worker" "$PYTEST_PYTHON" -m pytest -q \
"$ROOT/tier2/gen-worker/tests/test_game_artifact_store.py" \
"$ROOT/tier2/gen-worker/tests/test_game_source_archive.py" \
"$ROOT/tier2/gen-worker/tests/test_game_artifact_storage_store.py" \
"$ROOT/tier2/gen-worker/tests/test_game_artifact_storage_ddl.py" \
"$ROOT/tier2/gen-worker/tests/test_game_content_repository.py" \
|| { echo '✘ 游戏内容对象存储契约正负样本未过'; fail=1; }
fi
fi
# ── 门 4:品类 rubric fixture ↔ skill 双写对账 —— 触发 = 触及品类 rubric fixture 或品类 skill ──
if printf '%s\n' "$STAGED" | grep -qE '(cheap-worker/fixtures/genre-rubrics/|\.agents/skills/(trpg|heritage|puzzle|narrative|sim-business)-game-design\.md)'; then
python3 "$ROOT/.agents/tools/rubric-sync-gate.py" || { echo '✘ rubric 双写对账未过'; fail=1; }
fi
# ── 门 6:便宜档插件面三方一致性对账 —— 触发 = 触及插件目录/prompt 白名单/host-config 注入/PLUGIN_KEY_DIR ──
# 防漂移:白名单列了但没注入(运行时崩)、注入了但白名单没列(暗资产)、新增插件目录未裁定(悄悄成暗插件)。
if printf '%s\n' "$STAGED" | grep -qE '(game-runtime/src/plugins/|contracts/prompts/04-config/cheap-system\.md|game-runtime/games/_template/src/host-config\.js|amodel-gen/tools\.mjs)'; then
python3 "$ROOT/.agents/tools/plugin-surface-gate.py" || { echo '✘ 插件面三方对账未过'; fail=1; }
fi
# ── 门 5:Prompt 契约双闸 —— 触发 = 触及 prompts 契约(registry.yaml 或任一 prompt .md) ──
# 闸 a = 版本一致性(check_registry:registry.yaml↔.md frontmatter 的 version 必须相等);
# 闸 b = 四道闸·闸0 版本升号(check_version_bump:改了 prompt 正文相对 HEAD 必须升 version)。
if printf '%s\n' "$STAGED" | grep -qE '^contracts/prompts/'; then
python3 "$ROOT/contracts/prompts/check_registry.py" || { echo '✘ Prompt Registry 版本一致性未过'; fail=1; }
python3 "$ROOT/contracts/prompts/check_version_bump.py" || { echo '✘ Prompt 闸0 version 升号未过(改正文须升 version)'; fail=1; }
fi
if [ "$fail" -ne 0 ]; then
echo '提交被拦(明细见上;紧急绕过 git commit --no-verify,服务端门仍兜)'
exit 1
fi