@vorionsys/basis 1.0.1
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/.env.example +22 -0
- package/AMOY-MIGRATION.md +188 -0
- package/DEPLOY-AMOY.md +368 -0
- package/DEPLOY-NOW.md +216 -0
- package/DEPLOYMENT.md +239 -0
- package/GET-WALLET.md +286 -0
- package/QUICK-WALLET-SETUP.md +268 -0
- package/README.md +195 -0
- package/artifacts/@openzeppelin/contracts/access/AccessControl.sol/AccessControl.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/access/AccessControl.sol/AccessControl.json +236 -0
- package/artifacts/@openzeppelin/contracts/access/IAccessControl.sol/IAccessControl.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/access/IAccessControl.sol/IAccessControl.json +204 -0
- package/artifacts/@openzeppelin/contracts/interfaces/IERC4906.sol/IERC4906.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/interfaces/IERC4906.sol/IERC4906.json +328 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.json +113 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.json +97 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.json +114 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.json +444 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.json +296 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.json +45 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol/ERC721Enumerable.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol/ERC721Enumerable.json +521 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol/ERC721URIStorage.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol/ERC721URIStorage.json +476 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol/IERC721Enumerable.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol/IERC721Enumerable.json +352 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.json +341 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/utils/ERC721Utils.sol/ERC721Utils.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/token/ERC721/utils/ERC721Utils.sol/ERC721Utils.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/Panic.sol/Panic.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/Panic.sol/Panic.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/Strings.sol/Strings.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/Strings.sol/Strings.json +37 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.json +30 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.json +30 -0
- package/artifacts/@openzeppelin/contracts/utils/math/Math.sol/Math.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/math/Math.sol/Math.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/math/SafeCast.sol/SafeCast.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/math/SafeCast.sol/SafeCast.json +65 -0
- package/artifacts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.json +10 -0
- package/artifacts/build-info/357d1bba4062d461f497f221490811a3.json +1 -0
- package/artifacts/contracts/AgentCard.sol/AgentCard.dbg.json +4 -0
- package/artifacts/contracts/AgentCard.sol/AgentCard.json +1430 -0
- package/build_errors.txt +0 -0
- package/build_output.txt +0 -0
- package/cache/solidity-files-cache.json +885 -0
- package/contracts/AgentCard.sol +478 -0
- package/contracts/deploy/01-deploy-agentcard.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/kya/accountability.d.ts.map +1 -0
- package/dist/kya/accountability.js +100 -0
- package/dist/kya/authorization.d.ts.map +1 -0
- package/dist/kya/authorization.js +258 -0
- package/dist/kya/behavior.d.ts.map +1 -0
- package/dist/kya/behavior.js +142 -0
- package/dist/kya/identity.d.ts.map +1 -0
- package/dist/kya/identity.js +187 -0
- package/dist/kya/index.d.ts.map +1 -0
- package/dist/kya/index.js +99 -0
- package/dist/kya/types.d.ts.map +1 -0
- package/dist/kya/types.js +5 -0
- package/dist/trust-1000-agents.test.d.ts.map +1 -0
- package/dist/trust-1000-agents.test.js +608 -0
- package/dist/trust-capabilities.d.ts.map +1 -0
- package/dist/trust-capabilities.js +478 -0
- package/dist/trust-factors.d.ts.map +1 -0
- package/dist/trust-factors.js +588 -0
- package/dist/trust-factors.test.d.ts.map +1 -0
- package/dist/trust-factors.test.js +179 -0
- package/dist/validation-gate.d.ts.map +1 -0
- package/dist/validation-gate.js +468 -0
- package/dist/validation-gate.test.d.ts.map +1 -0
- package/dist/validation-gate.test.js +419 -0
- package/hardhat.config.ts +55 -0
- package/package.json +57 -0
- package/scripts/certify-agent.ts +91 -0
- package/scripts/deploy-agentcard.ts +63 -0
- package/scripts/mint-agentcard.ts +87 -0
- package/specs/adversarial-sandbox-test-suite.md +1055 -0
- package/specs/kya-framework.md +910 -0
- package/specs/trust-factors-v2.md +437 -0
- package/src/index.ts +14 -0
- package/src/kya/accountability.ts +132 -0
- package/src/kya/authorization.ts +325 -0
- package/src/kya/behavior.ts +169 -0
- package/src/kya/identity.ts +224 -0
- package/src/kya/index.ts +125 -0
- package/src/kya/types.ts +242 -0
- package/src/trust-1000-agents.test.ts +745 -0
- package/src/trust-capabilities.ts +517 -0
- package/src/trust-factors.test.ts +241 -0
- package/src/trust-factors.ts +666 -0
- package/src/validation-gate.test.ts +531 -0
- package/src/validation-gate.ts +665 -0
- package/test-kya-simple.ts +258 -0
- package/test-kya.ts +245 -0
- package/tsconfig.json +14 -0
- package/typechain-types/@openzeppelin/contracts/access/AccessControl.ts +324 -0
- package/typechain-types/@openzeppelin/contracts/access/IAccessControl.ts +292 -0
- package/typechain-types/@openzeppelin/contracts/access/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/index.ts +11 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/IERC4906.ts +462 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/index.ts +6 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/ERC721.ts +420 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721.ts +393 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721Receiver.ts +110 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.ts +470 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.ts +489 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.ts +443 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.ts +420 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/index.ts +7 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +8 -0
- package/typechain-types/@openzeppelin/contracts/token/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/utils/Strings.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/utils/index.ts +8 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/ERC165.ts +94 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/IERC165.ts +94 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/utils/math/SafeCast.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/utils/math/index.ts +4 -0
- package/typechain-types/@openzeppelin/index.ts +5 -0
- package/typechain-types/common.ts +131 -0
- package/typechain-types/contracts/AgentCard.ts +1415 -0
- package/typechain-types/contracts/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/AccessControl__factory.ts +250 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControl__factory.ts +218 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/index.ts +7 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC4906__factory.ts +339 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors__factory.ts +127 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors__factory.ts +111 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors__factory.ts +128 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/ERC721__factory.ts +455 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721Receiver__factory.ts +59 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721__factory.ts +307 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable__factory.ts +535 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage__factory.ts +490 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable__factory.ts +366 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata__factory.ts +355 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/index.ts +7 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +7 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/Strings__factory.ts +90 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +6 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/ERC165__factory.ts +41 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/IERC165__factory.ts +41 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/math/SafeCast__factory.ts +118 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/math/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/index.ts +4 -0
- package/typechain-types/factories/contracts/AgentCard__factory.ts +1480 -0
- package/typechain-types/factories/contracts/index.ts +4 -0
- package/typechain-types/factories/index.ts +5 -0
- package/typechain-types/index.ts +44 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BASIS Validation Gate
|
|
3
|
+
*
|
|
4
|
+
* Central validation gate that verifies agent manifests before execution.
|
|
5
|
+
* Combines CAR parsing, schema validation, and capability matching.
|
|
6
|
+
*
|
|
7
|
+
* This gate returns PASS/REJECT decisions for the Kaizen pipeline.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { TrustTier, TIER_THRESHOLDS } from './trust-factors';
|
|
12
|
+
import { hasCapability, getCapabilitiesForTier, type Capability } from './trust-capabilities';
|
|
13
|
+
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// VALIDATION GATE TYPES
|
|
16
|
+
// =============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Gate decision - determines whether agent can proceed
|
|
20
|
+
*/
|
|
21
|
+
export enum GateDecision {
|
|
22
|
+
/** Agent passes validation, proceed to Layer 2 */
|
|
23
|
+
PASS = 'PASS',
|
|
24
|
+
/** Agent fails validation, block execution */
|
|
25
|
+
REJECT = 'REJECT',
|
|
26
|
+
/** Agent requires human review before proceeding */
|
|
27
|
+
ESCALATE = 'ESCALATE',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Validation error severity levels
|
|
32
|
+
*/
|
|
33
|
+
export enum ValidationSeverity {
|
|
34
|
+
/** Informational - does not affect decision */
|
|
35
|
+
INFO = 'info',
|
|
36
|
+
/** Warning - may affect future decisions */
|
|
37
|
+
WARNING = 'warning',
|
|
38
|
+
/** Error - causes rejection */
|
|
39
|
+
ERROR = 'error',
|
|
40
|
+
/** Critical - immediate rejection with logging */
|
|
41
|
+
CRITICAL = 'critical',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A single validation issue
|
|
46
|
+
*/
|
|
47
|
+
export interface ValidationIssue {
|
|
48
|
+
/** Unique code for this issue type */
|
|
49
|
+
code: string;
|
|
50
|
+
/** Human-readable message */
|
|
51
|
+
message: string;
|
|
52
|
+
/** Severity level */
|
|
53
|
+
severity: ValidationSeverity;
|
|
54
|
+
/** Field path that caused the issue */
|
|
55
|
+
path?: string;
|
|
56
|
+
/** Expected value or format */
|
|
57
|
+
expected?: string;
|
|
58
|
+
/** Actual value received */
|
|
59
|
+
actual?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Result of validation gate check
|
|
64
|
+
*/
|
|
65
|
+
export interface ValidationGateResult {
|
|
66
|
+
/** Gate decision: PASS, REJECT, or ESCALATE */
|
|
67
|
+
decision: GateDecision;
|
|
68
|
+
/** Whether validation passed */
|
|
69
|
+
valid: boolean;
|
|
70
|
+
/** Agent identifier (CAR string or ID) */
|
|
71
|
+
agentId: string;
|
|
72
|
+
/** Agent's current trust tier */
|
|
73
|
+
trustTier?: TrustTier;
|
|
74
|
+
/** Agent's trust score (0-1000) */
|
|
75
|
+
trustScore?: number;
|
|
76
|
+
/** List of validation issues found */
|
|
77
|
+
issues: ValidationIssue[];
|
|
78
|
+
/** Summary of errors (severity=error or critical) */
|
|
79
|
+
errors: ValidationIssue[];
|
|
80
|
+
/** Summary of warnings */
|
|
81
|
+
warnings: ValidationIssue[];
|
|
82
|
+
/** Timestamp of validation */
|
|
83
|
+
validatedAt: Date;
|
|
84
|
+
/** Duration of validation in milliseconds */
|
|
85
|
+
durationMs: number;
|
|
86
|
+
/** Capabilities the agent is allowed to use */
|
|
87
|
+
allowedCapabilities?: string[];
|
|
88
|
+
/** Capabilities that were requested but denied */
|
|
89
|
+
deniedCapabilities?: string[];
|
|
90
|
+
/** Recommendations for improving validation result */
|
|
91
|
+
recommendations?: string[];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Agent manifest for validation
|
|
96
|
+
*/
|
|
97
|
+
export interface AgentManifest {
|
|
98
|
+
/** Agent identifier (CAR string format preferred) */
|
|
99
|
+
agentId: string;
|
|
100
|
+
/** Organization/owner of the agent */
|
|
101
|
+
organization?: string;
|
|
102
|
+
/** Agent classification/type */
|
|
103
|
+
agentClass?: string;
|
|
104
|
+
/** Capability domains the agent claims */
|
|
105
|
+
domains?: string[];
|
|
106
|
+
/** Capability level claimed (L0-L7) */
|
|
107
|
+
capabilityLevel?: number;
|
|
108
|
+
/** Version string */
|
|
109
|
+
version?: string;
|
|
110
|
+
/** Current trust score (0-1000) */
|
|
111
|
+
trustScore?: number;
|
|
112
|
+
/** Capabilities the agent claims to need */
|
|
113
|
+
requestedCapabilities?: string[];
|
|
114
|
+
/** Additional metadata */
|
|
115
|
+
metadata?: Record<string, unknown>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Registered agent profile (from registry)
|
|
120
|
+
*/
|
|
121
|
+
export interface RegisteredProfile {
|
|
122
|
+
/** Agent ID */
|
|
123
|
+
agentId: string;
|
|
124
|
+
/** Organization */
|
|
125
|
+
organization: string;
|
|
126
|
+
/** Agent class */
|
|
127
|
+
agentClass: string;
|
|
128
|
+
/** Approved domains */
|
|
129
|
+
approvedDomains: string[];
|
|
130
|
+
/** Maximum capability level */
|
|
131
|
+
maxCapabilityLevel: number;
|
|
132
|
+
/** Approved capabilities */
|
|
133
|
+
approvedCapabilities: string[];
|
|
134
|
+
/** Current trust score */
|
|
135
|
+
trustScore: number;
|
|
136
|
+
/** Registration date */
|
|
137
|
+
registeredAt: Date;
|
|
138
|
+
/** Last verification date */
|
|
139
|
+
lastVerifiedAt?: Date;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Options for validation gate
|
|
144
|
+
*/
|
|
145
|
+
export interface ValidationGateOptions {
|
|
146
|
+
/** Strict mode - treat warnings as errors */
|
|
147
|
+
strict?: boolean;
|
|
148
|
+
/** Require registered profile match */
|
|
149
|
+
requireRegisteredProfile?: boolean;
|
|
150
|
+
/** Allow capability escalation request */
|
|
151
|
+
allowCapabilityEscalation?: boolean;
|
|
152
|
+
/** Custom domain requirements */
|
|
153
|
+
requiredDomains?: string[];
|
|
154
|
+
/** Minimum trust tier required */
|
|
155
|
+
minimumTrustTier?: TrustTier;
|
|
156
|
+
/** Custom validators to run */
|
|
157
|
+
customValidators?: CustomValidator[];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Custom validator function
|
|
162
|
+
*/
|
|
163
|
+
export type CustomValidator = (
|
|
164
|
+
manifest: AgentManifest,
|
|
165
|
+
profile?: RegisteredProfile
|
|
166
|
+
) => ValidationIssue[];
|
|
167
|
+
|
|
168
|
+
// =============================================================================
|
|
169
|
+
// ZOD SCHEMAS
|
|
170
|
+
// =============================================================================
|
|
171
|
+
|
|
172
|
+
export const validationIssueSchema = z.object({
|
|
173
|
+
code: z.string(),
|
|
174
|
+
message: z.string(),
|
|
175
|
+
severity: z.nativeEnum(ValidationSeverity),
|
|
176
|
+
path: z.string().optional(),
|
|
177
|
+
expected: z.string().optional(),
|
|
178
|
+
actual: z.string().optional(),
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
export const agentManifestSchema = z.object({
|
|
182
|
+
agentId: z.string().min(1),
|
|
183
|
+
organization: z.string().optional(),
|
|
184
|
+
agentClass: z.string().optional(),
|
|
185
|
+
domains: z.array(z.string()).optional(),
|
|
186
|
+
capabilityLevel: z.number().int().min(0).max(7).optional(),
|
|
187
|
+
version: z.string().optional(),
|
|
188
|
+
trustScore: z.number().min(0).max(1000).optional(),
|
|
189
|
+
requestedCapabilities: z.array(z.string()).optional(),
|
|
190
|
+
metadata: z.record(z.unknown()).optional(),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
export const registeredProfileSchema = z.object({
|
|
194
|
+
agentId: z.string(),
|
|
195
|
+
organization: z.string(),
|
|
196
|
+
agentClass: z.string(),
|
|
197
|
+
approvedDomains: z.array(z.string()),
|
|
198
|
+
maxCapabilityLevel: z.number().int().min(0).max(7),
|
|
199
|
+
approvedCapabilities: z.array(z.string()),
|
|
200
|
+
trustScore: z.number().min(0).max(1000),
|
|
201
|
+
registeredAt: z.date(),
|
|
202
|
+
lastVerifiedAt: z.date().optional(),
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
export const validationGateResultSchema = z.object({
|
|
206
|
+
decision: z.nativeEnum(GateDecision),
|
|
207
|
+
valid: z.boolean(),
|
|
208
|
+
agentId: z.string(),
|
|
209
|
+
trustTier: z.nativeEnum(TrustTier).optional(),
|
|
210
|
+
trustScore: z.number().optional(),
|
|
211
|
+
issues: z.array(validationIssueSchema),
|
|
212
|
+
errors: z.array(validationIssueSchema),
|
|
213
|
+
warnings: z.array(validationIssueSchema),
|
|
214
|
+
validatedAt: z.date(),
|
|
215
|
+
durationMs: z.number(),
|
|
216
|
+
allowedCapabilities: z.array(z.string()).optional(),
|
|
217
|
+
deniedCapabilities: z.array(z.string()).optional(),
|
|
218
|
+
recommendations: z.array(z.string()).optional(),
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// =============================================================================
|
|
222
|
+
// HELPER FUNCTIONS
|
|
223
|
+
// =============================================================================
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Convert trust score to trust tier
|
|
227
|
+
*/
|
|
228
|
+
export function scoreToTier(score: number): TrustTier {
|
|
229
|
+
// Iterate through tiers in reverse order (highest first)
|
|
230
|
+
const tiers = [
|
|
231
|
+
TrustTier.T7_AUTONOMOUS,
|
|
232
|
+
TrustTier.T6_CERTIFIED,
|
|
233
|
+
TrustTier.T5_TRUSTED,
|
|
234
|
+
TrustTier.T4_OPERATIONAL,
|
|
235
|
+
TrustTier.T3_VERIFIED,
|
|
236
|
+
TrustTier.T2_PROVISIONAL,
|
|
237
|
+
TrustTier.T1_OBSERVED,
|
|
238
|
+
TrustTier.T0_SANDBOX,
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
for (const tier of tiers) {
|
|
242
|
+
const thresholds = TIER_THRESHOLDS[tier];
|
|
243
|
+
if (score >= thresholds.min && score <= thresholds.max) {
|
|
244
|
+
return tier;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return TrustTier.T0_SANDBOX;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Validate CAR string format
|
|
252
|
+
*/
|
|
253
|
+
function validateCARFormat(agentId: string | undefined): ValidationIssue[] {
|
|
254
|
+
const issues: ValidationIssue[] = [];
|
|
255
|
+
|
|
256
|
+
// Handle undefined/empty agentId
|
|
257
|
+
if (!agentId) {
|
|
258
|
+
issues.push({
|
|
259
|
+
code: 'MISSING_AGENT_ID',
|
|
260
|
+
message: 'Agent ID is required',
|
|
261
|
+
severity: ValidationSeverity.ERROR,
|
|
262
|
+
path: 'agentId',
|
|
263
|
+
});
|
|
264
|
+
return issues;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Basic CAR format: registry.org.class:DOMAINS-Ln@version
|
|
268
|
+
const carRegex = /^([a-z0-9]+)\.([a-z0-9-]+)\.([a-z0-9-]+):([A-Z]+)-L([0-7])@(\d+\.\d+\.\d+)(?:#[a-z0-9,_-]+)?$/;
|
|
269
|
+
|
|
270
|
+
if (!carRegex.test(agentId)) {
|
|
271
|
+
// Check if it looks like a legacy format or just an ID
|
|
272
|
+
if (agentId.includes(':') && agentId.includes('@')) {
|
|
273
|
+
issues.push({
|
|
274
|
+
code: 'INVALID_CAR_FORMAT',
|
|
275
|
+
message: 'CAR string format is invalid',
|
|
276
|
+
severity: ValidationSeverity.ERROR,
|
|
277
|
+
path: 'agentId',
|
|
278
|
+
expected: 'registry.org.class:DOMAINS-Ln@x.y.z',
|
|
279
|
+
actual: agentId,
|
|
280
|
+
});
|
|
281
|
+
} else if (!agentId.includes('.')) {
|
|
282
|
+
// Simple ID format - acceptable but noted
|
|
283
|
+
issues.push({
|
|
284
|
+
code: 'SIMPLE_ID_FORMAT',
|
|
285
|
+
message: 'Agent uses simple ID format instead of full CAR string',
|
|
286
|
+
severity: ValidationSeverity.INFO,
|
|
287
|
+
path: 'agentId',
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return issues;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Validate manifest against registered profile
|
|
297
|
+
*/
|
|
298
|
+
function validateAgainstProfile(
|
|
299
|
+
manifest: AgentManifest,
|
|
300
|
+
profile: RegisteredProfile
|
|
301
|
+
): ValidationIssue[] {
|
|
302
|
+
const issues: ValidationIssue[] = [];
|
|
303
|
+
|
|
304
|
+
// Check organization match
|
|
305
|
+
if (manifest.organization && manifest.organization !== profile.organization) {
|
|
306
|
+
issues.push({
|
|
307
|
+
code: 'ORG_MISMATCH',
|
|
308
|
+
message: 'Organization does not match registered profile',
|
|
309
|
+
severity: ValidationSeverity.ERROR,
|
|
310
|
+
path: 'organization',
|
|
311
|
+
expected: profile.organization,
|
|
312
|
+
actual: manifest.organization,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Check agent class match
|
|
317
|
+
if (manifest.agentClass && manifest.agentClass !== profile.agentClass) {
|
|
318
|
+
issues.push({
|
|
319
|
+
code: 'CLASS_MISMATCH',
|
|
320
|
+
message: 'Agent class does not match registered profile',
|
|
321
|
+
severity: ValidationSeverity.ERROR,
|
|
322
|
+
path: 'agentClass',
|
|
323
|
+
expected: profile.agentClass,
|
|
324
|
+
actual: manifest.agentClass,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Check capability level
|
|
329
|
+
if (manifest.capabilityLevel !== undefined) {
|
|
330
|
+
if (manifest.capabilityLevel > profile.maxCapabilityLevel) {
|
|
331
|
+
issues.push({
|
|
332
|
+
code: 'CAPABILITY_LEVEL_EXCEEDED',
|
|
333
|
+
message: 'Claimed capability level exceeds registered maximum',
|
|
334
|
+
severity: ValidationSeverity.ERROR,
|
|
335
|
+
path: 'capabilityLevel',
|
|
336
|
+
expected: `<= ${profile.maxCapabilityLevel}`,
|
|
337
|
+
actual: String(manifest.capabilityLevel),
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Check domains
|
|
343
|
+
if (manifest.domains) {
|
|
344
|
+
const unauthorizedDomains = manifest.domains.filter(
|
|
345
|
+
(d) => !profile.approvedDomains.includes(d)
|
|
346
|
+
);
|
|
347
|
+
if (unauthorizedDomains.length > 0) {
|
|
348
|
+
issues.push({
|
|
349
|
+
code: 'UNAUTHORIZED_DOMAINS',
|
|
350
|
+
message: `Agent claims unauthorized domains: ${unauthorizedDomains.join(', ')}`,
|
|
351
|
+
severity: ValidationSeverity.ERROR,
|
|
352
|
+
path: 'domains',
|
|
353
|
+
expected: profile.approvedDomains.join(', '),
|
|
354
|
+
actual: manifest.domains.join(', '),
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Check requested capabilities
|
|
360
|
+
if (manifest.requestedCapabilities) {
|
|
361
|
+
const unauthorizedCaps = manifest.requestedCapabilities.filter(
|
|
362
|
+
(c) => !profile.approvedCapabilities.includes(c)
|
|
363
|
+
);
|
|
364
|
+
if (unauthorizedCaps.length > 0) {
|
|
365
|
+
issues.push({
|
|
366
|
+
code: 'UNAUTHORIZED_CAPABILITIES',
|
|
367
|
+
message: `Agent requests unauthorized capabilities: ${unauthorizedCaps.join(', ')}`,
|
|
368
|
+
severity: ValidationSeverity.WARNING,
|
|
369
|
+
path: 'requestedCapabilities',
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return issues;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Validate trust tier requirements
|
|
379
|
+
*/
|
|
380
|
+
function validateTrustTier(
|
|
381
|
+
manifest: AgentManifest,
|
|
382
|
+
minimumTier?: TrustTier
|
|
383
|
+
): ValidationIssue[] {
|
|
384
|
+
const issues: ValidationIssue[] = [];
|
|
385
|
+
|
|
386
|
+
if (manifest.trustScore === undefined) {
|
|
387
|
+
issues.push({
|
|
388
|
+
code: 'MISSING_TRUST_SCORE',
|
|
389
|
+
message: 'Agent manifest does not include trust score',
|
|
390
|
+
severity: ValidationSeverity.WARNING,
|
|
391
|
+
path: 'trustScore',
|
|
392
|
+
});
|
|
393
|
+
return issues;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const agentTier = scoreToTier(manifest.trustScore);
|
|
397
|
+
|
|
398
|
+
if (minimumTier !== undefined) {
|
|
399
|
+
// Compare numeric tier values directly (TrustTier is a numeric enum 0-7)
|
|
400
|
+
if (agentTier < minimumTier) {
|
|
401
|
+
issues.push({
|
|
402
|
+
code: 'INSUFFICIENT_TRUST_TIER',
|
|
403
|
+
message: `Agent trust tier T${agentTier} is below minimum required T${minimumTier}`,
|
|
404
|
+
severity: ValidationSeverity.ERROR,
|
|
405
|
+
path: 'trustScore',
|
|
406
|
+
expected: `>= T${minimumTier}`,
|
|
407
|
+
actual: `T${agentTier}`,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return issues;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Validate requested capabilities against trust tier
|
|
417
|
+
*/
|
|
418
|
+
function validateCapabilitiesAgainstTier(
|
|
419
|
+
manifest: AgentManifest
|
|
420
|
+
): { issues: ValidationIssue[]; allowed: string[]; denied: string[] } {
|
|
421
|
+
const issues: ValidationIssue[] = [];
|
|
422
|
+
const allowed: string[] = [];
|
|
423
|
+
const denied: string[] = [];
|
|
424
|
+
|
|
425
|
+
if (!manifest.requestedCapabilities || manifest.requestedCapabilities.length === 0) {
|
|
426
|
+
return { issues, allowed, denied };
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const trustScore = manifest.trustScore ?? 0;
|
|
430
|
+
const agentTier = scoreToTier(trustScore);
|
|
431
|
+
|
|
432
|
+
for (const capability of manifest.requestedCapabilities) {
|
|
433
|
+
if (hasCapability(agentTier, capability)) {
|
|
434
|
+
allowed.push(capability);
|
|
435
|
+
} else {
|
|
436
|
+
denied.push(capability);
|
|
437
|
+
issues.push({
|
|
438
|
+
code: 'CAPABILITY_TIER_INSUFFICIENT',
|
|
439
|
+
message: `Capability ${capability} requires higher trust tier than ${agentTier}`,
|
|
440
|
+
severity: ValidationSeverity.WARNING,
|
|
441
|
+
path: 'requestedCapabilities',
|
|
442
|
+
actual: capability,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return { issues, allowed, denied };
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// =============================================================================
|
|
451
|
+
// MAIN VALIDATION GATE
|
|
452
|
+
// =============================================================================
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* BASIS Validation Gate
|
|
456
|
+
*
|
|
457
|
+
* Validates an agent manifest and returns a PASS/REJECT/ESCALATE decision.
|
|
458
|
+
*
|
|
459
|
+
* @param manifest - Agent manifest to validate
|
|
460
|
+
* @param profile - Optional registered profile for comparison
|
|
461
|
+
* @param options - Validation options
|
|
462
|
+
* @returns Validation result with decision
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* ```typescript
|
|
466
|
+
* const result = validateAgent({
|
|
467
|
+
* agentId: 'a3i.acme-corp.invoice-bot:ABF-L3@1.0.0',
|
|
468
|
+
* trustScore: 450,
|
|
469
|
+
* requestedCapabilities: ['CAP-DB-READ', 'CAP-WRITE-APPROVED'],
|
|
470
|
+
* });
|
|
471
|
+
*
|
|
472
|
+
* if (result.decision === GateDecision.PASS) {
|
|
473
|
+
* // Proceed to Layer 2 (INTENT)
|
|
474
|
+
* } else if (result.decision === GateDecision.REJECT) {
|
|
475
|
+
* // Block execution, log reasons
|
|
476
|
+
* console.log('Rejected:', result.errors);
|
|
477
|
+
* }
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
export function validateAgent(
|
|
481
|
+
manifest: AgentManifest,
|
|
482
|
+
profile?: RegisteredProfile,
|
|
483
|
+
options: ValidationGateOptions = {}
|
|
484
|
+
): ValidationGateResult {
|
|
485
|
+
const startTime = Date.now();
|
|
486
|
+
const issues: ValidationIssue[] = [];
|
|
487
|
+
|
|
488
|
+
// 1. Validate manifest schema
|
|
489
|
+
const schemaResult = agentManifestSchema.safeParse(manifest);
|
|
490
|
+
if (!schemaResult.success) {
|
|
491
|
+
for (const error of schemaResult.error.errors) {
|
|
492
|
+
issues.push({
|
|
493
|
+
code: 'SCHEMA_VALIDATION_FAILED',
|
|
494
|
+
message: error.message,
|
|
495
|
+
severity: ValidationSeverity.ERROR,
|
|
496
|
+
path: error.path.join('.'),
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// 2. Validate CAR format (handles undefined agentId)
|
|
502
|
+
const carIssues = validateCARFormat(manifest.agentId);
|
|
503
|
+
issues.push(...carIssues);
|
|
504
|
+
|
|
505
|
+
// If agentId is missing, short-circuit with early rejection
|
|
506
|
+
if (carIssues.some(i => i.code === 'MISSING_AGENT_ID')) {
|
|
507
|
+
return {
|
|
508
|
+
decision: GateDecision.REJECT,
|
|
509
|
+
valid: false,
|
|
510
|
+
agentId: manifest.agentId ?? 'unknown',
|
|
511
|
+
issues,
|
|
512
|
+
errors: issues.filter(i => i.severity === ValidationSeverity.ERROR || i.severity === ValidationSeverity.CRITICAL),
|
|
513
|
+
warnings: issues.filter(i => i.severity === ValidationSeverity.WARNING),
|
|
514
|
+
validatedAt: new Date(),
|
|
515
|
+
durationMs: Date.now() - startTime,
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// 3. Validate against registered profile
|
|
520
|
+
if (profile) {
|
|
521
|
+
issues.push(...validateAgainstProfile(manifest, profile));
|
|
522
|
+
} else if (options.requireRegisteredProfile) {
|
|
523
|
+
issues.push({
|
|
524
|
+
code: 'PROFILE_NOT_FOUND',
|
|
525
|
+
message: 'Agent must have a registered profile',
|
|
526
|
+
severity: ValidationSeverity.ERROR,
|
|
527
|
+
path: 'agentId',
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// 4. Validate trust tier requirements
|
|
532
|
+
issues.push(...validateTrustTier(manifest, options.minimumTrustTier));
|
|
533
|
+
|
|
534
|
+
// 5. Validate required domains
|
|
535
|
+
if (options.requiredDomains && options.requiredDomains.length > 0) {
|
|
536
|
+
const agentDomains = manifest.domains || [];
|
|
537
|
+
const missingDomains = options.requiredDomains.filter(
|
|
538
|
+
(d) => !agentDomains.includes(d)
|
|
539
|
+
);
|
|
540
|
+
if (missingDomains.length > 0) {
|
|
541
|
+
issues.push({
|
|
542
|
+
code: 'MISSING_REQUIRED_DOMAINS',
|
|
543
|
+
message: `Agent missing required domains: ${missingDomains.join(', ')}`,
|
|
544
|
+
severity: ValidationSeverity.ERROR,
|
|
545
|
+
path: 'domains',
|
|
546
|
+
expected: options.requiredDomains.join(', '),
|
|
547
|
+
actual: agentDomains.join(', ') || 'none',
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// 6. Validate capabilities against trust tier
|
|
553
|
+
const capValidation = validateCapabilitiesAgainstTier(manifest);
|
|
554
|
+
issues.push(...capValidation.issues);
|
|
555
|
+
|
|
556
|
+
// 7. Run custom validators
|
|
557
|
+
if (options.customValidators) {
|
|
558
|
+
for (const validator of options.customValidators) {
|
|
559
|
+
try {
|
|
560
|
+
issues.push(...validator(manifest, profile));
|
|
561
|
+
} catch (e) {
|
|
562
|
+
issues.push({
|
|
563
|
+
code: 'CUSTOM_VALIDATOR_ERROR',
|
|
564
|
+
message: `Custom validator failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
565
|
+
severity: ValidationSeverity.WARNING,
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Separate errors and warnings
|
|
572
|
+
const errors = issues.filter(
|
|
573
|
+
(i) => i.severity === ValidationSeverity.ERROR || i.severity === ValidationSeverity.CRITICAL
|
|
574
|
+
);
|
|
575
|
+
const warnings = issues.filter((i) => i.severity === ValidationSeverity.WARNING);
|
|
576
|
+
|
|
577
|
+
// Determine decision
|
|
578
|
+
let decision: GateDecision;
|
|
579
|
+
let valid: boolean;
|
|
580
|
+
|
|
581
|
+
const hasCritical = issues.some((i) => i.severity === ValidationSeverity.CRITICAL);
|
|
582
|
+
const hasErrors = errors.length > 0;
|
|
583
|
+
const hasWarnings = warnings.length > 0;
|
|
584
|
+
|
|
585
|
+
if (hasCritical || hasErrors) {
|
|
586
|
+
decision = GateDecision.REJECT;
|
|
587
|
+
valid = false;
|
|
588
|
+
} else if (options.strict && hasWarnings) {
|
|
589
|
+
decision = GateDecision.REJECT;
|
|
590
|
+
valid = false;
|
|
591
|
+
} else if (!options.strict && hasWarnings && capValidation.denied.length > 0) {
|
|
592
|
+
// Agent wants capabilities they can't have - escalate for review
|
|
593
|
+
decision = options.allowCapabilityEscalation ? GateDecision.ESCALATE : GateDecision.REJECT;
|
|
594
|
+
valid = decision === GateDecision.ESCALATE;
|
|
595
|
+
} else {
|
|
596
|
+
decision = GateDecision.PASS;
|
|
597
|
+
valid = true;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Build recommendations
|
|
601
|
+
const recommendations: string[] = [];
|
|
602
|
+
if (capValidation.denied.length > 0) {
|
|
603
|
+
recommendations.push(
|
|
604
|
+
`Increase trust score to access denied capabilities: ${capValidation.denied.join(', ')}`
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
if (!profile && !options.requireRegisteredProfile) {
|
|
608
|
+
recommendations.push('Consider registering agent profile for enhanced validation');
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Calculate trust tier
|
|
612
|
+
const trustTier = manifest.trustScore !== undefined ? scoreToTier(manifest.trustScore) : undefined;
|
|
613
|
+
|
|
614
|
+
return {
|
|
615
|
+
decision,
|
|
616
|
+
valid,
|
|
617
|
+
agentId: manifest.agentId,
|
|
618
|
+
trustTier,
|
|
619
|
+
trustScore: manifest.trustScore,
|
|
620
|
+
issues,
|
|
621
|
+
errors,
|
|
622
|
+
warnings,
|
|
623
|
+
validatedAt: new Date(),
|
|
624
|
+
durationMs: Date.now() - startTime,
|
|
625
|
+
allowedCapabilities: capValidation.allowed.length > 0 ? capValidation.allowed : undefined,
|
|
626
|
+
deniedCapabilities: capValidation.denied.length > 0 ? capValidation.denied : undefined,
|
|
627
|
+
recommendations: recommendations.length > 0 ? recommendations : undefined,
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Quick validation check - returns boolean
|
|
633
|
+
*/
|
|
634
|
+
export function isValidAgent(
|
|
635
|
+
manifest: AgentManifest,
|
|
636
|
+
profile?: RegisteredProfile,
|
|
637
|
+
options?: ValidationGateOptions
|
|
638
|
+
): boolean {
|
|
639
|
+
return validateAgent(manifest, profile, options).valid;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Create a validation gate with preset options
|
|
644
|
+
*/
|
|
645
|
+
export function createValidationGate(defaultOptions: ValidationGateOptions) {
|
|
646
|
+
return {
|
|
647
|
+
validate: (manifest: AgentManifest, profile?: RegisteredProfile, options?: ValidationGateOptions) =>
|
|
648
|
+
validateAgent(manifest, profile, { ...defaultOptions, ...options }),
|
|
649
|
+
isValid: (manifest: AgentManifest, profile?: RegisteredProfile, options?: ValidationGateOptions) =>
|
|
650
|
+
isValidAgent(manifest, profile, { ...defaultOptions, ...options }),
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Strict validation gate - treats warnings as errors
|
|
656
|
+
*/
|
|
657
|
+
export const strictValidationGate = createValidationGate({ strict: true });
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Production validation gate - requires registered profile
|
|
661
|
+
*/
|
|
662
|
+
export const productionValidationGate = createValidationGate({
|
|
663
|
+
requireRegisteredProfile: true,
|
|
664
|
+
minimumTrustTier: TrustTier.T2_PROVISIONAL,
|
|
665
|
+
});
|