Skip to content

Static Checks Gate ​

Spexso runs configurable static checks at two points in the workflow:

  1. Builder phase (per-task) — after Jest GREEN, before COMMIT. Runs on changed-files-only. Failures block the commit (3-strike rule, same as a failing test).
  2. Reviewer phase (per-issue) — full-project sweep. Failures surface as HIGH severity findings. No auto-rewrite — humans fix lint.

This closes the gap where non-Jest errors (UI5 XML namespace typos, broken i18n keys, manifest inconsistencies, broken CDS annotations) would otherwise reach runtime.

Configuration ​

In .spexso/config.json:

json
{
  "staticChecks": [
    "npx ui5lint {files}",
    "npx tsc --noEmit"
  ]
}
AspectValue
TypeArray of strings (shell commands)
Placeholder{files} — replaced with space-separated changed files at builder time; replaced with empty string at reviewer time
OrderSequential. First failure stops the chain (fail-fast).
Backwards compatibilityMissing key or empty array → step skipped silently

How {files} works ​

A command with the placeholder:

  • Builder phase: npx ui5lint app/admin/webapp/view/Plugins.view.xml (changed files only)
  • Reviewer phase: npx ui5lint (no args → full project)

A command without the placeholder runs identically in both phases (e.g. npx tsc --noEmit always sweeps the entire project).

UI5 linter — also an in-session MCP gate. The shell npx ui5lint above is the CI-runnable check. On top of it, the builder and reviewer run the run_ui5_linter tool from the ui5-mcp plugin in-session for UI5 diffs (see Agents → MCP-first & the UI5 linter gate). It's the same linter engine, but running it during the agent flow catches runtime-only defects (invalid aggregations, growing bindings missing $$operationMode: 'Server') before they reach the static-check stage or CI. npx ui5lint is the fallback when the plugin isn't installed.

Recipes per stack ​

StackSuggested staticChecks
CAP Node.js + UI5 Freestyle["npx ui5lint {files}", "npx tsc --noEmit", "npx cds compile srv --to json"]
CAP Node.js only (no UI)["npx tsc --noEmit", "npx cds compile srv --to json"]
CAP + Fiori Elements["npx ui5lint {files}", "npx tsc --noEmit", "npx cds compile srv --to json"]
React + CAP backend["npx tsc --noEmit", "npx cds compile srv --to json", "npx eslint {files}"]
Plain TypeScript library["npx tsc --noEmit", "npx eslint {files}"]
Build Work Zone HTML5["npx ui5lint {files}"]

How to configure ​

  • First-time setup: /spexso-setup detects relevant tools and proposes a starter list. Developer accepts/edits/skips.
  • Add a check later: /spexso-checks re-runs detection and proposes any missing entries. Use this when adding a new app type (e.g. first UI5 app in a previously CAP-only project).
  • Manual edit: edit .spexso/config.json directly. JSON-valid array of strings.

Behavior in detail ​

Builder phase (per task) ​

Position: between GREEN (tests pass) and COMMIT.

  • Read .spexso/config.json → staticChecks. Empty/missing → skip.
  • Compute changed files: git diff --name-only HEAD.
  • Substitute {files} placeholder per command.
  • Run sequentially. First non-zero exit → failure.
  • Failure → counts toward the 3-strike rule (same as a failing Jest test).
  • 4th attempt failure → pause, escalate to developer.

Reviewer phase (per issue) ​

Position: after the reviewer's existing diff-walk and severity classification.

  • Read same config.
  • Substitute {files} with empty string (full-project scope).
  • Run sequentially.
  • Failure → HIGH severity finding in the review.
  • No auto-rewrite — humans fix lint. This is the ONE exception to the reviewer's general auto-fix-on-HIGH behavior.

Builder post-commit nudge ​

After a successful task commit, the builder checks whether new file extensions appeared that aren't covered by any current staticChecks command. If so, it prints a one-line advisory:

💡 This task added .view.xml files but no static check covers them.
   Run /spexso-checks to add ui5lint to your config.

Advisory only — never blocks. Conservative heuristic; under-hinting preferred over false positives.

Out of scope ​

  • Spexso does not bundle any specific linter. Each project wires in its own tools.
  • Spexso never auto-fixes lint failures at builder phase. Failure → retry → escalate.
  • Reviewer-phase lint findings are explicitly not auto-rewritten (HIGH severity exception).
  • /spexso-checks — add/edit static checks at any time. See commands.
  • Add static check scenario — when you add a new UI5 app or other new file types.
  • TDD flow — where the static-checks gate fits in the per-task cycle.
  • Review flow — reviewer also runs static checks.