351 lines
12 KiB
JavaScript
351 lines
12 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import path from 'node:path';
|
|
|
|
import { executeGovernanceContract, runCompatibilityPreflight } from '../src/core/index.mjs';
|
|
import capabilityDescriptor from '../capabilities/openclaw-watchdog-reference.json' with { type: 'json' };
|
|
|
|
const packageRoot = path.resolve(import.meta.dirname, '..');
|
|
const repoRoot = path.resolve(packageRoot, '..', '..');
|
|
|
|
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 strictProfile = {
|
|
metadata: { id: 'strict-manager-mode' },
|
|
spec: {
|
|
package: { pluginVersion: '0.1.0-mainline' },
|
|
policies: {
|
|
overrides: {
|
|
checkpoints: { overdueAction: 'force_checkpoint' }
|
|
}
|
|
},
|
|
notifications: {
|
|
operatorVisibleRecoveryRequired: true
|
|
}
|
|
},
|
|
capability_expectations: {
|
|
required: [
|
|
'emit_canonical_events',
|
|
'evaluate_watchdog_overdue',
|
|
'create_queue_items',
|
|
'create_spool_handoff',
|
|
'write_bridge_receipts'
|
|
],
|
|
preferred: ['direct_sender_binding', 'final_delivery_ack']
|
|
}
|
|
};
|
|
|
|
test('capability descriptor -> policy evaluation -> decision planning yields adapter-compatible contract', () => {
|
|
const preflight = runCompatibilityPreflight({
|
|
capabilityDescriptor,
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
assert.equal(preflight.status, 'pass');
|
|
|
|
const result = executeGovernanceContract({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: {
|
|
checkpoint_overdue: true,
|
|
result_available: true,
|
|
result_forwarded: false,
|
|
}
|
|
},
|
|
evidence: [
|
|
{ id: 'ev-watchdog', quality: 'moderate', is_new: true }
|
|
],
|
|
capabilityDescriptor,
|
|
policyPacks: [noSilencePack],
|
|
context: {
|
|
signals: ['checkpoint_overdue'],
|
|
operator_context: { report_anchor_present: true }
|
|
},
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
|
|
assert.equal(result.evaluation.decision.decision, 'force_checkpoint');
|
|
assert.equal(result.preflight.status, 'pass');
|
|
assert.equal(result.planning.receipt.delivery_state, 'pending_external_send');
|
|
assert.deepEqual(result.contract.adapter_actions, ['notify_operator']);
|
|
assert.deepEqual(result.contract.package_actions, ['emit_event']);
|
|
assert.deepEqual(result.contract.blocked_actions, []);
|
|
assert.equal(result.contract.receipt_status, 'planned');
|
|
assert.equal(result.contract.runtime, 'openclaw-watchdog-reference');
|
|
});
|
|
|
|
test('executeGovernanceContract stays compatible for legacy callers without profile/packageVersion', () => {
|
|
const result = executeGovernanceContract({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: { checkpoint_overdue: true }
|
|
},
|
|
capabilityDescriptor,
|
|
policyPacks: [noSilencePack],
|
|
context: {
|
|
signals: ['checkpoint_overdue']
|
|
}
|
|
});
|
|
|
|
assert.equal(result.evaluation.decision.decision, 'force_checkpoint');
|
|
assert.equal(result.preflight.status, 'pass');
|
|
assert.equal(result.preflight.requested_plugin_version, null);
|
|
assert.ok(result.preflight.notes.some((note) => note.includes('skipped plugin version pin')));
|
|
assert.equal(result.planning.receipt.status, 'planned');
|
|
assert.deepEqual(result.contract.adapter_actions, ['notify_operator']);
|
|
assert.deepEqual(result.contract.package_actions, ['emit_event']);
|
|
});
|
|
|
|
test('legacy caller still fails once profile supplies compatibility envelope against mismatched descriptor', () => {
|
|
const brokenDescriptor = {
|
|
...capabilityDescriptor,
|
|
compatibility: {
|
|
...capabilityDescriptor.compatibility,
|
|
plugin_spec_versions: ['9.9.9'],
|
|
decision_schema: 'schemas/reporting-governance/not-the-canonical-decision.schema.json'
|
|
}
|
|
};
|
|
|
|
const result = executeGovernanceContract({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: { checkpoint_overdue: true }
|
|
},
|
|
capabilityDescriptor: brokenDescriptor,
|
|
policyPacks: [noSilencePack],
|
|
context: {
|
|
signals: ['checkpoint_overdue']
|
|
},
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
|
|
assert.equal(result.preflight.status, 'fail_closed');
|
|
assert.equal(result.contract.delivery_state, 'blocked');
|
|
assert.equal(result.contract.receipt_status, 'blocked');
|
|
assert.ok(result.planning.receipt.notes.some((note) => note.includes('schema mismatch: decision_schema')));
|
|
});
|
|
|
|
test('contract truthfully degrades when notify path can queue but cannot directly dispatch', () => {
|
|
const limitedDescriptor = {
|
|
...capabilityDescriptor,
|
|
metadata: {
|
|
...capabilityDescriptor.metadata,
|
|
id: 'limited-openclaw-watchdog-reference'
|
|
},
|
|
capabilities: {
|
|
...capabilityDescriptor.capabilities,
|
|
notification_path: {
|
|
...capabilityDescriptor.capabilities.notification_path,
|
|
sender_binding: { supported: false, level: 'none' },
|
|
direct_send: { supported: false, level: 'none' }
|
|
}
|
|
}
|
|
};
|
|
|
|
const preflight = runCompatibilityPreflight({
|
|
capabilityDescriptor: limitedDescriptor,
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
assert.equal(preflight.status, 'degraded');
|
|
|
|
const result = executeGovernanceContract({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: { checkpoint_overdue: true }
|
|
},
|
|
capabilityDescriptor: limitedDescriptor,
|
|
policyPacks: [noSilencePack],
|
|
context: {
|
|
signals: ['checkpoint_overdue']
|
|
},
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
|
|
assert.equal(result.evaluation.decision.decision, 'force_checkpoint');
|
|
assert.equal(result.preflight.status, 'degraded');
|
|
assert.deepEqual(result.contract.adapter_actions, ['notify_operator']);
|
|
assert.deepEqual(result.contract.blocked_actions, []);
|
|
assert.equal(result.contract.receipt_status, 'planned');
|
|
assert.ok(result.planning.receipt.notes.some((note) => note.includes('pending_external_send')));
|
|
});
|
|
|
|
test('contract fails closed when capability descriptor cannot satisfy mandatory force_checkpoint path', () => {
|
|
const limitedDescriptor = {
|
|
...capabilityDescriptor,
|
|
metadata: {
|
|
...capabilityDescriptor.metadata,
|
|
id: 'hard-limited-openclaw-watchdog-reference'
|
|
},
|
|
capabilities: {
|
|
...capabilityDescriptor.capabilities,
|
|
enforcement: {
|
|
...capabilityDescriptor.capabilities.enforcement,
|
|
force_checkpoint: { supported: false, level: 'none' }
|
|
}
|
|
}
|
|
};
|
|
|
|
const preflight = runCompatibilityPreflight({
|
|
capabilityDescriptor: limitedDescriptor,
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
assert.equal(preflight.status, 'fail_closed');
|
|
|
|
const result = executeGovernanceContract({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: { checkpoint_overdue: true }
|
|
},
|
|
capabilityDescriptor: limitedDescriptor,
|
|
policyPacks: [noSilencePack],
|
|
context: {
|
|
signals: ['checkpoint_overdue']
|
|
},
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
|
|
assert.equal(result.evaluation.decision.decision, 'force_checkpoint');
|
|
assert.equal(result.preflight.status, 'fail_closed');
|
|
assert.deepEqual(result.planning.enforcement_intent.planned_actions, []);
|
|
assert.deepEqual(result.contract.adapter_actions, []);
|
|
assert.deepEqual(result.contract.package_actions, []);
|
|
assert.deepEqual(result.contract.blocked_actions, []);
|
|
assert.equal(result.contract.delivery_state, 'blocked');
|
|
assert.equal(result.contract.receipt_status, 'blocked');
|
|
assert.equal(result.planning.receipt.status, 'blocked');
|
|
assert.equal(result.planning.receipt.delivery_state, 'blocked');
|
|
assert.deepEqual(result.planning.receipt.enforcement_intent, []);
|
|
assert.deepEqual(result.planning.receipt.blocked_actions, []);
|
|
assert.ok(result.planning.receipt.notes.some((note) => note.includes('failed closed')));
|
|
});
|
|
|
|
test('schema/version mismatch blocks contract before any runnable plan is produced', () => {
|
|
const brokenDescriptor = {
|
|
...capabilityDescriptor,
|
|
compatibility: {
|
|
...capabilityDescriptor.compatibility,
|
|
plugin_spec_versions: ['9.9.9'],
|
|
decision_schema: 'schemas/reporting-governance/not-the-canonical-decision.schema.json'
|
|
}
|
|
};
|
|
|
|
const result = executeGovernanceContract({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: { checkpoint_overdue: true }
|
|
},
|
|
capabilityDescriptor: brokenDescriptor,
|
|
policyPacks: [noSilencePack],
|
|
context: {
|
|
signals: ['checkpoint_overdue']
|
|
},
|
|
profile: strictProfile,
|
|
packageVersion: '0.1.0-mainline'
|
|
});
|
|
|
|
assert.equal(result.preflight.status, 'fail_closed');
|
|
assert.equal(result.contract.delivery_state, 'blocked');
|
|
assert.equal(result.contract.receipt_status, 'blocked');
|
|
assert.deepEqual(result.planning.enforcement_intent.planned_actions, []);
|
|
assert.deepEqual(result.planning.enforcement_intent.runtime_adapter_required, []);
|
|
assert.deepEqual(result.planning.enforcement_intent.package_core_actions, []);
|
|
assert.deepEqual(result.planning.receipt.enforcement_intent, []);
|
|
assert.deepEqual(result.planning.receipt.blocked_actions, []);
|
|
assert.ok(result.planning.receipt.notes.some((note) => note.includes('schema mismatch: decision_schema')));
|
|
assert.ok(result.planning.receipt.notes.some((note) => note.includes('plugin version 0.1.0-mainline is not declared compatible')));
|
|
});
|
|
|
|
test('executeGovernanceContract exposes deployment binding when profile artifact bindings are provided', () => {
|
|
const profileArtifact = {
|
|
...strictProfile,
|
|
kind: 'DeploymentProfileArtifact',
|
|
apiVersion: 'reporting-governance/v1alpha1',
|
|
metadata: {
|
|
...strictProfile.metadata,
|
|
runtime: 'openclaw',
|
|
compatibility_mode: 'strict_envelope',
|
|
},
|
|
spec: {
|
|
...strictProfile.spec,
|
|
bindings: {
|
|
runtime: 'openclaw',
|
|
entrypoint: 'plugins/reporting-governance/scripts/watchdog_auto_notify_orchestrator.mjs',
|
|
scripts: {
|
|
watchdog: 'plugins/reporting-governance/scripts/long_task_watchdog.mjs',
|
|
dispatcher: 'plugins/reporting-governance/scripts/operator_notify_dispatcher.mjs',
|
|
bridgeSupervisor: 'plugins/reporting-governance/scripts/operator_notify_bridge_supervisor.mjs',
|
|
senderBinding: 'plugins/reporting-governance/scripts/operator_notify_sender_binding.mjs',
|
|
orchestrator: 'plugins/reporting-governance/scripts/watchdog_auto_notify_orchestrator.mjs'
|
|
},
|
|
artifact_roots: {
|
|
queueItems: 'state/operator-notify-queue'
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const result = executeGovernanceContract({
|
|
event: {
|
|
type: 'silence_timeout',
|
|
payload: { checkpoint_overdue: true }
|
|
},
|
|
capabilityDescriptor,
|
|
policyPacks: [noSilencePack],
|
|
context: {
|
|
signals: ['checkpoint_overdue']
|
|
},
|
|
profile: profileArtifact,
|
|
packageVersion: '0.1.0-mainline',
|
|
repoRootOverride: repoRoot,
|
|
});
|
|
|
|
assert.equal(result.preflight.status, 'pass');
|
|
assert.equal(result.deploymentBinding.entrypoint, path.resolve(repoRoot, 'plugins/reporting-governance/scripts/watchdog_auto_notify_orchestrator.mjs'));
|
|
assert.equal(result.deploymentBinding.scripts.dispatcher, path.resolve(repoRoot, 'plugins/reporting-governance/scripts/operator_notify_dispatcher.mjs'));
|
|
assert.equal(result.deploymentBinding.artifactRoots.queueItems, path.resolve(repoRoot, 'state/operator-notify-queue'));
|
|
});
|