# WELD: everything in one file > WELD is a Laravel 13 app with Inertia and Vue that comes with the rest of the Wayne State stack already set up: sign-in, security headers, the standards check, code style and CI. Start your app from it. The README and the Markdown twin of every page, joined. The index is https://weld.apps.wayne.edu/llms.txt. Written by Squire's agent-ready kit; do not edit. --- ## README Source: https://nougat.snu.gs/enterprise-apps/weld/blob/HEAD/README.md On Citadel it is served by the raw-PHP deploy layer in [`deploy/`](https://nougat.snu.gs/enterprise-apps/weld/blob/HEAD/deploy/): a Squire kit whose front controller serves `site/` behind HELMET's security headers. For local development, keep serving `site/` directly. ## WELD **W**ired, **E**verything, **L**inked, **D**eployed. Many parts, one piece. WELD is the whole Wayne State app stack joined into one application. Install it, deploy it, and every part is already hooked up: sign-in, security headers, checks, coding standards, CI and the WayneUI interface. Think of it as the Megazord, except it comes with a deploy script and nobody has to shout to make it combine. ### Documentation The docs live at [site/docs/index.html](https://nougat.snu.gs/enterprise-apps/weld/blob/HEAD/site/docs/index.html) and ship to https://weld.apps.wayne.edu/docs/. They are built from `docs/` by the shared docs builder (`composer docs`) and checked in `composer ci`, so the page you read is the page that ships: same source, same bead. The docs wear the front page's look: the header is `docs/_header.html` and the theme is `docs/theme/weld.css` (named in `docs/docs.json`). Change the look there, never in the builder's kit files (`site/assets/docs.css`, `site/assets/docs.js`). ### Where the code lives The canonical repository is on nougat: [enterprise-apps/weld](https://nougat.snu.gs/enterprise-apps/weld). git.wayne.edu and GitHub ([waynestate/weld](https://github.com/waynestate/weld)) are read-only mirrors of it. Open issues and merge requests on nougat, not on the mirrors. This moves to git.wayne.edu once it has CI runners. The weld is made on nougat; the mirrors only get the polished bead. **Not to be confused with:** `weld:doctor` checks local setup only; standards checks are PROCTOR's. ### Get it WELD is an app you start from, not a library you require. The Megazord ships in a repo, not a box. Composer makes you a fresh copy, writes `.env`, generates the app key and runs the first migration: ``` composer create-project waynestate/weld my-app cd my-app npm ci ``` Or clone it, if you want the history too, and it is yours to rename: ``` git clone https://github.com/waynestate/weld.git my-app cd my-app composer install php vendor/bin/advisor install --client=claude --write npm ci # Windows (PowerShell): Copy-Item .env.example .env # Linux/macOS: cp .env.example .env php artisan key:generate ``` The `advisor install` line writes `.mcp.json`, the MCP config that points Claude Code at ADVISOR's server; the file is git-ignored, because a committed `.mcp.json` would run a program on whoever opens the project. Set `ADVISOR_ENABLED=1` in `.env` to switch the advisor on. Running WELD through Docker instead? PHP is not on your host PATH, so `bin/weld.ps1 up` and `bin/weld.sh up` run the same install inside the app container for you (skip it with `--no-advisor`, or `-NoAdvisor` on Windows); see ADVISOR's README for the details. ### Clone it and rename Want an app that is yours instead of a copy of WELD? Clone it, rename the four things that still say WELD, give it its own key, and re-run the checks. Clone into a folder named for the new app: ``` git clone https://github.com/waynestate/weld.git my-app cd my-app ``` Rename these four things: | What | Where | Change | | --- | --- | --- | | Composer name | `composer.json`, the `"name"` field | `waynestate/weld` becomes your package, e.g. `wayne-state/my-app` | | App name | `.env.example` (and `.env` once you have one) | `APP_NAME=WELD` becomes your app name; `VITE_APP_NAME` follows it through `${APP_NAME}` | | Site title | `site/index.html`, the `` tag | `WELD: Many parts, one piece.` becomes yours; the front page copy is about WELD itself, so rewrite it for your app | | Git remote | repository config | point `origin` at your own repository | The `App\` namespace stays as it is; nothing in the app, the tests or the welded packages needs it renamed. Then give the copy its own key and remote. Skip the copy if `up` already made `.env`. Windows PowerShell: ```powershell Copy-Item .env.example .env php artisan key:generate git remote set-url origin https://git.example.com/you/my-app.git ``` macOS and Linux (sh): ```sh cp .env.example .env php artisan key:generate git remote set-url origin https://git.example.com/you/my-app.git ``` Then re-run the checks the way CI does: `.\bin\weld.ps1 test` (or `bin/weld.sh test`), which runs `composer ci` in the container, plus `composer proctor` for the standards check. A photocopy is not a weld yet: when the checks pass under your name, the seam holds. Want a smaller starting point than a full Laravel app? Sourdough is the starter tool for every shape of Wayne State app. It bakes four shapes today: raw PHP, Laravel with Blade, Laravel with Blade plus Vue islands, and Laravel with Inertia and Vue; only raw PHP with a Vue SPA is not available yet. WELD is the Inertia and Vue shape, already assembled with every part wired and ready to clone. ### What is welded in | Part | What it does in WELD | |---|---| | WayneUI | The interface: Wayne State's design system, wired into the Vue front end and Blade layouts | | CREED | The written standards and `policy.json`: supported PHP, Laravel and Node versions | | Pinstripe | The coding standard: Pint, PHPStan level 8, ESLint and Prettier | | Preflight | The CI pipeline, from GitLab CI/CD components | | PROCTOR | The checks, run in CI and as the deploy gate | | SESAME | Sign-in: CAS, Entra ID (OpenID Connect) and the auth gateway driver, and app-native sessions | | HELMET | The baseline runtime: security headers and CSP, sessions, trusted proxies, `/up` | | Ziggy | Route names as URLs: the route list ships inside the Vite bundle, so `route()` works in Vue without an inline script | ### Status HELMET, SESAME and PROCTOR are welded in from Packagist; the rest of the cast is on Packagist too and gets welded on in turn. What is on the bench today: - `composer.json` is `waynestate/weld`, requires PHP `^8.3`, and the lock file resolves for 8.3.0 - `.env.example` sets `APP_NAME=WELD`, `LOG_CHANNEL=stderr` and `SESSION_DRIVER=database` - `Schema::defaultStringLength(191)` keeps index keys under Citadel's MySQL 5.6 767-byte cap - `.gitattributes` sets `* text=auto eol=lf` - `composer ci` is the CI contract: it runs validate, the tests with Pest, Pint, PHPStan level 8, the agent-ready check and audit, the same command on GitLab and GitHub - `pint.json` and `phpstan.neon` still copy Pinstripe's 0.1 Laravel presets; Pinstripe 0.1.1 is on Packagist (tagged), and they switch to `includes: vendor/waynestate/pinstripe/...` when WELD requires it - HELMET runs its security headers and CSP middleware in the global chain, so every response carries the baseline; the Vite build takes the per-request nonce; trusted proxies are a literal list in `bootstrap/app.php`; `/up` stays Laravel's built-in health route - SESAME owns sign-in at `/login` and `/logout`; the fake driver stands in for the identity provider locally, and CAS is an env change away - PROCTOR measures WELD against CREED's `policy.json` as a CI job (`composer proctor`): warnings pass, failures block - The starter kit's password auth (register, login, password reset, two-factor) is removed on purpose; the door is SESAME's - The license is MIT **Testing.** Write new tests in Pest. Use an `it('...', function () { ... });` closure under `tests/Feature` or `tests/Unit`; the existing PHPUnit class tests keep working and are converted only when you touch them. `composer test` runs both, and `tests/Pest.php` binds the Feature tests to the Laravel app and a fresh database. The suite runs on a fixed dummy `APP_KEY` set in `phpunit.xml` so it boots with no `.env`; the app refuses that key in production, so a copied test config cannot ship. Best practices for building, running and deploying WELD live in [BEST_PRACTICES.md](https://nougat.snu.gs/enterprise-apps/weld/blob/HEAD/BEST_PRACTICES.md). ### Run it locally One command strikes the spark; the containers do the welding. Docker is the only prerequisite: PHP and Node run in the containers, so the host needs neither. - Windows (PowerShell 5.1 or 7): `.\bin\weld.ps1 up` - macOS / Linux: `bin/weld.sh up` `up` copies `.env.example` to `.env` if it is missing, installs the PHP and Node dependencies in the containers, starts the app and Vite, generates the app key if it is not set, and runs the migrations. Then open http://localhost:8000. The same subcommands work on every OS: | Command | What it does | |---|---| | `up` | Bring the whole stack up, as above | | `down` | Stop and remove the containers | | `test` | Run `composer ci` in the app container | | `doctor` | Run `php artisan weld:doctor` in the app container | | `logs` | Follow the container logs | Deploying somewhere other than a laptop? [Running WELD off Citadel](https://nougat.snu.gs/enterprise-apps/weld/blob/HEAD/docs/running-off-citadel.md) covers OpenShift, Coolify and plain Docker, with Citadel for comparison. ### Oracle WELD speaks Oracle through `yajra/laravel-oci8`, and the wiring is already in: an `oracle` connection in `config/database.php`, a check command, and plain-language sentences for the common errors. Until you set the Oracle settings it stays dormant: nothing connects and nothing errors. Fill in one set of names in `.env` (the commented block in `.env.example`): `ORACLE_USERNAME`, `ORACLE_PASSWORD`, and either `ORACLE_TNS` (an Easy Connect string, `host:port/service`, or a full descriptor) or `ORACLE_HOST`, `ORACLE_PORT` and `ORACLE_SERVICE_NAME`. On a server, set them in the app's environment settings, never in a file in git. Check the settings and the connection in plain language, one line per finding: ``` php artisan oracle:check ``` The local `app` container runs the stock Composer image, which has no Oracle driver. When you need a real connection from your machine, the Oracle-ready image is opt-in through `compose.oracle.yaml`: ``` # Windows (PowerShell): $env:WELD_ORACLE_IMAGE = "squire/oracle-parity:8.3" docker compose -f compose.yaml -f compose.oracle.yaml up # macOS / Linux: WELD_ORACLE_IMAGE=squire/oracle-parity:8.3 docker compose -f compose.yaml -f compose.oracle.yaml up ``` The overlay swaps only the app's image and passes the `ORACLE_*` settings through from `.env`; the ports stay bound to `127.0.0.1`. It fails closed when `WELD_ORACLE_IMAGE` is unset. `squire/oracle-parity:8.3` is the name Squire documents for its parity image; build it once with Squire's `scripts/oracle-image-build.sh --flavour parity --php 8.3` (the name is a placeholder until a registry is chosen). ### Check your setup Maintainers: how to build, test and release this project, and where its data comes from, is in [MAINTAINING.md](https://nougat.snu.gs/enterprise-apps/weld/blob/HEAD/MAINTAINING.md). `weld:doctor` strikes an arc across the local setup and reports every joint: the app key, writable storage, the database and pending migrations. One line per check, PASS or WARN or FAIL; exit code 1 when anything FAILs, so it works as a gate. The standards checks (PHP version, debug in production, secure session cookies) belong to PROCTOR: run `composer proctor`, and the doctor report says so. A good bead is a quiet one: all PASS and nothing to say. - Windows (PowerShell): `.\bin\weld.ps1 doctor` - macOS / Linux: `bin/weld.sh doctor` - Straight to the container: `docker compose run --rm app php artisan weld:doctor` Add `--json` to any of them for a machine-readable report. ### WELD and Sourdough Sourdough is the starter tool for every shape of Wayne State app. It bakes four shapes today: raw PHP, Laravel with Blade, Laravel with Blade plus Vue islands, and Laravel with Inertia and Vue; only raw PHP with a Vue SPA is not available yet. WELD is one of those shapes, Laravel with Inertia and Vue, with every part already joined and proved to work together. Pick Sourdough when you want a starter you shape yourself. Pick WELD when you want the finished piece. ### Is WELD still Sourdough's Inertia shape? Sourdough writes a manifest of every file it generates (`.sourdough/manifest.json`: each path with its SHA-256). `bin/regen-check.php` compares that manifest with WELD file by file, skipping the product files WELD adds on top (listed in `.sourdough/product-files.json`) and any path with a `vendor` or `node_modules` segment. Each remaining path is reported as IDENTICAL, DIFFERS, MISSING_IN_WELD or RELOCATED. Sourdough keeps Squire's deploy kit at the app root, and WELD keeps it under `deploy/`; the gate reports those files as relocated, not drift, when the `deploy/` copy is byte-identical. `php artisan oracle:check` finds the check file in either place. The gate is a ratchet: `.sourdough/regen-baseline.json` records the drift already known and accepted, and the check fails only on new drift. CI runs it against a fresh `sourdough new --inertia` generation from Sourdough's main; locally, point it at your own generation: - Run the check: `php bin/regen-check.php --generated ` (or `composer regen-check -- --generated `) - Record the current drift as accepted: add `--write-baseline` ### The cast --- Source: https://weld.apps.wayne.edu/ ![WELD logo: a welder's helmet](https://weld.apps.wayne.edu/brand/weld-avatar-512.png) The Wayne State app stack ## WELD WELD stands for Wired, Everything, Linked, Deployed. Many parts, one piece. WELD is a Laravel 13 app with Inertia and Vue, and the rest of the stack is already in it: sign-in, security headers, the standards check, code style, CI and WayneUI. It's **one install**. Rename it and start on your own pages. `$ composer create-project waynestate/weld my-app` Any other shape? [Sourdough](https://sourdough.apps.wayne.edu/) starts four of the five, from raw PHP to Vue islands, with the same sign-in, headers and checks. [Get started](https://weld.apps.wayne.edu/#start) [Which piece do I need?](https://weld.apps.wayne.edu/#chooser) [Meet the cast](https://weld.apps.wayne.edu/#cast-title) [Docs](https://weld.apps.wayne.edu/docs/index.html) Start here ### Install it, then run one command Yes, this is a lot of packages. Most of you can ignore that. Install WELD, run the one command in step 2, and you have a working app with all of it set up. We split the stack into separate projects because Wayne State developers work on very different apps, and you shouldn't have to buy the whole shop to borrow one torch. 1. ### Install Composer makes a fresh copy, writes `.env`, sets the app key and runs the first migration. ``` composer create-project waynestate/weld my-app ``` 2. ### Start it in Docker This is the one command. You only need Docker, because PHP and Node run in the containers. Then open `localhost:8000`. ``` # macOS, Linux bin/weld.sh up # Windows (PowerShell) .\bin\weld.ps1 up ``` 3. ### Run the checks Runs the tests, Pint, PHPStan and `composer audit`, the same command CI runs. The standards check is separate: `composer proctor`. ``` composer ci ``` [Sourdough](https://sourdough.apps.wayne.edu/) makes the other shapes: `sourdough new my-app` for raw PHP, `sourdough new my-app --laravel` for Laravel with Blade, `sourdough new my-app --laravel --vue` for Vue islands. WELD is the Inertia and Vue shape, ready-made. Already have an app? ### Which piece do I need? Most Wayne State apps are older than this stack. Some are raw PHP, some are Laravel, and plenty only need sign-in or an upgrade. That's why every piece also works on its own. WELD is simply all of them installed together. - I'm starting a new app WELD or [Sourdough](https://sourdough.apps.wayne.edu/) Pick WELD for Laravel with Inertia and Vue, ready-made. Pick Sourdough to start any other shape, or to shape one yourself. - My raw PHP app just needs sign-in [SESAME](https://sesame.apps.wayne.edu/) Adds CAS or Entra ID sign-in to a raw PHP or Laravel app. Your app keeps its own session. - I'm stuck on PHP 7 [Booster](https://booster.apps.wayne.edu/) Upgrades PHP and Laravel one version at a time, and has a playbook for Vue 2 to 3. It never commits; you read the diff and merge it. - I'm deploying to Citadel [Squire](https://squire.apps.wayne.edu/) The build and release scripts Citadel expects, a health check, and a way to run your app locally on the same images. - I want CI on every push [Preflight](https://preflight.apps.wayne.edu/) GitLab CI components for PHP tests on each supported version, PROCTOR, Composer audit, Pint, PHPStan and ESLint. - I want safe defaults at runtime [HELMET](https://helmet.apps.wayne.edu/) Sends the security headers and CSP, hardens the session cookie and checks proxies before your first page is served. - I want it to look like Wayne State [WayneUI](https://wayneui.apps.wayne.edu/) Wayne State's design system. It works in static HTML, raw PHP, Blade and Vue. - I want Citadel to sign people in before my app [Drawbridge](https://drawbridge.apps.wayne.edu/) A gateway that signs people in through Entra ID before they reach your app. Your app then checks one small signed token. - I look after a lot of apps [Rollcall](https://rollcall.apps.wayne.edu/) Scans your apps and reports which PHP, Laravel and sign-in package each one runs, checked against CREED's support dates. - I code with an AI agent [ADVISOR](https://advisor.apps.wayne.edu/) An MCP server your agent can ask about the stack. It answers from CREED's policy file, not from what the model remembers. #### How the four check projects fit together CREED writes the rules down and PROCTOR grades your app against them. Pinstripe is the code style. Preflight runs all of it in CI. 1. [CREED](https://creed.apps.wayne.edu/) the rules The written standards, plus `policy.json`: which PHP, Laravel and Node versions are supported. 2. [PROCTOR](https://proctor.apps.wayne.edu/) the grader Reads your `composer.json` and lock file and reports each check against CREED as pass, warning, info or fail. 3. [Pinstripe](https://pinstripe.apps.wayne.edu/) the code style Shared presets for Pint, PHPStan, Rector, ESLint and Prettier. Your app adds only its own exceptions. 4. [Preflight](https://preflight.apps.wayne.edu/) the runner The CI pipeline that runs all of it, and your tests, on every push. WELD already has all four set up. Run `composer ci` and `composer proctor` on your machine, and GitLab runs both through Preflight on every push. ### The journey Roughly in order: what happens to a request on its way to the page, then what happens to your code before it ships. 1. [HELMET](https://helmet.apps.wayne.edu/) sets security headers 2. [SESAME](https://sesame.apps.wayne.edu/) signs the user in 3. [WayneUI](https://wayneui.apps.wayne.edu/) renders the page 4. [PROCTOR](https://proctor.apps.wayne.edu/) checks the code 5. [Preflight](https://preflight.apps.wayne.edu/) runs CI 6. [Squire](https://squire.apps.wayne.edu/) deploys Up close ### The cast The same projects with a bit more detail. The first seven are part of WELD. The next five work around your app: upgrades, the fleet scan, deploys, the sign-in gateway and the MCP server. After those come Sourdough and the one we're building next. ![WayneUI logo: a rounded frame around a solid shape, with a gold tab on the lower edge](https://weld.apps.wayne.edu/assets/marks/wayneui.svg) #### [WayneUI](https://wayneui.apps.wayne.edu/) 2.0 Contrast | AA Wayne State's design system. WELD uses it in the Vue front end and the Blade layouts. ``` $ pnpm verify ✓ tokens built ✓ contrast AA, every pair ✓ axe 0 violations a11y: 100 $ ``` ![CREED logo: a stone arch with a gold keystone](https://weld.apps.wayne.edu/assets/marks/creed.png) #### [CREED](https://creed.apps.wayne.edu/) 0.1 Volume | Eleven The written standards, plus `policy.json` with the support dates for PHP, Laravel, Node, MySQL, Vue and Inertia. PROCTOR, Rollcall and ADVISOR all read it. ``` $ creed policy show php 8.3, 8.4 laravel 12, 13 node 22 LTS volume eleven $ ``` ![HELMET logo: a white football helmet with a gold facemask](https://weld.apps.wayne.edu/assets/marks/helmet.png) #### [HELMET](https://helmet.apps.wayne.edu/) 0.2 Fit | Snug In WELD it runs in the global middleware, so every response carries the security headers and CSP. ``` $ helmet headers CSP strict, nonce HSTS 1 year frames DENY $ ``` ![SESAME logo: an open door with a gold gap](https://weld.apps.wayne.edu/assets/marks/sesame.png) #### [SESAME](https://sesame.apps.wayne.edu/) 0.2 Says | Open Sign-in through CAS, Entra ID or Drawbridge. Locally, a fake driver signs you in. ``` $ sesame login → off to CAS and back ✓ signed in as ab1234 ✓ session: app-native $ ``` ![PROCTOR logo: an eye with a gold square pupil](https://weld.apps.wayne.edu/assets/marks/proctor.png) #### [PROCTOR](https://proctor.apps.wayne.edu/) 0.2 Strictness | Kind In WELD it's `composer proctor`. In CI, warnings pass and failures block. ``` $ proctor check ✓ php 8.4 supported ✓ headers present ✓ 42 passed, 0 failed $ ``` ![Preflight logo: a runway with a gold center line](https://weld.apps.wayne.edu/assets/marks/preflight.png) #### [Preflight](https://preflight.apps.wayne.edu/) 0.1 Checklist | Long GitLab CI/CD components. WELD's pipeline uses them to run the tests on PHP 8.3, 8.4 and 8.5, plus the audit. ``` $ preflight run ✓ lint pass ✓ test 312 pass ✓ portability pass $ ``` ![Pinstripe logo: a striped necktie with a gold tie bar](https://weld.apps.wayne.edu/assets/marks/pinstripe.png) #### [Pinstripe](https://pinstripe.apps.wayne.edu/) 0.1 Creases | Sharp The code style presets. WELD runs Pint and PHPStan at level 8 from a copy of Pinstripe's 0.1 Laravel presets. ``` $ pinstripe apply ✓ pint 14 files pressed ✓ phpstan level 8, 0 errors ✓ eslint clean style: sharp $ ``` ![Booster logo: a syringe with rocket fins and a gold flame](https://weld.apps.wayne.edu/assets/marks/booster.png) #### [Booster](https://booster.apps.wayne.edu/) 0.1 Sting | Mild Plans an upgrade as hops, like Laravel 10 to 11, and runs them one at a time with Rector. Your tests have to pass on the new PHP before the next hop starts. ``` $ booster plan 1. laravel-10-to-11 2. laravel-11-to-12 3. php-82-to-83 $ ``` ![Rollcall logo: an open register with gold ticks](https://weld.apps.wayne.edu/assets/marks/rollcall.png) #### [Rollcall](https://rollcall.apps.wayne.edu/) 0.1 Attendance | Taken Every app answers “present”, with its PHP, Laravel and auth versions. Rollcall only reports. It never opens an issue or blocks a deploy. ``` $ rollcall report ✓ snapshot today drift none back row PHP 7.4, waving $ ``` ![Squire logo: a satchel with a gold buckle](https://weld.apps.wayne.edu/assets/marks/squire.png) #### [Squire](https://squire.apps.wayne.edu/) 0.3 Armor | Carried The deploy kit for Citadel: `build.sh`, a release script, a health check and local runs on the same images. This page deploys with it too. ``` $ squire doctor ✓ build.sh packages only ✓ release.sh idempotent ✓ /up answers $ ``` ![Drawbridge logo: a castle tower with its bridge down on a gold chain](https://weld.apps.wayne.edu/assets/marks/drawbridge.png) #### [Drawbridge](https://drawbridge.apps.wayne.edu/) 0.1 Moat | Full One OpenID Connect client, through Entra ID, for every app on Citadel. We'd rather get the nonce and state checks right once than in every app. ``` $ drawbridge config:validate ✓ oidc Entra ID, PKCE ✓ protected /admin/ ✓ headers stripped, every spelling bridge: lowered $ ``` ![ADVISOR logo: a speech bubble with a gold compass needle](https://weld.apps.wayne.edu/assets/marks/advisor.png) #### [ADVISOR](https://advisor.apps.wayne.edu/) 0.1 Office hours | Always Ask it which PHP you can build on and it answers from `policy.json`, with the date. It's read-only in 0.1: it can't write files or run shell commands. ``` $ advisor mcp ✓ serving stdio ✓ tools read-only answers: from policy.json $ ``` ![Sourdough logo: a starter jar with a gold band](https://weld.apps.wayne.edu/assets/marks/sourdough.png) #### [Sourdough](https://sourdough.apps.wayne.edu/) 0.1 Rise | Daily `sourdough new` makes a new app with SESAME, HELMET, PROCTOR and Preflight already in place. Use it when you'd rather shape the app yourself. It bakes four of the five app shapes today, and it is the starter for every shape. ``` $ sourdough new --raw Next steps: cd my-app composer install $ ``` #### Next off the line - Rolodex next Person data with types, so nobody has to flip through cards by hand. ### Pick your path The stack has five app shapes. Sourdough bakes four of them today; only raw PHP with a Vue SPA is still waiting. WELD is the Inertia and Vue one, built. From Sourdough #### Raw PHP Plain PHP with no framework and no build step, using WayneUI's standalone files. `composer global require waynestate/sourdough sourdough new my-app --raw` From Sourdough #### Laravel + Blade Laravel with Blade views, the classic WSU shape. `sourdough new my-app --laravel` From Sourdough #### Laravel + Blade + Vue islands Laravel with Blade views, and a little Vue where a page needs behavior. `sourdough new my-app --laravel --vue` This is WELD #### Laravel + Inertia/Vue Laravel 13 with Inertia 2 and Vue 3. This is the shape WELD is, with the stack already installed. `composer create-project waynestate/weld my-app` Not baked yet: raw PHP + Vue SPA (`--raw --vue`); it prints a plan today. Hand it to your agent ### Job tickets Two prompts for whatever coding agent you use. Copy one, or open it in OpenCode, Claude Code, Codex or ChatGPT. Each tells the agent what's already set up and what it must leave alone, and both tell it to ask you before it guesses. #### Get started with WELD Gets a new app running in Docker, checks it, and plans the rename. It won't rename anything until you say so. A prompt for your coding agent. Copy it as it stands: ```text You are a coding agent helping a Wayne State University developer start a new app from WELD: the Wayne State application stack welded into one Laravel app with Inertia and Vue. Sign-in (SESAME), security headers (HELMET), the standards check (PROCTOR) and CI are already joined. The job is to get it running and make it this developer's own. Read first: - https://weld.apps.wayne.edu/llms.txt, the index of WELD's pages, each one as Markdown. Fetch the pages you need; do not work from memory. - ADVISOR, the stack's MCP server, if it is connected: get_project_status and read_project_docs for weld answer from the stack's own docs, and policy_lookup gives today's PHP, Laravel and Node support from CREED. If it is not connected, say so and work from the pages. How to add it: https://advisor.apps.wayne.edu/llms.txt Task: 1. Clone WELD into a new folder with `git clone https://github.com/waynestate/weld.git my-app`, using the app name I give you in place of my-app. 2. Bring it up with Docker, the only prerequisite: `.\bin\weld.ps1 up` on Windows (PowerShell), `bin/weld.sh up` on macOS and Linux. It copies .env.example to .env, installs the PHP and Node dependencies in the containers, sets the app key and runs the migrations. 3. Check the setup with the doctor subcommand (`.\bin\weld.ps1 doctor` or `bin/weld.sh doctor`) and report every line that is not PASS. 4. Run the gate with the test subcommand, which runs `composer ci` in the app container, and the standards check with `composer proctor` (in the app container if the host has no PHP). 5. Propose what to rename to make it mine: APP_NAME in .env.example and the package name in composer.json. Do not change them yet. Constraints: - WELD is Laravel with Inertia and Vue. If I want raw PHP or Laravel with Blade, stop and point me at Sourdough, the starter for every shape: https://sourdough.apps.wayne.edu/llms.txt - Sign-in is SESAME's, at /login and /logout, and its fake driver stands in locally. Never add password auth back. - Never commit .env, and never paste a secret into a prompt or a file. - Give separate commands for Windows (PowerShell), macOS and Linux wherever they differ. - Ask me before you guess: an app name, a check that fails for a reason you cannot explain, or anything that touches a deploy. Output: what you ran and what it said, the doctor report, then the rename plan as numbered steps, then your questions. ``` #### Add a signed-in page to a WELD app Adds a route behind SESAME, a Vue page in the app layout and a feature test, then runs the checks. A prompt for your coding agent. Copy it as it stands: ```text You are a coding agent adding one signed-in page to an app built from WELD: the Wayne State application stack welded into one Laravel app with Inertia and Vue, at Wayne State University. Read first: - https://weld.apps.wayne.edu/llms.txt, then the pages it lists. BEST_PRACTICES.md in this repo says what each practice expects and which stack tool checks it. - ADVISOR, the stack's MCP server, if it is connected: call list_stack_rules with permutation laravel-inertia-vue, and read_project_docs for weld and sesame. If it is not connected, say so and work from the pages. - routes/web.php, resources/js/pages/Dashboard.vue, resources/js/layouts/ and tests/Feature/DashboardTest.php. Task: 1. If I have not said what the page is for, its URL and who may see it, ask. 2. Add the route in routes/web.php the way the dashboard route does it: Inertia::render for a page in resources/js/pages, behind the auth.sesame middleware, with a route name. 3. Write the Vue page with script setup and TypeScript, inside AppLayout with breadcrumbs, the way Dashboard.vue does. 4. Add a feature test beside DashboardTest.php: a guest is sent to /login, and a user signed in with the fake driver gets the page. 5. Run the gate: `composer ci`, or the test subcommand of bin/weld.sh (macOS, Linux) or bin\weld.ps1 (Windows) when the host has no PHP. Constraints: - Sign-in belongs to SESAME: protect the route with auth.sesame, and never add password auth. - HELMET sends a strict CSP with a per-request nonce: no inline scripts, and no new script hosts. - Keep PHPStan at level 8 and Pint clean. Never lower either to get the gate green. - Ask me before you guess, and before you add a migration, a Composer or npm package, or anything that touches a deploy. Output: the files you changed, the gate's result, then your questions. ``` The agent reads the same pages you do: [llms.txt](https://weld.apps.wayne.edu/llms.txt) lists them, [llms-full.txt](https://weld.apps.wayne.edu/llms-full.txt) holds them all in one file, and this page has a [Markdown twin](https://weld.apps.wayne.edu/index.md). Nothing here phones home. The buttons only copy text or open the tool you picked. --- Source: https://weld.apps.wayne.edu/docs/changelog.html ## Changelog[#](https://weld.apps.wayne.edu/docs/changelog.html#changelog) Notable changes to WELD, newest first. ### Unreleased[#](https://weld.apps.wayne.edu/docs/changelog.html#unreleased) - Changed: the docs pages wear the front page's look: the same header and main menu (Docs marked current), each page a cream sheet on the green field, commands on the quick start's terminal with its gold Copy button, the weld bead under every title, branded callouts and a derived dark mode. Motion only for readers who allow it. Sources: `docs/_header.html`, `docs/theme/weld.css`, the `theme` key in `docs/docs.json`. - Fixed: code on the front page's Sourdough card is cream, so it meets AA contrast on the deep green. - Changed: the front page header has a main nav that includes Docs. - Changed: the test APP_KEY is an obvious dummy (32 zero bytes), labeled test-only, and `App\Support\DummyAppKey` makes the app refuse it when `APP_ENV=production`; tests cover both. - Changed: the regen gate treats Squire kit files that WELD keeps under `deploy/` as relocated (not drift), and `oracle:check` finds the check file at the app root or under `deploy/`. - Changed: WELD adopts Pest 4 for new tests: the PHPUnit class tests run unchanged, `composer test` runs Pest over the whole suite, `tests/Pest.php` is configured, the example feature test is converted, and `pestphp/pest` is required at `^4` because Pest 5 needs PHP 8.4. - Changed: CI pins the Preflight components to the 0.1.4 release SHA, so PROCTOR's preflight-pinned check passes. - Changed: the GitHub Actions in WELD's CI (`actions/checkout`, `shivammathur/setup-php`) are pinned to commit SHAs with the tag in a comment, so PROCTOR's `ci-pipelines-unpinned-uses` warning is gone; setup-php moves from the unpublished `@v3` to 2.40.0. - Added: a docs site (site/docs/) built by the shared docs builder from docs/, checked in composer ci. - Changed: the regeneration baseline shrinks from 66 to 62 known-drift paths now that Sourdough no longer ships `resources/js/app.js`, `welcome.blade.php` or a phantom `vite.config.js`, and the `.editorconfig` matches. - Fixed: `npm run lint` passes on the shipped code: the dead `badgeDir` constant leaves `scripts/readme-art/build.mjs`, and Squire's kit bytes (`site/assets/agent-ready.js`, `site/assets/stack-env.js`, with the unused `catch (e)` bindings and dead variables fixed in Squire's kit) are synced in, so the ESLint config no longer excludes them. - Changed: `npm run lint` is now a pure check (`eslint .`); a new `npm run fix` script runs `eslint . --fix`. - Fixed: TrustedProxiesTest no longer depends on a local .env file. The trustProxies() closure in bootstrap/app.php runs when the HTTP kernel resolves on the first request, after the test's app refresh has re-read .env into the process environment, so the .env that composer create-project writes clobbered the value the test set and one of the four tests failed. The helper now re-asserts TRUSTED_PROXIES after the refresh, so the suite is green with a .env present and without one. - Changed: the README and front page say Sourdough bakes four shapes today (raw PHP, Laravel with Blade, Laravel with Blade plus Vue islands, and Laravel with Inertia and Vue) and only raw PHP with a Vue SPA is not available yet; the front page gains a card for the islands shape. WELD is the Inertia and Vue shape, already assembled with every part wired. - Changed: the front-page deploy layer pins HELMET ^0.3, PROCTOR ^0.4 and CREED ^0.1 (lock: HELMET 0.3.0, PROCTOR 0.4.0, CREED 0.1.6). - Changed: CI pins Preflight 0.1.4 (GitLab component includes and the GitHub reusable workflow at its tag commit); the deploy layer sets minimum-stability to stable. - Changed: HELMET moves to ^0.3 and PROCTOR to ^0.4 (lock: HELMET 0.3.0, PROCTOR 0.4.x, CREED 0.1.6, ADVISOR 0.1.5), so the newest PROCTOR checks run on WELD itself; an empty `HELMET_PROXIES=` now trusts nobody. Tests, style, analysis and PROCTOR pass unchanged. ### 0.1.2 (2026-11-03)[#](https://weld.apps.wayne.edu/docs/changelog.html#0-1-2-2026-11-03) - Changed: SESAME moves from 0.2 to 0.4 (`^0.4`). It now logs sign-in events (`sesame.login`, `sesame.logout`, with a per sign-in `session_ref`; turn off with `SESAME_LOG=false`), re-reads the signed-in user when the resolver asks for it, and the gateway driver refuses an `at+jwt` access token. WELD itself needed no code change. - Fixed: the user menu gains a Sign out item on SESAME's logout route, the app bar branding drops the Laravel Starter Kit name and links (WELD logo text, waynestate/weld repository, weld.apps.wayne.edu documentation), .editorconfig covers compose.yaml and its variants, ExampleTest stops booting the framework, and UiBrandingTest pins the branding. - Changed: docs and package metadata name nougat as the canonical repository, with git.wayne.edu and GitHub as read-only mirrors, until git.wayne.edu has CI runners. - Changed: Laravel's trusted proxy list now comes from the TRUSTED_PROXIES environment variable (unset keeps Citadel's 172.18.0.1, set but empty trusts none, `*` trusts all), instead of a literal address. Citadel behaviour is unchanged. - Changed: the README and front page now say Sourdough is the starter tool for every shape of Wayne State app (raw PHP and Laravel with Blade today, the Vue shapes planned) and WELD is the Inertia and Vue shape, already assembled and ready to clone. - Changed: CI pulls its Docker Hub images through the GitLab Dependency Proxy (the group's CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX), so pipelines no longer hit Docker Hub's anonymous pull limit. - Added: `waynestate/advisor` joins `require-dev` at `^0.1`, and "Clone it and rename" gains one step: `php vendor/bin/advisor install --client=claude --write` writes `.mcp.json`, which is now git-ignored because a committed MCP config would run a program on whoever opens the project. Set `ADVISOR_ENABLED=1` in `.env` to switch the advisor on. - Changed: `bin/weld.ps1 up` and `bin/weld.sh up` write `.mcp.json` from ADVISOR inside the app container as part of the first-run setup (no PHP on the host PATH in the Docker path), with a `--no-advisor` opt-out on both scripts (`-NoAdvisor` on the PowerShell one). - Changed: the deploy layer's Squire kit is refreshed to 0.3.3 (release options can now live in ./.env.squire). - Changed: the deploy layer's Squire kit is refreshed to 0.3.4 (the local .env.squire file is now git-ignored). - Changed: the deploy layer's Squire kit is refreshed to 0.4.0: deploy/oracle-check.php arrives, so `php artisan oracle:check` runs the real check, and release.sh runs it without failing the release. - Changed: the Oracle overlay docs name Squire's parity image, `squire/oracle-parity:8.3`. - Added: `StackIntegrationTest` pins HELMET's security headers on a signed-in dashboard, a 404 error page and `/up`; `ProctorCheckTest` runs PROCTOR against CREED's policy.json inside the test suite, which `composer ci` alone did not cover. - Added: README section "Clone it and rename": copy WELD, rename the composer name, APP_NAME, site title and git remote, regenerate the key and re-run the checks, for PowerShell and sh. - Changed: BEST_PRACTICES.md re-checked against the code on 2026-11-02: the Squire kit's Dockerfile, entrypoint and release script move W10, W12, W16 and W24 from `Not yet` to `Documented`, W8/W13/W22 sentences name the new deploy files, and the shifted line numbers in composer.json, .env.example and bootstrap/app.php are corrected. - Added: the regen gate, which makes "WELD is the prebuilt Inertia shape" checkable: `bin/regen-check.php` compares a freshly generated Sourdough Inertia app (its `.sourdough/manifest.json`, path to SHA-256) with WELD file by file, skipping `.sourdough/product-files.json` entries and any `vendor` or `node_modules` path, and fails only on drift not already recorded in `.sourdough/regen-baseline.json` (a ratchet; `--write-baseline` records the current drift). The logic lives in `App\Support\RegenCheck` with unit tests, `composer regen-check` passes arguments through (not part of `ci`), and warning-only `regen-gate` jobs in both pipelines generate a fresh app from Sourdough's main and run the gate. ### 0.1.1 (2026-10-29)[#](https://weld.apps.wayne.edu/docs/changelog.html#0-1-1-2026-10-29) - Added: agent-ready site (prompt blocks, Markdown twins, llms.txt), from Squire's kit. - Fixed: stale capability claims in the site and docs. - Changed: project names written as words except acronyms. - `npm run typecheck` (vue-tsc, no emit) joins the scripts, and it passes: the ten errors from the first run are fixed in the bullets below. - `site/assets/wayne-ui/marks/warrior-strong-reverse.svg` comes back from the WayneUI static bundle; the CSS has pointed at it since the front page assets landed. - The tsconfig `types` array keeps `vite/client` and regains `./resources/js/types`: the shared interfaces move from `index.ts` to `index.d.ts`, which is the shape that entry resolves to. `vue/tsx` stays out, because it never resolved. - `VITE_APP_NAME` is declared in a new `resources/js/env.d.ts` against vite/client's `ImportMetaEnv`, replacing the inline `declare module` block in the app entry. - The app entry imports the Ziggy config from a new `ziggy-value.js` beside the generated `ziggy.js`, with a matching `ziggy-value.d.ts`: the generated declaration names the routes but not the value, and the value's string `location` predates the package's typed shape, so the declaration stops at the config minus that field. - `SharedData` extends Inertia's `PageProps`, so it satisfies the constraint `usePage` puts on its type argument. - AppHeader types its page with `usePage()`, so the user menu meets a `User` instead of `unknown`. - TextLink's optional `method` prop takes Inertia's `Method` union instead of `string`. - Welcome reads the signed-in state from `usePage()` instead of `$page`, which vue-tsc does not recognize on the component instance. ### 0.1.0 (2026-10-29)[#](https://weld.apps.wayne.edu/docs/changelog.html#0-1-0-2026-10-29) - `waynestate/helmet` moves from `^0.1` to `^0.2` (locked at 0.2.3). The published `config/helmet.php` re-syncs with the package: `HELMET_PRESET` fills the proxy list (an unknown name throws at boot), and the security headers middleware joins the global chain, so every response carries the baseline. The trusted-header set narrows to `X-Forwarded-For` and `X-Forwarded-Proto`; `X-Forwarded-Port` is no longer trusted, because Citadel's HA-Proxy never sends it. - `php artisan weld:doctor`: local setup only: the app key, writable storage, the database and pending migrations. The standards checks (PHP version, debug in production, secure session cookies) belong to PROCTOR, and the report points at `composer proctor`. - Ziggy's route list leaves the inline `