agent-contracts 0.11.5 → 0.11.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -1
- package/dist/cli.js +450 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +376 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1204,6 +1204,22 @@ declare class ConfigLoadError extends Error {
|
|
|
1204
1204
|
declare function loadConfig(configPath?: string): Promise<ResolvedConfig | null>;
|
|
1205
1205
|
declare function resolveDslPath(dirArg: string | undefined, dirArgDefault: string, config: ResolvedConfig | null): string;
|
|
1206
1206
|
|
|
1207
|
+
interface DimensionResult {
|
|
1208
|
+
id: string;
|
|
1209
|
+
label: string;
|
|
1210
|
+
score: number;
|
|
1211
|
+
total: number;
|
|
1212
|
+
percent: number;
|
|
1213
|
+
weight: number;
|
|
1214
|
+
recommendations: string[];
|
|
1215
|
+
}
|
|
1216
|
+
interface ScoreResult {
|
|
1217
|
+
overall: number;
|
|
1218
|
+
dimensions: DimensionResult[];
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
declare function score(dsl: Dsl): ScoreResult;
|
|
1222
|
+
|
|
1207
1223
|
interface ResolvedCheck {
|
|
1208
1224
|
guardrail_id: string;
|
|
1209
1225
|
guardrail: Guardrail;
|
|
@@ -1259,4 +1275,4 @@ interface PathResolveResult {
|
|
|
1259
1275
|
}
|
|
1260
1276
|
declare function resolveBindingTargetPath(target: string, paths: Record<string, string>, bindingSoftware: string): PathResolveResult;
|
|
1261
1277
|
|
|
1262
|
-
export { type Agent, type AgentContractsConfig, AgentContractsConfigSchema, AgentSchema, type AppendOperator, AppendOperatorSchema, type Artifact, ArtifactSchema, BaseResolveError, type BindingOutput, BindingOutputSchema, CONTEXT_TYPES, type Check, CheckSchema, type Command, CommandSchema, type Components, ComponentsSchema, ConfigLoadError, type ContextType, ContextTypeSchema, type DelegatableTaskView, type DiagnosticMessage, type Dsl, DslLoadError, DslSchema, type EscalationCriterion, EscalationCriterionSchema, type ExecutionStep, ExecutionStepSchema, type Extends, ExtendsSchema, type ExternalParticipant, type GenerateDiagnostic, type GenerateGuardrailsOptions, type GenerateResult, type GlobalContext, type Guardrail, type GuardrailGenerationContext, type GuardrailPolicy, type GuardrailPolicyRule, type GuardrailPolicyRuleEscalation, GuardrailPolicyRuleEscalationSchema, GuardrailPolicyRuleSchema, GuardrailPolicySchema, GuardrailSchema, type GuardrailScope, GuardrailScopeSchema, type HandoffType, HandoffTypeSchema, type InsertAfterOperator, InsertAfterOperatorSchema, type LintDiagnostic, type LintRule, type LoadResult, type LoadedBinding, type Matcher, MatcherSchema, MergeError, type MergeableRecord, type MergedBehavioralSpec, type PathResolveResult, type PerAgentContext, type PerArtifactContext, type PerGuardrailContext, type PerGuardrailPolicyContext, type PerHandoffTypeContext, type PerPolicyContext, type PerTaskContext, type PerToolContext, type PerValidationContext, type PerWorkflowContext, type Policy, PolicySchema, type PolicyWhen, PolicyWhenSchema, type PrependOperator, PrependOperatorSchema, type Prerequisite, PrerequisiteSchema, type ReferenceDiagnostic, type RemoveOperator, RemoveOperatorSchema, type RenderTarget, RenderTargetSchema, type ReplaceOperator, ReplaceOperatorSchema, type Reporting, ReportingSchema, type ResolveChecksResult, type ResolveResult, type ResolvedCheck, type ResolvedConfig, type ResolvedRenderTarget, type Retry, type Rule, RuleSchema, type SchemaValidationResult, type Severity, type SoftwareBinding, SoftwareBindingSchema, type System, type SystemContext, SystemSchema, type Task, TaskSchema, type Tool, ToolSchema, type Validation, ValidationSchema, type VersionLiteral, VersionLiteralSchema, type Workflow, WorkflowSchema, type WorkflowStep, WorkflowStepSchema, type XExtensionDecl, XExtensionDeclSchema, buildArtifactContext, buildGlobalContext, buildGuardrailContext, buildGuardrailPolicyContext, buildHandoffTypeContext, buildPerAgentContext, buildPolicyContext, buildSystemContext, buildTaskContext, buildToolContext, buildValidationContext, buildWorkflowContext, builtinRules, checkDriftFromConfig, checkReferences, expandDefaults, generateGuardrails, lint, loadBindings, loadConfig, loadDsl, mergeDsl, renderFromConfig, resolve, resolveAllOf, resolveBase, resolveBindingTargetPath, resolveChecks, resolveDslPath, spectralLint, validateHandoffSchemas, validateSchema, yamlReservedKeySafetyRule };
|
|
1278
|
+
export { type Agent, type AgentContractsConfig, AgentContractsConfigSchema, AgentSchema, type AppendOperator, AppendOperatorSchema, type Artifact, ArtifactSchema, BaseResolveError, type BindingOutput, BindingOutputSchema, CONTEXT_TYPES, type Check, CheckSchema, type Command, CommandSchema, type Components, ComponentsSchema, ConfigLoadError, type ContextType, ContextTypeSchema, type DelegatableTaskView, type DiagnosticMessage, type DimensionResult, type Dsl, DslLoadError, DslSchema, type EscalationCriterion, EscalationCriterionSchema, type ExecutionStep, ExecutionStepSchema, type Extends, ExtendsSchema, type ExternalParticipant, type GenerateDiagnostic, type GenerateGuardrailsOptions, type GenerateResult, type GlobalContext, type Guardrail, type GuardrailGenerationContext, type GuardrailPolicy, type GuardrailPolicyRule, type GuardrailPolicyRuleEscalation, GuardrailPolicyRuleEscalationSchema, GuardrailPolicyRuleSchema, GuardrailPolicySchema, GuardrailSchema, type GuardrailScope, GuardrailScopeSchema, type HandoffType, HandoffTypeSchema, type InsertAfterOperator, InsertAfterOperatorSchema, type LintDiagnostic, type LintRule, type LoadResult, type LoadedBinding, type Matcher, MatcherSchema, MergeError, type MergeableRecord, type MergedBehavioralSpec, type PathResolveResult, type PerAgentContext, type PerArtifactContext, type PerGuardrailContext, type PerGuardrailPolicyContext, type PerHandoffTypeContext, type PerPolicyContext, type PerTaskContext, type PerToolContext, type PerValidationContext, type PerWorkflowContext, type Policy, PolicySchema, type PolicyWhen, PolicyWhenSchema, type PrependOperator, PrependOperatorSchema, type Prerequisite, PrerequisiteSchema, type ReferenceDiagnostic, type RemoveOperator, RemoveOperatorSchema, type RenderTarget, RenderTargetSchema, type ReplaceOperator, ReplaceOperatorSchema, type Reporting, ReportingSchema, type ResolveChecksResult, type ResolveResult, type ResolvedCheck, type ResolvedConfig, type ResolvedRenderTarget, type Retry, type Rule, RuleSchema, type SchemaValidationResult, type ScoreResult, type Severity, type SoftwareBinding, SoftwareBindingSchema, type System, type SystemContext, SystemSchema, type Task, TaskSchema, type Tool, ToolSchema, type Validation, ValidationSchema, type VersionLiteral, VersionLiteralSchema, type Workflow, WorkflowSchema, type WorkflowStep, WorkflowStepSchema, type XExtensionDecl, XExtensionDeclSchema, buildArtifactContext, buildGlobalContext, buildGuardrailContext, buildGuardrailPolicyContext, buildHandoffTypeContext, buildPerAgentContext, buildPolicyContext, buildSystemContext, buildTaskContext, buildToolContext, buildValidationContext, buildWorkflowContext, builtinRules, checkDriftFromConfig, checkReferences, expandDefaults, generateGuardrails, lint, loadBindings, loadConfig, loadDsl, mergeDsl, renderFromConfig, resolve, resolveAllOf, resolveBase, resolveBindingTargetPath, resolveChecks, resolveDslPath, score, spectralLint, validateHandoffSchemas, validateSchema, yamlReservedKeySafetyRule };
|
package/dist/index.js
CHANGED
|
@@ -51876,6 +51876,7 @@ var validationCoverageRule = {
|
|
|
51876
51876
|
}
|
|
51877
51877
|
validationsByArtifact.get(val.target_artifact).add(val.kind);
|
|
51878
51878
|
}
|
|
51879
|
+
const strictArtifactTypes = ["code", "config", "schema"];
|
|
51879
51880
|
for (const [artId, art] of Object.entries(dsl.artifacts)) {
|
|
51880
51881
|
const kinds = validationsByArtifact.get(artId);
|
|
51881
51882
|
if (!kinds || kinds.size === 0) {
|
|
@@ -51887,8 +51888,7 @@ var validationCoverageRule = {
|
|
|
51887
51888
|
});
|
|
51888
51889
|
continue;
|
|
51889
51890
|
}
|
|
51890
|
-
|
|
51891
|
-
if (mechanicalTypes.includes(art.type) && !kinds.has("mechanical") && !kinds.has("schema")) {
|
|
51891
|
+
if (strictArtifactTypes.includes(art.type) && !kinds.has("mechanical") && !kinds.has("schema")) {
|
|
51892
51892
|
diagnostics.push({
|
|
51893
51893
|
ruleId: "validation-coverage",
|
|
51894
51894
|
severity: "warning",
|
|
@@ -51897,6 +51897,16 @@ var validationCoverageRule = {
|
|
|
51897
51897
|
});
|
|
51898
51898
|
}
|
|
51899
51899
|
}
|
|
51900
|
+
for (const [artId, art] of Object.entries(dsl.artifacts)) {
|
|
51901
|
+
if (art.required_validations.length === 0) {
|
|
51902
|
+
diagnostics.push({
|
|
51903
|
+
ruleId: "validation-coverage",
|
|
51904
|
+
severity: "warning",
|
|
51905
|
+
path: `artifacts.${artId}`,
|
|
51906
|
+
message: `Artifact "${artId}" has empty required_validations`
|
|
51907
|
+
});
|
|
51908
|
+
}
|
|
51909
|
+
}
|
|
51900
51910
|
const referencedValidations = /* @__PURE__ */ new Set();
|
|
51901
51911
|
for (const wf of Object.values(dsl.workflow)) {
|
|
51902
51912
|
for (const step of wf.steps) {
|
|
@@ -52283,6 +52293,101 @@ var yamlReservedKeySafetyRule = {
|
|
|
52283
52293
|
}
|
|
52284
52294
|
};
|
|
52285
52295
|
|
|
52296
|
+
// src/linter/rules/artifact-required-validation-wiring.ts
|
|
52297
|
+
var artifactRequiredValidationWiringRule = {
|
|
52298
|
+
id: "artifact-required-validation-wiring",
|
|
52299
|
+
description: "Every validation listed in artifact.required_validations must exist, target the artifact, and be referenced in a workflow step or task.",
|
|
52300
|
+
run(dsl) {
|
|
52301
|
+
const diagnostics = [];
|
|
52302
|
+
const referencedValidations = /* @__PURE__ */ new Set();
|
|
52303
|
+
for (const wf of Object.values(dsl.workflow)) {
|
|
52304
|
+
for (const step of wf.steps) {
|
|
52305
|
+
if (step.type === "validation") {
|
|
52306
|
+
referencedValidations.add(step.validation);
|
|
52307
|
+
}
|
|
52308
|
+
}
|
|
52309
|
+
}
|
|
52310
|
+
for (const task of Object.values(dsl.tasks)) {
|
|
52311
|
+
for (const valId of task.validations) {
|
|
52312
|
+
referencedValidations.add(valId);
|
|
52313
|
+
}
|
|
52314
|
+
}
|
|
52315
|
+
for (const [artId, art] of Object.entries(dsl.artifacts)) {
|
|
52316
|
+
for (const reqValId of art.required_validations) {
|
|
52317
|
+
const val = dsl.validations[reqValId];
|
|
52318
|
+
if (!val) {
|
|
52319
|
+
diagnostics.push({
|
|
52320
|
+
ruleId: "artifact-required-validation-wiring",
|
|
52321
|
+
severity: "error",
|
|
52322
|
+
path: `artifacts.${artId}`,
|
|
52323
|
+
message: `required_validation "${reqValId}" does not exist in validations`
|
|
52324
|
+
});
|
|
52325
|
+
continue;
|
|
52326
|
+
}
|
|
52327
|
+
if (val.target_artifact !== artId) {
|
|
52328
|
+
diagnostics.push({
|
|
52329
|
+
ruleId: "artifact-required-validation-wiring",
|
|
52330
|
+
severity: "error",
|
|
52331
|
+
path: `artifacts.${artId}`,
|
|
52332
|
+
message: `required_validation "${reqValId}" has target_artifact "${val.target_artifact}" instead of "${artId}"`
|
|
52333
|
+
});
|
|
52334
|
+
}
|
|
52335
|
+
if (!referencedValidations.has(reqValId)) {
|
|
52336
|
+
diagnostics.push({
|
|
52337
|
+
ruleId: "artifact-required-validation-wiring",
|
|
52338
|
+
severity: "warning",
|
|
52339
|
+
path: `artifacts.${artId}`,
|
|
52340
|
+
message: `required_validation "${reqValId}" is defined but not referenced in any workflow step or task`
|
|
52341
|
+
});
|
|
52342
|
+
}
|
|
52343
|
+
}
|
|
52344
|
+
}
|
|
52345
|
+
return diagnostics;
|
|
52346
|
+
}
|
|
52347
|
+
};
|
|
52348
|
+
|
|
52349
|
+
// src/linter/rules/task-output-validation-completeness.ts
|
|
52350
|
+
var taskOutputValidationCompletenessRule = {
|
|
52351
|
+
id: "task-output-validation-completeness",
|
|
52352
|
+
description: "Tasks producing artifacts should cover those artifacts' required_validations in their validations list.",
|
|
52353
|
+
run(dsl) {
|
|
52354
|
+
const diagnostics = [];
|
|
52355
|
+
for (const [taskId, task] of Object.entries(dsl.tasks)) {
|
|
52356
|
+
const producedArtifacts = /* @__PURE__ */ new Set();
|
|
52357
|
+
if (task.execution_steps) {
|
|
52358
|
+
for (const step of task.execution_steps) {
|
|
52359
|
+
if (step.produces_artifact) {
|
|
52360
|
+
producedArtifacts.add(step.produces_artifact);
|
|
52361
|
+
}
|
|
52362
|
+
}
|
|
52363
|
+
}
|
|
52364
|
+
const agent = dsl.agents[task.target_agent];
|
|
52365
|
+
if (agent) {
|
|
52366
|
+
for (const artId of agent.can_write_artifacts) {
|
|
52367
|
+
producedArtifacts.add(artId);
|
|
52368
|
+
}
|
|
52369
|
+
}
|
|
52370
|
+
const taskValidations = new Set(task.validations);
|
|
52371
|
+
for (const artId of producedArtifacts) {
|
|
52372
|
+
const art = dsl.artifacts[artId];
|
|
52373
|
+
if (!art || art.required_validations.length === 0) continue;
|
|
52374
|
+
const missing = art.required_validations.filter(
|
|
52375
|
+
(v2) => !taskValidations.has(v2)
|
|
52376
|
+
);
|
|
52377
|
+
if (missing.length > 0) {
|
|
52378
|
+
diagnostics.push({
|
|
52379
|
+
ruleId: "task-output-validation-completeness",
|
|
52380
|
+
severity: "warning",
|
|
52381
|
+
path: `tasks.${taskId}`,
|
|
52382
|
+
message: `Task produces artifact "${artId}" which requires validations [${missing.join(", ")}] but task.validations does not include them`
|
|
52383
|
+
});
|
|
52384
|
+
}
|
|
52385
|
+
}
|
|
52386
|
+
}
|
|
52387
|
+
return diagnostics;
|
|
52388
|
+
}
|
|
52389
|
+
};
|
|
52390
|
+
|
|
52286
52391
|
// src/linter/linter.ts
|
|
52287
52392
|
var builtinRules = [
|
|
52288
52393
|
validationCoverageRule,
|
|
@@ -52292,7 +52397,9 @@ var builtinRules = [
|
|
|
52292
52397
|
artifactOwnershipRule,
|
|
52293
52398
|
toolCommandsRule,
|
|
52294
52399
|
guardrailPolicyCoverageRule,
|
|
52295
|
-
yamlReservedKeySafetyRule
|
|
52400
|
+
yamlReservedKeySafetyRule,
|
|
52401
|
+
artifactRequiredValidationWiringRule,
|
|
52402
|
+
taskOutputValidationCompletenessRule
|
|
52296
52403
|
];
|
|
52297
52404
|
function lint(dsl, rules = builtinRules) {
|
|
52298
52405
|
const diagnostics = [];
|
|
@@ -54437,6 +54544,271 @@ ${issues}`,
|
|
|
54437
54544
|
return results;
|
|
54438
54545
|
}
|
|
54439
54546
|
|
|
54547
|
+
// src/scorer/scorer.ts
|
|
54548
|
+
function pct(n3, d2) {
|
|
54549
|
+
return d2 === 0 ? 100 : Math.round(n3 / d2 * 100);
|
|
54550
|
+
}
|
|
54551
|
+
function artifactValidationCoverage(dsl) {
|
|
54552
|
+
const entries = Object.entries(dsl.artifacts);
|
|
54553
|
+
const total = entries.length;
|
|
54554
|
+
const covered = entries.filter(
|
|
54555
|
+
([, a3]) => a3.required_validations.length > 0
|
|
54556
|
+
).length;
|
|
54557
|
+
const missing = entries.filter(([, a3]) => a3.required_validations.length === 0).map(([id]) => id);
|
|
54558
|
+
return {
|
|
54559
|
+
id: "artifact-validation-coverage",
|
|
54560
|
+
label: "Artifact validation coverage",
|
|
54561
|
+
score: covered,
|
|
54562
|
+
total,
|
|
54563
|
+
percent: pct(covered, total),
|
|
54564
|
+
weight: 3,
|
|
54565
|
+
recommendations: missing.length > 0 ? [`${missing.length} artifacts missing required_validations: ${missing.join(", ")}`] : []
|
|
54566
|
+
};
|
|
54567
|
+
}
|
|
54568
|
+
function taskValidationCoverage(dsl) {
|
|
54569
|
+
const entries = Object.entries(dsl.tasks);
|
|
54570
|
+
const total = entries.length;
|
|
54571
|
+
const covered = entries.filter(([, t3]) => t3.validations.length > 0).length;
|
|
54572
|
+
const missing = entries.filter(([, t3]) => t3.validations.length === 0).map(([id]) => id);
|
|
54573
|
+
return {
|
|
54574
|
+
id: "task-validation-coverage",
|
|
54575
|
+
label: "Task validation coverage",
|
|
54576
|
+
score: covered,
|
|
54577
|
+
total,
|
|
54578
|
+
percent: pct(covered, total),
|
|
54579
|
+
weight: 3,
|
|
54580
|
+
recommendations: missing.length > 0 ? [`${missing.length} tasks missing validations: ${missing.join(", ")}`] : []
|
|
54581
|
+
};
|
|
54582
|
+
}
|
|
54583
|
+
function guardrailPolicyCoverage(dsl) {
|
|
54584
|
+
const guardrailIds = Object.keys(dsl.guardrails);
|
|
54585
|
+
const total = guardrailIds.length;
|
|
54586
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
54587
|
+
for (const policy of Object.values(dsl.guardrail_policies)) {
|
|
54588
|
+
for (const rule of policy.rules) {
|
|
54589
|
+
referenced.add(rule.guardrail);
|
|
54590
|
+
}
|
|
54591
|
+
}
|
|
54592
|
+
const covered = guardrailIds.filter((id) => referenced.has(id)).length;
|
|
54593
|
+
const missing = guardrailIds.filter((id) => !referenced.has(id));
|
|
54594
|
+
return {
|
|
54595
|
+
id: "guardrail-policy-coverage",
|
|
54596
|
+
label: "Guardrail policy coverage",
|
|
54597
|
+
score: covered,
|
|
54598
|
+
total,
|
|
54599
|
+
percent: pct(covered, total),
|
|
54600
|
+
weight: 2,
|
|
54601
|
+
recommendations: missing.length > 0 ? [`${missing.length} guardrails not in any policy: ${missing.join(", ")}`] : []
|
|
54602
|
+
};
|
|
54603
|
+
}
|
|
54604
|
+
function workflowValidationIntegration(dsl) {
|
|
54605
|
+
const blockingValidations = Object.entries(dsl.validations).filter(
|
|
54606
|
+
([, v2]) => v2.blocking
|
|
54607
|
+
);
|
|
54608
|
+
const total = blockingValidations.length;
|
|
54609
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
54610
|
+
for (const wf of Object.values(dsl.workflow)) {
|
|
54611
|
+
for (const step of wf.steps) {
|
|
54612
|
+
if (step.type === "validation") {
|
|
54613
|
+
referenced.add(step.validation);
|
|
54614
|
+
}
|
|
54615
|
+
}
|
|
54616
|
+
}
|
|
54617
|
+
for (const task of Object.values(dsl.tasks)) {
|
|
54618
|
+
for (const valId of task.validations) {
|
|
54619
|
+
referenced.add(valId);
|
|
54620
|
+
}
|
|
54621
|
+
}
|
|
54622
|
+
const covered = blockingValidations.filter(
|
|
54623
|
+
([id]) => referenced.has(id)
|
|
54624
|
+
).length;
|
|
54625
|
+
const missing = blockingValidations.filter(([id]) => !referenced.has(id)).map(([id]) => id);
|
|
54626
|
+
return {
|
|
54627
|
+
id: "workflow-validation-integration",
|
|
54628
|
+
label: "Workflow validation integration",
|
|
54629
|
+
score: covered,
|
|
54630
|
+
total,
|
|
54631
|
+
percent: pct(covered, total),
|
|
54632
|
+
weight: 3,
|
|
54633
|
+
recommendations: missing.length > 0 ? [`${missing.length} blocking validations not wired: ${missing.join(", ")}`] : []
|
|
54634
|
+
};
|
|
54635
|
+
}
|
|
54636
|
+
var OPTIONAL_ENTITY_FIELDS = {
|
|
54637
|
+
agents: {
|
|
54638
|
+
section: "agents",
|
|
54639
|
+
fields: ["responsibilities", "constraints", "rules"]
|
|
54640
|
+
},
|
|
54641
|
+
tasks: {
|
|
54642
|
+
section: "tasks",
|
|
54643
|
+
fields: ["description", "responsibilities", "execution_steps", "completion_criteria"]
|
|
54644
|
+
},
|
|
54645
|
+
artifacts: {
|
|
54646
|
+
section: "artifacts",
|
|
54647
|
+
fields: ["description", "visibility"]
|
|
54648
|
+
},
|
|
54649
|
+
tools: {
|
|
54650
|
+
section: "tools",
|
|
54651
|
+
fields: ["description", "commands"]
|
|
54652
|
+
},
|
|
54653
|
+
workflow: {
|
|
54654
|
+
section: "workflow",
|
|
54655
|
+
fields: ["description", "trigger", "entry_conditions"]
|
|
54656
|
+
},
|
|
54657
|
+
guardrails: {
|
|
54658
|
+
section: "guardrails",
|
|
54659
|
+
fields: ["rationale", "tags"]
|
|
54660
|
+
}
|
|
54661
|
+
};
|
|
54662
|
+
function hasNonEmpty(obj, field) {
|
|
54663
|
+
const val = obj[field];
|
|
54664
|
+
if (val === void 0 || val === null) return false;
|
|
54665
|
+
if (typeof val === "string") return val.length > 0;
|
|
54666
|
+
if (Array.isArray(val)) return val.length > 0;
|
|
54667
|
+
return true;
|
|
54668
|
+
}
|
|
54669
|
+
function schemaCompleteness(dsl) {
|
|
54670
|
+
let totalSlots = 0;
|
|
54671
|
+
let filledSlots = 0;
|
|
54672
|
+
const lowSections = [];
|
|
54673
|
+
for (const [sectionKey, meta] of Object.entries(OPTIONAL_ENTITY_FIELDS)) {
|
|
54674
|
+
const entities = dsl[meta.section];
|
|
54675
|
+
if (!entities) continue;
|
|
54676
|
+
let sectionTotal = 0;
|
|
54677
|
+
let sectionFilled = 0;
|
|
54678
|
+
for (const entity of Object.values(entities)) {
|
|
54679
|
+
for (const field of meta.fields) {
|
|
54680
|
+
sectionTotal++;
|
|
54681
|
+
totalSlots++;
|
|
54682
|
+
if (hasNonEmpty(entity, field)) {
|
|
54683
|
+
sectionFilled++;
|
|
54684
|
+
filledSlots++;
|
|
54685
|
+
}
|
|
54686
|
+
}
|
|
54687
|
+
}
|
|
54688
|
+
if (sectionTotal > 0 && pct(sectionFilled, sectionTotal) < 50) {
|
|
54689
|
+
lowSections.push(sectionKey);
|
|
54690
|
+
}
|
|
54691
|
+
}
|
|
54692
|
+
return {
|
|
54693
|
+
id: "schema-completeness",
|
|
54694
|
+
label: "Schema completeness",
|
|
54695
|
+
score: filledSlots,
|
|
54696
|
+
total: totalSlots,
|
|
54697
|
+
percent: pct(filledSlots, totalSlots),
|
|
54698
|
+
weight: 1,
|
|
54699
|
+
recommendations: lowSections.length > 0 ? [`Low optional field coverage in: ${lowSections.join(", ")}`] : []
|
|
54700
|
+
};
|
|
54701
|
+
}
|
|
54702
|
+
function crossReferenceBidirectionality(dsl) {
|
|
54703
|
+
let totalChecks = 0;
|
|
54704
|
+
let passedChecks = 0;
|
|
54705
|
+
const issues = [];
|
|
54706
|
+
for (const [agentId, agent] of Object.entries(dsl.agents)) {
|
|
54707
|
+
for (const toolId of agent.can_execute_tools) {
|
|
54708
|
+
totalChecks++;
|
|
54709
|
+
const tool = dsl.tools[toolId];
|
|
54710
|
+
if (tool && tool.invokable_by.includes(agentId)) {
|
|
54711
|
+
passedChecks++;
|
|
54712
|
+
} else {
|
|
54713
|
+
issues.push(`agent ${agentId} \u2192 tool ${toolId}`);
|
|
54714
|
+
}
|
|
54715
|
+
}
|
|
54716
|
+
for (const artId of agent.can_write_artifacts) {
|
|
54717
|
+
totalChecks++;
|
|
54718
|
+
const art = dsl.artifacts[artId];
|
|
54719
|
+
if (art && (art.producers.includes(agentId) || art.editors.includes(agentId))) {
|
|
54720
|
+
passedChecks++;
|
|
54721
|
+
} else {
|
|
54722
|
+
issues.push(`agent ${agentId} \u2192 artifact ${artId} (write)`);
|
|
54723
|
+
}
|
|
54724
|
+
}
|
|
54725
|
+
for (const artId of agent.can_read_artifacts) {
|
|
54726
|
+
totalChecks++;
|
|
54727
|
+
const art = dsl.artifacts[artId];
|
|
54728
|
+
if (art && (art.consumers.includes(agentId) || art.producers.includes(agentId) || art.editors.includes(agentId))) {
|
|
54729
|
+
passedChecks++;
|
|
54730
|
+
} else {
|
|
54731
|
+
issues.push(`agent ${agentId} \u2192 artifact ${artId} (read)`);
|
|
54732
|
+
}
|
|
54733
|
+
}
|
|
54734
|
+
}
|
|
54735
|
+
for (const [toolId, tool] of Object.entries(dsl.tools)) {
|
|
54736
|
+
for (const agentId of tool.invokable_by) {
|
|
54737
|
+
totalChecks++;
|
|
54738
|
+
const agent = dsl.agents[agentId];
|
|
54739
|
+
if (agent && agent.can_execute_tools.includes(toolId)) {
|
|
54740
|
+
passedChecks++;
|
|
54741
|
+
} else {
|
|
54742
|
+
issues.push(`tool ${toolId} \u2192 agent ${agentId}`);
|
|
54743
|
+
}
|
|
54744
|
+
}
|
|
54745
|
+
}
|
|
54746
|
+
return {
|
|
54747
|
+
id: "cross-reference-bidirectionality",
|
|
54748
|
+
label: "Cross-reference bidirectionality",
|
|
54749
|
+
score: passedChecks,
|
|
54750
|
+
total: totalChecks,
|
|
54751
|
+
percent: pct(passedChecks, totalChecks),
|
|
54752
|
+
weight: 2,
|
|
54753
|
+
recommendations: issues.length > 0 ? [`${issues.length} unreciprocated cross-references: ${issues.slice(0, 5).join(", ")}${issues.length > 5 ? `, ... (${issues.length - 5} more)` : ""}`] : []
|
|
54754
|
+
};
|
|
54755
|
+
}
|
|
54756
|
+
function guardrailScopeResolution(dsl) {
|
|
54757
|
+
let totalRefs = 0;
|
|
54758
|
+
let resolvedRefs = 0;
|
|
54759
|
+
const unresolved = [];
|
|
54760
|
+
const sectionMap = {
|
|
54761
|
+
agents: dsl.agents,
|
|
54762
|
+
tasks: dsl.tasks,
|
|
54763
|
+
tools: dsl.tools,
|
|
54764
|
+
artifacts: dsl.artifacts,
|
|
54765
|
+
workflows: dsl.workflow
|
|
54766
|
+
};
|
|
54767
|
+
for (const [guardrailId, guardrail] of Object.entries(dsl.guardrails)) {
|
|
54768
|
+
const scope = guardrail.scope;
|
|
54769
|
+
for (const [scopeKey, entityIds] of Object.entries(scope)) {
|
|
54770
|
+
if (!Array.isArray(entityIds)) continue;
|
|
54771
|
+
const section = sectionMap[scopeKey];
|
|
54772
|
+
if (!section) continue;
|
|
54773
|
+
for (const entityId of entityIds) {
|
|
54774
|
+
totalRefs++;
|
|
54775
|
+
if (section[entityId]) {
|
|
54776
|
+
resolvedRefs++;
|
|
54777
|
+
} else {
|
|
54778
|
+
unresolved.push(`${guardrailId}.scope.${scopeKey}: ${entityId}`);
|
|
54779
|
+
}
|
|
54780
|
+
}
|
|
54781
|
+
}
|
|
54782
|
+
}
|
|
54783
|
+
return {
|
|
54784
|
+
id: "guardrail-scope-resolution",
|
|
54785
|
+
label: "Guardrail scope resolution",
|
|
54786
|
+
score: resolvedRefs,
|
|
54787
|
+
total: totalRefs,
|
|
54788
|
+
percent: pct(resolvedRefs, totalRefs),
|
|
54789
|
+
weight: 2,
|
|
54790
|
+
recommendations: unresolved.length > 0 ? [`${unresolved.length} unresolved scope refs: ${unresolved.join(", ")}`] : []
|
|
54791
|
+
};
|
|
54792
|
+
}
|
|
54793
|
+
function score(dsl) {
|
|
54794
|
+
const dimensions = [
|
|
54795
|
+
artifactValidationCoverage(dsl),
|
|
54796
|
+
taskValidationCoverage(dsl),
|
|
54797
|
+
guardrailPolicyCoverage(dsl),
|
|
54798
|
+
workflowValidationIntegration(dsl),
|
|
54799
|
+
schemaCompleteness(dsl),
|
|
54800
|
+
crossReferenceBidirectionality(dsl),
|
|
54801
|
+
guardrailScopeResolution(dsl)
|
|
54802
|
+
];
|
|
54803
|
+
const totalWeight = dimensions.reduce((s2, d2) => s2 + d2.weight, 0);
|
|
54804
|
+
const weightedSum = dimensions.reduce(
|
|
54805
|
+
(s2, d2) => s2 + d2.percent * d2.weight,
|
|
54806
|
+
0
|
|
54807
|
+
);
|
|
54808
|
+
const overall = totalWeight === 0 ? 100 : Math.round(weightedSum / totalWeight);
|
|
54809
|
+
return { overall, dimensions };
|
|
54810
|
+
}
|
|
54811
|
+
|
|
54440
54812
|
// src/guardrail-generator/generator.ts
|
|
54441
54813
|
import { readFile as readFile5, writeFile as writeFile2, mkdir as mkdir2, chmod, unlink as unlink2 } from "fs/promises";
|
|
54442
54814
|
import { resolve as resolve6, dirname as dirname6 } from "path";
|
|
@@ -54749,6 +55121,7 @@ export {
|
|
|
54749
55121
|
resolveBindingTargetPath,
|
|
54750
55122
|
resolveChecks,
|
|
54751
55123
|
resolveDslPath,
|
|
55124
|
+
score,
|
|
54752
55125
|
spectralLint,
|
|
54753
55126
|
validateHandoffSchemas,
|
|
54754
55127
|
validateSchema,
|