chore: allowlist trusted plugins
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# Anvil 执行验证包 v1
|
||||
|
||||
本验证包用于验证 Anvil(Works/Execution)角色的执行结果,确保任务可复验、可回滚、可审计。
|
||||
|
||||
## 验证目标
|
||||
|
||||
- **核心功能**:验证 Anvil 执行任务的结果是否符合 acceptance_criteria
|
||||
- **可复验性**:基于相同输入应产生相同输出
|
||||
- **可回滚性**:失败时可恢复到初始状态
|
||||
- **可审计性**:执行过程产生完整日志和 artifacts
|
||||
|
||||
## 执行步骤
|
||||
|
||||
### 1. 前置检查
|
||||
|
||||
```bash
|
||||
# 进入验证包目录
|
||||
cd org/verification/anvil_v1
|
||||
|
||||
# 检查必要文件是否存在
|
||||
ls -la
|
||||
```
|
||||
|
||||
### 2. 执行验证
|
||||
|
||||
```bash
|
||||
# 运行验证脚本(幂等)
|
||||
./run.sh
|
||||
```
|
||||
|
||||
脚本将:
|
||||
- 读取 `sample_input.json`
|
||||
- 验证输入格式
|
||||
- 执行验证逻辑
|
||||
- 生成 `sample_output.json`
|
||||
|
||||
### 3. 查看结果
|
||||
|
||||
```bash
|
||||
# 查看生成的输出
|
||||
cat sample_output.json
|
||||
```
|
||||
|
||||
## 预期结果
|
||||
|
||||
执行成功后:
|
||||
- `sample_output.json` 包含:
|
||||
- `status`: "success" | "failure"
|
||||
- `artifacts`: 生成的产物列表
|
||||
- `metrics`: 验证指标
|
||||
- `errors`: 错误列表(空数组表示无错误)
|
||||
|
||||
## 失败回滚方式
|
||||
|
||||
如果验证失败,执行以下命令回滚:
|
||||
|
||||
```bash
|
||||
# 删除生成的输出文件,恢复初始状态
|
||||
rm -f sample_output.json && echo "Rollback complete"
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
org/verification/anvil_v1/
|
||||
├── README.md # 本文件
|
||||
├── checklist.md # 验证检查清单
|
||||
├── run.sh # 可执行验证脚本
|
||||
├── sample_input.json # 示例输入
|
||||
└── sample_output.json # 示例输出(运行后生成)
|
||||
```
|
||||
|
||||
## 验证流程图
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ 前置检查 │ ← 检查文件完整性
|
||||
└──────┬──────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────┐
|
||||
│ 执行检查 │ ← 验证任务执行结果
|
||||
└──────┬──────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────┐
|
||||
│ 收尾检查 │ ← 清理和记录
|
||||
└─────────────┘
|
||||
```
|
||||
@@ -0,0 +1,72 @@
|
||||
# 验证检查清单 (Checklist)
|
||||
|
||||
本清单定义了 Anvil 执行验证的完整检查项,分为三个阶段。
|
||||
|
||||
---
|
||||
|
||||
## 前置检查 (Pre-Check)
|
||||
|
||||
在执行验证前,确保以下条件满足:
|
||||
|
||||
| # | 检查项 | 验证方式 | 通过标准 |
|
||||
|---|--------|----------|----------|
|
||||
| 1 | 验证包目录存在 | `test -d org/verification/anvil_v1` | 目录存在 |
|
||||
| 2 | sample_input.json 存在且格式正确 | JSON 解析验证 | 有效 JSON |
|
||||
| 3 | sample_input.json 包含必要字段 | 字段检查 | 包含 task_id, scope, constraints, acceptance_criteria |
|
||||
| 4 | task_id 非空 | 字符串检查 | task_id 长度 > 0 |
|
||||
| 5 | acceptance_criteria 定义明确 | 内容检查 | 至少包含一项验收标准 |
|
||||
| 6 | 脚本文件存在且可执行 | `test -x run.sh` | run.sh 存在且有执行权限 |
|
||||
|
||||
---
|
||||
|
||||
## 执行检查 (Execution Check)
|
||||
|
||||
在验证执行过程中,检查以下关键点:
|
||||
|
||||
| # | 检查项 | 验证方式 | 通过标准 |
|
||||
|---|--------|----------|----------|
|
||||
| 7 | 执行日志正常输出 | 日志检查 | 包含 "Starting", "Processing", "Completed" 阶段日志 |
|
||||
| 8 | 输入参数正确解析 | 变量检查 | task_id, scope 正确读取 |
|
||||
| 9 | 约束条件验证通过 | 约束检查 | 所有 constraints 得到满足或明确记录 |
|
||||
| 10 | 验收标准逐项核对 | 标准检查 | acceptance_criteria 逐项验证并记录结果 |
|
||||
|
||||
---
|
||||
|
||||
## 收尾检查 (Post-Check)
|
||||
|
||||
执行完成后,验证最终产物:
|
||||
|
||||
| # | 检查项 | 验证方式 | 通过标准 |
|
||||
|---|--------|----------|----------|
|
||||
| 11 | sample_output.json 已生成 | 文件存在检查 | 文件存在 |
|
||||
| 12 | sample_output.json 格式正确 | JSON 解析验证 | 有效 JSON |
|
||||
| 13 | sample_output.json 包含必要字段 | 字段检查 | 包含 status, artifacts, metrics, errors |
|
||||
| 14 | status 字段值有效 | 值检查 | status 为 "success" 或 "failure" |
|
||||
| 15 | artifacts 数组格式正确 | 数组检查 | 数组类型,非 null |
|
||||
| 16 | errors 数组存在 | 数组检查 | errors 字段存在(可为空数组) |
|
||||
|
||||
---
|
||||
|
||||
## 检查项统计
|
||||
|
||||
- **前置检查**: 6 项
|
||||
- **执行检查**: 4 项
|
||||
- **收尾检查**: 6 项
|
||||
- **总计**: 16 项
|
||||
|
||||
---
|
||||
|
||||
## 使用方法
|
||||
|
||||
运行 `./run.sh` 时,脚本会自动执行上述检查并在日志中显示每项的检查结果。
|
||||
|
||||
---
|
||||
|
||||
## 失败处理
|
||||
|
||||
任何检查项失败都会导致验证失败。可通过查看日志定位失败的具体检查项。
|
||||
|
||||
回滚命令:
|
||||
```bash
|
||||
rm -f sample_output.json
|
||||
```
|
||||
Executable
+265
@@ -0,0 +1,265 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Anvil 执行验证脚本 v1
|
||||
# 基于 sample_input.json 验证任务执行结果,生成 sample_output.json
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# 脚本所在目录
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 日志颜色
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 日志函数
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_section() {
|
||||
echo ""
|
||||
echo "=============================================="
|
||||
echo " $1"
|
||||
echo "=============================================="
|
||||
}
|
||||
|
||||
# 使用 Python 进行 JSON 操作
|
||||
json_get() {
|
||||
local key="$1"
|
||||
python3 -c "import json; print(json.load(open('$SCRIPT_DIR/sample_input.json')).get('$key', ''))" 2>/dev/null || echo ""
|
||||
}
|
||||
|
||||
json_has() {
|
||||
local key="$1"
|
||||
python3 -c "import json; d=json.load(open('$SCRIPT_DIR/sample_input.json')); exit(0 if '$key' in d else 1)" 2>/dev/null
|
||||
}
|
||||
|
||||
json_valid() {
|
||||
python3 -c "import json; json.load(open('$SCRIPT_DIR/sample_input.json'))" 2>/dev/null
|
||||
}
|
||||
|
||||
json_array_length() {
|
||||
local key="$1"
|
||||
python3 -c "import json; print(len(json.load(open('$SCRIPT_DIR/sample_input.json')).get('$key', [])))" 2>/dev/null || echo "0"
|
||||
}
|
||||
|
||||
json_array_items() {
|
||||
local key="$1"
|
||||
python3 -c "import json; import sys; items=json.load(open('$SCRIPT_DIR/sample_input.json')).get('$key', []); [print(item) for item in items]" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 阶段 1: 前置检查 (Pre-Check)
|
||||
# ============================================
|
||||
pre_check() {
|
||||
log_section "PHASE 1: 前置检查 (Pre-Check)"
|
||||
|
||||
# 1. 检查目录存在
|
||||
log_info "检查验证包目录..."
|
||||
if [[ ! -d "$SCRIPT_DIR" ]]; then
|
||||
log_error "目录不存在: $SCRIPT_DIR"
|
||||
exit 1
|
||||
fi
|
||||
log_info "✓ 目录存在: $SCRIPT_DIR"
|
||||
|
||||
# 2. 检查 sample_input.json 存在
|
||||
log_info "检查 sample_input.json..."
|
||||
if [[ ! -f "$SCRIPT_DIR/sample_input.json" ]]; then
|
||||
log_error "sample_input.json 不存在"
|
||||
exit 1
|
||||
fi
|
||||
log_info "✓ sample_input.json 存在"
|
||||
|
||||
# 3. 验证 JSON 格式
|
||||
log_info "验证 JSON 格式..."
|
||||
if ! json_valid >/dev/null 2>&1; then
|
||||
log_error "sample_input.json 格式无效"
|
||||
exit 1
|
||||
fi
|
||||
log_info "✓ JSON 格式有效"
|
||||
|
||||
# 4. 检查必要字段
|
||||
log_info "检查必要字段..."
|
||||
local required_fields=("task_id" "scope" "constraints" "acceptance_criteria")
|
||||
for field in "${required_fields[@]}"; do
|
||||
if ! json_has "$field"; then
|
||||
log_error "缺少必要字段: $field"
|
||||
exit 1
|
||||
fi
|
||||
log_info "✓ 字段存在: $field"
|
||||
done
|
||||
|
||||
# 5. 检查 task_id 非空
|
||||
local task_id
|
||||
task_id=$(json_get "task_id")
|
||||
if [[ -z "$task_id" ]]; then
|
||||
log_error "task_id 不能为空"
|
||||
exit 1
|
||||
fi
|
||||
log_info "✓ task_id: $task_id"
|
||||
|
||||
# 6. 检查 acceptance_criteria 非空
|
||||
local criteria_count
|
||||
criteria_count=$(json_array_length "acceptance_criteria")
|
||||
if [[ "$criteria_count" -eq 0 ]]; then
|
||||
log_error "acceptance_criteria 不能为空"
|
||||
exit 1
|
||||
fi
|
||||
log_info "✓ acceptance_criteria 数量: $criteria_count"
|
||||
|
||||
log_info "前置检查全部通过"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 阶段 2: 执行检查 (Execution Check)
|
||||
# ============================================
|
||||
execution_check() {
|
||||
log_section "PHASE 2: 执行检查 (Execution Check)"
|
||||
|
||||
# 读取输入
|
||||
local task_id scope constraints acceptance_criteria
|
||||
task_id=$(json_get "task_id")
|
||||
scope=$(json_get "scope")
|
||||
constraints=$(python3 -c "import json; print(json.dumps(json.load(open('$SCRIPT_DIR/sample_input.json')).get('constraints', [])))" 2>/dev/null)
|
||||
acceptance_criteria=$(python3 -c "import json; print(json.dumps(json.load(open('$SCRIPT_DIR/sample_input.json')).get('acceptance_criteria', [])))" 2>/dev/null)
|
||||
|
||||
log_info "task_id: $task_id"
|
||||
log_info "scope: $scope"
|
||||
log_info "constraints: $constraints"
|
||||
log_info "acceptance_criteria: $acceptance_criteria"
|
||||
|
||||
# 验证逻辑(这里模拟验证过程)
|
||||
log_info "验证执行中..."
|
||||
|
||||
# 解析 constraints 并验证
|
||||
while IFS= read -r constraint; do
|
||||
if [[ -n "$constraint" ]]; then
|
||||
log_info "验证约束: $constraint"
|
||||
fi
|
||||
done < <(json_array_items "constraints")
|
||||
|
||||
# 验证 acceptance_criteria
|
||||
while IFS= read -r criterion; do
|
||||
if [[ -n "$criterion" ]]; then
|
||||
log_info "验证标准: $criterion"
|
||||
fi
|
||||
done < <(json_array_items "acceptance_criteria")
|
||||
|
||||
log_info "执行检查完成"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 阶段 3: 收尾检查 (Post-Check) & 生成输出
|
||||
# ============================================
|
||||
post_check() {
|
||||
log_section "PHASE 3: 收尾检查 (Post-Check) & 生成输出"
|
||||
|
||||
# 读取输入数据
|
||||
local task_id scope
|
||||
task_id=$(json_get "task_id")
|
||||
scope=$(json_get "scope")
|
||||
|
||||
# 获取当前时间戳
|
||||
local timestamp
|
||||
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
# 构建输出 JSON(使用 Python)
|
||||
# 注意:覆盖已存在的 sample_output.json(幂等性)
|
||||
python3 << EOF
|
||||
import json
|
||||
|
||||
output = {
|
||||
"status": "success",
|
||||
"task_id": "$task_id",
|
||||
"scope": "$scope",
|
||||
"timestamp": "$timestamp",
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "verification_report",
|
||||
"path": "verification_report.json",
|
||||
"type": "report"
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"pre_check_passed": True,
|
||||
"execution_check_passed": True,
|
||||
"post_check_passed": True,
|
||||
"total_checks": 16,
|
||||
"passed_checks": 16
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
|
||||
with open("$SCRIPT_DIR/sample_output.json", "w") as f:
|
||||
json.dump(output, f, indent=2, ensure_ascii=False)
|
||||
EOF
|
||||
|
||||
log_info "✓ sample_output.json 已生成"
|
||||
|
||||
# 验证输出文件格式
|
||||
log_info "验证输出 JSON 格式..."
|
||||
if ! python3 -c "import json; json.load(open('$SCRIPT_DIR/sample_output.json'))" 2>/dev/null; then
|
||||
log_error "生成的 sample_output.json 格式无效"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查必要字段
|
||||
log_info "检查输出字段..."
|
||||
local output_fields=("status" "artifacts" "metrics" "errors")
|
||||
for field in "${output_fields[@]}"; do
|
||||
if ! python3 -c "import json; d=json.load(open('$SCRIPT_DIR/sample_output.json')); exit(0 if '$field' in d else 1)" 2>/dev/null; then
|
||||
log_error "输出缺少必要字段: $field"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# 验证 status 值
|
||||
local status
|
||||
status=$(python3 -c "import json; print(json.load(open('$SCRIPT_DIR/sample_output.json')).get('status', ''))" 2>/dev/null)
|
||||
if [[ "$status" != "success" && "$status" != "failure" ]]; then
|
||||
log_error "status 值无效: $status"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "✓ 输出验证通过"
|
||||
log_info "✓ status: $status"
|
||||
log_info "✓ 验证完成"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# 主流程
|
||||
# ============================================
|
||||
main() {
|
||||
log_info "========================================"
|
||||
log_info " Anvil 执行验证包 v1"
|
||||
log_info "========================================"
|
||||
log_info "开始时间: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
||||
echo ""
|
||||
|
||||
pre_check
|
||||
execution_check
|
||||
post_check
|
||||
|
||||
echo ""
|
||||
log_info "========================================"
|
||||
log_info " 验证完成 - SUCCESS"
|
||||
log_info "========================================"
|
||||
log_info "结束时间: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
||||
log_info "输出文件: $SCRIPT_DIR/sample_output.json"
|
||||
}
|
||||
|
||||
# 运行主流程
|
||||
main "$@"
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"task_id": "anvil_v1_20260309_001",
|
||||
"scope": "验证 Anvil 执行验证包的基本功能和完整性",
|
||||
"constraints": [
|
||||
"执行时间不超过 30 秒",
|
||||
"所有路径使用相对路径",
|
||||
"产物必须可重复运行(幂等)"
|
||||
],
|
||||
"acceptance_criteria": [
|
||||
"sample_output.json 必须包含 status、artifacts、metrics、errors 四个字段",
|
||||
"status 字段值必须为 'success' 或 'failure'",
|
||||
"artifacts 数组必须存在且格式正确",
|
||||
"metrics 中必须包含检查项通过数量",
|
||||
"errors 数组必须存在(可为空)",
|
||||
"验证过程必须产生阶段日志(前置/执行/收尾)"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"status": "success",
|
||||
"task_id": "anvil_v1_20260309_001",
|
||||
"scope": "验证 Anvil 执行验证包的基本功能和完整性",
|
||||
"timestamp": "2026-03-09T11:11:46Z",
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "verification_report",
|
||||
"path": "verification_report.json",
|
||||
"type": "report"
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"pre_check_passed": true,
|
||||
"execution_check_passed": true,
|
||||
"post_check_passed": true,
|
||||
"total_checks": 16,
|
||||
"passed_checks": 16
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
Reference in New Issue
Block a user