@unrdf/hooks 26.4.3 → 26.4.4

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.
Files changed (56) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +562 -53
  3. package/examples/atomvm-fibo-hooks-demo.mjs +323 -0
  4. package/examples/delta-monitoring-example.mjs +213 -0
  5. package/examples/fibo-jtbd-governance.mjs +388 -0
  6. package/examples/hook-chains/node_modules/.bin/jiti +0 -0
  7. package/examples/hook-chains/node_modules/.bin/msw +0 -0
  8. package/examples/hook-chains/node_modules/.bin/terser +0 -0
  9. package/examples/hook-chains/node_modules/.bin/tsc +0 -0
  10. package/examples/hook-chains/node_modules/.bin/tsserver +0 -0
  11. package/examples/hook-chains/node_modules/.bin/tsx +0 -0
  12. package/examples/hook-chains/node_modules/.bin/validate-hooks +0 -0
  13. package/examples/hook-chains/node_modules/.bin/vite +0 -0
  14. package/examples/hook-chains/node_modules/.bin/vitest +0 -0
  15. package/examples/hook-chains/node_modules/.bin/yaml +0 -0
  16. package/examples/hooks-marketplace.mjs +261 -0
  17. package/examples/n3-reasoning-example.mjs +279 -0
  18. package/examples/policy-hooks/node_modules/.bin/jiti +0 -0
  19. package/examples/policy-hooks/node_modules/.bin/msw +0 -0
  20. package/examples/policy-hooks/node_modules/.bin/terser +0 -0
  21. package/examples/policy-hooks/node_modules/.bin/tsc +0 -0
  22. package/examples/policy-hooks/node_modules/.bin/tsserver +0 -0
  23. package/examples/policy-hooks/node_modules/.bin/tsx +0 -0
  24. package/examples/policy-hooks/node_modules/.bin/validate-hooks +0 -0
  25. package/examples/policy-hooks/node_modules/.bin/vite +0 -0
  26. package/examples/policy-hooks/node_modules/.bin/vitest +0 -0
  27. package/examples/policy-hooks/node_modules/.bin/yaml +0 -0
  28. package/examples/shacl-repair-example.mjs +191 -0
  29. package/examples/window-condition-example.mjs +285 -0
  30. package/package.json +26 -23
  31. package/src/atomvm.mjs +9 -0
  32. package/src/define.mjs +114 -0
  33. package/src/executor.mjs +23 -0
  34. package/src/hooks/atomvm-bridge.mjs +332 -0
  35. package/src/hooks/builtin-hooks.mjs +13 -7
  36. package/src/hooks/condition-evaluator.mjs +684 -77
  37. package/src/hooks/define-hook.mjs +23 -23
  38. package/src/hooks/effect-executor.mjs +630 -0
  39. package/src/hooks/effect-sandbox.mjs +19 -9
  40. package/src/hooks/file-resolver.mjs +155 -1
  41. package/src/hooks/hook-chain-compiler.mjs +11 -1
  42. package/src/hooks/hook-executor.mjs +98 -73
  43. package/src/hooks/knowledge-hook-engine.mjs +133 -7
  44. package/src/hooks/ontology-learner.mjs +190 -0
  45. package/src/hooks/query.mjs +3 -3
  46. package/src/hooks/schemas.mjs +47 -3
  47. package/src/hooks/security/error-sanitizer.mjs +46 -24
  48. package/src/hooks/self-play-autonomics.mjs +423 -0
  49. package/src/hooks/telemetry.mjs +32 -9
  50. package/src/hooks/validate.mjs +100 -33
  51. package/src/index.mjs +2 -0
  52. package/src/lib/admit-hook.mjs +615 -0
  53. package/src/policy-compiler.mjs +12 -2
  54. package/dist/index.d.mts +0 -1738
  55. package/dist/index.d.ts +0 -1738
  56. package/dist/index.mjs +0 -1738
@@ -0,0 +1,279 @@
1
+ /**
2
+ * @unrdf/hooks - N3 Forward-Chaining Reasoning Example
3
+ *
4
+ * Demonstrates semantic inference using N3 rules and EYE reasoner.
5
+ * Derives new facts from existing data through logical rules.
6
+ *
7
+ * Use cases:
8
+ * - RDFS/OWL-like reasoning (class hierarchies, property inference)
9
+ * - Business rule execution (access control, workflow logic)
10
+ * - Data enrichment (derive properties from rules)
11
+ * - Compliance checking (derive compliance status)
12
+ */
13
+
14
+ import { createStore } from '@unrdf/oxigraph';
15
+ import { evaluateCondition } from '../src/hooks/condition-evaluator.mjs';
16
+ import { UnrdfDataFactory as DataFactory } from '@unrdf/core/rdf/n3-justified-only';
17
+
18
+ const { namedNode, literal, quad } = DataFactory;
19
+
20
+ console.log('=== N3 Forward-Chaining Reasoning Example ===\n');
21
+
22
+ // Example 1: Simple class inheritance
23
+ console.log('1. Simple Class Inheritance\n');
24
+
25
+ const classInheritanceCondition = {
26
+ kind: 'n3',
27
+ rules: `
28
+ @prefix : <http://example.org/> .
29
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
30
+
31
+ # Rule: If X is subclass of Y and Z is instance of X, then Z is instance of Y
32
+ { ?x rdfs:subClassOf ?y . ?z a ?x } => { ?z a ?y } .
33
+ `,
34
+ askQuery: 'ASK { ?s a <http://example.org/Animal> }'
35
+ };
36
+
37
+ console.log('Rules:');
38
+ console.log(classInheritanceCondition.rules);
39
+ console.log('');
40
+ console.log('Scenario:');
41
+ console.log(' Data: Dog subClassOf Animal, Fido a Dog');
42
+ console.log(' Inference: Fido a Animal (derived)');
43
+ console.log(' Query: ASK { ?s a Animal } → true\n');
44
+
45
+ // Example 2: Access control reasoning
46
+ console.log('2. Access Control Reasoning\n');
47
+
48
+ const accessControlCondition = {
49
+ kind: 'n3',
50
+ rules: `
51
+ @prefix : <http://example.org/> .
52
+
53
+ # Rule 1: Admins can access everything
54
+ { ?user a :Admin } => { ?user :canAccess :SecureArea } .
55
+
56
+ # Rule 2: Group members inherit group permissions
57
+ { ?user :isMemberOf ?group . ?group :hasPermission ?perm }
58
+ => { ?user :hasPermission ?perm } .
59
+
60
+ # Rule 3: Users with edit permission need audit logging
61
+ { ?user :hasPermission :EditContent }
62
+ => { ?user :requiresAuditLog true } .
63
+
64
+ # Rule 4: Audit logging required if accessing secure area
65
+ { ?user :canAccess :SecureArea }
66
+ => { ?user :requiresAuditLog true } .
67
+ `,
68
+ askQuery: 'ASK { ?user :requiresAuditLog true }'
69
+ };
70
+
71
+ console.log('Rules demonstrate multi-level inference:');
72
+ console.log(' Rule 1: Admin role → access permission');
73
+ console.log(' Rule 2: Group membership → inherit permissions');
74
+ console.log(' Rule 3: Edit permission → audit requirement');
75
+ console.log(' Rule 4: Secure access → audit requirement');
76
+ console.log('');
77
+ console.log('Scenario:');
78
+ console.log(' Data: alice a Admin, bob :isMemberOf :editors');
79
+ console.log(' Step 1: alice a Admin → alice :canAccess :SecureArea');
80
+ console.log(' Step 2: alice :canAccess :SecureArea → alice :requiresAuditLog true');
81
+ console.log(' Step 3: bob :isMemberOf :editors → check group permissions');
82
+ console.log(' Result: Audit requirements derived from roles\n');
83
+
84
+ // Example 3: Business process workflow
85
+ console.log('3. Business Process Workflow Reasoning\n');
86
+
87
+ const workflowCondition = {
88
+ kind: 'n3',
89
+ rules: `
90
+ @prefix : <http://example.org/> .
91
+
92
+ # Rule 1: Large trades require compliance review
93
+ { ?trade a :Trade ; :amount ?amt . ?amt > 1000000 }
94
+ => { ?trade :requiresCompliance true } .
95
+
96
+ # Rule 2: Compliance required trades need risk assessment
97
+ { ?trade :requiresCompliance true }
98
+ => { ?trade :requiresRiskAssessment true } .
99
+
100
+ # Rule 3: Risk assessment must be approved by senior reviewer
101
+ { ?trade :requiresRiskAssessment true }
102
+ => { ?trade :requiresApprovalLevel :Senior } .
103
+
104
+ # Rule 4: High-risk trades need compliance officer sign-off
105
+ { ?trade :riskLevel :High ; :requiresApprovalLevel :Senior }
106
+ => { ?trade :requiresComplianceOfficer true } .
107
+
108
+ # Rule 5: Anything needing compliance officer needs audit trail
109
+ { ?trade :requiresComplianceOfficer true }
110
+ => { ?trade :auditTrailRequired true } .
111
+ `,
112
+ askQuery: 'ASK { ?trade :auditTrailRequired true }'
113
+ };
114
+
115
+ console.log('Multi-step workflow rules:');
116
+ console.log(' Trade amount > $1M → requires compliance');
117
+ console.log(' Requires compliance → requires risk assessment');
118
+ console.log(' Requires risk assessment → requires senior approval');
119
+ console.log(' High risk + senior approval → needs compliance officer');
120
+ console.log(' Needs compliance officer → needs audit trail');
121
+ console.log('');
122
+ console.log('Execution:');
123
+ console.log(' Input: Trade with amount $1.5M');
124
+ console.log(' Derives: auditTrailRequired = true');
125
+ console.log(' Effect: Create audit record in system\n');
126
+
127
+ // Example 4: Data enrichment
128
+ console.log('4. Data Enrichment Through Reasoning\n');
129
+
130
+ const enrichmentCondition = {
131
+ kind: 'n3',
132
+ rules: `
133
+ @prefix : <http://example.org/> .
134
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
135
+
136
+ # Rule 1: Calculate age from birthDate
137
+ { ?person :birthDate ?birth }
138
+ => { ?person :age ?age } . # Would need SPARQL for real calculation
139
+
140
+ # Rule 2: Categorize by age
141
+ { ?person :age ?age . ?age > 65 }
142
+ => { ?person :category :Senior } .
143
+
144
+ { ?person :age ?age . ?age >= 18 . ?age <= 65 }
145
+ => { ?person :category :Adult } .
146
+
147
+ { ?person :age ?age . ?age < 18 }
148
+ => { ?person :category :Minor } .
149
+
150
+ # Rule 3: Seniors get special benefits
151
+ { ?person :category :Senior }
152
+ => { ?person :eligibleFor :SeniorDiscount } .
153
+
154
+ # Rule 4: Mark complete profiles
155
+ { ?person :name ?n ; :email ?e ; :category ?c }
156
+ => { ?person :profileComplete true } .
157
+ `,
158
+ askQuery: 'ASK { ?p :profileComplete true }'
159
+ };
160
+
161
+ console.log('Enrichment rules:');
162
+ console.log(' Birthdate → derive age');
163
+ console.log(' Age → categorize as Senior/Adult/Minor');
164
+ console.log(' Senior → eligible for discount');
165
+ console.log(' Complete profile (name + email + category) → mark as complete');
166
+ console.log('');
167
+ console.log('Input: Person with name, email, age');
168
+ console.log('Output: Category, discounts, completeness flag\n');
169
+
170
+ // Example 5: Compliance rule engine
171
+ console.log('5. Compliance Rule Engine\n');
172
+
173
+ const complianceCondition = {
174
+ kind: 'n3',
175
+ rules: `
176
+ @prefix : <http://example.org/> .
177
+
178
+ # GDPR Rules
179
+ { ?entity a :PersonalData ; :storedIn ?jurisdiction .
180
+ ?jurisdiction :region ?region . ?region != :EU }
181
+ => { ?entity :gdprViolation :DataResidency } .
182
+
183
+ # PCI-DSS Rules
184
+ { ?entity a :CardData ; :encryptionLevel ?level .
185
+ ?level < 256 }
186
+ => { ?entity :pciViolation :InsufficientEncryption } .
187
+
188
+ # SOX Rules (for public companies)
189
+ { ?company a :PublicCompany ;
190
+ :hasFinancialData ?data }
191
+ => { ?company :requiresSoxCompliance true } .
192
+
193
+ # Any violation → requires remediation
194
+ { ?entity :gdprViolation ?v } => { ?entity :requiresRemediation true } .
195
+ { ?entity :pciViolation ?v } => { ?entity :requiresRemediation true } .
196
+
197
+ # Mark non-compliant if has violations
198
+ { ?entity :requiresRemediation true }
199
+ => { ?entity :complianceStatus :NonCompliant } .
200
+ `,
201
+ askQuery: 'ASK { ?entity :complianceStatus :NonCompliant }'
202
+ };
203
+
204
+ console.log('Compliance engine checks:');
205
+ console.log(' GDPR: Personal data must be in EU jurisdiction');
206
+ console.log(' PCI-DSS: Card data must be 256-bit encrypted');
207
+ console.log(' SOX: Public companies must audit financial data');
208
+ console.log(' Any violation → mark non-compliant\n');
209
+
210
+ // Performance considerations
211
+ console.log('6. Performance Considerations\n');
212
+
213
+ console.log('Forward-chaining semantics:');
214
+ console.log(' - All applicable rules fire until fixpoint');
215
+ console.log(' - Derives all possible new facts');
216
+ console.log(' - Complete closure of logical consequences');
217
+ console.log('');
218
+ console.log('Performance factors:');
219
+ console.log(' 1. Rule count: More rules = more inference steps');
220
+ console.log(' 2. Data size: Large graphs = more match attempts');
221
+ console.log(' 3. Rule complexity: Join patterns in antecedents');
222
+ console.log(' 4. Iteration count: Fixpoint may require many passes');
223
+ console.log('');
224
+ console.log('Optimization tips:');
225
+ console.log(' ✓ Materialize frequently derived facts');
226
+ console.log(' ✓ Use specific patterns (avoid ?x ?p ?o)');
227
+ console.log(' ✓ Order rules: simple → complex');
228
+ console.log(' ✗ Avoid rules that derive rule premises');
229
+ console.log(' ✗ Don\'t use reasoning for high-frequency checks\n');
230
+
231
+ // Full hook example
232
+ console.log('7. Complete Hook with N3 Reasoning\n');
233
+
234
+ console.log(`
235
+ const dataEnrichmentHook = {
236
+ name: 'enriched-trade-data',
237
+
238
+ condition: {
239
+ kind: 'n3',
240
+ rules: \`
241
+ @prefix : <http://example.org/> .
242
+
243
+ { ?trade a :Trade ; :amount ?amt . ?amt > 500000 }
244
+ => { ?trade :largeTradeIndicator true } .
245
+
246
+ { ?trade :largeTradeIndicator true }
247
+ => { ?trade :requiresReview true } .
248
+
249
+ { ?trade :requiresReview true ; :counterparty ?cp }
250
+ => { ?cp :hadLargeTrade true } .
251
+ \`,
252
+ askQuery: 'ASK { ?t :requiresReview true }'
253
+ },
254
+
255
+ effects: [{
256
+ kind: 'sparql-construct',
257
+ query: \`
258
+ CONSTRUCT {
259
+ ?trade :reviewStatus ex:Pending ;
260
+ :derivedFrom ex:N3Rules ;
261
+ :timestamp ?now .
262
+ }
263
+ WHERE {
264
+ ?trade :requiresReview true .
265
+ BIND (NOW() as ?now)
266
+ }
267
+ \`
268
+ }]
269
+ };
270
+
271
+ Execution:
272
+ 1. Trade added with amount > $500K
273
+ 2. N3 reasoning: derives :requiresReview true
274
+ 3. Condition ASK: "is there a :requiresReview?" → true
275
+ 4. Effect executes: marks trade as pending review
276
+ 5. Counterparty flagged for trading pattern analysis
277
+ `);
278
+
279
+ console.log('\n=== Example Complete ===');
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,191 @@
1
+ /**
2
+ * @unrdf/hooks - SHACL Repair Mode Example
3
+ *
4
+ * Demonstrates SHACL validation with automatic repair.
5
+ * When validation fails, repair queries fix data, then re-validate.
6
+ *
7
+ * Use cases:
8
+ * - Auto-filling missing required properties with defaults
9
+ * - Normalizing invalid references
10
+ * - Fixing data quality issues automatically
11
+ */
12
+
13
+ import { createStore } from '@unrdf/oxigraph';
14
+ import { evaluateCondition } from '../src/hooks/condition-evaluator.mjs';
15
+ import { UnrdfDataFactory as DataFactory } from '@unrdf/core/rdf/n3-justified-only';
16
+
17
+ const { namedNode, literal, quad } = DataFactory;
18
+
19
+ console.log('=== SHACL Repair Mode Example ===\n');
20
+
21
+ // Create a test store
22
+ const store = createStore();
23
+
24
+ // Add test data (some valid, some missing required properties)
25
+ console.log('1. Loading test data...');
26
+ store.add(
27
+ quad(
28
+ namedNode('http://example.org/trade/t1'),
29
+ namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
30
+ namedNode('http://example.org/Trade')
31
+ )
32
+ );
33
+ store.add(
34
+ quad(
35
+ namedNode('http://example.org/trade/t1'),
36
+ namedNode('http://example.org/amount'),
37
+ literal('150000')
38
+ )
39
+ );
40
+ // Note: missing riskScore
41
+
42
+ store.add(
43
+ quad(
44
+ namedNode('http://example.org/trade/t2'),
45
+ namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
46
+ namedNode('http://example.org/Trade')
47
+ )
48
+ );
49
+ // Note: missing both amount and riskScore
50
+
51
+ console.log(` Loaded ${store.size} quads\n`);
52
+
53
+ // Define SHACL condition with repair query
54
+ console.log('2. Defining SHACL repair condition...\n');
55
+
56
+ const shaclRepairCondition = {
57
+ kind: 'shacl',
58
+ ref: {
59
+ uri: 'file:///shapes/trade-shape.ttl',
60
+ // Note: in production, provide actual sha256 hash
61
+ // sha256: 'abc123def456...'
62
+ },
63
+ enforcementMode: 'repair',
64
+ repairConstruct: `
65
+ # Fill in missing required properties with defaults
66
+ CONSTRUCT {
67
+ ?trade ex:riskScore ?defaultRisk ;
68
+ ex:amount ?defaultAmount ;
69
+ ex:status ex:Pending .
70
+ }
71
+ WHERE {
72
+ ?trade a ex:Trade .
73
+ OPTIONAL { ?trade ex:riskScore ?existing . }
74
+ OPTIONAL { ?trade ex:amount ?existingAmount . }
75
+ FILTER (!BOUND(?existing) || !BOUND(?existingAmount))
76
+ BIND (50 as ?defaultRisk)
77
+ BIND (0 as ?defaultAmount)
78
+ }
79
+ `
80
+ };
81
+
82
+ console.log('Repair CONSTRUCT query:');
83
+ console.log(shaclRepairCondition.repairConstruct);
84
+ console.log('');
85
+
86
+ // Example 1: Block mode (strictest - no repairs)
87
+ console.log('3. Example: Block Mode (no repairs)\n');
88
+ const blockCondition = {
89
+ ...shaclRepairCondition,
90
+ enforcementMode: 'block'
91
+ };
92
+
93
+ console.log('With block mode:');
94
+ console.log('- Validation failure = hook fails (false)');
95
+ console.log('- No automatic repair attempted');
96
+ console.log('- Application must handle fix separately\n');
97
+
98
+ // Example 2: Annotate mode (audit trail)
99
+ console.log('4. Example: Annotate Mode (logging)\n');
100
+ const annotateCondition = {
101
+ ...shaclRepairCondition,
102
+ enforcementMode: 'annotate'
103
+ };
104
+
105
+ console.log('With annotate mode:');
106
+ console.log('- Validation failure = add sh:ValidationResult triples');
107
+ console.log('- Returns true (permits operation)');
108
+ console.log('- Violations recorded in RDF for audit trail');
109
+ console.log('- Good for compliance tracking\n');
110
+
111
+ // Example 3: Repair mode (automatic fixing)
112
+ console.log('5. Example: Repair Mode (automatic fix)\n');
113
+ const repairCondition = {
114
+ ...shaclRepairCondition,
115
+ enforcementMode: 'repair'
116
+ };
117
+
118
+ console.log('With repair mode:');
119
+ console.log('- Validation failure = execute repairConstruct');
120
+ console.log('- Repair adds missing properties with defaults');
121
+ console.log('- Re-validates after repair');
122
+ console.log('- Returns success/failure of final validation\n');
123
+
124
+ // Example 4: Multi-phase repair strategy
125
+ console.log('6. Complex Example: Multi-Phase Repair\n');
126
+
127
+ const complexRepairCondition = {
128
+ kind: 'shacl',
129
+ ref: { uri: 'file:///shapes/comprehensive.ttl' },
130
+ enforcementMode: 'repair',
131
+ repairConstruct: `
132
+ PREFIX ex: <http://example.org/>
133
+ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
134
+
135
+ CONSTRUCT {
136
+ ?entity ex:status ex:Reviewed ;
137
+ ex:lastChecked ?now ;
138
+ ex:quality ?quality .
139
+ }
140
+ WHERE {
141
+ ?entity a ex:Entity .
142
+ BIND (NOW() as ?now)
143
+
144
+ # Quality assessment: calculate based on completeness
145
+ OPTIONAL { ?entity ex:description ?desc . }
146
+ OPTIONAL { ?entity ex:classification ?class . }
147
+ OPTIONAL { ?entity ex:owner ?owner . }
148
+
149
+ BIND (
150
+ IF(BOUND(?desc) && BOUND(?class) && BOUND(?owner),
151
+ "high",
152
+ "medium")
153
+ as ?quality
154
+ )
155
+ }
156
+ `
157
+ };
158
+
159
+ console.log('Multi-phase repair includes:');
160
+ console.log('1. Add status field if missing');
161
+ console.log('2. Record timestamp of check');
162
+ console.log('3. Calculate quality score based on available properties\n');
163
+
164
+ // Practical workflow
165
+ console.log('7. Practical Workflow\n');
166
+ console.log('Step 1: Data arrives (potentially with gaps)');
167
+ console.log('Step 2: evaluateCondition() with shacl/repair');
168
+ console.log('Step 3: If validation fails:');
169
+ console.log(' - Auto repair executes');
170
+ console.log(' - Missing properties filled with defaults');
171
+ console.log(' - Re-validation checks if repair succeeded');
172
+ console.log('Step 4: Result indicates success/failure');
173
+ console.log('Step 5: Application continues based on result\n');
174
+
175
+ // Best practices
176
+ console.log('8. Best Practices for Repair Mode\n');
177
+ console.log('✓ Use repair for:');
178
+ console.log(' - Filling optional properties with sensible defaults');
179
+ console.log(' - Normalizing data format (URI standardization)');
180
+ console.log(' - Adding audit/lifecycle properties');
181
+ console.log('');
182
+ console.log('✗ Avoid repair for:');
183
+ console.log(' - Changing core business data semantics');
184
+ console.log(' - Complex transformations (use effects instead)');
185
+ console.log(' - Expensive computations (will run on every violation)');
186
+ console.log('');
187
+ console.log('💡 Combine with effects:');
188
+ console.log(' 1. Condition: shacl/repair → auto-fix violations');
189
+ console.log(' 2. Effect: sparql-construct → apply business logic\n');
190
+
191
+ console.log('=== Example Complete ===');