enterprise-agent-designer 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codebuddy-plugin/plugin.json +66 -0
- package/CHANGELOG.md +729 -0
- package/DESIGN_NOTE.md +101 -0
- package/LICENSE +21 -0
- package/PACKAGE.yaml +209 -0
- package/README.md +109 -0
- package/RETROSPECTIVE_v0.1-v0.10.md +67 -0
- package/RUNTIME_ASSEMBLY.md +134 -0
- package/SYSTEM_PROMPT.md +139 -0
- package/agents/agent-designer.md +151 -0
- package/avatars/.gitkeep +0 -0
- package/avatars/expert.png +0 -0
- package/evaluation/README.md +60 -0
- package/evaluation/cases.json +2045 -0
- package/evaluation/document-reviewer-holdout.md +24 -0
- package/package.json +33 -0
- package/references/optional-host-workflow.md +105 -0
- package/scripts/check_agent_delivery.py +202 -0
- package/scripts/optional/workflow_controller.py +478 -0
- package/scripts/validate.py +437 -0
- package/scripts/verify_v0321_guards.py +410 -0
- package/skills/design-enterprise-agent/SKILL.md +131 -0
- package/skills/design-enterprise-agent/references/41-performance-worked-example.md +199 -0
- package/skills/design-enterprise-agent/references/cold-start-and-writing.md +163 -0
- package/skills/design-enterprise-agent/references/requirements-grilling.md +40 -0
- package/skills/design-enterprise-agent/references/runtime-and-integration.md +102 -0
- package/skills/design-enterprise-agent/references/task-adaptive-runtime.md +70 -0
- package/skills/design-enterprise-agent/scripts/finalize_agent_delivery.py +748 -0
- package/skills/grill-with-docs/SKILL.md +58 -0
- package/skills/grill-with-docs/references/design-context-format.md +101 -0
- package/skills/grilling/SKILL.md +62 -0
- package/skills/review-enterprise-agent/SKILL.md +86 -0
- package/skills/review-enterprise-agent/references/isolated-review-contract.md +154 -0
- package/skills/review-enterprise-agent/scripts/validate_review_receipt.py +338 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Lightweight package checks. Passing does not evaluate Agent behavior."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import re
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
13
|
+
VERSION = "0.34.1"
|
|
14
|
+
|
|
15
|
+
REQUIRED_FILES = [
|
|
16
|
+
"PACKAGE.yaml",
|
|
17
|
+
"README.md",
|
|
18
|
+
"SYSTEM_PROMPT.md",
|
|
19
|
+
"RUNTIME_ASSEMBLY.md",
|
|
20
|
+
"references/optional-host-workflow.md",
|
|
21
|
+
"DESIGN_NOTE.md",
|
|
22
|
+
"RETROSPECTIVE_v0.1-v0.10.md",
|
|
23
|
+
"CHANGELOG.md",
|
|
24
|
+
"scripts/check_agent_delivery.py",
|
|
25
|
+
"scripts/verify_v0321_guards.py",
|
|
26
|
+
"scripts/optional/workflow_controller.py",
|
|
27
|
+
"skills/grilling/SKILL.md",
|
|
28
|
+
"skills/grill-with-docs/SKILL.md",
|
|
29
|
+
"skills/grill-with-docs/references/design-context-format.md",
|
|
30
|
+
"skills/design-enterprise-agent/SKILL.md",
|
|
31
|
+
"skills/design-enterprise-agent/scripts/finalize_agent_delivery.py",
|
|
32
|
+
"skills/design-enterprise-agent/references/cold-start-and-writing.md",
|
|
33
|
+
"skills/design-enterprise-agent/references/requirements-grilling.md",
|
|
34
|
+
"skills/design-enterprise-agent/references/runtime-and-integration.md",
|
|
35
|
+
"skills/design-enterprise-agent/references/41-performance-worked-example.md",
|
|
36
|
+
"skills/design-enterprise-agent/references/task-adaptive-runtime.md",
|
|
37
|
+
"skills/review-enterprise-agent/SKILL.md",
|
|
38
|
+
"skills/review-enterprise-agent/references/isolated-review-contract.md",
|
|
39
|
+
"skills/review-enterprise-agent/scripts/validate_review_receipt.py",
|
|
40
|
+
"evaluation/README.md",
|
|
41
|
+
"evaluation/cases.json",
|
|
42
|
+
"evaluation/document-reviewer-holdout.md",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
REQUIRED_CATEGORIES = {
|
|
46
|
+
"document_evidence_gap_can_trigger_exploration",
|
|
47
|
+
"rationale_supports_unenumerated_strategy",
|
|
48
|
+
"interview_explores_before_solution",
|
|
49
|
+
"interaction_form_matches_purpose",
|
|
50
|
+
"strategy_same_intent_different_state",
|
|
51
|
+
"strategy_same_state_different_intent",
|
|
52
|
+
"correction_updates_dependencies_not_everything",
|
|
53
|
+
"generated_agent_must_execute_not_describe",
|
|
54
|
+
"interview_sufficient_material_does_not_repeat",
|
|
55
|
+
"cold_start_one_line_role_fork",
|
|
56
|
+
"old_draft_requires_business_identity_alignment",
|
|
57
|
+
"cold_start_weak_draft_rebuilds_target_behavior",
|
|
58
|
+
"sufficient_materials_direct_delivery",
|
|
59
|
+
"document_grounded_grilling_persists_resolved_context",
|
|
60
|
+
"recursive_full_frontier_grilling",
|
|
61
|
+
"surface_decisions_do_not_close_professional_task",
|
|
62
|
+
"complete_rubric_may_be_professionally_inapplicable",
|
|
63
|
+
"natural_system_prompt_and_professional_skill",
|
|
64
|
+
"knowledge_tool_dependency_not_connected",
|
|
65
|
+
"single_chat_no_fake_review_harness",
|
|
66
|
+
"no_invented_business_parameters",
|
|
67
|
+
"actual_assets_not_compiled_markdown",
|
|
68
|
+
"full_source_runtime_requires_source_gate",
|
|
69
|
+
"invalid_review_receipt_blocks_manual_packaging",
|
|
70
|
+
"evidence_status_honest",
|
|
71
|
+
"read_only_review",
|
|
72
|
+
"isolated_grounding_review_rejects_self_approval",
|
|
73
|
+
"isolated_source_review_catches_cross_asset_conflicts",
|
|
74
|
+
"review_round_never_overrides_materiality",
|
|
75
|
+
"strict_standard_counterexample_not_anchor_failure",
|
|
76
|
+
"grounding_requires_business_object_not_carrier",
|
|
77
|
+
"task_rubric_contract_only_not_blocked",
|
|
78
|
+
"source_authority_audit_rejects_context_self_authorization",
|
|
79
|
+
"frozen_source_snapshot_blocks_post_review_mutation",
|
|
80
|
+
"strict_counterexample_requires_authoritative_premises",
|
|
81
|
+
"missing_evaluation_prerequisite_routes_to_owner",
|
|
82
|
+
"quality_definition_not_standard_coverage",
|
|
83
|
+
"source_rejects_unsupported_scope_expansion",
|
|
84
|
+
"source_requires_skill_dependency_closure",
|
|
85
|
+
"performance_no_tool_prospective_design",
|
|
86
|
+
"performance_contract_only_static_analysis",
|
|
87
|
+
"performance_trace_bound_measured_claim",
|
|
88
|
+
"adaptive_runtime_simple_task_reuses_path",
|
|
89
|
+
"adaptive_runtime_task_shape_without_new_authority",
|
|
90
|
+
"adaptive_runtime_generated_code_not_permission",
|
|
91
|
+
"adaptive_runtime_partial_write_recovery",
|
|
92
|
+
"adaptive_runtime_changed_dependency_invalidates_evidence",
|
|
93
|
+
"adaptive_runtime_total_cost_and_quality",
|
|
94
|
+
"adaptive_runtime_archive_not_production_policy",
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
CASE_FIELDS = {
|
|
98
|
+
"id",
|
|
99
|
+
"category",
|
|
100
|
+
"user_request",
|
|
101
|
+
"context",
|
|
102
|
+
"mock_tools",
|
|
103
|
+
"expected_behaviors",
|
|
104
|
+
"prohibited_behaviors",
|
|
105
|
+
"expected_end_state",
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
REVIEW_RECEIPT_FIELDS = {
|
|
109
|
+
"review_mode",
|
|
110
|
+
"review_scope",
|
|
111
|
+
"review_round",
|
|
112
|
+
"verdict",
|
|
113
|
+
"lowest_failed_layer",
|
|
114
|
+
"decisive_reason",
|
|
115
|
+
"evidence",
|
|
116
|
+
"preserve",
|
|
117
|
+
"return_to",
|
|
118
|
+
"next_action",
|
|
119
|
+
"change_condition",
|
|
120
|
+
"reviewed_snapshot_id",
|
|
121
|
+
"grounding_audit",
|
|
122
|
+
"source_audit",
|
|
123
|
+
"materiality_audit",
|
|
124
|
+
"authority_audit",
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
REVIEW_FAILED_LAYERS = {
|
|
128
|
+
"requirements",
|
|
129
|
+
"professional-task",
|
|
130
|
+
"role",
|
|
131
|
+
"principles",
|
|
132
|
+
"skill-topology",
|
|
133
|
+
"tool-knowledge",
|
|
134
|
+
"output-handoff",
|
|
135
|
+
"trace-runtime",
|
|
136
|
+
"none",
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
REVIEW_RETURN_TARGETS = {
|
|
140
|
+
"grilling",
|
|
141
|
+
"grill-with-docs",
|
|
142
|
+
"design-enterprise-agent",
|
|
143
|
+
"delivery-finalizer",
|
|
144
|
+
"user",
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def read(relative: str) -> str:
|
|
149
|
+
return (ROOT / relative).read_text(encoding="utf-8")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def main() -> int:
|
|
153
|
+
errors: list[str] = []
|
|
154
|
+
|
|
155
|
+
for relative in REQUIRED_FILES:
|
|
156
|
+
if not (ROOT / relative).is_file():
|
|
157
|
+
errors.append(f"缺少文件:{relative}")
|
|
158
|
+
if errors:
|
|
159
|
+
return report(errors)
|
|
160
|
+
|
|
161
|
+
markers = {
|
|
162
|
+
"PACKAGE.yaml": rf"(?m)^version:\s*{re.escape(VERSION)}\s*$",
|
|
163
|
+
"SYSTEM_PROMPT.md": rf"(?m)^Agent-Version:\s*{re.escape(VERSION)}\s*$",
|
|
164
|
+
"RUNTIME_ASSEMBLY.md": rf"(?m)^Assembly-Version:\s*{re.escape(VERSION)}\s*$",
|
|
165
|
+
"references/optional-host-workflow.md": rf"(?m)^Workflow-Version:\s*{re.escape(VERSION)}\s*$",
|
|
166
|
+
"skills/grilling/SKILL.md": rf"(?m)^Skill-Version:\s*{re.escape(VERSION)}\s*$",
|
|
167
|
+
"skills/grill-with-docs/SKILL.md": rf"(?m)^Skill-Version:\s*{re.escape(VERSION)}\s*$",
|
|
168
|
+
"skills/grill-with-docs/references/design-context-format.md": rf"(?m)^Context-Format-Version:\s*{re.escape(VERSION)}\s*$",
|
|
169
|
+
"skills/design-enterprise-agent/SKILL.md": rf"(?m)^Skill-Version:\s*{re.escape(VERSION)}\s*$",
|
|
170
|
+
"skills/review-enterprise-agent/SKILL.md": rf"(?m)^Skill-Version:\s*{re.escape(VERSION)}\s*$",
|
|
171
|
+
"skills/review-enterprise-agent/references/isolated-review-contract.md": rf"(?m)^Reference-Version:\s*{re.escape(VERSION)}\s*$",
|
|
172
|
+
"skills/design-enterprise-agent/references/cold-start-and-writing.md": rf"(?m)^Reference-Version:\s*{re.escape(VERSION)}\s*$",
|
|
173
|
+
"skills/design-enterprise-agent/references/requirements-grilling.md": rf"(?m)^Reference-Version:\s*{re.escape(VERSION)}\s*$",
|
|
174
|
+
"skills/design-enterprise-agent/references/runtime-and-integration.md": rf"(?m)^Reference-Version:\s*{re.escape(VERSION)}\s*$",
|
|
175
|
+
"skills/design-enterprise-agent/references/task-adaptive-runtime.md": rf"(?m)^Reference-Version:\s*{re.escape(VERSION)}\s*$",
|
|
176
|
+
}
|
|
177
|
+
for relative, pattern in markers.items():
|
|
178
|
+
if not re.search(pattern, read(relative)):
|
|
179
|
+
errors.append(f"版本不一致:{relative}")
|
|
180
|
+
|
|
181
|
+
behavior_markers = {
|
|
182
|
+
"SYSTEM_PROMPT.md": "grounding-gate",
|
|
183
|
+
"RUNTIME_ASSEMBLY.md": "subagent_type = general-purpose",
|
|
184
|
+
"references/optional-host-workflow.md": "不进入默认装配",
|
|
185
|
+
"scripts/optional/workflow_controller.py": "WORKFLOW_NOT_TERMINAL",
|
|
186
|
+
"skills/grilling/SKILL.md": "candidate-grounded",
|
|
187
|
+
"skills/grill-with-docs/SKILL.md": "DESIGN_CONTEXT.md",
|
|
188
|
+
"skills/grill-with-docs/references/design-context-format.md": "candidate-for-grounding-review",
|
|
189
|
+
"skills/design-enterprise-agent/SKILL.md": "source-gate",
|
|
190
|
+
"skills/design-enterprise-agent/references/41-performance-worked-example.md": "first_divergence",
|
|
191
|
+
"skills/review-enterprise-agent/SKILL.md": "隔离模式",
|
|
192
|
+
"skills/review-enterprise-agent/references/isolated-review-contract.md": "grounding-gate",
|
|
193
|
+
"skills/review-enterprise-agent/scripts/validate_review_receipt.py": "counterexample_basis",
|
|
194
|
+
"skills/design-enterprise-agent/scripts/finalize_agent_delivery.py": "--forbid-evaluation-term",
|
|
195
|
+
}
|
|
196
|
+
for relative, marker in behavior_markers.items():
|
|
197
|
+
if marker not in read(relative):
|
|
198
|
+
errors.append(f"关键行为或交付边界缺失:{relative}")
|
|
199
|
+
|
|
200
|
+
obsolete_question_limits = {
|
|
201
|
+
"SYSTEM_PROMPT.md": ("每次只处理一个最上游问题", "最后只提出一个业务人员能够回答的问题"),
|
|
202
|
+
"skills/grilling/SKILL.md": ("每轮只问这一题", "只交付当前问题"),
|
|
203
|
+
"skills/grill-with-docs/SKILL.md": ("每轮只呈现",),
|
|
204
|
+
"skills/design-enterprise-agent/references/requirements-grilling.md": ("一次只问一个完整问题", "最后提出的唯一问题"),
|
|
205
|
+
}
|
|
206
|
+
for relative, markers in obsolete_question_limits.items():
|
|
207
|
+
text = read(relative)
|
|
208
|
+
for marker in markers:
|
|
209
|
+
if marker in text:
|
|
210
|
+
errors.append(f"仍保留已废止的机械单问题限制:{relative} -> {marker}")
|
|
211
|
+
|
|
212
|
+
try:
|
|
213
|
+
suite = json.loads(read("evaluation/cases.json"))
|
|
214
|
+
except json.JSONDecodeError as exc:
|
|
215
|
+
errors.append(f"案例 JSON 无法解析:{exc}")
|
|
216
|
+
return report(errors)
|
|
217
|
+
|
|
218
|
+
if suite.get("version") != VERSION:
|
|
219
|
+
errors.append("案例版本与包版本不一致")
|
|
220
|
+
|
|
221
|
+
cases = suite.get("cases")
|
|
222
|
+
if not isinstance(cases, list) or not cases:
|
|
223
|
+
errors.append("案例必须是非空数组")
|
|
224
|
+
return report(errors)
|
|
225
|
+
|
|
226
|
+
ids: list[str] = []
|
|
227
|
+
categories: set[str] = set()
|
|
228
|
+
for index, case in enumerate(cases):
|
|
229
|
+
if not isinstance(case, dict):
|
|
230
|
+
errors.append(f"案例 {index} 不是对象")
|
|
231
|
+
continue
|
|
232
|
+
case_id = case.get("id")
|
|
233
|
+
if not isinstance(case_id, str) or not case_id:
|
|
234
|
+
errors.append(f"案例 {index} 缺少 id")
|
|
235
|
+
case_id = str(index)
|
|
236
|
+
else:
|
|
237
|
+
ids.append(case_id)
|
|
238
|
+
missing = CASE_FIELDS - set(case)
|
|
239
|
+
if missing:
|
|
240
|
+
errors.append(f"案例 {case_id} 缺少字段:{sorted(missing)}")
|
|
241
|
+
category = case.get("category")
|
|
242
|
+
if isinstance(category, str):
|
|
243
|
+
categories.add(category)
|
|
244
|
+
for key in ("expected_behaviors", "prohibited_behaviors"):
|
|
245
|
+
if not isinstance(case.get(key), list) or not case.get(key):
|
|
246
|
+
errors.append(f"案例 {case_id} 的 {key} 必须是非空数组")
|
|
247
|
+
for tool_fixture in case.get("mock_tools", []):
|
|
248
|
+
if not isinstance(tool_fixture, dict):
|
|
249
|
+
continue
|
|
250
|
+
on_call = tool_fixture.get("on_call", {})
|
|
251
|
+
if not isinstance(on_call, dict) or on_call.get("tool") != "Agent":
|
|
252
|
+
continue
|
|
253
|
+
result = tool_fixture.get("result", {})
|
|
254
|
+
if not isinstance(result, dict):
|
|
255
|
+
errors.append(f"案例 {case_id} 的 Agent 模拟返回必须是对象")
|
|
256
|
+
continue
|
|
257
|
+
if result.get("result_type") == "invalid_raw_review_output":
|
|
258
|
+
if not isinstance(result.get("raw_output"), str) or not result["raw_output"].strip():
|
|
259
|
+
errors.append(f"案例 {case_id} 的无效评审原始返回必须保留非空 raw_output")
|
|
260
|
+
continue
|
|
261
|
+
missing_receipt = REVIEW_RECEIPT_FIELDS - set(result)
|
|
262
|
+
if missing_receipt:
|
|
263
|
+
errors.append(
|
|
264
|
+
f"案例 {case_id} 的隔离复审收据缺少字段:{sorted(missing_receipt)}"
|
|
265
|
+
)
|
|
266
|
+
if result.get("lowest_failed_layer") not in REVIEW_FAILED_LAYERS:
|
|
267
|
+
errors.append(
|
|
268
|
+
f"案例 {case_id} 的 lowest_failed_layer 不在契约枚举中:"
|
|
269
|
+
f"{result.get('lowest_failed_layer')}"
|
|
270
|
+
)
|
|
271
|
+
verdict = result.get("verdict")
|
|
272
|
+
if verdict == "pass" and result.get("lowest_failed_layer") != "none":
|
|
273
|
+
errors.append(f"案例 {case_id} 的 pass 收据最低失败层必须为 none")
|
|
274
|
+
if verdict in {"revision_required", "insufficient_basis"} and result.get("lowest_failed_layer") == "none":
|
|
275
|
+
errors.append(f"案例 {case_id} 的非 pass 收据最低失败层不能为 none")
|
|
276
|
+
if result.get("return_to") not in REVIEW_RETURN_TARGETS:
|
|
277
|
+
errors.append(f"案例 {case_id} 的 return_to 不在契约枚举中")
|
|
278
|
+
review_round = result.get("review_round")
|
|
279
|
+
if (
|
|
280
|
+
not isinstance(review_round, int)
|
|
281
|
+
or isinstance(review_round, bool)
|
|
282
|
+
or review_round < 1
|
|
283
|
+
):
|
|
284
|
+
errors.append(f"案例 {case_id} 的 review_round 必须是正整数")
|
|
285
|
+
if not isinstance(result.get("reviewed_snapshot_id"), str):
|
|
286
|
+
errors.append(f"案例 {case_id} 的 reviewed_snapshot_id 必须是字符串")
|
|
287
|
+
authority = result.get("authority_audit")
|
|
288
|
+
if not isinstance(authority, dict):
|
|
289
|
+
errors.append(f"案例 {case_id} 的 authority_audit 必须是对象")
|
|
290
|
+
else:
|
|
291
|
+
for key in ("stable_rules_reviewed", "unresolved_or_unauthorized"):
|
|
292
|
+
if not isinstance(authority.get(key), list):
|
|
293
|
+
errors.append(f"案例 {case_id} 的 authority_audit.{key} 必须是数组")
|
|
294
|
+
if (
|
|
295
|
+
result.get("verdict") == "pass"
|
|
296
|
+
and authority.get("unresolved_or_unauthorized")
|
|
297
|
+
):
|
|
298
|
+
errors.append(f"案例 {case_id} 的 pass 收据仍含无权或未解决规则")
|
|
299
|
+
review_mode = on_call.get("review_mode")
|
|
300
|
+
if result.get("review_mode") != review_mode:
|
|
301
|
+
errors.append(f"案例 {case_id} 的 review_mode 与宿主调用不一致")
|
|
302
|
+
if result.get("review_scope") != "isolated-subagent":
|
|
303
|
+
errors.append(f"案例 {case_id} 的 review_scope 不是 isolated-subagent")
|
|
304
|
+
if review_mode == "grounding-gate" and result.get("reviewed_snapshot_id") != "not_applicable":
|
|
305
|
+
errors.append(f"案例 {case_id} 的 grounding-gate 快照必须为 not_applicable")
|
|
306
|
+
if review_mode == "source-gate" and not str(result.get("reviewed_snapshot_id", "")).startswith("sha256:"):
|
|
307
|
+
errors.append(f"案例 {case_id} 的 source-gate 未绑定 sha256 快照")
|
|
308
|
+
if review_mode == "grounding-gate" and not isinstance(
|
|
309
|
+
result.get("grounding_audit"), dict
|
|
310
|
+
):
|
|
311
|
+
errors.append(f"案例 {case_id} 的 grounding-gate 缺少结构化 grounding_audit")
|
|
312
|
+
if review_mode == "grounding-gate" and result.get("source_audit") != "not_applicable":
|
|
313
|
+
errors.append(f"案例 {case_id} 的 grounding-gate source_audit 必须为 not_applicable")
|
|
314
|
+
if review_mode == "grounding-gate" and result.get("materiality_audit") != "not_applicable":
|
|
315
|
+
errors.append(f"案例 {case_id} 的 grounding-gate materiality_audit 必须为 not_applicable")
|
|
316
|
+
if (
|
|
317
|
+
review_mode == "grounding-gate"
|
|
318
|
+
and result.get("verdict") == "pass"
|
|
319
|
+
and isinstance(result.get("grounding_audit"), dict)
|
|
320
|
+
and result["grounding_audit"].get("standard_mode")
|
|
321
|
+
== "coverage-or-applicability"
|
|
322
|
+
):
|
|
323
|
+
basis = result["grounding_audit"].get("counterexample_basis")
|
|
324
|
+
expected_basis = {
|
|
325
|
+
"standard_source_status": {"verified-text", "authorized-scope-confirmation"},
|
|
326
|
+
"anchor_set_completeness": {"confirmed"},
|
|
327
|
+
"all_explicit_anchors_satisfied": {True},
|
|
328
|
+
"coverage_gap_status": {"confirmed"},
|
|
329
|
+
"scenario_evidence_status": {"verified-case", "self-contained-fixture"},
|
|
330
|
+
}
|
|
331
|
+
if not isinstance(basis, dict):
|
|
332
|
+
errors.append(f"案例 {case_id} 的 grounding-gate pass 缺少 counterexample_basis")
|
|
333
|
+
else:
|
|
334
|
+
for key, allowed in expected_basis.items():
|
|
335
|
+
if basis.get(key) not in allowed:
|
|
336
|
+
errors.append(
|
|
337
|
+
f"案例 {case_id} 的 counterexample_basis.{key} 不满足 pass 条件"
|
|
338
|
+
)
|
|
339
|
+
for key in ("standard_source", "coverage_gap_source"):
|
|
340
|
+
if not isinstance(basis.get(key), str) or not basis.get(key).strip():
|
|
341
|
+
errors.append(f"案例 {case_id} 的 counterexample_basis.{key} 必须非空")
|
|
342
|
+
if review_mode == "source-gate":
|
|
343
|
+
materiality = result.get("materiality_audit")
|
|
344
|
+
if not isinstance(materiality, dict):
|
|
345
|
+
errors.append(f"案例 {case_id} 的 source-gate 缺少 materiality_audit")
|
|
346
|
+
else:
|
|
347
|
+
required_materiality = {
|
|
348
|
+
"overall_goal",
|
|
349
|
+
"consumer_decision",
|
|
350
|
+
"first_release_boundary",
|
|
351
|
+
"material_blocker_found",
|
|
352
|
+
"material_effect",
|
|
353
|
+
"same_failure_family_scope",
|
|
354
|
+
"deferred_non_blocking",
|
|
355
|
+
"late_round_blocking_justification",
|
|
356
|
+
}
|
|
357
|
+
missing_materiality = required_materiality - set(materiality)
|
|
358
|
+
if missing_materiality:
|
|
359
|
+
errors.append(
|
|
360
|
+
f"案例 {case_id} 的 materiality_audit 缺少字段:{sorted(missing_materiality)}"
|
|
361
|
+
)
|
|
362
|
+
if result.get("verdict") == "pass" and materiality.get("material_blocker_found") is not False:
|
|
363
|
+
errors.append(f"案例 {case_id} 的 source-gate pass 仍声明 material blocker")
|
|
364
|
+
if result.get("verdict") != "pass" and materiality.get("material_blocker_found") is not True:
|
|
365
|
+
errors.append(f"案例 {case_id} 的 source-gate 非 pass 未声明 material blocker")
|
|
366
|
+
if result.get("verdict") != "pass" and not materiality.get("same_failure_family_scope"):
|
|
367
|
+
errors.append(f"案例 {case_id} 的 source-gate 非 pass 缺少同类横向扫描范围")
|
|
368
|
+
late_round_justification = materiality.get("late_round_blocking_justification")
|
|
369
|
+
allowed_late_round_justifications = {
|
|
370
|
+
"not_applicable",
|
|
371
|
+
"new-independent-failure-class",
|
|
372
|
+
"material-same-family-missed-instance",
|
|
373
|
+
"patch-introduced-failure",
|
|
374
|
+
"previously-unobservable-failure",
|
|
375
|
+
}
|
|
376
|
+
if late_round_justification not in allowed_late_round_justifications:
|
|
377
|
+
errors.append(
|
|
378
|
+
f"案例 {case_id} 的 late_round_blocking_justification 不在允许枚举中"
|
|
379
|
+
)
|
|
380
|
+
if result.get("verdict") == "pass" and late_round_justification != "not_applicable":
|
|
381
|
+
errors.append(
|
|
382
|
+
f"案例 {case_id} 的 source-gate pass 必须使用 not_applicable"
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
if review_mode == "source-gate" and result.get("verdict") == "pass":
|
|
386
|
+
snapshot_id = result.get("reviewed_snapshot_id", "")
|
|
387
|
+
if not snapshot_id.startswith("sha256:"):
|
|
388
|
+
errors.append(f"案例 {case_id} 的 source-gate pass 未绑定冻结快照")
|
|
389
|
+
audit = result.get("source_audit")
|
|
390
|
+
if not isinstance(audit, dict):
|
|
391
|
+
errors.append(f"案例 {case_id} 的 source-gate pass 缺少 source_audit")
|
|
392
|
+
else:
|
|
393
|
+
expected_source_audit = {
|
|
394
|
+
"normal_case_replay": "pass",
|
|
395
|
+
"highest_risk_case_replay": "pass",
|
|
396
|
+
"finding_classification_consistent": True,
|
|
397
|
+
"unsupported_scope_expansion_found": False,
|
|
398
|
+
"skill_dependency_closure": "pass",
|
|
399
|
+
}
|
|
400
|
+
for key, expected in expected_source_audit.items():
|
|
401
|
+
if audit.get(key) != expected:
|
|
402
|
+
errors.append(
|
|
403
|
+
f"案例 {case_id} 的 source_audit.{key} 不满足 pass 条件"
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
duplicates = sorted({case_id for case_id in ids if ids.count(case_id) > 1})
|
|
407
|
+
if duplicates:
|
|
408
|
+
errors.append(f"案例 id 重复:{duplicates}")
|
|
409
|
+
|
|
410
|
+
if len(cases) != len(REQUIRED_CATEGORIES):
|
|
411
|
+
errors.append(f"案例数量应为 {len(REQUIRED_CATEGORIES)},实际为 {len(cases)}")
|
|
412
|
+
|
|
413
|
+
missing_categories = REQUIRED_CATEGORIES - categories
|
|
414
|
+
extra_categories = categories - REQUIRED_CATEGORIES
|
|
415
|
+
if missing_categories:
|
|
416
|
+
errors.append(f"核心行为类别缺失:{sorted(missing_categories)}")
|
|
417
|
+
if extra_categories:
|
|
418
|
+
errors.append(f"存在未裁决类别:{sorted(extra_categories)}")
|
|
419
|
+
|
|
420
|
+
return report(errors)
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def report(errors: list[str]) -> int:
|
|
424
|
+
if errors:
|
|
425
|
+
print(f"FAIL:{len(errors)} 个源码结构问题")
|
|
426
|
+
for error in errors:
|
|
427
|
+
print(f"- {error}")
|
|
428
|
+
return 1
|
|
429
|
+
count = len(json.loads(read("evaluation/cases.json"))["cases"])
|
|
430
|
+
print(f"PASS:文件、版本、四个 Skill 入口和 {count} 个高信号案例结构有效")
|
|
431
|
+
print("说明:该结果不评价 Agent 行为,不构成 L1,也不是模型上限测试。")
|
|
432
|
+
return 0
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
if __name__ == "__main__":
|
|
436
|
+
sys.exit(main())
|
|
437
|
+
|