VSA Monolith Framework

Rules & checks

Every rule exists because the defect in the right-hand column shipped once. This is the list, and vsa check --list prints it on your machine.

Terminal
vsa check                  # everything; exit 1 on any error
vsa check --only=dom-scope  # one rule
vsa check --strict          # warnings block too
vsa check --json            # for CI

The rules

RuleWhat it requiresWhat it caught
bundle-pathsBundle and style entries resolve to git-tracked files, exact caseA misspelled component file, an untracked CSS file
render-namesScriptManager::render('x') names a bundle that existsA bundle renamed in one place only
global-nameA page or dialog's file name matches the global it declaresA component whose file and global disagreed
declarationsNo duplicate top-level names per shell, and no implicit globalsA dialog assigned without a declaration; clearTimeout shadowed
globals-existEvery PascalCase global a file uses is provided by its shellDialogs and list views that were never loaded on the page using them
page-leafNothing outside a page references that page's globalsHelpers reached across pages that happened to be loaded together
reachableEvery page is in an app file or an alternative route, or named somewhereA page that existed but nothing could open
dom-scopePages query page.root, blade styles are scoped, the root id exists22 uses of document.* and 7 cases of CSS leaking across pages
blade-escapeNo request value printed raw; warns on any raw variableA meta tag echoing a request value
secretsNo API keys or secrets in client codeA chat API key and a Pusher secret in shipped JavaScript
permission-keysverifyAuth(), allowed() and access_mod() name the permission or module code, never a numeric idAn action guarded by id 327, which no store actually had — so the guard passed for everyone
cdn-pinnedCDN URLs carry a versionA component pulled at @latest, which changed under a running app
cdn-freshEvery CDN URL a shell bundle names answers 200 (one HEAD each; offline is not a failure)An unpublished version and a component renamed in a VSEL release — the app loads without it
app-fileThe app file is plain data; its pages exist and are loaded by the app's shell; the module is a ref code or null; navigation names only declared pages, once; labels exist in every locale; icons resolve; badge keys are mapped. A report must name a module, a category listed in report_categories, and only filters its report_filters dictionary definesA menu link to a misspelled component, a generator writing module_id = 0, and a report whose filter the console then refused to save
slugsApp-file slugs are unique, a single segment, and not a route group—
vsa-idiomA page uses the live VSApp API, carries the .vs-page contract on its root, and names no class that no stylesheet definesA generated nine-page app in which every page was dead on arrival — main_view.* threw at parse time and took every later file in the bundle with it — while check reported 0 errors
epoch-committedA changed asset_epoch is staged, judged against the index, not HEADA bump left in a working copy: cache:bust said “set”, nobody committed it, and every browser kept its old JS
xauth-consoleThe console the xauth:* commands push to is the one .env signs in againstvsa.json naming one console while .env pointed at another: both halves reported success, and the only symptom was a menu item that never appeared

Errors and warnings

An error is something that will fail at runtime or on deploy. A warning is a rule the codebase does not fully meet yet — unscoped page CSS, document.* inside a page, a raw variable in a report blade. Warnings do not block. --strict makes them block, once that backlog is cleared.

While a decision is pending, a specific finding can be parked in vsa.json under knownIssues, which turns that one error into a warning and records why.

How globals are resolved

Every page's markup and every script share one document, so the question “is Foo defined?” really means “does any file this shell loads declare Foo?”. To answer it, the checker collects declarations from the bundle files, the shell's inline <script> blocks and its <script src> files, the menus' and layouts' inline scripts, and the scripts the core fetches at runtime.

VSEL components arrive from the CDN, so their declarations cannot be read from the project. known-globals.json ships with the CLI and lists the globals each CDN file declares; vsa check --update-globals records new ones.

Where checks run

  • On save — vsa serve runs them as you work
  • On commit — the project's pre-commit hook runs vsa check, skipping the rules named in quickSkip (by default just the one that needs the network)
  • In CI — vsa check --json, usually with vsa i18n:missing --lang=en beside it