README.md
README.md is a file in Project Scripts. 108 lines of code and 0 definitions.
<!-- Auto-generated 2026-10-04T16:25Z v10 -->
# @project/scripts
<!-- concern:overview -->
## Purpose
Every standalone script lives here, in one governed root instead of inside the members it inspects. The root has the containers `configuration`, `core` and `runtime` plus the flat `types` bucket. Each script is a thin `runtime/entrypoints/<subject>.entrypoint.ts` that drives the loaders, analyzers, validators and adapters under `core/` and writes the lines in `configuration/strings/`.
`closure.entrypoint.ts` is the generator the rest of the stack depends on. It walks the application member with the TypeScript AST through `buildClosureGraph` in `core/coordinators/closure.coordinator.ts` and writes the closure graph, which every graph-aware lint rule reads at module-eval time. The graph holds registers, consumers, emits, subscribes, exports, imports and interfaces, plus the ids, strings and icons export sets. Its keys are relative to the member, so a rule keying them from the application root matches nothing.
The other gate steps are checks that need a whole-tree walk a per-file AST rule cannot do:
- `source.entrypoint.ts`: a line cap over the stylesheets and markup the TypeScript line rule does not parse
- `style.entrypoint.ts`: dead-CSS detection
- `coverage.entrypoint.ts`: a floor on the passing-test count
- `server.entrypoint.ts`: every build config serves over encrypted transport
- `nginx.entrypoint.ts`: the server configuration carries no comment and selects the njs engine it is tested against
- `dependency.entrypoint.ts`: every dependency install script has an `allowScripts` decision
The developer runs the rest through root package scripts: `snapshot` (`snapshot.entrypoint.ts`), `capture` (`route.entrypoint.ts`), `viewport` (`viewport.entrypoint.ts`) and `rates` (`rate.entrypoint.ts`).
`viewport` serves the built site over HTTPS on a free local port and opens each route in a headless browser that emulates a phone: a narrow viewport, a touch screen and a phone user agent. It evaluates `auditPage` from `core/probes/viewport.probe.ts` in every page and reports elements past the screen edge, form fields under the size that stops the browser zooming on focus, text under the legible size, controls under the touch minimum, and content cut off by its container. It writes one screenshot per route and a JSON report into the output folder. The run exits non-zero on any finding except cut-off content, which it only reports, because a container that scrolls on purpose looks the same.
<!-- /concern:overview -->
<!-- concern:use -->
## When to use
- Adding a generated artifact the gate refreshes before a later stage reads it.
- Adding a check that sees the whole tree at once, such as a cross-file count, a reachability question or a whole-corpus scan.
- Adding a check over a file type the lint stack does not parse, such as raw markup, an asset manifest or a server configuration.
- Adding a probe the developer runs by hand against the dev server or the live site.
## When NOT to use
- A check expressible as a single-file AST predicate. That check is a lint rule under `.govlab/rules/eslint/`, where it reports at the offending line.
- A script the application imports or a build step runs. That script lives in the build member.
- A one-off investigation. That work belongs in the scratchpad, because this root holds the steps that run every time.
<!-- /concern:use -->
<!-- concern:charts -->
## Architecture charts
The structure, logical-flow and dependency diagrams derived from the source AST live in [_code.info.generated/mermaid-charts.generated.md](./_code.info.generated/mermaid-charts.generated.md).
<!-- /concern:charts -->
<!-- concern:install -->
## Install
A private workspace member resolved through the root `package.json` workspaces list. One `npm install` at the repo root is the whole setup. It declares only its `@govlab/*`, `@banes-lab/*` and `@ssot/*` siblings, and the third-party packages it uses, such as `purgecss`, `vite` and `typescript`, are hoisted at the root. There is no build step. The gate invokes each entrypoint directly as `node project.scripts/runtime/entrypoints/<subject>.entrypoint.ts`, never through an npm script name.
## Quick start
```sh EXAMPLE: Rebuild the closure graph the graph-aware lint rules read
node project.scripts/runtime/entrypoints/closure.entrypoint.ts
# closure-graph: registers, consumers, exports, imports and interfaces, counted as it walks
```
```sh EXAMPLE: Run the standalone checks the way the gate does
node project.scripts/runtime/entrypoints/source.entrypoint.ts # every CSS and HTML file under the cap
node project.scripts/runtime/entrypoints/style.entrypoint.ts # no unused selectors
node project.scripts/runtime/entrypoints/nginx.entrypoint.ts # no comment, and the njs engine selected
node project.scripts/runtime/entrypoints/coverage.entrypoint.ts # reads the vitest json report
```
```sh EXAMPLE: Audit the built site as a phone renders it
npm run verify -- --member app --only "Build site"
npm run viewport -- --out-dir <folder>
npm run viewport -- --out-dir <folder> --route / --route /pag/keywords --width 360
```
<!-- /concern:install -->
<!-- concern:api -->
## API
The package exposes no public API.
<!-- /concern:api -->
<!-- concern:config -->
## Configuration
No config file. Every location resolves through `@ssot/paths`, with `absolutePath("app.member")` for the tree under inspection. The thresholds are constants of this root: `MIN_PASSING_TESTS` in `configuration/constants/coverage.constants.ts`, and the line cap, which is the quality config's `file-length` value read from the generated thresholds. The argv contracts of the developer's scripts are in `configuration/configs/`. Reports are written under the lint reports folder, which is also where `coverage.entrypoint.ts` expects the vitest json report to exist already.
<!-- /concern:config -->
<!-- concern:deps -->
## Dependencies
- `@banes-lab/build-scripts`
- `@banes-lab/content`
- `@banes-lab/web`
- `@govlab/argv`
- `@govlab/canonical-write`
- `@govlab/constants`
- `@govlab/content-fingerprint`
- `@govlab/context`
- `@govlab/docs`
- `@govlab/pipeline`
- `@govlab/quality`
- `@govlab/stats`
- `@ssot/govlab`
- `@ssot/paths`
- `@ssot/secrets`
<!-- /concern:deps -->
<!-- concern:ai-context -->
## AI context
- The auto-fix stage runs before linting. `closure.entrypoint.ts` writes the graph every graph-aware rule reads at module-eval time, so a lint pass ahead of it reads a stale graph. The ordering exists only as position in the stage array, and no predicate asserts it.
- A graph-aware rule fails closed when the graph is missing. A crash here does not degrade to a skipped check. It turns into a wall of violations in the next stage, so read the auto-fix output before diagnosing a lint explosion.
- Never derive a root from `import.meta.url` here. These scripts live in one root and inspect another, and file-relative arithmetic resolves inside `project.scripts/` and finds nothing. A discovery walk would return an empty set, and every downstream check would pass vacuously.
- The gate runs each entrypoint from the repo root, so a relative path in a glob or a `process.cwd()` call resolves against the workspace root, not the inspected tree. Build globs from `relativePath("app.member")` instead of assuming the cwd.
- `coverage.entrypoint.ts` reads a report it does not produce. If the vitest step was skipped, it exits non-zero instead of passing vacuously.
<!-- /concern:ai-context -->
<!-- concern:domains -->
## Domains
This package serves these software domains, which `_manifest.json` declares in `domains` from the two-tier software-domain vocabulary (`meta → sub`):
- **developer-tooling** — build-tooling, code-generation, linting-quality
<!-- /concern:domains -->
<!-- concern:quality-governance -->
## Quality governance
The canonical quality catalog resolves the quality concepts that govern this package. `_manifest.json` declares them in `governedBy`, and a lint package derives them from the concepts its own rules enforce. Each maps to the custom lint rules that enforce it:
- **duplicate-code** — _complexity_
- **separation-of-concerns** — _complexity_
- **type-safety** — _correctness_
<!-- /concern:quality-governance -->
<!-- concern:disposal -->
## Disposal
- Remove the steps that invoke this root's entrypoints from the stage planner: the closure graph in the auto-fix stage, the line cap and dead CSS in the linting stage, the test floor in the testing stage, and the install-script, transport and server-configuration checks.
- Delete the graph-aware rules under `.govlab/rules/eslint/`. Without the graph they fail closed, which is worse than absent.
- Remove the `snapshot`, `capture`, `viewport` and `rates` scripts from the root `package.json`.
- Remove the `project.scripts` entries from `containers` and `specialContainers` in `.govlab/shared/configs/taxonomy.config.ts`, the `scripts` key under `project` in `project.paths/paths.yaml`, and the root with its workspace entry.
<!-- /concern:disposal -->
<!-- concern:metrics -->
---
stable · 0 exports · 15 deps · 0 principles · 3 concepts
<!-- /concern:metrics -->