Files
weichenandCursor 90f77eac93 feat(authz): implement six-phase permissions, settings and workflow v2
Close P0 auth gaps for lineage/runs, stage ABAC fail-closed, and
project:create; add IAM migrations 00021-23, me settings APIs, schema v2
manifests, orchestrator skeleton, and gate A regression coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00

85 lines
2.2 KiB
Go

package squad
import (
"encoding/json"
"os"
"path/filepath"
"strings"
)
// ValidateQualityGateV2 按 quality_gate_key 执行结构化门禁。
func ValidateQualityGateV2(gateKey, wsDir string) []string {
switch gateKey {
case "quality.system_reqs.v2":
return validateRequirementsJSON(wsDir)
case "quality.test_manager.v2":
return validateTestCasesJSON(wsDir)
default:
return nil
}
}
func validateRequirementsJSON(wsDir string) []string {
path := filepath.Join(wsDir, "artifacts", "requirements.json")
raw, err := os.ReadFile(path)
if err != nil {
return []string{"requirements.json 为必需产物"}
}
var reqs []map[string]any
if err := json.Unmarshal(raw, &reqs); err != nil {
return []string{"requirements.json 格式无效"}
}
ids := map[string]bool{}
issues := make([]string, 0)
for _, r := range reqs {
id, _ := r["id"].(string)
if id == "" {
issues = append(issues, "需求缺少 id")
continue
}
if ids[id] {
issues = append(issues, "重复需求 id: "+id)
}
ids[id] = true
for _, field := range []string{"verification_method", "acceptance_criteria"} {
if v, _ := r[field].(string); strings.TrimSpace(v) == "" {
issues = append(issues, id+": 缺少 "+field)
}
}
}
return issues
}
func validateTestCasesJSON(wsDir string) []string {
path := filepath.Join(wsDir, "artifacts", "test_cases.json")
raw, err := os.ReadFile(path)
if err != nil {
return []string{"test_cases.json 为必需产物"}
}
var cases []map[string]any
if err := json.Unmarshal(raw, &cases); err != nil {
return []string{"test_cases.json 格式无效"}
}
reqPath := filepath.Join(wsDir, "artifacts", "requirements.json")
reqRaw, err := os.ReadFile(reqPath)
if err != nil {
return []string{"缺少上游 requirements.json 无法验证覆盖率"}
}
var reqs []map[string]any
_ = json.Unmarshal(reqRaw, &reqs)
covered := map[string]bool{}
for _, tc := range cases {
if rid, _ := tc["requirement_id"].(string); rid != "" {
covered[rid] = true
}
}
issues := make([]string, 0)
for _, r := range reqs {
id, _ := r["id"].(string)
if id != "" && !covered[id] {
issues = append(issues, "需求未覆盖: "+id)
}
}
return issues
}