配置: 冻结正文 Gate A 成功运行时探针
This commit is contained in:
parent
0c7427360b
commit
f1e1de581a
@ -48,8 +48,8 @@
|
||||
"writerInputProvenance": "preregistered_fine_outline",
|
||||
"oracleInputProvenance": "oracle_reference_scaffold",
|
||||
"maxContextChars": 140000,
|
||||
"modelVersion": "pending_probe",
|
||||
"adapterVersion": "pending_probe",
|
||||
"modelVersion": "claude-opus-4-8[1m]",
|
||||
"adapterVersion": "writer-runtime-v1|claude-cli-2.1.211|binary-sha256-5a728a76198b6eca7f3c7cdbff43bab44b77b48c2108f7a3107d889773382629",
|
||||
"sampling": {
|
||||
"temperature": "unsupported",
|
||||
"topP": "unsupported",
|
||||
@ -58,6 +58,41 @@
|
||||
},
|
||||
"detectorProfile": "writer-detector-report-v1"
|
||||
},
|
||||
"executionAuthorization": {
|
||||
"runtimeProbe": {
|
||||
"status": "successful",
|
||||
"checkedAt": "2026-07-22T22:09:32+08:00",
|
||||
"claudeExecutablePath": "/Users/qingse/.nvm/versions/node/v24.15.0/bin/claude",
|
||||
"claudeExecutableSha256": "5a728a76198b6eca7f3c7cdbff43bab44b77b48c2108f7a3107d889773382629",
|
||||
"claudeCliVersion": "2.1.211",
|
||||
"modelAlias": "opus",
|
||||
"resolvedModelId": "claude-opus-4-8[1m]",
|
||||
"executionProfileSha256": "sha256:9812b32c14c6a95204a22555c34b84353a96d4df5e5988a00df23634022e34ca",
|
||||
"executionReceiptSha256": "sha256:5e1171201771cd921c187b3bdc9d192f3bb0abbba4115a4489150721c4d72477",
|
||||
"structuredOutputSha256": "sha256:4062edaf750fb8074e7e83e0c9028c94e32468a8b6f1614774328ef045150f93",
|
||||
"terminalReason": "completed",
|
||||
"totalCostUsd": "0.003885",
|
||||
"modelMatch": true,
|
||||
"exitCode": 0,
|
||||
"apiErrorStatus": null,
|
||||
"receiptSha256": "sha256:63de7cea7b33dd328bc526bb76175d53a3a03179f2d901badf7547cd42cf4c70"
|
||||
},
|
||||
"budget": {
|
||||
"status": "pending",
|
||||
"reason": "Gate A 的 writer、semantic_detector、blind_judge 机械最低调用次数已登记,但本次单次执行预算尚未获得明确批准;不得创建模型 runner。",
|
||||
"maxCalls": {
|
||||
"writer": 15,
|
||||
"semantic_detector": 15,
|
||||
"blind_judge": 15
|
||||
},
|
||||
"receiptSha256": "sha256:aeb40e282c1031f40e007504edf32e783266a02cce74b3c1d32ec94d2e266be4"
|
||||
},
|
||||
"rawRetention": {
|
||||
"status": "pending",
|
||||
"reason": "本次执行的原始 prompt/response 与 token 留存尚未获得明确批准;不得创建 raw vault。",
|
||||
"receiptSha256": "sha256:9d912dcafdc2988708d4a2dd21a216382a51eccb8354c5d9f252de2f96d77d45"
|
||||
}
|
||||
},
|
||||
"armPolicies": {
|
||||
"A": {
|
||||
"evidenceStrategy": "generic_prose_retrieval",
|
||||
|
||||
@ -60,6 +60,7 @@ CANONICAL_CHAPTER_STATUSES = frozenset({"published", "confirmed", "canonical"})
|
||||
EXPECTED_WRITER_INPUT_PROVENANCE = "preregistered_fine_outline"
|
||||
EXPECTED_ORACLE_INPUT_PROVENANCE = "oracle_reference_scaffold"
|
||||
PREREGISTERED_MAX_CONTEXT_CHARS = 140_000
|
||||
RUNTIME_ADAPTER_VERSION_PREFIX = "writer-runtime-v1"
|
||||
|
||||
|
||||
class WriterReferenceWorkError(AdapterError):
|
||||
@ -78,6 +79,29 @@ def _sha256_value(value: Any) -> str:
|
||||
return "sha256:" + hashlib.sha256(_safe_json(value).encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def _is_full_sha256(value: Any) -> bool:
|
||||
"""只接受不带前缀的 64 位小写 SHA-256。"""
|
||||
|
||||
return isinstance(value, str) and len(value) == 64 and all(
|
||||
char in "0123456789abcdef" for char in value
|
||||
)
|
||||
|
||||
|
||||
def _validate_self_hash(value: Mapping[str, Any], field: str) -> None:
|
||||
"""校验对象的 receiptSha256 是否等于其规范 JSON 自哈希。"""
|
||||
|
||||
receipt = value.get("receiptSha256")
|
||||
if not isinstance(receipt, str) or not receipt.startswith("sha256:") or not _is_full_sha256(
|
||||
receipt.removeprefix("sha256:")
|
||||
):
|
||||
raise WriterReferenceWorkError(f"{field}.receiptSha256 必须是 canonical SHA-256")
|
||||
expected = _sha256_value(
|
||||
{key: item for key, item in value.items() if key != "receiptSha256"}
|
||||
)
|
||||
if receipt != expected:
|
||||
raise WriterReferenceWorkError(f"{field}.receiptSha256 canonical 自哈希无效")
|
||||
|
||||
|
||||
def _positive_chapter(value: Any, field: str) -> int:
|
||||
"""严格接受正整数章号,不把 bool、浮点或模糊文本猜成章号。"""
|
||||
|
||||
@ -163,8 +187,49 @@ def _validate_loader_controls(
|
||||
samples = base_config.get("samples")
|
||||
if not isinstance(samples, list) or not samples:
|
||||
raise WriterReferenceWorkError("基础配置 samples 不能为空")
|
||||
if common.get("modelVersion") != "pending_probe" or common.get("adapterVersion") != "pending_probe":
|
||||
raise WriterReferenceWorkError("modelVersion/adapterVersion 必须保持 pending_probe")
|
||||
execution_authorization = base_config.get("executionAuthorization")
|
||||
if not isinstance(execution_authorization, Mapping):
|
||||
raise WriterReferenceWorkError("基础配置缺少 executionAuthorization")
|
||||
runtime_probe = execution_authorization.get("runtimeProbe")
|
||||
if not isinstance(runtime_probe, Mapping):
|
||||
raise WriterReferenceWorkError("executionAuthorization.runtimeProbe 必须是对象")
|
||||
if runtime_probe.get("status") != "successful":
|
||||
raise WriterReferenceWorkError("executionAuthorization.runtimeProbe 必须为 successful")
|
||||
_validate_self_hash(runtime_probe, "executionAuthorization.runtimeProbe")
|
||||
cli_version = runtime_probe.get("claudeCliVersion")
|
||||
executable_sha256 = runtime_probe.get("claudeExecutableSha256")
|
||||
if not isinstance(cli_version, str) or not cli_version.strip():
|
||||
raise WriterReferenceWorkError("runtimeProbe.claudeCliVersion 不能为空")
|
||||
if not _is_full_sha256(executable_sha256):
|
||||
raise WriterReferenceWorkError(
|
||||
"runtimeProbe.claudeExecutableSha256 必须是完整 64 位小写 SHA-256"
|
||||
)
|
||||
resolved_model_id = runtime_probe.get("resolvedModelId")
|
||||
if not isinstance(resolved_model_id, str) or not resolved_model_id.strip():
|
||||
raise WriterReferenceWorkError("runtimeProbe.resolvedModelId 不能为空")
|
||||
if common.get("modelVersion") != resolved_model_id:
|
||||
raise WriterReferenceWorkError(
|
||||
"commonControls.modelVersion 必须精确等于 runtimeProbe.resolvedModelId"
|
||||
)
|
||||
expected_adapter_version = (
|
||||
f"{RUNTIME_ADAPTER_VERSION_PREFIX}|claude-cli-{cli_version}|"
|
||||
f"binary-sha256-{executable_sha256}"
|
||||
)
|
||||
if common.get("adapterVersion") != expected_adapter_version:
|
||||
raise WriterReferenceWorkError(
|
||||
"commonControls.adapterVersion 未绑定 runtimeProbe 的 CLI version 与 executable hash"
|
||||
)
|
||||
for control_name in ("budget", "rawRetention"):
|
||||
control = execution_authorization.get(control_name)
|
||||
if not isinstance(control, Mapping):
|
||||
raise WriterReferenceWorkError(
|
||||
f"executionAuthorization.{control_name} 必须是对象"
|
||||
)
|
||||
if control.get("status") != "pending":
|
||||
raise WriterReferenceWorkError(
|
||||
f"executionAuthorization.{control_name} 必须保持 pending"
|
||||
)
|
||||
_validate_self_hash(control, f"executionAuthorization.{control_name}")
|
||||
if common.get("sampling") != {
|
||||
"temperature": "unsupported",
|
||||
"topP": "unsupported",
|
||||
|
||||
@ -18,6 +18,7 @@ sys.path.insert(0, str(SCRIPT_DIR))
|
||||
sys.path.insert(0, str(READ_CONTEXT_SCRIPTS))
|
||||
|
||||
import load_writer_reference_work as loader # noqa: E402
|
||||
import run_writer_replay as replay_module # noqa: E402
|
||||
from load_writer_reference_work import ( # noqa: E402
|
||||
WriterReferenceWorkError,
|
||||
assemble_writer_gate_config,
|
||||
@ -38,6 +39,17 @@ SELECTOR_DIGEST = loader.selector_sha256(SELECTOR_PATH.read_bytes())
|
||||
FILE_HASH = "02cf1f8c1ca03c26e0b839d88fe536e83c0af20fd8972235b7aedca6a33becf4"
|
||||
SOURCE_HASH = f"sha256:{FILE_HASH}"
|
||||
SOURCE_VERSION = f"raw-file-v1:{SOURCE_HASH}"
|
||||
EXPECTED_CLAUDE_EXECUTABLE_SHA256 = (
|
||||
"5a728a76198b6eca7f3c7cdbff43bab44b77b48c2108f7a3107d889773382629"
|
||||
)
|
||||
|
||||
|
||||
def _refresh_self_hash(value: dict[str, object]) -> None:
|
||||
"""按 loader 使用的规范 JSON 算法刷新测试夹具自哈希。"""
|
||||
|
||||
value["receiptSha256"] = loader._sha256_value(
|
||||
{key: item for key, item in value.items() if key != "receiptSha256"}
|
||||
)
|
||||
|
||||
|
||||
def _card_row(
|
||||
@ -357,8 +369,34 @@ class LoadWriterReferenceWorkTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(self.base_config["commonControls"]["selectorSha256"], SELECTOR_DIGEST)
|
||||
self.assertEqual(self.base_config["strategyVersion"], "writer-abc-single-variable-v2")
|
||||
self.assertEqual(self.base_config["commonControls"]["modelVersion"], "pending_probe")
|
||||
self.assertEqual(self.base_config["commonControls"]["adapterVersion"], "pending_probe")
|
||||
probe = self.base_config["executionAuthorization"]["runtimeProbe"]
|
||||
self.assertEqual(probe["status"], "successful")
|
||||
self.assertEqual(
|
||||
self.base_config["commonControls"]["modelVersion"], probe["resolvedModelId"]
|
||||
)
|
||||
self.assertEqual(len(probe["claudeExecutableSha256"]), 64)
|
||||
self.assertEqual(
|
||||
probe["claudeExecutableSha256"], EXPECTED_CLAUDE_EXECUTABLE_SHA256
|
||||
)
|
||||
self.assertEqual(
|
||||
self.base_config["commonControls"]["adapterVersion"],
|
||||
"writer-runtime-v1|claude-cli-"
|
||||
+ probe["claudeCliVersion"]
|
||||
+ "|binary-sha256-"
|
||||
+ probe["claudeExecutableSha256"],
|
||||
)
|
||||
for control_name in ("runtimeProbe", "budget", "rawRetention"):
|
||||
control = self.base_config["executionAuthorization"][control_name]
|
||||
self.assertEqual(
|
||||
control["receiptSha256"],
|
||||
loader._sha256_value(
|
||||
{key: item for key, item in control.items() if key != "receiptSha256"}
|
||||
),
|
||||
)
|
||||
self.assertEqual(self.base_config["executionAuthorization"]["budget"]["status"], "pending")
|
||||
self.assertEqual(
|
||||
self.base_config["executionAuthorization"]["rawRetention"]["status"], "pending"
|
||||
)
|
||||
self.assertEqual(
|
||||
self.base_config["commonControls"]["sampling"],
|
||||
{
|
||||
@ -417,6 +455,100 @@ class LoadWriterReferenceWorkTest(unittest.TestCase):
|
||||
rows=_assembly_rows(self.base_config),
|
||||
)
|
||||
|
||||
def test_runtime_probe_status_tamper_fails_closed(self):
|
||||
"""runtime probe 不是成功状态时必须在 loader 控制门阻断。"""
|
||||
|
||||
tampered = copy.deepcopy(self.base_config)
|
||||
tampered["executionAuthorization"]["runtimeProbe"]["status"] = "failed"
|
||||
with self.assertRaisesRegex(WriterReferenceWorkError, "runtimeProbe.*successful"):
|
||||
loader._validate_loader_controls(
|
||||
tampered,
|
||||
self.selectors,
|
||||
selector_digest=SELECTOR_DIGEST,
|
||||
)
|
||||
|
||||
def test_runtime_probe_self_hash_tamper_fails_closed(self):
|
||||
"""runtime probe receipt 的 canonical 自哈希被篡改时必须失败关闭。"""
|
||||
|
||||
tampered = copy.deepcopy(self.base_config)
|
||||
tampered["executionAuthorization"]["runtimeProbe"]["receiptSha256"] = (
|
||||
"sha256:" + "0" * 64
|
||||
)
|
||||
with self.assertRaisesRegex(WriterReferenceWorkError, "runtimeProbe.*自哈希"):
|
||||
loader._validate_loader_controls(
|
||||
tampered,
|
||||
self.selectors,
|
||||
selector_digest=SELECTOR_DIGEST,
|
||||
)
|
||||
|
||||
def test_model_version_tamper_fails_closed(self):
|
||||
"""公共 modelVersion 必须精确绑定 probe 解析出的模型 ID。"""
|
||||
|
||||
tampered = copy.deepcopy(self.base_config)
|
||||
tampered["commonControls"]["modelVersion"] = "claude-opus-tampered"
|
||||
with self.assertRaisesRegex(WriterReferenceWorkError, "modelVersion.*resolvedModelId"):
|
||||
loader._validate_loader_controls(
|
||||
tampered,
|
||||
self.selectors,
|
||||
selector_digest=SELECTOR_DIGEST,
|
||||
)
|
||||
|
||||
def test_adapter_version_tamper_fails_closed(self):
|
||||
"""公共 adapterVersion 必须同时绑定 probe CLI 版本和完整 executable hash。"""
|
||||
|
||||
tampered = copy.deepcopy(self.base_config)
|
||||
tampered["commonControls"]["adapterVersion"] = "writer-runtime-v1|tampered"
|
||||
with self.assertRaisesRegex(WriterReferenceWorkError, "adapterVersion"):
|
||||
loader._validate_loader_controls(
|
||||
tampered,
|
||||
self.selectors,
|
||||
selector_digest=SELECTOR_DIGEST,
|
||||
)
|
||||
|
||||
def test_executable_hash_must_remain_full_and_bound(self):
|
||||
"""probe executable hash 截断后即使重签 receipt 也不能通过。"""
|
||||
|
||||
tampered = copy.deepcopy(self.base_config)
|
||||
probe = tampered["executionAuthorization"]["runtimeProbe"]
|
||||
probe["claudeExecutableSha256"] = EXPECTED_CLAUDE_EXECUTABLE_SHA256[:-1]
|
||||
_refresh_self_hash(probe)
|
||||
with self.assertRaisesRegex(WriterReferenceWorkError, "64 位"):
|
||||
loader._validate_loader_controls(
|
||||
tampered,
|
||||
self.selectors,
|
||||
selector_digest=SELECTOR_DIGEST,
|
||||
)
|
||||
|
||||
def test_assembly_preserves_pending_execution_authorization_and_blocks_before_side_effects(self):
|
||||
"""装配不得补批准;真实 execute 应因 pending budget 阻断且不创建 vault/runner。"""
|
||||
|
||||
expected_authorization = copy.deepcopy(self.base_config["executionAuthorization"])
|
||||
config = assemble_writer_gate_config(
|
||||
base_config=self.base_config,
|
||||
selector_config=self.selectors,
|
||||
selector_digest=SELECTOR_DIGEST,
|
||||
rows=_assembly_rows(self.base_config),
|
||||
)
|
||||
self.assertEqual(config["executionAuthorization"], expected_authorization)
|
||||
self.assertEqual(config["executionAuthorization"]["budget"]["status"], "pending")
|
||||
self.assertEqual(config["executionAuthorization"]["rawRetention"]["status"], "pending")
|
||||
with tempfile.TemporaryDirectory(dir="/private/tmp") as directory:
|
||||
output_dir = pathlib.Path(directory) / "run"
|
||||
with patch.object(replay_module, "RawVaultManager") as vault_manager, patch.object(
|
||||
replay_module.subprocess, "run"
|
||||
) as runner:
|
||||
result = run_writer_replay(
|
||||
config,
|
||||
run_id="loader-pending-budget",
|
||||
output_dir=output_dir,
|
||||
execute=True,
|
||||
)
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(result["status"], "blocked_budget_authorization")
|
||||
self.assertEqual(result["errors"], ["BUDGET_AUTHORIZATION_REQUIRED"])
|
||||
vault_manager.assert_not_called()
|
||||
runner.assert_not_called()
|
||||
|
||||
def test_milestone_ranges_expand_and_keep_latest_three_unique_chapters(self):
|
||||
"""明确区间按绝对章展开,重复章去重后只保留最近三章。"""
|
||||
|
||||
|
||||
@ -1069,7 +1069,52 @@ class WriterReplayDryRunTest(unittest.TestCase):
|
||||
|
||||
result = run_writer_replay(gate_config, run_id="gate-a-preregistered-dry-run")
|
||||
self.assertTrue(result["ok"])
|
||||
self.assertEqual(result["status"], "ready")
|
||||
self.assertEqual(len(result["samples"]), 5)
|
||||
self.assertEqual(gate_config["commonControls"]["modelVersion"], "claude-opus-4-8[1m]")
|
||||
self.assertIn("writer-runtime-v1", gate_config["commonControls"]["adapterVersion"])
|
||||
self.assertIn("2.1.211", gate_config["commonControls"]["adapterVersion"])
|
||||
executable_sha256 = gate_config["executionAuthorization"]["runtimeProbe"][
|
||||
"claudeExecutableSha256"
|
||||
]
|
||||
self.assertEqual(len(executable_sha256), 64)
|
||||
self.assertEqual(
|
||||
executable_sha256,
|
||||
"5a728a76198b6eca7f3c7cdbff43bab44b77b48c2108f7a3107d889773382629",
|
||||
)
|
||||
self.assertIn(executable_sha256, gate_config["commonControls"]["adapterVersion"])
|
||||
self.assertNotIn("executionProfiles", gate_config)
|
||||
self.assertNotIn("profileSha256", gate_config["executionAuthorization"])
|
||||
|
||||
def test_gate_a_execute_blocks_pending_budget_before_vault_or_runner(self):
|
||||
"""正式 Gate A 已完成 runtime probe,但预算未批准时必须在副作用前阻断。"""
|
||||
|
||||
gate_config_path = SCRIPT_DIR.parent / "configs" / "writer-gate-a-deep-space-v1.json"
|
||||
gate_config = json.loads(gate_config_path.read_text(encoding="utf-8"))
|
||||
vault_calls: list[pathlib.Path] = []
|
||||
|
||||
def vault_factory(path):
|
||||
vault_calls.append(path)
|
||||
return RawVaultManager(path)
|
||||
|
||||
adapters, writer, semantic, judge = _production_adapters(vault_factory=vault_factory)
|
||||
with tempfile.TemporaryDirectory(dir="/private/tmp") as directory:
|
||||
output = pathlib.Path(directory) / "run"
|
||||
result = run_writer_replay(
|
||||
gate_config,
|
||||
run_id="gate-a-pending-budget",
|
||||
output_dir=output,
|
||||
execute=True,
|
||||
production_adapters=adapters,
|
||||
)
|
||||
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(result["status"], "blocked_budget_authorization")
|
||||
self.assertEqual(result["errors"], ["BUDGET_AUTHORIZATION_REQUIRED"])
|
||||
self.assertEqual(vault_calls, [])
|
||||
self.assertEqual(writer.calls, [])
|
||||
self.assertEqual(semantic.calls, [])
|
||||
self.assertEqual(judge.calls, [])
|
||||
|
||||
|
||||
class WriterReplayExecuteBoundaryTest(unittest.TestCase):
|
||||
@ -1540,6 +1585,28 @@ class WriterReplayProductionIntegrationTest(unittest.TestCase):
|
||||
self.assertEqual(writer.calls, [])
|
||||
self.assertNotIn("binding_verifier", inspect.signature(run_writer_replay).parameters)
|
||||
|
||||
def test_runtime_probe_self_hash_tamper_fails_closed_before_runner(self):
|
||||
"""runtime probe receipt 自哈希被篡改时,不能进入任何模型 runner。"""
|
||||
|
||||
adapters, writer, semantic, judge = _production_adapters()
|
||||
tampered = _production_config()
|
||||
tampered["executionAuthorization"]["runtimeProbe"]["receiptSha256"] = (
|
||||
"sha256:" + "0" * 64
|
||||
)
|
||||
|
||||
result, _output = self._run(
|
||||
adapters,
|
||||
evaluation_config=tampered,
|
||||
run_id="tampered-runtime-probe",
|
||||
)
|
||||
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(result["status"], "blocked_execute_authorization")
|
||||
self.assertEqual(result["errors"], ["EXECUTE_AUTHORIZATION_HASH_INVALID"])
|
||||
self.assertEqual(writer.calls, [])
|
||||
self.assertEqual(semantic.calls, [])
|
||||
self.assertEqual(judge.calls, [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@ -354,11 +354,11 @@ dry-run 命令:
|
||||
|
||||
dry-run 只生成计划、manifest 和上下文摘要,不调用模型。测试注入路径用于机械验证 writer、detector 与盲评编排,但与真实执行共用 probe、预算、raw 保留和 profile 授权门;候选只进入受租约约束的 RawVault,普通输出目录不落 raw。judge 只接收独立盲化内容和共同评测参考,不能取得 raw 目录、真实臂映射或任一臂专属证据;评委顺序变化不得改变共同参考。即使全部离线测试通过,也不得据此声称真实回放或 Gate A 已完成。
|
||||
|
||||
截至 2026-07-22,本版第一阶段实现已接通:A/C 原文检索与 allowlist diff、B 负对照、全评测集平衡表、oracleTruthPack、writer 联合回执、真实 semantic detector、隔离 blind judge、GateInputBuilder、confounders、RawVault、文件 CAS、Gate B receipt 签发器和细纲 real-run 入口守卫。执行 profile 绑定绝对 Claude CLI 路径/hash/版本、完整模型 ID、单次预算、schema 和系统提示词;系统失败优先于样本不足。提交前机械证据为 replay-eval 180 项、writer 8 项、上下文装配 14 项、detector 12 项、judge 13 项全部通过,Gate A dry-run 5 个样本均为 ready;独立对抗复审覆盖空内层回执、judge 合法改分后重签、测试 adapter 绕授权、错误 CLI 绑定、detector 泄漏和 CAS 非破坏恢复。该证据只证明离线编排合同实现,不等于成功探测、预算批准、真实 Gate A 或生成质量通过。
|
||||
截至 2026-07-22,本版第一阶段实现已接通:A/C 原文检索与 allowlist diff、B 负对照、全评测集平衡表、oracleTruthPack、writer 联合回执、真实 semantic detector、隔离 blind judge、GateInputBuilder、confounders、RawVault、文件 CAS、Gate B receipt 签发器和细纲 real-run 入口守卫。执行 profile 绑定绝对 Claude CLI 路径/hash/版本、完整模型 ID、单次预算、schema 和系统提示词;系统失败优先于样本不足。当前机械证据为 replay-eval 199 项全部通过,Gate A dry-run 5 个样本均为 ready;独立对抗复审覆盖空内层回执、judge 合法改分后重签、测试 adapter 绕授权、错误 CLI 绑定、detector 泄漏和 CAS 非破坏恢复。该证据只证明离线编排合同实现,不等于预算批准、真实 Gate A 或生成质量通过。
|
||||
|
||||
真实 CLI 极小探测还有直接证据:两次 Opus 探测分别等待 177043ms 与 185505ms 后因 API 503 失败,进程 `exit=1`;JSON envelope 却同时出现 `type=result`、`subtype=success`、`is_error=true`、`api_error_status=503`、`terminal_reason=api_error`、`stop_reason=stop_sequence`、`total_cost_usd=0`、完整零值 `usage` 和空 `modelUsage={}`。因此 `subtype=success`、合法 JSON、完整 usage 或 `stop_reason=stop_sequence` 都不能单独证明调用成功;该证据也说明每次调用必须有编排器硬 deadline。安全摘要只记录状态码和受控字段,不记录具体网关错误正文。
|
||||
|
||||
该失败探测没有产生可验证的成功 `structured_output` 或完整 model ID,只能证明失败 envelope 语义。必须先完成第 11.4 节成功探测,才能冻结离线评测 adapter 所需字段;在此之前 `--execute` 继续失败关闭。
|
||||
随后完成了第 11.4 节正式成功探测:绝对 CLI 路径绑定版本 `2.1.211` 与二进制 SHA-256,实际完整模型 ID 为 `claude-opus-4-8[1m]`;进程 `exit=0`、`is_error=false`、`terminal_reason=completed`、`modelMatch=true`,严格 schema 产出 `structured_output`,单次成本 `$0.003885`。其 `structuredOutputSha256=sha256:4062edaf750fb8074e7e83e0c9028c94e32468a8b6f1614774328ef045150f93`、`executionProfileSha256=sha256:9812b32c14c6a95204a22555c34b84353a96d4df5e5988a00df23634022e34ca`、`executionReceiptSha256=sha256:5e1171201771cd921c187b3bdc9d192f3bb0abbba4115a4489150721c4d72477` 已冻结进预注册配置。探测同时暴露并修复了三处真实运行合同缺口:完整模型 ID 的能力后缀、自定义网关安全认证字段、Claude usage 中非数值元数据;对应回归测试已纳入机械门禁。
|
||||
|
||||
`writer_gate.py` 已按 10.1 改为系统失败优先;detector 指标只接受严格校验并绑定模型回执的真实语义报告,禁止常量、默认通过或测试替身进入 real-run。第三评委报告非法或仍不稳定时,样本和顶层都失败;GateInputBuilder 还会把 reviewer 原始 structured output 与内层 ExecutionReceipt 绑定后重算 panel,报告内容即使重签自身 hash 也不能替换模型原始结论。
|
||||
|
||||
@ -443,7 +443,7 @@ vault 路径由可信编排器生成不可猜测 ID,拒绝调用方传入绝
|
||||
|
||||
每次调用都产生不含正文的 `ExecutionReceipt`,至少记录 `adapterRole/invocationId/requestedModelId/actualModelId/modelMatch/effort/maxBudgetUsdPerCall/totalCostUsd/usage/modelUsage/stopReason/terminalReason/isError/apiErrorStatus/exitCode/durationMs/inputSha256/structuredOutputSha256/jsonSchemaSha256`。CLI 结果未提供完整实际 model ID、`total_cost_usd`、usage、modelUsage、stop reason 或 terminal reason,或任一字段无法归一化时,回执非法,不能把该调用算作成功。
|
||||
|
||||
`envelope.structured_output` 是唯一业务对象,必须直接通过该角色的严格 JSON schema;`envelope.result` 只作审计和受控错误分类,禁止解析为业务 JSON,也禁止作为 structured_output 缺失时的 fallback。当前 503 探测没有证明 2.1.211 成功响应的 `structured_output` 字段形状;实现前必须完成一次极小成功探测并冻结 envelope schema/hash。该探测未成功前 Gate A 不得启动。
|
||||
`envelope.structured_output` 是唯一业务对象,必须直接通过该角色的严格 JSON schema;`envelope.result` 只作审计和受控错误分类,禁止解析为业务 JSON,也禁止作为 structured_output 缺失时的 fallback。版本 2.1.211 的成功探测已经证明并冻结 `structured_output`、完整模型 ID、usage/modelUsage 与终止字段的形状和回执 hash;任何后续运行与该探针绑定不一致仍须失败关闭。
|
||||
|
||||
调用成功必须联合满足:进程 `exitCode=0`;envelope `type=result` 且 `is_error=false`;`terminal_reason` 属于该角色预注册的正常终止集合;业务输出通过严格 schema;`modelUsage` 能证明实际模型且与请求模型一致;`usage` 结构和数值合法并可核账。`subtype=success` 与 `stop_reason` 只作审计字段,不能覆盖非零退出、`is_error=true`、API error、空 `modelUsage` 或 schema 失败。
|
||||
|
||||
@ -475,7 +475,7 @@ vault 路径由可信编排器生成不可猜测 ID,拒绝调用方传入绝
|
||||
|
||||
Gate A real-run 只允许使用满足本节合同的离线评测 adapter。执行前必须机械证明:成功 structured_output 探测已冻结;Gate A 总预算与单次预算已确认;A/C 执行配置、事实约束和原文字符预算相等;全评测集顺序表平衡;完整上下文 allowlist diff 通过;temperature/topP/seed 为 `unsupported/not_claimed`;三类 schema、oracleTruthPack、GateInputBuilder、泄漏审计与回执测试通过;judge 隔离无法发现 raw、映射和臂名;raw lease、vault 权限/逃逸/保留/清理测试通过;文件 CAS journal 的并发、崩溃和迟到结果测试通过。Gate B 启动前另行预注册并批准独立预算,不得沿用 Gate A 批准。
|
||||
|
||||
本次设计先定义合同,当前 adapter 已按合同实现并通过离线机械测试,但这仍不等于 Gate A 已运行或通过。成功 `structured_output` 探测和完整模型 ID 尚未取得,Gate A 总预算与 raw 保留期也尚未批准,因此仓内配置保持 `pending_probe`,真实 `--execute` 机械返回 `blocked_runtime_probe`,且在阻断前不创建 raw 目录、不调用模型。
|
||||
本次设计先定义合同,当前 adapter 已按合同实现并通过离线机械测试,成功 `structured_output` 探测和完整模型 ID 也已冻结,但这仍不等于 Gate A 已运行或通过。Gate A 总预算与 raw 保留期尚未批准,因此仓内 `executionAuthorization.budget/rawRetention` 保持 `pending`;真实 `--execute` 必须在创建 runner、raw 目录或调用模型前失败关闭。
|
||||
|
||||
## 12. 用户闭环与下游交接(Gate B 后第二阶段)
|
||||
|
||||
@ -507,7 +507,7 @@ Gate A real-run 只允许使用满足本节合同的离线评测 adapter。执
|
||||
|
||||
- 本修订版通过产品流程与技术合同两类独立评审。
|
||||
- 用户确认本文为正文智能体实验台任务 SoT。
|
||||
- 第 11 节离线评测 adapter 已实现并通过离线机械测试;成功探测、预算或 raw 授权任一缺失时,真实 `--execute` 仍保持失败关闭。设计评审与测试通过都不代表 Gate A 完成。
|
||||
- 第 11 节离线评测 adapter 已实现并通过离线机械测试,成功探测已冻结;预算或 raw 授权任一缺失时,真实 `--execute` 仍保持失败关闭。设计评审、测试与探针通过都不代表 Gate A 完成。
|
||||
- Gate A real-run 前,用户明确批准总预算、三类单次预算、最大调用次数和 raw 最长保留期。
|
||||
- Gate B real-run 前,按其样本集另行批准独立总预算、三类单次预算、最大调用次数和最坏总额。
|
||||
- writer、semantic detector、blind judge、oracleTruthPack、GateInputBuilder、Gate B receipt 签发器与细纲入口守卫的严格 schema、隔离、回执、路径安全、文件 CAS 和失败码均有机械测试证据。
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user