evidential-protocol 1.0.0

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.
@@ -0,0 +1,184 @@
1
+ /**
2
+ * EP-1 Validation — enforces protocol rules on evidential responses.
3
+ */
4
+ import { CONFIDENCE_FLOORS, CLASS_STRENGTH, } from "./types.js";
5
+ /** Validate a single Evidence object. */
6
+ export function validateEvidence(evidence, path = "evidence") {
7
+ const errors = [];
8
+ // Class must be valid
9
+ if (!CONFIDENCE_FLOORS[evidence.class]) {
10
+ errors.push({
11
+ rule: "valid-class",
12
+ message: `Invalid evidence class: "${evidence.class}"`,
13
+ path,
14
+ severity: "error",
15
+ });
16
+ return errors;
17
+ }
18
+ // Confidence must meet class floor
19
+ const floor = CONFIDENCE_FLOORS[evidence.class];
20
+ if (evidence.confidence < floor) {
21
+ errors.push({
22
+ rule: "confidence-floor",
23
+ message: `Confidence ${evidence.confidence} below floor ${floor} for class "${evidence.class}"`,
24
+ path: `${path}.confidence`,
25
+ severity: "error",
26
+ });
27
+ }
28
+ // Confidence must be 0.0–1.0
29
+ if (evidence.confidence < 0 || evidence.confidence > 1) {
30
+ errors.push({
31
+ rule: "confidence-range",
32
+ message: `Confidence must be 0.0–1.0, got ${evidence.confidence}`,
33
+ path: `${path}.confidence`,
34
+ severity: "error",
35
+ });
36
+ }
37
+ // Source is required
38
+ if (!evidence.source || evidence.source.trim() === "") {
39
+ errors.push({
40
+ rule: "source-required",
41
+ message: "Evidence must have a source",
42
+ path: `${path}.source`,
43
+ severity: "error",
44
+ });
45
+ }
46
+ // Timestamp is required
47
+ if (!evidence.timestamp) {
48
+ errors.push({
49
+ rule: "timestamp-required",
50
+ message: "Evidence must have a timestamp",
51
+ path: `${path}.timestamp`,
52
+ severity: "error",
53
+ });
54
+ }
55
+ // Conjecture MUST have reasoning
56
+ if (evidence.class === "conjecture" && !evidence.reasoning) {
57
+ errors.push({
58
+ rule: "conjecture-reasoning",
59
+ message: "Conjecture class requires a reasoning field",
60
+ path: `${path}.reasoning`,
61
+ severity: "error",
62
+ });
63
+ }
64
+ // Direct evidence SHOULD have TTL
65
+ if (evidence.class === "direct" && !evidence.ttl) {
66
+ errors.push({
67
+ rule: "direct-ttl",
68
+ message: "Direct evidence should include TTL for degradation tracking",
69
+ path: `${path}.ttl`,
70
+ severity: "warning",
71
+ });
72
+ }
73
+ return errors;
74
+ }
75
+ /** Validate a single EvidentialClaim. */
76
+ export function validateClaim(claim, index) {
77
+ const errors = [];
78
+ const path = `claims[${index}]`;
79
+ if (!claim.claim || claim.claim.trim() === "") {
80
+ errors.push({
81
+ rule: "claim-text-required",
82
+ message: "Claim must have text",
83
+ path: `${path}.claim`,
84
+ severity: "error",
85
+ });
86
+ }
87
+ if (!claim.evidence) {
88
+ errors.push({
89
+ rule: "evidence-required",
90
+ message: "Every claim must have an evidence object",
91
+ path: `${path}.evidence`,
92
+ severity: "error",
93
+ });
94
+ return errors;
95
+ }
96
+ errors.push(...validateEvidence(claim.evidence, `${path}.evidence`));
97
+ return errors;
98
+ }
99
+ /** Validate a full EvidentialResponse. */
100
+ export function validateResponse(response) {
101
+ const all = [];
102
+ // Must have ep_version
103
+ if (response.ep_version !== "1.0") {
104
+ all.push({
105
+ rule: "version",
106
+ message: `Unsupported protocol version: "${response.ep_version}"`,
107
+ severity: "error",
108
+ });
109
+ }
110
+ // Must have producer
111
+ if (!response.producer || response.producer.trim() === "") {
112
+ all.push({
113
+ rule: "producer-required",
114
+ message: "Response must identify its producer",
115
+ path: "producer",
116
+ severity: "error",
117
+ });
118
+ }
119
+ // Must have at least one claim
120
+ if (!response.claims || response.claims.length === 0) {
121
+ all.push({
122
+ rule: "claims-required",
123
+ message: "Response must contain at least one claim",
124
+ path: "claims",
125
+ severity: "error",
126
+ });
127
+ }
128
+ else {
129
+ // Validate each claim
130
+ for (let i = 0; i < response.claims.length; i++) {
131
+ all.push(...validateClaim(response.claims[i], i));
132
+ }
133
+ // Verify aggregate_class is the lowest class
134
+ const lowestStrength = Math.min(...response.claims.map((c) => CLASS_STRENGTH[c.evidence.class]));
135
+ const expectedClass = Object.entries(CLASS_STRENGTH).find(([, v]) => v === lowestStrength)?.[0];
136
+ if (expectedClass && response.aggregate_class !== expectedClass) {
137
+ all.push({
138
+ rule: "aggregate-class-consistency",
139
+ message: `Aggregate class should be "${expectedClass}" (lowest), got "${response.aggregate_class}"`,
140
+ path: "aggregate_class",
141
+ severity: "error",
142
+ });
143
+ }
144
+ }
145
+ // Must have produced_at
146
+ if (!response.produced_at) {
147
+ all.push({
148
+ rule: "produced-at-required",
149
+ message: "Response must have produced_at timestamp",
150
+ path: "produced_at",
151
+ severity: "error",
152
+ });
153
+ }
154
+ const errors = all.filter((e) => e.severity === "error");
155
+ const warnings = all.filter((e) => e.severity === "warning");
156
+ return {
157
+ valid: errors.length === 0,
158
+ errors,
159
+ warnings,
160
+ };
161
+ }
162
+ /** Validate an MCP evidence tag. */
163
+ export function validateMcpTag(tag) {
164
+ const all = [];
165
+ if (tag.ep_version !== "1.0") {
166
+ all.push({
167
+ rule: "version",
168
+ message: `Unsupported version: "${tag.ep_version}"`,
169
+ severity: "error",
170
+ });
171
+ }
172
+ all.push(...validateEvidence({
173
+ class: tag.class,
174
+ confidence: tag.confidence,
175
+ source: tag.source,
176
+ timestamp: tag.timestamp,
177
+ ttl: tag.ttl,
178
+ reasoning: tag.reasoning,
179
+ }, "_evidence"));
180
+ const errors = all.filter((e) => e.severity === "error");
181
+ const warnings = all.filter((e) => e.severity === "warning");
182
+ return { valid: errors.length === 0, errors, warnings };
183
+ }
184
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "evidential-protocol",
3
+ "version": "1.0.0",
4
+ "description": "Matsés-inspired evidential metadata for AI agent outputs. Every claim declares how it knows.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "test": "node --test dist/tests/",
11
+ "lint": "tsc --noEmit",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "keywords": [
15
+ "evidential",
16
+ "ai-agents",
17
+ "mcp",
18
+ "trust",
19
+ "provenance",
20
+ "epistemic",
21
+ "matses"
22
+ ],
23
+ "author": "Matthew Karsten <MatthewKarstenConnects@gmail.com>",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/ExpertVagabond/evidential-protocol.git"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "schema"
32
+ ],
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ },
38
+ "./schema": {
39
+ "types": "./dist/schema.d.ts",
40
+ "import": "./dist/schema.js"
41
+ },
42
+ "./validate": {
43
+ "types": "./dist/validate.d.ts",
44
+ "import": "./dist/validate.js"
45
+ },
46
+ "./middleware": {
47
+ "types": "./dist/middleware.d.ts",
48
+ "import": "./dist/middleware.js"
49
+ }
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^25.5.0",
53
+ "typescript": "^5.9.3"
54
+ }
55
+ }
@@ -0,0 +1,94 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://psm.dev/schemas/evidential-response.schema.json",
4
+ "title": "EvidentialResponse",
5
+ "description": "EP-1 Evidential Protocol response. Every AI agent output must conform to this schema.",
6
+ "type": "object",
7
+ "required": ["ep_version", "data", "claims", "aggregate_class", "aggregate_confidence", "producer", "produced_at"],
8
+ "properties": {
9
+ "ep_version": {
10
+ "type": "string",
11
+ "const": "1.0",
12
+ "description": "Protocol version."
13
+ },
14
+ "data": {
15
+ "description": "The output payload (any shape)."
16
+ },
17
+ "claims": {
18
+ "type": "array",
19
+ "minItems": 1,
20
+ "items": { "$ref": "#/$defs/EvidentialClaim" },
21
+ "description": "All claims made in this response."
22
+ },
23
+ "aggregate_class": {
24
+ "$ref": "#/$defs/EvidenceClass",
25
+ "description": "Lowest evidence class among all claims."
26
+ },
27
+ "aggregate_confidence": {
28
+ "type": "number",
29
+ "minimum": 0,
30
+ "maximum": 1,
31
+ "description": "Weighted mean confidence across claims."
32
+ },
33
+ "producer": {
34
+ "type": "string",
35
+ "minLength": 1,
36
+ "description": "Agent or tool that produced this response."
37
+ },
38
+ "produced_at": {
39
+ "type": "string",
40
+ "format": "date-time",
41
+ "description": "ISO 8601 timestamp."
42
+ }
43
+ },
44
+ "$defs": {
45
+ "EvidenceClass": {
46
+ "type": "string",
47
+ "enum": ["direct", "inferred", "reported", "conjecture"]
48
+ },
49
+ "EvidenceSource": {
50
+ "type": "object",
51
+ "required": ["class", "source", "detail"],
52
+ "properties": {
53
+ "class": { "$ref": "#/$defs/EvidenceClass" },
54
+ "source": { "type": "string", "minLength": 1 },
55
+ "detail": { "type": "string" },
56
+ "timestamp": { "type": "string", "format": "date-time" }
57
+ }
58
+ },
59
+ "Evidence": {
60
+ "type": "object",
61
+ "required": ["class", "confidence", "source", "timestamp"],
62
+ "properties": {
63
+ "class": { "$ref": "#/$defs/EvidenceClass" },
64
+ "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
65
+ "source": { "type": "string", "minLength": 1 },
66
+ "reasoning": { "type": "string" },
67
+ "timestamp": { "type": "string", "format": "date-time" },
68
+ "ttl": { "type": "integer", "minimum": 0 },
69
+ "sources": {
70
+ "type": "array",
71
+ "items": { "$ref": "#/$defs/EvidenceSource" }
72
+ }
73
+ },
74
+ "if": {
75
+ "properties": { "class": { "const": "conjecture" } }
76
+ },
77
+ "then": {
78
+ "required": ["reasoning"]
79
+ }
80
+ },
81
+ "EvidentialClaim": {
82
+ "type": "object",
83
+ "required": ["claim", "evidence"],
84
+ "properties": {
85
+ "claim": { "type": "string", "minLength": 1 },
86
+ "evidence": { "$ref": "#/$defs/Evidence" },
87
+ "refs": {
88
+ "type": "array",
89
+ "items": { "type": "string" }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }