144 lines
4.6 KiB
JavaScript
144 lines
4.6 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { evaluatePolicyPack, evaluatePolicies } from '../src/core/policy-evaluator.mjs';
|
|
|
|
const capabilityDescriptor = {
|
|
capabilities: {
|
|
enforcement: {
|
|
block_transition: { supported: true, level: 'partial' },
|
|
force_checkpoint: { supported: true, level: 'partial' },
|
|
rewrite_message: { supported: false, level: 'none' },
|
|
annotate_placeholder: { supported: false, level: 'none' },
|
|
request_review: { supported: false, level: 'none' },
|
|
downgrade_status: { supported: false, level: 'none' },
|
|
escalate: { supported: true, level: 'full' }
|
|
}
|
|
}
|
|
};
|
|
|
|
const noSilencePack = {
|
|
metadata: { id: 'no-silence', severity_default: 'high' },
|
|
spec: {
|
|
evaluation_mode: 'any_rule_match',
|
|
rules: [
|
|
{
|
|
id: 'no-silence.missed-checkpoint',
|
|
title: 'Missed checkpoint requires visible recovery',
|
|
intent: 'Prevent overdue checkpoints from becoming invisible.',
|
|
triggers: { event_types: ['silence_timeout'] },
|
|
conditions: {
|
|
all: [
|
|
{ fact: 'checkpoint.is_overdue', equals: true }
|
|
]
|
|
},
|
|
decision_output: {
|
|
decision: 'force_checkpoint',
|
|
severity: 'high',
|
|
reason: 'checkpoint overdue triggered forced operator-visible recovery',
|
|
suggested_status: 'in_progress',
|
|
required_actions: [
|
|
{ action: 'notify_operator', target: 'operator_channel', mandatory: true },
|
|
{ action: 'emit_event', target: 'event_stream', mandatory: true }
|
|
],
|
|
operator_notice: {
|
|
required: true,
|
|
channel: 'telegram',
|
|
urgency: 'high',
|
|
message: 'Required update: checkpoint overdue.',
|
|
deadline: '2026-01-01T00:00:00.000Z'
|
|
}
|
|
},
|
|
operator_message_templates: {
|
|
checkpoint_forced: 'Required update: task exceeded allowed silence window.'
|
|
}
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
const verifiedCompletionPack = {
|
|
metadata: { id: 'verified-completion-only', severity_default: 'medium' },
|
|
spec: {
|
|
evaluation_mode: 'any_rule_match',
|
|
rules: [
|
|
{
|
|
id: 'verified-completion-only.insufficient-evidence',
|
|
title: 'Unsupported completion is downgraded',
|
|
intent: 'Completion claims require moderate evidence.',
|
|
triggers: {
|
|
event_types: ['task_claimed_complete'],
|
|
claim_types: ['completion']
|
|
},
|
|
conditions: {
|
|
all: [
|
|
{ fact: 'evidence.completion_min_quality', equals: false }
|
|
]
|
|
},
|
|
decision_output: {
|
|
decision: 'downgrade_status',
|
|
severity: 'high',
|
|
reason: 'completion evidence does not meet moderate threshold',
|
|
suggested_status: 'pending_verification',
|
|
required_actions: [
|
|
{
|
|
action: 'set_status',
|
|
target: 'task_record',
|
|
mandatory: true,
|
|
details: { to: 'pending_verification' }
|
|
},
|
|
{
|
|
action: 'append_audit_note',
|
|
target: 'task_record',
|
|
mandatory: true,
|
|
details: { note: 'downgraded unsupported completion' }
|
|
}
|
|
],
|
|
operator_notice: null
|
|
},
|
|
operator_message_templates: {
|
|
status_downgraded: 'Completion claim downgraded to pending verification.'
|
|
}
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
test('evaluatePolicyPack returns force_checkpoint for overdue silence event', () => {
|
|
const result = evaluatePolicyPack({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: { checkpoint_overdue: true }
|
|
},
|
|
evidence: [],
|
|
capabilityDescriptor,
|
|
policyPack: noSilencePack,
|
|
context: {
|
|
signals: ['checkpoint_overdue']
|
|
}
|
|
});
|
|
|
|
assert.equal(result.decision.decision, 'force_checkpoint');
|
|
assert.equal(result.decision.policy_id, 'no-silence.missed-checkpoint');
|
|
assert.equal(result.decision.operator_notice.required, true);
|
|
assert.equal(result.facts.checkpoint.is_overdue, true);
|
|
});
|
|
|
|
test('evaluatePolicies picks downgrade_status over allow for weak completion claim', () => {
|
|
const result = evaluatePolicies({
|
|
event: {
|
|
type: 'task_claimed_complete',
|
|
payload: {}
|
|
},
|
|
evidence: [
|
|
{ id: 'ev-1', quality: 'weak', is_new: true }
|
|
],
|
|
capabilityDescriptor,
|
|
policyPacks: [verifiedCompletionPack]
|
|
});
|
|
|
|
assert.equal(result.decision.decision, 'downgrade_status');
|
|
assert.equal(result.decision.suggested_status, 'pending_verification');
|
|
assert.equal(result.evaluations[0].decision.policy_id, 'verified-completion-only.insufficient-evidence');
|
|
});
|