feat(reporting-governance): add profile artifact binding slice

This commit is contained in:
Eve
2026-05-08 10:07:26 +08:00
parent 000f6b6a8b
commit 6366f70491
15 changed files with 695 additions and 6 deletions

View File

@@ -43,7 +43,30 @@ test('runCompatibilityPreflight passes strict profile against reference descript
assert.equal(result.errors.length, 0);
});
test('runCompatibilityPreflight fails closed on schema/version mismatch', () => {
test('runCompatibilityPreflight keeps legacy compatibility mode open when caller provides no compatibility envelope', () => {
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 = runCompatibilityPreflight({
capabilityDescriptor: brokenDescriptor
});
assert.equal(result.status, 'pass');
assert.equal(result.requested_profile, null);
assert.equal(result.requested_plugin_version, null);
assert.equal(result.compatibility.version_ok, true);
assert.equal(result.errors.length, 0);
assert.ok(result.compatibility.schema_checks.some((entry) => entry.key === 'decision_schema' && entry.ok === false));
assert.ok(result.notes.some((note) => note.includes('skipped plugin version pin')));
});
test('runCompatibilityPreflight fails closed on schema/version mismatch once compatibility envelope is present', () => {
const brokenDescriptor = {
...capabilityDescriptor,
compatibility: {

View File

@@ -81,7 +81,7 @@ test('package root export resolves public package surface only', () => {
}
});
test('adapters subpath export resolves package-owned adapter index', () => {
test('adapters subpath export resolves package-owned adapter index plus profile artifact loader helpers', () => {
const root = createFixtureRoot();
try {
installPackageAlias(root);
@@ -93,7 +93,9 @@ test('adapters subpath export resolves package-owned adapter index', () => {
`);
assert.deepEqual(result.adapterKeys, [
'createDeploymentBindingContract',
'createRuntimeBinding',
'loadDeploymentProfileArtifact',
'runBridgeSupervisorAdapter',
'runDispatcherAdapter',
'runOrchestratorAdapter',

View File

@@ -131,6 +131,36 @@ test('executeGovernanceContract stays compatible for legacy callers without prof
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,

View File

@@ -19,9 +19,11 @@ const requiredPaths = [
'src/adapters/sender-binding.mjs',
'src/adapters/orchestrator.mjs',
'src/storage',
'src/storage/profile-artifact.mjs',
'src/reference/openclaw-watchdog-chain.md',
'capabilities/openclaw-watchdog-reference.json',
'examples/openclaw-watchdog-reference.descriptor.example.json'
'examples/openclaw-watchdog-reference.descriptor.example.json',
'profiles/strict-manager-mode.profile.json'
];
test('reporting-governance package skeleton paths exist', () => {

View File

@@ -0,0 +1,47 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import { loadDeploymentProfileArtifact, createDeploymentBindingContract } from '../src/storage/profile-artifact.mjs';
import { createRuntimeBinding } from '../src/adapters/index.mjs';
const packageRoot = path.resolve(import.meta.dirname, '..');
const repoRoot = path.resolve(packageRoot, '..', '..');
test('deployment profile artifact loads from package profiles and preserves compatibility envelope metadata', () => {
const { artifactPath, artifact } = loadDeploymentProfileArtifact({ profileId: 'strict-manager-mode' });
assert.equal(path.relative(packageRoot, artifactPath), path.join('profiles', 'strict-manager-mode.profile.json'));
assert.equal(artifact.kind, 'DeploymentProfileArtifact');
assert.equal(artifact.metadata.id, 'strict-manager-mode');
assert.equal(artifact.metadata.compatibility_mode, 'strict_envelope');
assert.equal(artifact.spec.package.pluginVersion, '0.1.0-mainline');
});
test('deployment binding contract resolves package artifact into real repo script and artifact paths', () => {
const { artifact } = loadDeploymentProfileArtifact({ profileId: 'strict-manager-mode' });
const binding = createDeploymentBindingContract({ artifact });
assert.equal(binding.runtime, 'openclaw');
assert.equal(binding.pluginVersion, '0.1.0-mainline');
assert.equal(binding.compatibilityMode, 'strict_envelope');
assert.equal(binding.entrypoint, path.resolve(repoRoot, 'scripts/watchdog_auto_notify_orchestrator.mjs'));
assert.equal(binding.scripts.watchdog, path.resolve(repoRoot, 'scripts/long_task_watchdog.mjs'));
assert.equal(binding.artifactRoots.queueItems, path.resolve(repoRoot, 'state/operator-notify-queue'));
assert.equal(fs.existsSync(binding.scripts.orchestrator), true);
});
test('runtime binding can be instantiated from profile artifact binding contract', () => {
const { artifact } = loadDeploymentProfileArtifact({ profileId: 'strict-manager-mode' });
const contract = createDeploymentBindingContract({ artifact });
const runtimeBinding = createRuntimeBinding({
cwd: repoRoot,
scripts: contract.scripts,
});
assert.equal(runtimeBinding.cwd, repoRoot);
assert.equal(runtimeBinding.scripts.dispatcher, contract.scripts.dispatcher);
assert.equal(runtimeBinding.scripts.bridgeSupervisor, contract.scripts.bridgeSupervisor);
assert.equal(runtimeBinding.scripts.senderBinding, contract.scripts.senderBinding);
});