Hitting Submit runs, in order:

  1. Static validation - the form's own required/min/max/regex rules.
  2. validate.js - cross-field validation. Stops here if it writes any error.
  3. process.js - decides which layout partials to include, and can prepare presentation data for blocks.
  4. Render - the assembled layout is drawn and saved to the shared output folder.
form values --> static validation --> validate.js --> process.js --> render --> PDF
                     |                     |
                 rejects with          rejects with
                 field errors          field/general errors

Nothing about a submission is saved anywhere except the generated PDF itself - the PDF is the record. A value process.js computes is baked into that PDF at generation time; editing the script later never changes a PDF already generated.

process.js alone is required - no fallback. A project missing it generates no blocks at all, just the blank canvas.

validate.js/process.js run in a sandboxed script engine with no network or filesystem access beyond reading the project's own layout partials, and are bounded by the Processing time limit setting - a script that runs long enough is stopped rather than left to hang the submission.