@o-lang/olang 1.1.1 → 1.1.2

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/runtime.js +23 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@o-lang/olang",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "author": "Olalekan Ogundipe <info@workfily.com>",
5
5
  "description": "O-Lang: A governance language for user-directed, rule-enforced agent workflows",
6
6
  "main": "./src/index.js",
package/src/runtime.js CHANGED
@@ -343,9 +343,8 @@ class RuntimeAPI {
343
343
  }
344
344
  };
345
345
 
346
+ // ✅ STRICT SAFETY: Updated runResolvers with failure halting
346
347
  const runResolvers = async (action) => {
347
- const outputs = [];
348
-
349
348
  const mathPattern =
350
349
  /^(Add|Subtract|Multiply|Divide|Sum|Avg|Min|Max|Round|Floor|Ceil|Abs)\b/i;
351
350
 
@@ -371,13 +370,13 @@ class RuntimeAPI {
371
370
  resolversToRun = [agentResolver];
372
371
  }
373
372
 
374
- // ✅ Return the FIRST resolver that returns a non-undefined result
373
+ // ✅ STRICT SAFETY: Fail fast on resolver errors or empty results
375
374
  for (let idx = 0; idx < resolversToRun.length; idx++) {
376
375
  const resolver = resolversToRun[idx];
377
- enforceResolverPolicy(resolver, step); // ✅ Use new policy enforcement
376
+ enforceResolverPolicy(resolver, step);
378
377
 
379
378
  try {
380
- let result; // ✅ ADDITION 4 — External Resolver Execution Path
379
+ let result;
381
380
 
382
381
  if (this._isExternalResolver(resolver)) {
383
382
  result = await this._callExternalResolver(
@@ -389,22 +388,32 @@ class RuntimeAPI {
389
388
  result = await resolver(action, this.context);
390
389
  }
391
390
 
392
- if (result !== undefined) {
393
- this.context[`__resolver_${idx}`] = result;
394
- return result;
391
+ // SAFETY GUARD 1: Reject undefined/null results
392
+ if (result === undefined || result === null) {
393
+ throw new Error(
394
+ `[O-Lang SAFETY] Resolver "${resolver.resolverName || resolver.name || 'anonymous'}" returned empty result for action: "${action}". ` +
395
+ `Workflow halted to prevent unsafe data propagation.`
396
+ );
395
397
  }
396
398
 
397
- outputs.push(result);
398
399
  this.context[`__resolver_${idx}`] = result;
400
+ return result;
401
+
399
402
  } catch (e) {
400
- this.addWarning(`Resolver ${resolver?.resolverName || resolver?.name || idx} failed for action "${action}": ${e.message}`);
401
- outputs.push(null);
402
- this.context[`__resolver_${idx}`] = null;
403
+ // SAFETY GUARD 2: HALT workflow immediately on resolver failure
404
+ throw new Error(
405
+ `[O-Lang SAFETY] Resolver "${resolver?.resolverName || resolver?.name || idx}" failed for action "${action}": ${e.message}\n` +
406
+ `Workflow execution halted.`
407
+ );
403
408
  }
404
409
  }
405
410
 
406
- // If no resolver handled the action, return undefined
407
- return undefined;
411
+ // SAFETY GUARD 3: No resolver handled the action HALT
412
+ throw new Error(
413
+ `[O-Lang SAFETY] No resolver handled action: "${action}". ` +
414
+ `Available resolvers: ${resolversToRun.map(r => r.resolverName || r.name || 'anonymous').join(', ')}. ` +
415
+ `Workflow execution halted.`
416
+ );
408
417
  };
409
418
 
410
419
  switch (stepType) {