diff --git a/.gitignore b/.gitignore index f2471a36d..74875645f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,9 @@ postgres/pgsql-test/output/ .env.local graphql/server/logs/ graphql/server/*.heapsnapshot +scripts/scale-validate/out/ +scripts/scale-validate/fleet*.json +scripts/scale-validate/drifted.json +scripts/scale-spike/ +packages/perf-harness/perf-out/ +/metrics.jsonl diff --git a/packages/perf-harness/.gitignore b/packages/perf-harness/.gitignore new file mode 100644 index 000000000..c71e46e3f --- /dev/null +++ b/packages/perf-harness/.gitignore @@ -0,0 +1,3 @@ +dist/ +.smoke-out/ +perf-out/ diff --git a/packages/perf-harness/DESIGN.md b/packages/perf-harness/DESIGN.md new file mode 100644 index 000000000..faf0846ec --- /dev/null +++ b/packages/perf-harness/DESIGN.md @@ -0,0 +1,168 @@ +# @constructive-io/perf-harness — Design + +Reusable performance / regression harness for the Constructive GraphQL server. +Port of the ad-hoc `scripts/scale-validate/*.mjs` tooling (built during the +2026-07 blueprint-pooling validation program) into a proper monorepo package, +so the next time a memory/scale regression appears it is re-run with one +command instead of hand-driven scripts. + +**The originals in `scripts/scale-validate/` are the behavioral source of +truth. Port faithfully: every CLI flag, default, output field, and exit code is +preserved unless this document says otherwise. Do not redesign algorithms.** + +## Package identity + +- Directory: `packages/perf-harness` (auto-included by `pnpm-workspace.yaml` glob `packages/*`; lerna derives from pnpm — no registration anywhere) +- Name: `@constructive-io/perf-harness`, version `0.1.0`, license MIT, author `Constructive ` +- Bin: `{ "perf-harness": "index.js", "cperf": "index.js" }` (dist-relative like `packages/cli`; shebang `#!/usr/bin/env node` as FIRST line of `src/index.ts` — makage preserves it; no makage config file exists or is needed) +- `main: index.js`, `module: esm/index.js`, `types: index.d.ts`, `publishConfig: { access: public, directory: dist }`, NO `files` field (no sibling has one) +- Scripts (verbatim sibling standard): + `clean: makage clean` / `prepack: npm run build` / `build: makage build` / `build:dev: makage build --dev` / `dev: ts-node ./src/index.ts` / `lint: eslint . --fix` / `test: jest --passWithNoTests` / `test:watch: jest --watch` +- dependencies: `pg ^8.21.0` (imported directly), `inquirerer ^4.9.1`, `@inquirerer/utils ^3.3.9`, `graphile-cache workspace:^` (lazy-required ONLY inside `report predict` — see below) +- devDependencies: `@types/pg ^8.20.0`, `@types/node ^22.19.11`, `makage ^0.3.0`, `ts-node ^10.9.2`, `@inquirerer/test ^1.4.3` +- Do NOT declare typescript / jest / ts-jest / eslint / graphql — root-hoisted or irrelevant. +- `tsconfig.json`, `tsconfig.esm.json`, `jest.config.js`: byte-identical to `packages/server-utils` versions (extends `../../tsconfig.json`; ESM variant outDir `dist/esm`, module es2022, declaration false; jest = ts-jest preset, testRegex `(/__tests__/.*|(\.|/)(test|spec))\.(jsx?|tsx?)$`, modulePathIgnorePatterns `['dist/*']`, NO trailing commas). +- NO eslint config file in the package (root `.eslintrc.json` governs). Code style: 2-space, single quotes, semicolons, no trailing commas, `_`-prefixed unused args. + +## Hard rules (safety + fidelity) + +1. **Hub guardrail**: `HUB_PORTS = [5432, 3000, 3001, 3002, 9000]`. EVERY command that dials Postgres or a server port calls `assertPortAllowed(port, allowHub)` and fails with a clear error naming the flag `--allow-hub` to override. PG port default is **5433, never 5432** (preserve the `_lib.mjs` comment's intent). +2. **Credentials**: never hardcoded. `--email` defaults to `seeder@gmail.com`; `--password` has NO default — resolution order: flag > `PERF_PASSWORD` env. Commands needing auth error out with guidance when it is missing. Never interpolate creds into shell strings (we spawn with arg arrays only). +3. **No absolute paths** in code. Repo root discovered by walking up from cwd to the first `pnpm-workspace.yaml` (`findRepoRoot()`); server command defaults to `['node', '/packages/cli/dist/index.js']`, overridable via `--server-cmd`. +4. All outputs under `--out-dir` (default `./perf-out`), created with mkdir -p. File naming: `metrics-