@criterionx/core 0.1.2 → 0.3.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.
- package/README.md +78 -47
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -1,69 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @criterionx/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Universal decision engine for business-critical decisions.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- **Deterministic evaluation** (same inputs → same result)
|
|
7
|
-
- **Explainability first-class** (every result has a reason + trace)
|
|
8
|
-
- **Zero side effects** (no DB, no fetch, no IO inside decisions)
|
|
5
|
+
## Installation
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Criterion is **not** a web framework and it does **not** fetch data.
|
|
15
|
-
It runs decisions against a provided **Context**.
|
|
7
|
+
```bash
|
|
8
|
+
npm install @criterionx/core zod
|
|
9
|
+
```
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Engine, defineDecision } from "@criterionx/core";
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
|
|
17
|
+
const riskDecision = defineDecision({
|
|
18
|
+
id: "transaction-risk",
|
|
19
|
+
version: "1.0.0",
|
|
20
|
+
inputSchema: z.object({ amount: z.number() }),
|
|
21
|
+
outputSchema: z.object({ risk: z.enum(["HIGH", "LOW"]) }),
|
|
22
|
+
profileSchema: z.object({ threshold: z.number() }),
|
|
23
|
+
rules: [
|
|
24
|
+
{
|
|
25
|
+
id: "high-risk",
|
|
26
|
+
when: (input, profile) => input.amount > profile.threshold,
|
|
27
|
+
emit: () => ({ risk: "HIGH" }),
|
|
28
|
+
explain: (input, profile) =>
|
|
29
|
+
`Amount ${input.amount} exceeds threshold ${profile.threshold}`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "low-risk",
|
|
33
|
+
when: () => true,
|
|
34
|
+
emit: () => ({ risk: "LOW" }),
|
|
35
|
+
explain: () => "Amount within acceptable range",
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const engine = new Engine();
|
|
41
|
+
const result = engine.run(
|
|
42
|
+
riskDecision,
|
|
43
|
+
{ amount: 15000 },
|
|
44
|
+
{ profile: { threshold: 10000 } }
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
console.log(result.data); // { risk: "HIGH" }
|
|
48
|
+
```
|
|
22
49
|
|
|
23
|
-
|
|
50
|
+
---
|
|
24
51
|
|
|
25
|
-
|
|
26
|
-
- a workflow/BPMN engine
|
|
27
|
-
- an enterprise rules platform
|
|
28
|
-
- a plugin marketplace
|
|
29
|
-
- a data pipeline
|
|
30
|
-
- a forecasting system
|
|
52
|
+
## Architectural Invariants
|
|
31
53
|
|
|
32
|
-
|
|
54
|
+
> **This package is HTTP-agnostic. It must never depend on server concerns.**
|
|
33
55
|
|
|
34
|
-
|
|
56
|
+
### Non-Negotiable Principles
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
1. **Pure and Deterministic**
|
|
59
|
+
- Same input + same profile = same output, always
|
|
60
|
+
- No hidden state, no side effects
|
|
37
61
|
|
|
38
|
-
|
|
62
|
+
2. **No I/O in Rules**
|
|
63
|
+
- Rules cannot fetch data
|
|
64
|
+
- Rules cannot make network calls
|
|
65
|
+
- Rules cannot read from filesystem
|
|
66
|
+
- All data must be passed in as context
|
|
39
67
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
68
|
+
3. **Explicit Dependencies**
|
|
69
|
+
- No auto-discovery
|
|
70
|
+
- No magic imports
|
|
71
|
+
- Decisions are explicitly passed to consumers
|
|
43
72
|
|
|
44
|
-
|
|
73
|
+
4. **Validation at Boundaries**
|
|
74
|
+
- Input validated via Zod schema
|
|
75
|
+
- Output validated via Zod schema
|
|
76
|
+
- Profile validated via Zod schema
|
|
45
77
|
|
|
46
|
-
|
|
78
|
+
5. **Explainability**
|
|
79
|
+
- Every rule has an `explain` function
|
|
80
|
+
- Every result includes full audit trace
|
|
47
81
|
|
|
48
|
-
|
|
49
|
-
- `examples/` — decision specs in declarative formats (no code required)
|
|
50
|
-
- `diagrams/` — Mermaid diagrams for architecture (optional early)
|
|
51
|
-
- `src/` — future minimal TS implementation (later)
|
|
82
|
+
### What This Package Does NOT Do
|
|
52
83
|
|
|
53
|
-
|
|
84
|
+
- HTTP/REST handling (use `@criterionx/server`)
|
|
85
|
+
- Database operations
|
|
86
|
+
- File system access
|
|
87
|
+
- Network requests
|
|
88
|
+
- Caching
|
|
89
|
+
- Authentication/Authorization
|
|
54
90
|
|
|
55
|
-
|
|
56
|
-
- `examples/finance/currency-exposure-risk/` — generic currency risk using profiles
|
|
91
|
+
This is intentional. The core is a knife, not a Swiss Army knife.
|
|
57
92
|
|
|
58
|
-
|
|
59
|
-
- `examples/eligibility/user-tier-eligibility/` — user tier eligibility decision
|
|
93
|
+
---
|
|
60
94
|
|
|
61
|
-
##
|
|
95
|
+
## Documentation
|
|
62
96
|
|
|
63
|
-
|
|
64
|
-
- `docs/04-decision-profiles.md`
|
|
65
|
-
- `examples/finance/currency-exposure-risk/decision.xml`
|
|
66
|
-
- `examples/eligibility/user-tier-eligibility/decision.xml`
|
|
97
|
+
Full documentation: [https://tomymaritano.github.io/criterionx/](https://tomymaritano.github.io/criterionx/)
|
|
67
98
|
|
|
68
99
|
## License
|
|
69
100
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@criterionx/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Universal decision engine for business-critical decisions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,14 +16,6 @@
|
|
|
16
16
|
"LICENSE",
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
21
|
-
"test": "vitest run",
|
|
22
|
-
"test:watch": "vitest",
|
|
23
|
-
"test:coverage": "vitest run --coverage",
|
|
24
|
-
"typecheck": "tsc --noEmit",
|
|
25
|
-
"prepublishOnly": "npm run build"
|
|
26
|
-
},
|
|
27
19
|
"keywords": [
|
|
28
20
|
"decision-engine",
|
|
29
21
|
"rules-engine",
|
|
@@ -42,12 +34,16 @@
|
|
|
42
34
|
"license": "MIT",
|
|
43
35
|
"repository": {
|
|
44
36
|
"type": "git",
|
|
45
|
-
"url": "https://github.com/tomymaritano/
|
|
37
|
+
"url": "https://github.com/tomymaritano/criterionx.git",
|
|
38
|
+
"directory": "packages/core"
|
|
46
39
|
},
|
|
47
40
|
"bugs": {
|
|
48
|
-
"url": "https://github.com/tomymaritano/
|
|
41
|
+
"url": "https://github.com/tomymaritano/criterionx/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/tomymaritano/criterionx#readme",
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"zod": "^3.22.0"
|
|
49
46
|
},
|
|
50
|
-
"homepage": "https://github.com/tomymaritano/criterion#readme",
|
|
51
47
|
"devDependencies": {
|
|
52
48
|
"@vitest/coverage-v8": "^2.0.0",
|
|
53
49
|
"tsup": "^8.0.0",
|
|
@@ -55,10 +51,14 @@
|
|
|
55
51
|
"vitest": "^2.0.0",
|
|
56
52
|
"zod": "^3.22.0"
|
|
57
53
|
},
|
|
58
|
-
"peerDependencies": {
|
|
59
|
-
"zod": "^3.22.0"
|
|
60
|
-
},
|
|
61
54
|
"engines": {
|
|
62
55
|
"node": ">=18"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
59
|
+
"test": "vitest run",
|
|
60
|
+
"test:watch": "vitest",
|
|
61
|
+
"test:coverage": "vitest run --coverage",
|
|
62
|
+
"typecheck": "tsc --noEmit"
|
|
63
63
|
}
|
|
64
|
-
}
|
|
64
|
+
}
|