feat: block progress claims without execution evidence
This commit is contained in:
@@ -17,6 +17,18 @@ const EVIDENCE_FIELDS = Object.freeze({
|
||||
'handoff.mode',
|
||||
'replyClosureMode',
|
||||
]),
|
||||
progressionClaim: Object.freeze([
|
||||
'progressionClaim',
|
||||
'claimedProgression',
|
||||
'statusSummary',
|
||||
]),
|
||||
executionEvidence: Object.freeze([
|
||||
'toolCallEvidence',
|
||||
'dispatchEvidence',
|
||||
'fileChangeEvidence',
|
||||
'verificationEvidence',
|
||||
'checkpointArtifactEvidence',
|
||||
]),
|
||||
});
|
||||
|
||||
const GATE_REQUIREMENTS = Object.freeze({
|
||||
@@ -35,6 +47,11 @@ const GATE_REQUIREMENTS = Object.freeze({
|
||||
acceptedFields: EVIDENCE_FIELDS.buttonPathMode,
|
||||
requiredValue: 'button_path',
|
||||
}),
|
||||
executionEvidence: Object.freeze({
|
||||
evidenceKey: 'executionEvidence',
|
||||
acceptedFields: EVIDENCE_FIELDS.executionEvidence,
|
||||
requiredValue: 'tool call, dispatch, file change, verification output, or checkpoint artifact evidence',
|
||||
}),
|
||||
});
|
||||
|
||||
function fail(code, message) {
|
||||
@@ -136,6 +153,16 @@ function usesButtonPath(input) {
|
||||
return hasAcceptedValue(input, EVIDENCE_FIELDS.buttonPathMode, 'button_path');
|
||||
}
|
||||
|
||||
function claimsProgressionWithoutEvidence(input) {
|
||||
const progressionClaim = EVIDENCE_FIELDS.progressionClaim
|
||||
.map((fieldPath) => getPathValue(input, fieldPath))
|
||||
.find((value) => hasNonEmptyString(value));
|
||||
|
||||
if (!hasNonEmptyString(progressionClaim)) return false;
|
||||
|
||||
return !hasAnyNonEmptyString(input, EVIDENCE_FIELDS.executionEvidence);
|
||||
}
|
||||
|
||||
function evaluateGate(input) {
|
||||
const gateRequired = isLongTask(input);
|
||||
const reasons = [];
|
||||
@@ -175,6 +202,13 @@ function evaluateGate(input) {
|
||||
allowedResponseModes.push('button_path');
|
||||
}
|
||||
|
||||
if (claimsProgressionWithoutEvidence(input)) {
|
||||
failed = true;
|
||||
reasons.push('claimed progression without concrete execution evidence is forbidden');
|
||||
requiredEvidence.push(describeRequirement(GATE_REQUIREMENTS.executionEvidence));
|
||||
allowedResponseModes.push('evidence_preserving_follow_up');
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
reasons.push('required long-task gate evidence is present or no gated condition was triggered');
|
||||
allowedResponseModes.push(needsOwnerDecision(input) ? 'button_path' : 'direct_reply');
|
||||
|
||||
Reference in New Issue
Block a user