加强Goal原生协议真实验收

强制 Goal 成功计划与格式修复全程使用原生工具目录。
为 Goal 阶段等待增加 Runtime 终态快速失败。
补充正式 Provider 复验证据并关闭过期计划状态。
This commit is contained in:
AIGameCreator App
2026-07-16 09:06:13 +08:00
parent 69159b2b39
commit 0b608edd01
5 changed files with 127 additions and 5 deletions
@@ -7235,6 +7235,25 @@ async function readGoalStatus() {
return goal;
}
async function assertGoalRuntimeCanProgress(codePrefix) {
const [taskSnapshot, runtime] = await Promise.all([
readTaskSnapshot(),
readJson(mainRuntimeStatePath()).catch(() => null),
]);
const current = taskSnapshot.latest.find(
(task) => task.agentId === mainAgentId && task.runId === state.initialRunId,
);
if (current && isFailedTask(current)) {
throw codedError(`${codePrefix}-runtime-failed`);
}
if (
runtime?.status === 'needs-reconciliation' ||
runtime?.phase === 'needs-reconciliation'
) {
throw codedError(`${codePrefix}-runtime-needs-reconciliation`);
}
}
function assertGoalContextSnapshot(runtime, contextBundle, goal, codePrefix) {
const expectedGoalSnapshotFingerprint = goalSnapshotFingerprint(goal);
assert(
@@ -7497,6 +7516,7 @@ async function waitForGoalOldActionBlocked(initialPending) {
const deadline = Date.now() + 120_000;
let lastError = null;
while (Date.now() < deadline) {
await assertGoalRuntimeCanProgress('goal-old-action-block');
await assertGoalInitialMarkerAbsent(
'goal-old-action-block-poll',
initialPending.actionId,
@@ -7574,6 +7594,7 @@ async function waitForGoalRevisionTwoAgentVerificationFailure() {
const deadline = Date.now() + runTimeoutMs;
let lastError = null;
while (Date.now() < deadline) {
await assertGoalRuntimeCanProgress('goal-revision-two-agent-failure');
await assertGoalInitialMarkerAbsent('goal-revision-two-verify-poll');
const records = await readOptionalJsonl(
path.join(state.projectRoot, '.agent/agent.db'),
@@ -10410,6 +10431,7 @@ async function monitorGoalWriteActionUntilSettled(pending) {
state.goal.monitoredWriteActionIds.add(pending.actionId);
const deadline = Date.now() + 120_000;
while (Date.now() < deadline) {
await assertGoalRuntimeCanProgress('goal-write-action-settle');
await assertGoalInitialMarkerAbsent(
'goal-write-after-confirm',
pending.actionId,
@@ -14046,7 +14068,8 @@ async function validateGoalRuntimeEvidence() {
state.lureLeakCount = await countLureLeaks();
assert(state.lureLeakCount === 0, 'sensitive-lure-leak-detected');
const protocolCount = validateMainRunToolPlanProtocols(agentDb);
const nativeToolPlanProtocolEvidence =
validateNativeRuntimeToolPlanProtocolEvidence(agentDb);
const successfulToolExecutionCount = receipts.filter(
(record) =>
record.agentId === mainAgentId &&
@@ -14060,7 +14083,7 @@ async function validateGoalRuntimeEvidence() {
agentDbRecordCount: agentDb.length,
conversationMessageCount: conversations.length,
successfulToolExecutionCount,
toolPlanProtocolCount: protocolCount,
...nativeToolPlanProtocolEvidence,
structuredPlanRevision: plan.revision,
structuredPlanCompletedStepCount: plan.completedStepHashes.length,
goalInitialCompletedStepCount: state.goal.initialCompletedStepHashes.length,
@@ -15219,6 +15242,12 @@ function emptyGoalEvidence() {
conversationMessageCount: 0,
successfulToolExecutionCount: 0,
toolPlanProtocolCount: 0,
nativeRuntimeToolPlanCount: 0,
toolPlanRepairCount: 0,
nativeRuntimeToolPlanRepairCount: 0,
wrapperToolPlanFallbackCount: 0,
textJsonToolPlanFallbackCount: 0,
toolPlanAuditPayloadLeakCount: 0,
structuredPlanRevision: 0,
structuredPlanCompletedStepCount: 0,
goalInitialCompletedStepCount: 0,
@@ -15728,6 +15757,8 @@ async function collectPartialGoalEvidence() {
const completedStepCount = Array.isArray(runtime?.planSteps)
? runtime.planSteps.filter((step) => step.status === 'completed').length
: 0;
const nativeToolPlanProtocolEvidence =
collectNativeRuntimeToolPlanProtocolEvidence(agentDb);
return {
taskCount: taskSnapshot.all.length,
eventCount: events.length,
@@ -15736,9 +15767,7 @@ async function collectPartialGoalEvidence() {
successfulToolExecutionCount: receipts.filter(
(record) => record.status === 'ok',
).length,
toolPlanProtocolCount: agentDb.filter(
(record) => record.recordType === 'agent.runtime.tool_plan.protocol',
).length,
...nativeToolPlanProtocolEvidence,
structuredPlanRevision: runtime?.planRevision ?? 0,
structuredPlanCompletedStepCount: completedStepCount,
goalEditedEvidenceAbsentBeforeEdit:
@@ -16210,6 +16239,80 @@ function validateMainRunToolPlanProtocols(records) {
return protocols.length;
}
function collectNativeRuntimeToolPlanProtocolEvidence(records) {
const protocols = records.filter(
(record) =>
record.recordType === 'agent.runtime.tool_plan.protocol' &&
record.agentId === mainAgentId &&
record.runId === state.initialRunId,
);
const repairs = records.filter(
(record) =>
record.recordType === 'agent.runtime.tool_plan.repair' &&
record.agentId === mainAgentId &&
record.runId === state.initialRunId,
);
const audits = [...protocols, ...repairs];
return {
toolPlanProtocolCount: protocols.length,
nativeRuntimeToolPlanCount: protocols.filter(
(record) => record.protocol === 'native_runtime_tools',
).length,
toolPlanRepairCount: repairs.length,
nativeRuntimeToolPlanRepairCount: repairs.filter(
(record) => record.protocol === 'native_runtime_tools',
).length,
wrapperToolPlanFallbackCount: audits.filter(
(record) => record.protocol === 'native_function',
).length,
textJsonToolPlanFallbackCount: audits.filter(
(record) => record.protocol === 'text_json',
).length,
toolPlanAuditPayloadLeakCount: audits.filter(
(record) =>
Object.hasOwn(record, 'arguments') ||
Object.hasOwn(record, 'response') ||
Object.hasOwn(record, 'toolArguments'),
).length,
};
}
function validateNativeRuntimeToolPlanProtocolEvidence(records) {
const protocolCount = validateMainRunToolPlanProtocols(records);
const evidence = collectNativeRuntimeToolPlanProtocolEvidence(records);
const protocols = records.filter(
(record) =>
record.recordType === 'agent.runtime.tool_plan.protocol' &&
record.agentId === mainAgentId &&
record.runId === state.initialRunId,
);
assert(
evidence.toolPlanProtocolCount === protocolCount &&
evidence.nativeRuntimeToolPlanCount === protocolCount &&
evidence.nativeRuntimeToolPlanRepairCount ===
evidence.toolPlanRepairCount &&
evidence.wrapperToolPlanFallbackCount === 0 &&
evidence.textJsonToolPlanFallbackCount === 0 &&
evidence.toolPlanAuditPayloadLeakCount === 0 &&
protocols.every(
(record) =>
Number.isSafeInteger(record.functionCallCount) &&
record.functionCallCount > 0 &&
Array.isArray(record.callIds) &&
record.callIds.length === record.functionCallCount &&
new Set(record.callIds).size === record.callIds.length &&
Array.isArray(record.functionNames) &&
record.functionNames.length === record.functionCallCount &&
record.functionNames.every(
(name) =>
isNonEmptyString(name) && name !== 'submit_agent_tool_plan',
),
),
'goal-native-tool-plan-protocol-required',
);
return evidence;
}
async function validateSameRunSteerEvidence({
agentDb,
activity,