mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-09-24 23:10:56 +08:00
release: v1.25.0
This commit is contained in:
@@ -7,10 +7,15 @@ import process from "node:process";
|
||||
const CONTRACT_PATH = "src/lib/governance/modalityRuntimeContracts.json";
|
||||
const CAPABILITY_MATRIX_PATH =
|
||||
"src/lib/governance/modalityCapabilityMatrix.json";
|
||||
const ARTIFACT_GRAPH_PATH = "src/lib/governance/modalityArtifactGraph.json";
|
||||
const EXECUTION_PROFILE_PATH =
|
||||
"src/lib/governance/modalityExecutionProfiles.json";
|
||||
const REQUIRED_DOCS = [
|
||||
"docs/roadmap/warp/runtime-fact-map.md",
|
||||
"docs/roadmap/warp/contract-schema.md",
|
||||
"docs/roadmap/warp/capability-matrix.md",
|
||||
"docs/roadmap/warp/execution-profile.md",
|
||||
"docs/roadmap/warp/artifact-graph.md",
|
||||
"docs/roadmap/warp/evolution-guide.md",
|
||||
];
|
||||
|
||||
@@ -105,6 +110,24 @@ const FAILURE_REASONS = new Set([
|
||||
"file_unavailable",
|
||||
"source_unavailable",
|
||||
]);
|
||||
const PROFILE_WRITE_MODES = new Set([
|
||||
"domain_task_artifact",
|
||||
"domain_document_artifact",
|
||||
"runtime_observation_trace",
|
||||
"timeline_backed_document_artifact",
|
||||
"document_or_compat_file_artifact",
|
||||
]);
|
||||
const ARTIFACT_IMPLEMENTATION_STATUSES = new Set([
|
||||
"current",
|
||||
"partial",
|
||||
"planned",
|
||||
]);
|
||||
const REQUIRED_ARTIFACT_INDEX_FIELDS = new Set([
|
||||
"task_id",
|
||||
"contract_key",
|
||||
"artifact_kind",
|
||||
"status",
|
||||
]);
|
||||
const ENTRY_KINDS = new Set([
|
||||
"command",
|
||||
"button_action",
|
||||
@@ -431,7 +454,515 @@ function validateCapabilityMatrix(matrix) {
|
||||
};
|
||||
}
|
||||
|
||||
function validateContractRegistry(registry, matrixRefs) {
|
||||
function validateArtifactGraph(graph) {
|
||||
const errors = [];
|
||||
pushIf(errors, graph.version !== 1, "artifactGraph.version must be 1");
|
||||
pushIf(
|
||||
errors,
|
||||
graph.status !== "current",
|
||||
"artifactGraph.status must be current",
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!isNonEmptyString(graph.owner),
|
||||
"artifactGraph.owner must be set",
|
||||
);
|
||||
|
||||
const artifactMap = collectUniqueObjects(
|
||||
errors,
|
||||
graph.artifact_kinds,
|
||||
"kind",
|
||||
"artifactGraph.artifact_kinds",
|
||||
);
|
||||
|
||||
for (const kind of ARTIFACT_KINDS) {
|
||||
pushIf(
|
||||
errors,
|
||||
!artifactMap.has(kind),
|
||||
`artifactGraph.artifact_kinds is missing known artifact kind: ${kind}`,
|
||||
);
|
||||
}
|
||||
|
||||
for (const [kind, artifact] of artifactMap.entries()) {
|
||||
pushIf(
|
||||
errors,
|
||||
!ARTIFACT_KINDS.has(kind),
|
||||
`artifact ${kind}.kind is unknown: ${kind}`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!LIFECYCLES.has(artifact.lifecycle),
|
||||
`artifact ${kind}.lifecycle is unknown: ${String(artifact.lifecycle)}`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!MODALITIES.has(artifact.modality),
|
||||
`artifact ${kind}.modality is unknown: ${String(artifact.modality)}`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!ARTIFACT_IMPLEMENTATION_STATUSES.has(artifact.implementation_status),
|
||||
`artifact ${kind}.implementation_status is unknown: ${String(artifact.implementation_status)}`,
|
||||
);
|
||||
validateStringArray(errors, kind, "truth_sources", artifact.truth_sources);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
kind,
|
||||
"viewer_surfaces",
|
||||
artifact.viewer_surfaces,
|
||||
VIEWER_SURFACES,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
kind,
|
||||
"evidence_events",
|
||||
artifact.evidence_events,
|
||||
EVIDENCE_EVENTS,
|
||||
);
|
||||
validateStringArray(
|
||||
errors,
|
||||
kind,
|
||||
"task_index_fields",
|
||||
artifact.task_index_fields,
|
||||
);
|
||||
validateStringArray(
|
||||
errors,
|
||||
kind,
|
||||
"current_contracts",
|
||||
artifact.current_contracts,
|
||||
{ allowEmpty: true },
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!isNonEmptyString(artifact.notes),
|
||||
`artifact ${kind}.notes must be set`,
|
||||
);
|
||||
|
||||
if (
|
||||
artifact.implementation_status === "current" ||
|
||||
artifact.implementation_status === "partial"
|
||||
) {
|
||||
const indexFields = new Set(
|
||||
Array.isArray(artifact.task_index_fields)
|
||||
? artifact.task_index_fields
|
||||
: [],
|
||||
);
|
||||
for (const requiredField of REQUIRED_ARTIFACT_INDEX_FIELDS) {
|
||||
pushIf(
|
||||
errors,
|
||||
!indexFields.has(requiredField),
|
||||
`artifact ${kind}.task_index_fields must include ${requiredField}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
errors,
|
||||
artifactMap,
|
||||
};
|
||||
}
|
||||
|
||||
function hasIntersection(left, right) {
|
||||
if (!Array.isArray(left) || !Array.isArray(right)) {
|
||||
return false;
|
||||
}
|
||||
const rightSet = new Set(right);
|
||||
return left.some((value) => rightSet.has(value));
|
||||
}
|
||||
|
||||
function validateContractArtifactGraph(errors, contract, artifactGraphRefs) {
|
||||
const contractKey = contract.contract_key;
|
||||
if (!Array.isArray(contract.artifact_kinds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const artifactKind of contract.artifact_kinds) {
|
||||
const artifact = artifactGraphRefs.artifactMap.get(artifactKind);
|
||||
if (!artifact) {
|
||||
errors.push(`${contractKey}.artifact_kinds references artifact not defined in graph: ${artifactKind}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
pushIf(
|
||||
errors,
|
||||
Array.isArray(artifact.current_contracts) &&
|
||||
artifact.current_contracts.length > 0 &&
|
||||
!artifact.current_contracts.includes(contractKey),
|
||||
`${contractKey}.artifact_kinds contains ${artifactKind}, but artifactGraph.${artifactKind}.current_contracts does not include ${contractKey}`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!hasIntersection(contract.truth_source, artifact.truth_sources),
|
||||
`${contractKey}.artifact_kinds ${artifactKind} has no truth_source intersection with artifact graph`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!hasIntersection(contract.viewer_surface, artifact.viewer_surfaces),
|
||||
`${contractKey}.artifact_kinds ${artifactKind} has no viewer_surface intersection with artifact graph`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!hasIntersection(contract.evidence_events, artifact.evidence_events),
|
||||
`${contractKey}.artifact_kinds ${artifactKind} has no evidence_events intersection with artifact graph`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveExecutorAdapterKey(executor) {
|
||||
if (!isPlainObject(executor)) {
|
||||
return null;
|
||||
}
|
||||
if (!isNonEmptyString(executor.executor_kind) || !isNonEmptyString(executor.binding_key)) {
|
||||
return null;
|
||||
}
|
||||
return `${executor.executor_kind}:${executor.binding_key}`;
|
||||
}
|
||||
|
||||
function validateSubset(errors, label, actualValues, requiredValues) {
|
||||
const actualSet = new Set(Array.isArray(actualValues) ? actualValues : []);
|
||||
for (const requiredValue of requiredValues || []) {
|
||||
pushIf(
|
||||
errors,
|
||||
!actualSet.has(requiredValue),
|
||||
`${label} must include ${requiredValue}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateArtifactPolicy(errors, label, policy, artifactGraphRefs) {
|
||||
pushIf(errors, !isPlainObject(policy), `${label}.artifact_policy must be an object`);
|
||||
if (!isPlainObject(policy)) {
|
||||
return;
|
||||
}
|
||||
pushIf(
|
||||
errors,
|
||||
!PROFILE_WRITE_MODES.has(policy.write_mode),
|
||||
`${label}.artifact_policy.write_mode is unknown: ${String(policy.write_mode)}`,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
label,
|
||||
"artifact_policy.artifact_kinds",
|
||||
policy.artifact_kinds,
|
||||
ARTIFACT_KINDS,
|
||||
);
|
||||
if (Array.isArray(policy.artifact_kinds)) {
|
||||
for (const artifactKind of policy.artifact_kinds) {
|
||||
pushIf(
|
||||
errors,
|
||||
!artifactGraphRefs.artifactMap.has(artifactKind),
|
||||
`${label}.artifact_policy.artifact_kinds references artifact not defined in graph: ${artifactKind}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
validateEnumArray(
|
||||
errors,
|
||||
label,
|
||||
"artifact_policy.viewer_surfaces",
|
||||
policy.viewer_surfaces,
|
||||
VIEWER_SURFACES,
|
||||
);
|
||||
}
|
||||
|
||||
function validateExecutionProfiles(registry, profiles, matrixRefs, artifactGraphRefs) {
|
||||
const errors = [];
|
||||
pushIf(errors, profiles.version !== 1, "executionProfiles.version must be 1");
|
||||
pushIf(
|
||||
errors,
|
||||
profiles.status !== "current",
|
||||
"executionProfiles.status must be current",
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!isNonEmptyString(profiles.owner),
|
||||
"executionProfiles.owner must be set",
|
||||
);
|
||||
|
||||
const contractMap = collectUniqueObjects(
|
||||
errors,
|
||||
registry.contracts,
|
||||
"contract_key",
|
||||
"runtimeContracts.contracts",
|
||||
);
|
||||
const profileMap = collectUniqueObjects(
|
||||
errors,
|
||||
profiles.profiles,
|
||||
"profile_key",
|
||||
"executionProfiles.profiles",
|
||||
);
|
||||
const adapterMap = collectUniqueObjects(
|
||||
errors,
|
||||
profiles.executor_adapters,
|
||||
"adapter_key",
|
||||
"executionProfiles.executor_adapters",
|
||||
);
|
||||
|
||||
for (const [adapterKey, adapter] of adapterMap.entries()) {
|
||||
pushIf(
|
||||
errors,
|
||||
!LIFECYCLES.has(adapter.lifecycle),
|
||||
`executor adapter ${adapterKey}.lifecycle is unknown: ${String(adapter.lifecycle)}`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!EXECUTOR_KINDS.has(adapter.executor_kind),
|
||||
`executor adapter ${adapterKey}.executor_kind is unknown: ${String(adapter.executor_kind)}`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!isNonEmptyString(adapter.binding_key),
|
||||
`executor adapter ${adapterKey}.binding_key must be set`,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
isNonEmptyString(adapter.executor_kind) &&
|
||||
isNonEmptyString(adapter.binding_key) &&
|
||||
adapterKey !== `${adapter.executor_kind}:${adapter.binding_key}`,
|
||||
`executor adapter ${adapterKey}.adapter_key must equal executor_kind:binding_key`,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
adapterKey,
|
||||
"supported_contracts",
|
||||
adapter.supported_contracts,
|
||||
new Set(contractMap.keys()),
|
||||
);
|
||||
for (const fieldName of [
|
||||
"supports_progress",
|
||||
"supports_cancel",
|
||||
"supports_resume",
|
||||
"supports_artifact",
|
||||
]) {
|
||||
pushIf(
|
||||
errors,
|
||||
typeof adapter[fieldName] !== "boolean",
|
||||
`executor adapter ${adapterKey}.${fieldName} must be boolean`,
|
||||
);
|
||||
}
|
||||
validateEnumArray(
|
||||
errors,
|
||||
adapterKey,
|
||||
"artifact_output_kinds",
|
||||
adapter.artifact_output_kinds,
|
||||
ARTIFACT_KINDS,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
adapterKey,
|
||||
"permission_requirements",
|
||||
adapter.permission_requirements,
|
||||
PERMISSIONS,
|
||||
);
|
||||
validateStringArray(
|
||||
errors,
|
||||
adapterKey,
|
||||
"credential_requirements",
|
||||
adapter.credential_requirements,
|
||||
{ allowEmpty: true },
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
adapterKey,
|
||||
"failure_mapping",
|
||||
adapter.failure_mapping,
|
||||
FAILURE_REASONS,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
adapterKey,
|
||||
"evidence_events",
|
||||
adapter.evidence_events,
|
||||
EVIDENCE_EVENTS,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!isNonEmptyString(adapter.notes),
|
||||
`executor adapter ${adapterKey}.notes must be set`,
|
||||
);
|
||||
}
|
||||
|
||||
const supportedContractsByProfile = new Set();
|
||||
for (const [profileKey, profile] of profileMap.entries()) {
|
||||
pushIf(
|
||||
errors,
|
||||
!LIFECYCLES.has(profile.lifecycle),
|
||||
`execution profile ${profileKey}.lifecycle is unknown: ${String(profile.lifecycle)}`,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
profileKey,
|
||||
"supported_contracts",
|
||||
profile.supported_contracts,
|
||||
new Set(contractMap.keys()),
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
profileKey,
|
||||
"model_role_slots",
|
||||
profile.model_role_slots,
|
||||
matrixRefs.modelRoleSlots,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
profileKey,
|
||||
"permission_profile_keys",
|
||||
profile.permission_profile_keys,
|
||||
PERMISSIONS,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
profileKey,
|
||||
"executor_adapter_keys",
|
||||
profile.executor_adapter_keys,
|
||||
new Set(adapterMap.keys()),
|
||||
);
|
||||
validateArtifactPolicy(errors, profileKey, profile.artifact_policy, artifactGraphRefs);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
profileKey,
|
||||
"limecore_policy_refs",
|
||||
profile.limecore_policy_refs,
|
||||
LIMECORE_POLICY_REFS,
|
||||
);
|
||||
pushIf(
|
||||
errors,
|
||||
!isNonEmptyString(profile.user_lock_policy),
|
||||
`execution profile ${profileKey}.user_lock_policy must be set`,
|
||||
);
|
||||
validateStringArray(
|
||||
errors,
|
||||
profileKey,
|
||||
"fallback_behavior",
|
||||
profile.fallback_behavior,
|
||||
);
|
||||
validateEnumArray(
|
||||
errors,
|
||||
profileKey,
|
||||
"evidence_events",
|
||||
profile.evidence_events,
|
||||
EVIDENCE_EVENTS,
|
||||
);
|
||||
validateStringArray(errors, profileKey, "audit_fields", profile.audit_fields);
|
||||
pushIf(
|
||||
errors,
|
||||
!isNonEmptyString(profile.notes),
|
||||
`execution profile ${profileKey}.notes must be set`,
|
||||
);
|
||||
|
||||
for (const contractKey of profile.supported_contracts || []) {
|
||||
const contract = contractMap.get(contractKey);
|
||||
if (!contract) {
|
||||
continue;
|
||||
}
|
||||
supportedContractsByProfile.add(contractKey);
|
||||
const adapterKey = resolveExecutorAdapterKey(contract.executor_binding);
|
||||
validateSubset(
|
||||
errors,
|
||||
`execution profile ${profileKey}.model_role_slots`,
|
||||
profile.model_role_slots,
|
||||
[contract.routing_slot],
|
||||
);
|
||||
validateSubset(
|
||||
errors,
|
||||
`execution profile ${profileKey}.permission_profile_keys`,
|
||||
profile.permission_profile_keys,
|
||||
contract.permission_profile_keys,
|
||||
);
|
||||
validateSubset(
|
||||
errors,
|
||||
`execution profile ${profileKey}.limecore_policy_refs`,
|
||||
profile.limecore_policy_refs,
|
||||
contract.limecore_policy_refs,
|
||||
);
|
||||
validateSubset(
|
||||
errors,
|
||||
`execution profile ${profileKey}.artifact_policy.artifact_kinds`,
|
||||
profile.artifact_policy?.artifact_kinds,
|
||||
contract.artifact_kinds,
|
||||
);
|
||||
validateSubset(
|
||||
errors,
|
||||
`execution profile ${profileKey}.artifact_policy.viewer_surfaces`,
|
||||
profile.artifact_policy?.viewer_surfaces,
|
||||
contract.viewer_surface,
|
||||
);
|
||||
if (adapterKey) {
|
||||
validateSubset(
|
||||
errors,
|
||||
`execution profile ${profileKey}.executor_adapter_keys`,
|
||||
profile.executor_adapter_keys,
|
||||
[adapterKey],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const [contractKey, contract] of contractMap.entries()) {
|
||||
if (contract.lifecycle !== "current") {
|
||||
continue;
|
||||
}
|
||||
pushIf(
|
||||
errors,
|
||||
!supportedContractsByProfile.has(contractKey),
|
||||
`current contract ${contractKey} must be covered by an execution profile`,
|
||||
);
|
||||
const adapterKey = resolveExecutorAdapterKey(contract.executor_binding);
|
||||
const adapter = adapterKey ? adapterMap.get(adapterKey) : null;
|
||||
pushIf(
|
||||
errors,
|
||||
!adapter,
|
||||
`current contract ${contractKey}.executor_binding must be defined in executionProfiles.executor_adapters: ${String(adapterKey)}`,
|
||||
);
|
||||
if (!adapter) {
|
||||
continue;
|
||||
}
|
||||
validateSubset(
|
||||
errors,
|
||||
`executor adapter ${adapterKey}.supported_contracts`,
|
||||
adapter.supported_contracts,
|
||||
[contractKey],
|
||||
);
|
||||
for (const fieldName of [
|
||||
"supports_progress",
|
||||
"supports_cancel",
|
||||
"supports_resume",
|
||||
"supports_artifact",
|
||||
]) {
|
||||
pushIf(
|
||||
errors,
|
||||
adapter[fieldName] !== contract.executor_binding[fieldName],
|
||||
`current contract ${contractKey}.executor_binding.${fieldName} must match executor adapter ${adapterKey}`,
|
||||
);
|
||||
}
|
||||
validateSubset(
|
||||
errors,
|
||||
`executor adapter ${adapterKey}.artifact_output_kinds`,
|
||||
adapter.artifact_output_kinds,
|
||||
contract.artifact_kinds,
|
||||
);
|
||||
validateSubset(
|
||||
errors,
|
||||
`executor adapter ${adapterKey}.permission_requirements`,
|
||||
adapter.permission_requirements,
|
||||
contract.permission_profile_keys,
|
||||
);
|
||||
validateSubset(
|
||||
errors,
|
||||
`executor adapter ${adapterKey}.failure_mapping`,
|
||||
adapter.failure_mapping,
|
||||
contract.executor_binding.failure_mapping,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
errors,
|
||||
profileCount: profileMap.size,
|
||||
adapterCount: adapterMap.size,
|
||||
};
|
||||
}
|
||||
|
||||
function validateContractRegistry(registry, matrixRefs, artifactGraphRefs) {
|
||||
const errors = [];
|
||||
pushIf(errors, registry.version !== 1, "registry.version must be 1");
|
||||
pushIf(errors, registry.status !== "current", "registry.status must be current");
|
||||
@@ -508,6 +1039,7 @@ function validateContractRegistry(registry, matrixRefs) {
|
||||
}
|
||||
pushIf(errors, !isNonEmptyString(contract.owner_surface), `${contractKey}.owner_surface must be set`);
|
||||
validateEntryBindings(errors, contract);
|
||||
validateContractArtifactGraph(errors, contract, artifactGraphRefs);
|
||||
}
|
||||
|
||||
return errors;
|
||||
@@ -523,7 +1055,7 @@ function validateRequiredDocs() {
|
||||
});
|
||||
}
|
||||
|
||||
function renderSuccess(registry, matrix) {
|
||||
function renderSuccess(registry, matrix, graph, profileReport) {
|
||||
const currentCount = registry.contracts.filter(
|
||||
(contract) => contract.lifecycle === "current",
|
||||
).length;
|
||||
@@ -533,19 +1065,35 @@ function renderSuccess(registry, matrix) {
|
||||
` current: ${currentCount}`,
|
||||
` capabilities: ${matrix.capabilities.length}`,
|
||||
` model roles: ${matrix.model_roles.length}`,
|
||||
` artifact kinds: ${graph.artifact_kinds.length}`,
|
||||
` execution profiles: ${profileReport.profileCount}`,
|
||||
` executor adapters: ${profileReport.adapterCount}`,
|
||||
` registry: ${CONTRACT_PATH}`,
|
||||
` matrix: ${CAPABILITY_MATRIX_PATH}`,
|
||||
` graph: ${ARTIFACT_GRAPH_PATH}`,
|
||||
` profiles: ${EXECUTION_PROFILE_PATH}`,
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function main() {
|
||||
const registry = readJson(CONTRACT_PATH);
|
||||
const matrix = readJson(CAPABILITY_MATRIX_PATH);
|
||||
const graph = readJson(ARTIFACT_GRAPH_PATH);
|
||||
const profiles = readJson(EXECUTION_PROFILE_PATH);
|
||||
const matrixReport = validateCapabilityMatrix(matrix);
|
||||
const graphReport = validateArtifactGraph(graph);
|
||||
const profileReport = validateExecutionProfiles(
|
||||
registry,
|
||||
profiles,
|
||||
matrixReport,
|
||||
graphReport,
|
||||
);
|
||||
const errors = [
|
||||
...validateRequiredDocs(),
|
||||
...matrixReport.errors,
|
||||
...validateContractRegistry(registry, matrixReport),
|
||||
...graphReport.errors,
|
||||
...validateContractRegistry(registry, matrixReport, graphReport),
|
||||
...profileReport.errors,
|
||||
];
|
||||
|
||||
if (errors.length > 0) {
|
||||
@@ -556,7 +1104,7 @@ function main() {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(renderSuccess(registry, matrix));
|
||||
console.log(renderSuccess(registry, matrix, graph, profileReport));
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -287,7 +287,7 @@ describe("harness-eval-history-record", () => {
|
||||
},
|
||||
),
|
||||
).not.toThrow();
|
||||
}, 30_000);
|
||||
}, 60_000);
|
||||
|
||||
it("应记录本地 summary 历史,并生成非 seed 的 trend / cleanup", () => {
|
||||
const tempRoot = createTempRoot();
|
||||
@@ -442,7 +442,7 @@ describe("harness-eval-history-record", () => {
|
||||
),
|
||||
),
|
||||
).toBe(true);
|
||||
}, 30_000);
|
||||
}, 90_000);
|
||||
|
||||
it("并发记录 history 时不应覆盖已有样本", async () => {
|
||||
const tempRoot = createTempRoot();
|
||||
@@ -478,5 +478,5 @@ describe("harness-eval-history-record", () => {
|
||||
|
||||
expect(historyFiles).toHaveLength(2);
|
||||
expect(firstResult.recordedSummaryPath).not.toBe(secondResult.recordedSummaryPath);
|
||||
}, 30_000);
|
||||
}, 60_000);
|
||||
});
|
||||
|
||||
@@ -303,7 +303,7 @@ describe("GitHub release asset staging", () => {
|
||||
"arm-sig",
|
||||
);
|
||||
writeFile(
|
||||
path.join(assetsDir, "aarch64-apple-darwin", "Lime_1.24.0_aarch64.dmg"),
|
||||
path.join(assetsDir, "aarch64-apple-darwin", "Lime_1.25.0_aarch64.dmg"),
|
||||
);
|
||||
writeFile(path.join(assetsDir, "x86_64-apple-darwin", "Lime.app.tar.gz"));
|
||||
writeFile(
|
||||
@@ -311,7 +311,7 @@ describe("GitHub release asset staging", () => {
|
||||
"x64-sig",
|
||||
);
|
||||
writeFile(
|
||||
path.join(assetsDir, "x86_64-apple-darwin", "Lime_1.24.0_x64.dmg"),
|
||||
path.join(assetsDir, "x86_64-apple-darwin", "Lime_1.25.0_x64.dmg"),
|
||||
);
|
||||
writeFile(latestPath, "{}");
|
||||
|
||||
@@ -319,29 +319,29 @@ describe("GitHub release asset staging", () => {
|
||||
assetsDir,
|
||||
extraAssets: [latestPath],
|
||||
outDir,
|
||||
version: "v1.24.0",
|
||||
version: "v1.25.0",
|
||||
});
|
||||
|
||||
expect(copied.map((item) => item.name).sort()).toEqual(
|
||||
[
|
||||
"Lime_1.24.0_aarch64.app.tar.gz",
|
||||
"Lime_1.24.0_aarch64.app.tar.gz.sig",
|
||||
"Lime_1.24.0_aarch64.dmg",
|
||||
"Lime_1.24.0_x64.app.tar.gz",
|
||||
"Lime_1.24.0_x64.app.tar.gz.sig",
|
||||
"Lime_1.24.0_x64.dmg",
|
||||
"Lime_1.25.0_aarch64.app.tar.gz",
|
||||
"Lime_1.25.0_aarch64.app.tar.gz.sig",
|
||||
"Lime_1.25.0_aarch64.dmg",
|
||||
"Lime_1.25.0_x64.app.tar.gz",
|
||||
"Lime_1.25.0_x64.app.tar.gz.sig",
|
||||
"Lime_1.25.0_x64.dmg",
|
||||
"latest.json",
|
||||
].sort(),
|
||||
);
|
||||
expect(
|
||||
fs.readFileSync(
|
||||
path.join(outDir, "Lime_1.24.0_aarch64.app.tar.gz.sig"),
|
||||
path.join(outDir, "Lime_1.25.0_aarch64.app.tar.gz.sig"),
|
||||
"utf8",
|
||||
),
|
||||
).toBe("arm-sig");
|
||||
expect(
|
||||
fs.readFileSync(
|
||||
path.join(outDir, "Lime_1.24.0_x64.app.tar.gz.sig"),
|
||||
path.join(outDir, "Lime_1.25.0_x64.app.tar.gz.sig"),
|
||||
"utf8",
|
||||
),
|
||||
).toBe("x64-sig");
|
||||
|
||||
Reference in New Issue
Block a user