@dogfood-lab/verify 1.4.0 → 1.6.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.
@@ -27,23 +27,14 @@ import { validatePayload } from '@dogfood-lab/schemas';
27
27
  * @returns {{ valid: boolean, errors: string[] }}
28
28
  */
29
29
  export function validateSubmissionSchema(submission) {
30
- let result;
31
- try {
32
- result = validatePayload('recordSubmission', submission);
33
- } catch (e) {
34
- // The canonical compile path can throw at compileSchema time if the
35
- // schema file is unreadable or malformed (Ajv compile fault). Pre-H3
36
- // the corresponding fault was surfaced via a `{ __loadError }` sentinel
37
- // that the runValidator helper in verify/index.js never actually
38
- // routed through `VALIDATOR_FAULT_*` — `getValidator` returned a plain
39
- // object and the call site special-cased its `__loadError` key. The
40
- // post-H3 path is cleaner: a thrown error here propagates up to
41
- // runValidator which already wraps thrown validators in
42
- // `VALIDATOR_FAULT_SCHEMA` (D1B-003 humanization). Same operator-
43
- // facing prefix, just routed through the lawful seam instead of a
44
- // sentinel. No catch — propagate.
45
- throw e;
46
- }
30
+ // The canonical compile path can throw at compileSchema time if the schema
31
+ // file is unreadable or malformed (Ajv compile fault). We deliberately do
32
+ // NOT catch it here: a thrown error propagates up to runValidator in
33
+ // verify/index.js, which wraps thrown validators in `VALIDATOR_FAULT_SCHEMA`
34
+ // (D1B-003 humanization). Pre-H3 this fault was surfaced via a `{ __loadError }`
35
+ // sentinel the call site special-cased; routing the throw through the lawful
36
+ // runValidator seam yields the same operator-facing prefix without the sentinel.
37
+ const result = validatePayload('recordSubmission', submission);
47
38
 
48
39
  if (result.valid) {
49
40
  return { valid: true, errors: [] };
@@ -52,8 +52,12 @@ export function validateStepResults(scenarioResult) {
52
52
 
53
53
  // A scenario cannot be "pass" if any step is "fail" or "blocked"
54
54
  if (verdict === 'pass') {
55
+ // Guard `s != null` to match the two sibling loops above: a null element is
56
+ // already reported as malformed there, and dereferencing `s.status` here
57
+ // would throw a TypeError that runValidator misclassifies as an operational
58
+ // VALIDATOR_FAULT_STEPS instead of a submission-bad signal (verify-B-004).
55
59
  const failingSteps = step_results.filter(
56
- s => s.status === 'fail' || s.status === 'blocked'
60
+ s => s != null && (s.status === 'fail' || s.status === 'blocked')
57
61
  );
58
62
  if (failingSteps.length > 0) {
59
63
  const ids = failingSteps.map(s => s.step_id).join(', ');