VSA Monolith Framework

Configuration

Two files decide how the CLI treats a project: vsa.json, which every project has, and .env, where the identity credential lives.

vsa.json

It sits at the project root, and it is how vsa recognises a project at all.

vsa.json
{
  "name": "Acme HR",
  "cli": ">=1.0.0",
  "devPort": 8093,
  "modules": { "kind": "code", "allowFalse": true },
  "xauth": { "project": "ACME-HR", "app": "hr" },
  "env": {
    "required": { "SUBS_ID": "the subscription this install serves" },
    "services": { "SIGNAL_URL": "live updates" },
    "liveSideEffects": [{ "keys": "^PLASGATE_", "why": "sends REAL, billed SMS" }]
  },
  "knownIssues": [
    { "check": "dom-scope", "file": "public/js/pages/main/Old.js", "why": "rewrite planned" }
  ]
}
KeyMeaning
nameThe product name, used by make:app titles and vsa help
cliThe CLI version this project needs (>=x.y.z or ^x.y). An older CLI refuses to run here
devPortThe port vsa serve uses
modulesHow app files name a page's XAuth module: kind code (ref codes, the default — xauth:sync creates them) or id for legacy numeric ids. allowFalse lets false mark a non-routable page
env.required.env keys doctor treats as an error when missing, on top of the defaults (APP_KEY, APP_URL, DB_*, COOKIE_NAME, XAUTH_*). A key set to null is removed
env.servicesKeys reported as a warning instead, where the value is the feature that stops working without them
env.liveSideEffectsKeys (as a regex) that make a development checkout act on the real world. doctor warns — this is what stops a local run from sending billed SMS
knownIssuesErrors check downgrades to warnings while a decision is pending. Keep it empty when you can
xauth.consoleThe development console. setup writes it into a new .env, serve always passes it to the app, doctor probes it
xauth.projectThe project's code in the console, matched case-insensitively and kept UPPER-CASE — DMS, PRM. Every xauth:* command matches on it, and xauth:register creates a project under it when the console has none, so it must be the code the console already uses for this product
xauth.appThe entry application, the one XAUTH_APP_ID names. Under a project credential it is a name rather than a key — but the mirror pull will not run without it
templateOnly in the template’s own vsa.json: the paths it owns and the ones it merges. vsa upgrade reads nothing else when deciding what it may touch. A project records the template commit it was taken from, so a later upgrade knows what changed
quickSkipChecks the pre-commit hook and vsa serve skip. Defaults to cdn-fresh, the only rule that needs the network

config/vsa.php

The runtime half: plain data, read by the app and by vsa without booting Laravel — so no env() on a key the CLI reads, no closures, no function calls.

KeyMeaning
asset_epochAppended to the ?v= of every bundle the shell loads — the one reliable way to make every browser fetch fresh JS and CSS. Change it with vsa cache:bust, and commit it: vsa check fails a bump that was only edited
assetsauto (built when public/dist/manifest.json exists, raw otherwise), raw, or built — where a missing manifest is a visible error rather than a silent fall back to raw files on a production deploy
lazy_pagesLoad a page's script and markup the first time it is opened instead of putting every page in the document at boot. Once per app lifecycle, not per navigation, and hovering a menu item prefetches. Off by default, because it changes when a page's script runs
tenant_domain, tenant_transportWhich transports name the subscriber — see Routes & tenancy
dev_subs_codeLocal only, and blanked in config outside APP_ENV=local so config:cache on a real host bakes an empty value even if the key is copied there by mistake

The XAuth credential in .env

A deployed host authenticates as its project, not as one application. doctor and serve read the same module for this, so they never describe a checkout differently.

KeyRole
XAUTH_PROJECT_ID
XAUTH_PROJECT_SECRET
The credential, covering every application of the project. Issued on the console's Projects screen — xauth:register cannot issue it, because the provisioner only ever issues application secrets
XAUTH_APP_ID Names the entry application in X-App-Id. It has no secret of its own under a project credential, but it is not optional: the mirror pull refuses to run without it, and the app-specific APIs address it
XAUTH_APP_SECRET The older per-application credential. Still valid, and still right for a single app deployed alone on its host. Never read once a project credential is set

What doctor reports

  • Error — no credential at all, or a half-filled project pair. A project pair does not fall back to the application pair: the client treats it as configured only when both keys are set, so one empty key is a dead sign-in.
  • Warning — a project credential with no XAUTH_APP_ID. Sign-in still works, so it is not an error: a host that only signs people in does not need it, and .env does not say which kind of host this is.
  • Info — XAUTH_APP_SECRET set alongside a project credential, where nothing reads it, and which of the two modes the checkout is in.
  • Warning — the same key assigned twice. phpdotenv keeps the last one while xauth:sync writes to the first, so a credential written there can look applied and do nothing.

vsa check does not read .env at all. It reads the code the browser downloads. Its only credential-related rule is secrets, which is value-shaped and so already covers a project secret pasted into client code.